]> git.ipfire.org Git - thirdparty/mkosi.git/commitdiff
Parse credentials from files/dirs during parsing instead of afterwards 2575/head
authorDaan De Meyer <daan.j.demeyer@gmail.com>
Mon, 1 Apr 2024 16:02:07 +0000 (18:02 +0200)
committerDaan De Meyer <daan.j.demeyer@gmail.com>
Tue, 2 Apr 2024 10:11:53 +0000 (12:11 +0200)
mkosi/config.py
mkosi/resources/mkosi.md

index 7df0a5d2feb7249e7ae05c88dbcae1d824695aef..aa8696957e29de020ce4cf45f146ccde85c516ef 100644 (file)
@@ -794,6 +794,7 @@ def config_make_dict_parser(delimiter: str,
                             *,
                             parse: Callable[[str], tuple[str, Any]],
                             unescape: bool = False,
+                            allow_paths: bool = False,
                             reset: bool = True) -> ConfigParseCallback:
     def config_parse_dict(value: Optional[str], old: Optional[dict[str, Any]]) -> Optional[dict[str, Any]]:
         new = old.copy() if old else {}
@@ -801,6 +802,24 @@ def config_make_dict_parser(delimiter: str,
         if value is None:
             return {}
 
+        if allow_paths and "=" not in value:
+            if Path(value).is_dir():
+                for p in Path(value).iterdir():
+                    if p.is_dir():
+                        continue
+
+                    if os.access(p, os.X_OK):
+                        new[p.name] = run([p], stdout=subprocess.PIPE, env=os.environ).stdout
+                    else:
+                        new[p.name] = p.read_text()
+            elif (p := Path(value)).exists():
+                if os.access(p, os.X_OK):
+                    new[p.name] = run([p], stdout=subprocess.PIPE, env=os.environ).stdout
+                else:
+                    new[p.name] = p.read_text()
+            else:
+                die(f"{p} does not exist")
+
         if unescape:
             lex = shlex.shlex(value, posix=True)
             lex.whitespace_split = True
@@ -2621,8 +2640,10 @@ SETTINGS = (
         long="--credential",
         metavar="NAME=VALUE",
         section="Host",
-        parse=config_make_dict_parser(delimiter=" ", parse=parse_credential, unescape=True),
+        parse=config_make_dict_parser(delimiter=" ", parse=parse_credential, allow_paths=True, unescape=True),
         help="Pass a systemd credential to systemd-nspawn or qemu",
+        paths=("mkosi.credentials",),
+        path_default=False,
     ),
     ConfigSetting(
         dest="kernel_command_line_extra",
@@ -3496,18 +3517,10 @@ def load_credentials(args: argparse.Namespace) -> dict[str, str]:
     creds = {
         "agetty.autologin": "root",
         "login.noauth": "yes",
+        "firstboot.locale": "C.UTF-8",
+        **args.credentials,
     }
 
-    d = Path("mkosi.credentials")
-    if args.directory is not None and d.is_dir():
-        for e in d.iterdir():
-            if os.access(e, os.X_OK):
-                creds[e.name] = run([e], stdout=subprocess.PIPE, env=os.environ).stdout
-            else:
-                creds[e.name] = e.read_text()
-
-    creds |= args.credentials
-
     if "firstboot.timezone" not in creds:
         if find_binary("timedatectl"):
             tz = run(
@@ -3520,9 +3533,6 @@ def load_credentials(args: argparse.Namespace) -> dict[str, str]:
 
         creds["firstboot.timezone"] = tz
 
-    if "firstboot.locale" not in creds:
-        creds["firstboot.locale"] = "C.UTF-8"
-
     if "ssh.authorized_keys.root" not in creds:
         if args.ssh_certificate:
             pubkey = run(["openssl", "x509", "-in", args.ssh_certificate, "-pubkey", "-noout"],
index c7aac8a5e4c3fa24571ab9250d5234a442a9add4..f3e1d55ed984fcbc6dca54cdab4f5407a9800ebd 100644 (file)
@@ -1636,9 +1636,17 @@ boolean argument: either `1`, `yes`, or `true` to enable, or `0`, `no`,
 
 `Credentials=`, `--credential=`
 
-: Set credentials to be passed to systemd-nspawn or qemu respectively when
-  `mkosi shell/boot` or `mkosi qemu` are used. This option takes a space separated
-  list of key=value assignments.
+: Set credentials to be passed to systemd-nspawn or qemu respectively
+  when `mkosi shell/boot` or `mkosi qemu` are used. This option takes a
+  space separated list of values which can be either key=value pairs or
+  paths. If a path is provided, if it is a file, the credential name
+  will be the name of the file. If the file is executable, the
+  credential value will be the output of executing the file. Otherwise,
+  the credential value will be the contents of the file. If the path is
+  a directory, the same logic applies to each file in the directory.
+
+: Note that values will only be treated as paths if they do not contain
+  the delimiter (`=`).
 
 `KernelCommandLineExtra=`, `--kernel-command-line-extra=`