def stage(self, directory):
        mirror_dir = self.get_mirror_directory()

        try:
            manifest = self._load_manifest()
        except (OSError, SourceError) as e:
            raise SourceError("Unable to load manifest: {}".format(e)) from e

        try:
            for layer in manifest["layers"]:
                layer_digest = layer["digest"]
                blob_path = os.path.join(mirror_dir, layer_digest + ".tar.gz")

                self._verify_blob(blob_path, expected_digest=layer_digest)
                (
                    extract_fileset,
                    white_out_fileset,
                ) = self._get_extract_and_remove_files(blob_path)

                # remove files associated with whiteouts
                for white_out_file in white_out_fileset:
                    white_out_file = os.path.join(directory, white_out_file)
                    os.remove(white_out_file)

                # extract files for the current layer
                with tarfile.open(blob_path, tarinfo=ReadableTarInfo) as tar:
                    with self.tempdir() as td:
                        tar.extractall(path=td, members=extract_fileset)
                        link_files(td, directory)

        except (OSError, SourceError, tarfile.TarError) as e:
            raise SourceError("{}: Error staging source: {}".format(self,
                                                                    e)) from e
Exemplo n.º 2
0
    def stage(self, directory):
        mirror_dir = self.get_mirror_directory()

        try:
            manifest = self._load_manifest()
        except (OSError, SourceError) as e:
            raise SourceError("Unable to load manifest: {}".format(e)) from e

        try:
            for layer in manifest['layers']:
                layer_digest = layer['digest']
                blob_path = os.path.join(mirror_dir, layer_digest + '.tar.gz')

                self._verify_blob(blob_path, expected_digest=layer_digest)

                def tar_filter(info):
                    return not (info.isdev() or info.name.startswith('dev/'))

                with tarfile.open(blob_path) as tar:
                    members = filter(tar_filter, tar.getmembers())
                    with self.tempdir() as td:
                        tar.extractall(path=td, members=members)
                        link_files(td, directory)

        except (OSError, SourceError, tarfile.TarError) as e:
            raise SourceError("{}: Error staging source: {}".format(self,
                                                                    e)) from e
    def assemble(self, sandbox):
        self.stage_sources(sandbox, 'input')

        basedir = sandbox.get_directory()
        allfiles = os.path.join(basedir, 'buildstream', 'allfiles')
        reldirectory = os.path.relpath(self.directory, '/')
        subdir = os.path.join(allfiles, reldirectory)
        etcdir = os.path.join(allfiles, 'etc')
        installdir = os.path.join(basedir, 'buildstream', 'install')
        filesdir = os.path.join(installdir, 'files')
        filesetcdir = os.path.join(filesdir, 'etc')
        stagedir = os.path.join(os.sep, 'buildstream', 'allfiles')

        os.makedirs(allfiles, exist_ok=True)
        os.makedirs(filesdir, exist_ok=True)
        if self.metadata.has_section('Application'):
            os.makedirs(os.path.join(installdir, 'export'), exist_ok=True)

        for section in self.metadata.sections():
            if section.startswith('Extension '):
                try:
                    extensiondir = self.metadata.get(section, 'directory')
                    os.makedirs(os.path.join(installdir, 'files',
                                             extensiondir),
                                exist_ok=True)
                except PermissionError as e:
                    raise ElementError(
                        "Permission denied: Cannot create {}".format(
                            extensiondir))

        with self.timed_activity("Creating flatpak image", silent_nested=True):
            self.stage_dependency_artifacts(sandbox,
                                            Scope.BUILD,
                                            path=stagedir,
                                            include=self.include,
                                            exclude=self.exclude)
            utils.link_files(subdir, filesdir)
            if os.path.exists(etcdir):
                utils.link_files(etcdir, filesetcdir)

        metadatafile = os.path.join(installdir, 'metadata')
        with open(metadatafile, "w") as m:
            self.metadata.write(m)
        return os.path.join(os.sep, 'buildstream', 'install')
Exemplo n.º 4
0
    def stage(self, sandbox):
        super().stage(sandbox)
        # For each package, create a subdir in build-root and copy the files to there
        # then reconstitute the /DEBIAN files.
        input_elm = self.search(Scope.BUILD, self.__input)
        if not input_elm:
            raise ElementError(
                "{}: Failed to find input element {} in build-depends".format(
                    self.name, self.__input))
            return
        bstdata = input_elm.get_public_data('bst')
        if "dpkg-data" not in bstdata:
            raise ElementError(
                "{}: input element {} does not have any bst.dpkg-data public data"
                .format(self.name, self.__input))
        for package, package_data in self.node_items(bstdata['dpkg-data']):
            package_name = package_data.get(
                "name", "{}-{}".format(input_elm.normal_name, package))
            if not ("split-rules" in bstdata
                    and package in bstdata["split-rules"]):
                raise ElementError(
                    "{}: Input element {} does not have bst.split-rules.{}".
                    format(self.name, self.__input.name, package))
            package_splits = bstdata['split-rules'][package]
            package_files = input_elm.compute_manifest(include=[package])
            src = os.path.join(sandbox.get_directory(),
                               self.get_variable("build-root").lstrip(os.sep))
            dst = os.path.join(src, package)
            os.makedirs(dst, exist_ok=True)
            utils.link_files(src, dst, files=package_files)

            # Create this dir. If it already exists,
            # something unexpected has happened.
            debiandir = os.path.join(dst, "DEBIAN")
            os.makedirs(debiandir)

            # Recreate the DEBIAN files.
            # control is extracted verbatim, and is mandatory.
            if "control" not in package_data:
                raise ElementError(
                    "{}: Cannot reconstitute package {}".format(
                        self.name, package),
                    detail="There is no public.bst.dpkg-data.{}.control".
                    format(package))
            controlpath = os.path.join(debiandir, "control")
            controltext = package_data["control"]
            # Slightly ugly way of renaming the package
            controltext = re.sub(r"^Package:\s*\S+",
                                 "Package: {}".format(package_name),
                                 controltext)
            with open(controlpath, "w") as f:
                f.write(controltext)

            # Generate a DEBIAN/md5sums file from the artifact
            md5sums = {}
            for split in package_files:
                filepath = os.path.join(src, split.lstrip(os.sep))
                if os.path.isfile(filepath):
                    md5sums[split] = md5sum_file(filepath)
            md5sumspath = os.path.join(debiandir, "md5sums")
            with open(md5sumspath, "w") as f:
                for path, md5sum in md5sums.items():
                    f.write("{}  {}\n".format(md5sum, path))

            # scripts may exist
            if ("package-scripts" in bstdata
                    and package in bstdata["package-scripts"]):
                for script in ["postinst", "preinst", "postrm", "prerm"]:
                    if script in bstdata["package-scripts"][package]:
                        filepath = os.path.join(debiandir, script)
                        with open(filepath, "w") as f:
                            f.write(
                                bstdata["package-scripts"][package][script])
                        os.chmod(filepath, 0o755)