[et-mgmt-tools] [PATCH] virt-convert: vdisk fixes
john.levon at sun.com
john.levon at sun.com
Fri Jul 25 15:54:09 UTC 2008
# HG changeset patch
# User john.levon at sun.com
# Date 1217001227 25200
# Node ID 004b1455bb21116bc6ae83a8257b68d4f04cd732
# Parent c0bd4e747433ae4ab8ade954ed0b95c521661147
virt-convert: vdisk fixes
Update the vdisk code for new vdisk behaviour.
Signed-off-by: John Levon <john.levon at sun.com>
diff --git a/virtconv/diskcfg.py b/virtconv/diskcfg.py
--- a/virtconv/diskcfg.py
+++ b/virtconv/diskcfg.py
@@ -18,9 +18,12 @@
# MA 02110-1301 USA.
#
+import popen2
import shutil
import errno
+import sys
import os
+import re
DISK_FORMAT_NONE = 0
DISK_FORMAT_RAW = 1
@@ -32,7 +35,7 @@ DISK_TYPE_ISO = 2
DISK_TYPE_ISO = 2
disk_suffixes = {
- DISK_FORMAT_RAW: ".img",
+ DISK_FORMAT_RAW: ".raw",
DISK_FORMAT_VMDK: ".vmdk",
DISK_FORMAT_VDISK: ".vdisk.xml",
}
@@ -60,6 +63,15 @@ def ensuredirs(path):
except OSError, e:
if e.errno != errno.EEXIST:
raise
+
+def run_cmd(cmd):
+ """
+ Return the exit status and output to stdout and stderr.
+ """
+ proc = popen2.Popen3(cmd, capturestderr=True)
+ proc.tochild.close()
+ ret = proc.wait()
+ return ret, proc.fromchild.readlines(), proc.childerr.readlines()
class disk(object):
"""Definition of an individual disk instance."""
@@ -114,15 +126,27 @@ class disk(object):
if need_copy:
if out_format == DISK_FORMAT_VDISK:
- stdin, stdout = os.popen2(["/usr/bin/vdiskadm", "import", "-n",
- "-f", "-t", qemu_formats[self.format],
- "\"%s\"" % os.path.join(indir, self.path)])
- paths = stdout.readlines()
- stdin.close()
- stdout.close()
- for path in paths:
- self.copy_file(os.path.join(indir, path),
- os.path.join(outdir, path))
+ # copy any sub-files for the disk as well as the disk
+ # itself
+ ret, stdout, stderr = run_cmd(["/usr/lib/xen/bin/vdiskadm", "import",
+ "-npqf", os.path.join(indir, self.path)])
+
+ if ret != 0:
+ raise RuntimeError("Disk conversion failed with "
+ "exit status %d: %s" % (ret, "".join(stderr)))
+ if len(stderr):
+ print >> sys.stderr, stderr
+
+ stubpath = os.path.dirname(self.path)
+
+ for item in stdout:
+ type, path = item.strip().split(':', 1)
+ if not (type == "snapshot" or type == "file"):
+ continue
+ infile = os.path.join(indir, stubpath, path)
+ outfile = os.path.join(outdir, stubpath, path)
+ self.copy_file(infile, outfile)
+
return need_convert
# this is not correct for all VMDK files, but it will have
@@ -156,27 +180,63 @@ class disk(object):
absin = os.path.join(indir, relin)
absout = os.path.join(outdir, relout)
- ensuredirs(absout)
-
- if out_format == DISK_FORMAT_VDISK:
- convert_cmd = ("""/usr/bin/vdiskadm import -t %s "%s" "%s" """ %
- (qemu_formats[out_format], absin, absout))
- elif out_format == DISK_FORMAT_RAW:
- convert_cmd = ("""qemu-img convert -O %s "%s" "%s" """ %
- (qemu_formats[out_format], absin, absout))
- else:
+ if not (out_format == DISK_FORMAT_VDISK or
+ out_format == DISK_FORMAT_RAW):
raise NotImplementedError("Cannot convert to disk format %s" %
output_format)
- self.clean += [ absout ]
-
- ret = os.system(convert_cmd)
+ ensuredirs(absout)
+
+ if out_format != DISK_FORMAT_VDISK:
+
+ self.clean += [ absout ]
+
+ ret, stdout, stderr = run_cmd(["qemu-img", "convert", "-O",
+ qemu_formats[out_format], absin, absout])
+ if ret != 0:
+ raise RuntimeError("Disk conversion failed with "
+ "exit status %d: %s" % (ret, "".join(stderr)))
+ if len(stderr):
+ print >> sys.stderr, stderr
+
+ self.path = relout
+ self.format = out_format
+ return
+
+ #
+ # The presumption is that the top-level disk name can't contain
+ # spaces, but the sub-disks can. We don't want to break an
+ # existing config if we're doing it in-place, so be careful
+ # about copying versus moving.
+ #
+ spath = re.sub(r'\s', '_', relin)
+ if spath != relin:
+ infile = os.path.join(outdir, relin)
+ outfile = os.path.join(outdir, spath)
+ if indir == outdir:
+ shutil.copy(infile, outfile)
+ else:
+ shutil.move(infile, outfile)
+ self.path = spath
+ relin = spath
+
+ ret, stdout, stderr = run_cmd(["/usr/lib/xen/bin/vdiskadm", "import",
+ "-fp", os.path.join(outdir, relin)])
+
if ret != 0:
- raise RuntimeError("Disk conversion failed with exit status %d"
- % ret)
-
- self.path = relout
- self.format = out_format
+ raise RuntimeError("Disk conversion failed with "
+ "exit status %d: %s" % (ret, "".join(stderr)))
+ if len(stderr):
+ print >> sys.stderr, stderr
+
+ stubpath = os.path.dirname(relin)
+
+ for item in stdout:
+ type, path = item.strip().split(':', 1)
+ if type == "store":
+ path = os.path.join(stubpath, path)
+ self.clean += [ os.path.join(outdir, path) ]
+ self.format = out_format
def disk_formats():
"""
More information about the et-mgmt-tools
mailing list