Пример #1
0
    def test_resolve_latest(self):

        deps = DependencyUtils.install(
            PackageIdentifier.parse_list(["testlatest_1.0"]), APMAP, {})
        self.assertEqual(["version_2.0", "testlatest_1.0"],
                         list(map(str, map(IDENTIFIER_GETTER, deps))))

        deps = DependencyUtils.install(
            PackageIdentifier.parse_list(["testlatest_1.0"]), APMAP,
            filtermap(IPMAP, "version_1.0"))
        self.assertEqual(["version_2.0", "testlatest_1.0"],
                         list(map(str, map(IDENTIFIER_GETTER, deps))))

        deps = DependencyUtils.install(
            PackageIdentifier.parse_list(["testlatest_1.0"]), APMAP,
            filtermap(IPMAP, "version_2.0"))
        self.assertEqual(["testlatest_1.0"],
                         list(map(str, map(IDENTIFIER_GETTER, deps))))

        deps = DependencyUtils.prereq(
            PackageIdentifier.parse_list(["testlatest_2.0"]), APMAP, {})
        self.assertEqual(["version_2.0"],
                         list(map(str, map(IDENTIFIER_GETTER, deps))))

        deps = DependencyUtils.prereq(
            PackageIdentifier.parse_list(["testlatest_2.0", "testlatest_2.1"]),
            APMAP, {})
        self.assertEqual(["version_2.0"],
                         list(map(str, map(IDENTIFIER_GETTER, deps))))
Пример #2
0
    def test_depends_install(self):
        deps = DependencyUtils.install(PackageIdentifier.parse_list([]),
                                       self.pm.list_available_packages(),
                                       self.pm.list_installed_packages())
        self.__assert_deps(deps, [], AvailablePackage)

        deps = DependencyUtils.install(
            PackageIdentifier.parse_list(["container-A_1.0"]),
            self.pm.list_available_packages(),
            self.pm.list_installed_packages())
        self.__assert_deps(deps, [
            "container-E_1.0", "container-B_1.0", "container-C_1.0",
            "container-A_1.0"
        ], AvailablePackage)

        self.pm.install_packages(
            PackageIdentifier.parse_list(["container-A_1.0"]))

        deps = DependencyUtils.install(
            PackageIdentifier.parse_list(["container-A_1.0"]),
            self.pm.list_available_packages(),
            self.pm.list_installed_packages())
        self.__assert_deps(deps, [], AvailablePackage)

        deps = DependencyUtils.install(
            PackageIdentifier.parse_list(["container-A_2.0"]),
            self.pm.list_available_packages(),
            self.pm.list_installed_packages())
        self.__assert_deps(deps, ["container-D_1.0", "container-A_2.0"],
                           AvailablePackage)
Пример #3
0
    def test_install(self):
        deps = DependencyUtils.install(PackageIdentifier.parse_list(
            ["container-A_1.0", "container-A_2.0"]),
                                       APMAP, {},
                                       env=Environment())
        self.assertEqual([
            "container-E_1.0", "container-B_1.0", "container-C_1.0",
            "container-A_1.0", "container-D_1.0", "container-A_2.0"
        ], deps2strlist(deps))

        deps = DependencyUtils.install(PackageIdentifier.parse_list(
            ["container-A_1.0", "container-A_2.0"]),
                                       APMAP,
                                       filtermap(IPMAP, "container-E_1.0"),
                                       env=Environment())
        self.assertEqual([
            "container-B_1.0", "container-C_1.0", "container-A_1.0",
            "container-D_1.0", "container-A_2.0"
        ], deps2strlist(deps))
    def test_depends_with_custom_env(self):
        env = Environment.build(self.pm.build_builtin_environment(), self.pm.build_user_environment(), Environment("Custom env", {}))
        deps = DependencyUtils.install(
            PackageIdentifier.parse_list(["condition_1.0"]), self.pm.list_available_packages(), self.pm.list_installed_packages(), env=env
        )
        self.__assert_deps(deps, ["condition-B_1.0", "condition-D_1.0", "condition-F_1.0", "condition-H_1.0", "condition_1.0"], AvailablePackage)

        self.pm.update_user_environment(set_map={"FOO": "HELLO"})
        env = Environment.build(self.pm.build_builtin_environment(), self.pm.build_user_environment(), Environment("Custom env", {}))
        deps = DependencyUtils.install(
            PackageIdentifier.parse_list(["condition_1.0"]), self.pm.list_available_packages(), self.pm.list_installed_packages(), env=env
        )
        self.__assert_deps(deps, ["condition-A_1.0", "condition-D_1.0", "condition-F_1.0", "condition-H_1.0", "condition_1.0"], AvailablePackage)

        self.pm.update_user_environment(set_map={"FOO": "HELLO"})
        env = Environment.build(self.pm.build_builtin_environment(), self.pm.build_user_environment(), Environment("Custom env", {"FOO": "BAR"}))
        deps = DependencyUtils.install(
            PackageIdentifier.parse_list(["condition_1.0"]), self.pm.list_available_packages(), self.pm.list_installed_packages(), env=env
        )
        self.__assert_deps(deps, ["condition-A_1.0", "condition-C_1.0", "condition-F_1.0", "condition_1.0"], AvailablePackage)
Пример #5
0
    def provision_profile(self, profile):
        if not profile.folder.is_dir():
            # Create folder if needed
            profile.folder.mkdir(parents=True)
        else:
            # Clean folder content
            for item in profile.folder.glob("*"):
                if item.is_symlink():
                    item.unlink()
                else:
                    shutil.rmtree(str(item))

        # Check if all needed packages are installed
        missing_packages = DependencyUtils.install(
            profile.packages,
            self.list_available_packages(),
            self.list_installed_packages(),
            env=self.build_pf_environment(profile))
        if len(missing_packages) == 0:
            self.logger.print_verbose("All packages are already installed")
        else:
            self.logger.print_default("Profile is out of sync")
            try:
                self.install_packages(profile.packages,
                                      env=self.build_pf_environment(profile))
            except Exception as e:
                raise ProfileProvisioningException(e)

        # Do all needed links
        errors = 0
        for ip in self.get_profile_dependencies(profile):
            pi_folder = profile.folder / ip.identifier.name
            if pi_folder.exists():
                pi_folder = profile.folder / str(ip.identifier)
            try:
                env = self.build_pf_environment(profile)
                self.sync_packages([ip.identifier], env=env)
                pi_folder.symlink_to(ip.folder)
            except Exception as e:
                errors += 1
                self.logger.print_error(
                    "Error while sync operation on {ip.identifier}".format(
                        ip=ip))
                self.logger.print_error(str(e))
                print_trace()

        # Touch folder when provisionning is done without error
        if errors == 0:
            profile.folder.touch(exist_ok=True)
Пример #6
0
    def test_uninstall(self):

        ipmap = OrderedDict()
        for ap in DependencyUtils.install(
                PackageIdentifier.parse_list(
                    ["container-A_1.0", "container-A_2.0"]), APMAP, {}):
            ipmap[ap.identifier] = IPMAP[ap.identifier]

        self.assertEqual([
            "container-E_1.0", "container-B_1.0", "container-C_1.0",
            "container-A_1.0", "container-D_1.0", "container-A_2.0"
        ], deps2strlist(ipmap.values()))

        deps = DependencyUtils.uninstall(
            PackageIdentifier.parse_list(["container-A_1.0"]), ipmap)

        self.assertEqual(
            ["container-A_1.0", "container-B_1.0", "container-E_1.0"],
            deps2strlist(deps))
Пример #7
0
    def test_prereq(self):
        prereqs = DependencyUtils.prereq(
            PackageIdentifier.parse_list(["pkg-with-prereq_1.0"]), APMAP, {})
        self.assertEqual(list(map(str, prereqs)),
                         ["prereq-A_1.0", "prereq-B_1.0"])
        for p in prereqs:
            self.assertTrue(isinstance(p, AvailablePackage))

        prereqs = DependencyUtils.prereq(
            PackageIdentifier.parse_list(["pkg-with-prereq_1.0"]), APMAP,
            IPMAP)
        self.assertEqual(list(map(str, prereqs)),
                         ["prereq-A_1.0", "prereq-B_1.0"])
        for p in prereqs:
            self.assertTrue(isinstance(p, InstalledPackage))

        prereqs = DependencyUtils.prereq(
            PackageIdentifier.parse_list(["pkg-with-prereq_2.0"]), APMAP, {})
        self.assertEqual(list(map(str, prereqs)),
                         ["prereq-A_1.0", "prereq-B_2.0"])

        prereqs = DependencyUtils.prereq(
            PackageIdentifier.parse_list(["pkg-with-prereq_0.1"]), APMAP, {})
        self.assertEqual(list(map(str, prereqs)), ["prereq-A_0.1-fail"])

        prereqs = DependencyUtils.prereq(
            PackageIdentifier.parse_list(["pkg-with-deps-with-prereq_1.0"]),
            APMAP, {})
        self.assertEqual(list(map(str, prereqs)), [])
        install = DependencyUtils.install(
            PackageIdentifier.parse_list(["pkg-with-deps-with-prereq_1.0"]),
            APMAP, {})
        prereqs = DependencyUtils.prereq([x.identifier for x in install],
                                         APMAP, {})
        self.assertEqual(list(map(str, prereqs)),
                         ["prereq-A_1.0", "prereq-B_1.0"])
Пример #8
0
 def _getdeps(env, ipmap):
     return DependencyUtils.install(PackageIdentifier.parse_list(
         ["condition_1.0"]),
                                    APMAP,
                                    ipmap,
                                    env=env)
Пример #9
0
    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
Пример #10
0
    def install_packages(self,
                         items: 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():
            ipmap = self.list_installed_packages()
            apmap = self.list_available_packages()
            pilist = []
            for item in items:
                if isinstance(item, PackageIdentifier):
                    # Package identifier is given
                    pilist.append(item)
                elif PackageIdentifier.is_valid_identifier(item):
                    # Package identifier string given
                    pilist.append(PackageIdentifier.parse(item))
                else:
                    # If leaf artifacts are given, add/replace identifiers of available packages
                    la = LeafArtifact(Path(item))
                    pilist.append(la.identifier)
                    apmap[la.identifier] = la
            out = []

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

            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
                download_count = 0
                for ap in [
                        ap for ap in ap_to_install
                        if isinstance(ap, AvailablePackage)
                ]:
                    download_count += 1
                    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(
                    [ap.identifier for ap in ap_to_install],
                    apmap,
                    ipmap,
                    env=env)

                if len(prereq_to_install) > 0:
                    try:
                        self.__install_prereq(
                            prereq_to_install,
                            ipmap,
                            env=env,
                            keep_folder_on_error=keep_folder_on_error)
                    except BaseException as e:
                        raise PrereqException(e)

                # Download ap list
                self.logger.print_default(
                    "Downloading {size} package(s)".format(
                        size=download_count))
                la_to_install = []
                for mf in ap_to_install:
                    if isinstance(mf, AvailablePackage):
                        la_to_install.append(self.__download_ap(mf))
                    elif isinstance(mf, LeafArtifact):
                        la_to_install.append(mf)

                # 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,
                        ipmap,
                        keep_folder_on_error=keep_folder_on_error)
                    out.append(ip)

            return out
Пример #11
0
    def execute(self, args, uargs):
        pm = PackageManager()
        env = None
        # If the user specified env values, build a complete env
        if args.custom_envlist is not None:
            env = Environment.build(
                pm.build_builtin_environment(), pm.build_user_environment(),
                Environment("Custom env",
                            env_list_to_map(args.custom_envlist)))

        items = None
        if args.dependency_type == "available":
            items = DependencyUtils.install(PackageIdentifier.parse_list(
                args.packages),
                                            pm.list_available_packages(), {},
                                            env=env)
        elif args.dependency_type == "install":
            items = DependencyUtils.install(PackageIdentifier.parse_list(
                args.packages),
                                            pm.list_available_packages(),
                                            pm.list_installed_packages(),
                                            env=env)
        elif args.dependency_type == "installed":
            items = DependencyUtils.installed(PackageIdentifier.parse_list(
                args.packages),
                                              pm.list_installed_packages(),
                                              env=env,
                                              ignore_unknown=True)
        elif args.dependency_type == "uninstall":
            items = DependencyUtils.uninstall(PackageIdentifier.parse_list(
                args.packages),
                                              pm.list_installed_packages(),
                                              env=env)
        elif args.dependency_type == "prereq":
            items = DependencyUtils.prereq(PackageIdentifier.parse_list(
                args.packages),
                                           pm.list_available_packages(),
                                           pm.list_installed_packages(),
                                           env=env)
        elif args.dependency_type == "upgrade":
            items, _ = DependencyUtils.upgrade(
                None if len(args.packages) == 0 else args.packages,
                pm.list_available_packages(),
                pm.list_installed_packages(),
                env=env)
        elif args.dependency_type == "rdepends":
            mfmap = OrderedDict()
            mfmap.update(
                DependencyUtils.rdepends(PackageIdentifier.parse_list(
                    args.packages),
                                         pm.list_available_packages(),
                                         env=env))
            mfmap.update(
                DependencyUtils.rdepends(PackageIdentifier.parse_list(
                    args.packages),
                                         pm.list_installed_packages(),
                                         env=env))
            items = mfmap.values()
        else:
            raise ValueError()

        rend = ManifestListRenderer()
        rend.extend(items)
        pm.print_renderer(rend)