0

I have an S3 bucket that has a bunch of legacy files. I just switched on versioning and am trying to figure out what sort of deletion protection this gives me for the legacy files, compared to new files uploaded since after the switch. Here's some sample code:

import boto
c = boto.connect_s3()
bucket = c.get_bucket('my-bucket')
pfx='myfolder/subfolder/'
i = 0
for k in bucket.list_versions(prefix=pfx):
    if type(k) == boto.s3.deletemarker.DeleteMarker:
        print "DM %s %s" % (k.name, k.version_id)
    else:
        s = k.get_contents_as_string()
        print "REG %s %s %d" % (k.name, k.version_id, len(s))

the pfx contains some legacy files, so the first time I ran this I got something like this:

REG myfolder/subfolder/ null 0
REG myfolder/subfolder/f1 null 369
REG myfolder/subfolder/f2 null 427
REG myfolder/subfolder/f3 null 141

I then deleted f2 using the S3Browser tool. When I reran the code above, i got this:

REG myfolder/subfolder/ null 0
REG myfolder/subfolder/f1 null 369
DM myfolder/subfolder/f2 KPNaxqBeIrCGKUx3tYUsRDwWzKbX06
REG myfolder/subfolder/f2 null 427
REG myfolder/subfolder/f3 null 141

Question is: is there a way of retrieving/undeleting the (only) version of f2 I just deleted?

I Z
  • 5,719
  • 19
  • 53
  • 100

2 Answers2

1

Enabling versioning on a previously-unversioned bucket gives exactly the same deletion protection on existing objects as on new objects, with only one minor difference... and this difference is visible in your output, though it's hard to make sense of, at first.

Each version of a versioned object in versioned buckets has a version id, and when you delete the latest version, it's replaced by a delete marker, which gets a new version id. To access the old version, you access it by its version id, or remove the delete marker. All of this, you already know.

The difference is that when you enable versioning, all of the existing non-versioned objects actually get a version id, and that version id is, literally, "null." Not "null" as in "value is absent" in the three-valued-logic sense, but actually the 4 bytes, n u l l. You can use this version id to access the object the same way you access any versioned object by its key and version id.

Michael - sqlbot
  • 169,571
  • 25
  • 353
  • 427
0

Once you enable versioning on a bucket it is enabled for all objects in the bucket. Any object that is deleted, regardless of whether it was created before or after versioning was enabled, will result in a DeleteMarker being written to the bucket. The object, and any previous versions of the object, will still be there unless you explicitly do a versioned delete operation.

So, if you call list_versions(prefix='myfolder/subfolder/f2') on that bucket it should return a Key object for the version which remains. You should be able to use the normal methods of the Key object to retrieve the contents of the object.

garnaat
  • 44,310
  • 7
  • 123
  • 103