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()
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()
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])
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)
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()
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()
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()
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)
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)
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])
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)
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)
def losetup(path): check_call( ["losetup", "-P", "--find", "--show", path] ) return get_associated_lodev(path)
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")],