[et-mgmt-tools] [PATCH 02 of 11] Cleanup on failure

john.levon at sun.com john.levon at sun.com
Mon Jul 7 22:51:32 UTC 2008


# HG changeset patch
# User john.levon at sun.com
# Date 1215470371 25200
# Node ID f0ddebbf39a3926f55045ade4fbf850706ed6c3e
# Parent  c75d57437b7b219443580f6e9d6736d27d76ebcf
Cleanup on failure

If we can't convert the disks or export the file, perform some cleanup.

Signed-off-by: John Levon <john.levon at sun.com>

diff --git a/virt-convert b/virt-convert
--- a/virt-convert
+++ b/virt-convert
@@ -31,6 +31,7 @@ import virtconv.vmconfig as vmconfig
 import virtconv.vmconfig as vmconfig
 
 def parse_args():
+    """Parse and verify command line."""
     opts = OptionParser()
     opts.set_usage("%prog [options] inputdir|input.vmx "
         "[outputdir|output.xml]")
@@ -93,6 +94,36 @@ def parse_args():
 
     return options
 
+def rmrf(path):
+    """Remove a directory and all its contents."""
+
+    assert path is not None
+
+    for dirpath, _, files in os.walk(path):
+        for filename in files:
+            os.remove(os.path.join(dirpath, filename))
+    for dirpath, subdirs, _ in os.walk(path, topdown=False):
+        for dirname in subdirs:
+            os.rmdir(os.path.join(dirpath, dirname))
+    os.rmdir(path)
+
+def cleanup(msg, options, created_dir):
+    """
+    After failure, clean up anything we created. Take a conservative
+    approach: only if we created the output directory do we delete
+    anything.
+    """
+    logging.error(msg)
+
+    if created_dir:
+        try:
+            rmrf(options.output_dir)
+        except OSError, e:
+            logging.error("Couldn't clean up output directory \"%s\": %s" %
+                (options.output_dir, e.strerror))
+
+    sys.exit(1)
+
 def main():
     options = parse_args()
     cli.setupLogging("virt-convert", options.debug)
@@ -131,12 +162,15 @@ def main():
 
     vmdef.arch = options.arch
 
+    created_dir = False
     unixname = vmdef.name.replace(" ", "-")
+
     if not options.output_dir:
         options.output_dir = unixname
     try:
         logging.debug("Creating directory %s" % options.output_dir)
         os.mkdir(options.output_dir)
+        created_dir = True
     except OSError, e:
         if (e.errno != errno.EEXIST):
             logging.error("Could not create directory %s: %s" %
@@ -156,19 +190,19 @@ def main():
         for d in vmdef.disks:
             d.convert(options.input_dir, options.output_dir,
                 vmconfig.DISK_TYPE_RAW)
-    except Exception, e:
-        logging.error(e)
-        sys.exit(1)
+    except OSError, e:
+        cleanup("Couldn't convert disks: %s" % e.strerror, options, created_dir)
+    except RuntimeError, e:
+        cleanup("Couldn't convert disks: %s" % e.message, options, created_dir)
  
     try:
         outp.export_file(vmdef, options.output_file)
-    except Exception, e:
-        logging.error(e)
-        sys.exit(1)
+    except ValueError, e:
+        cleanup("Couldn't export to file \"%s\": %s" %
+            (options.output_file, e.message), options, created_dir)
 
     print "\n\nConversion completed and placed in: %s" % options.output_dir
 
-    
 if __name__ == "__main__":
     try:
         main()
diff --git a/virtconv/vmconfig.py b/virtconv/vmconfig.py
--- a/virtconv/vmconfig.py
+++ b/virtconv/vmconfig.py
@@ -77,7 +77,9 @@ class disk(object):
             (infile, qemu_formats[output_type],
             os.path.join(output_dir, outfile)))
 
-        os.system(convert_cmd)
+        ret = os.system(convert_cmd)
+        if ret != 0:
+            raise RuntimeError("qemu-img failed with exit status %d" % ret)
 
         # Note: this is the *relative* path still
         self.path = outfile




More information about the et-mgmt-tools mailing list