示例#1
0
    def verify(self) -> bool:
        """
        This method runs several checks to ensure local copying can proceed. It is automatically
        executed at package initialisation. This includes:

        * checks if all expected keys are present in the configuration file

        Returns:
            bool:   verification success
        """

        logger = KtrLogger(LOG_PREFIX)

        success = True

        # check if the configuration file is valid
        expected_keys = ["keep", "orig"]

        for key in expected_keys:
            if key not in self.spkg.conf["local"]:
                logger.err("The [local] section in the package's .conf file doesn't set the '" +
                           key +
                           "' key.")
                success = False

        return success
示例#2
0
    def verify(self) -> bool:
        """
        This method runs several checks to ensure copr uploads can proceed. It is automatically
        executed at package initialisation. This includes:

        * checks if all expected keys are present in the configuration file
        * checks if the `copr-cli` binary is installed and can be found on the system

        Returns:
            bool:   verification success
        """

        logger = KtrLogger(LOG_PREFIX)

        success = True

        # check if the configuration file is valid
        expected_keys = ["active", "dists", "keep", "repo", "wait"]

        for key in expected_keys:
            if key not in self.upkg.conf["copr"]:
                logger.err("The [copr] section in the package's .conf file doesn't set the '" +
                           key +
                           "' key.")
                success = False

        # check if copr is installed
        try:
            subprocess.check_output(["which", "copr-cli"])
        except subprocess.CalledProcessError:
            logger.log("Install copr-cli to use the specified builder.")
            success = False

        return success
示例#3
0
def ktr_mkdirp(path: str) -> bool:
    """
    This function checks for directory existence and the ability to write to it. If the directory
    does not exist, it will be created.

    Arguments:
        str path:   path of directory to check and create

    Returns:
        bool:       success (or not)
    """

    logger = KtrLogger(LOG_PREFIX)

    if os.path.exists(path):
        if os.access(path, os.W_OK):
            return True
        else:
            logger.err(path + " can't be written to.")
            return False
    else:
        logger.log(path + " directory doesn't exist and will be created.")
        try:
            os.makedirs(path)
        except OSError:
            logger.err(path + " directory could not be created.")
            return False
        return True
示例#4
0
    def verify(self) -> bool:
        """
        This method runs several checks to ensure bzr commands can proceed. It is automatically
        executed at package initialisation. This includes:

        * checks if all expected keys are present in the configuration file
        * checks if the `bzr` binary is installed and can be found on the system

        Returns:
            bool:   verification success
        """

        logger = KtrLogger(LOG_PREFIX)

        success = True

        # check if the configuration file is valid
        expected_keys = ["branch", "keep", "keep_repo", "orig", "revno"]

        for key in expected_keys:
            if key not in self.spkg.conf["bzr"]:
                logger.err("The [bzr] section in the package's .conf file doesn't set the '" +
                           key +
                           "' key.")
                success = False

        # check if bzr is installed
        try:
            subprocess.check_output(["which", "bzr"]).decode().rstrip("\n")
        except subprocess.CalledProcessError:
            logger.log("Install bzr to use the specified source.")
            success = False

        return success
示例#5
0
    def update(self) -> bool:
        """
        This method executes a git repository update as specified in the package configuration file.
        If a specific commit has been set in the config file, this method will not attempt to
        execute an update.

        Returns:
            bool: *True* if update available and successful, *False* if not
        """

        ktr = Kentauros()
        logger = KtrLogger(LOG_PREFIX)

        # if specific commit is requested, do not pull updates (obviously)
        if self.get_commit() == "HEAD":
            return False

        # check for connectivity to server
        if not is_connected(self.get_orig()):
            logger.log("No connection to remote host detected. Cancelling source update.", 2)
            return False

        # construct git command
        cmd = ["git", "pull", "--rebase"]

        # add --verbose or --quiet depending on settings
        if (ktr.verby == 2) and not ktr.debug:
            cmd.append("--quiet")
        if (ktr.verby == 0) or ktr.debug:
            cmd.append("--verbose")

        # check if source directory exists before going there
        if not os.access(self.dest, os.W_OK):
            logger.err("Sources need to be get before an update can be run.")
            return False

        # get old commit ID
        rev_old = self.commit()

        # change to git repository directory
        prev_dir = os.getcwd()
        os.chdir(self.dest)

        # get updates
        logger.log_command(cmd, 1)
        subprocess.call(cmd)

        # go back to previous dir
        os.chdir(prev_dir)

        # get new commit ID
        rev_new = self.commit()
        self.date()

        # return True if update found, False if not
        return rev_new != rev_old
示例#6
0
    def clean(self) -> bool:
        if not os.path.exists(self.pdir):
            return True

        logger = KtrLogger(LOG_PREFIX)

        try:
            assert Kentauros().conf.get_packdir() in self.pdir
            assert os.path.isabs(self.pdir)
            shutil.rmtree(self.pdir)
            return True
        except AssertionError:
            logger.err("The Package exports directory looks weird. Doing nothing.")
            return False
        except OSError:
            logger.err("The Package exports directory couldn't be removed.")
            return False
示例#7
0
    def export(self) -> bool:
        """
        This method copies the build results (if any) from the mock result directory to the
        directory specified for binary package exports.

        Returns:
            bool:   *True* if successful, *False* if not
        """

        if not self.get_active():
            return True

        if not self.get_export():
            return True

        logger = KtrLogger(LOG_PREFIX)

        os.makedirs(self.edir, exist_ok=True)

        if not os.path.exists(self.edir):
            logger.err("Package exports directory could not be created.")
            return False

        if not os.access(self.edir, os.W_OK):
            logger.err("Package exports directory can not be written to.")
            return False

        mock_result_dirs = list()

        for dist in self.get_dists():
            path = get_dist_result_path(dist)
            if os.path.exists(path):
                mock_result_dirs.append(path)
            else:
                corrected_path = get_dist_result_path(get_dist_from_mock_config(dist))
                mock_result_dirs.append(corrected_path)

        file_results = list()

        for result_dir in mock_result_dirs:
            file_results += glob.glob(os.path.join(result_dir, "*.rpm"))

        for file in file_results:
            shutil.copy2(file, self.edir)

        return True
示例#8
0
    def __init__(self, conf_name: str):
        assert isinstance(conf_name, str)

        ktr = Kentauros()
        logger = KtrLogger(LOG_PREFIX)

        self.file = os.path.join(ktr.conf.get_confdir(), conf_name + ".conf")
        self.conf = ConfigParser()
        self.conf_name = conf_name

        if not os.path.exists(self.file):
            raise FileNotFoundError("Package configuration file does not exist.")

        success = self.conf.read(self.file)
        if not success:
            logger.err("Package configuration could not be read.")
            logger.err("Path: " + self.file)
            raise PackageError("Package configuration could not be read.")

        if not self.verify():
            raise PackageError("Package configuration file is invalid.")

        self.name = self.conf.get("package", "name")

        modules_str = str(self.conf.get("package", "modules"))
        module_type_list = modules_str.split(",")

        if module_type_list == [""]:
            module_type_list = []

        self.modules = OrderedDict()

        for module_type in module_type_list:
            module_type_enum = PkgModuleType[module_type.upper()]
            module_implement = str(self.conf.get("modules", module_type)).upper()

            module = PKG_MODULE_DICT[module_type_enum][
                PKG_MODULE_TYPE_DICT[module_type_enum][module_implement]](self)

            self.modules[module_type] = module

        for module in self.modules.values():
            assert isinstance(module, PkgModule)
            module.verify()
示例#9
0
    def verify(self) -> bool:
        """
        This method runs several checks to ensure git commands can proceed. It is automatically
        executed at package initialisation. This includes:

        * checks if all expected keys are present in the configuration file
        * checks that the configuration file is consistent (i.e. shallow clone and commit checkout
          are not compatible)
        * checks if the `git` binary is installed and can be found on the system

        Returns:
            bool:   verification success
        """

        logger = KtrLogger(LOG_PREFIX)

        success = True

        # check if the configuration file is valid
        expected_keys = ["branch", "commit", "keep", "keep_repo", "orig", "shallow"]

        for key in expected_keys:
            if key not in self.spkg.conf["git"]:
                logger.err("The [git] section in the package's .conf file doesn't set the '" +
                           key +
                           "' key.")
                success = False

        # shallow clones and checking out a specific commit is not supported
        if (self.get_commit() != "HEAD") and self.get_shallow():
            logger.err("Shallow clones are not compatible with specifying a specific commit.")
            success = False

        # check if git is installed
        try:
            subprocess.check_output(["which", "git"]).decode().rstrip("\n")
        except subprocess.CalledProcessError:
            logger.log("Install git to use the specified source.")
            success = False

        return success
示例#10
0
    def verify(self) -> bool:
        """
        This method runs several checks to ensure mock builds can proceed. It is automatically
        executed at package initialisation. This includes:

        * checks if all expected keys are present in the configuration file
        * checks if the `mock` binary is installed and can be found on the system
        * checks if the current user is allowed to run builds with mock
        * checks if the current user is root (building as root is strongly discouraged)

        Returns:
            bool:   verification success
        """

        logger = KtrLogger(LOG_PREFIX)

        success = True

        # check if the configuration file is valid
        expected_keys = ["active", "dists", "export", "keep"]

        for key in expected_keys:
            if key not in self.bpkg.conf["mock"]:
                logger.err("The [mock] section in the package's .conf file doesn't set the '" +
                           key +
                           "' key.")
                success = False

        # check if mock is installed
        try:
            subprocess.check_output(["which", "mock"]).decode().rstrip("\n")
        except subprocess.CalledProcessError:
            logger.log("Install mock to use the specified builder.")
            success = False

        # check if the user is in the "mock" group or is root
        mock_group = grp.getgrnam("mock")
        mock_user = os.getenv("USER")

        if mock_user not in mock_group.gr_mem:
            logger.err("The current user is not allowed to use mock.")
            logger.err("Add yourself to the 'mock' group, log out and back in.")
            success = False

        if mock_user == "root":
            logger.err("Don't attempt to run mock as root.")
            success = False

        return success
示例#11
0
    def execute(self) -> bool:
        """
        This method runs the "chain reaction" corresponding to the package specified at
        initialisation, with the configuration from the package configuration file.

        Returns:
            bool:   ``True`` if chain went all the way through, ``False`` if not
        """

        ktr = Kentauros()
        logger = KtrLogger(LOGPREFIX)
        force = ktr.cli.get_force()

        success = True

        for module in self.kpkg.get_modules():
            succeeded = module.execute()

            if not succeeded:
                logger.err("Execution of module '" + str(module) + "' wasn't successful.")

                if force:
                    logger.log("Execution is forced to continue.")
                    success = success and succeeded
                    continue
                else:
                    success = False
                    break

        self.update_status()

        if success:
            logger.log(self.kpkg.get_conf_name() + ": Success!")
        else:
            logger.log(self.kpkg.get_conf_name() + ": Not successful.")

        return success
示例#12
0
    def verify(self) -> bool:
        """
        This method runs several checks to ensure srpm builds can proceed. It is automatically
        executed at package initialisation. This includes:

        * checks if all expected keys are present in the configuration file
        * checks if the `mock` binary is installed and can be found on the system
        * checks if the current user is allowed to run builds with mock
        * checks if the current user is root (building as root is strongly discouraged)
        * checks if the .spec file is present at the expected location

        Returns:
            bool:   verification success
        """

        logger = KtrLogger(LOG_PREFIX)

        success = True

        # check if the configuration file is valid
        expected_keys = []

        for key in expected_keys:
            if key not in self.cpkg.conf["srpm"]:
                logger.err("The [srpm] section in the package's .conf file doesn't set the '" +
                           key +
                           "' key.")
                success = False

        # check for .spec file presence
        if not os.path.exists(self.path):
            logger.err("Spec file has not been found at the expected location:")
            logger.err(self.path)
            success = False

        # check if rpmbuild and rpmdev-bumpspec are installed
        try:
            subprocess.check_output(["which", "rpmbuild"]).decode().rstrip("\n")
        except subprocess.CalledProcessError:
            logger.log("Install rpm-build to use the srpm constructor.")
            success = False

        try:
            subprocess.check_output(["which", "rpmdev-bumpspec"]).decode().rstrip("\n")
        except subprocess.CalledProcessError:
            logger.log("Install rpmdevtools to use the srpm constructor.")
            success = False

        return success
示例#13
0
    def prepare(self) -> bool:
        """
        This method prepares all files necessary for source package assembly.

        This includes

        - copying every file (not directories) from package source directory to `rpmbuild/SOURCES`,
        - removing the latest tarball from the package source directory if it should not be kept,
        - copying the package configuration file to `rpmbuild/SOURCES`
        - preparing the `package.spec` file in `rpmbuild/SPECS` from the file in the spec directory,
        - defining macros for git and bzr version string additions,
        - setting `Version:` and `Release:` tags according to configuration,
        - appending a changelog entry automatically for every different build,
        - copying back the modified spec file to preserve added changelog entries.

        Returns:
            bool:           returns `True` if the preparation was successful.
        """

        ktr = Kentauros()
        logger = KtrLogger(LOG_PREFIX)

        spec = RPMSpec(self.path, self.cpkg.get_module("source"))

        if not os.path.exists(self.rpmbdir):
            warnings.warn("Make sure to call Constructor.init() before .prepare()!", Warning)
            self.init()

        # copy sources to rpmbuild/SOURCES
        for entry in os.listdir(self.cpkg.get_module("source").sdir):
            entry_path = os.path.join(self.cpkg.get_module("source").sdir, entry)
            if os.path.isfile(entry_path):
                shutil.copy2(entry_path, self.srcsdir)
                logger.log("File copied to SOURCES: " + entry_path, 1)

        # remove tarballs if they should not be kept
        if not self.cpkg.get_module("source").get_keep():

            # if source is a tarball (or similar) from the beginning:
            if os.path.isfile(self.cpkg.get_module("source").dest):
                os.remove(self.cpkg.get_module("source").dest)

            # otherwise it is in kentauros' standard .tar.gz format:
            else:
                tarballs = glob.glob(os.path.join(self.cpkg.get_module("source").sdir,
                                                  self.cpkg.get_name()) + "*.tar.gz")
                # remove only the newest one to be safe
                tarballs.sort(reverse=True)
                if os.path.isfile(tarballs[0]):
                    assert self.cpkg.get_module("source").sdir in tarballs[0]
                    os.remove(tarballs[0])
                    logger.log("Tarball removed: " + tarballs[0], 1)

        # copy package.conf to rpmbuild/SOURCES
        shutil.copy2(self.cpkg.file, self.srcsdir)
        logger.log("Package configuration copied to SOURCES: " + self.cpkg.file, 1)

        # construct preamble and new version string
        old_version = self._get_last_version(spec)
        old_release = self._get_last_release(spec)
        new_version = self.cpkg.get_version()

        # TODO: check if release resetting / incrementing logic works now

        spec.set_version()
        spec.set_source()

        # if old version and new version are different, force release reset to 0
        rel_reset = (new_version != old_version)

        # start constructing release string from old release string
        if rel_reset:
            spec.do_release_reset()

        # write preamble to new spec file
        preamble = spec.build_preamble_string()

        # calculate absolute path of new spec file and copy it over
        new_spec_path = os.path.join(self.specdir, self.cpkg.get_name() + ".spec")
        spec.export_to_file(new_spec_path)

        # use "rpmdev-bumpspec" to increment release number and create changelog entries
        force = ktr.cli.get_force()

        logger.dbg("Old Version: " + old_version)
        logger.dbg("New Version: " + new_version)
        logger.dbg("Old Release: " + old_release)

        # if major version has changed, put it into the changelog
        if (old_version != new_version) or (old_release[0] == "0"):
            do_release_bump(new_spec_path,
                            "Update to version " + self.cpkg.get_version() + ".")
            new_rpm_spec = RPMSpec(new_spec_path, self.cpkg.get_module("source"))

        # else if nothing changed but "force" was set (packaging changes)
        # old_version =!= new_version, rel_reset !=!= True
        elif force:
            message = ktr.cli.get_message()
            if message is None:
                do_release_bump(new_spec_path, "Update for packaging changes.")
            else:
                do_release_bump(new_spec_path, message)

            new_rpm_spec = RPMSpec(new_spec_path, self.cpkg.get_module("source"))

        # else if version has not changed, but snapshot has been updated:
        # old_version =!= new_version
        elif rel_reset:
            new_rpm_spec = RPMSpec(new_spec_path, self.cpkg.get_module("source"))
            new_rpm_spec.do_release_reset()
            do_release_bump(new_spec_path, "Update to latest snapshot.")
            new_rpm_spec = RPMSpec(new_spec_path, self.cpkg.get_module("source"))

        else:
            logger.err("Something went wrong.")
            return False

        self.last_release = new_rpm_spec.get_release()
        self.last_version = new_rpm_spec.get_version()

        # copy new spec file back to ktr/specdir to preserve version tracking,
        # release number and changelog consistency (keep old version once as backup)
        # BUT: remove preamble again, it would break things otherwise

        new_rpm_spec.contents = new_rpm_spec.contents.replace(preamble, "")
        shutil.copy2(self.path, self.path + ".old")
        new_rpm_spec.export_to_file(self.path)

        return True
示例#14
0
    def get(self) -> bool:
        """
        This method executes the git repository download to the package source directory. This
        respects the branch and commit set in the package configuration file.

        Returns:
            bool: *True* if successful, *False* if not or source pre-exists
        """

        ktr = Kentauros()
        logger = KtrLogger(LOG_PREFIX)

        # check if $KTR_BASE_DIR/sources/$PACKAGE exists and create if not
        if not os.access(self.sdir, os.W_OK):
            os.makedirs(self.sdir)

        # if source directory seems to already exist, return False
        if os.access(self.dest, os.R_OK):
            rev = self.commit()
            logger.log("Sources already downloaded. Latest commit id:", 2)
            logger.log(rev, 2)
            return False

        # check for connectivity to server
        if not is_connected(self.get_orig()):
            logger.log("No connection to remote host detected. Cancelling source checkout.", 2)
            return False

        # construct clone command
        cmd_clone = ["git", "clone"]

        # add --verbose or --quiet depending on settings
        if (ktr.verby == 2) and not ktr.debug:
            cmd_clone.append("--quiet")
        if (ktr.verby == 0) or ktr.debug:
            cmd_clone.append("--verbose")

        # set --depth==1 if shallow is specified
        if self.get_shallow():
            cmd_clone.append("--depth=1")

        # set branch if specified
        if self.get_branch():
            cmd_clone.append("--branch")
            cmd_clone.append(self.get_branch())

        # set origin and destination
        cmd_clone.append(self.get_orig())
        cmd_clone.append(self.dest)

        # clone git repo from origin to destination
        logger.log_command(cmd_clone, 1)
        subprocess.call(cmd_clone)

        # if commit is specified: checkout commit
        if self.get_commit():
            # construct checkout command
            cmd_checkout = ["git", "checkout", self.get_commit()]

            # go to git repo and remember old cwd
            prev_dir = os.getcwd()
            os.chdir(self.dest)

            # checkout commit
            logger.log_command(cmd_checkout, 1)
            subprocess.call(cmd_checkout)

            # go to previous dir
            os.chdir(prev_dir)

        # get commit ID
        rev = self.commit()
        self.date()

        # check if checkout worked
        if self.get_commit() != "HEAD":
            if self.get_commit() != rev:
                logger.err("Something went wrong, requested commit not checked out.")
                return False

        # return True if successful
        return True
示例#15
0
    def verify(self) -> bool:
        """
        This method verifies that the absolute minimum for proceeding with package initialisation is
        set. This also ensures the validity of some entries.

        Returns:
            bool:   *True* if configuration is minimally valid, *False* if entries are missing
        """

        assert isinstance(self.conf, ConfigParser)

        logger = KtrLogger(LOG_PREFIX)

        success = True

        # [package]
        if "package" not in self.conf.sections():
            logger.err("Package configuration file does not have a 'package' section.")
            success = False

        # name =
        if "name" not in self.conf["package"]:
            logger.err("Package configuration file doesn't set 'name' in the 'package' section.")
            success = False

        if self.conf.get("package", "name") == "":
            logger.err("Package configuration file doesn't set 'name' in the 'package' section.")
            success = False

        # version =
        if "version" not in self.conf["package"]:
            logger.err("Package configuration file doesn't set 'version' in the 'package' section.")
            success = False

        if "-" in self.conf.get("package", "version"):
            logger.err("Hyphens are not a valid part of a version string.")
            logger.err("Replace it with another character, e.g. '~' or '+'.")
            success = False

        # modules =
        if self.conf.get("package", "modules") == "":
            logger.err("Package configuration file doesn't set 'modules' in the 'package' section.")
            success = False

        # [modules]
        if "modules" not in self.conf.sections():
            logger.err("Package configuration file does not have a 'modules' section.")
            success = False

        modules_str = str(self.conf.get("package", "modules"))
        module_list = modules_str.split(",")

        if module_list == [""]:
            module_list = []

        # check if the module is recognised
        for module in module_list:
            try:
                PkgModuleType[module.upper()]
            except KeyError:
                raise PackageError("Module '" + module + "' is not one of the recognised modules.")

        # check if modules are defined in the [modules] section
        for module in module_list:
            if module not in self.conf["modules"]:
                logger.err("Package configuration file doesn't define module '" +
                           module +
                           "' in the 'modules' section.")
                success = False

        # check if each module has its configuration section
        for module in module_list:
            if self.conf.get("modules", module) not in self.conf.sections():
                logger.err("Package configuration file doesn't have a section for module '" +
                           module +
                           "'.")
                success = False

        return success
示例#16
0
    def export(self) -> bool:
        """
        This method executes the export from the package source repository to a tarball with pretty
        file name. It also respects the `git.keep=False` setting in the package configuration file -
        the git repository will be deleted from disk after the export if this flag is set.

        Returns:
            bool:   *True* if successful or already done, *False* at failure
        """

        ktr = Kentauros()
        logger = KtrLogger(LOG_PREFIX)

        def remove_not_keep():
            """
            This local function removes the git repository and is called after source export, if
            not keeping the repository around was specified in the configuration file.
            """

            if not self.get_keep():
                # try to be careful with "rm -r"
                assert os.path.isabs(self.dest)
                assert ktr.conf.get_datadir() in self.dest
                shutil.rmtree(self.dest)
                logger.log("git repository has been deleted after exporting to tarball.", 1)

        # construct git command to export HEAD or specified commit
        cmd = ["git", "archive", self.get_commit()]

        # check if git repo exists
        if not os.access(self.dest, os.R_OK):
            logger.err("Sources need to be get before they can be exported.")
            return False

        version = self.formatver()
        name_version = self.spkg.get_name() + "-" + version

        # add prefix
        cmd.append("--prefix=" + name_version + "/")

        file_name = os.path.join(self.sdir, name_version + ".tar.gz")

        cmd.append("--output")
        cmd.append(file_name)

        # check if file has already been exported
        if os.path.exists(file_name):
            logger.log("Tarball has already been exported.", 1)
            # remove git repo if keep is False
            remove_not_keep()
            return True

        # remember previous directory
        prev_dir = os.getcwd()

        # change to git repository directory
        os.chdir(self.dest)

        # export tar.gz to $KTR_DATA_DIR/$PACKAGE/*.tar.gz
        logger.log_command(cmd, 1)
        subprocess.call(cmd)

        # update saved rev and date
        self.commit()
        self.date()

        # remove git repo if keep is False
        remove_not_keep()

        os.chdir(prev_dir)
        return True
示例#17
0
    def export(self) -> bool:
        """
        This method executes the export from the package source repository to a tarball with pretty
        file name. It also respects the `bzr.keep=False` setting in the package configuration file -
        the bzr repository will be deleted from disk after the export if this flag is set.

        Returns:
            bool:       `True` if successful, `False` if not or already exported
        """

        ktr = Kentauros()
        logger = KtrLogger(LOG_PREFIX)

        def remove_not_keep():
            """
            This local function removes the bzr repository and is called after source export, if
            not keeping the repository around was specified in the configuration file.
            """

            if not self.get_keep_repo():
                # try to be careful with "rm -r"
                assert os.path.isabs(self.dest)
                assert ktr.conf.get_datadir() in self.dest
                shutil.rmtree(self.dest)
                logger.log("bzr repository deleted after export to tarball", 1)

        # construct bzr command
        cmd = ["bzr", "export"]

        # add --verbose or --quiet depending on settings
        if (ktr.verby == 2) and not ktr.debug:
            cmd.append("--quiet")
        if (ktr.verby == 0) or ktr.debug:
            cmd.append("--verbose")

        # export HEAD or specified commit
        if self.get_revno():
            cmd.append("--revision")
            cmd.append(self.get_revno())

        # check if bzr repo exists
        if not os.access(self.dest, os.R_OK):
            logger.err("Sources need to be get before they can be exported.")
            return False

        version = self.formatver()
        name_version = self.spkg.get_name() + "-" + version

        file_name = os.path.join(self.sdir, name_version + ".tar.gz")

        cmd.append(file_name)

        # check if file has already been exported
        if os.path.exists(file_name):
            logger.log("Tarball has already been exported.", 1)
            # remove bzr repo if keep is False
            remove_not_keep()
            return False

        # remember previous directory
        prev_dir = os.getcwd()

        # change to git repository directory
        os.chdir(self.dest)

        # export tar.gz to $KTR_DATA_DIR/$PACKAGE/*.tar.gz
        logger.log_command(cmd, 1)
        subprocess.call(cmd)

        # update saved rev
        self.rev()

        # remove bzr repo if keep is False
        remove_not_keep()

        os.chdir(prev_dir)
        return True
示例#18
0
    def get(self) -> bool:
        """
        This method executes the bzr repository download to the package source directory. This
        respects the branch and revision set in the package configuration file.

        Returns:
            bool:  `True` if successful, `False` if not or source already exists
        """

        ktr = Kentauros()
        logger = KtrLogger(LOG_PREFIX)

        # check if $KTR_BASE_DIR/sources/$PACKAGE exists and create if not
        if not os.access(self.sdir, os.W_OK):
            os.makedirs(self.sdir)

        # if source directory seems to already exist, return False
        if os.access(self.dest, os.R_OK):
            rev = self.rev()
            logger.log("Sources already downloaded. Latest revision: " + str(rev), 1)
            return False

        # check for connectivity to server
        if not is_connected(self.remote):
            logger.log("No connection to remote host detected. Cancelling source checkout.", 2)
            return False

        # construct bzr command
        cmd = ["bzr", "branch"]

        # add --verbose or --quiet depending on settings
        if (ktr.verby == 2) and not ktr.debug:
            cmd.append("--quiet")
        if (ktr.verby == 0) or ktr.debug:
            cmd.append("--verbose")

        # set origin
        if not self.get_branch():
            cmd.append(self.get_orig())
        else:
            cmd.append(self.get_orig() + "/" + self.get_branch())

        # set revision is specified
        if self.get_revno():
            cmd.append("--revision")
            cmd.append(self.get_revno())

        # set destination
        cmd.append(self.dest)

        # branch bzr repo from origin to destination
        logger.log_command(cmd, 1)
        subprocess.call(cmd)

        # get commit ID
        rev = self.rev()

        # check if checkout worked
        if self.get_revno():
            if self.get_revno() != rev:
                logger.err("Something went wrong, requested commit not available.")
                return False

        # return True if successful
        return True
示例#19
0
def run():
    """
    This function is corresponding to (one of) the "main" function of the `kentauros` package and is
    the entry point used by the `ktr.py` script from git and the script installed at installation.
    """

    ktr = Kentauros()
    logger = KtrLogger(LOG_PREFIX)

    print_parameters()

    # if no action is specified: exit
    if ktr.cli.get_action() is None:
        logger.log("No action specified. Exiting.")
        logger.log("Use 'ktr --help' for more information.")
        print_flush()
        return

    if not ktr_bootstrap():
        raise SystemExit()

    packages = list()

    # if only specified packages are to be processed: process packages from CLI only
    if not ktr.cli.get_packages_all():
        packages = ktr.cli.get_packages().copy()

        for pkg in packages:
            pkg_conf_path = os.path.join(ktr.conf.get_confdir(), pkg + ".conf")

            if not os.path.exists(pkg_conf_path):
                logger.err("Package configuration for '" + pkg + "' could not be found.")
                packages.remove(pkg)

    # if all package are to be processed: get package configs present in the package configuration
    # directory
    else:
        pkg_conf_paths = glob.glob(os.path.join(ktr.conf.get_confdir(), "*.conf"))

        for pkg_conf_path in pkg_conf_paths:
            packages.append(os.path.basename(pkg_conf_path).replace(".conf", ""))

    if not packages:
        logger.log("No packages have been specified or found. Exiting.")
        print_flush()
        raise SystemExit()

    packages.sort()

    # log list of found packages
    logger.log_list("Packages", packages)
    print_flush()

    # generate package objects
    for name in packages:
        assert isinstance(name, str)

        try:
            pkg = Package(name)
            ktr.add_package(name, pkg)
        except PackageError:
            logger.log("Package with configuration file '" + name + "' is invalid, skipping.")
            continue

    actions_success = list()
    actions_failure = list()

    # run action for every specified package
    for name in ktr.get_package_names():
        assert isinstance(name, str)

        if ktr.state_read(name) is None:
            logger.log("Importing new package into the database.")
            import_action = ImportAction(name)
            import_action.execute()

        action_type = ktr.cli.get_action()
        action = ACTION_DICT[action_type](name)
        success = action.execute()

        if success:
            actions_success.append(name)
        else:
            actions_failure.append(name)

    print_flush()

    if actions_success:
        logger.log_list("Successful actions", actions_success)

    if actions_failure:
        logger.log_list("Failed actions", actions_failure)

    print_flush()

    raise SystemExit()