예제 #1
0
    def install_local_packages(self, packages):
        def in_chroot(lst):
            return ["chroot", self.chroot] + lst

        packages = [ os.path.abspath(p) for p in packages ]
        for package in packages:
            if not os.path.isfile(package):
                raise Exception("package file %r does not exist" % package)
            if not package.startswith(self.chroot + os.path.sep):
                raise Exception("package file %r is not within the chroot" % package)

        pkgmgr, config, lock = self.grab_pm("in_chroot")
        try:
            with lock:
                # always happens in chroot
                # packages must be a list of paths to RPMs valid within the chroot
                for option, retries in options_retries:
                    logger.info("Installing packages %s: %s", option, ", ".join(packages))
                    cmd = in_chroot(
                        [pkgmgr]
                        + (['localinstall'] if pkgmgr == "yum" else ['install'])
                        + ['-y']
                        + option
                        + ['-c', config.name[len(self.chroot):]]
                        + (['--'] if pkgmgr == "yum" else [])
                    ) + [ p[len(self.chroot):] for p in packages ]
                    try:
                        out, ret = retrymod.retry(retries)(check_call_retry_rpmdberror)(cmd)
                    except RpmdbCorruptionError:
                        logger.warning("Repairing RPMDB corruption before retrying package install...")
                        cmdmod.check_call(in_chroot(["rpm", "--rebuilddb"]))
                        out, ret = retrymod.retry(retries)(check_call_retry_rpmdberror)(cmd)
                return out, ret
        finally:
            self.ungrab_pm()
예제 #2
0
    def ensure_packages_installed(self, packages, method="in_chroot"):
        def in_chroot(lst):
            return ["chroot", self.chroot] + lst

        pkgmgr, config, lock = self.grab_pm(method)
        try:
            with lock:
                try:
                    check_call(in_chroot(["rpm", "-q"] + packages),
                                        stdout=file(os.devnull, "w"), stderr=subprocess.STDOUT)
                    logger.info("All required packages are available")
                except subprocess.CalledProcessError:
                    logger.info("Installing packages %s: %s", method, ", ".join(packages))
                    if method == 'in_chroot':
                        cmd = in_chroot([pkgmgr, 'install', '-y',
                                        '-c', config.name[len(self.chroot):]])
                    elif method == 'out_of_chroot':
                        cmd = [pkgmgr,
                            'install',
                            '--disableplugin=*qubes*',
                            '-y',
                            '-c', config.name,
                            '--installroot=%s' % self.chroot,
                            '--releasever=%d' % self.releasever]
                    if pkgmgr != "dnf":
                        cmd = cmd + ['--']
                    cmd = cmd + packages
                    return check_call_retry_rpmdberror(cmd)
        finally:
            self.ungrab_pm()
예제 #3
0
def create_file(filename, sizebytes, owner=None, group=None):
    f = file(filename, "wb")
    f.seek(sizebytes-1)
    f.write("\0")
    f.close()
    if owner:
        check_call(["chown", owner, "--", filename])
    if group:
        check_call(["chgrp", group, "--", filename])
예제 #4
0
 def ensure_packages_installed(self, packages, method="in_chroot"):
     logger.info("Checking packages are available: %s", packages)
     try:
         check_call(["rpm", "-q"] + packages,
                    stdout=file(os.devnull, "w"), stderr=subprocess.STDOUT)
         logger.info("All required packages are available")
     except subprocess.CalledProcessError:
         logger.info("Installing packages %s: %s", method, ", ".join(packages))
         cmd = [self.strategy, 'install', '-y']
         if self.strategy != "dnf":
             cmd = cmd + ['--']
         cmd = cmd + packages
         return check_call_retry_rpmdberror(cmd)
예제 #5
0
    def ensure_packages_installed(self, packages, method="in_chroot"):
        def in_chroot(lst):
            return ["chroot", self.chroot] + lst

        pkgmgr, config, lock = self.grab_pm(method)
        try:
            try:
                with lock:
                    cmdmod.check_call_no_output(
                        in_chroot(["rpm", "-q"] + packages))
                logger.info("All required packages are available")
                return
            except subprocess.CalledProcessError:
                pass
            for option, retries in options_retries:
                logger.info("Installing packages %s %s: %s", option, method,
                            ", ".join(packages))
                cmd = (([pkgmgr] if method == "out_of_chroot" else in_chroot(
                    [pkgmgr])) + ["install", "-y", "--disableplugin=*qubes*"] +
                       ([
                           "-c", config.name if method == "out_of_chroot" else
                           config.name[len(self.chroot):]
                       ]) + option + ([
                           '--installroot=%s' % self.chroot,
                           '--releasever=%d' % self.releasever
                       ] if method == "out_of_chroot" else []) +
                       (['--'] if pkgmgr == "yum" else []) + packages)
                try:
                    with lock:
                        out, ret = retrymod.retry(retries)(
                            check_call_retry_rpmdberror)(cmd)
                except RpmdbCorruptionError:
                    if method == "out_of_chroot":
                        # We do not support recovery in this case.
                        raise
                    logger.warning(
                        "Repairing RPMDB corruption before retrying package install..."
                    )
                    cmdmod.check_call(in_chroot(["rpm", "--rebuilddb"]))
                    with lock:
                        out, ret = retrymod.retry(retries)(
                            check_call_retry_rpmdberror)(cmd)
            return out, ret
        finally:
            self.ungrab_pm()
예제 #6
0
    def install_local_packages(self, packages):
        def in_chroot(lst):
            return ["chroot", self.chroot] + lst

        packages = [os.path.abspath(p) for p in packages]
        for package in packages:
            if not os.path.isfile(package):
                raise Exception("package file %r does not exist" % package)
            if not package.startswith(self.chroot + os.path.sep):
                raise Exception("package file %r is not within the chroot" %
                                package)

        pkgmgr, config, lock = self.grab_pm("in_chroot")
        try:
            with lock:
                # always happens in chroot
                # packages must be a list of paths to RPMs valid within the chroot
                for option, retries in options_retries:
                    logger.info("Installing packages %s: %s", option,
                                ", ".join(packages))
                    cmd = in_chroot([pkgmgr] + (
                        ['localinstall'] if pkgmgr == "yum" else ['install']) +
                                    ['-y'] + option +
                                    ['-c', config.name[len(self.chroot):]] +
                                    (['--'] if pkgmgr == "yum" else [])) + [
                                        p[len(self.chroot):] for p in packages
                                    ]
                    try:
                        out, ret = retrymod.retry(retries)(
                            check_call_retry_rpmdberror)(cmd)
                    except RpmdbCorruptionError:
                        logger.warning(
                            "Repairing RPMDB corruption before retrying package install..."
                        )
                        cmdmod.check_call(in_chroot(["rpm", "--rebuilddb"]))
                        out, ret = retrymod.retry(retries)(
                            check_call_retry_rpmdberror)(cmd)
                return out, ret
        finally:
            self.ungrab_pm()
예제 #7
0
    def ensure_packages_installed(self, packages, method="in_chroot"):
        def in_chroot(lst):
            return ["chroot", self.chroot] + lst

        pkgmgr, config, lock = self.grab_pm(method)
        try:
                try:
                    with lock:
                        cmdmod.check_call_no_output(in_chroot(["rpm", "-q"] + packages))
                    logger.info("All required packages are available")
                    return
                except subprocess.CalledProcessError:
                    pass
                for option, retries in options_retries:
                    logger.info("Installing packages %s %s: %s", option, method, ", ".join(packages))
                    cmd = (
                        ([pkgmgr] if method == "out_of_chroot" else in_chroot([pkgmgr]))
                        + ["install", "-y", "--disableplugin=*qubes*"]
                        + (["-c", config.name if method == "out_of_chroot" else config.name[len(self.chroot):]])
                        + option
                        + (['--installroot=%s' % self.chroot,
                            '--releasever=%d' % self.releasever] if method == "out_of_chroot" else [])
                        + (['--'] if pkgmgr == "yum" else [])
                        + packages
                    )
                    try:
                        with lock:
                            out, ret = retrymod.retry(retries)(check_call_retry_rpmdberror)(cmd)
                    except RpmdbCorruptionError:
                        if method == "out_of_chroot":
                            # We do not support recovery in this case.
                            raise
                        logger.warning("Repairing RPMDB corruption before retrying package install...")
                        cmdmod.check_call(in_chroot(["rpm", "--rebuilddb"]))
                        with lock:
                            out, ret = retrymod.retry(retries)(check_call_retry_rpmdberror)(cmd)
                return out, ret
        finally:
            self.ungrab_pm()
예제 #8
0
    def setup_filesystems(rootpart, bootpart, lukspassword, luksoptions):

        try: output = check_output(["blkid", "-c", "/dev/null", bootpart])
        except subprocess.CalledProcessError: output = ""
        if 'TYPE="ext4"' not in output:
            check_call(["mkfs.ext4", "-L", "boot_" + poolname, bootpart])
        bootpartuuid = check_output(["blkid", "-c", "/dev/null", bootpart, "-o", "value", "-s", "UUID"]).strip()

        if lukspassword:
            needsdoing = False
            try:
                rootuuid = check_output(["blkid", "-c", "/dev/null", rootpart, "-o", "value", "-s", "UUID"]).strip()
                if not rootuuid:
                    raise IndexError("no UUID for %s" % rootpart)
                luksuuid = "luks-" + rootuuid
            except IndexError:
                needsdoing = True
            except subprocess.CalledProcessError, e:
                if e.returncode != 2: raise
                needsdoing = True
            if needsdoing:
                luksopts = shlex.split(luksoptions) if luksoptions else []
                cmd = ["cryptsetup", "-y", "-v", "luksFormat"] + luksopts + [rootpart, '-']
                proc = Popen(cmd, stdin=subprocess.PIPE)
                proc.communicate(lukspassword)
                retcode = proc.wait()
                if retcode != 0: raise subprocess.CalledProcessError(retcode,cmd)
                rootuuid = check_output(["blkid", "-c", "/dev/null", rootpart, "-o", "value", "-s", "UUID"]).strip()
                if not rootuuid:
                    raise IndexError("still no UUID for %s" % rootpart)
                luksuuid = "luks-" + rootuuid
            if not os.path.exists(j("/dev","mapper",luksuuid)):
                cmd = ["cryptsetup", "-y", "-v", "luksOpen", rootpart, luksuuid]
                proc = Popen(cmd, stdin=subprocess.PIPE)
                proc.communicate(lukspassword)
                retcode = proc.wait()
                if retcode != 0: raise subprocess.CalledProcessError(retcode,cmd)
            to_luks_close.append(luksuuid)
            rootpart = j("/dev","mapper",luksuuid)
예제 #9
0
def deploy_zfs_in_machine(p, in_chroot, pkgmgr, branch,
                          prebuilt_rpms_path, break_before, to_unmount, to_rmdir):
    arch = platform.machine()
    stringtoexclude = "debuginfo"

    # check for stage stop
    if break_before == "install_prebuilt_rpms":
        raise BreakingBefore(break_before)

    if prebuilt_rpms_path:
        target_rpms_path = p(j("tmp","zfs-fedora-installer-prebuilt-rpms"))
        if not os.path.isdir(target_rpms_path):
            os.mkdir(target_rpms_path)
        if ismount(target_rpms_path):
            if os.stat(prebuilt_rpms_path).st_ino != os.stat(target_rpms_path):
                umount(target_rpms_path)
                bindmount(os.path.abspath(prebuilt_rpms_path), target_rpms_path)
        else:
            bindmount(os.path.abspath(prebuilt_rpms_path), target_rpms_path)
        if os.path.isdir(target_rpms_path):
            to_rmdir.append(target_rpms_path)
        if ismount(target_rpms_path):
            to_unmount.append(target_rpms_path)
        prebuilt_rpms_to_install = glob.glob(j(prebuilt_rpms_path,"*%s.rpm"%(arch,))) + glob.glob(j(prebuilt_rpms_path,"*%s.rpm"%("noarch",)))
        prebuilt_rpms_to_install = set([
            os.path.basename(s)
            for s in prebuilt_rpms_to_install
            if stringtoexclude not in os.path.basename(s)
        ])
    else:
        target_rpms_path = None
        prebuilt_rpms_to_install = set()

    if prebuilt_rpms_to_install:
        logging.info(
            "Installing available prebuilt RPMs: %s",
            prebuilt_rpms_to_install
        )
        files_to_install = [
            j(target_rpms_path, s)
            for s in prebuilt_rpms_to_install
        ]
        pkgmgr.install_local_packages(files_to_install)

    if target_rpms_path:
        umount(target_rpms_path)
        to_unmount.remove(target_rpms_path)
        check_call(["rmdir", target_rpms_path])
        to_rmdir.remove(target_rpms_path)

    # check for stage stop
    if break_before == "install_grub_zfs_fixer":
        raise BreakingBefore(break_before)

    for project, patterns in (
        (
            "grub-zfs-fixer",
            (
                "RPMS/%s/*.%s.rpm" % ("noarch", "noarch"),
                "RPMS/*.%s.rpm" % ("noarch",),
            ),
        ),
    ):
        grubzfsfixerpath = j(os.path.dirname(__file__), os.path.pardir, os.path.pardir, "grub-zfs-fixer")
        class FixerNotInstalledYet(Exception): pass
        try:
            logging.info("Checking if %s has the GRUB ZFS fixer installed", project)
            try:
                fixerlines = file(j(grubzfsfixerpath, "grub-zfs-fixer.spec")).readlines()
                fixerversion = [ x.split()[1] for x in fixerlines if x.startswith("Version:") ][0]
                fixerrelease = [ x.split()[1] for x in fixerlines if x.startswith("Release:") ][0]
                check_output(in_chroot([
                    "rpm",
                    "-q",
                    "grub-zfs-fixer-%s-%s" % (fixerversion, fixerrelease)
                ]))
            except subprocess.CalledProcessError:
                raise FixerNotInstalledYet()
        except FixerNotInstalledYet:
            logging.info("%s does not have the GRUB ZFS fixer, building", project)
            project_dir = p(j("usr","src",project))
            def getrpms(pats, directory):
                therpms = [
                    rpmfile
                    for pat in pats
                    for rpmfile in glob.glob(j(directory, pat))
                    if stringtoexclude not in os.path.basename(rpmfile)
                ]
                return therpms
            files_to_install = getrpms(patterns, project_dir)
            if not files_to_install:
                if not os.path.isdir(project_dir):
                    os.mkdir(project_dir)

                pkgmgr.ensure_packages_installed(
                    [
                        "rpm-build", "tar", "gzip",
                    ],
                )
                logging.info("Tarring %s tarball", project)
                check_call(['tar', 'cvzf', j(project_dir, "%s.tar.gz" % project), project],
                            cwd=j(grubzfsfixerpath, os.path.pardir))
                logging.info("Building project: %s", project)
                project_dir_in_chroot = project_dir[len(p(""))-1:]
                check_call(in_chroot(["rpmbuild", "--define", "_topdir %s"%(project_dir_in_chroot,), "-ta", j(project_dir_in_chroot,"%s.tar.gz" % project)]))
                files_to_install = getrpms(patterns, project_dir)

            logging.info("Installing built RPMs: %s", files_to_install)
            pkgmgr.install_local_packages(files_to_install)

    # Check we have a patched grub2-mkconfig.
    mkconfig_file = p(j("usr", "sbin", "grub2-mkconfig"))
    mkconfig_text = file(mkconfig_file).read()
    if "This program was patched by fix-grub-mkconfig" not in mkconfig_text:
        raise ZFSBuildFailure("expected to find patched %s but could not find it.  Perhaps the grub-zfs-fixer RPM was never installed?" % mkconfig_file)

    for project, patterns, keystonepkgs, mindeps in (
        (
            "spl",
            (
                "spl-*.%s.rpm" % arch,
                "spl-dkms-*.noarch.rpm",
            ),
            ('spl', 'spl-dkms'),
            [
                "make", "autoconf", "automake", "gcc", "libtool", "git",
                "rpm-build", "dkms",
            ],
        ),
        (
            "zfs",
            (
                "zfs-dkms-*.noarch.rpm",
                "libnvpair*.%s.rpm" % arch,
                "libuutil*.%s.rpm" % arch,
                "libzfs?-[0123456789]*.%s.rpm" % arch,
                "libzfs?-devel-[0123456789]*.%s.rpm" % arch,
                "libzpool*.%s.rpm" % arch,
                "zfs-[0123456789]*.%s.rpm" % arch,
                "zfs-dracut-*.%s.rpm" % arch,
            ),
            ('zfs', 'zfs-dkms', 'zfs-dracut'),
            [
                "zlib-devel", "libuuid-devel", "bc", "libblkid-devel",
                "libattr-devel", "lsscsi", "mdadm", "parted",
                "libudev-devel",
            ],
        ),
    ):
        # check for stage stop
        if break_before == "deploy_%s" % project:
            raise BreakingBefore(break_before)

        try:
            logging.info("Checking if keystone packages %s are installed", ", ".join(keystonepkgs))
            check_call(in_chroot(["rpm", "-q"] + list(keystonepkgs)),
                                stdout=file(os.devnull,"w"), stderr=subprocess.STDOUT)
        except subprocess.CalledProcessError:
            logging.info("Package %s-dkms is not installed, building", project)
            project_dir = p(j("usr","src",project))
            def getrpms(pats, directory):
                therpms = [
                    rpmfile
                    for pat in pats
                    for rpmfile in glob.glob(j(directory, pat))
                    if stringtoexclude not in os.path.basename(rpmfile)
                ]
                return therpms
            files_to_install = getrpms(patterns, project_dir)
            if not files_to_install:
                if not os.path.isdir(project_dir):
                    repo = "https://github.com/Rudd-O/%s" % project
                    logging.info("Cloning git repository: %s", repo)
                    cmd = ["git", "clone", repo, project_dir]
                    check_call(cmd)
                    cmd = ["git", "checkout", branch]
                    check_call(cmd, cwd= project_dir)
                    cmd = ["git", "--no-pager", "show"]
                    check_call(cmd, cwd= project_dir)

                pkgmgr.ensure_packages_installed(mindeps)

                logging.info("Building project: %s", project)
                cores = multiprocessing.cpu_count()
                cmd = in_chroot(["bash", "-c",
                    (
                        "cd /usr/src/%s && "
                        "./autogen.sh && "
                        "./configure --with-config=user && "
                        "make -j%s rpm-utils && "
                        "make -j%s rpm-dkms" % (project, cores, cores)
                    )
                ])
                check_call(cmd)
                files_to_install = getrpms(patterns, project_dir)

            logging.info("Installing built RPMs: %s", files_to_install)
            pkgmgr.install_local_packages(files_to_install)

    # Check we have a ZFS.ko for at least one kernel.
    modules_dir = p(j("usr", "lib", "modules", "*", "*", "zfs.ko"))
    modules_files = glob.glob(modules_dir)
    if not modules_files:
        raise ZFSBuildFailure("expected to find but could not find module zfs.ko in %s.  Perhaps the ZFS source you used is too old to work with the kernel this program installed?" % modules_dir)
예제 #10
0
def install_fedora(voldev, volsize, bootdev=None, bootsize=256,
                   poolname='tank', hostname='localhost.localdomain',
                   rootpassword='******', swapsize=1024,
                   releasever=None, lukspassword=None,
                   do_cleanup=True,
                   interactive_qemu=False,
                   luksoptions=None,
                   prebuilt_rpms_path=None,
                   yum_cachedir_path=None,
                   force_kvm=None,
                   chown=None,
                   chgrp=None,
                   break_before=None,
                   branch="master",
                   workdir='/var/lib/zfs-fedora-installer',
    ):

    if lukspassword and not BootDriver.is_typeable(lukspassword):
        raise ImpossiblePassphrase("LUKS passphrase %r cannot be typed during boot" % lukspassword)

    if rootpassword and not BootDriver.is_typeable(rootpassword):
        raise ImpossiblePassphrase("root password %r cannot be typed during boot" % rootpassword)

    original_voldev = voldev
    original_bootdev = bootdev

    undoer = Undoer()
    to_un_losetup = undoer.to_un_losetup
    to_luks_close = undoer.to_luks_close
    to_export = undoer.to_export
    to_rmdir = undoer.to_rmdir
    to_unmount = undoer.to_unmount
    to_rmrf = undoer.to_rmrf

    def cleanup():
        undoer.undo()

    if not releasever:
        releasever = ChrootPackageManager.get_my_releasever()

    @contextlib.contextmanager
    def setup_blockdevs(voldev, bootdev):

        voltype = filetype(voldev)
        if bootdev: boottype = filetype(bootdev)

        if voltype == 'doesntexist':  # FIXME use truncate directly with python.  no need to dick around.
            create_file(voldev, volsize * 1024 * 1024, owner=chown, group=chgrp)
            voltype = 'file'

        if bootdev and boottype == 'doesntexist':
            create_file(bootdev, bootsize * 1024 * 1024, owner=chown, group=chgrp)
            boottype = 'file'

        if voltype == 'file':
            if get_associated_lodev(voldev):
                voldev = get_associated_lodev(voldev)
            else:
                voldev = losetup(voldev)
            to_un_losetup.append(voldev)
            voltype = 'blockdev'

        if bootdev and boottype == 'file':
            if get_associated_lodev(bootdev):
                bootdev = get_associated_lodev(bootdev)
            else:
                bootdev = losetup(bootdev)
            to_un_losetup.append(bootdev)
            boottype = 'blockdev'

        if bootdev:
            bootpart = bootdev + "-part1"
            if not os.path.exists(bootpart):
                bootpart = bootpart = bootdev + "p1"
            if not os.path.exists(bootpart):
                bootpart = bootpart = bootdev + "1"
            if not os.path.exists(bootpart):
                bootpart = None
            rootpart = voldev

            if not bootpart:
                cmd = ["fdisk", bootdev]
                pr = Popen(cmd, stdin=subprocess.PIPE)
                pr.communicate(
    '''n
    p
    1



    p
    w
    '''
                )
                retcode = pr.wait()
                if retcode != 0: raise subprocess.CalledProcessError(retcode,cmd)
                time.sleep(2)

            bootpart = bootdev + "-part1"
            if not os.path.exists(bootpart):
                bootpart = bootpart = bootdev + "p1"
            if not os.path.exists(bootpart):
                bootpart = bootpart = bootdev + "1"
            if not os.path.exists(bootpart):
                assert 0, "partition 1 in device %r failed to be created"%bootdev

        else:
            bootpart = voldev + "-part1"
            if not os.path.exists(bootpart):
                bootpart = bootpart = voldev + "p1"
            if not os.path.exists(bootpart):
                bootpart = bootpart = voldev + "1"
            if not os.path.exists(bootpart):
                bootpart = None
            rootpart = voldev + "-part2"
            if not os.path.exists(rootpart):
                rootpart = rootpart = voldev + "p2"
            if not os.path.exists(rootpart):
                rootpart = rootpart = voldev + "2"
            if not os.path.exists(rootpart):
                rootpart = None

            assert (not bootpart and not rootpart) or (bootpart and rootpart), "weird shit bootpart %s rootpart %s\nYou might want to nuke the partition table on the device/file you specified first." %(bootpart, rootpart)

            bootstartsector = 2048
            bootendsector = bootstartsector + ( bootsize * 1024 * 1024 / 512 ) - 1
            rootstartsector = bootendsector + 1
            rootendsector = ( get_file_size(voldev) / 512 ) - 1 - ( 16 * 1024 * 1024 / 512 )
            if not rootpart and not bootpart:
                cmd = ["fdisk", voldev]
                pr = Popen(cmd, stdin=subprocess.PIPE)
                pr.communicate(
    '''n
p
1
%d
%d

n
p
2
%d
%d
p
w
'''%(bootstartsector, bootendsector, rootstartsector, rootendsector)
                )
                retcode = pr.wait()
                if retcode != 0: raise subprocess.CalledProcessError(retcode,cmd)
                time.sleep(2)

            bootpart = voldev + "-part1"
            if not os.path.exists(bootpart):
                bootpart = voldev + "p1"
            if not os.path.exists(bootpart):
                bootpart = voldev + "1"
            if not os.path.exists(bootpart):
                assert 0, "partition 1 in device %r failed to be created"%voldev
            rootpart = voldev + "-part2"
            if not os.path.exists(rootpart):
                rootpart = rootpart = voldev + "p2"
            if not os.path.exists(rootpart):
                rootpart = rootpart = voldev + "2"
            if not os.path.exists(rootpart):
                assert 0, "partition 2 in device %r failed to be created"%voldev

        yield rootpart, bootpart

    @contextlib.contextmanager
    def setup_filesystems(rootpart, bootpart, lukspassword, luksoptions):

        try: output = check_output(["blkid", "-c", "/dev/null", bootpart])
        except subprocess.CalledProcessError: output = ""
        if 'TYPE="ext4"' not in output:
            check_call(["mkfs.ext4", "-L", "boot_" + poolname, bootpart])
        bootpartuuid = check_output(["blkid", "-c", "/dev/null", bootpart, "-o", "value", "-s", "UUID"]).strip()

        if lukspassword:
            needsdoing = False
            try:
                rootuuid = check_output(["blkid", "-c", "/dev/null", rootpart, "-o", "value", "-s", "UUID"]).strip()
                if not rootuuid:
                    raise IndexError("no UUID for %s" % rootpart)
                luksuuid = "luks-" + rootuuid
            except IndexError:
                needsdoing = True
            except subprocess.CalledProcessError, e:
                if e.returncode != 2: raise
                needsdoing = True
            if needsdoing:
                luksopts = shlex.split(luksoptions) if luksoptions else []
                cmd = ["cryptsetup", "-y", "-v", "luksFormat"] + luksopts + [rootpart, '-']
                proc = Popen(cmd, stdin=subprocess.PIPE)
                proc.communicate(lukspassword)
                retcode = proc.wait()
                if retcode != 0: raise subprocess.CalledProcessError(retcode,cmd)
                rootuuid = check_output(["blkid", "-c", "/dev/null", rootpart, "-o", "value", "-s", "UUID"]).strip()
                if not rootuuid:
                    raise IndexError("still no UUID for %s" % rootpart)
                luksuuid = "luks-" + rootuuid
            if not os.path.exists(j("/dev","mapper",luksuuid)):
                cmd = ["cryptsetup", "-y", "-v", "luksOpen", rootpart, luksuuid]
                proc = Popen(cmd, stdin=subprocess.PIPE)
                proc.communicate(lukspassword)
                retcode = proc.wait()
                if retcode != 0: raise subprocess.CalledProcessError(retcode,cmd)
            to_luks_close.append(luksuuid)
            rootpart = j("/dev","mapper",luksuuid)

        rootmountpoint = j(workdir, poolname)
        try:
            check_call(["zfs", "list", "-H", "-o", "name", poolname],
                                stdout=file(os.devnull,"w"))
        except subprocess.CalledProcessError, e:
            try:
                check_call(["zpool", "import", "-f",
                                    "-R", rootmountpoint,
                                    poolname])
            except subprocess.CalledProcessError, e:
                check_call(["zpool", "create", "-m", "none",
                                    "-o", "ashift=12",
                                    "-O", "compression=on",
                                    "-O", "atime=off",
                                    "-O", "com.sun:auto-snapshot=false",
                                    "-R", rootmountpoint,
                                    poolname, rootpart])
예제 #11
0
 def undo(self):
     for n, (typ, o) in reversed(list(enumerate(self.actions[:]))):
         if typ == "unmount":
             umount(o)
         if typ == "rmrf":
             shutil.rmtree(o)
         if typ == "rmdir":
             os.rmdir(o)
         if typ == "export":
             check_call(["sync"])
             check_call(["zpool", "export", o])
         if typ == "luks_close":
             check_call(["sync"])
             check_call(["cryptsetup", "luksClose", o])
         if typ == "un_losetup":
             check_call(["sync"])
             if get_associated_lodev(o):
                 check_call(["losetup", "-d", o])
             if get_associated_lodev(o):
                 logging.error("losetup -d failed with device %s", o)
         self.actions.pop(n)
예제 #12
0
def delete_contents(directory):
    if not os.path.exists(directory):
        return
    ps = [ j(directory, p) for p in os.listdir(directory) ]
    if ps:
        check_call(["rm", "-rf"] + ps)
예제 #13
0
def losetup(path):
    check_call(
        ["losetup", "-P", "--find", "--show", path]
    )
    return get_associated_lodev(path)
예제 #14
0
            try:
                check_call(["zpool", "import", "-f",
                                    "-R", rootmountpoint,
                                    poolname])
            except subprocess.CalledProcessError, e:
                check_call(["zpool", "create", "-m", "none",
                                    "-o", "ashift=12",
                                    "-O", "compression=on",
                                    "-O", "atime=off",
                                    "-O", "com.sun:auto-snapshot=false",
                                    "-R", rootmountpoint,
                                    poolname, rootpart])
        to_export.append(poolname)

        try:
            check_call(["zfs", "list", "-H", "-o", "name", j(poolname, "ROOT")],
                                stdout=file(os.devnull,"w"))
        except subprocess.CalledProcessError, e:
            check_call(["zfs", "create", j(poolname, "ROOT")])

        try:
            check_call(["zfs", "list", "-H", "-o", "name", j(poolname, "ROOT", "os")],
                                stdout=file(os.devnull,"w"))
            if not os.path.ismount(rootmountpoint):
                check_call(["zfs", "mount", j(poolname, "ROOT", "os")])
        except subprocess.CalledProcessError, e:
            check_call(["zfs", "create", "-o", "mountpoint=/", j(poolname, "ROOT", "os")])
            check_call(["touch", j(rootmountpoint, ".autorelabel")])
        to_unmount.append(rootmountpoint)

        try:
            check_call(["zfs", "list", "-H", "-o", "name", j(poolname, "swap")],