Beispiel #1
0
 def test_tar_size(self):
     for filename, testfunc in (("compress-tar_1.0.leaf",
                                 self.assertGreater),
                                ("compress-xz_1.0.leaf", self.assertLess)):
         file = self.repository_folder / filename
         self.assertTrue(file.exists())
         la = LeafArtifact(file)
         testfunc(file.stat().st_size, la.get_total_size())
Beispiel #2
0
 def __build_pkg_node(self, tarfile: Path, manifest: Manifest = None):
     out = OrderedDict()
     if manifest is None:
         manifest = LeafArtifact(tarfile)
     out[JsonConstants.INFO] = manifest.info_node
     out[JsonConstants.REMOTE_PACKAGE_HASH] = hash_compute(tarfile)
     out[JsonConstants.REMOTE_PACKAGE_SIZE] = tarfile.stat().st_size
     return out
Beispiel #3
0
 def __download_ap(self, ap: AvailablePackage) -> LeafArtifact:
     """
     Download given available package and returns the files in cache folder
     @return LeafArtifact
     """
     cachedfile = self.__download_cache_folder / get_cached_artifact_name(
         ap.filename, ap.hashsum)
     download_and_verify_file(ap.url,
                              cachedfile,
                              logger=self.logger,
                              hashstr=ap.hashsum)
     return LeafArtifact(cachedfile)
Beispiel #4
0
 def __download_ap(self, ap: AvailablePackage) -> LeafArtifact:
     """
     Download given available package and returns the files in cache folder
     @return LeafArtifact
     """
     cachedfile = self.__download_cache_folder / get_cached_artifact_name(
         ap.filename, ap.hashsum)
     # Select best candidate
     candidate = ap.best_candidate
     self.logger.print_verbose(
         "Downloading {ap.identifier} from {ap.remote.alias}: {ap.url}".
         format(ap=candidate))
     download_and_verify_file(candidate.url,
                              cachedfile,
                              logger=self.logger,
                              hashstr=ap.hashsum)
     return LeafArtifact(cachedfile)
Beispiel #5
0
    def execute(self, args, uargs):
        def tostring(item):
            if item is None:
                return ""
            if isinstance(item, (list, tuple)):
                return ", ".join(map(tostring, item))
            if isinstance(item, dict):
                return tostring(
                    list(
                        map(lambda kv: "{0}={1}".format(kv[0], kv[1]),
                            item.items())))
            return str(item)

        for index in range(0, len(args.files)):
            if index > 0:
                print("")
            file = args.files[index]
            try:
                la = LeafArtifact(file)
                if args.format is None:
                    print(file)
                    kvfmt = "  {k}: {v}"
                    print(kvfmt.format(k="identifier", v=la.identifier))
                    print(kvfmt.format(k="name", v=la.name))
                    print(kvfmt.format(k="version", v=la.version))
                    for k, v in la.info_node.items():
                        if k not in ("name", "version"):
                            print(kvfmt.format(k=k, v=tostring(v)))
                elif args.format == "json":
                    print(jtostring(la.info_node, pp=True))
                else:

                    class MyFormatter(Formatter):
                        def __init__(self, la, *args, **kwargs):
                            Formatter.__init__(self, *args, **kwargs)

                        def get_value(self, key, args, kwargs):
                            return tostring(la.info_node.get(key))

                    print(MyFormatter(la).format(args.format))
            except BaseException as e:
                print("Invalid leaf file {f}: {e}".format(f=file, e=e))
Beispiel #6
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