From 38438d5fda7bfdda0b665144c55cae00d9cf5fcf Mon Sep 17 00:00:00 2001 From: InsanePrawn Date: Sun, 24 Oct 2021 04:32:47 +0200 Subject: [PATCH] Chroot.initialise(): add `reset` param, refactor in general --- chroot.py | 115 ++++++++++++++++++++++++++++------------------------ config.py | 1 + packages.py | 11 ++--- 3 files changed, 70 insertions(+), 57 deletions(-) diff --git a/chroot.py b/chroot.py index 49b43dd..49d01f7 100644 --- a/chroot.py +++ b/chroot.py @@ -3,6 +3,9 @@ import logging import subprocess import os import atexit +from glob import glob +from shutil import rmtree + from config import config from distro import get_base_distro, RepoInfo from shlex import quote as shell_quote @@ -10,7 +13,6 @@ from utils import mount, umount from distro import get_kupfer_local from wrapper import enforce_wrap from constants import Arch, GCC_HOSTSPECS, CROSSDIRECT_PKGS -from glob import glob from generator import generate_makepkg_conf BIND_BUILD_DIRS = 'BINDBUILDDIRS' @@ -163,12 +165,12 @@ class Chroot: def initialize( self, + reset: bool = False, fail_if_initialized: bool = False, ): - base_distro = get_base_distro(self.arch) pacman_conf_target = self.get_path('etc/pacman.conf') - if self.initialized: + if self.initialized and not reset: # chroot must have been initialized already! if fail_if_initialized: raise Exception(f"Chroot {self.name} is already initialized, this seems like a bug") @@ -177,27 +179,35 @@ class Chroot: self.deactivate() if self.copy_base: - base_chroot = get_base_chroot(self.arch) - if base_chroot == self: - raise Exception('base_chroot == self, bailing out. this is a bug') - base_chroot.initialize() - logging.info(f'Copying {base_chroot.name} chroot to {self.name}') - result = subprocess.run([ - 'rsync', - '-a', - '--delete', - '-q', - '-W', - '-x', - '--exclude', - 'pkgbuilds', - '--exclude', - 'prebuilts', - f'{base_chroot.path}/', - f'{self.path}/', - ]) - if result.returncode != 0: - raise Exception(f'Failed to copy {base_chroot.name} to {self.name}') + if reset or not os.path.exists(self.get_path('usr/bin')): + base_chroot = get_base_chroot(self.arch) + if base_chroot == self: + raise Exception('base_chroot == self, bailing out. this is a bug') + base_chroot.initialize() + logging.info(f'Copying {base_chroot.name} chroot to {self.name}') + result = subprocess.run([ + 'rsync', + '-a', + '--delete', + '-q', + '-W', + '-x', + '--exclude', + 'pkgbuilds', + '--exclude', + 'prebuilts', + f'{base_chroot.path}/', + f'{self.path}/', + ]) + if result.returncode != 0: + raise Exception(f'Failed to copy {base_chroot.name} to {self.name}') + self.write_pacman_conf() + self.activate() + self.try_install_packages(self.base_packages, refresh=True, allow_fail=False) + self.deactivate() + else: + logging.debug(f'{self.name}: Reusing existing installation') + self.write_pacman_conf() # patch makepkg with open(self.get_path('/usr/bin/makepkg'), 'r') as file: @@ -207,34 +217,33 @@ class Chroot: file.write(data) # configure makepkg - data = generate_makepkg_conf(self.arch, cross=False) - data = data.replace('xz -c', 'xz -T0 -c') - data = data.replace(' check ', ' !check ') - with open(self.get_path('/etc/makepkg.conf'), 'w') as file: - file.write(data) + self.write_makepkg_conf(self.arch, cross_chroot_relative=None, cross=False) + else: + # base chroot + if reset: + logging.info(f'Resetting {self.name}') + for dir in glob(os.join(self.path, '*')): + rmtree(dir) - os.makedirs(self.get_path('/etc'), exist_ok=True) + self.write_pacman_conf() - conf_text = base_distro.get_pacman_conf(self.extra_repos) - with open(pacman_conf_target, 'w') as file: - file.write(conf_text) + logging.info(f'Pacstrapping chroot {self.name}: {", ".join(self.base_packages)}') - logging.info(f'Installing packages to {self.name}: {", ".join(self.base_packages)}') + result = subprocess.run([ + 'pacstrap', + '-C', + pacman_conf_target, + '-c', + '-G', + self.path, + ] + self.base_packages + [ + '--needed', + '--overwrite=*', + '-yyuu', + ]) + if result.returncode != 0: + raise Exception(f'Failed to initialize chroot "{self.name}"') - result = subprocess.run([ - 'pacstrap', - '-C', - pacman_conf_target, - '-c', - '-G', - self.path, - ] + self.base_packages + [ - '--needed', - '--overwrite=*', - '-yyuu', - ]) - if result.returncode != 0: - raise Exception(f'Failed to initialize chroot "{self.name}"') self.initialized = True def mount( @@ -301,10 +310,6 @@ class Chroot: self.umount('proc') self.active = False - def reset(self): - self.initialized = False - self.initialize() - def run_cmd(self, script: str, inner_env: dict[str, str] = {}, @@ -458,6 +463,12 @@ class Chroot: f.write(makepkg_cross_conf) return makepkg_conf_path_relative + def write_pacman_conf(self): + os.makedirs(self.get_path('/etc'), exist_ok=True) + conf_text = get_base_distro(self.arch).get_pacman_conf(self.extra_repos) + with open(self.get_path('etc/pacman.conf'), 'w') as file: + file.write(conf_text) + @click.command('chroot') @click.argument('type', required=False, default='build') diff --git a/config.py b/config.py index 70ce4bc..f86bc19 100644 --- a/config.py +++ b/config.py @@ -28,6 +28,7 @@ PROFILE_EMPTY: Profile = {key: None for key in PROFILE_DEFAULTS.keys()} CONFIG_DEFAULTS = { 'build': { 'ccache': True, + 'clean_mode': True, 'crosscompile': True, 'crossdirect': True, 'threads': 0, diff --git a/packages.py b/packages.py index 9c2c2fc..9ba698d 100644 --- a/packages.py +++ b/packages.py @@ -399,9 +399,7 @@ def setup_build_chroot(arch: Arch, extra_packages: list[str] = [], clean_chroot: extra_repos=get_kupfer_local(arch).repos, ) logging.info(f'Initializing {arch} build chroot') - if clean_chroot: - chroot.reset() - chroot.initialize() + chroot.initialize(reset=clean_chroot) chroot.activate() chroot.mount_pacman_cache() chroot.mount_pkgbuilds() @@ -448,9 +446,7 @@ def build_package( extra_packages=['base-devel'] + CROSSDIRECT_PKGS, clean_chroot=clean_chroot, ) - cross = foreign_arch and package.mode == 'cross' and enable_crosscompile - chroots = set([target_chroot, native_chroot]) if cross: logging.info(f'Cross-compiling {package.path}') @@ -522,6 +518,7 @@ def build_packages( enable_crosscompile: bool = True, enable_crossdirect: bool = True, enable_ccache: bool = True, + clean_chroot: bool = False, ): build_levels = get_unbuilt_package_levels(repo, packages, arch, force=force) @@ -539,6 +536,7 @@ def build_packages( enable_crosscompile=enable_crosscompile, enable_crossdirect=enable_crossdirect, enable_ccache=enable_ccache, + clean_chroot=clean_chroot, ) files += add_package_to_repo(package, arch) return files @@ -552,6 +550,7 @@ def build_packages_by_paths( enable_crosscompile: bool = True, enable_crossdirect: bool = True, enable_ccache: bool = True, + clean_chroot: bool = False, ): if isinstance(paths, str): paths = [paths] @@ -567,6 +566,7 @@ def build_packages_by_paths( enable_crosscompile=enable_crosscompile, enable_crossdirect=enable_crossdirect, enable_ccache=enable_ccache, + clean_chroot=clean_chroot, ) @@ -622,6 +622,7 @@ def build(paths: list[str], force: bool, arch: Arch): enable_crosscompile=config.file['build']['crosscompile'], enable_crossdirect=config.file['build']['crossdirect'], enable_ccache=config.file['build']['ccache'], + clean_chroot=config.file['build']['clean_mode'], )