Skip to content

Commit

Permalink
mkosi-initrd: build using a temporary directory
Browse files Browse the repository at this point in the history
Fixes #3083
  • Loading branch information
aafeijoo-suse authored and DaanDeMeyer committed Oct 3, 2024
1 parent 601b152 commit 6b0dfe5
Showing 1 changed file with 63 additions and 46 deletions.
109 changes: 63 additions & 46 deletions mkosi/initrd.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,9 +11,10 @@
import mkosi.resources
from mkosi.config import DocFormat, OutputFormat
from mkosi.documentation import show_docs
from mkosi.log import log_setup
from mkosi.log import log_notice, log_setup
from mkosi.run import find_binary, run, uncaught_exception_handler
from mkosi.sandbox import __version__
from mkosi.sandbox import __version__, umask
from mkosi.tree import copy_tree
from mkosi.types import PathString
from mkosi.util import resource_path

Expand Down Expand Up @@ -88,55 +89,58 @@ def main() -> None:
show_docs("mkosi-initrd", DocFormat.all(), resources=r)
return

cmdline: list[PathString] = [
"mkosi",
"--force",
"--directory", "",
"--format", args.format,
"--output", args.output,
"--output-dir", args.output_dir,
"--extra-tree", f"/usr/lib/modules/{args.kernel_version}:/usr/lib/modules/{args.kernel_version}",
"--extra-tree=/usr/lib/firmware:/usr/lib/firmware",
"--remove-files=/usr/lib/firmware/*-ucode",
"--kernel-modules-exclude=.*",
"--kernel-modules-include=host",
"--build-sources", "",
"--include=mkosi-initrd",
] # fmt: skip

if args.debug:
cmdline += ["--debug"]
if args.debug_shell:
cmdline += ["--debug-shell"]

if os.getuid() == 0:
cmdline += [
"--workspace-dir=/var/tmp",
"--package-cache-dir=/var",
"--cache-only=metadata",
]
if args.format != OutputFormat.directory.value:
cmdline += ["--output-mode=600"]

for d in (
"/usr/lib/mkosi-initrd",
"/usr/local/lib/mkosi-initrd",
"/run/mkosi-initrd",
"/etc/mkosi-initrd",
with (
tempfile.TemporaryDirectory() as staging_dir,
tempfile.TemporaryDirectory() as sandbox_tree,
):
if Path(d).exists():
cmdline += ["--include", d]
cmdline: list[PathString] = [
"mkosi",
"--force",
"--directory", "",
"--format", args.format,
"--output", args.output,
"--output-dir", staging_dir,
"--extra-tree", f"/usr/lib/modules/{args.kernel_version}:/usr/lib/modules/{args.kernel_version}",
"--extra-tree=/usr/lib/firmware:/usr/lib/firmware",
"--remove-files=/usr/lib/firmware/*-ucode",
"--kernel-modules-exclude=.*",
"--kernel-modules-include=host",
"--build-sources", "",
"--include=mkosi-initrd",
] # fmt: skip

if args.debug:
cmdline += ["--debug"]
if args.debug_shell:
cmdline += ["--debug-shell"]

if os.getuid() == 0:
cmdline += [
"--workspace-dir=/var/tmp",
"--package-cache-dir=/var",
"--cache-only=metadata",
]
if args.format != OutputFormat.directory.value:
cmdline += ["--output-mode=600"]

for d in (
"/usr/lib/mkosi-initrd",
"/usr/local/lib/mkosi-initrd",
"/run/mkosi-initrd",
"/etc/mkosi-initrd",
):
if Path(d).exists():
cmdline += ["--include", d]

with tempfile.TemporaryDirectory() as d:
# Make sure we don't use any of mkosi's default repositories.
for p in (
"yum.repos.d/mkosi.repo",
"apt/sources.list.d/mkosi.sources",
"zypp/repos.d/mkosi.repo",
"pacman.conf",
):
(Path(d) / "etc" / p).parent.mkdir(parents=True, exist_ok=True)
(Path(d) / "etc" / p).touch()
(Path(sandbox_tree) / "etc" / p).parent.mkdir(parents=True, exist_ok=True)
(Path(sandbox_tree) / "etc" / p).touch()

# Copy in the host's package manager configuration.
for p in (
Expand All @@ -150,18 +154,18 @@ def main() -> None:
if not (Path("/etc") / p).exists():
continue

(Path(d) / "etc" / p).parent.mkdir(parents=True, exist_ok=True)
(Path(sandbox_tree) / "etc" / p).parent.mkdir(parents=True, exist_ok=True)
if (Path("/etc") / p).resolve().is_file():
shutil.copy2(Path("/etc") / p, Path(d) / "etc" / p)
shutil.copy2(Path("/etc") / p, Path(sandbox_tree) / "etc" / p)
else:
shutil.copytree(
Path("/etc") / p,
Path(d) / "etc" / p,
Path(sandbox_tree) / "etc" / p,
ignore=shutil.ignore_patterns("gnupg"),
dirs_exist_ok=True,
)

cmdline += ["--sandbox-tree", d]
cmdline += ["--sandbox-tree", sandbox_tree]

# Prefer dnf as dnf5 has not yet officially replaced it and there's a much bigger chance that there
# will be a populated dnf cache directory.
Expand All @@ -172,6 +176,19 @@ def main() -> None:
env={"MKOSI_DNF": dnf.name} if (dnf := find_binary("dnf", "dnf5")) else {},
)

if args.output_dir:
with umask(~0o700):
Path(args.output_dir).mkdir(parents=True, exist_ok=True)
else:
args.output_dir = Path.cwd()

log_notice(f"Copying {staging_dir}/{args.output} to {args.output_dir}/{args.output}")
# mkosi symlinks the expected output image, so dereference it
copy_tree(
Path(f"{staging_dir}/{args.output}").resolve(),
Path(f"{args.output_dir}/{args.output}"),
)


if __name__ == "__main__":
main()

0 comments on commit 6b0dfe5

Please sign in to comment.