From: Daan De Meyer Date: Thu, 13 Feb 2025 21:23:41 +0000 (+0100) Subject: Move load_environment() into finalize_environment() method of Config X-Git-Tag: v26~384^2~6 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=afbbb6af3c45f90300e72e10a451eae2f7a79932;p=thirdparty%2Fmkosi.git Move load_environment() into finalize_environment() method of Config Let's stop showing all derived environment variables values in the summary and let's stop passing them to the default tools and initrd images since they'll be derived again there anyway. --- diff --git a/mkosi/__init__.py b/mkosi/__init__.py index aa45675d9..4cace1d67 100644 --- a/mkosi/__init__.py +++ b/mkosi/__init__.py @@ -421,7 +421,7 @@ def configure_extension_release(context: Context) -> None: if f"{prefix}_SCOPE" not in extrelease: f.write( f"{prefix}_SCOPE=" - f"{context.config.environment.get(f'{prefix}_SCOPE', 'initrd system portable')}\n" + f"{context.config.finalize_environment().get(f'{prefix}_SCOPE', 'initrd system portable')}\n" ) if "ARCHITECTURE" not in extrelease: @@ -579,7 +579,7 @@ def run_configure_scripts(config: Config) -> Config: with complete_step(f"Running configure script {script}…"): result = run( ["/work/configure"], - env=env | config.environment, + env=env | config.finalize_environment(), sandbox=config.sandbox( options=[ "--dir", "/work/src", @@ -652,7 +652,7 @@ def run_sync_scripts(config: Config) -> None: with complete_step(f"Running sync script {script}…"): run( ["/work/sync", "final"], - env=env | config.environment, + env=env | config.finalize_environment(), stdin=sys.stdin, sandbox=config.sandbox( network=True, @@ -671,7 +671,9 @@ def script_maybe_chroot_sandbox( network: bool, ) -> Iterator[list[PathString]]: options = ["--dir", "/work/src", "--chdir", "/work/src", *options] - suppress_chown = parse_boolean(context.config.environment.get("MKOSI_CHROOT_SUPPRESS_CHOWN", "0")) + suppress_chown = parse_boolean( + context.config.finalize_environment().get("MKOSI_CHROOT_SUPPRESS_CHOWN", "0") + ) helpers = { "mkosi-chroot": [ @@ -743,7 +745,7 @@ def run_prepare_scripts(context: Context, build: bool) -> None: if context.config.profiles: env["PROFILES"] = " ".join(context.config.profiles) - env |= context.config.environment + env |= context.config.finalize_environment() with ( mount_build_overlay(context) if build else contextlib.nullcontext(), @@ -819,7 +821,7 @@ def run_build_scripts(context: Context) -> None: CHROOT_BUILDDIR="/work/build", ) - env |= context.config.environment + env |= context.config.finalize_environment() with ( mount_build_overlay(context, volatile=True), @@ -889,7 +891,7 @@ def run_postinst_scripts(context: Context) -> None: if context.config.build_dir is not None: env |= dict(BUILDDIR="/work/build") - env |= context.config.environment + env |= context.config.finalize_environment() with ( finalize_source_mounts( @@ -958,7 +960,7 @@ def run_finalize_scripts(context: Context) -> None: if context.config.build_dir is not None: env |= dict(BUILDDIR="/work/build") - env |= context.config.environment + env |= context.config.finalize_environment() with ( finalize_source_mounts( @@ -1026,7 +1028,7 @@ def run_postoutput_scripts(context: Context) -> None: with complete_step(f"Running post-output script {script}…"): run( ["/work/postoutput"], - env=env | context.config.environment, + env=env | context.config.finalize_environment(), sandbox=context.sandbox( # postoutput scripts should run as (fake) root so that file ownership is # always recorded as if owned by root. @@ -1637,7 +1639,7 @@ def run_ukify( else subprocess.DEVNULL ), stdout=stdout, - env=context.config.environment, + env=context.config.finalize_environment(), sandbox=context.sandbox( options=[*opt, *options], devices=context.config.secure_boot_key_source.type != KeySourceType.file, @@ -2474,7 +2476,7 @@ def calculate_signature_gpg(context: Context) -> None: workdir(context.staging / context.config.output_checksum), ] - home = Path(context.config.environment.get("GNUPGHOME", INVOKING_USER.home() / ".gnupg")) + home = Path(context.config.finalize_environment().get("GNUPGHOME", INVOKING_USER.home() / ".gnupg")) if not home.exists(): die(f"GPG home {home} not found") @@ -2507,7 +2509,7 @@ def calculate_signature_sop(context: Context) -> None: ): run( [context.config.openpgp_tool, "sign", "/signing-key.pgp"], - env=context.config.environment, + env=context.config.finalize_environment(), stdin=i, stdout=o, sandbox=context.sandbox( @@ -4184,7 +4186,7 @@ def run_shell(args: Args, config: Config) -> None: workdir(fname), ], stdin=sys.stdin, - env=config.environment, + env=config.finalize_environment(), sandbox=config.sandbox( network=True, devices=True, @@ -4294,7 +4296,7 @@ def run_shell(args: Args, config: Config) -> None: cmdline, stdin=sys.stdin, stdout=sys.stdout, - env=os.environ | config.environment, + env=os.environ | config.finalize_environment(), log=False, sandbox=config.sandbox( devices=True, @@ -4335,7 +4337,7 @@ def run_systemd_tool(tool: str, args: Args, config: Config) -> None: [tool_path, "--root" if output.is_dir() else "--image", output, *args.cmdline], stdin=sys.stdin, stdout=sys.stdout, - env=os.environ | config.environment, + env=os.environ | config.finalize_environment(), log=False, sandbox=config.sandbox( network=True, @@ -4574,7 +4576,7 @@ def run_clean_scripts(config: Config) -> None: with complete_step(f"Running clean script {script}…"): run( ["/work/clean"], - env=env | config.environment, + env=env | config.finalize_environment(), sandbox=config.sandbox( tools=False, options=[ diff --git a/mkosi/bootloader.py b/mkosi/bootloader.py index 8fdd0f0f5..5344c4138 100644 --- a/mkosi/bootloader.py +++ b/mkosi/bootloader.py @@ -440,7 +440,7 @@ def run_systemd_sign_tool( return run( cmdline, stdout=stdout, - env={**config.environment, **env}, + env={**config.finalize_environment(), **env}, sandbox=config.sandbox(options=options, devices=devices), ) @@ -475,7 +475,7 @@ def run_systemd_sign_tool( cmd, stdin=(sys.stdin if key_source.type != KeySourceType.file else subprocess.DEVNULL), stdout=stdout, - env={**config.environment, **env}, + env={**config.finalize_environment(), **env}, sandbox=config.sandbox( options=opt, devices=( @@ -546,7 +546,7 @@ def sign_efi_binary(context: Context, input: Path, output: Path) -> Path: if context.config.secure_boot_key_source.type != KeySourceType.file else subprocess.DEVNULL ), - env=context.config.environment, + env=context.config.finalize_environment(), sandbox=context.sandbox( options=options, devices=context.config.secure_boot_key_source.type != KeySourceType.file, diff --git a/mkosi/burn.py b/mkosi/burn.py index 24dc20e3c..51f77e737 100644 --- a/mkosi/burn.py +++ b/mkosi/burn.py @@ -38,7 +38,7 @@ def run_burn(args: Args, config: Config) -> None: cmd, stdin=sys.stdin, stdout=sys.stdout, - env=os.environ | config.environment, + env=os.environ | config.finalize_environment(), log=False, sandbox=config.sandbox( devices=True, diff --git a/mkosi/config.py b/mkosi/config.py index a7cae41fc..10f230768 100644 --- a/mkosi/config.py +++ b/mkosi/config.py @@ -1975,6 +1975,49 @@ class Config: image: Optional[str] + def finalize_environment(self) -> dict[str, str]: + env = { + "SYSTEMD_TMPFILES_FORCE_SUBVOL": "0", + "SYSTEMD_ASK_PASSWORD_KEYRING_TIMEOUT_SEC": "infinity", + "SYSTEMD_ASK_PASSWORD_KEYRING_TYPE": "session", + "TERM": finalize_term(), + } + + if self.image is not None: + env["SUBIMAGE"] = self.image + if self.image_id is not None: + env["IMAGE_ID"] = self.image_id + if self.image_version is not None: + env["IMAGE_VERSION"] = self.image_version + if self.source_date_epoch is not None: + env["SOURCE_DATE_EPOCH"] = str(self.source_date_epoch) + if self.proxy_url is not None: + for e in ("http_proxy", "https_proxy"): + env[e] = self.proxy_url + env[e.upper()] = self.proxy_url + if self.proxy_exclude: + env["no_proxy"] = ",".join(self.proxy_exclude) + env["NO_PROXY"] = ",".join(self.proxy_exclude) + if self.proxy_peer_certificate: + env["GIT_PROXY_SSL_CAINFO"] = "/proxy.cacert" + if self.proxy_client_certificate: + env["GIT_PROXY_SSL_CERT"] = "/proxy.clientcert" + if self.proxy_client_key: + env["GIT_PROXY_SSL_KEY"] = "/proxy.clientkey" + if dnf := os.getenv("MKOSI_DNF"): + env["MKOSI_DNF"] = dnf + if gnupghome := os.getenv("GNUPGHOME"): + env["GNUPGHOME"] = gnupghome + + env |= dict( + parse_environment(line) + for f in self.environment_files + for line in f.read_text().strip().splitlines() + ) + env |= self.environment + + return env + def name(self) -> str: return self.image or self.image_id or "default" @@ -4697,50 +4740,6 @@ def finalize_term() -> str: return term if sys.stderr.isatty() else "dumb" -def load_environment(args: argparse.Namespace) -> dict[str, str]: - env = { - "SYSTEMD_TMPFILES_FORCE_SUBVOL": "0", - "SYSTEMD_ASK_PASSWORD_KEYRING_TIMEOUT_SEC": "infinity", - "SYSTEMD_ASK_PASSWORD_KEYRING_TYPE": "session", - "TERM": finalize_term(), - } - - if args.image is not None: - env["SUBIMAGE"] = args.image - if args.image_id is not None: - env["IMAGE_ID"] = args.image_id - if args.image_version is not None: - env["IMAGE_VERSION"] = args.image_version - if args.source_date_epoch is not None: - env["SOURCE_DATE_EPOCH"] = str(args.source_date_epoch) - if args.proxy_url is not None: - for e in ("http_proxy", "https_proxy"): - env[e] = args.proxy_url - env[e.upper()] = args.proxy_url - if args.proxy_exclude: - env["no_proxy"] = ",".join(args.proxy_exclude) - env["NO_PROXY"] = ",".join(args.proxy_exclude) - if args.proxy_peer_certificate: - env["GIT_PROXY_SSL_CAINFO"] = "/proxy.cacert" - if args.proxy_client_certificate: - env["GIT_PROXY_SSL_CERT"] = "/proxy.clientcert" - if args.proxy_client_key: - env["GIT_PROXY_SSL_KEY"] = "/proxy.clientkey" - if dnf := os.getenv("MKOSI_DNF"): - env["MKOSI_DNF"] = dnf - if gnupghome := os.getenv("GNUPGHOME"): - env["GNUPGHOME"] = gnupghome - - env |= dict( - parse_environment(line) - for f in args.environment_files - for line in f.read_text().strip().splitlines() - ) - env |= args.environment - - return env - - def load_args(args: argparse.Namespace) -> Args: if args.cmdline and not args.verb.supports_cmdline(): die(f"Arguments after verb are not supported for {args.verb}.") @@ -4765,8 +4764,6 @@ def load_config(config: argparse.Namespace) -> Config: ): config.build_dir /= f"{config.distribution}~{config.release}~{config.architecture}" - config.environment = load_environment(config) - return Config.from_namespace(config) diff --git a/mkosi/distributions/centos.py b/mkosi/distributions/centos.py index b7817e182..3d4e54eb2 100644 --- a/mkosi/distributions/centos.py +++ b/mkosi/distributions/centos.py @@ -242,7 +242,9 @@ class Installer(DistributionInstaller): # For EPEL we make the assumption that epel is mirrored in the parent directory of the mirror # URL and path we were given. Since this doesn't work for all scenarios, we also allow # overriding the mirror via an environment variable. - url = context.config.environment.get("EPEL_MIRROR", join_mirror(mirror, "../fedora")) + url = context.config.finalize_environment().get( + "EPEL_MIRROR", join_mirror(mirror, "../fedora") + ) yield RpmRepository( repo, f"baseurl={url}/{dir}/$releasever/Everything/$basearch", diff --git a/mkosi/installer/__init__.py b/mkosi/installer/__init__.py index 0453d362b..4afe44036 100644 --- a/mkosi/installer/__init__.py +++ b/mkosi/installer/__init__.py @@ -41,11 +41,11 @@ class PackageManager: "SYSTEMD_IN_CHROOT": "1", } - if "SYSTEMD_HWDB_UPDATE_BYPASS" not in context.config.environment: + if "SYSTEMD_HWDB_UPDATE_BYPASS" not in context.config.finalize_environment(): env["SYSTEMD_HWDB_UPDATE_BYPASS"] = "1" if ( - "KERNEL_INSTALL_BYPASS" not in context.config.environment + "KERNEL_INSTALL_BYPASS" not in context.config.finalize_environment() and context.config.bootable != ConfigFeature.disabled ): env["KERNEL_INSTALL_BYPASS"] = "1" diff --git a/mkosi/installer/apt.py b/mkosi/installer/apt.py index f635dc69a..3f1a35f1c 100644 --- a/mkosi/installer/apt.py +++ b/mkosi/installer/apt.py @@ -148,7 +148,10 @@ class Apt(PackageManager): "DEBCONF_INTERACTIVE_SEEN": "true", } - if "INITRD" not in context.config.environment and context.config.bootable != ConfigFeature.disabled: + if ( + "INITRD" not in context.config.finalize_environment() + and context.config.bootable != ConfigFeature.disabled + ): env["INITRD"] = "No" return super().finalize_environment(context) | env diff --git a/mkosi/installer/dnf.py b/mkosi/installer/dnf.py index 8115fb7fd..af5de1452 100644 --- a/mkosi/installer/dnf.py +++ b/mkosi/installer/dnf.py @@ -17,7 +17,7 @@ class Dnf(PackageManager): @classmethod def executable(cls, config: Config) -> str: # Allow the user to override autodetection with an environment variable - dnf = config.environment.get("MKOSI_DNF") + dnf = config.finalize_environment().get("MKOSI_DNF") return Path(dnf or config.find_binary("dnf5") or "dnf").name @classmethod diff --git a/mkosi/qemu.py b/mkosi/qemu.py index 9c78b06f0..b69e5a408 100644 --- a/mkosi/qemu.py +++ b/mkosi/qemu.py @@ -696,7 +696,7 @@ def generate_scratch_fs(config: Config) -> Iterator[Path]: with tempfile.NamedTemporaryFile(dir="/var/tmp", prefix="mkosi-scratch-") as scratch: scratch.truncate(1024**4) fs = config.distribution.filesystem() - extra = config.environment.get(f"SYSTEMD_REPART_MKFS_OPTIONS_{fs.upper()}", "") + extra = config.finalize_environment().get(f"SYSTEMD_REPART_MKFS_OPTIONS_{fs.upper()}", "") run( [f"mkfs.{fs}", "-L", "scratch", "-q", *extra.split(), workdir(Path(scratch.name))], sandbox=config.sandbox(options=["--bind", scratch.name, workdir(Path(scratch.name))]), @@ -1001,7 +1001,7 @@ def machine1_is_available(config: Config) -> bool: services = json.loads( run( ["busctl", "list", "--json=pretty"], - env=os.environ | config.environment, + env=os.environ | config.finalize_environment(), sandbox=config.sandbox(relaxed=True), stdout=subprocess.PIPE, ).stdout.strip() @@ -1060,7 +1060,7 @@ def register_machine(config: Config, pid: int, fname: Path, cid: Optional[int]) } ), ], - env=os.environ | config.environment, + env=os.environ | config.finalize_environment(), sandbox=config.sandbox(relaxed=True), stdin=sys.stdin, # Prevent varlinkctl's empty '{}' response from showing up in the terminal. @@ -1089,7 +1089,7 @@ def register_machine(config: Config, pid: int, fname: Path, cid: Optional[int]) str(pid), fname if fname.is_dir() else "", ], # fmt: skip - env=os.environ | config.environment, + env=os.environ | config.finalize_environment(), sandbox=config.sandbox(relaxed=True), stdin=sys.stdin, stdout=sys.stdout, @@ -1562,7 +1562,7 @@ def run_qemu(args: Args, config: Config) -> None: stdout=stdout, stderr=stderr, pass_fds=qemu_device_fds.values(), - env=os.environ | config.environment, + env=os.environ | config.finalize_environment(), sandbox=config.sandbox( network=True, devices=True, @@ -1625,7 +1625,7 @@ def run_ssh(args: Args, config: Config) -> None: cmd, stdin=sys.stdin, stdout=sys.stdout, - env=os.environ | config.environment | {"SHELL": "/bin/bash"}, + env=os.environ | config.finalize_environment() | {"SHELL": "/bin/bash"}, log=False, sandbox=config.sandbox( network=True, diff --git a/mkosi/sysupdate.py b/mkosi/sysupdate.py index 5b2e3909f..a9bc5e841 100644 --- a/mkosi/sysupdate.py +++ b/mkosi/sysupdate.py @@ -49,7 +49,7 @@ def run_sysupdate(args: Args, config: Config) -> None: cmd, stdin=sys.stdin, stdout=sys.stdout, - env=os.environ | config.environment, + env=os.environ | config.finalize_environment(), log=False, sandbox=config.sandbox( devices=True, diff --git a/mkosi/vmspawn.py b/mkosi/vmspawn.py index ad7fa8337..e7e996f35 100644 --- a/mkosi/vmspawn.py +++ b/mkosi/vmspawn.py @@ -114,7 +114,7 @@ def run_vmspawn(args: Args, config: Config) -> None: cmdline, stdin=sys.stdin, stdout=sys.stdout, - env=env | config.environment, + env=env | config.finalize_environment(), log=False, sandbox=config.sandbox( network=True, diff --git a/tests/test_config.py b/tests/test_config.py index 2360e943b..5f9830755 100644 --- a/tests/test_config.py +++ b/tests/test_config.py @@ -1299,7 +1299,7 @@ def test_environment(tmp_path: Path) -> None: } # Only check values for keys from expected, as config.environment contains other items as well - assert {k: config.environment[k] for k in expected.keys()} == expected + assert {k: config.finalize_environment()[k] for k in expected.keys()} == expected assert config.environment_files == [Path.cwd() / "mkosi.env", Path.cwd() / "other.env"]