Check if remote files exist before uploading
authorNikos Skalkotos <skalkoto@grnet.gr>
Fri, 24 May 2013 11:20:12 +0000 (14:20 +0300)
committerNikos Skalkotos <skalkoto@grnet.gr>
Fri, 24 May 2013 11:20:12 +0000 (14:20 +0300)
Before uploading to pithos, check if any remote file gets
overwritten.

image_creator/dialog_menu.py
image_creator/kamaki_wrapper.py
image_creator/main.py

index d4da713..a167d73 100644 (file)
@@ -136,6 +136,19 @@ def upload_image(session):
         if len(filename) == 0:
             d.msgbox("Filename cannot be empty", width=SMALL_WIDTH)
             continue
+
+        kamaki = Kamaki(session['account'], None)
+        overwrite = []
+        for f in (filename, "%s.md5sum" % filename, "%s.meta" % filename):
+            if kamaki.object_exists(f):
+                overwrite.append(f)
+
+        if len(overwrite) > 0:
+            if d.yesno("The following pithos object(s) already exist(s):\n"
+                       "%s\nDo you want to overwrite them?" %
+                       "\n".join(overwrite), width=WIDTH, defaultno=1):
+                continue
+
         session['upload'] = filename
         break
 
@@ -143,12 +156,12 @@ def upload_image(session):
     try:
         out = image.out
         out.add(gauge)
+        kamaki.out = out
         try:
             if 'checksum' not in session:
                 md5 = MD5(out)
                 session['checksum'] = md5.compute(image.device, size)
 
-            kamaki = Kamaki(session['account'], out)
             try:
                 # Upload image file
                 with open(image.device, 'rb') as f:
@@ -156,14 +169,6 @@ def upload_image(session):
                         kamaki.upload(f, size, filename,
                                       "Calculating block hashes",
                                       "Uploading missing blocks")
-                # Upload metadata file
-                out.output("Uploading metadata file...")
-                metastring = extract_metadata_string(session)
-                kamaki.upload(StringIO.StringIO(metastring),
-                              size=len(metastring),
-                              remote_path="%s.meta" % filename)
-                out.success("done")
-
                 # Upload md5sum file
                 out.output("Uploading md5sum file...")
                 md5str = "%s %s\n" % (session['checksum'], filename)
@@ -237,12 +242,19 @@ def register_image(session):
         out = session['image'].out
         out.add(gauge)
         try:
-            out.output("Registering %s image with Cyclades..." % img_type)
             try:
+                out.output("Registering %s image with Cyclades..." % img_type)
                 kamaki = Kamaki(session['account'], out)
                 kamaki.register(name, session['pithos_uri'], metadata,
                                 is_public)
                 out.success('done')
+                # Upload metadata file
+                out.output("Uploading metadata file...")
+                metastring = extract_metadata_string(session)
+                kamaki.upload(StringIO.StringIO(metastring),
+                              size=len(metastring),
+                              remote_path="%s.meta" % session['upload'])
+                out.success("done")
             except ClientError as e:
                 d.msgbox("Error in pithos+ client: %s" % e.message)
                 return False
@@ -504,7 +516,6 @@ def sysprep(session):
     help_title = "System Preperation Tasks"
     sysprep_help = "%s\n%s\n\n" % (help_title, '=' * len(help_title))
 
-
     syspreps = image.os.list_syspreps()
 
     if len(syspreps) == 0:
@@ -556,15 +567,13 @@ def sysprep(session):
                     try:
                         err = "Unable to execute the system preparation " \
                             "tasks. Couldn't mount the media%s."
+                        title = "System Preparation"
                         if not image.mounted:
-                            d.msgbox(err % "", title="System Preperation",
-                                     width=SMALL_WIDTH)
+                            d.msgbox(err % "", title=title, width=SMALL_WIDTH)
                             return
                         elif image.mounted_ro:
-                            d.msgbox(
-                                err % " read-write",title="System Preperation",
-                                width=SMALL_WIDTH
-                            )
+                            d.msgbox(err % " read-write", title=title,
+                                     width=SMALL_WIDTH)
                             return
 
                         # The checksum is invalid. We have mounted the image rw
index 3f809d0..a722c7b 100644 (file)
@@ -117,4 +117,16 @@ class Kamaki(object):
         params = {'is_public': is_public, 'disk_format': 'diskdump'}
         self.image_client.register(name, location, params, str_metadata)
 
+    def object_exists(self, location):
+        """Check if an object exists in pythos"""
+
+        try:
+            self.pithos_client.get_object_info(location)
+        except ClientError as e:
+            if e.status == 404:  # Object not found error
+                return False
+            else:
+                raise
+        return True
+
 # vim: set sta sts=4 shiftwidth=4 sw=4 et ai :
index 560d4b5..99a35e3 100644 (file)
@@ -181,8 +181,8 @@ def image_creator():
         for extension in ('', '.meta', '.md5sum'):
             filename = "%s%s" % (options.outfile, extension)
             if os.path.exists(filename):
-                raise FatalError("Output file %s exists "
-                                 "(use --force to overwrite it)" % filename)
+                raise FatalError("Output file `%s' exists "
+                                 "(use --force to overwrite it)." % filename)
 
     # Check if the authentication token is valid. The earlier the better
     if options.token is not None:
@@ -191,9 +191,24 @@ def image_creator():
             if account is None:
                 raise FatalError("The authentication token you provided is not"
                                  " valid!")
+            else:
+                kamaki = Kamaki(account, out)
         except ClientError as e:
             raise FatalError("Astakos client: %d %s" % (e.status, e.message))
 
+    if options.upload and not options.force:
+        if kamaki.object_exists(options.upload):
+            raise FatalError("Remote pithos object `%s' exists "
+                             "(use --force to overwrite it)." % options.upload)
+        if kamaki.object_exists("%s.md5sum" % options.upload):
+            raise FatalError("Remote pithos object `%s.md5sum' exists "
+                             "(use --force to overwrite it)." % options.upload)
+
+    if options.register and not options.force:
+        if kamaki.object_exists("%s.meta" % options.upload):
+            raise FatalError("Remote pithos object `%s.meta' exists "
+                             "(use --force to overwrite it)." % options.upload)
+
     disk = Disk(options.source, out, options.tmp)
 
     def signal_handler(signum, frame):
@@ -272,19 +287,12 @@ def image_creator():
             uploaded_obj = ""
             if options.upload:
                 out.output("Uploading image to pithos:")
-                kamaki = Kamaki(account, out)
                 with open(snapshot, 'rb') as f:
                     uploaded_obj = kamaki.upload(
                         f, size, options.upload,
-                        "(1/4)  Calculating block hashes",
-                        "(2/4)  Uploading missing blocks")
-
-                out.output("(3/4)  Uploading metadata file ...", False)
-                kamaki.upload(StringIO.StringIO(metastring),
-                              size=len(metastring),
-                              remote_path="%s.%s" % (options.upload, 'meta'))
-                out.success('done')
-                out.output("(4/4)  Uploading md5sum file ...", False)
+                        "(1/3)  Calculating block hashes",
+                        "(2/3)  Uploading missing blocks")
+                out.output("(3/3)  Uploading md5sum file ...", False)
                 md5sumstr = '%s %s\n' % (checksum,
                                          os.path.basename(options.upload))
                 kamaki.upload(StringIO.StringIO(md5sumstr),
@@ -300,6 +308,11 @@ def image_creator():
                 kamaki.register(options.register, uploaded_obj, metadata,
                                 options.public)
                 out.success('done')
+                out.output("Uploading metadata file ...", False)
+                kamaki.upload(StringIO.StringIO(metastring),
+                              size=len(metastring),
+                              remote_path="%s.%s" % (options.upload, 'meta'))
+                out.success('done')
                 out.output()
         except ClientError as e:
             raise FatalError("Pithos client: %d %s" % (e.status, e.message))