1
0
forked from clan/clan-core

Merge pull request 'Consistently pass nix options to underlying tools' (#1488) from pass-nix-options into main

This commit is contained in:
clan-bot 2024-05-29 08:25:53 +00:00
commit d138e29a53
23 changed files with 285 additions and 197 deletions

View File

@ -145,14 +145,14 @@
machine.succeed("echo testing > /var/test-backups/somefile") machine.succeed("echo testing > /var/test-backups/somefile")
# create # create
machine.succeed("clan --debug --flake ${self} backups create test-backup") machine.succeed("clan backups create --debug --flake ${self} test-backup")
machine.wait_until_succeeds("! systemctl is-active borgbackup-job-test-backup >&2") machine.wait_until_succeeds("! systemctl is-active borgbackup-job-test-backup >&2")
machine.succeed("test -f /run/mount-external-disk") machine.succeed("test -f /run/mount-external-disk")
machine.succeed("test -f /run/unmount-external-disk") machine.succeed("test -f /run/unmount-external-disk")
# list # list
backup_id = json.loads(machine.succeed("borg-job-test-backup list --json"))["archives"][0]["archive"] backup_id = json.loads(machine.succeed("borg-job-test-backup list --json"))["archives"][0]["archive"]
out = machine.succeed("clan --debug --flake ${self} backups list test-backup").strip() out = machine.succeed("clan backups list --debug --flake ${self} test-backup").strip()
print(out) print(out)
assert backup_id in out, f"backup {backup_id} not found in {out}" assert backup_id in out, f"backup {backup_id} not found in {out}"
localbackup_id = "hdd::/mnt/external-disk/snapshot.0" localbackup_id = "hdd::/mnt/external-disk/snapshot.0"
@ -160,14 +160,14 @@
## borgbackup restore ## borgbackup restore
machine.succeed("rm -f /var/test-backups/somefile") machine.succeed("rm -f /var/test-backups/somefile")
machine.succeed(f"clan --debug --flake ${self} backups restore test-backup borgbackup 'test-backup::borg@machine:.::{backup_id}' >&2") machine.succeed(f"clan backups restore --debug --flake ${self} test-backup borgbackup 'test-backup::borg@machine:.::{backup_id}' >&2")
assert machine.succeed("cat /var/test-backups/somefile").strip() == "testing", "restore failed" assert machine.succeed("cat /var/test-backups/somefile").strip() == "testing", "restore failed"
machine.succeed("test -f /var/test-service/pre-restore-command") machine.succeed("test -f /var/test-service/pre-restore-command")
machine.succeed("test -f /var/test-service/post-restore-command") machine.succeed("test -f /var/test-service/post-restore-command")
## localbackup restore ## localbackup restore
machine.succeed("rm -f /var/test-backups/somefile /var/test-service/{pre,post}-restore-command") machine.succeed("rm -f /var/test-backups/somefile /var/test-service/{pre,post}-restore-command")
machine.succeed(f"clan --debug --flake ${self} backups restore test-backup localbackup '{localbackup_id}' >&2") machine.succeed(f"clan backups restore --debug --flake ${self} test-backup localbackup '{localbackup_id}' >&2")
assert machine.succeed("cat /var/test-backups/somefile").strip() == "testing", "restore failed" assert machine.succeed("cat /var/test-backups/somefile").strip() == "testing", "restore failed"
machine.succeed("test -f /var/test-service/pre-restore-command") machine.succeed("test -f /var/test-service/pre-restore-command")
machine.succeed("test -f /var/test-service/post-restore-command") machine.succeed("test -f /var/test-service/post-restore-command")

View File

@ -1,33 +1,58 @@
{ ... }: { self, ... }:
{ {
perSystem = perSystem =
{ ... }:
{ {
# checks = pkgs.lib.mkIf (pkgs.stdenv.isLinux) { nodes,
# flash = (import ../lib/test-base.nix) { pkgs,
# name = "flash"; lib,
# nodes.target = { ...
# virtualisation.emptyDiskImages = [ 4096 ]; }:
# virtualisation.memorySize = 3000; let
# environment.systemPackages = [ self.packages.${pkgs.system}.clan-cli ]; dependencies = [
# environment.etc."install-closure".source = "${closureInfo}/store-paths"; self
pkgs.stdenv.drvPath
pkgs.jq
pkgs.disko
pkgs.stdenvNoCC.drvPath
pkgs.openssl
pkgs.curl
self.clanInternals.machines.${pkgs.hostPlatform.system}.test_install_machine.config.system.build.toplevel
self.clanInternals.machines.${pkgs.hostPlatform.system}.test_install_machine.config.system.build.diskoScript
self.clanInternals.machines.${pkgs.hostPlatform.system}.test_install_machine.config.system.clan.deployment.file
self.clanInternals.machines.${pkgs.hostPlatform.system}.test_install_machine.pkgs.disko
] ++ builtins.map (i: i.outPath) (builtins.attrValues self.inputs);
closureInfo = pkgs.closureInfo { rootPaths = dependencies; };
in
{
# Currently disabled...
checks = pkgs.lib.mkIf (false && pkgs.stdenv.isLinux) {
flash = (import ../lib/test-base.nix) {
name = "flash";
nodes.target = {
virtualisation.emptyDiskImages = [ 4096 ];
virtualisation.memorySize = 3000;
environment.systemPackages = [ self.packages.${pkgs.system}.clan-cli ];
environment.etc."install-closure".source = "${closureInfo}/store-paths";
# nix.settings = { nix.settings = {
# substituters = lib.mkForce [ ]; substituters = lib.mkForce [ ];
# hashed-mirrors = null; hashed-mirrors = null;
# connect-timeout = lib.mkForce 3; connect-timeout = lib.mkForce 3;
# flake-registry = pkgs.writeText "flake-registry" ''{"flakes":[],"version":2}''; flake-registry = pkgs.writeText "flake-registry" ''{"flakes":[],"version":2}'';
# experimental-features = [ experimental-features = [
# "nix-command" "nix-command"
# "flakes" "flakes"
# ]; ];
# }; };
# }; };
# testScript = '' testScript = ''
# start_all() start_all()
# machine.succeed("clan --debug --flake ${../..} flash --yes --disk main /dev/vdb test_install_machine") machine.succeed("nix-store --verify-path ${
# ''; self.clanInternals.machines.${pkgs.hostPlatform.system}.test_install_machine.config.system.build.diskoScript
# } { inherit pkgs self; }; }")
# }; machine.execute("timeout 30 clan flash --debug --flake ${../..} --yes --disk main /dev/vdb test_install_machine")
'';
} { inherit pkgs self; };
};
}; };
} }

View File

@ -2,8 +2,8 @@
{ {
clan.machines.test_install_machine = { clan.machines.test_install_machine = {
clan.networking.targetHost = "test_install_machine"; clan.networking.targetHost = "test_install_machine";
fileSystems."/".device = lib.mkDefault "/dev/null"; fileSystems."/".device = lib.mkDefault "/dev/vdb";
boot.loader.grub.device = lib.mkDefault "/dev/null"; boot.loader.grub.device = lib.mkDefault "/dev/vdb";
imports = [ self.nixosModules.test_install_machine ]; imports = [ self.nixosModules.test_install_machine ];
}; };
@ -98,7 +98,7 @@
client.succeed("${pkgs.coreutils}/bin/install -Dm 600 ${../lib/ssh/privkey} /root/.ssh/id_ed25519") client.succeed("${pkgs.coreutils}/bin/install -Dm 600 ${../lib/ssh/privkey} /root/.ssh/id_ed25519")
client.wait_until_succeeds("ssh -o StrictHostKeyChecking=accept-new -v root@target hostname") client.wait_until_succeeds("ssh -o StrictHostKeyChecking=accept-new -v root@target hostname")
client.succeed("clan --debug --flake ${../..} machines install --yes test_install_machine root@target >&2") client.succeed("clan machines install --debug --flake ${../..} --yes test_install_machine root@target >&2")
try: try:
target.shutdown() target.shutdown()
except BrokenPipeError: except BrokenPipeError:

View File

@ -46,7 +46,7 @@ sudo umount /dev/sdb1
It also includes the language and keymap currently used into the installer image. It also includes the language and keymap currently used into the installer image.
```bash ```bash
clan --flake git+https://git.clan.lol/clan/clan-core flash flash-installer --disk main /dev/sd<X> clan flash --flake git+https://git.clan.lol/clan/clan-core flash-installer --disk main /dev/sd<X>
``` ```
!!! Danger "Specifying the wrong device can lead to unrecoverable data loss." !!! Danger "Specifying the wrong device can lead to unrecoverable data loss."

View File

@ -51,19 +51,14 @@ class AppendOptionAction(argparse.Action):
lst.append(values[1]) lst.append(values[1])
def create_parser(prog: str | None = None) -> argparse.ArgumentParser: def flake_path(arg: str) -> str | Path:
parser = argparse.ArgumentParser( flake_dir = Path(arg).resolve()
prog=prog, if flake_dir.exists() and flake_dir.is_dir():
description="The clan cli tool.", return flake_dir
epilog=( return arg
"""
Online reference for the clan cli tool: https://docs.clan.lol/reference/cli/
For more detailed information, visit: https://docs.clan.lol
"""
),
formatter_class=argparse.RawTextHelpFormatter,
)
def add_common_flags(parser: argparse.ArgumentParser) -> None:
parser.add_argument( parser.add_argument(
"--debug", "--debug",
help="Enable debug logging", help="Enable debug logging",
@ -80,12 +75,6 @@ For more detailed information, visit: https://docs.clan.lol
default=[], default=[],
) )
def flake_path(arg: str) -> str | Path:
flake_dir = Path(arg).resolve()
if flake_dir.exists() and flake_dir.is_dir():
return flake_dir
return arg
parser.add_argument( parser.add_argument(
"--flake", "--flake",
help="path to the flake where the clan resides in, can be a remote flake or local, can be set through the [CLAN_DIR] environment variable", help="path to the flake where the clan resides in, can be a remote flake or local, can be set through the [CLAN_DIR] environment variable",
@ -94,6 +83,30 @@ For more detailed information, visit: https://docs.clan.lol
type=flake_path, type=flake_path,
) )
def register_common_flags(parser: argparse.ArgumentParser) -> None:
has_subparsers = False
for action in parser._actions:
if isinstance(action, argparse._SubParsersAction):
for choice, child_parser in action.choices.items():
has_subparsers = True
register_common_flags(child_parser)
if not has_subparsers:
add_common_flags(parser)
def create_parser(prog: str | None = None) -> argparse.ArgumentParser:
parser = argparse.ArgumentParser(
prog=prog,
description="The clan cli tool.",
epilog=(
"""
Online reference for the clan cli tool: https://docs.clan.lol/reference/cli/
For more detailed information, visit: https://docs.clan.lol
"""
),
formatter_class=argparse.RawTextHelpFormatter,
)
subparsers = parser.add_subparsers() subparsers = parser.add_subparsers()
parser_backups = subparsers.add_parser( parser_backups = subparsers.add_parser(
@ -208,7 +221,7 @@ For more detailed information, visit: https://docs.clan.lol/getting-started/secr
This subcommand provides an interface to facts of clan machines. This subcommand provides an interface to facts of clan machines.
Facts are artifacts that a service can generate. Facts are artifacts that a service can generate.
There are public and secret facts. There are public and secret facts.
Public facts can be referenced by other machines directly. Public facts can be referenced by other machines directly.
Public facts can include: ip addresses, public keys. Public facts can include: ip addresses, public keys.
Secret facts can include: passwords, private keys. Secret facts can include: passwords, private keys.
@ -223,7 +236,7 @@ Examples:
$ clan facts generate $ clan facts generate
Will generate facts for all machines. Will generate facts for all machines.
$ clan facts generate --service [SERVICE] --regenerate $ clan facts generate --service [SERVICE] --regenerate
Will regenerate facts, if they are already generated for a specific service. Will regenerate facts, if they are already generated for a specific service.
This is especially useful for resetting certain passwords while leaving the rest This is especially useful for resetting certain passwords while leaving the rest
@ -250,7 +263,7 @@ Examples:
List all the machines managed by clan. List all the machines managed by clan.
$ clan machines update [MACHINES] $ clan machines update [MACHINES]
Will update the specified machine [MACHINE], if [MACHINE] is omitted, the command Will update the specified machine [MACHINE], if [MACHINE] is omitted, the command
will attempt to update every configured machine. will attempt to update every configured machine.
$ clan machines install [MACHINES] [TARGET_HOST] $ clan machines install [MACHINES] [TARGET_HOST]
@ -285,6 +298,8 @@ For more detailed information, visit: https://docs.clan.lol/getting-started/depl
if argcomplete: if argcomplete:
argcomplete.autocomplete(parser) argcomplete.autocomplete(parser)
register_common_flags(parser)
return parser return parser

View File

@ -33,6 +33,8 @@ def create_backup(machine: Machine, provider: str | None = None) -> None:
def create_command(args: argparse.Namespace) -> None: def create_command(args: argparse.Namespace) -> None:
if args.flake is None:
raise ClanError("Could not find clan flake toplevel directory")
machine = Machine(name=args.machine, flake=args.flake) machine = Machine(name=args.machine, flake=args.flake)
create_backup(machine=machine, provider=args.provider) create_backup(machine=machine, provider=args.provider)

View File

@ -48,6 +48,8 @@ def list_backups(machine: Machine, provider: str | None = None) -> list[Backup]:
def list_command(args: argparse.Namespace) -> None: def list_command(args: argparse.Namespace) -> None:
if args.flake is None:
raise ClanError("Could not find clan flake toplevel directory")
machine = Machine(name=args.machine, flake=args.flake) machine = Machine(name=args.machine, flake=args.flake)
backups = list_backups(machine=machine, provider=args.provider) backups = list_backups(machine=machine, provider=args.provider)
for backup in backups: for backup in backups:

View File

@ -62,6 +62,8 @@ def restore_backup(
def restore_command(args: argparse.Namespace) -> None: def restore_command(args: argparse.Namespace) -> None:
if args.flake is None:
raise ClanError("Could not find clan flake toplevel directory")
machine = Machine(name=args.machine, flake=args.flake) machine = Machine(name=args.machine, flake=args.flake)
restore_backup( restore_backup(
machine=machine, machine=machine,

View File

@ -209,9 +209,9 @@ def generate_facts(
def generate_command(args: argparse.Namespace) -> None: def generate_command(args: argparse.Namespace) -> None:
if len(args.machines) == 0: if len(args.machines) == 0:
machines = get_all_machines(args.flake) machines = get_all_machines(args.flake, args.option)
else: else:
machines = get_selected_machines(args.flake, args.machines) machines = get_selected_machines(args.flake, args.option, args.machines)
generate_facts(machines, args.service, args.regenerate) generate_facts(machines, args.service, args.regenerate)

View File

@ -85,7 +85,9 @@ def flash_machine(
disks: dict[str, str], disks: dict[str, str],
system_config: dict[str, Any], system_config: dict[str, Any],
dry_run: bool, dry_run: bool,
write_efi_boot_entries: bool,
debug: bool, debug: bool,
extra_args: list[str] = [],
) -> None: ) -> None:
secret_facts_module = importlib.import_module(machine.secret_facts_module) secret_facts_module = importlib.import_module(machine.secret_facts_module)
secret_facts_store: SecretStoreBase = secret_facts_module.SecretStore( secret_facts_store: SecretStoreBase = secret_facts_module.SecretStore(
@ -112,6 +114,8 @@ def flash_machine(
disko_install.append("sudo") disko_install.append("sudo")
disko_install.append("disko-install") disko_install.append("disko-install")
if write_efi_boot_entries:
disko_install.append("--write-efi-boot-entries")
if dry_run: if dry_run:
disko_install.append("--dry-run") disko_install.append("--dry-run")
if debug: if debug:
@ -128,6 +132,8 @@ def flash_machine(
json.dumps(system_config), json.dumps(system_config),
] ]
) )
disko_install.extend(["--option", "dry-run", "true"])
disko_install.extend(extra_args)
cmd = nix_shell( cmd = nix_shell(
["nixpkgs#disko"], ["nixpkgs#disko"],
@ -148,6 +154,8 @@ class FlashOptions:
mode: str mode: str
language: str language: str
keymap: str keymap: str
write_efi_boot_entries: bool
nix_options: list[str]
class AppendDiskAction(argparse.Action): class AppendDiskAction(argparse.Action):
@ -178,6 +186,8 @@ def flash_command(args: argparse.Namespace) -> None:
mode=args.mode, mode=args.mode,
language=args.lang, language=args.lang,
keymap=args.keymap, keymap=args.keymap,
write_efi_boot_entries=args.write_efi_boot_entries,
nix_options=args.options,
) )
machine = Machine(opts.machine, flake=opts.flake) machine = Machine(opts.machine, flake=opts.flake)
@ -233,6 +243,8 @@ def flash_command(args: argparse.Namespace) -> None:
system_config=extra_config, system_config=extra_config,
dry_run=opts.dry_run, dry_run=opts.dry_run,
debug=opts.debug, debug=opts.debug,
write_efi_boot_entries=opts.write_efi_boot_entries,
extra_args=opts.nix_options,
) )
@ -251,12 +263,14 @@ def register_parser(parser: argparse.ArgumentParser) -> None:
help="device to flash to", help="device to flash to",
default={}, default={},
) )
mode_help = textwrap.dedent("""\ mode_help = textwrap.dedent(
"""\
Specify the mode of operation. Valid modes are: format, mount." Specify the mode of operation. Valid modes are: format, mount."
Format will format the disk before installing. Format will format the disk before installing.
Mount will mount the disk before installing. Mount will mount the disk before installing.
Mount is useful for updating an existing system without losing data. Mount is useful for updating an existing system without losing data.
""") """
)
parser.add_argument( parser.add_argument(
"--mode", "--mode",
type=str, type=str,
@ -293,4 +307,16 @@ def register_parser(parser: argparse.ArgumentParser) -> None:
default=False, default=False,
action="store_true", action="store_true",
) )
parser.add_argument(
"--write-efi-boot-entries",
help=textwrap.dedent(
"""
Write EFI boot entries to the NVRAM of the system for the installed system.
Specify this option if you plan to boot from this disk on the current machine,
but not if you plan to move the disk to another machine.
"""
).strip(),
default=False,
action="store_true",
)
parser.set_defaults(func=flash_command) parser.set_defaults(func=flash_command)

View File

@ -26,6 +26,7 @@ def install_nixos(
debug: bool = False, debug: bool = False,
password: str | None = None, password: str | None = None,
no_reboot: bool = False, no_reboot: bool = False,
extra_args: list[str] = [],
) -> None: ) -> None:
secret_facts_module = importlib.import_module(machine.secret_facts_module) secret_facts_module = importlib.import_module(machine.secret_facts_module)
log.info(f"installing {machine.name}") log.info(f"installing {machine.name}")
@ -56,6 +57,7 @@ def install_nixos(
f"{machine.flake}#{machine.name}", f"{machine.flake}#{machine.name}",
"--extra-files", "--extra-files",
str(tmpdir), str(tmpdir),
*extra_args,
] ]
if no_reboot: if no_reboot:
@ -95,6 +97,7 @@ class InstallOptions:
debug: bool debug: bool
no_reboot: bool no_reboot: bool
json_ssh_deploy: dict[str, str] | None json_ssh_deploy: dict[str, str] | None
nix_options: list[str]
def install_command(args: argparse.Namespace) -> None: def install_command(args: argparse.Namespace) -> None:
@ -127,6 +130,7 @@ def install_command(args: argparse.Namespace) -> None:
debug=args.debug, debug=args.debug,
no_reboot=args.no_reboot, no_reboot=args.no_reboot,
json_ssh_deploy=json_ssh_deploy, json_ssh_deploy=json_ssh_deploy,
nix_options=args.option,
) )
machine = Machine(opts.machine, flake=opts.flake) machine = Machine(opts.machine, flake=opts.flake)
machine.target_host_address = opts.target_host machine.target_host_address = opts.target_host
@ -142,6 +146,7 @@ def install_command(args: argparse.Namespace) -> None:
debug=opts.debug, debug=opts.debug,
password=password, password=password,
no_reboot=opts.no_reboot, no_reboot=opts.no_reboot,
extra_args=opts.nix_options,
) )

View File

@ -7,7 +7,7 @@ from .machines import Machine
# function to speedup eval if we want to evauluate all machines # function to speedup eval if we want to evauluate all machines
def get_all_machines(flake_dir: Path) -> list[Machine]: def get_all_machines(flake_dir: Path, nix_options: list[str]) -> list[Machine]:
config = nix_config() config = nix_config()
system = config["system"] system = config["system"]
json_path = run( json_path = run(
@ -19,13 +19,20 @@ def get_all_machines(flake_dir: Path) -> list[Machine]:
machines = [] machines = []
for name, machine_data in machines_json.items(): for name, machine_data in machines_json.items():
machines.append( machines.append(
Machine(name=name, flake=flake_dir, deployment_info=machine_data) Machine(
name=name,
flake=flake_dir,
deployment_info=machine_data,
nix_options=nix_options,
)
) )
return machines return machines
def get_selected_machines(flake_dir: Path, machine_names: list[str]) -> list[Machine]: def get_selected_machines(
flake_dir: Path, nix_options: list[str], machine_names: list[str]
) -> list[Machine]:
machines = [] machines = []
for name in machine_names: for name in machine_names:
machines.append(Machine(name=name, flake=flake_dir)) machines.append(Machine(name=name, flake=flake_dir, nix_options=nix_options))
return machines return machines

View File

@ -41,9 +41,10 @@ class QMPWrapper:
class Machine: class Machine:
flake: str | Path
name: str name: str
flake: str | Path
data: MachineData data: MachineData
nix_options: list[str]
eval_cache: dict[str, str] eval_cache: dict[str, str]
build_cache: dict[str, Path] build_cache: dict[str, Path]
_flake_path: Path | None _flake_path: Path | None
@ -55,6 +56,7 @@ class Machine:
name: str, name: str,
flake: Path | str, flake: Path | str,
deployment_info: dict | None = None, deployment_info: dict | None = None,
nix_options: list[str] = [],
machine: MachineData | None = None, machine: MachineData | None = None,
) -> None: ) -> None:
""" """
@ -76,6 +78,7 @@ class Machine:
self.build_cache: dict[str, Path] = {} self.build_cache: dict[str, Path] = {}
self._flake_path: Path | None = None self._flake_path: Path | None = None
self._deployment_info: None | dict = deployment_info self._deployment_info: None | dict = deployment_info
self.nix_options = nix_options
state_dir = vm_state_dir(flake_url=str(self.flake), vm_name=self.data.name) state_dir = vm_state_dir(flake_url=str(self.flake), vm_name=self.data.name)
@ -242,9 +245,9 @@ class Machine:
flake = f"path:{self.flake_dir}" flake = f"path:{self.flake_dir}"
args += [ args += [
f'{flake}#clanInternals.machines."{system}".{self.data.name}.{attr}', f'{flake}#clanInternals.machines."{system}".{self.data.name}.{attr}'
*nix_options,
] ]
args += nix_options + self.nix_options
if method == "eval": if method == "eval":
output = run_no_stdout(nix_eval(args)).stdout.strip() output = run_no_stdout(nix_eval(args)).stdout.strip()

View File

@ -110,11 +110,9 @@ def deploy_nixos(machines: MachineGroup) -> None:
ssh_arg += " -i " + host.key if host.key else "" ssh_arg += " -i " + host.key if host.key else ""
extra_args = host.meta.get("extra_args", [])
cmd = [ cmd = [
"nixos-rebuild", "nixos-rebuild",
"switch", "switch",
*extra_args,
"--fast", "--fast",
"--option", "--option",
"keep-going", "keep-going",
@ -124,6 +122,7 @@ def deploy_nixos(machines: MachineGroup) -> None:
"true", "true",
"--build-host", "--build-host",
"", "",
*machine.nix_options,
"--flake", "--flake",
f"{path}#{machine.name}", f"{path}#{machine.name}",
] ]
@ -143,7 +142,9 @@ def update(args: argparse.Namespace) -> None:
raise ClanError("Could not find clan flake toplevel directory") raise ClanError("Could not find clan flake toplevel directory")
machines = [] machines = []
if len(args.machines) == 1 and args.target_host is not None: if len(args.machines) == 1 and args.target_host is not None:
machine = Machine(name=args.machines[0], flake=args.flake) machine = Machine(
name=args.machines[0], flake=args.flake, nix_options=args.option
)
machine.target_host_address = args.target_host machine.target_host_address = args.target_host
machines.append(machine) machines.append(machine)
@ -153,7 +154,7 @@ def update(args: argparse.Namespace) -> None:
else: else:
if len(args.machines) == 0: if len(args.machines) == 0:
ignored_machines = [] ignored_machines = []
for machine in get_all_machines(args.flake): for machine in get_all_machines(args.flake, args.option):
if machine.deployment_info.get("requireExplicitUpdate", False): if machine.deployment_info.get("requireExplicitUpdate", False):
continue continue
try: try:
@ -173,7 +174,7 @@ def update(args: argparse.Namespace) -> None:
print(machine, file=sys.stderr) print(machine, file=sys.stderr)
else: else:
machines = get_selected_machines(args.flake, args.machines) machines = get_selected_machines(args.flake, args.option, args.machines)
deploy_nixos(MachineGroup(machines)) deploy_nixos(MachineGroup(machines))

View File

@ -11,10 +11,10 @@ def test_backups(
cli.run( cli.run(
[ [
"--flake",
str(test_flake_with_core.path),
"backups", "backups",
"list", "list",
"--flake",
str(test_flake_with_core.path),
"vm1", "vm1",
] ]
) )

View File

@ -39,9 +39,9 @@ def test_set_some_option(
cli = Cli() cli = Cli()
cli.run( cli.run(
[ [
"config",
"--flake", "--flake",
str(test_flake.path), str(test_flake.path),
"config",
"--quiet", "--quiet",
"--options-file", "--options-file",
example_options, example_options,
@ -64,9 +64,9 @@ def test_configure_machine(
cli.run( cli.run(
[ [
"config",
"--flake", "--flake",
str(test_flake.path), str(test_flake.path),
"config",
"-m", "-m",
"machine1", "machine1",
"clan.jitsi.enable", "clan.jitsi.enable",
@ -78,9 +78,9 @@ def test_configure_machine(
# read a option value # read a option value
cli.run( cli.run(
[ [
"config",
"--flake", "--flake",
str(test_flake.path), str(test_flake.path),
"config",
"-m", "-m",
"machine1", "machine1",
"clan.jitsi.enable", "clan.jitsi.enable",

View File

@ -15,10 +15,10 @@ def test_flakes_inspect(
cli = Cli() cli = Cli()
cli.run( cli.run(
[ [
"--flake",
str(test_flake_with_core.path),
"flakes", "flakes",
"inspect", "inspect",
"--flake",
str(test_flake_with_core.path),
"--machine", "--machine",
"vm1", "vm1",
] ]

View File

@ -21,55 +21,55 @@ def test_import_sops(
monkeypatch.setenv("SOPS_AGE_KEY", age_keys[1].privkey) monkeypatch.setenv("SOPS_AGE_KEY", age_keys[1].privkey)
cli.run( cli.run(
[ [
"--flake",
str(test_flake.path),
"secrets", "secrets",
"machines", "machines",
"add", "add",
"--flake",
str(test_flake.path),
"machine1", "machine1",
age_keys[0].pubkey, age_keys[0].pubkey,
] ]
) )
cli.run( cli.run(
[ [
"--flake",
str(test_flake.path),
"secrets", "secrets",
"users", "users",
"add", "add",
"--flake",
str(test_flake.path),
"user1", "user1",
age_keys[1].pubkey, age_keys[1].pubkey,
] ]
) )
cli.run( cli.run(
[ [
"--flake",
str(test_flake.path),
"secrets", "secrets",
"users", "users",
"add", "add",
"--flake",
str(test_flake.path),
"user2", "user2",
age_keys[2].pubkey, age_keys[2].pubkey,
] ]
) )
cli.run( cli.run(
[ [
"--flake",
str(test_flake.path),
"secrets", "secrets",
"groups", "groups",
"add-user", "add-user",
"--flake",
str(test_flake.path),
"group1", "group1",
"user1", "user1",
] ]
) )
cli.run( cli.run(
[ [
"--flake",
str(test_flake.path),
"secrets", "secrets",
"groups", "groups",
"add-user", "add-user",
"--flake",
str(test_flake.path),
"group1", "group1",
"user2", "user2",
] ]
@ -78,10 +78,10 @@ def test_import_sops(
# To edit: # To edit:
# SOPS_AGE_KEY=AGE-SECRET-KEY-1U5ENXZQAY62NC78Y2WC0SEGRRMAEEKH79EYY5TH4GPFWJKEAY0USZ6X7YQ sops --age age14tva0txcrl0zes05x7gkx56qd6wd9q3nwecjac74xxzz4l47r44sv3fz62 ./data/secrets.yaml # SOPS_AGE_KEY=AGE-SECRET-KEY-1U5ENXZQAY62NC78Y2WC0SEGRRMAEEKH79EYY5TH4GPFWJKEAY0USZ6X7YQ sops --age age14tva0txcrl0zes05x7gkx56qd6wd9q3nwecjac74xxzz4l47r44sv3fz62 ./data/secrets.yaml
cmd = [ cmd = [
"--flake",
str(test_flake.path),
"secrets", "secrets",
"import-sops", "import-sops",
"--flake",
str(test_flake.path),
"--group", "--group",
"group1", "group1",
"--machine", "--machine",
@ -91,10 +91,10 @@ def test_import_sops(
cli.run(cmd) cli.run(cmd)
capsys.readouterr() capsys.readouterr()
cli.run(["--flake", str(test_flake.path), "secrets", "users", "list"]) cli.run(["secrets", "users", "list", "--flake", str(test_flake.path)])
users = sorted(capsys.readouterr().out.rstrip().split()) users = sorted(capsys.readouterr().out.rstrip().split())
assert users == ["user1", "user2"] assert users == ["user1", "user2"]
capsys.readouterr() capsys.readouterr()
cli.run(["--flake", str(test_flake.path), "secrets", "get", "secret-key"]) cli.run(["secrets", "get", "--flake", str(test_flake.path), "secret-key"])
assert capsys.readouterr().out == "secret-value" assert capsys.readouterr().out == "secret-value"

View File

@ -9,11 +9,11 @@ def test_machine_subcommands(
) -> None: ) -> None:
cli = Cli() cli = Cli()
cli.run( cli.run(
["--flake", str(test_flake_with_core.path), "machines", "create", "machine1"] ["machines", "create", "--flake", str(test_flake_with_core.path), "machine1"]
) )
capsys.readouterr() capsys.readouterr()
cli.run(["--flake", str(test_flake_with_core.path), "machines", "list"]) cli.run(["machines", "list", "--flake", str(test_flake_with_core.path)])
out = capsys.readouterr() out = capsys.readouterr()
@ -22,11 +22,11 @@ def test_machine_subcommands(
assert "vm2" in out.out assert "vm2" in out.out
cli.run( cli.run(
["--flake", str(test_flake_with_core.path), "machines", "delete", "machine1"] ["machines", "delete", "--flake", str(test_flake_with_core.path), "machine1"]
) )
capsys.readouterr() capsys.readouterr()
cli.run(["--flake", str(test_flake_with_core.path), "machines", "list"]) cli.run(["machines", "list", "--flake", str(test_flake_with_core.path)])
out = capsys.readouterr() out = capsys.readouterr()
assert "machine1" not in out.out assert "machine1" not in out.out

View File

@ -27,11 +27,11 @@ def _test_identities(
cli.run( cli.run(
[ [
"--flake",
str(test_flake.path),
"secrets", "secrets",
what, what,
"add", "add",
"--flake",
str(test_flake.path),
"foo", "foo",
age_keys[0].pubkey, age_keys[0].pubkey,
] ]
@ -41,11 +41,11 @@ def _test_identities(
with pytest.raises(ClanError): # raises "foo already exists" with pytest.raises(ClanError): # raises "foo already exists"
cli.run( cli.run(
[ [
"--flake",
str(test_flake.path),
"secrets", "secrets",
what, what,
"add", "add",
"--flake",
str(test_flake.path),
"foo", "foo",
age_keys[0].pubkey, age_keys[0].pubkey,
] ]
@ -54,11 +54,11 @@ def _test_identities(
# rotate the key # rotate the key
cli.run( cli.run(
[ [
"--flake",
str(test_flake.path),
"secrets", "secrets",
what, what,
"add", "add",
"--flake",
str(test_flake.path),
"-f", "-f",
"foo", "foo",
age_keys[1].privkey, age_keys[1].privkey,
@ -68,11 +68,11 @@ def _test_identities(
capsys.readouterr() # empty the buffer capsys.readouterr() # empty the buffer
cli.run( cli.run(
[ [
"--flake",
str(test_flake.path),
"secrets", "secrets",
what, what,
"get", "get",
"--flake",
str(test_flake.path),
"foo", "foo",
] ]
) )
@ -80,18 +80,18 @@ def _test_identities(
assert age_keys[1].pubkey in out.out assert age_keys[1].pubkey in out.out
capsys.readouterr() # empty the buffer capsys.readouterr() # empty the buffer
cli.run(["--flake", str(test_flake.path), "secrets", what, "list"]) cli.run(["secrets", what, "list", "--flake", str(test_flake.path)])
out = capsys.readouterr() # empty the buffer out = capsys.readouterr() # empty the buffer
assert "foo" in out.out assert "foo" in out.out
cli.run(["--flake", str(test_flake.path), "secrets", what, "remove", "foo"]) cli.run(["secrets", what, "remove", "--flake", str(test_flake.path), "foo"])
assert not (sops_folder / what / "foo" / "key.json").exists() assert not (sops_folder / what / "foo" / "key.json").exists()
with pytest.raises(ClanError): # already removed with pytest.raises(ClanError): # already removed
cli.run(["--flake", str(test_flake.path), "secrets", what, "remove", "foo"]) cli.run(["secrets", what, "remove", "--flake", str(test_flake.path), "foo"])
capsys.readouterr() capsys.readouterr()
cli.run(["--flake", str(test_flake.path), "secrets", what, "list"]) cli.run(["secrets", what, "list", "--flake", str(test_flake.path)])
out = capsys.readouterr() out = capsys.readouterr()
assert "foo" not in out.out assert "foo" not in out.out
@ -113,17 +113,17 @@ def test_groups(
) -> None: ) -> None:
cli = Cli() cli = Cli()
capsys.readouterr() # empty the buffer capsys.readouterr() # empty the buffer
cli.run(["--flake", str(test_flake.path), "secrets", "groups", "list"]) cli.run(["secrets", "groups", "list", "--flake", str(test_flake.path)])
assert capsys.readouterr().out == "" assert capsys.readouterr().out == ""
with pytest.raises(ClanError): # machine does not exist yet with pytest.raises(ClanError): # machine does not exist yet
cli.run( cli.run(
[ [
"--flake",
str(test_flake.path),
"secrets", "secrets",
"groups", "groups",
"add-machine", "add-machine",
"--flake",
str(test_flake.path),
"group1", "group1",
"machine1", "machine1",
] ]
@ -131,33 +131,33 @@ def test_groups(
with pytest.raises(ClanError): # user does not exist yet with pytest.raises(ClanError): # user does not exist yet
cli.run( cli.run(
[ [
"--flake",
str(test_flake.path),
"secrets", "secrets",
"groups", "groups",
"add-user", "add-user",
"--flake",
str(test_flake.path),
"groupb1", "groupb1",
"user1", "user1",
] ]
) )
cli.run( cli.run(
[ [
"--flake",
str(test_flake.path),
"secrets", "secrets",
"machines", "machines",
"add", "add",
"--flake",
str(test_flake.path),
"machine1", "machine1",
age_keys[0].pubkey, age_keys[0].pubkey,
] ]
) )
cli.run( cli.run(
[ [
"--flake",
str(test_flake.path),
"secrets", "secrets",
"groups", "groups",
"add-machine", "add-machine",
"--flake",
str(test_flake.path),
"group1", "group1",
"machine1", "machine1",
] ]
@ -166,11 +166,11 @@ def test_groups(
# Should this fail? # Should this fail?
cli.run( cli.run(
[ [
"--flake",
str(test_flake.path),
"secrets", "secrets",
"groups", "groups",
"add-machine", "add-machine",
"--flake",
str(test_flake.path),
"group1", "group1",
"machine1", "machine1",
] ]
@ -178,51 +178,51 @@ def test_groups(
cli.run( cli.run(
[ [
"--flake",
str(test_flake.path),
"secrets", "secrets",
"users", "users",
"add", "add",
"--flake",
str(test_flake.path),
"user1", "user1",
age_keys[0].pubkey, age_keys[0].pubkey,
] ]
) )
cli.run( cli.run(
[ [
"--flake",
str(test_flake.path),
"secrets", "secrets",
"groups", "groups",
"add-user", "add-user",
"--flake",
str(test_flake.path),
"group1", "group1",
"user1", "user1",
] ]
) )
capsys.readouterr() # empty the buffer capsys.readouterr() # empty the buffer
cli.run(["--flake", str(test_flake.path), "secrets", "groups", "list"]) cli.run(["secrets", "groups", "list", "--flake", str(test_flake.path)])
out = capsys.readouterr().out out = capsys.readouterr().out
assert "user1" in out assert "user1" in out
assert "machine1" in out assert "machine1" in out
cli.run( cli.run(
[ [
"--flake",
str(test_flake.path),
"secrets", "secrets",
"groups", "groups",
"remove-user", "remove-user",
"--flake",
str(test_flake.path),
"group1", "group1",
"user1", "user1",
] ]
) )
cli.run( cli.run(
[ [
"--flake",
str(test_flake.path),
"secrets", "secrets",
"groups", "groups",
"remove-machine", "remove-machine",
"--flake",
str(test_flake.path),
"group1", "group1",
"machine1", "machine1",
] ]
@ -251,90 +251,90 @@ def test_secrets(
) -> None: ) -> None:
cli = Cli() cli = Cli()
capsys.readouterr() # empty the buffer capsys.readouterr() # empty the buffer
cli.run(["--flake", str(test_flake.path), "secrets", "list"]) cli.run(["secrets", "list", "--flake", str(test_flake.path)])
assert capsys.readouterr().out == "" assert capsys.readouterr().out == ""
monkeypatch.setenv("SOPS_NIX_SECRET", "foo") monkeypatch.setenv("SOPS_NIX_SECRET", "foo")
monkeypatch.setenv("SOPS_AGE_KEY_FILE", str(test_flake.path / ".." / "age.key")) monkeypatch.setenv("SOPS_AGE_KEY_FILE", str(test_flake.path / ".." / "age.key"))
cli.run(["--flake", str(test_flake.path), "secrets", "key", "generate"]) cli.run(["secrets", "key", "generate", "--flake", str(test_flake.path)])
capsys.readouterr() # empty the buffer capsys.readouterr() # empty the buffer
cli.run(["--flake", str(test_flake.path), "secrets", "key", "show"]) cli.run(["secrets", "key", "show", "--flake", str(test_flake.path)])
key = capsys.readouterr().out key = capsys.readouterr().out
assert key.startswith("age1") assert key.startswith("age1")
cli.run( cli.run(
["--flake", str(test_flake.path), "secrets", "users", "add", "testuser", key] ["secrets", "users", "add", "--flake", str(test_flake.path), "testuser", key]
) )
with pytest.raises(ClanError): # does not exist yet with pytest.raises(ClanError): # does not exist yet
cli.run(["--flake", str(test_flake.path), "secrets", "get", "nonexisting"]) cli.run(["secrets", "get", "--flake", str(test_flake.path), "nonexisting"])
cli.run(["--flake", str(test_flake.path), "secrets", "set", "initialkey"]) cli.run(["secrets", "set", "--flake", str(test_flake.path), "initialkey"])
capsys.readouterr() capsys.readouterr()
cli.run(["--flake", str(test_flake.path), "secrets", "get", "initialkey"]) cli.run(["secrets", "get", "--flake", str(test_flake.path), "initialkey"])
assert capsys.readouterr().out == "foo" assert capsys.readouterr().out == "foo"
capsys.readouterr() capsys.readouterr()
cli.run(["--flake", str(test_flake.path), "secrets", "users", "list"]) cli.run(["secrets", "users", "list", "--flake", str(test_flake.path)])
users = capsys.readouterr().out.rstrip().split("\n") users = capsys.readouterr().out.rstrip().split("\n")
assert len(users) == 1, f"users: {users}" assert len(users) == 1, f"users: {users}"
owner = users[0] owner = users[0]
monkeypatch.setenv("EDITOR", "cat") monkeypatch.setenv("EDITOR", "cat")
cli.run(["--flake", str(test_flake.path), "secrets", "set", "--edit", "initialkey"]) cli.run(["secrets", "set", "--edit", "--flake", str(test_flake.path), "initialkey"])
monkeypatch.delenv("EDITOR") monkeypatch.delenv("EDITOR")
cli.run(["--flake", str(test_flake.path), "secrets", "rename", "initialkey", "key"]) cli.run(["secrets", "rename", "--flake", str(test_flake.path), "initialkey", "key"])
capsys.readouterr() # empty the buffer capsys.readouterr() # empty the buffer
cli.run(["--flake", str(test_flake.path), "secrets", "list"]) cli.run(["secrets", "list", "--flake", str(test_flake.path)])
assert capsys.readouterr().out == "key\n" assert capsys.readouterr().out == "key\n"
capsys.readouterr() # empty the buffer capsys.readouterr() # empty the buffer
cli.run(["--flake", str(test_flake.path), "secrets", "list", "nonexisting"]) cli.run(["secrets", "list", "--flake", str(test_flake.path), "nonexisting"])
assert capsys.readouterr().out == "" assert capsys.readouterr().out == ""
capsys.readouterr() # empty the buffer capsys.readouterr() # empty the buffer
cli.run(["--flake", str(test_flake.path), "secrets", "list", "key"]) cli.run(["secrets", "list", "--flake", str(test_flake.path), "key"])
assert capsys.readouterr().out == "key\n" assert capsys.readouterr().out == "key\n"
cli.run( cli.run(
[ [
"--flake",
str(test_flake.path),
"secrets", "secrets",
"machines", "machines",
"add", "add",
"--flake",
str(test_flake.path),
"machine1", "machine1",
age_keys[1].pubkey, age_keys[1].pubkey,
] ]
) )
cli.run( cli.run(
[ [
"--flake",
str(test_flake.path),
"secrets", "secrets",
"machines", "machines",
"add-secret", "add-secret",
"--flake",
str(test_flake.path),
"machine1", "machine1",
"key", "key",
] ]
) )
capsys.readouterr() capsys.readouterr()
cli.run(["--flake", str(test_flake.path), "secrets", "machines", "list"]) cli.run(["secrets", "machines", "list", "--flake", str(test_flake.path)])
assert capsys.readouterr().out == "machine1\n" assert capsys.readouterr().out == "machine1\n"
with use_key(age_keys[1].privkey, monkeypatch): with use_key(age_keys[1].privkey, monkeypatch):
capsys.readouterr() capsys.readouterr()
cli.run(["--flake", str(test_flake.path), "secrets", "get", "key"]) cli.run(["secrets", "get", "--flake", str(test_flake.path), "key"])
assert capsys.readouterr().out == "foo" assert capsys.readouterr().out == "foo"
# rotate machines key # rotate machines key
cli.run( cli.run(
[ [
"--flake",
str(test_flake.path),
"secrets", "secrets",
"machines", "machines",
"add", "add",
"--flake",
str(test_flake.path),
"-f", "-f",
"machine1", "machine1",
age_keys[0].privkey, age_keys[0].privkey,
@ -344,17 +344,17 @@ def test_secrets(
# should also rotate the encrypted secret # should also rotate the encrypted secret
with use_key(age_keys[0].privkey, monkeypatch): with use_key(age_keys[0].privkey, monkeypatch):
capsys.readouterr() capsys.readouterr()
cli.run(["--flake", str(test_flake.path), "secrets", "get", "key"]) cli.run(["secrets", "get", "--flake", str(test_flake.path), "key"])
assert capsys.readouterr().out == "foo" assert capsys.readouterr().out == "foo"
cli.run( cli.run(
[ [
"--flake",
str(test_flake.path),
"secrets", "secrets",
"machines", "machines",
"remove-secret", "remove-secret",
"--flake",
str(test_flake.path),
"machine1", "machine1",
"key", "key",
] ]
@ -362,37 +362,37 @@ def test_secrets(
cli.run( cli.run(
[ [
"--flake",
str(test_flake.path),
"secrets", "secrets",
"users", "users",
"add", "add",
"--flake",
str(test_flake.path),
"user1", "user1",
age_keys[1].pubkey, age_keys[1].pubkey,
] ]
) )
cli.run( cli.run(
[ [
"--flake",
str(test_flake.path),
"secrets", "secrets",
"users", "users",
"add-secret", "add-secret",
"--flake",
str(test_flake.path),
"user1", "user1",
"key", "key",
] ]
) )
capsys.readouterr() capsys.readouterr()
with use_key(age_keys[1].privkey, monkeypatch): with use_key(age_keys[1].privkey, monkeypatch):
cli.run(["--flake", str(test_flake.path), "secrets", "get", "key"]) cli.run(["secrets", "get", "--flake", str(test_flake.path), "key"])
assert capsys.readouterr().out == "foo" assert capsys.readouterr().out == "foo"
cli.run( cli.run(
[ [
"--flake",
str(test_flake.path),
"secrets", "secrets",
"users", "users",
"remove-secret", "remove-secret",
"--flake",
str(test_flake.path),
"user1", "user1",
"key", "key",
] ]
@ -401,44 +401,44 @@ def test_secrets(
with pytest.raises(ClanError): # does not exist yet with pytest.raises(ClanError): # does not exist yet
cli.run( cli.run(
[ [
"--flake",
str(test_flake.path),
"secrets", "secrets",
"groups", "groups",
"add-secret", "add-secret",
"--flake",
str(test_flake.path),
"admin-group", "admin-group",
"key", "key",
] ]
) )
cli.run( cli.run(
[ [
"--flake",
str(test_flake.path),
"secrets", "secrets",
"groups", "groups",
"add-user", "add-user",
"--flake",
str(test_flake.path),
"admin-group", "admin-group",
"user1", "user1",
] ]
) )
cli.run( cli.run(
[ [
"--flake",
str(test_flake.path),
"secrets", "secrets",
"groups", "groups",
"add-user", "add-user",
"--flake",
str(test_flake.path),
"admin-group", "admin-group",
owner, owner,
] ]
) )
cli.run( cli.run(
[ [
"--flake",
str(test_flake.path),
"secrets", "secrets",
"groups", "groups",
"add-secret", "add-secret",
"--flake",
str(test_flake.path),
"admin-group", "admin-group",
"key", "key",
] ]
@ -447,10 +447,10 @@ def test_secrets(
capsys.readouterr() # empty the buffer capsys.readouterr() # empty the buffer
cli.run( cli.run(
[ [
"--flake",
str(test_flake.path),
"secrets", "secrets",
"set", "set",
"--flake",
str(test_flake.path),
"--group", "--group",
"admin-group", "admin-group",
"key2", "key2",
@ -459,28 +459,28 @@ def test_secrets(
with use_key(age_keys[1].privkey, monkeypatch): with use_key(age_keys[1].privkey, monkeypatch):
capsys.readouterr() capsys.readouterr()
cli.run(["--flake", str(test_flake.path), "secrets", "get", "key"]) cli.run(["secrets", "get", "--flake", str(test_flake.path), "key"])
assert capsys.readouterr().out == "foo" assert capsys.readouterr().out == "foo"
# extend group will update secrets # extend group will update secrets
cli.run( cli.run(
[ [
"--flake",
str(test_flake.path),
"secrets", "secrets",
"users", "users",
"add", "add",
"--flake",
str(test_flake.path),
"user2", "user2",
age_keys[2].pubkey, age_keys[2].pubkey,
] ]
) )
cli.run( cli.run(
[ [
"--flake",
str(test_flake.path),
"secrets", "secrets",
"groups", "groups",
"add-user", "add-user",
"--flake",
str(test_flake.path),
"admin-group", "admin-group",
"user2", "user2",
] ]
@ -488,16 +488,16 @@ def test_secrets(
with use_key(age_keys[2].privkey, monkeypatch): # user2 with use_key(age_keys[2].privkey, monkeypatch): # user2
capsys.readouterr() capsys.readouterr()
cli.run(["--flake", str(test_flake.path), "secrets", "get", "key"]) cli.run(["secrets", "get", "--flake", str(test_flake.path), "key"])
assert capsys.readouterr().out == "foo" assert capsys.readouterr().out == "foo"
cli.run( cli.run(
[ [
"--flake",
str(test_flake.path),
"secrets", "secrets",
"groups", "groups",
"remove-user", "remove-user",
"--flake",
str(test_flake.path),
"admin-group", "admin-group",
"user2", "user2",
] ]
@ -505,24 +505,24 @@ def test_secrets(
with pytest.raises(ClanError), use_key(age_keys[2].privkey, monkeypatch): with pytest.raises(ClanError), use_key(age_keys[2].privkey, monkeypatch):
# user2 is not in the group anymore # user2 is not in the group anymore
capsys.readouterr() capsys.readouterr()
cli.run(["--flake", str(test_flake.path), "secrets", "get", "key"]) cli.run(["secrets", "get", "--flake", str(test_flake.path), "key"])
print(capsys.readouterr().out) print(capsys.readouterr().out)
cli.run( cli.run(
[ [
"--flake",
str(test_flake.path),
"secrets", "secrets",
"groups", "groups",
"remove-secret", "remove-secret",
"--flake",
str(test_flake.path),
"admin-group", "admin-group",
"key", "key",
] ]
) )
cli.run(["--flake", str(test_flake.path), "secrets", "remove", "key"]) cli.run(["secrets", "remove", "--flake", str(test_flake.path), "key"])
cli.run(["--flake", str(test_flake.path), "secrets", "remove", "key2"]) cli.run(["secrets", "remove", "--flake", str(test_flake.path), "key2"])
capsys.readouterr() # empty the buffer capsys.readouterr() # empty the buffer
cli.run(["--flake", str(test_flake.path), "secrets", "list"]) cli.run(["secrets", "list", "--flake", str(test_flake.path)])
assert capsys.readouterr().out == "" assert capsys.readouterr().out == ""

View File

@ -24,27 +24,27 @@ def test_generate_secret(
cli = Cli() cli = Cli()
cli.run( cli.run(
[ [
"--flake",
str(test_flake_with_core.path),
"secrets", "secrets",
"users", "users",
"add", "add",
"--flake",
str(test_flake_with_core.path),
"user1", "user1",
age_keys[0].pubkey, age_keys[0].pubkey,
] ]
) )
cli.run( cli.run(
[ [
"--flake",
str(test_flake_with_core.path),
"secrets", "secrets",
"groups", "groups",
"add-user", "add-user",
"--flake",
str(test_flake_with_core.path),
"admins", "admins",
"user1", "user1",
] ]
) )
cmd = ["--flake", str(test_flake_with_core.path), "facts", "generate", "vm1"] cmd = ["facts", "generate", "--flake", str(test_flake_with_core.path), "vm1"]
cli.run(cmd) cli.run(cmd)
has_secret(test_flake_with_core.path, "vm1-age.key") has_secret(test_flake_with_core.path, "vm1-age.key")
has_secret(test_flake_with_core.path, "vm1-zerotier-identity-secret") has_secret(test_flake_with_core.path, "vm1-zerotier-identity-secret")
@ -60,7 +60,7 @@ def test_generate_secret(
secret1_mtime = identity_secret.lstat().st_mtime_ns secret1_mtime = identity_secret.lstat().st_mtime_ns
# test idempotency for vm1 and also generate for vm2 # test idempotency for vm1 and also generate for vm2
cli.run(["facts", "generate"]) cli.run(["facts", "generate", "--flake", str(test_flake_with_core.path)])
assert age_key.lstat().st_mtime_ns == age_key_mtime assert age_key.lstat().st_mtime_ns == age_key_mtime
assert identity_secret.lstat().st_mtime_ns == secret1_mtime assert identity_secret.lstat().st_mtime_ns == secret1_mtime

View File

@ -23,11 +23,11 @@ def test_secrets_upload(
cli = Cli() cli = Cli()
cli.run( cli.run(
[ [
"--flake",
str(test_flake_with_core.path),
"secrets", "secrets",
"users", "users",
"add", "add",
"--flake",
str(test_flake_with_core.path),
"user1", "user1",
age_keys[0].pubkey, age_keys[0].pubkey,
] ]
@ -35,18 +35,18 @@ def test_secrets_upload(
cli.run( cli.run(
[ [
"--flake",
str(test_flake_with_core.path),
"secrets", "secrets",
"machines", "machines",
"add", "add",
"--flake",
str(test_flake_with_core.path),
"vm1", "vm1",
age_keys[1].pubkey, age_keys[1].pubkey,
] ]
) )
monkeypatch.setenv("SOPS_NIX_SECRET", age_keys[0].privkey) monkeypatch.setenv("SOPS_NIX_SECRET", age_keys[0].privkey)
cli.run( cli.run(
["--flake", str(test_flake_with_core.path), "secrets", "set", "vm1-age.key"] ["secrets", "set", "--flake", str(test_flake_with_core.path), "vm1-age.key"]
) )
flake = test_flake_with_core.path.joinpath("flake.nix") flake = test_flake_with_core.path.joinpath("flake.nix")
@ -55,7 +55,7 @@ def test_secrets_upload(
new_text = flake.read_text().replace("__CLAN_TARGET_ADDRESS__", addr) new_text = flake.read_text().replace("__CLAN_TARGET_ADDRESS__", addr)
flake.write_text(new_text) flake.write_text(new_text)
cli.run(["--flake", str(test_flake_with_core.path), "facts", "upload", "vm1"]) cli.run(["facts", "upload", "--flake", str(test_flake_with_core.path), "vm1"])
# the flake defines this path as the location where the sops key should be installed # the flake defines this path as the location where the sops key should be installed
sops_key = test_flake_with_core.path.joinpath("key.txt") sops_key = test_flake_with_core.path.joinpath("key.txt")

View File

@ -86,7 +86,7 @@ def test_inspect(
test_flake_with_core: FlakeForTest, capsys: pytest.CaptureFixture test_flake_with_core: FlakeForTest, capsys: pytest.CaptureFixture
) -> None: ) -> None:
cli = Cli() cli = Cli()
cli.run(["--flake", str(test_flake_with_core.path), "vms", "inspect", "vm1"]) cli.run(["vms", "inspect", "--flake", str(test_flake_with_core.path), "vm1"])
out = capsys.readouterr() # empty the buffer out = capsys.readouterr() # empty the buffer
assert "Cores" in out.out assert "Cores" in out.out