Example #1
0
 def ungrab_pm(self, *ignored, **kwignored):
     if self.cachedir:
         with lockfile(j(self.cachedir, "ifz-lockfile")):
             while self.cachemounts:
                 while ismount(self.cachemounts[-1]):
                     logger.debug("Unmounting %s", self.cachemounts[-1])
                     umount(self.cachemounts[-1])
                 os.rmdir(self.cachemounts[-1])
                 self.cachemounts.pop()
     if self.pkgmgr_config:
         self.pkgmgr_config.close()
         self.pkgmgr_config = None
Example #2
0
 def ungrab_pm(self, *ignored, **kwignored):
     if self.cachedir:
         with lockfile(j(self.cachedir, "ifz-lockfile")):
             while self.cachemounts:
                 while ismount(self.cachemounts[-1]):
                     logger.debug("Unmounting %s", self.cachemounts[-1])
                     umount(self.cachemounts[-1])
                 os.rmdir(self.cachemounts[-1])
                 self.cachemounts.pop()
     if self.pkgmgr_config:
         self.pkgmgr_config.close()
         self.pkgmgr_config = None
Example #3
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)
Example #4
0
    def grab_pm(self, method):
        if self.cachemounts or self.pkgmgr_config:
            assert 0, "programming error, invalid state, cannot enter without exiting first"

        if method == "in_chroot":
            dirforconfig = self.chroot
            if os.path.isfile(j(self.chroot, "etc", "dnf", "dnf.conf")):
                sourceconf = j(self.chroot, "etc", "dnf", "dnf.conf")
                pkgmgr = "dnf"
            elif os.path.isfile(j(self.chroot, "etc", "yum.conf")):
                sourceconf = j(self.chroot, "etc", "yum.conf")
                pkgmgr = "yum"
            else:
                raise Exception("Cannot use in_chroot method without a working yum or DNF inside the chroot")
            ver = self.releasever
        elif method == "out_of_chroot":
            dirforconfig = os.getenv("TMPDIR") or "/tmp"
            if os.path.exists("/etc/dnf/dnf.conf"):
                sourceconf = "/etc/dnf/dnf.conf"
                pkgmgr = "dnf"
            elif os.path.exists("/etc/yum.conf"):
                sourceconf = "/etc/yum.conf"
                pkgmgr = "yum"
            else:
                raise Exception("Cannot use out_of_chroot method without a working yum or DNF installed on your system")
            ver = self.myreleasever
        else:
            assert 0, "method unknown: %r" % method

        parms = dict(
            source=sourceconf,
            directory=dirforconfig,
            logfile="/dev/null",
            debuglevel=2,
            reposdir="/nonexistent",
            include=None,
            keepcache=1 if pkgmgr == "yum" else True,
        )

        # /yumcache
        if self.cachedir:
            makedirs([self.cachedir])
            with lockfile(j(self.cachedir, "ifz-lockfile")):
                # /yumcache/(dnf|yum)/(ver)/(lib|cache)
                persistdir = j(self.cachedir, pkgmgr, str(ver), "lib")
                cachedir   = j(self.cachedir, pkgmgr, str(ver), "cache")
                makedirs([persistdir, cachedir])
                # /yumcache/(dnf|yum)/(ver)/lock
                # /chroot/var/(lib|cache)/(dnf|yum)
                persistin, cachein = makedirs([
                    j(self.chroot, "tmp-%s-%s" % (pkgmgr, x))
                    for x in ["lib", "cache"]
                ])
                maybemounted = [persistin, cachein]
                while maybemounted:
                    while ismount(maybemounted[-1]):
                        logger.debug("Preemptively unmounting %s", maybemounted[-1])
                        umount(maybemounted[-1])
                    maybemounted.pop()
                for x, y in ([persistdir, persistin], [cachedir, cachein]):
                    logger.debug("Mounting %s to %s", x, y)
                    self.cachemounts.append(bindmount(x, y))
            # /var/(lib|cache)/(dnf|yum)
            parms["persistdir"] = persistin[len(self.chroot):]
            parms["cachedir"] = cachein[len(self.chroot):]
            lock = lockfile(j(self.cachedir, pkgmgr, str(ver), "lock"))
        else:
            lock = dummylock()

        self.pkgmgr_config = make_temp_yum_config(**parms)
        return pkgmgr, self.pkgmgr_config, lock
Example #5
0
    def grab_pm(self, method):
        if self.cachemounts or self.pkgmgr_config:
            assert 0, "programming error, invalid state, cannot enter without exiting first"

        if method == "in_chroot":
            dirforconfig = self.chroot
            if os.path.isfile(j(self.chroot, "etc", "dnf", "dnf.conf")):
                sourceconf = j(self.chroot, "etc", "dnf", "dnf.conf")
                pkgmgr = "dnf"
            elif os.path.isfile(j(self.chroot, "etc", "yum.conf")):
                sourceconf = j(self.chroot, "etc", "yum.conf")
                pkgmgr = "yum"
            else:
                raise Exception("Cannot use in_chroot method without a working yum or DNF inside the chroot")
            ver = self.releasever
        elif method == "out_of_chroot":
            dirforconfig = os.getenv("TMPDIR") or "/tmp"
            if os.path.exists("/etc/dnf/dnf.conf"):
                sourceconf = "/etc/dnf/dnf.conf"
                pkgmgr = "dnf"
            elif os.path.exists("/etc/yum.conf"):
                sourceconf = "/etc/yum.conf"
                pkgmgr = "yum"
            else:
                raise Exception("Cannot use out_of_chroot method without a working yum or DNF installed on your system")
            ver = self.myreleasever
        else:
            assert 0, "method unknown: %r" % method

        parms = dict(
            source=sourceconf,
            directory=dirforconfig,
            logfile="/dev/null",
            debuglevel=2,
            reposdir="/nonexistent",
            include=None,
            keepcache=1 if pkgmgr == "yum" else True,
        )

        # /yumcache
        if self.cachedir:
            makedirs([self.cachedir])
            with lockfile(j(self.cachedir, "ifz-lockfile")):
                # /yumcache/(dnf|yum)/(ver)/(lib|cache)
                persistdir = j(self.cachedir, pkgmgr, str(ver), "lib")
                cachedir   = j(self.cachedir, pkgmgr, str(ver), "cache")
                makedirs([persistdir, cachedir])
                # /yumcache/(dnf|yum)/(ver)/lock
                lock = lockfile(j(self.cachedir, pkgmgr, str(ver), "lock"))
                # /chroot/var/(lib|cache)/(dnf|yum)
                persistin, cachein = makedirs([
                    j(self.chroot, "tmp-%s-%s" % (pkgmgr, x))
                    for x in ["lib", "cache"]
                ])
                maybemounted = [persistin, cachein]
                while maybemounted:
                    while ismount(maybemounted[-1]):
                        logger.debug("Preemptively unmounting %s", maybemounted[-1])
                        umount(maybemounted[-1])
                    maybemounted.pop()
                for x, y in ([persistdir, persistin], [cachedir, cachein]):
                    logger.debug("Mounting %s to %s", x, y)
                    self.cachemounts.append(bindmount(x, y))
            # /var/(lib|cache)/(dnf|yum)
            parms["persistdir"] = persistin[len(self.chroot):]
            parms["cachedir"] = cachein[len(self.chroot):]
        else:
            lock = dummylock()

        self.pkgmgr_config = make_temp_yum_config(**parms)
        return pkgmgr, self.pkgmgr_config, lock
Example #6
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)
Example #7
0
 def cleanup():
     for fs in reversed(to_unmount):
         umount(fs)
     for filename in to_rmdir:
         os.rmdir(filename)