def build_package(self) -> types.TaskDict: """Build DEB packages from source files.""" mounts = [ utils.bind_ro_mount(source=self.sources, target=Path('/debbuild/pkg-src')), utils.bind_ro_mount(source=self.debuild_sources, target=Path('/debbuild/pkg-meta')), utils.bind_mount(source=constants.PKG_DEB_ROOT, target=Path('/debbuild/result')), ] builddeb_callable = docker_command.DockerRun( command=['/entrypoint.sh', 'builddeb'], builder=self.builder, run_config=docker_command.DEB_BASE_CONFIG, mounts=mounts, environment={ 'VERSION': '{}-{}'.format(self.version, self.build_id) }, ) task = self.basic_task task.update({ 'name': 'build_deb_pkg', 'actions': [builddeb_callable], 'doc': 'Build DEB package from sources for {}'.format(self.name), 'title': utils.title_with_target1('BUILD DEB'), 'targets': [self.deb], }) task['file_dep'].extend(coreutils.ls_files_rec(self.sources)) task['file_dep'].extend(coreutils.ls_files_rec(self.debuild_sources)) task['task_dep'].append('_package_mkdir_deb_iso_root') task['task_dep'].append('_build_deb_container') return task
def _get_buildsrpm_mounts(self, srpm_dir: Path) -> List[types.Mount]: """Return the list of container mounts required by `buildsrpm`.""" mounts = [ # .spec file utils.bind_ro_mount( source=self.spec, target=Path('/rpmbuild/SPECS', self.spec.name) ), # SRPM directory. utils.bind_mount( source=srpm_dir, target=Path('/rpmbuild/SRPMS'), ), # rpmlint configuration file docker_command.RPMLINTRC_MOUNT ] # Source files. for source in self.sources: mounts.append( utils.bind_ro_mount( source=source, target=Path('/rpmbuild/SOURCES', source.name) ) ) return mounts
def convert_package(self) -> types.TaskDict: """Build a DEB package from a RPM one.""" mounts = [ utils.bind_ro_mount(source=self.sources, target=Path('/rpmbuild/source.rpm')), utils.bind_mount(source=constants.PKG_DEB_ROOT, target=Path('/debbuild/result')), ] builddeb_callable = docker_command.DockerRun( command=['/entrypoint.sh', 'rpm2deb'], builder=self.builder, run_config=docker_command.DEB_BASE_CONFIG, mounts=mounts) task = self.basic_task task.update({ 'name': 'convert_rpm_pkg_to_deb', 'actions': [builddeb_callable], 'doc': 'Build DEB package from RPM for {}'.format(self.name), 'title': utils.title_with_target1('RPM2DEB'), 'targets': [self.deb], }) task['file_dep'].append(self.sources) task['task_dep'].append('_package_mkdir_deb_iso_root') task['task_dep'].append('_build_deb_container') return task
def _buildrepo_action(self) -> types.Action: """Return the command to run `reprepro` inside a container.""" mounts = [ utils.bind_ro_mount(source=constants.ROOT / 'packages' / 'debian' / 'distributions', target=Path('/distributions')), utils.bind_ro_mount(source=self.pkgdir, target=Path('/packages')), utils.bind_mount(source=self.rootdir, target=Path('/repository')) ] buildrepo_callable = docker_command.DockerRun( command=['/entrypoint.sh', 'buildrepo', self.fullname], builder=self.builder, mounts=mounts, read_only=True, run_config=docker_command.DEB_BASE_CONFIG) return buildrepo_callable
def task__download_deb_packages() -> types.TaskDict: """Download Debian packages locally.""" witness = constants.PKG_DEB_ROOT / '.witness' def clean() -> None: """Delete downloaded Debian packages.""" for repository in DEB_REPOSITORIES: # Repository with an explicit list of packages are created by a # dedicated task that will also handle their cleaning, so we skip # them here. if repository.packages: continue coreutils.rm_rf(repository.pkgdir) utils.unlink_if_exist(witness) constants.REPO_DEB_ROOT.rmdir() def mkdirs() -> None: """Create directories for the repositories.""" for repository in DEB_REPOSITORIES: repository.pkgdir.mkdir(exist_ok=True) mounts = [ utils.bind_ro_mount( source=constants.ROOT / 'packages' / 'debian' / 'download_packages.py', target=Path('/download_packages.py'), ), utils.bind_mount(source=constants.PKG_DEB_ROOT, target=Path('/repositories')), ] dl_packages_callable = docker_command.DockerRun( command=['/download_packages.py', *DEB_TO_DOWNLOAD], builder=builder.DEB_BUILDER, mounts=mounts, environment={'SALT_VERSION': versions.SALT_VERSION}, run_config=docker_command.default_run_config( constants.DEBIAN_ENTRYPOINT)) return { 'title': utils.title_with_target1('GET DEB PKGS'), 'actions': [mkdirs, dl_packages_callable], 'targets': [constants.PKG_DEB_ROOT / '.witness'], 'task_dep': [ '_package_mkdir_deb_root', '_package_mkdir_deb_iso_root', '_build_builder:{}'.format(builder.DEB_BUILDER.name), ], 'clean': [clean], 'uptodate': [doit.tools.config_changed(_TO_DOWNLOAD_DEB_CONFIG)], # Prevent Docker from polluting our output. 'verbosity': 0, }
def _buildrepo_action(self) -> types.Action: """Return the command to run `buildrepo` inside a container.""" mounts = [ utils.bind_ro_mount(source=self.rootdir, target=Path('/repository')), utils.bind_mount(source=self.repodata, target=Path('/repository/repodata')) ] buildrepo_callable = docker_command.DockerRun( command=['/entrypoint.sh', 'buildrepo'], builder=self.builder, mounts=mounts, read_only=True, run_config=docker_command.RPM_BASE_CONFIG) return buildrepo_callable
def _get_buildrpm_mounts(srpm_path: Path, rpm_dir: Path) -> List[types.Mount]: """Return the list of container mounts required by `buildrpm`.""" mounts = [ # SRPM directory. utils.bind_ro_mount(source=srpm_path, target=Path('/rpmbuild/SRPMS', srpm_path.name)), # RPM directory. utils.bind_mount( source=rpm_dir, target=Path('/rpmbuild/RPMS'), ), # rpmlint configuration file docker_command.RPMLINTRC_MOUNT ] return mounts
def default_run_config(entrypoint: Path) -> Dict[str, Any]: """Return a default run configuration.""" return { 'hostname': 'build', 'mounts': [ utils.bind_ro_mount(target=Path('/entrypoint.sh'), source=entrypoint) ], 'environment': { 'TARGET_UID': os.geteuid(), 'TARGET_GID': os.getegid() }, 'tmpfs': { '/tmp': '' }, 'remove': True }
def generate_meta(self) -> types.TaskDict: """Generate the .meta file for the package.""" spec_guest_file = Path('/rpmbuild/SPECS', self.spec.name) meta_guest_file = Path('/rpmbuild/META', self.meta.name) mounts = [ utils.bind_ro_mount( source=self.spec, target=spec_guest_file ), utils.bind_mount( source=self.meta.parent, target=meta_guest_file.parent ) ] rpmspec_config = docker_command.default_run_config( constants.REDHAT_ENTRYPOINT ) rpmspec_config['read_only'] = True buildmeta_callable = docker_command.DockerRun( command=['/entrypoint.sh', 'buildmeta'], builder=self.builder, environment={ 'SPEC': self.spec.name, 'META': self.meta.name }, run_config=rpmspec_config, mounts=mounts ) task = self.basic_task task.update({ 'name': self._get_task_name('rpmspec'), 'actions': [buildmeta_callable], 'doc': 'Generate {}.meta'.format(self.name), 'title': utils.title_with_target1('RPMSPEC'), 'targets': [self.meta], }) task['file_dep'].extend([self.spec]) task['task_dep'].append(self._get_task_name(self.MKDIR_TASK_NAME, with_basename=True)) return task
def generate_meta(self) -> types.TaskDict: """Generate the .meta file for the package.""" spec_guest_file = Path('/rpmbuild/SPECS', self.spec.name) meta_guest_file = Path('/rpmbuild/META', self.meta.name) mounts = [ utils.get_entrypoint_mount('redhat'), utils.bind_ro_mount(source=self.spec, target=spec_guest_file), utils.bind_mount(source=self.meta.parent, target=meta_guest_file.parent) ] command = ['/entrypoint.sh', 'buildmeta'] rpmspec_config = { 'hostname': 'build', 'read_only': True, 'remove': True } buildmeta_callable = docker_command.DockerRun( command=command, builder=self.builder, environment={ 'SPEC': self.spec.name, 'META': self.meta.name }, run_config=rpmspec_config, mounts=mounts) task = self.basic_task task.update({ 'name': 'pkg_rpmspec', 'actions': [buildmeta_callable], 'doc': 'Generate {}.meta'.format(self.name), 'title': utils.title_with_target1('RPMSPEC'), 'targets': [self.meta], }) task['file_dep'].extend([self.spec]) task['task_dep'].append('{}:{}'.format(self.basename, self.MKDIR_TASK_NAME)) return task
from pathlib import Path from typing import Any, Callable, Dict, List, Optional, Type import docker # type: ignore from docker.errors import BuildError, ContainerError # type: ignore from docker.types import Mount # type: ignore from doit.exceptions import TaskError # type: ignore from buildchain import constants from buildchain import utils from buildchain.targets import image DOCKER_CLIENT: docker.DockerClient = docker.from_env() RPMLINTRC_MOUNT: Mount = utils.bind_ro_mount( target=Path('/rpmbuild/rpmlintrc'), source=constants.ROOT / 'packages' / 'redhat' / 'rpmlintrc', ) RPM_BASE_CONFIG = { 'hostname': 'build', 'mounts': [utils.get_entrypoint_mount('redhat')], 'environment': { 'TARGET_UID': os.geteuid(), 'TARGET_GID': os.getegid() }, 'tmpfs': { '/tmp': '' }, 'remove': True }