[Pkg-escience-soc2009] [SCM] Tool for creating VM images. branch, master, updated. 7be39d5ed989166da0f27fdfc6b0f47385ca182e

Steffen Moeller steffen_moeller at gmx.de
Sat Jun 20 13:04:20 UTC 2009


The following commit has been merged in the master branch:
commit 7be39d5ed989166da0f27fdfc6b0f47385ca182e
Author: Steffen Moeller <steffen_moeller at gmx.de>
Date:   Sat Jun 20 15:03:42 2009 +0200

    dh_prep or dh_clean seem to have removed files.

diff --git a/VMBuilder/plugins/ubuntu/hardy.py~ b/VMBuilder/plugins/ubuntu/hardy.py~
deleted file mode 100644
index 3ce1caf..0000000
--- a/VMBuilder/plugins/ubuntu/hardy.py~
+++ /dev/null
@@ -1,41 +0,0 @@
-#
-#    Uncomplicated VM Builder
-#    Copyright (C) 2007-2008 Canonical Ltd.
-#    
-#    See AUTHORS for list of contributors
-#
-#    This program is free software: you can redistribute it and/or modify
-#    it under the terms of the GNU General Public License as published by
-#    the Free Software Foundation, either version 3 of the License, or
-#    (at your option) any later version.
-#
-#    This program is distributed in the hope that it will be useful,
-#    but WITHOUT ANY WARRANTY; without even the implied warranty of
-#    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-#    GNU General Public License for more details.
-#
-#    You should have received a copy of the GNU General Public License
-#    along with this program.  If not, see <http://www.gnu.org/licenses/>.
-#
-import suite
-import logging
-import VMBuilder
-from VMBuilder.util		    import run_cmd
-from VMBuilder.plugins.ubuntu.gutsy import Gutsy
-
-class Hardy(Gutsy):
-    virtio_net = True
-
-    def xen_kernel_path(self):
-	rcmd = run_cmd('chroot', self.destdir, 'dpkg', '-S', 'xen')
-	temp = rcmd[0].split(": ")
-	xen_kernel = temp[0].split("linux-image-")
-	path = '/boot/vmlinuz-%s' %xen_kernel
-	return path
-
-    def xen_ramdisk_path(self):
-	rcmd = run_cmd('chroot', self.destdir, 'dpkg', '-S', 'xen')
-	temp = rcmd[0].split(": ")
-	xen_ramdisk = temp[0].split("linux-image-")
-	path = '/boot/initrd.img-%s' %xen_ramdisk
-	return path
diff --git a/VMBuilder/vm.py~ b/VMBuilder/vm.py~
deleted file mode 100644
index 01b764e..0000000
--- a/VMBuilder/vm.py~
+++ /dev/null
@@ -1,554 +0,0 @@
-#
-#    Uncomplicated VM Builder
-#    Copyright (C) 2007-2008 Canonical Ltd.
-#    
-#    See AUTHORS for list of contributors
-#
-#    This program is free software: you can redistribute it and/or modify
-#    it under the terms of the GNU General Public License as published by
-#    the Free Software Foundation, either version 3 of the License, or
-#    (at your option) any later version.
-#
-#    This program is distributed in the hope that it will be useful,
-#    but WITHOUT ANY WARRANTY; without even the implied warranty of
-#    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-#    GNU General Public License for more details.
-#
-#    You should have received a copy of the GNU General Public License
-#    along with this program.  If not, see <http://www.gnu.org/licenses/>.
-#
-#    The VM class
-import ConfigParser
-from   gettext             import gettext
-import logging
-import re
-import os
-import optparse
-import shutil
-import tempfile
-import textwrap
-import socket
-import struct
-import urllib
-import VMBuilder
-import VMBuilder.util      as util
-import VMBuilder.log       as log
-import VMBuilder.disk      as disk
-from   VMBuilder.disk      import Disk, Filesystem
-from   VMBuilder.exception import VMBuilderException, VMBuilderUserError
-_ = gettext
-
-class VM(object):
-    """The VM object has the following attributes of relevance to plugins:
-
-    distro: A distro object, representing the distro running in the vm
-
-    disks: The disk images for the vm.
-    filesystems: The filesystem images for the vm.
-
-    result_files: A list of the files that make up the entire vm.
-                  The ownership of these files will be fixed up.
-
-    optparser: Will be of interest mostly to frontends. Any sort of option
-               a plugin accepts will be represented in the optparser.
-    
-
-    """
-    def __init__(self, conf=None):
-        self.hypervisor = None #: hypervisor object, representing the hypervisor the vm is destined for
-        self.distro = None
-
-        self.disks = []
-        self.filesystems = []
-
-        self.result_files = []
-        self.plugins  = []
-        self._cleanup_cbs = []
-
-        #: final destination for the disk images
-        self.destdir = None
-        #: tempdir where we do all the work
-        self.workdir = None
-        #: mount point where the disk images will be mounted
-        self.rootmnt = None
-        #: directory where we build up the guest filesystem
-        self.tmproot = None
-
-        self.fsmounted = False
-
-        self.optparser = _MyOptParser(epilog="ubuntu-vm-builder is Copyright (C) 2007-2008 Canonical Ltd. and written by Soren Hansen <soren at canonical.com>.", usage='%prog hypervisor distro [options]')
-        self.optparser.arg_help = (('hypervisor', self.hypervisor_help), ('distro', self.distro_help))
-
-        self.confparser = ConfigParser.SafeConfigParser()
-
-        if conf:
-            if not(os.path.isfile(conf)):
-                raise VMBuilderUserError('The path to the configuration file is not valid: %s.' % conf)
-        else:
-            conf = ''
-
-        self.confparser.read(['/etc/vmbuilder.cfg', os.path.expanduser('~/.vmbuilder.cfg'), conf])
-
-        self._register_base_settings()
-
-<<<<<<< HEAD:VMBuilder/vm.py
-        self.add_clean_cmd('rm', log.logfile)
-
-=======
->>>>>>> vmbuilder_ec2_patches:VMBuilder/vm.py
-    def get_version_info(self):
-        import vcsversion
-        info = vcsversion.version_info
-        info['major'] = 0
-        info['minor'] = 10
-        return info
-       
-    def cleanup(self):
-        logging.info("Cleaning up")
-        while len(self._cleanup_cbs) > 0:
-            self._cleanup_cbs.pop(0)()
-
-    def add_clean_cb(self, cb):
-        self._cleanup_cbs.insert(0, cb)
-
-    def add_clean_cmd(self, *argv, **kwargs):
-        cb = lambda : util.run_cmd(*argv, **kwargs)
-        self.add_clean_cb(cb)
-        return cb
-
-    def cancel_cleanup(self, cb):
-        try:
-            self._cleanup_cbs.remove(cb)
-        except ValueError, e:
-            # Wasn't in there. No worries.
-            pass
-
-    def distro_help(self):
-        return 'Distro. Valid options: %s' % " ".join(VMBuilder.distros.keys())
-
-    def hypervisor_help(self):
-        return 'Hypervisor. Valid options: %s' % " ".join(VMBuilder.hypervisors.keys())
-
-    def register_setting(self, *args, **kwargs):
-        return self.optparser.add_option(*args, **kwargs)
-
-    def register_setting_group(self, group):
-        return self.optparser.add_option_group(group)
-
-    def setting_group(self, *args, **kwargs):
-        return optparse.OptionGroup(self.optparser, *args, **kwargs)
-
-    def _register_base_settings(self):
-        self.register_setting('-d', '--dest', dest='destdir', help='Specify the destination directory. [default: <hypervisor>-<distro>].')
-        self.register_setting('-c', '--config',  type='string', help='Specify a additional configuration file')
-        self.register_setting('--debug', action='callback', callback=log.set_verbosity, help='Show debug information')
-        self.register_setting('-v', '--verbose', action='callback', callback=log.set_verbosity, help='Show progress information')
-        self.register_setting('-q', '--quiet', action='callback', callback=log.set_verbosity, help='Silent operation')
-        self.register_setting('-t', '--tmp', default=os.environ.get('TMPDIR', '/tmp'), help='Use TMP as temporary working space for image generation. Defaults to $TMPDIR if it is defined or /tmp otherwise. [default: %default]')
-        self.register_setting('--templates', metavar='DIR', help='Prepend DIR to template search path.')
-        self.register_setting('-o', '--overwrite', action='store_true', default=False, help='Force overwrite of destination directory if it already exist. [default: %default]')
-        self.register_setting('--in-place', action='store_true', default=False, help='Install directly into the filesystem images. This is needed if your $TMPDIR is nodev and/or nosuid, but will result in slightly larger file system images.')
-        self.register_setting('--tmpfs', metavar="OPTS", help='Use a tmpfs as the working directory, specifying its size or "-" to use tmpfs default (suid,dev,size=1G).')
-        self.register_setting('-m', '--mem', type='int', default=128, help='Assign MEM megabytes of memory to the guest vm. [default: %default]')
-        self.register_setting('--cpus', type='int', default=1, help='Number of virtual CPU\'s. [default: %default]')
-
-        group = self.setting_group('Network related options')
-        domainname = '.'.join(socket.gethostbyname_ex(socket.gethostname())[0].split('.')[1:]) or "defaultdomain"
-        group.add_option('--domain', metavar='DOMAIN', default=domainname, help='Set DOMAIN as the domain name of the guest [default: The domain of the machine running this script: %default].')
-        group.add_option('--ip', metavar='ADDRESS', default='dhcp', help='IP address in dotted form [default: %default].')
-        group.add_option('--mac', metavar='VALUE', help='MAC address of the guest [default: one will be automatically generated on first run].')
-        group.add_option('--mask', metavar='VALUE', help='IP mask in dotted form [default: based on ip setting]. Ignored if --ip is not specified.')
-        group.add_option('--net', metavar='ADDRESS', help='IP net address in dotted form [default: based on ip setting]. Ignored if --ip is not specified.')
-        group.add_option('--bcast', metavar='VALUE', help='IP broadcast in dotted form [default: based on ip setting]. Ignored if --ip is not specified.')
-        group.add_option('--gw', metavar='ADDRESS', help='Gateway (router) address in dotted form [default: based on ip setting (first valid address in the network)]. Ignored if --ip is not specified.')
-        group.add_option('--dns', metavar='ADDRESS', help='DNS address in dotted form [default: based on ip setting (first valid address in the network)] Ignored if --ip is not specified.')
-        self.register_setting_group(group)
-
-    def add_disk(self, *args, **kwargs):
-        """Adds a disk image to the virtual machine"""
-        disk = Disk(self, *args, **kwargs)
-        self.disks.append(disk)
-        return disk
-
-    def add_filesystem(self, *args, **kwargs):
-        """Adds a filesystem to the virtual machine"""
-        fs = Filesystem(self, *args, **kwargs)
-        self.filesystems.append(fs)
-        return fs
-
-    def call_hooks(self, func):
-        for plugin in self.plugins:
-            getattr(plugin, func)()
-        getattr(self.hypervisor, func)()
-        getattr(self.distro, func)()
-        
-    def deploy(self):
-        """
-        "Deploy" the VM, by asking the plugins in turn to deploy it.
-
-        If no non-hypervior and non-distro plugin accepts to deploy
-        the image, thfe hypervisor's default deployment is used.
-
-        Returns when the first True is returned.
-        """
-        for plugin in self.plugins:
-             if getattr(plugin, 'deploy')():
-                 return True
-        getattr(self.hypervisor, 'deploy')()
-
-    def set_distro(self, arg):
-        if arg in VMBuilder.distros.keys():
-            self.distro = VMBuilder.distros[arg](self)
-            self.set_defaults()
-        else:
-            raise VMBuilderUserError("Invalid distro. Valid distros: %s" % " ".join(VMBuilder.distros.keys()))
-
-    def set_hypervisor(self, arg):
-        if arg in VMBuilder.hypervisors.keys():
-            self.hypervisor = VMBuilder.hypervisors[arg](self)
-            self.set_defaults()
-        else:
-            raise VMBuilderUserError("Invalid hypervisor. Valid hypervisors: %s" % " ".join(VMBuilder.hypervisors.keys()))
-
-    def get_conf_value(self, key):
-        # This is horrible. Did I mention I hate people who (ab)use exceptions
-        # to handle non-exceptional events?
-        confvalue = None
-        try:
-            confvalue = self.confparser.get('DEFAULT', key)
-        except ConfigParser.NoSectionError, e:
-            pass
-        except ConfigParser.NoOptionError, e:
-            pass
-
-        try:
-            confvalue = self.confparser.get(self.hypervisor.arg, key)
-        except ConfigParser.NoSectionError, e:
-            pass
-        except ConfigParser.NoOptionError, e:
-            pass
-
-        try:
-            confvalue = self.confparser.get(self.distro.arg, key)
-        except ConfigParser.NoSectionError, e:
-            pass
-        except ConfigParser.NoOptionError, e:
-            pass
-
-        try:
-            confvalue = self.confparser.get('%s/%s' % (self.hypervisor.arg, self.distro.arg), key)
-        except ConfigParser.NoSectionError, e:
-            pass
-        except ConfigParser.NoOptionError, e:
-            pass
-
-        logging.debug('Returning value %s for configuration key %s' % (repr(confvalue), key))
-        return confvalue
-    
-    def set_defaults(self):
-        """
-        is called to give all the plugins and the distro and hypervisor plugin a chance to set
-        some reasonable defaults, which the frontend then can inspect and present
-        """
-        multiline_split = re.compile("\s*,\s*")
-        if self.distro and self.hypervisor:
-            for plugin in VMBuilder._plugins:
-                self.plugins.append(plugin(self))
-
-            self.optparser.set_defaults(destdir='%s-%s' % (self.distro.arg, self.hypervisor.arg))
-
-            (settings, dummy) = self.optparser.parse_args([])
-            for (k,v) in settings.__dict__.iteritems():
-                confvalue = self.get_conf_value(k)
-                if confvalue:
-                    if self.optparser.get_option('--%s' % k):
-                        if self.optparser.get_option('--%s' % k).action == 'append':
-                            values = multiline_split.split(confvalue)
-                            setattr(self, k, values)
-                        else:
-                            setattr(self, k, confvalue)
-                    else:
-                        setattr(self, k, confvalue)
-                else:
-                    setattr(self, k, v)
-
-            self.distro.set_defaults()
-            self.hypervisor.set_defaults()
-
-
-    def ip_defaults(self):
-        """
-        is called to validate the ip configuration given and set defaults
-        """
-
-        logging.debug("ip: %s" % self.ip)
-        
-        if self.mac:
-            valid_mac_address = re.compile("([0-9a-f]{2}:){5}([0-9a-f]{2})", re.IGNORECASE)
-            if not valid_mac_address.search(self.mac):
-                raise VMBuilderUserError("Malformed MAC address entered: %s" % self.mac)
-            else:
-                logging.debug("Valid mac given: %s" % self.mac)
-
-        if self.ip != 'dhcp':
-            if self.domain == '':
-                raise VMBuilderUserError('Domain is undefined and host has no domain set.')
-
-            try:
-                numip = struct.unpack('I', socket.inet_aton(self.ip))[0] 
-            except socket.error:
-                raise VMBuilderUserError('%s is not a valid ip address' % self.ip)
-             
-            if not self.mask:
-                ipclass = numip & 0xFF
-                if (ipclass > 0) and (ipclass <= 127):
-                    mask = 0xFF
-                elif (ipclass > 128) and (ipclass < 192):
-                    mask = 0xFFFF
-                elif (ipclass < 224):
-                    mask = 0xFFFFFF
-                else:
-                    raise VMBuilderUserError('The class of the ip address specified (%s) does not seem right' % self.ip)
-            else:
-                mask = struct.unpack('I', socket.inet_aton(self.mask))[0]
-
-            numnet = numip & mask
-
-            if not self.net:
-                self.net = socket.inet_ntoa( struct.pack('I', numnet ) )
-            if not self.bcast:
-                self.bcast = socket.inet_ntoa( struct.pack('I', numnet + (mask ^ 0xFFFFFFFF)))
-            if not self.gw:
-                self.gw = socket.inet_ntoa( struct.pack('I', numnet + 0x01000000 ) )
-            if not self.dns:
-                self.dns = self.gw
-
-            self.mask = socket.inet_ntoa( struct.pack('I', mask ) )
-
-            logging.debug("net: %s" % self.net)
-            logging.debug("netmask: %s" % self.mask)
-            logging.debug("broadcast: %s" % self.bcast)
-            logging.debug("gateway: %s" % self.gw)
-            logging.debug("dns: %s" % self.dns)
-
-    def create_directory_structure(self):
-        """Creates the directory structure where we'll be doing all the work
-
-        When create_directory_structure returns, the following attributes will be set:
-
-         - L{VM.destdir}: The final destination for the disk images
-         - L{VM.workdir}: The temporary directory where we'll do all the work
-         - L{VM.rootmnt}: The root mount point where all the target filesystems will be mounted
-         - L{VM.tmproot}: The directory where we build up the guest filesystem
-
-        ..and the corresponding directories are created.
-
-        Additionally, L{VM.destdir} is created, which is where the files (disk images, filesystem
-        images, run scripts, etc.) will eventually be placed.
-        """
-
-        self.workdir = self.create_workdir()
-        self.add_clean_cmd('rm', '-rf', self.workdir)
-
-        logging.debug('Temporary directory: %s', self.workdir)
-
-        self.rootmnt = '%s/target' % self.workdir
-        logging.debug('Creating the root mount directory: %s', self.rootmnt)
-        os.mkdir(self.rootmnt)
-
-        self.tmproot = '%s/root' % self.workdir
-        logging.debug('Creating temporary root: %s', self.tmproot)
-        os.mkdir(self.tmproot)
-
-        # destdir is where the user's files will land when they're done
-        if os.path.exists(self.destdir):
-            if self.overwrite:
-                logging.info('%s exists, and --overwrite specified. Removing..' % (self.destdir, ))
-                shutil.rmtree(self.destdir)
-            else:
-                raise VMBuilderUserError('%s already exists' % (self.destdir,))
-
-        logging.debug('Creating destination directory: %s', self.destdir)
-        os.mkdir(self.destdir)
-        self.add_clean_cmd('rmdir', self.destdir, ignore_fail=True)
-
-        self.result_files.append(self.destdir)
-
-    def create_workdir(self):
-        """Creates the working directory for this vm and returns its path"""
-        return tempfile.mkdtemp('', 'vmbuilder', self.tmp)
-
-    def mount_partitions(self):
-        """Mounts all the vm's partitions and filesystems below .rootmnt"""
-        logging.info('Mounting target filesystems')
-        fss = disk.get_ordered_filesystems(self)
-        for fs in fss:
-            fs.mount()
-            self.distro.post_mount(fs)
-
-        self.fsmounted = True
-
-    def umount_partitions(self):
-        """Unmounts all the vm's partitions and filesystems"""
-        logging.info('Unmounting target filesystem')
-        fss = VMBuilder.disk.get_ordered_filesystems(self)
-        fss.reverse()
-        for fs in fss:
-            fs.umount()
-        for disk in self.disks:
-            disk.unmap()
-
-        self.fsmounted = False
-
-    def install(self):
-        if self.in_place:
-            self.installdir = self.rootmnt
-        else:
-            self.installdir = self.tmproot
-
-        logging.info("Installing guest operating system. This might take some time...")
-        self.distro.install(self.installdir)
-
-        self.call_hooks('post_install')
-    
-        if not self.in_place:
-            logging.info("Copying to disk images")
-            util.run_cmd('rsync', '-aHA', '%s/' % self.tmproot, self.rootmnt)
-
-        if self.hypervisor.needs_bootloader:
-            logging.info("Installing bootloader")
-            self.distro.install_bootloader()
-
-        self.distro.install_vmbuilder_log(log.logfile, self.rootmnt)
-
-    def preflight_check(self):
-        for opt in sum([self.confparser.options(section) for section in self.confparser.sections()], []) + [k for (k,v) in self.confparser.defaults().iteritems()]:
-            if '-' in opt:
-                raise VMBuilderUserError('You specified a "%s" config option in a config file, but that is not valid. Perhaps you meant "%s"?' % (opt, opt.replace('-', '_')))
-
-        self.ip_defaults()
-        self.call_hooks('preflight_check')
-
-        # Check repository availability
-        if self.mirror:
-            testurl = self.mirror
-        else:
-            testurl = 'http://archive.ubuntu.com/'
-
-        try:
-            logging.debug('Testing access to %s' % testurl)
-            testnet = urllib.urlopen(testurl)
-        except IOError:
-            raise VMBuilderUserError('Could not connect to %s. Please check your connectivity and try again.' % testurl)
-
-        testnet.close()
-
-    def install_file(self, path, contents=None, source=None, mode=None):
-        fullpath = '%s%s' % (self.installdir, path)
-        if source and not contents:
-            shutil.copy(source, fullpath) 
-        else:
-            fp = open(fullpath, 'w')
-            fp.write(contents)
-            fp.close()
-        if mode:
-            os.chmod(fullpath, mode)
-        return fullpath
-
-    def create(self):
-        """
-        The core vm creation method
-        
-        The VM creation happens in the following steps:
-
-        A series of preliminary checks are performed:
-         - We check if we're being run as root, since 
-           the filesystem handling requires root priv's
-         - Each plugin's preflight_check method is called.
-           See L{VMBuilder.plugins.Plugin} documentation for details
-         - L{create_directory_structure} is called
-         - VMBuilder.disk.create_partitions is called
-         - VMBuilder.disk.create_filesystems is called
-         - .mount_partitions is called
-         - .install is called
-
-        """
-        util.checkroot()
-
-        finished = False
-        try:
-            self.preflight_check()
-            self.create_directory_structure()
-
-            disk.create_partitions(self)
-            disk.create_filesystems(self)
-            self.mount_partitions()
-
-            self.install()
-
-            self.umount_partitions()
-
-            self.hypervisor.finalize()
-
-            self.deploy()
-
-            util.fix_ownership(self.result_files)
-
-            finished = True
-        except VMBuilderException,e:
-            raise e
-        finally:
-            if not finished:
-                logging.debug("Oh, dear, an exception occurred")
-            self.cleanup()
-
-class _MyOptParser(optparse.OptionParser):
-    def format_arg_help(self, formatter):
-        result = []
-        for arg in self.arg_help:
-            result.append(self.format_arg(formatter, arg))
-        return "".join(result)
-
-    def format_arg(self, formatter, arg):
-        result = []
-        arghelp = arg[1]()
-        arg = arg[0]
-        width = formatter.help_position - formatter.current_indent - 2
-        if len(arg) > width:
-            arg = "%*s%s\n" % (self.current_indent, "", arg)
-            indent_first = formatter.help_position
-        else:                       # start help on same line as opts
-            arg = "%*s%-*s  " % (formatter.current_indent, "", width, arg)
-            indent_first = 0
-        result.append(arg)
-        help_lines = textwrap.wrap(arghelp, formatter.help_width)
-        result.append("%*s%s\n" % (indent_first, "", help_lines[0]))
-        result.extend(["%*s%s\n" % (formatter.help_position, "", line)
-                           for line in help_lines[1:]])
-        return "".join(result)
-
-    def format_option_help(self, formatter=None):
-        if formatter is None:
-            formatter = self.formatter
-        formatter.store_option_strings(self)
-        result = []
-        if self.arg_help:
-            result.append(formatter.format_heading(_("Arguments")))
-            formatter.indent()
-            result.append(self.format_arg_help(formatter))
-            result.append("\n")
-            result.append("*** Use vmbuilder <hypervisor> <distro> --help to get more options. Hypervisor, distro, and plugins specific help is only available when the first two arguments are supplied.\n")
-            result.append("\n")
-            formatter.dedent()
-        result.append(formatter.format_heading(_("Options")))
-        formatter.indent()
-        if self.option_list:
-            result.append(optparse.OptionContainer.format_option_help(self, formatter))
-            result.append("\n")
-        for group in self.option_groups:
-            result.append(group.format_help(formatter))
-            result.append("\n")
-        formatter.dedent()
-        # Drop the last "\n", or the header if no options or option groups:
-        return "".join(result[:-1])
-

-- 
Tool for creating VM images.



More information about the Pkg-escience-soc2009 mailing list