From d73230306b827972cdc99f21d247c54d5d7c0b6d Mon Sep 17 00:00:00 2001 From: Tom Zanussi Date: Sun, 3 Aug 2014 12:14:16 -0500 Subject: wic: Remove mic chroot mic chroot allows users to chroot into an existing mic image and isn't used by wic, so remove it. Removing chroot.py leads in turn to various plugin-loading failures for a number of plugins that wic doesn't use either, so remove those as well. The existing source plugins refer to chroot but don't use it, so fix those up. Signed-off-by: Tom Zanussi --- scripts/lib/mic/chroot.py | 343 ----------- scripts/lib/mic/imager/fs.py | 99 --- scripts/lib/mic/imager/livecd.py | 750 ----------------------- scripts/lib/mic/imager/liveusb.py | 308 ---------- scripts/lib/mic/imager/loop.py | 418 ------------- scripts/lib/mic/imager/raw.py | 501 --------------- scripts/lib/mic/plugins/imager/direct_plugin.py | 2 +- scripts/lib/mic/plugins/imager/fs_plugin.py | 143 ----- scripts/lib/mic/plugins/imager/livecd_plugin.py | 255 -------- scripts/lib/mic/plugins/imager/liveusb_plugin.py | 260 -------- scripts/lib/mic/plugins/imager/loop_plugin.py | 255 -------- scripts/lib/mic/plugins/imager/raw_plugin.py | 275 --------- scripts/lib/mic/plugins/source/bootimg-efi.py | 2 +- scripts/lib/mic/plugins/source/bootimg-pcbios.py | 2 +- scripts/lib/mic/plugins/source/rootfs.py | 2 +- 15 files changed, 4 insertions(+), 3611 deletions(-) delete mode 100644 scripts/lib/mic/chroot.py delete mode 100644 scripts/lib/mic/imager/fs.py delete mode 100644 scripts/lib/mic/imager/livecd.py delete mode 100644 scripts/lib/mic/imager/liveusb.py delete mode 100644 scripts/lib/mic/imager/loop.py delete mode 100644 scripts/lib/mic/imager/raw.py delete mode 100644 scripts/lib/mic/plugins/imager/fs_plugin.py delete mode 100644 scripts/lib/mic/plugins/imager/livecd_plugin.py delete mode 100644 scripts/lib/mic/plugins/imager/liveusb_plugin.py delete mode 100644 scripts/lib/mic/plugins/imager/loop_plugin.py delete mode 100644 scripts/lib/mic/plugins/imager/raw_plugin.py (limited to 'scripts/lib/mic') diff --git a/scripts/lib/mic/chroot.py b/scripts/lib/mic/chroot.py deleted file mode 100644 index 99fb9a2c17..0000000000 --- a/scripts/lib/mic/chroot.py +++ /dev/null @@ -1,343 +0,0 @@ -#!/usr/bin/python -tt -# -# Copyright (c) 2009, 2010, 2011 Intel, Inc. -# -# 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; version 2 of the License -# -# 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, write to the Free Software Foundation, Inc., 59 -# Temple Place - Suite 330, Boston, MA 02111-1307, USA. - -from __future__ import with_statement -import os -import shutil -import subprocess - -from mic import msger -from mic.conf import configmgr -from mic.utils import misc, errors, runner, fs_related - -chroot_lockfd = -1 -chroot_lock = "" -BIND_MOUNTS = ( - "/proc", - "/proc/sys/fs/binfmt_misc", - "/sys", - "/dev", - "/dev/pts", - "/dev/shm", - "/var/lib/dbus", - "/var/run/dbus", - "/var/lock", - ) - -def cleanup_after_chroot(targettype,imgmount,tmpdir,tmpmnt): - if imgmount and targettype == "img": - imgmount.cleanup() - - if tmpdir: - shutil.rmtree(tmpdir, ignore_errors = True) - - if tmpmnt: - shutil.rmtree(tmpmnt, ignore_errors = True) - -def check_bind_mounts(chrootdir, bindmounts): - chrootmounts = [] - for mount in bindmounts.split(";"): - if not mount: - continue - - srcdst = mount.split(":") - if len(srcdst) == 1: - srcdst.append("none") - - if not os.path.isdir(srcdst[0]): - return False - - if srcdst[1] == "" or srcdst[1] == "none": - srcdst[1] = None - - if srcdst[0] in BIND_MOUNTS or srcdst[0] == '/': - continue - - if chrootdir: - if not srcdst[1]: - srcdst[1] = os.path.abspath(os.path.expanduser(srcdst[0])) - else: - srcdst[1] = os.path.abspath(os.path.expanduser(srcdst[1])) - - tmpdir = chrootdir + "/" + srcdst[1] - if os.path.isdir(tmpdir): - msger.warning("Warning: dir %s has existed." % tmpdir) - - return True - -def cleanup_mounts(chrootdir): - umountcmd = misc.find_binary_path("umount") - abs_chrootdir = os.path.abspath(chrootdir) - mounts = open('/proc/mounts').readlines() - for line in reversed(mounts): - if abs_chrootdir not in line: - continue - - point = line.split()[1] - - # '/' to avoid common name prefix - if abs_chrootdir == point or point.startswith(abs_chrootdir + '/'): - args = [ umountcmd, "-l", point ] - ret = runner.quiet(args) - if ret != 0: - msger.warning("failed to unmount %s" % point) - - return 0 - -def setup_chrootenv(chrootdir, bindmounts = None, mountparent = True): - global chroot_lockfd, chroot_lock - - def get_bind_mounts(chrootdir, bindmounts, mountparent = True): - chrootmounts = [] - if bindmounts in ("", None): - bindmounts = "" - - for mount in bindmounts.split(";"): - if not mount: - continue - - srcdst = mount.split(":") - srcdst[0] = os.path.abspath(os.path.expanduser(srcdst[0])) - if len(srcdst) == 1: - srcdst.append("none") - - # if some bindmount is not existed, but it's created inside - # chroot, this is not expected - if not os.path.exists(srcdst[0]): - os.makedirs(srcdst[0]) - - if not os.path.isdir(srcdst[0]): - continue - - if srcdst[0] in BIND_MOUNTS or srcdst[0] == '/': - msger.verbose("%s will be mounted by default." % srcdst[0]) - continue - - if srcdst[1] == "" or srcdst[1] == "none": - srcdst[1] = None - else: - srcdst[1] = os.path.abspath(os.path.expanduser(srcdst[1])) - if os.path.isdir(chrootdir + "/" + srcdst[1]): - msger.warning("%s has existed in %s , skip it."\ - % (srcdst[1], chrootdir)) - continue - - chrootmounts.append(fs_related.BindChrootMount(srcdst[0], - chrootdir, - srcdst[1])) - - """Default bind mounts""" - for pt in BIND_MOUNTS: - if not os.path.exists(pt): - continue - chrootmounts.append(fs_related.BindChrootMount(pt, - chrootdir, - None)) - - if mountparent: - chrootmounts.append(fs_related.BindChrootMount("/", - chrootdir, - "/parentroot", - "ro")) - - for kernel in os.listdir("/lib/modules"): - chrootmounts.append(fs_related.BindChrootMount( - "/lib/modules/"+kernel, - chrootdir, - None, - "ro")) - - return chrootmounts - - def bind_mount(chrootmounts): - for b in chrootmounts: - msger.verbose("bind_mount: %s -> %s" % (b.src, b.dest)) - b.mount() - - def setup_resolv(chrootdir): - try: - shutil.copyfile("/etc/resolv.conf", chrootdir + "/etc/resolv.conf") - except: - pass - - globalmounts = get_bind_mounts(chrootdir, bindmounts, mountparent) - bind_mount(globalmounts) - - setup_resolv(chrootdir) - - mtab = "/etc/mtab" - dstmtab = chrootdir + mtab - if not os.path.islink(dstmtab): - shutil.copyfile(mtab, dstmtab) - - chroot_lock = os.path.join(chrootdir, ".chroot.lock") - chroot_lockfd = open(chroot_lock, "w") - - return globalmounts - -def cleanup_chrootenv(chrootdir, bindmounts=None, globalmounts=()): - global chroot_lockfd, chroot_lock - - def bind_unmount(chrootmounts): - for b in reversed(chrootmounts): - msger.verbose("bind_unmount: %s -> %s" % (b.src, b.dest)) - b.unmount() - - def cleanup_resolv(chrootdir): - try: - fd = open(chrootdir + "/etc/resolv.conf", "w") - fd.truncate(0) - fd.close() - except: - pass - - def kill_processes(chrootdir): - import glob - for fp in glob.glob("/proc/*/root"): - try: - if os.readlink(fp) == chrootdir: - pid = int(fp.split("/")[2]) - os.kill(pid, 9) - except: - pass - - def cleanup_mountdir(chrootdir, bindmounts): - if bindmounts == "" or bindmounts == None: - return - chrootmounts = [] - for mount in bindmounts.split(";"): - if not mount: - continue - - srcdst = mount.split(":") - - if len(srcdst) == 1: - srcdst.append("none") - - if srcdst[0] == "/": - continue - - if srcdst[1] == "" or srcdst[1] == "none": - srcdst[1] = srcdst[0] - - srcdst[1] = os.path.abspath(os.path.expanduser(srcdst[1])) - tmpdir = chrootdir + "/" + srcdst[1] - if os.path.isdir(tmpdir): - if len(os.listdir(tmpdir)) == 0: - shutil.rmtree(tmpdir, ignore_errors = True) - else: - msger.warning("Warning: dir %s isn't empty." % tmpdir) - - chroot_lockfd.close() - bind_unmount(globalmounts) - - if not fs_related.my_fuser(chroot_lock): - tmpdir = chrootdir + "/parentroot" - if os.path.exists(tmpdir) and len(os.listdir(tmpdir)) == 0: - shutil.rmtree(tmpdir, ignore_errors = True) - - cleanup_resolv(chrootdir) - - if os.path.exists(chrootdir + "/etc/mtab"): - os.unlink(chrootdir + "/etc/mtab") - - kill_processes(chrootdir) - - cleanup_mountdir(chrootdir, bindmounts) - -def chroot(chrootdir, bindmounts = None, execute = "/bin/bash"): - def mychroot(): - os.chroot(chrootdir) - os.chdir("/") - - if configmgr.chroot['saveto']: - savefs = True - saveto = configmgr.chroot['saveto'] - wrnmsg = "Can't save chroot fs for dir %s exists" % saveto - if saveto == chrootdir: - savefs = False - wrnmsg = "Dir %s is being used to chroot" % saveto - elif os.path.exists(saveto): - if msger.ask("Dir %s already exists, cleanup and continue?" % - saveto): - shutil.rmtree(saveto, ignore_errors = True) - savefs = True - else: - savefs = False - - if savefs: - msger.info("Saving image to directory %s" % saveto) - fs_related.makedirs(os.path.dirname(os.path.abspath(saveto))) - runner.quiet("cp -af %s %s" % (chrootdir, saveto)) - devs = ['dev/fd', - 'dev/stdin', - 'dev/stdout', - 'dev/stderr', - 'etc/mtab'] - ignlst = [os.path.join(saveto, x) for x in devs] - map(os.unlink, filter(os.path.exists, ignlst)) - else: - msger.warning(wrnmsg) - - dev_null = os.open("/dev/null", os.O_WRONLY) - files_to_check = ["/bin/bash", "/sbin/init"] - - architecture_found = False - - """ Register statically-linked qemu-arm if it is an ARM fs """ - qemu_emulator = None - - for ftc in files_to_check: - ftc = "%s/%s" % (chrootdir,ftc) - - # Return code of 'file' is "almost always" 0 based on some man pages - # so we need to check the file existance first. - if not os.path.exists(ftc): - continue - - for line in runner.outs(['file', ftc]).splitlines(): - if 'ARM' in line: - qemu_emulator = misc.setup_qemu_emulator(chrootdir, "arm") - architecture_found = True - break - - if 'Intel' in line: - architecture_found = True - break - - if architecture_found: - break - - os.close(dev_null) - if not architecture_found: - raise errors.CreatorError("Failed to get architecture from any of the " - "following files %s from chroot." \ - % files_to_check) - - try: - msger.info("Launching shell. Exit to continue.\n" - "----------------------------------") - globalmounts = setup_chrootenv(chrootdir, bindmounts) - subprocess.call(execute, preexec_fn = mychroot, shell=True) - - except OSError, err: - raise errors.CreatorError("chroot err: %s" % str(err)) - - finally: - cleanup_chrootenv(chrootdir, bindmounts, globalmounts) - if qemu_emulator: - os.unlink(chrootdir + qemu_emulator) diff --git a/scripts/lib/mic/imager/fs.py b/scripts/lib/mic/imager/fs.py deleted file mode 100644 index d53b29cb47..0000000000 --- a/scripts/lib/mic/imager/fs.py +++ /dev/null @@ -1,99 +0,0 @@ -#!/usr/bin/python -tt -# -# Copyright (c) 2011 Intel, Inc. -# -# 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; version 2 of the License -# -# 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, write to the Free Software Foundation, Inc., 59 -# Temple Place - Suite 330, Boston, MA 02111-1307, USA. - -import os - -from mic import msger -from mic.utils import runner, misc -from mic.utils.errors import CreatorError -from mic.utils.fs_related import find_binary_path -from mic.imager.baseimager import BaseImageCreator - -class FsImageCreator(BaseImageCreator): - def __init__(self, cfgmgr = None, pkgmgr = None): - self.zips = { - "tar.bz2" : "" - } - BaseImageCreator.__init__(self, cfgmgr, pkgmgr) - self._fstype = None - self._fsopts = None - self._include_src = False - - def package(self, destdir = "."): - - ignores = ["/dev/fd", - "/dev/stdin", - "/dev/stdout", - "/dev/stderr", - "/etc/mtab"] - - if not os.path.exists(destdir): - os.makedirs(destdir) - - if self._recording_pkgs: - self._save_recording_pkgs(destdir) - - if not self.pack_to: - fsdir = os.path.join(destdir, self.name) - - misc.check_space_pre_cp(self._instroot, destdir) - msger.info("Copying %s to %s ..." % (self._instroot, fsdir)) - runner.show(['cp', "-af", self._instroot, fsdir]) - - for exclude in ignores: - if os.path.exists(fsdir + exclude): - os.unlink(fsdir + exclude) - - self.outimage.append(fsdir) - - else: - (tar, comp) = os.path.splitext(self.pack_to) - try: - tarcreat = {'.tar': '-cf', - '.gz': '-czf', - '.bz2': '-cjf', - '.tgz': '-czf', - '.tbz': '-cjf'}[comp] - except KeyError: - raise CreatorError("Unsupported comression for this image type:" - " '%s', try '.tar', '.tar.gz', etc" % comp) - - dst = os.path.join(destdir, self.pack_to) - msger.info("Pack rootfs to %s. Please wait..." % dst) - - tar = find_binary_path('tar') - tar_cmdline = [tar, "--numeric-owner", - "--preserve-permissions", - "--preserve-order", - "--one-file-system", - "--directory", - self._instroot] - for ignore_entry in ignores: - if ignore_entry.startswith('/'): - ignore_entry = ignore_entry[1:] - - tar_cmdline.append("--exclude=%s" % (ignore_entry)) - - tar_cmdline.extend([tarcreat, dst, "."]) - - rc = runner.show(tar_cmdline) - if rc: - raise CreatorError("Failed compress image with tar.bz2. " - "Cmdline: %s" % (" ".join(tar_cmdline))) - - self.outimage.append(dst) - diff --git a/scripts/lib/mic/imager/livecd.py b/scripts/lib/mic/imager/livecd.py deleted file mode 100644 index e36f4a76c6..0000000000 --- a/scripts/lib/mic/imager/livecd.py +++ /dev/null @@ -1,750 +0,0 @@ -#!/usr/bin/python -tt -# -# Copyright (c) 2011 Intel, Inc. -# -# 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; version 2 of the License -# -# 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, write to the Free Software Foundation, Inc., 59 -# Temple Place - Suite 330, Boston, MA 02111-1307, USA. - -import os, sys -import glob -import shutil - -from mic import kickstart, msger -from mic.utils import fs_related, runner, misc -from mic.utils.errors import CreatorError -from mic.imager.loop import LoopImageCreator - - -class LiveImageCreatorBase(LoopImageCreator): - """A base class for LiveCD image creators. - - This class serves as a base class for the architecture-specific LiveCD - image creator subclass, LiveImageCreator. - - LiveImageCreator creates a bootable ISO containing the system image, - bootloader, bootloader configuration, kernel and initramfs. - """ - - def __init__(self, creatoropts = None, pkgmgr = None): - """Initialise a LiveImageCreator instance. - - This method takes the same arguments as ImageCreator.__init__(). - """ - LoopImageCreator.__init__(self, creatoropts, pkgmgr) - - #Controls whether to use squashfs to compress the image. - self.skip_compression = False - - #Controls whether an image minimizing snapshot should be created. - # - #This snapshot can be used when copying the system image from the ISO in - #order to minimize the amount of data that needs to be copied; simply, - #it makes it possible to create a version of the image's filesystem with - #no spare space. - self.skip_minimize = False - - #A flag which indicates i act as a convertor default false - self.actasconvertor = False - - #The bootloader timeout from kickstart. - if self.ks: - self._timeout = kickstart.get_timeout(self.ks, 10) - else: - self._timeout = 10 - - #The default kernel type from kickstart. - if self.ks: - self._default_kernel = kickstart.get_default_kernel(self.ks, - "kernel") - else: - self._default_kernel = None - - if self.ks: - parts = kickstart.get_partitions(self.ks) - if len(parts) > 1: - raise CreatorError("Can't support multi partitions in ks file " - "for this image type") - # FIXME: rename rootfs img to self.name, - # else can't find files when create iso - self._instloops[0]['name'] = self.name + ".img" - - self.__isodir = None - - self.__modules = ["=ata", - "sym53c8xx", - "aic7xxx", - "=usb", - "=firewire", - "=mmc", - "=pcmcia", - "mptsas"] - if self.ks: - self.__modules.extend(kickstart.get_modules(self.ks)) - - self._dep_checks.extend(["isohybrid", - "unsquashfs", - "mksquashfs", - "dd", - "genisoimage"]) - - # - # Hooks for subclasses - # - def _configure_bootloader(self, isodir): - """Create the architecture specific booloader configuration. - - This is the hook where subclasses must create the booloader - configuration in order to allow a bootable ISO to be built. - - isodir -- the directory where the contents of the ISO are to - be staged - """ - raise CreatorError("Bootloader configuration is arch-specific, " - "but not implemented for this arch!") - def _get_menu_options(self): - """Return a menu options string for syslinux configuration. - """ - if self.ks is None: - return "liveinst autoinst" - r = kickstart.get_menu_args(self.ks) - return r - - def _get_kernel_options(self): - """Return a kernel options string for bootloader configuration. - - This is the hook where subclasses may specify a set of kernel - options which should be included in the images bootloader - configuration. - - A sensible default implementation is provided. - """ - - if self.ks is None: - r = "ro rd.live.image" - else: - r = kickstart.get_kernel_args(self.ks) - - return r - - def _get_mkisofs_options(self, isodir): - """Return the architecture specific mkisosfs options. - - This is the hook where subclasses may specify additional arguments - to mkisofs, e.g. to enable a bootable ISO to be built. - - By default, an empty list is returned. - """ - return [] - - # - # Helpers for subclasses - # - def _has_checkisomd5(self): - """Check whether checkisomd5 is available in the install root.""" - def _exists(path): - return os.path.exists(self._instroot + path) - - if _exists("/usr/bin/checkisomd5") and os.path.exists("/usr/bin/implantisomd5"): - return True - - return False - - def __restore_file(self,path): - try: - os.unlink(path) - except: - pass - if os.path.exists(path + '.rpmnew'): - os.rename(path + '.rpmnew', path) - - def _mount_instroot(self, base_on = None): - LoopImageCreator._mount_instroot(self, base_on) - self.__write_initrd_conf(self._instroot + "/etc/sysconfig/mkinitrd") - self.__write_dracut_conf(self._instroot + "/etc/dracut.conf.d/02livecd.conf") - - def _unmount_instroot(self): - self.__restore_file(self._instroot + "/etc/sysconfig/mkinitrd") - self.__restore_file(self._instroot + "/etc/dracut.conf.d/02livecd.conf") - LoopImageCreator._unmount_instroot(self) - - def __ensure_isodir(self): - if self.__isodir is None: - self.__isodir = self._mkdtemp("iso-") - return self.__isodir - - def _get_isodir(self): - return self.__ensure_isodir() - - def _set_isodir(self, isodir = None): - self.__isodir = isodir - - def _create_bootconfig(self): - """Configure the image so that it's bootable.""" - self._configure_bootloader(self.__ensure_isodir()) - - def _get_post_scripts_env(self, in_chroot): - env = LoopImageCreator._get_post_scripts_env(self, in_chroot) - - if not in_chroot: - env["LIVE_ROOT"] = self.__ensure_isodir() - - return env - def __write_dracut_conf(self, path): - if not os.path.exists(os.path.dirname(path)): - fs_related.makedirs(os.path.dirname(path)) - f = open(path, "a") - f.write('add_dracutmodules+=" dmsquash-live pollcdrom "') - f.close() - - def __write_initrd_conf(self, path): - content = "" - if not os.path.exists(os.path.dirname(path)): - fs_related.makedirs(os.path.dirname(path)) - f = open(path, "w") - - content += 'LIVEOS="yes"\n' - content += 'PROBE="no"\n' - content += 'MODULES+="squashfs ext3 ext2 vfat msdos "\n' - content += 'MODULES+="sr_mod sd_mod ide-cd cdrom "\n' - - for module in self.__modules: - if module == "=usb": - content += 'MODULES+="ehci_hcd uhci_hcd ohci_hcd "\n' - content += 'MODULES+="usb_storage usbhid "\n' - elif module == "=firewire": - content += 'MODULES+="firewire-sbp2 firewire-ohci "\n' - content += 'MODULES+="sbp2 ohci1394 ieee1394 "\n' - elif module == "=mmc": - content += 'MODULES+="mmc_block sdhci sdhci-pci "\n' - elif module == "=pcmcia": - content += 'MODULES+="pata_pcmcia "\n' - else: - content += 'MODULES+="' + module + ' "\n' - f.write(content) - f.close() - - def __create_iso(self, isodir): - iso = self._outdir + "/" + self.name + ".iso" - genisoimage = fs_related.find_binary_path("genisoimage") - args = [genisoimage, - "-J", "-r", - "-hide-rr-moved", "-hide-joliet-trans-tbl", - "-V", self.fslabel, - "-o", iso] - - args.extend(self._get_mkisofs_options(isodir)) - - args.append(isodir) - - if runner.show(args) != 0: - raise CreatorError("ISO creation failed!") - - """ It should be ok still even if you haven't isohybrid """ - isohybrid = None - try: - isohybrid = fs_related.find_binary_path("isohybrid") - except: - pass - - if isohybrid: - args = [isohybrid, "-partok", iso ] - if runner.show(args) != 0: - raise CreatorError("Hybrid ISO creation failed!") - - self.__implant_md5sum(iso) - - def __implant_md5sum(self, iso): - """Implant an isomd5sum.""" - if os.path.exists("/usr/bin/implantisomd5"): - implantisomd5 = "/usr/bin/implantisomd5" - else: - msger.warning("isomd5sum not installed; not setting up mediacheck") - implantisomd5 = "" - return - - runner.show([implantisomd5, iso]) - - def _stage_final_image(self): - try: - fs_related.makedirs(self.__ensure_isodir() + "/LiveOS") - - minimal_size = self._resparse() - - if not self.skip_minimize: - fs_related.create_image_minimizer(self.__isodir + \ - "/LiveOS/osmin.img", - self._image, - minimal_size) - - if self.skip_compression: - shutil.move(self._image, self.__isodir + "/LiveOS/ext3fs.img") - else: - fs_related.makedirs(os.path.join( - os.path.dirname(self._image), - "LiveOS")) - shutil.move(self._image, - os.path.join(os.path.dirname(self._image), - "LiveOS", "ext3fs.img")) - fs_related.mksquashfs(os.path.dirname(self._image), - self.__isodir + "/LiveOS/squashfs.img") - - self.__create_iso(self.__isodir) - - if self.pack_to: - isoimg = os.path.join(self._outdir, self.name + ".iso") - packimg = os.path.join(self._outdir, self.pack_to) - misc.packing(packimg, isoimg) - os.unlink(isoimg) - - finally: - shutil.rmtree(self.__isodir, ignore_errors = True) - self.__isodir = None - -class x86LiveImageCreator(LiveImageCreatorBase): - """ImageCreator for x86 machines""" - def _get_mkisofs_options(self, isodir): - return [ "-b", "isolinux/isolinux.bin", - "-c", "isolinux/boot.cat", - "-no-emul-boot", "-boot-info-table", - "-boot-load-size", "4" ] - - def _get_required_packages(self): - return ["syslinux", "syslinux-extlinux"] + \ - LiveImageCreatorBase._get_required_packages(self) - - def _get_isolinux_stanzas(self, isodir): - return "" - - def __find_syslinux_menu(self): - for menu in ["vesamenu.c32", "menu.c32"]: - if os.path.isfile(self._instroot + "/usr/share/syslinux/" + menu): - return menu - - raise CreatorError("syslinux not installed : " - "no suitable /usr/share/syslinux/*menu.c32 found") - - def __find_syslinux_mboot(self): - # - # We only need the mboot module if we have any xen hypervisors - # - if not glob.glob(self._instroot + "/boot/xen.gz*"): - return None - - return "mboot.c32" - - def __copy_syslinux_files(self, isodir, menu, mboot = None): - files = ["isolinux.bin", menu] - if mboot: - files += [mboot] - - for f in files: - path = self._instroot + "/usr/share/syslinux/" + f - - if not os.path.isfile(path): - raise CreatorError("syslinux not installed : " - "%s not found" % path) - - shutil.copy(path, isodir + "/isolinux/") - - def __copy_syslinux_background(self, isodest): - background_path = self._instroot + \ - "/usr/share/branding/default/syslinux/syslinux-vesa-splash.jpg" - - if not os.path.exists(background_path): - return False - - shutil.copyfile(background_path, isodest) - - return True - - def __copy_kernel_and_initramfs(self, isodir, version, index): - bootdir = self._instroot + "/boot" - isDracut = False - - if self._alt_initrd_name: - src_initrd_path = os.path.join(bootdir, self._alt_initrd_name) - else: - if os.path.exists(bootdir + "/initramfs-" + version + ".img"): - src_initrd_path = os.path.join(bootdir, "initramfs-" +version+ ".img") - isDracut = True - else: - src_initrd_path = os.path.join(bootdir, "initrd-" +version+ ".img") - - try: - msger.debug("copy %s to %s" % (bootdir + "/vmlinuz-" + version, isodir + "/isolinux/vmlinuz" + index)) - shutil.copyfile(bootdir + "/vmlinuz-" + version, - isodir + "/isolinux/vmlinuz" + index) - - msger.debug("copy %s to %s" % (src_initrd_path, isodir + "/isolinux/initrd" + index + ".img")) - shutil.copyfile(src_initrd_path, - isodir + "/isolinux/initrd" + index + ".img") - except: - raise CreatorError("Unable to copy valid kernels or initrds, " - "please check the repo.") - - is_xen = False - if os.path.exists(bootdir + "/xen.gz-" + version[:-3]): - shutil.copyfile(bootdir + "/xen.gz-" + version[:-3], - isodir + "/isolinux/xen" + index + ".gz") - is_xen = True - - return (is_xen,isDracut) - - def __is_default_kernel(self, kernel, kernels): - if len(kernels) == 1: - return True - - if kernel == self._default_kernel: - return True - - if kernel.startswith("kernel-") and kernel[7:] == self._default_kernel: - return True - - return False - - def __get_basic_syslinux_config(self, **args): - return """ -default %(menu)s -timeout %(timeout)d - -%(background)s -menu title Welcome to %(distroname)s! -menu color border 0 #ffffffff #00000000 -menu color sel 7 #ff000000 #ffffffff -menu color title 0 #ffffffff #00000000 -menu color tabmsg 0 #ffffffff #00000000 -menu color unsel 0 #ffffffff #00000000 -menu color hotsel 0 #ff000000 #ffffffff -menu color hotkey 7 #ffffffff #ff000000 -menu color timeout_msg 0 #ffffffff #00000000 -menu color timeout 0 #ffffffff #00000000 -menu color cmdline 0 #ffffffff #00000000 -menu hidden -menu clear -""" % args - - def __get_image_stanza(self, is_xen, isDracut, **args): - if isDracut: - args["rootlabel"] = "live:CDLABEL=%(fslabel)s" % args - else: - args["rootlabel"] = "CDLABEL=%(fslabel)s" % args - if not is_xen: - template = """label %(short)s - menu label %(long)s - kernel vmlinuz%(index)s - append initrd=initrd%(index)s.img root=%(rootlabel)s rootfstype=iso9660 %(liveargs)s %(extra)s -""" - else: - template = """label %(short)s - menu label %(long)s - kernel mboot.c32 - append xen%(index)s.gz --- vmlinuz%(index)s root=%(rootlabel)s rootfstype=iso9660 %(liveargs)s %(extra)s --- initrd%(index)s.img -""" - return template % args - - def __get_image_stanzas(self, isodir): - versions = [] - kernels = self._get_kernel_versions() - for kernel in kernels: - for version in kernels[kernel]: - versions.append(version) - - if not versions: - raise CreatorError("Unable to find valid kernels, " - "please check the repo") - - kernel_options = self._get_kernel_options() - - """ menu can be customized highly, the format is: - - short_name1:long_name1:extra_opts1;short_name2:long_name2:extra_opts2 - - e.g.: autoinst:InstallationOnly:systemd.unit=installer-graphical.service - but in order to keep compatible with old format, these are still ok: - - liveinst autoinst - liveinst;autoinst - liveinst::;autoinst:: - """ - oldmenus = {"basic": { - "short": "basic", - "long": "Installation Only (Text based)", - "extra": "basic nosplash 4" - }, - "liveinst": { - "short": "liveinst", - "long": "Installation Only", - "extra": "liveinst nosplash 4" - }, - "autoinst": { - "short": "autoinst", - "long": "Autoinstall (Deletes all existing content)", - "extra": "autoinst nosplash 4" - }, - "netinst": { - "short": "netinst", - "long": "Network Installation", - "extra": "netinst 4" - }, - "verify": { - "short": "check", - "long": "Verify and", - "extra": "check" - } - } - menu_options = self._get_menu_options() - menus = menu_options.split(";") - for i in range(len(menus)): - menus[i] = menus[i].split(":") - if len(menus) == 1 and len(menus[0]) == 1: - """ Keep compatible with the old usage way """ - menus = menu_options.split() - for i in range(len(menus)): - menus[i] = [menus[i]] - - cfg = "" - - default_version = None - default_index = None - index = "0" - netinst = None - for version in versions: - (is_xen, isDracut) = self.__copy_kernel_and_initramfs(isodir, version, index) - if index == "0": - self._isDracut = isDracut - - default = self.__is_default_kernel(kernel, kernels) - - if default: - long = "Boot %s" % self.distro_name - elif kernel.startswith("kernel-"): - long = "Boot %s(%s)" % (self.name, kernel[7:]) - else: - long = "Boot %s(%s)" % (self.name, kernel) - - oldmenus["verify"]["long"] = "%s %s" % (oldmenus["verify"]["long"], - long) - # tell dracut not to ask for LUKS passwords or activate mdraid sets - if isDracut: - kern_opts = kernel_options + " rd.luks=0 rd.md=0 rd.dm=0" - else: - kern_opts = kernel_options - - cfg += self.__get_image_stanza(is_xen, isDracut, - fslabel = self.fslabel, - liveargs = kern_opts, - long = long, - short = "linux" + index, - extra = "", - index = index) - - if default: - cfg += "menu default\n" - default_version = version - default_index = index - - for menu in menus: - if not menu[0]: - continue - short = menu[0] + index - - if len(menu) >= 2: - long = menu[1] - else: - if menu[0] in oldmenus.keys(): - if menu[0] == "verify" and not self._has_checkisomd5(): - continue - if menu[0] == "netinst": - netinst = oldmenus[menu[0]] - continue - long = oldmenus[menu[0]]["long"] - extra = oldmenus[menu[0]]["extra"] - else: - long = short.upper() + " X" + index - extra = "" - - if len(menu) >= 3: - extra = menu[2] - - cfg += self.__get_image_stanza(is_xen, isDracut, - fslabel = self.fslabel, - liveargs = kernel_options, - long = long, - short = short, - extra = extra, - index = index) - - index = str(int(index) + 1) - - if not default_version: - default_version = versions[0] - if not default_index: - default_index = "0" - - if netinst: - cfg += self.__get_image_stanza(is_xen, isDracut, - fslabel = self.fslabel, - liveargs = kernel_options, - long = netinst["long"], - short = netinst["short"], - extra = netinst["extra"], - index = default_index) - - return cfg - - def __get_memtest_stanza(self, isodir): - memtest = glob.glob(self._instroot + "/boot/memtest86*") - if not memtest: - return "" - - shutil.copyfile(memtest[0], isodir + "/isolinux/memtest") - - return """label memtest - menu label Memory Test - kernel memtest -""" - - def __get_local_stanza(self, isodir): - return """label local - menu label Boot from local drive - localboot 0xffff -""" - - def _configure_syslinux_bootloader(self, isodir): - """configure the boot loader""" - fs_related.makedirs(isodir + "/isolinux") - - menu = self.__find_syslinux_menu() - - self.__copy_syslinux_files(isodir, menu, - self.__find_syslinux_mboot()) - - background = "" - if self.__copy_syslinux_background(isodir + "/isolinux/splash.jpg"): - background = "menu background splash.jpg" - - cfg = self.__get_basic_syslinux_config(menu = menu, - background = background, - name = self.name, - timeout = self._timeout * 10, - distroname = self.distro_name) - - cfg += self.__get_image_stanzas(isodir) - cfg += self.__get_memtest_stanza(isodir) - cfg += self.__get_local_stanza(isodir) - cfg += self._get_isolinux_stanzas(isodir) - - cfgf = open(isodir + "/isolinux/isolinux.cfg", "w") - cfgf.write(cfg) - cfgf.close() - - def __copy_efi_files(self, isodir): - if not os.path.exists(self._instroot + "/boot/efi/EFI/redhat/grub.efi"): - return False - shutil.copy(self._instroot + "/boot/efi/EFI/redhat/grub.efi", - isodir + "/EFI/boot/grub.efi") - shutil.copy(self._instroot + "/boot/grub/splash.xpm.gz", - isodir + "/EFI/boot/splash.xpm.gz") - - return True - - def __get_basic_efi_config(self, **args): - return """ -default=0 -splashimage=/EFI/boot/splash.xpm.gz -timeout %(timeout)d -hiddenmenu - -""" %args - - def __get_efi_image_stanza(self, **args): - return """title %(long)s - kernel /EFI/boot/vmlinuz%(index)s root=CDLABEL=%(fslabel)s rootfstype=iso9660 %(liveargs)s %(extra)s - initrd /EFI/boot/initrd%(index)s.img -""" %args - - def __get_efi_image_stanzas(self, isodir, name): - # FIXME: this only supports one kernel right now... - - kernel_options = self._get_kernel_options() - checkisomd5 = self._has_checkisomd5() - - cfg = "" - - for index in range(0, 9): - # we don't support xen kernels - if os.path.exists("%s/EFI/boot/xen%d.gz" %(isodir, index)): - continue - cfg += self.__get_efi_image_stanza(fslabel = self.fslabel, - liveargs = kernel_options, - long = name, - extra = "", index = index) - if checkisomd5: - cfg += self.__get_efi_image_stanza( - fslabel = self.fslabel, - liveargs = kernel_options, - long = "Verify and Boot " + name, - extra = "check", - index = index) - break - - return cfg - - def _configure_efi_bootloader(self, isodir): - """Set up the configuration for an EFI bootloader""" - fs_related.makedirs(isodir + "/EFI/boot") - - if not self.__copy_efi_files(isodir): - shutil.rmtree(isodir + "/EFI") - return - - for f in os.listdir(isodir + "/isolinux"): - os.link("%s/isolinux/%s" %(isodir, f), - "%s/EFI/boot/%s" %(isodir, f)) - - - cfg = self.__get_basic_efi_config(name = self.name, - timeout = self._timeout) - cfg += self.__get_efi_image_stanzas(isodir, self.name) - - cfgf = open(isodir + "/EFI/boot/grub.conf", "w") - cfgf.write(cfg) - cfgf.close() - - # first gen mactel machines get the bootloader name wrong apparently - if rpmmisc.getBaseArch() == "i386": - os.link(isodir + "/EFI/boot/grub.efi", - isodir + "/EFI/boot/boot.efi") - os.link(isodir + "/EFI/boot/grub.conf", - isodir + "/EFI/boot/boot.conf") - - # for most things, we want them named boot$efiarch - efiarch = {"i386": "ia32", "x86_64": "x64"} - efiname = efiarch[rpmmisc.getBaseArch()] - os.rename(isodir + "/EFI/boot/grub.efi", - isodir + "/EFI/boot/boot%s.efi" %(efiname,)) - os.link(isodir + "/EFI/boot/grub.conf", - isodir + "/EFI/boot/boot%s.conf" %(efiname,)) - - - def _configure_bootloader(self, isodir): - self._configure_syslinux_bootloader(isodir) - self._configure_efi_bootloader(isodir) - -arch = "i386" -if arch in ("i386", "x86_64"): - LiveCDImageCreator = x86LiveImageCreator -elif arch.startswith("arm"): - LiveCDImageCreator = LiveImageCreatorBase -else: - raise CreatorError("Architecture not supported!") diff --git a/scripts/lib/mic/imager/liveusb.py b/scripts/lib/mic/imager/liveusb.py deleted file mode 100644 index a909928a4c..0000000000 --- a/scripts/lib/mic/imager/liveusb.py +++ /dev/null @@ -1,308 +0,0 @@ -#!/usr/bin/python -tt -# -# Copyright (c) 2011 Intel, Inc. -# -# 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; version 2 of the License -# -# 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, write to the Free Software Foundation, Inc., 59 -# Temple Place - Suite 330, Boston, MA 02111-1307, USA. - -import os -import shutil -import re - -from mic import msger -from mic.utils import misc, fs_related, runner -from mic.utils.errors import CreatorError, MountError -from mic.utils.partitionedfs import PartitionedMount -from mic.imager.livecd import LiveCDImageCreator - - -class LiveUSBImageCreator(LiveCDImageCreator): - def __init__(self, *args): - LiveCDImageCreator.__init__(self, *args) - - self._dep_checks.extend(["kpartx", "parted"]) - - # remove dependency of genisoimage in parent class - if "genisoimage" in self._dep_checks: - self._dep_checks.remove("genisoimage") - - def _create_usbimg(self, isodir): - overlaysizemb = 64 #default - #skipcompress = self.skip_compression? - fstype = "vfat" - homesizemb=0 - swapsizemb=0 - homefile="home.img" - plussize=128 - kernelargs=None - - if fstype == 'vfat': - if overlaysizemb > 2047: - raise CreatorError("Can't have an overlay of 2048MB or " - "greater on VFAT") - - if homesizemb > 2047: - raise CreatorError("Can't have an home overlay of 2048MB or " - "greater on VFAT") - - if swapsizemb > 2047: - raise CreatorError("Can't have an swap overlay of 2048MB or " - "greater on VFAT") - - livesize = misc.get_file_size(isodir + "/LiveOS") - - usbimgsize = (overlaysizemb + \ - homesizemb + \ - swapsizemb + \ - livesize + \ - plussize) * 1024L * 1024L - - disk = fs_related.SparseLoopbackDisk("%s/%s.usbimg" \ - % (self._outdir, self.name), - usbimgsize) - usbmnt = self._mkdtemp("usb-mnt") - usbloop = PartitionedMount(usbmnt) - usbloop.add_disk('/dev/sdb', disk) - - usbloop.add_partition(usbimgsize/1024/1024, - "/dev/sdb", - "/", - fstype, - boot=True) - - usbloop.mount() - - try: - fs_related.makedirs(usbmnt + "/LiveOS") - - if os.path.exists(isodir + "/LiveOS/squashfs.img"): - shutil.copyfile(isodir + "/LiveOS/squashfs.img", - usbmnt + "/LiveOS/squashfs.img") - else: - fs_related.mksquashfs(os.path.dirname(self._image), - usbmnt + "/LiveOS/squashfs.img") - - if os.path.exists(isodir + "/LiveOS/osmin.img"): - shutil.copyfile(isodir + "/LiveOS/osmin.img", - usbmnt + "/LiveOS/osmin.img") - - if fstype == "vfat" or fstype == "msdos": - uuid = usbloop.partitions[0]['mount'].uuid - label = usbloop.partitions[0]['mount'].fslabel - usblabel = "UUID=%s-%s" % (uuid[0:4], uuid[4:8]) - overlaysuffix = "-%s-%s-%s" % (label, uuid[0:4], uuid[4:8]) - else: - diskmount = usbloop.partitions[0]['mount'] - usblabel = "UUID=%s" % diskmount.uuid - overlaysuffix = "-%s-%s" % (diskmount.fslabel, diskmount.uuid) - - args = ['cp', "-Rf", isodir + "/isolinux", usbmnt + "/syslinux"] - rc = runner.show(args) - if rc: - raise CreatorError("Can't copy isolinux directory %s" \ - % (isodir + "/isolinux/*")) - - if os.path.isfile("/usr/share/syslinux/isolinux.bin"): - syslinux_path = "/usr/share/syslinux" - elif os.path.isfile("/usr/lib/syslinux/isolinux.bin"): - syslinux_path = "/usr/lib/syslinux" - else: - raise CreatorError("syslinux not installed : " - "cannot find syslinux installation path") - - for f in ("isolinux.bin", "vesamenu.c32"): - path = os.path.join(syslinux_path, f) - if os.path.isfile(path): - args = ['cp', path, usbmnt + "/syslinux/"] - rc = runner.show(args) - if rc: - raise CreatorError("Can't copy syslinux file " + path) - else: - raise CreatorError("syslinux not installed: " - "syslinux file %s not found" % path) - - fd = open(isodir + "/isolinux/isolinux.cfg", "r") - text = fd.read() - fd.close() - pattern = re.compile('CDLABEL=[^ ]*') - text = pattern.sub(usblabel, text) - pattern = re.compile('rootfstype=[^ ]*') - text = pattern.sub("rootfstype=" + fstype, text) - if kernelargs: - text = text.replace("rd.live.image", "rd.live.image " + kernelargs) - - if overlaysizemb > 0: - msger.info("Initializing persistent overlay file") - overfile = "overlay" + overlaysuffix - if fstype == "vfat": - args = ['dd', - "if=/dev/zero", - "of=" + usbmnt + "/LiveOS/" + overfile, - "count=%d" % overlaysizemb, - "bs=1M"] - else: - args = ['dd', - "if=/dev/null", - "of=" + usbmnt + "/LiveOS/" + overfile, - "count=1", - "bs=1M", - "seek=%d" % overlaysizemb] - rc = runner.show(args) - if rc: - raise CreatorError("Can't create overlay file") - text = text.replace("rd.live.image", "rd.live.image rd.live.overlay=" + usblabel) - text = text.replace(" ro ", " rw ") - - if swapsizemb > 0: - msger.info("Initializing swap file") - swapfile = usbmnt + "/LiveOS/" + "swap.img" - args = ['dd', - "if=/dev/zero", - "of=" + swapfile, - "count=%d" % swapsizemb, - "bs=1M"] - rc = runner.show(args) - if rc: - raise CreatorError("Can't create swap file") - args = ["mkswap", "-f", swapfile] - rc = runner.show(args) - if rc: - raise CreatorError("Can't mkswap on swap file") - - if homesizemb > 0: - msger.info("Initializing persistent /home") - homefile = usbmnt + "/LiveOS/" + homefile - if fstype == "vfat": - args = ['dd', - "if=/dev/zero", - "of=" + homefile, - "count=%d" % homesizemb, - "bs=1M"] - else: - args = ['dd', - "if=/dev/null", - "of=" + homefile, - "count=1", - "bs=1M", - "seek=%d" % homesizemb] - rc = runner.show(args) - if rc: - raise CreatorError("Can't create home file") - - mkfscmd = fs_related.find_binary_path("/sbin/mkfs." + fstype) - if fstype == "ext2" or fstype == "ext3": - args = [mkfscmd, "-F", "-j", homefile] - else: - args = [mkfscmd, homefile] - rc = runner.show(args) - if rc: - raise CreatorError("Can't mke2fs home file") - if fstype == "ext2" or fstype == "ext3": - tune2fs = fs_related.find_binary_path("tune2fs") - args = [tune2fs, - "-c0", - "-i0", - "-ouser_xattr,acl", - homefile] - rc = runner.show(args) - if rc: - raise CreatorError("Can't tune2fs home file") - - if fstype == "vfat" or fstype == "msdos": - syslinuxcmd = fs_related.find_binary_path("syslinux") - syslinuxcfg = usbmnt + "/syslinux/syslinux.cfg" - args = [syslinuxcmd, - "-d", - "syslinux", - usbloop.partitions[0]["device"]] - - elif fstype == "ext2" or fstype == "ext3": - extlinuxcmd = fs_related.find_binary_path("extlinux") - syslinuxcfg = usbmnt + "/syslinux/extlinux.conf" - args = [extlinuxcmd, - "-i", - usbmnt + "/syslinux"] - - else: - raise CreatorError("Invalid file system type: %s" % (fstype)) - - os.unlink(usbmnt + "/syslinux/isolinux.cfg") - fd = open(syslinuxcfg, "w") - fd.write(text) - fd.close() - rc = runner.show(args) - if rc: - raise CreatorError("Can't install boot loader.") - - finally: - usbloop.unmount() - usbloop.cleanup() - - # Need to do this after image is unmounted and device mapper is closed - msger.info("set MBR") - mbrfile = "/usr/lib/syslinux/mbr.bin" - if not os.path.exists(mbrfile): - mbrfile = "/usr/share/syslinux/mbr.bin" - if not os.path.exists(mbrfile): - raise CreatorError("mbr.bin file didn't exist.") - mbrsize = os.path.getsize(mbrfile) - outimg = "%s/%s.usbimg" % (self._outdir, self.name) - - args = ['dd', - "if=" + mbrfile, - "of=" + outimg, - "seek=0", - "conv=notrunc", - "bs=1", - "count=%d" % (mbrsize)] - rc = runner.show(args) - if rc: - raise CreatorError("Can't set MBR.") - - def _stage_final_image(self): - try: - isodir = self._get_isodir() - fs_related.makedirs(isodir + "/LiveOS") - - minimal_size = self._resparse() - - if not self.skip_minimize: - fs_related.create_image_minimizer(isodir + "/LiveOS/osmin.img", - self._image, - minimal_size) - - if self.skip_compression: - shutil.move(self._image, - isodir + "/LiveOS/ext3fs.img") - else: - fs_related.makedirs(os.path.join( - os.path.dirname(self._image), - "LiveOS")) - shutil.move(self._image, - os.path.join(os.path.dirname(self._image), - "LiveOS", "ext3fs.img")) - fs_related.mksquashfs(os.path.dirname(self._image), - isodir + "/LiveOS/squashfs.img") - - self._create_usbimg(isodir) - - if self.pack_to: - usbimg = os.path.join(self._outdir, self.name + ".usbimg") - packimg = os.path.join(self._outdir, self.pack_to) - misc.packing(packimg, usbimg) - os.unlink(usbimg) - - finally: - shutil.rmtree(isodir, ignore_errors = True) - self._set_isodir(None) - diff --git a/scripts/lib/mic/imager/loop.py b/scripts/lib/mic/imager/loop.py deleted file mode 100644 index 4d05ef271d..0000000000 --- a/scripts/lib/mic/imager/loop.py +++ /dev/null @@ -1,418 +0,0 @@ -#!/usr/bin/python -tt -# -# Copyright (c) 2011 Intel, Inc. -# -# 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; version 2 of the License -# -# 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, write to the Free Software Foundation, Inc., 59 -# Temple Place - Suite 330, Boston, MA 02111-1307, USA. - -import os -import glob -import shutil - -from mic import kickstart, msger -from mic.utils.errors import CreatorError, MountError -from mic.utils import misc, runner, fs_related as fs -from mic.imager.baseimager import BaseImageCreator - - -# The maximum string length supported for LoopImageCreator.fslabel -FSLABEL_MAXLEN = 32 - - -def save_mountpoints(fpath, loops, arch = None): - """Save mount points mapping to file - - :fpath, the xml file to store partition info - :loops, dict of partition info - :arch, image arch - """ - - if not fpath or not loops: - return - - from xml.dom import minidom - doc = minidom.Document() - imgroot = doc.createElement("image") - doc.appendChild(imgroot) - if arch: - imgroot.setAttribute('arch', arch) - for loop in loops: - part = doc.createElement("partition") - imgroot.appendChild(part) - for (key, val) in loop.items(): - if isinstance(val, fs.Mount): - continue - part.setAttribute(key, str(val)) - - with open(fpath, 'w') as wf: - wf.write(doc.toprettyxml(indent=' ')) - - return - -def load_mountpoints(fpath): - """Load mount points mapping from file - - :fpath, file path to load - """ - - if not fpath: - return - - from xml.dom import minidom - mount_maps = [] - with open(fpath, 'r') as rf: - dom = minidom.parse(rf) - imgroot = dom.documentElement - for part in imgroot.getElementsByTagName("partition"): - p = dict(part.attributes.items()) - - try: - mp = (p['mountpoint'], p['label'], p['name'], - int(p['size']), p['fstype']) - except KeyError: - msger.warning("Wrong format line in file: %s" % fpath) - except ValueError: - msger.warning("Invalid size '%s' in file: %s" % (p['size'], fpath)) - else: - mount_maps.append(mp) - - return mount_maps - -class LoopImageCreator(BaseImageCreator): - """Installs a system into a loopback-mountable filesystem image. - - LoopImageCreator is a straightforward ImageCreator subclass; the system - is installed into an ext3 filesystem on a sparse file which can be - subsequently loopback-mounted. - - When specifying multiple partitions in kickstart file, each partition - will be created as a separated loop image. - """ - - def __init__(self, creatoropts=None, pkgmgr=None, - compress_image=None, - shrink_image=False): - """Initialize a LoopImageCreator instance. - - This method takes the same arguments as ImageCreator.__init__() - with the addition of: - - fslabel -- A string used as a label for any filesystems created. - """ - - BaseImageCreator.__init__(self, creatoropts, pkgmgr) - - self.compress_image = compress_image - self.shrink_image = shrink_image - - self.__fslabel = None - self.fslabel = self.name - - self.__blocksize = 4096 - if self.ks: - self.__fstype = kickstart.get_image_fstype(self.ks, - "ext3") - self.__fsopts = kickstart.get_image_fsopts(self.ks, - "defaults,noatime") - - allloops = [] - for part in sorted(kickstart.get_partitions(self.ks), - key=lambda p: p.mountpoint): - if part.fstype == "swap": - continue - - label = part.label - mp = part.mountpoint - if mp == '/': - # the base image - if not label: - label = self.name - else: - mp = mp.rstrip('/') - if not label: - msger.warning('no "label" specified for loop img at %s' - ', use the mountpoint as the name' % mp) - label = mp.split('/')[-1] - - imgname = misc.strip_end(label, '.img') + '.img' - allloops.append({ - 'mountpoint': mp, - 'label': label, - 'name': imgname, - 'size': part.size or 4096L * 1024 * 1024, - 'fstype': part.fstype or 'ext3', - 'extopts': part.extopts or None, - 'loop': None, # to be created in _mount_instroot - }) - self._instloops = allloops - - else: - self.__fstype = None - self.__fsopts = None - self._instloops = [] - - self.__imgdir = None - - if self.ks: - self.__image_size = kickstart.get_image_size(self.ks, - 4096L * 1024 * 1024) - else: - self.__image_size = 0 - - self._img_name = self.name + ".img" - - def get_image_names(self): - if not self._instloops: - return None - - return [lo['name'] for lo in self._instloops] - - def _set_fst