Skip to content

Commit

Permalink
Parse credentials from files/dirs during parsing instead of afterwards
Browse files Browse the repository at this point in the history
  • Loading branch information
DaanDeMeyer committed Apr 2, 2024
1 parent 2f8c434 commit e0345e0
Show file tree
Hide file tree
Showing 2 changed files with 35 additions and 17 deletions.
38 changes: 24 additions & 14 deletions mkosi/config.py
Original file line number Diff line number Diff line change
Expand Up @@ -794,13 +794,32 @@ 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 {}

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
Expand Down Expand Up @@ -2621,8 +2640,10 @@ def parse_ini(path: Path, only_sections: Collection[str] = ()) -> Iterator[tuple
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",
Expand Down Expand Up @@ -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(
Expand All @@ -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"],
Expand Down
14 changes: 11 additions & 3 deletions mkosi/resources/mkosi.md
Original file line number Diff line number Diff line change
Expand Up @@ -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 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=`

Expand Down

0 comments on commit e0345e0

Please sign in to comment.