From: Daan De Meyer Date: Sun, 3 Dec 2023 12:21:35 +0000 (+0100) Subject: tree: Pass in use_subvolumes feature instead of MkosiConfig object X-Git-Tag: v20~114^2~11 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=ffe92f782a194a1a104dfd335f2e04674da531a1;p=thirdparty%2Fmkosi.git tree: Pass in use_subvolumes feature instead of MkosiConfig object This makes the tree functions a little more generic. --- diff --git a/mkosi/__init__.py b/mkosi/__init__.py index 257d88fd1..bc33a6059 100644 --- a/mkosi/__init__.py +++ b/mkosi/__init__.py @@ -1043,7 +1043,7 @@ def install_base_trees(state: MkosiState) -> None: with complete_step("Copying in base trees…"): for path in state.config.base_trees: - install_tree(state.config, path, state.root) + install_tree(path, state.root, use_subvolumes=state.config.use_subvolumes) def install_skeleton_trees(state: MkosiState) -> None: @@ -1053,7 +1053,7 @@ def install_skeleton_trees(state: MkosiState) -> None: with complete_step("Copying in skeleton file trees…"): for tree in state.config.skeleton_trees: source, target = tree.with_prefix() - install_tree(state.config, source, state.root, target) + install_tree(source, state.root, target, use_subvolumes=state.config.use_subvolumes) def install_package_manager_trees(state: MkosiState) -> None: @@ -1063,7 +1063,7 @@ def install_package_manager_trees(state: MkosiState) -> None: with complete_step("Copying in package manager file trees…"): for tree in state.config.package_manager_trees: source, target = tree.with_prefix() - install_tree(state.config, source, state.workspace / "pkgmngr", target) + install_tree(source, state.workspace / "pkgmngr", target, use_subvolumes=state.config.use_subvolumes) def install_extra_trees(state: MkosiState) -> None: @@ -1073,7 +1073,7 @@ def install_extra_trees(state: MkosiState) -> None: with complete_step("Copying in extra file trees…"): for tree in state.config.extra_trees: source, target = tree.with_prefix() - install_tree(state.config, source, state.root, target) + install_tree(source, state.root, target, use_subvolumes=state.config.use_subvolumes) def install_build_dest(state: MkosiState) -> None: @@ -1081,7 +1081,7 @@ def install_build_dest(state: MkosiState) -> None: return with complete_step("Copying in build tree…"): - copy_tree(state.config, state.install_dir, state.root) + copy_tree(state.install_dir, state.root, use_subvolumes=state.config.use_subvolumes) def gzip_binary() -> str: @@ -1474,7 +1474,7 @@ def compressor_command(compression: Compression) -> list[PathString]: def maybe_compress(config: MkosiConfig, compression: Compression, src: Path, dst: Optional[Path] = None) -> None: if not compression or src.is_dir(): if dst: - move_tree(config, src, dst) + move_tree(src, dst, use_subvolumes=config.use_subvolumes) return if not dst: @@ -1946,13 +1946,13 @@ def save_cache(state: MkosiState) -> None: # We only use the cache-overlay directory for caching if we have a base tree, otherwise we just # cache the root directory. if (state.workspace / "cache-overlay").exists(): - move_tree(state.config, state.workspace / "cache-overlay", final) + move_tree(state.workspace / "cache-overlay", final, use_subvolumes=state.config.use_subvolumes) else: - move_tree(state.config, state.root, final) + move_tree(state.root, final, use_subvolumes=state.config.use_subvolumes) if need_build_overlay(state.config) and (state.workspace / "build-overlay").exists(): rmtree(build) - move_tree(state.config, state.workspace / "build-overlay", build) + move_tree(state.workspace / "build-overlay", build, use_subvolumes=state.config.use_subvolumes) manifest.write_text( json.dumps( @@ -1987,7 +1987,7 @@ def reuse_cache(state: MkosiState) -> bool: return False with complete_step("Copying cached trees"): - copy_tree(state.config, final, state.root) + copy_tree(final, state.root, use_subvolumes=state.config.use_subvolumes) if need_build_overlay(state.config): (state.workspace / "build-overlay").symlink_to(build) @@ -2193,7 +2193,7 @@ def finalize_staging(state: MkosiState) -> None: # Make sure all build outputs that are not directories are owned by the user running mkosi. if not f.is_dir(): os.chown(f, INVOKING_USER.uid, INVOKING_USER.gid, follow_symlinks=False) - move_tree(state.config, f, state.config.output_dir_or_cwd()) + move_tree(f, state.config.output_dir_or_cwd(), use_subvolumes=state.config.use_subvolumes) def normalize_mtime(root: Path, mtime: Optional[int], directory: Optional[Path] = None) -> None: diff --git a/mkosi/distributions/gentoo.py b/mkosi/distributions/gentoo.py index 5ed0fe1de..5f0c247f2 100644 --- a/mkosi/distributions/gentoo.py +++ b/mkosi/distributions/gentoo.py @@ -134,7 +134,7 @@ class Installer(DistributionInstaller): for d in ("binpkgs", "distfiles", "repos/gentoo"): (state.cache_dir / d).mkdir(parents=True, exist_ok=True) - copy_tree(state.config, state.pkgmngr, stage3, preserve_owner=False) + copy_tree(state.pkgmngr, stage3, preserve_owner=False, use_subvolumes=state.config.use_subvolumes) features = " ".join([ # Disable sandboxing in emerge because we already do it in mkosi. diff --git a/mkosi/installer/dnf.py b/mkosi/installer/dnf.py index 345b647f9..eb3e35f69 100644 --- a/mkosi/installer/dnf.py +++ b/mkosi/installer/dnf.py @@ -101,7 +101,7 @@ def setup_dnf(state: MkosiState, repos: Iterable[Repo], filelists: bool = True) (macros / "macros.lang").write_text(f"%_install_langs {state.config.locale}") rpmconfigdir = Path(run(["rpm", "--eval", "%{_rpmconfigdir}"], stdout=subprocess.PIPE).stdout.strip()) - copy_tree(state.config, rpmconfigdir, state.pkgmngr / "usr/lib/rpm", clobber=False) + copy_tree(rpmconfigdir, state.pkgmngr / "usr/lib/rpm", clobber=False, use_subvolumes=state.config.use_subvolumes) def dnf_cmd(state: MkosiState) -> list[PathString]: diff --git a/mkosi/qemu.py b/mkosi/qemu.py index 16001fd9f..e0e92c436 100644 --- a/mkosi/qemu.py +++ b/mkosi/qemu.py @@ -364,7 +364,7 @@ def copy_ephemeral(config: MkosiConfig, src: Path) -> Iterator[Path]: tmp = src.parent / f"{src.name}-{uuid.uuid4().hex}" try: - copy_tree(config, src, tmp) + copy_tree(src, tmp, use_subvolumes=config.use_subvolumes) yield tmp finally: rmtree(tmp) diff --git a/mkosi/state.py b/mkosi/state.py index a0fc84975..25f0b57b7 100644 --- a/mkosi/state.py +++ b/mkosi/state.py @@ -21,7 +21,7 @@ class MkosiState: if config.overlay: self.root.mkdir() else: - make_tree(self.config, self.root) + make_tree(self.root, use_subvolumes=self.config.use_subvolumes) self.staging.mkdir() self.pkgmngr.mkdir() diff --git a/mkosi/tree.py b/mkosi/tree.py index dfbe77aee..014f130b2 100644 --- a/mkosi/tree.py +++ b/mkosi/tree.py @@ -7,7 +7,7 @@ from pathlib import Path from typing import Optional from mkosi.archive import extract_tar -from mkosi.config import ConfigFeature, MkosiConfig +from mkosi.config import ConfigFeature from mkosi.log import die from mkosi.run import run from mkosi.types import PathString @@ -23,20 +23,20 @@ def is_subvolume(path: Path) -> bool: return path.is_dir() and statfs(path) == "btrfs" and path.stat().st_ino == 256 -def make_tree(config: MkosiConfig, path: Path) -> None: - if config.use_subvolumes == ConfigFeature.enabled and not shutil.which("btrfs"): +def make_tree(path: Path, use_subvolumes: ConfigFeature = ConfigFeature.disabled) -> None: + if use_subvolumes == ConfigFeature.enabled and not shutil.which("btrfs"): die("Subvolumes requested but the btrfs command was not found") if statfs(path.parent) != "btrfs": - if config.use_subvolumes == ConfigFeature.enabled: + if use_subvolumes == ConfigFeature.enabled: die(f"Subvolumes requested but {path} is not located on a btrfs filesystem") path.mkdir() return - if config.use_subvolumes != ConfigFeature.disabled and shutil.which("btrfs") is not None: + if use_subvolumes != ConfigFeature.disabled and shutil.which("btrfs") is not None: result = run(["btrfs", "subvolume", "create", path], - check=config.use_subvolumes == ConfigFeature.enabled).returncode + check=use_subvolumes == ConfigFeature.enabled).returncode else: result = 1 @@ -48,11 +48,18 @@ def cp_version() -> GenericVersion: return GenericVersion(run(["cp", "--version"], stdout=subprocess.PIPE).stdout.strip().splitlines()[0].split()[3]) -def copy_tree(config: MkosiConfig, src: Path, dst: Path, *, preserve_owner: bool = True, clobber: bool = True) -> None: - subvolume = (config.use_subvolumes == ConfigFeature.enabled or - config.use_subvolumes == ConfigFeature.auto and shutil.which("btrfs") is not None) +def copy_tree( + src: Path, + dst: Path, + *, + preserve_owner: bool = True, + clobber: bool = True, + use_subvolumes: ConfigFeature = ConfigFeature.disabled, +) -> None: + subvolume = (use_subvolumes == ConfigFeature.enabled or + use_subvolumes == ConfigFeature.auto and shutil.which("btrfs") is not None) - if config.use_subvolumes == ConfigFeature.enabled and not shutil.which("btrfs"): + if use_subvolumes == ConfigFeature.enabled and not shutil.which("btrfs"): die("Subvolumes requested but the btrfs command was not found") copy: list[PathString] = [ @@ -88,7 +95,7 @@ def copy_tree(config: MkosiConfig, src: Path, dst: Path, *, preserve_owner: bool if shutil.which("btrfs"): result = run(["btrfs", "subvolume", "snapshot", src, dst], - check=config.use_subvolumes == ConfigFeature.enabled).returncode + check=use_subvolumes == ConfigFeature.enabled).returncode else: result = 1 @@ -100,7 +107,7 @@ def rmtree(*paths: Path) -> None: run(["rm", "-rf", "--", *paths]) -def move_tree(config: MkosiConfig, src: Path, dst: Path) -> None: +def move_tree(src: Path, dst: Path, use_subvolumes: ConfigFeature = ConfigFeature.disabled) -> None: if src == dst: return @@ -113,11 +120,16 @@ def move_tree(config: MkosiConfig, src: Path, dst: Path) -> None: if e.errno != errno.EXDEV: raise e - copy_tree(config, src, dst) + copy_tree(src, dst, use_subvolumes=use_subvolumes) rmtree(src) -def install_tree(config: MkosiConfig, src: Path, dst: Path, target: Optional[Path] = None) -> None: +def install_tree( + src: Path, + dst: Path, + target: Optional[Path] = None, + use_subvolumes: ConfigFeature = ConfigFeature.disabled, +) -> None: t = dst if target: t = dst / target.relative_to("/") @@ -126,7 +138,7 @@ def install_tree(config: MkosiConfig, src: Path, dst: Path, target: Optional[Pat t.parent.mkdir(parents=True, exist_ok=True) if src.is_dir() or (src.is_file() and target): - copy_tree(config, src, t, preserve_owner=False) + copy_tree(src, t, preserve_owner=False, use_subvolumes=use_subvolumes) elif src.suffix == ".tar": extract_tar(src, t) elif src.suffix == ".raw":