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
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')
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)