Hello!

Today I want to share the results of my research on the versioning of objects in S3. I heard about this feature for a long time, but did not know much. And even now I don’t really know much - I’ll tell you how to enable versioning in bucket and getting objects of different versions.
My research has shown that this function is not particularly in demand, and there are no ready-made free tools for versioning at all. But there are libraries that have this functionality. Need - develop, they say.
')
So, for versioning, in the bucket we first need to enable it. There are 2 ways to do this, and both are tied to the API.
- Net REST / SOAP Request
- Through the library
I will use the Ruby library
aws-sdk , which we will install:
$ gem install aws-sdk
After that, log in to the Ruby console:
$ irb
Next, log in and enable versioning for the bucket:
require 'aws-sdk' s3 = AWS::S3.new( :access_key_id => ENV['AMAZON_ACCESS_KEY_ID'], :secret_access_key => ENV['AMAZON_SECRET_ACCESS_KEY'] ) my_bucket=s3.buckets['epamcccctesting'] my_bucket.enable_versioning
I think that you know what the environment variables AMAZON_ACCESS_KEY_ID and AMAZON_SECRET_ACCESS_KEY mean - we will not dwell on them.
So, in the console, we will see that versioning is enabled:

So, how does the versioning happen? Yes, just. AWS, when trying to replace a file, does not replace it, but assigns a new version, which is given in the POST requester headers. Well, or in the parameters in the library.
Versions look like this:
x-amz-version-id: mHYT.SyFXgHoG6xCy5yQVk6n6riJct4u x-amz-version-id: .KSpevNIkZSgBoCz4vU3iTBttGWXWqIc
After this GET request, you can access the version of the file of interest by inserting in the getter parameters versionId. Without this parameter, we will get the latest version of this file.
Example: I uploaded 3 versions of the file into the bakt and received different versions in headers. You can get these versions from the following links:
It's pretty simple. Deleting a file is also done with the versionId parameter.
In general, it is clear that the functionality is there, but it is not clear why it is still not widely used and there is no normal and convenient implementation for the CLI. For example, backup storage would be convenient. You can also find a dozen examples where file versioning would be a very convenient and simple solution.
Maybe you use versioning somewhere? Tell something interesting?
UPD : For example, displaying versions of an object with dates and sizes:
my_bucket=s3.buckets['epamcccctesting'] file = my_bucket.objects["file"] file.versions.each do |version| puts version.head[:last_modified].to_s + ' ' + version.version_id + ' ' + version.head[:content_length].to_s + ' bytes' end 2012-12-20 16:15:11 +0200 NQc0gba0nv6znIfSHRaxR0fT3I.ZaUQ5 4 bytes 2012-12-20 16:14:52 +0200 s73raBjbDF2pZpQT9o4qPu4Yn0piy1wL 3 bytes 2012-12-20 16:13:59 +0200 6Txnrqbcb4LaXo2MGYP9gn61Em0UIrUq 2 bytes
UPD: Recently, versioning can be enabled via the console:
