install: upload vars needed for activation for installation

This commit is contained in:
Michael Hoang
2024-12-21 12:41:19 +11:00
committed by Mic92
parent 0721a338fb
commit 1d7e0c1c02
3 changed files with 14 additions and 12 deletions

View File

@@ -5,7 +5,6 @@
... ...
}: }:
let let
inherit (lib) mkOption;
inherit (builtins) inherit (builtins)
hashString hashString
toJSON toJSON
@@ -198,9 +197,11 @@ in
}; };
neededFor = lib.mkOption { neededFor = lib.mkOption {
description = '' description = ''
Enabling this option causes the secret to be decrypted/installed before users and groups are created. This option determines when the secret will be decrypted and deployed to the target machine.
This can be used to retrieve user's passwords.
Setting this option moves the secret to /run/secrets-for-users and disallows setting owner and group to anything else than root. By setting this to `activation`, the secret will be deployed prior to running `nixos-rebuild` or `nixos-install`.
By setting this to `user`, the secret will be deployed prior to users and groups are created, allowing
users' passwords to be managed by vars. The secret will be stored in `/run/secrets-for-users` and `owner` and `group` must be `root`.
''; '';
type = lib.types.enum [ type = lib.types.enum [
"activation" "activation"

View File

@@ -1,5 +1,4 @@
import argparse import argparse
import importlib
import logging import logging
import os import os
import sys import sys
@@ -44,9 +43,7 @@ def install_machine(opts: InstallOptions) -> None:
machine = opts.machine machine = opts.machine
machine.override_target_host = opts.target_host machine.override_target_host = opts.target_host
secret_facts_module = importlib.import_module(machine.secret_facts_module)
machine.info(f"installing {machine.name}") machine.info(f"installing {machine.name}")
secret_facts_store = secret_facts_module.SecretStore(machine=machine)
h = machine.target_host h = machine.target_host
target_host = f"{h.user or 'root'}@{h.host}" target_host = f"{h.user or 'root'}@{h.host}"
@@ -63,7 +60,8 @@ def install_machine(opts: InstallOptions) -> None:
upload_dir_ = upload_dir_[1:] upload_dir_ = upload_dir_[1:]
upload_dir = tmpdir / upload_dir_ upload_dir = tmpdir / upload_dir_
upload_dir.mkdir(parents=True) upload_dir.mkdir(parents=True)
secret_facts_store.upload(upload_dir) machine.secret_facts_store.upload(upload_dir)
machine.secret_vars_store.populate_dir(upload_dir)
if opts.password: if opts.password:
os.environ["SSHPASS"] = opts.password os.environ["SSHPASS"] = opts.password

View File

@@ -172,17 +172,20 @@ class SecretStore(StoreBase):
self.machine.flake_dir, self.machine.flake_dir,
sops_secrets_folder(self.machine.flake_dir) / key_name, sops_secrets_folder(self.machine.flake_dir) / key_name,
) )
(output_dir / "key.txt").touch(mode=0o600)
(output_dir / "key.txt").write_text(key) (output_dir / "key.txt").write_text(key)
for generator in self.machine.vars_generators: for generator in self.machine.vars_generators:
for file in generator.files: for file in generator.files:
if file.needed_for == "activation": if file.needed_for == "activation":
(output_dir / generator.name / file.name).parent.mkdir( target_path = output_dir / generator.name / file.name
target_path.parent.mkdir(
parents=True, parents=True,
exist_ok=True, exist_ok=True,
) )
(output_dir / generator.name / file.name).write_bytes( # chmod after in case it doesn't have u+w
self.get(generator, file.name) target_path.touch(mode=0o600)
) target_path.write_bytes(self.get(generator, file.name))
target_path.chmod(file.mode)
def upload(self) -> None: def upload(self) -> None:
with TemporaryDirectory(prefix="sops-upload-") as tempdir: with TemporaryDirectory(prefix="sops-upload-") as tempdir: