]> git.ipfire.org Git - thirdparty/mkosi.git/commitdiff
Move load_environment() into finalize_environment() method of Config
authorDaan De Meyer <daan.j.demeyer@gmail.com>
Thu, 13 Feb 2025 21:23:41 +0000 (22:23 +0100)
committerDaan De Meyer <daan.j.demeyer@gmail.com>
Fri, 14 Feb 2025 13:45:27 +0000 (14:45 +0100)
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.

12 files changed:
mkosi/__init__.py
mkosi/bootloader.py
mkosi/burn.py
mkosi/config.py
mkosi/distributions/centos.py
mkosi/installer/__init__.py
mkosi/installer/apt.py
mkosi/installer/dnf.py
mkosi/qemu.py
mkosi/sysupdate.py
mkosi/vmspawn.py
tests/test_config.py

index aa45675d9fc063c0c2233e6d64e4bcef27ef68a6..4cace1d67b4107fcd5877d509ed02108017e9a09 100644 (file)
@@ -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=[
index 8fdd0f0f5c0be6972d12c913c994d2f2a334506e..5344c4138993bcd8f55ce6ecac144f51fa430ebf 100644 (file)
@@ -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,
index 24dc20e3c98cefc345996d2b049b0b5df777cf14..51f77e7379785d14748a8ce6f93102088f4a5d85 100644 (file)
@@ -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,
index a7cae41fca06844dc3b1a787fe17f71a4aa2e4f9..10f2307686e6ab5e5ea0c6068417e23e650c33fd 100644 (file)
@@ -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)
 
 
index b7817e182ef9f0074c76fe036ff1f0403e22d191..3d4e54eb2a3d4fd73eb46f73bb31834511ca33e4 100644 (file)
@@ -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",
index 0453d362bc4a23e675739c33936d5225cae7538d..4afe44036d33637a39caa4c304740b96c3821abc 100644 (file)
@@ -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"
index f635dc69a2c9858fb89fcecb27af7c0168ac7704..3f1a35f1c806202ed6005791795a86647bf364ac 100644 (file)
@@ -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
index 8115fb7fdf3f37695136515f933d52aacca2ec92..af5de14525924e1b3f6105ae481a281b89e2d546 100644 (file)
@@ -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
index 9c78b06f07d0d0e132f0220a3ed105befcf594e9..b69e5a408e77520e3b4a80094038a0766b6b0903 100644 (file)
@@ -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,
index 5b2e3909f43c53a6223eef4ee914969987561cc6..a9bc5e841b40b4d91d76b5c0ab2144ef4fdd6a21 100644 (file)
@@ -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,
index ad7fa8337794f8b3ada932386ab93825daa51fc6..e7e996f353a87653000d32727450ac97fedc0c3e 100644 (file)
@@ -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,
index 2360e943bf871f0a2586dafedebe5839539e57dc..5f9830755161ab9d993b84e07742df8a849129f3 100644 (file)
@@ -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"]