コード例 #1
0
    def test_bootstrap_workspace(self):
        self.leaf_exec("init")
        self.leaf_exec(("profile", "create"), "foo")
        self.leaf_exec(("profile", "config"), "-p", "container-A")
        self.leaf_exec(("profile", "sync"))
        self.check_current_profile("foo")
        self.leaf_exec(("profile", "create"), "bar")
        self.check_current_profile("bar")
        self.leaf_exec("status")
        self.leaf_exec(("env", "print"))
        self.check_profile_content(
            "foo", ["container-A", "container-C", "container-D"])
        data_folder = self.workspace_folder / LeafFiles.WS_DATA_FOLDERNAME
        self.assertTrue(data_folder.exists())
        rmtree_force(data_folder)
        self.assertFalse(data_folder.exists())

        self.leaf_exec("status")
        self.leaf_exec(("env", "print"), expected_rc=2)
        self.leaf_exec(("profile", "switch"), "foo")
        self.check_current_profile("foo")
        self.leaf_exec(("env", "print"), expected_rc=2)
        self.leaf_exec(("profile", "sync"))
        self.leaf_exec(("env", "print"))
        self.check_profile_content(
            "foo", ["container-A", "container-C", "container-D"])
コード例 #2
0
 def tearDown(self):
     # Reset env
     LeafSettings.VERBOSITY.value = None
     LeafSettings.CONFIG_FOLDER.value = None
     LeafSettings.CACHE_FOLDER.value = None
     LeafSettings.USER_PKG_FOLDER.value = None
     # Clean volatile folder
     rmtree_force(self.volatile_folder)
コード例 #3
0
ファイル: packages.py プロジェクト: NicolasLambert/leaf
    def __extract_artifact(
            self,
            la: LeafArtifact,
            env: Environment,
            install_folder: Path,
            ipmap: dict = None,
            keep_folder_on_error: bool = False) -> InstalledPackage:
        """
        Install a leaf artifact
        @return InstalledPackage
        """
        target_folder = install_folder / str(la.identifier)
        if target_folder.is_dir():
            raise LeafException(
                "Folder already exists: {folder}".format(folder=target_folder))

        # Check already installed
        ipmap = ipmap or self.list_installed_packages()
        if la.identifier in ipmap:
            raise LeafException(
                "Package is already installed: {la.identifier}".format(la=la))

        # Check leaf min version
        min_version = check_leaf_min_version([la])
        if min_version:
            raise LeafOutOfDateException(
                "You need to upgrade leaf to v{version} to install {la.identifier}"
                .format(version=min_version, la=la))

        # Create folder
        target_folder.mkdir(parents=True)

        try:
            # Extract content
            self.logger.print_verbose("Extract {la.path} in {dest}".format(
                la=la, dest=target_folder))
            with TarFile.open(str(la.path)) as tf:
                tf.extractall(str(target_folder))
            # Execute post install steps
            out = InstalledPackage(target_folder / LeafFiles.MANIFEST)
            ipmap[out.identifier] = out
            self.__execute_steps(out.identifier,
                                 ipmap,
                                 StepExecutor.install,
                                 env=env)
            return out
        except Exception as e:
            self.logger.print_error("Error during installation:", e)
            if keep_folder_on_error:
                target_folder = mark_folder_as_ignored(target_folder)
                self.logger.print_verbose(
                    "Mark folder as ignored: {folder}".format(
                        folder=target_folder))
            else:
                self.logger.print_verbose(
                    "Remove folder: {folder}".format(folder=target_folder))
                rmtree_force(target_folder)
            raise e
コード例 #4
0
ファイル: testutils.py プロジェクト: sam974/leaf
    def setUp(self):
        if self.verbosity and LEAF_UT_SKIP.is_set():
            if self.verbosity.lower() in LEAF_UT_SKIP.value.lower():
                self.skipTest("Verbosity {verbosity} is ignored".format(verbosity=self.verbosity))

        # Clean volatile folder just in case
        rmtree_force(self.volatile_folder)
        # Setup leaf via env
        LeafSettings.VERBOSITY.value = self.verbosity
        LeafSettings.CONFIG_FOLDER.value = self.config_folder
        LeafSettings.CACHE_FOLDER.value = self.cache_folder
        LeafSettings.USER_PKG_FOLDER.value = self.install_folder
コード例 #5
0
ファイル: packages.py プロジェクト: NicolasLambert/leaf
    def uninstall_packages(self, pilist: list):
        """
        Remove given package
        """
        with self.application_lock.acquire():
            ipmap = self.list_installed_packages()

            iplist_to_remove = DependencyUtils.uninstall(pilist,
                                                         ipmap,
                                                         logger=self.logger)

            if len(iplist_to_remove) == 0:
                self.logger.print_default("No package to remove")
            else:
                # Confirm
                text = ", ".join(
                    [str(ip.identifier) for ip in iplist_to_remove])
                self.logger.print_quiet(
                    "Packages to uninstall: {packages}".format(packages=text))
                self.print_with_confirm(raise_on_decline=True)
                for ip in iplist_to_remove:
                    if ip.read_only:
                        raise LeafException(
                            "Cannot uninstall system package {ip.identifier}".
                            format(ip=ip))
                    self.logger.print_default(
                        "Removing {ip.identifier}".format(ip=ip))
                    self.__execute_steps(ip.identifier, ipmap,
                                         StepExecutor.uninstall)
                    self.logger.print_verbose(
                        "Remove folder: {ip.folder}".format(ip=ip))
                    rmtree_force(ip.folder)
                    del ipmap[ip.identifier]

                self.logger.print_default("{count} package(s) removed".format(
                    count=len(iplist_to_remove)))
コード例 #6
0
 def tearDownClass(cls):
     # Do not remove folder in case of debug
     if not LEAF_UT_DEBUG.as_boolean():
         rmtree_force(LeafTestCase._TEST_FOLDER)
コード例 #7
0
    return line


def check_content(tester: TestCase, template_file: Path, lines: list,
                  variables: dict):
    if template_file is None:
        # No check
        return

    if LEAF_UT_CREATE_TEMPLATE.as_boolean():
        # Generate template if envar is set
        if not template_file.parent.exists():
            template_file.parent.mkdir()
        with template_file.open("w") as fp:
            for line in lines:
                fp.write(replace_vars(line, variables, reverse=True) + "\n")

    # Check content with actual content
    template_lines = list(
        map(lambda l: replace_vars(l, variables, reverse=False),
            get_lines(template_file)))
    tester.assertEqual(lines, template_lines)


if __name__ == "__main__":
    output = Path("/tmp/leaf/repository")
    print("Generate repository in {output}".format(output=output))
    rmtree_force(output)
    mkdirs(output)
    generate_repository(TEST_REMOTE_PACKAGE_SOURCE, output)
コード例 #8
0
ファイル: packages.py プロジェクト: NicolasLambert/leaf
    def install_packages(self,
                         pilist: list,
                         env: Environment = None,
                         keep_folder_on_error: bool = False):
        """
        Compute dependency tree, check compatibility, download from remotes and extract needed packages
        @return: InstalledPackage list
        """
        with self.application_lock.acquire():
            prereq_install_folder = None
            ipmap = self.list_installed_packages()
            apmap = self.list_available_packages()
            out = []

            # Build env to resolve dynamic dependencies
            if env is None:
                env = Environment.build(self.build_builtin_environment(),
                                        self.build_user_environment())

            try:
                ap_to_install = DependencyUtils.install(pilist,
                                                        apmap,
                                                        ipmap,
                                                        env=env)

                # Check leaf min version
                min_version = check_leaf_min_version(ap_to_install)
                if min_version:
                    raise LeafOutOfDateException(
                        "You need to upgrade leaf to v{version} to install {text}"
                        .format(version=min_version,
                                text=", ".join([
                                    str(ap.identifier) for ap in ap_to_install
                                ])))

                # Check nothing to do
                if len(ap_to_install) == 0:
                    self.logger.print_default("All packages are installed")
                else:
                    # Check available size
                    download_totalsize = 0
                    for ap in ap_to_install:
                        if ap.size is not None:
                            download_totalsize += ap.size
                    fs_check_free_space(self.download_cache_folder,
                                        download_totalsize)

                    # Confirm
                    text = ", ".join(
                        [str(ap.identifier) for ap in ap_to_install])
                    self.logger.print_quiet(
                        "Packages to install: {packages}".format(
                            packages=text))
                    if download_totalsize > 0:
                        self.logger.print_default(
                            "Total size:", sizeof_fmt(download_totalsize))
                    self.print_with_confirm(raise_on_decline=True)

                    # Install prereq
                    prereq_to_install = DependencyUtils.prereq(pilist,
                                                               apmap,
                                                               ipmap,
                                                               env=env)

                    if len(prereq_to_install) > 0:
                        self.logger.print_default("Check required packages")
                        prereq_install_folder = mkdir_tmp_leaf_dir()
                        self.install_prereq(
                            [p.identifier for p in prereq_to_install],
                            prereq_install_folder,
                            apmap=apmap,
                            env=env)

                    # Download ap list
                    self.logger.print_default(
                        "Downloading {size} package(s)".format(
                            size=len(ap_to_install)))
                    la_to_install = []
                    for ap in ap_to_install:
                        la_to_install.append(self.__download_ap(ap))

                    # Check the extracted size
                    extracted_totalsize = 0
                    for la in la_to_install:
                        if la.final_size is not None:
                            extracted_totalsize += la.final_size
                        else:
                            extracted_totalsize += la.get_total_size()
                    fs_check_free_space(self.install_folder,
                                        extracted_totalsize)

                    # Extract la list
                    for la in la_to_install:
                        self.logger.print_default(
                            "[{current}/{total}] Installing {la.identifier}".
                            format(current=(len(out) + 1),
                                   total=len(la_to_install),
                                   la=la))
                        ip = self.__extract_artifact(
                            la,
                            env,
                            self.install_folder,
                            ipmap=ipmap,
                            keep_folder_on_error=keep_folder_on_error)
                        out.append(ip)

            finally:
                if not keep_folder_on_error and prereq_install_folder is not None:
                    self.logger.print_verbose(
                        "Remove prereq root folder {folder}".format(
                            folder=prereq_install_folder))
                    rmtree_force(prereq_install_folder)

            return out