def install_os(self): self.nics = [self.NIC()] self.call_hooks('preflight_check') self.call_hooks('configure_networking', self.nics) self.call_hooks('configure_mounting', self.disks, self.filesystems) self.chroot_dir = tmpdir() self.call_hooks('mount_partitions', self.chroot_dir) run_cmd('rsync', '-aHA', '%s/' % self.distro.chroot_dir, self.chroot_dir) self.distro.set_chroot_dir(self.chroot_dir) if self.needs_bootloader: self.call_hooks('install_bootloader', self.chroot_dir, self.disks) self.call_hooks('install_kernel', self.chroot_dir) self.distro.call_hooks('post_install') self.call_hooks('unmount_partitions') os.rmdir(self.chroot_dir)
def main(self): tmpfs_mount_point = None try: optparser = optparse.OptionParser() self.set_usage(optparser) optparser.add_option('--version', action='callback', callback=self.versioninfo, help='Show version information') group = optparse.OptionGroup(optparser, 'Build options') group.add_option('--debug', action='callback', callback=self.set_verbosity, help='Show debug information') group.add_option('--verbose', '-v', action='callback', callback=self.set_verbosity, help='Show progress information') group.add_option('--quiet', '-q', action='callback', callback=self.set_verbosity, help='Silent operation') group.add_option( '--overwrite', '-o', action='store_true', help='Remove destination directory before starting build') group.add_option('--config', '-c', type='str', help='Configuration file') group.add_option('--templates', metavar='DIR', help='Prepend DIR to template search path.') group.add_option('--destdir', '-d', type='str', help='Destination directory') group.add_option('--only-chroot', action='store_true', help=("Only build the chroot. Don't install it " "on disk images or anything.")) group.add_option('--chroot-dir', help="Build the chroot in directory.") group.add_option('--existing-chroot', help="Use existing chroot.") group.add_option('--tmp', '-t', metavar='DIR', dest='tmp_root', default=tempfile.gettempdir(), help=('Use TMP as temporary working space for ' 'image generation. Defaults to $TMPDIR if ' 'it is defined or /tmp otherwise. ' '[default: %default]')) group.add_option('--tmpfs', metavar="SIZE", help=('Use a tmpfs as the working directory, ' 'specifying its size or "-" to use tmpfs ' 'default (suid,dev,size=1G).')) group.add_option( '--skip-hook', metavar="HOOK", type='str', action='append', dest='skipped_hooks', default=[], help=('Skip calling this hook. Use this only if you ' 'know what you are doing. Disabling hooks will' 'mostly result in an unstable or not bootable' 'system. Can be specified multiple times to' 'disable multiple hooks')) optparser.add_option_group(group) group = optparse.OptionGroup(optparser, 'Disk') group.add_option('--rootsize', metavar='SIZE', default=4096, help=('Size (in MB) of the root filesystem ' '[default: %default]')) group.add_option( '--optsize', metavar='SIZE', default=0, help=('Size (in MB) of the /opt filesystem. If not' ' set, no /opt filesystem will be added.')) group.add_option('--swapsize', metavar='SIZE', default=1024, help=('Size (in MB) of the swap partition ' '[default: %default]')) group.add_option( '--raw', metavar='PATH', type='str', action='append', help=("Specify a file (or block device) to use as " "first disk image (can be specified multiple" " times).")) group.add_option( '--part', metavar='PATH', type='str', help=("Specify a partition table in PATH. Each " "line of partfile should specify (root " "first): \n mountpoint size \none per " "line, separated by space, where size is " "in megabytes. You can have up to 4 " "virtual disks, a new disk starts on a " "line containing only '---'. ie: \n root " "2000 \n /boot 512 \n swap 1000 \n " "--- \n /var 8000 \n /var/log 2000" "Insert \"diskpartition\" line as partition " "to adisk to use this disk as one partition " "and don't create partition table and MBR")) optparser.add_option_group(group) optparser.disable_interspersed_args() (dummy, args) = optparser.parse_args(sys.argv[1:]) optparser.enable_interspersed_args() hypervisor, distro = self.handle_args(optparser, args) self.add_settings_from_context(optparser, distro) self.add_settings_from_context(optparser, hypervisor) hypervisor.register_hook('fix_ownership', self.fix_ownership) config_files = [ '/etc/vmbuilder.cfg', os.path.expanduser('~/.vmbuilder.cfg') ] (self.options, args) = optparser.parse_args(sys.argv[2:]) if os.geteuid() != 0: raise VMBuilderUserError('Must run as root') hypervisor.set_skipped_hooks(self.options.skipped_hooks) distro.set_skipped_hooks(self.options.skipped_hooks) logging.debug("Launch directory: {}".format(os.getcwd())) distro.overwrite = hypervisor.overwrite = self.options.overwrite destdir = self.options.destdir or ('%s-%s' % (distro.arg, hypervisor.arg)) logging.debug("Output destdir: {}".format(destdir)) if self.options.tmpfs and self.options.chroot_dir: raise VMBuilderUserError( '--chroot-dir and --tmpfs can not be used together.') if os.path.exists(destdir): if os.path.realpath(destdir) == os.getcwd(): raise VMBuilderUserError( 'Current working directory cannot be used as a destination directory' ) if self.options.overwrite: logging.debug('%s existed, but -o was specified. ' 'Nuking it.' % destdir) shutil.rmtree(destdir) else: raise VMBuilderUserError('%s already exists' % destdir) if self.options.config: config_files.append(self.options.config) util.apply_config_files_to_context(config_files, distro) util.apply_config_files_to_context(config_files, hypervisor) if self.options.templates: distro.template_dirs.insert(0, '%s/%%s' % self.options.templates) hypervisor.template_dirs.insert( 0, '%s/%%s' % self.options.templates) for option in dir(self.options): if option.startswith('_') or option in [ 'ensure_value', 'read_module', 'read_file' ]: continue val = getattr(self.options, option) option = option.replace('_', '-') if val: if (distro.has_setting(option) and distro.get_setting_default(option) != val): distro.set_setting_fuzzy(option, val) elif (hypervisor.has_setting(option) and hypervisor.get_setting_default(option) != val): hypervisor.set_setting_fuzzy(option, val) chroot_dir = None if self.options.existing_chroot: distro.set_chroot_dir(self.options.existing_chroot) distro.call_hooks('preflight_check') else: if self.options.tmpfs is not None: if str(self.options.tmpfs) == '-': tmpfs_size = 1024 else: tmpfs_size = int(self.options.tmpfs) tmpfs_mount_point = util.set_up_tmpfs( tmp_root=self.options.tmp_root, size=tmpfs_size) chroot_dir = tmpfs_mount_point elif self.options.chroot_dir: os.mkdir(self.options.chroot_dir) chroot_dir = self.options.chroot_dir else: chroot_dir = util.tmpdir(tmp_root=self.options.tmp_root) distro.set_chroot_dir(chroot_dir) distro.build_chroot() if self.options.only_chroot: print 'Chroot can be found in %s' % distro.chroot_dir sys.exit(0) self.set_disk_layout(optparser, hypervisor) hypervisor.install_os() os.mkdir(destdir) self.fix_ownership(destdir) hypervisor.finalise(destdir) # If chroot_dir is not None, it means we created it, # and if we reach here, it means the user didn't pass # --only-chroot. Hence, we need to remove it to clean # up after ourselves. if chroot_dir is not None and tmpfs_mount_point is None: util.run_cmd('rm', '-rf', '--one-file-system', chroot_dir) except VMBuilderException, e: logging.error(e) raise
def main(self): tmpfs_mount_point = None try: optparser = optparse.OptionParser() self.set_usage(optparser) optparser.add_option('--version', action='callback', callback=self.versioninfo, help='Show version information') group = optparse.OptionGroup(optparser, 'Build options') group.add_option('--debug', action='callback', callback=self.set_verbosity, help='Show debug information') group.add_option('--verbose', '-v', action='callback', callback=self.set_verbosity, help='Show progress information') group.add_option('--quiet', '-q', action='callback', callback=self.set_verbosity, help='Silent operation') group.add_option('--overwrite', '-o', action='store_true', help='Remove destination directory before starting build') group.add_option('--config', '-c', type='str', help='Configuration file') group.add_option('--templates', metavar='DIR', help='Prepend DIR to template search path.') group.add_option('--destdir', '-d', type='str', help='Destination directory') group.add_option('--only-chroot', action='store_true', help=("Only build the chroot. Don't install it " "on disk images or anything.")) group.add_option('--chroot-dir', help="Build the chroot in directory.") group.add_option('--existing-chroot', help="Use existing chroot.") group.add_option('--tmp', '-t', metavar='DIR', dest='tmp_root', default=tempfile.gettempdir(), help=('Use TMP as temporary working space for ' 'image generation. Defaults to $TMPDIR if ' 'it is defined or /tmp otherwise. ' '[default: %default]')) group.add_option('--tmpfs', metavar="SIZE", help=('Use a tmpfs as the working directory, ' 'specifying its size or "-" to use tmpfs ' 'default (suid,dev,size=1G).')) group.add_option('--skip-hook', metavar="HOOK", type='str', action='append', dest='skipped_hooks', default=[], help=('Skip calling this hook. Use this only if you ' 'know what you are doing. Disabling hooks will' 'mostly result in an unstable or not bootable' 'system. Can be specified multiple times to' 'disable multiple hooks')) optparser.add_option_group(group) group = optparse.OptionGroup(optparser, 'Disk') group.add_option('--rootsize', metavar='SIZE', default=4096, help=('Size (in MB) of the root filesystem ' '[default: %default]')) group.add_option('--optsize', metavar='SIZE', default=0, help=('Size (in MB) of the /opt filesystem. If not' ' set, no /opt filesystem will be added.')) group.add_option('--swapsize', metavar='SIZE', default=1024, help=('Size (in MB) of the swap partition ' '[default: %default]')) group.add_option('--raw', metavar='PATH', type='str', action='append', help=("Specify a file (or block device) to use as " "first disk image (can be specified multiple" " times).")) group.add_option('--part', metavar='PATH', type='str', help=("Specify a partition table in PATH. Each " "line of partfile should specify (root " "first): \n mountpoint size \none per " "line, separated by space, where size is " "in megabytes. You can have up to 4 " "virtual disks, a new disk starts on a " "line containing only '---'. ie: \n root " "2000 \n /boot 512 \n swap 1000 \n " "--- \n /var 8000 \n /var/log 2000" "Insert \"diskpartition\" line as partition " "to adisk to use this disk as one partition " "and don't create partition table and MBR")) optparser.add_option_group(group) optparser.disable_interspersed_args() (dummy, args) = optparser.parse_args(sys.argv[1:]) optparser.enable_interspersed_args() hypervisor, distro = self.handle_args(optparser, args) self.add_settings_from_context(optparser, distro) self.add_settings_from_context(optparser, hypervisor) hypervisor.register_hook('fix_ownership', self.fix_ownership) config_files = ['/etc/vmbuilder.cfg', os.path.expanduser('~/.vmbuilder.cfg')] (self.options, args) = optparser.parse_args(sys.argv[2:]) if os.geteuid() != 0: raise VMBuilderUserError('Must run as root') hypervisor.set_skipped_hooks(self.options.skipped_hooks) distro.set_skipped_hooks(self.options.skipped_hooks) logging.debug("Launch directory: {}".format(os.getcwd())) distro.overwrite = hypervisor.overwrite = self.options.overwrite destdir = self.options.destdir or ('%s-%s' % (distro.arg, hypervisor.arg)) logging.debug("Output destdir: {}".format(destdir)) if self.options.tmpfs and self.options.chroot_dir: raise VMBuilderUserError('--chroot-dir and --tmpfs can not be used together.') if os.path.exists(destdir): if os.path.realpath(destdir) == os.getcwd(): raise VMBuilderUserError('Current working directory cannot be used as a destination directory') if self.options.overwrite: logging.debug('%s existed, but -o was specified. ' 'Nuking it.' % destdir) shutil.rmtree(destdir) else: raise VMBuilderUserError('%s already exists' % destdir) if self.options.config: config_files.append(self.options.config) util.apply_config_files_to_context(config_files, distro) util.apply_config_files_to_context(config_files, hypervisor) if self.options.templates: distro.template_dirs.insert(0, '%s/%%s' % self.options.templates) hypervisor.template_dirs.insert(0, '%s/%%s' % self.options.templates) for option in dir(self.options): if option.startswith('_') or option in ['ensure_value', 'read_module', 'read_file']: continue val = getattr(self.options, option) option = option.replace('_', '-') if val: if (distro.has_setting(option) and distro.get_setting_default(option) != val): distro.set_setting_fuzzy(option, val) elif (hypervisor.has_setting(option) and hypervisor.get_setting_default(option) != val): hypervisor.set_setting_fuzzy(option, val) chroot_dir = None if self.options.existing_chroot: distro.set_chroot_dir(self.options.existing_chroot) distro.call_hooks('preflight_check') else: if self.options.tmpfs is not None: if str(self.options.tmpfs) == '-': tmpfs_size = 1024 else: tmpfs_size = int(self.options.tmpfs) tmpfs_mount_point = util.set_up_tmpfs( tmp_root=self.options.tmp_root, size=tmpfs_size) chroot_dir = tmpfs_mount_point elif self.options.chroot_dir: os.mkdir(self.options.chroot_dir) chroot_dir = self.options.chroot_dir else: chroot_dir = util.tmpdir(tmp_root=self.options.tmp_root) distro.set_chroot_dir(chroot_dir) distro.build_chroot() if self.options.only_chroot: print 'Chroot can be found in %s' % distro.chroot_dir sys.exit(0) self.set_disk_layout(optparser, hypervisor) hypervisor.install_os() os.mkdir(destdir) self.fix_ownership(destdir) hypervisor.finalise(destdir) # If chroot_dir is not None, it means we created it, # and if we reach here, it means the user didn't pass # --only-chroot. Hence, we need to remove it to clean # up after ourselves. if chroot_dir is not None and tmpfs_mount_point is None: util.run_cmd('rm', '-rf', '--one-file-system', chroot_dir) except VMBuilderException, e: logging.error(e) raise
def main(self): tmpfs_mount_point = None try: optparser = optparse.OptionParser() self.set_usage(optparser) optparser.add_option( "--version", action="callback", callback=self.versioninfo, help="Show version information" ) group = optparse.OptionGroup(optparser, "Build options") group.add_option("--debug", action="callback", callback=self.set_verbosity, help="Show debug information") group.add_option( "--verbose", "-v", action="callback", callback=self.set_verbosity, help="Show progress information" ) group.add_option("--quiet", "-q", action="callback", callback=self.set_verbosity, help="Silent operation") group.add_option("--overwrite", "-o", action="store_true", help="Configuration file") group.add_option("--config", "-c", type="str", help="Configuration file") group.add_option("--templates", metavar="DIR", help="Prepend DIR to template search path.") group.add_option("--destdir", "-d", type="str", help="Destination directory") group.add_option( "--only-chroot", action="store_true", help=("Only build the chroot. Don't install it " "on disk images or anything."), ) group.add_option("--chroot-dir", help="Build the chroot in directory.") group.add_option("--existing-chroot", help="Use existing chroot.") group.add_option( "--tmp", "-t", metavar="DIR", dest="tmp_root", default=tempfile.gettempdir(), help=( "Use TMP as temporary working space for " "image generation. Defaults to $TMPDIR if " "it is defined or /tmp otherwise. " "[default: %default]" ), ) group.add_option( "--tmpfs", metavar="SIZE", help=( "Use a tmpfs as the working directory, " 'specifying its size or "-" to use tmpfs ' "default (suid,dev,size=1G)." ), ) optparser.add_option_group(group) group = optparse.OptionGroup(optparser, "Disk") group.add_option( "--rootsize", metavar="SIZE", default=4096, help=("Size (in MB) of the root filesystem " "[default: %default]"), ) group.add_option( "--optsize", metavar="SIZE", default=0, help=("Size (in MB) of the /opt filesystem. If not" " set, no /opt filesystem will be added."), ) group.add_option( "--swapsize", metavar="SIZE", default=1024, help=("Size (in MB) of the swap partition " "[default: %default]"), ) group.add_option( "--raw", metavar="PATH", type="str", action="append", help=( "Specify a file (or block device) to use as " "first disk image (can be specified multiple" " times)." ), ) group.add_option( "--part", metavar="PATH", type="str", help=( "Specify a partition table in PATH. Each " "line of partfile should specify (root " "first): \n mountpoint size \none per " "line, separated by space, where size is " "in megabytes. You can have up to 4 " "virtual disks, a new disk starts on a " "line containing only '---'. ie: \n root " "2000 \n /boot 512 \n swap 1000 \n " "--- \n /var 8000 \n /var/log 2000" ), ) optparser.add_option_group(group) optparser.disable_interspersed_args() (dummy, args) = optparser.parse_args(sys.argv[1:]) optparser.enable_interspersed_args() hypervisor, distro = self.handle_args(optparser, args) self.add_settings_from_context(optparser, distro) self.add_settings_from_context(optparser, hypervisor) hypervisor.register_hook("fix_ownership", self.fix_ownership) config_files = ["/etc/vmbuilder.cfg", os.path.expanduser("~/.vmbuilder.cfg")] (self.options, args) = optparser.parse_args(sys.argv[2:]) if os.geteuid() != 0: raise VMBuilderUserError("Must run as root") distro.overwrite = hypervisor.overwrite = self.options.overwrite destdir = self.options.destdir or ("%s-%s" % (distro.arg, hypervisor.arg)) if self.options.tmpfs and self.options.chroot_dir: raise VMBuilderUserError("--chroot-dir and --tmpfs can not be used together.") if os.path.exists(destdir): if self.options.overwrite: logging.debug("%s existed, but -o was specified. " "Nuking it." % destdir) shutil.rmtree(destdir) else: raise VMBuilderUserError("%s already exists" % destdir) if self.options.config: config_files.append(self.options.config) util.apply_config_files_to_context(config_files, distro) util.apply_config_files_to_context(config_files, hypervisor) if self.options.templates: distro.template_dirs.insert(0, "%s/%%s" % self.options.templates) hypervisor.template_dirs.insert(0, "%s/%%s" % self.options.templates) for option in dir(self.options): if option.startswith("_") or option in ["ensure_value", "read_module", "read_file"]: continue val = getattr(self.options, option) option = option.replace("_", "-") if val: if distro.has_setting(option) and distro.get_setting_default(option) != val: distro.set_setting_fuzzy(option, val) elif hypervisor.has_setting(option) and hypervisor.get_setting_default(option) != val: hypervisor.set_setting_fuzzy(option, val) chroot_dir = None if self.options.existing_chroot: distro.set_chroot_dir(self.options.existing_chroot) distro.call_hooks("preflight_check") else: if self.options.tmpfs is not None: if str(self.options.tmpfs) == "-": tmpfs_size = 1024 else: tmpfs_size = int(self.options.tmpfs) tmpfs_mount_point = util.set_up_tmpfs(tmp_root=self.options.tmp_root, size=tmpfs_size) chroot_dir = tmpfs_mount_point elif self.options.chroot_dir: os.mkdir(self.options.chroot_dir) chroot_dir = self.options.chroot_dir else: chroot_dir = util.tmpdir(tmp_root=self.options.tmp_root) distro.set_chroot_dir(chroot_dir) distro.build_chroot() if self.options.only_chroot: print "Chroot can be found in %s" % distro.chroot_dir sys.exit(0) self.set_disk_layout(optparser, hypervisor) hypervisor.install_os() os.mkdir(destdir) self.fix_ownership(destdir) hypervisor.finalise(destdir) # If chroot_dir is not None, it means we created it, # and if we reach here, it means the user didn't pass # --only-chroot. Hence, we need to remove it to clean # up after ourselves. if chroot_dir is not None and tmpfs_mount_point is None: util.run_cmd("rm", "-rf", "--one-file-system", chroot_dir) except VMBuilderException, e: logging.error(e) raise