# HG changeset patch # User tjd21@xxxxxxxxxxxxxxxxxxxxxx # Node ID 0cdf19cb2a92a7782dd715ae82cfe9a220c1268c # Parent 8098cc1daac47f5ac371947a669b9ba15c6cf3f4 Added "guest:(dev)/path/to/file" syntax to xm create filenames Added pyfscat script to pygrub, needed for guest: syntax Signed-off-by: Tim Deegan diff -r 8098cc1daac4 -r 0cdf19cb2a92 tools/pygrub/setup.py --- a/tools/pygrub/setup.py Sun Dec 4 00:52:38 2005 +++ b/tools/pygrub/setup.py Sun Dec 4 12:20:27 2005 @@ -43,7 +43,7 @@ author_email='katzj@xxxxxxxxxx', license='GPL', package_dir={'grub': 'src'}, - scripts = ["src/pygrub"], + scripts = ["src/pygrub", "src/pyfscat"], packages=pkgs, ext_modules = fsys_mods ) diff -r 8098cc1daac4 -r 0cdf19cb2a92 tools/python/xen/xm/create.py --- a/tools/python/xen/xm/create.py Sun Dec 4 00:52:38 2005 +++ b/tools/python/xen/xm/create.py Sun Dec 4 12:20:27 2005 @@ -26,6 +26,8 @@ import socket import commands import time +import re +import tempfile import xen.lowlevel.xc @@ -387,6 +389,9 @@ fn=set_value, default=None, use="X11 display to use") +gopts.var('delete_after', val='FILES', + fn=append_value, default=[], + use="Files to delete after domain starts") def err(msg): """Print an error to stderr and exit. @@ -409,13 +414,52 @@ else: return s +def file_from_guest(file, vals): + """Extract a file from one of the guest disk images. + """ + if len(vals.disk) < 1: + err("No disks configured and guest-fs file requested") + m = re.match('^\(([^)]+)\)(.*)$', file) + if m != None: + dev = m.group(1) + file = m.group(2) + dev_uname = None + for disk in vals.disk: + (uname, vdev, _, _) = disk + if dev == vdev: + dev_uname = uname + break + if dev_uname == None: + err("Can't find guest block dev %s to extract %s" % (dev, file)) + else: + (dev_uname, _, _, _) = vals.disk[0] + dev_file = blkif.blkdev_uname_to_file(dev_uname) + if dev_file == None: + err("Can't find guest disk image %s to extract %s" % (dev_uname, file)) + (tfd, fname) = tempfile.mkstemp() + os.close(tfd) + rv = os.system("pyfscat -q %s %s %s" % (dev_file, file, fname)) + if rv != 0: + os.unlink(fname) + err("Can't extract %s from guest disk image %s" % (file, dev_uname)) + vals.delete_after.append(fname) + return fname + +def parse_filename(file, vals): + """Parse filename for 'guest:' format + """ + if file.startswith("guest:"): + return file_from_guest(file[6:], vals) + else: + return os.path.abspath(file) + def configure_image(vals): """Create the image config. """ config_image = [ vals.builder ] - config_image.append([ 'kernel', os.path.abspath(vals.kernel) ]) + config_image.append([ 'kernel', parse_filename(vals.kernel, vals) ]) if vals.ramdisk: - config_image.append([ 'ramdisk', os.path.abspath(vals.ramdisk) ]) + config_image.append([ 'ramdisk', parse_filename(vals.ramdisk, vals) ]) if vals.cmdline_ip: cmdline_ip = strip('ip=', vals.cmdline_ip) config_image.append(['ip', cmdline_ip]) @@ -803,6 +847,10 @@ server.xend_domain_destroy(dom) err("Failed to unpause domain %s" % dom) opts.info("Started domain %s" % (dom)) + + for file in opts.vals.delete_after: + os.unlink(file) + return int(sxp.child_value(dominfo, 'domid')) def parseCommandLine(argv): diff -r 8098cc1daac4 -r 0cdf19cb2a92 tools/pygrub/src/pyfscat --- /dev/null Sun Dec 4 00:52:38 2005 +++ b/tools/pygrub/src/pyfscat Sun Dec 4 12:20:27 2005 @@ -0,0 +1,82 @@ +#!/usr/bin/python +# +# pyfscat - extract a file's contents from a filesystem image. +# +# Copyright (C) 2005 XenSource Ltd +# +# Based on pygrub, Copyright 2005 Red Hat, Inc. +# Jeremy Katz +# +# This software may be freely redistributed under the terms of the GNU +# general public license. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +# + +import os, sys + +sys.path = [ '/usr/lib/python' ] + sys.path + +import grub.fsys + +def file_from_fs_image(dev_path, path, out_path, quiet): + """Extract a file from a filesystem image using pygrub's libraries. + """ + offset = 0 + fs = None + for fstype in grub.fsys.fstypes.values(): + if fstype.sniff_magic(dev_path, offset): + fs = fstype.open_fs(dev_path, offset) + break + if fs is None: + if not quiet: + print >> sys.stderr, ("Can't open a filesystem image in %s" + % (dev_path)) + return False + if not fs.file_exist(path): + if not quiet: + print >> sys.stderr, ("Can't find file %s in %s" + % (path, dev_path)) + return False + fd = fs.open_file(path, os.O_RDONLY) + contents = fd.read() + + # We have something to write: fix up somewhere to put it + if out_path == "-": + sys.stdout.write(contents) + else: + try: + out_file = open(out_path, 'w') + out_file.write(contents) + out_file.close() + except IOError: + if not quiet: + print >> sys.stderr, "Can't write to %s" % (out_path) + return False + return True + +def usage(): + print >> sys.stderr, ("Usage: %s [-q] []\n" + "\n" + "Extracts file from fs image " + "to (or stdout)" + % (sys.argv[0],)) + + +quiet = False +if len(sys.argv) > 1 and sys.argv[1] == "-q": + quiet = True + del sys.argv[1] + +if len(sys.argv) == 3: + out_path = "-" +elif len(sys.argv) == 4: + out_path = sys.argv[3] +else: + usage() + sys.exit(1) + +if not file_from_fs_image(sys.argv[1], sys.argv[2], out_path, quiet): + sys.exit(1)