From 584299e199f9870eb7ed1a574e1a397e1719bcc8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=B6rg=20Thalheim?= Date: Fri, 2 Feb 2024 11:32:48 +0700 Subject: [PATCH] rename deployment address to target address This is a prepares having a build server for deployment --- checks/backups/flake-module.nix | 1 + checks/installation/flake-module.nix | 1 + docs/admins/machines.md | 9 ++--- nixosModules/clanCore/networking.nix | 21 ++++++++++-- nixosModules/clanCore/outputs.nix | 14 +++++--- pkgs/clan-cli/clan_cli/machines/install.py | 7 +--- pkgs/clan-cli/clan_cli/machines/machines.py | 34 ++++++++++--------- pkgs/clan-cli/clan_cli/machines/update.py | 4 +-- pkgs/clan-cli/tests/machines/vm1/default.nix | 2 +- .../machines/vm_with_secrets/default.nix | 2 +- .../machines/vm_without_secrets/default.nix | 2 +- .../tests/test_flake_with_core/flake.nix | 4 +-- .../test_flake_with_core_and_pass/flake.nix | 2 +- .../tests/test_secrets_password_store.py | 2 +- pkgs/clan-cli/tests/test_secrets_upload.py | 2 +- pkgs/clan-cli/tests/test_vms_cli.py | 5 ++- 16 files changed, 69 insertions(+), 43 deletions(-) diff --git a/checks/backups/flake-module.nix b/checks/backups/flake-module.nix index e453ec1e7..5f958f698 100644 --- a/checks/backups/flake-module.nix +++ b/checks/backups/flake-module.nix @@ -5,6 +5,7 @@ let directory = ../..; machines = { test_backup_client = { + clan.networking.targetHost = "client"; imports = [ self.nixosModules.test_backup_client ]; fileSystems."/".device = "/dev/null"; boot.loader.grub.device = "/dev/null"; diff --git a/checks/installation/flake-module.nix b/checks/installation/flake-module.nix index dc4721248..8fca0a464 100644 --- a/checks/installation/flake-module.nix +++ b/checks/installation/flake-module.nix @@ -5,6 +5,7 @@ let directory = ../..; machines = { test_install_machine = { + clan.networking.targetHost = "test_install_machine"; imports = [ self.nixosModules.test_install_machine ]; }; }; diff --git a/docs/admins/machines.md b/docs/admins/machines.md index 61b9b4b57..004d7efd2 100644 --- a/docs/admins/machines.md +++ b/docs/admins/machines.md @@ -88,17 +88,18 @@ $ clan machines install my-machine ## Update Your Machines -Clan CLI enables you to remotely update your machines over SSH. This requires setting up a deployment address for each target machine. +Clan CLI enables you to remotely update your machines over SSH. This requires setting up a target address for each target machine. -### Setting the Deployment Address +### Setting the Target Host Replace `host_or_ip` with the actual hostname or IP address of your target machine: ```shellSession -$ clan config --machine my-machine clan.networking.deploymentAddress root@host_or_ip +$ clan config --machine my-machine clan.networking.targetHost root@host_or_ip ``` -_Note: The use of `root@` in the deployment address implies SSH access as the root user. Ensure that the root login is secured and only used when necessary._ +_Note: The use of `root@` in the target address implies SSH access as the root user. +Ensure that the root login is secured and only used when necessary._ ### Updating Machine Configurations diff --git a/nixosModules/clanCore/networking.nix b/nixosModules/clanCore/networking.nix index d2c5dacbc..8dc826169 100644 --- a/nixosModules/clanCore/networking.nix +++ b/nixosModules/clanCore/networking.nix @@ -1,7 +1,7 @@ { config, lib, ... }: { options.clan.networking = { - deploymentAddress = lib.mkOption { + targetHost = lib.mkOption { description = '' The target SSH node for deployment. @@ -14,10 +14,27 @@ - user@machine2.example.com - root@example.com:2222&IdentityFile=/path/to/private/key ''; + type = lib.types.str; + }; + buildHost = lib.mkOption { + description = '' + The build SSH node where nixos-rebuild will be executed. + + If set to null, the targetHost will be used. + + format: user@host:port&SSH_OPTION=SSH_VALUE + examples: + - machine.example.com + - user@machine2.example.com + - root@example.com:2222&IdentityFile=/path/to/private/key + ''; type = lib.types.nullOr lib.types.str; - default = "root@${config.networking.hostName}"; + default = null; }; }; + imports = [ + (lib.mkRenamedOptionModule [ "clan" "networking" "deploymentAddress" ] [ "clan" "networking" "buildHost" ]) + ]; config = { # conflicts with systemd-resolved networking.useHostResolvConf = false; diff --git a/nixosModules/clanCore/outputs.nix b/nixosModules/clanCore/outputs.nix index fb8fc5d8e..d5f39bf92 100644 --- a/nixosModules/clanCore/outputs.nix +++ b/nixosModules/clanCore/outputs.nix @@ -19,10 +19,16 @@ the location of the deployment.json file ''; }; - deploymentAddress = lib.mkOption { + deployment.buildHost = lib.mkOption { type = lib.types.str; description = '' - the address of the deployment server + the hostname of the build host where nixos-rebuild is run + ''; + }; + deployment.targetHost = lib.mkOption { + type = lib.types.str; + description = '' + the hostname of the target host to be deployed to ''; }; secretsUploadDirectory = lib.mkOption { @@ -66,10 +72,10 @@ config = { system.clan.deployment.data = { inherit (config.system.clan) secretsModule secretsData; - inherit (config.clan.networking) deploymentAddress; + inherit (config.clan.networking) targetHost buildHost; inherit (config.clanCore) secretsUploadDirectory; }; system.clan.deployment.file = pkgs.writeText "deployment.json" (builtins.toJSON config.system.clan.deployment.data); - }; + }; } diff --git a/pkgs/clan-cli/clan_cli/machines/install.py b/pkgs/clan-cli/clan_cli/machines/install.py index 925252e72..2d00a1d4c 100644 --- a/pkgs/clan-cli/clan_cli/machines/install.py +++ b/pkgs/clan-cli/clan_cli/machines/install.py @@ -14,14 +14,12 @@ log = logging.getLogger(__name__) def install_nixos(machine: Machine, kexec: str | None = None) -> None: - log.info(f"deployment address1: {machine.deployment_info['deploymentAddress']}") secrets_module = importlib.import_module(machine.secrets_module) log.info(f"installing {machine.name}") log.info(f"using secret store: {secrets_module.SecretStore}") secret_store = secrets_module.SecretStore(machine=machine) h = machine.host - log.info(f"deployment address2: {machine.deployment_info['deploymentAddress']}") target_host = f"{h.user or 'root'}@{h.host}" log.info(f"target host: {target_host}") @@ -77,10 +75,7 @@ def install_command(args: argparse.Namespace) -> None: kexec=args.kexec, ) machine = Machine(opts.machine, flake=opts.flake) - machine.get_deployment_info() - machine.deployment_info["deploymentAddress"] = opts.target_host - log.info(f"target host: {opts.target_host}") - log.info(f"deployment address: {machine.deployment_info['deploymentAddress']}") + machine.target_host = opts.target_host install_nixos(machine, kexec=opts.kexec) diff --git a/pkgs/clan-cli/clan_cli/machines/machines.py b/pkgs/clan-cli/clan_cli/machines/machines.py index aa7f30538..6c85770bb 100644 --- a/pkgs/clan-cli/clan_cli/machines/machines.py +++ b/pkgs/clan-cli/clan_cli/machines/machines.py @@ -28,8 +28,7 @@ class Machine: self.eval_cache: dict[str, str] = {} self.build_cache: dict[str, Path] = {} - if deployment_info is not None: - self.deployment_info = deployment_info + self._deployment_info: None | dict[str, str] = deployment_info def __str__(self) -> str: return f"Machine(name={self.name}, flake={self.flake})" @@ -37,29 +36,34 @@ class Machine: def __repr__(self) -> str: return str(self) - def get_deployment_info(self) -> None: - self.deployment_info = json.loads( + @property + def deployment_info(self) -> dict[str, str]: + if self._deployment_info is not None: + return self._deployment_info + self._deployment_info = json.loads( self.build_nix("config.system.clan.deployment.file").read_text() ) print(f"self_deployment_info: {self.deployment_info}") + return self._deployment_info @property - def deployment_address(self) -> str: - if not hasattr(self, "deployment_info"): - self.get_deployment_info() - return self.deployment_info["deploymentAddress"] + def target_host(self) -> str: + # deploymentAddress is deprecated. + return ( + self.deployment_info.get("targetHost") + or self.deployment_info["deploymentAddress"] + ) + + @target_host.setter + def target_host(self, value: str) -> None: + self.deployment_info["targetHost"] = value @property def secrets_module(self) -> str: - if not hasattr(self, "deployment_info"): - self.get_deployment_info() - print(f"self_deployment_info2: {self.deployment_info}") return self.deployment_info["secretsModule"] @property def secrets_data(self) -> dict: - if not hasattr(self, "deployment_info"): - self.get_deployment_info() if self.deployment_info["secretsData"]: try: return json.loads(Path(self.deployment_info["secretsData"]).read_text()) @@ -72,8 +76,6 @@ class Machine: @property def secrets_upload_directory(self) -> str: - if not hasattr(self, "deployment_info"): - self.get_deployment_info() return self.deployment_info["secretsUploadDirectory"] @property @@ -90,7 +92,7 @@ class Machine: @property def host(self) -> Host: return parse_deployment_address( - self.name, self.deployment_address, meta={"machine": self} + self.name, self.target_host, meta={"machine": self} ) def eval_nix(self, attr: str, refresh: bool = False) -> str: diff --git a/pkgs/clan-cli/clan_cli/machines/update.py b/pkgs/clan-cli/clan_cli/machines/update.py index b12410271..49a0ff239 100644 --- a/pkgs/clan-cli/clan_cli/machines/update.py +++ b/pkgs/clan-cli/clan_cli/machines/update.py @@ -91,7 +91,7 @@ def get_all_machines(clan_dir: Path) -> HostGroup: # very hacky. would be better to do a MachinesGroup instead host = parse_deployment_address( name, - machine_data["deploymentAddress"], + machine_data.get("targetHost") or machine_data.get("deploymentAddress"), meta={ "machine": Machine( name=name, flake=clan_dir, deployment_info=machine_data @@ -116,7 +116,7 @@ def update(args: argparse.Namespace) -> None: raise ClanError("Could not find clan flake toplevel directory") if len(args.machines) == 1 and args.target_host is not None: machine = Machine(name=args.machines[0], flake=args.flake) - machine.deployment_info["deploymentAddress"] = args.target_host + machine.target_host = args.target_host host = parse_deployment_address( args.machines[0], args.target_host, diff --git a/pkgs/clan-cli/tests/machines/vm1/default.nix b/pkgs/clan-cli/tests/machines/vm1/default.nix index c6c1ee586..8ae4d04fb 100644 --- a/pkgs/clan-cli/tests/machines/vm1/default.nix +++ b/pkgs/clan-cli/tests/machines/vm1/default.nix @@ -1,5 +1,5 @@ { lib, ... }: { - clan.networking.deploymentAddress = "__CLAN_DEPLOYMENT_ADDRESS__"; + clan.networking.targetHost = "__CLAN_TARGET_ADDRESS__"; system.stateVersion = lib.version; sops.age.keyFile = "__CLAN_SOPS_KEY_PATH__"; clanCore.secretsUploadDirectory = "__CLAN_SOPS_KEY_DIR__"; diff --git a/pkgs/clan-cli/tests/machines/vm_with_secrets/default.nix b/pkgs/clan-cli/tests/machines/vm_with_secrets/default.nix index c6c1ee586..8ae4d04fb 100644 --- a/pkgs/clan-cli/tests/machines/vm_with_secrets/default.nix +++ b/pkgs/clan-cli/tests/machines/vm_with_secrets/default.nix @@ -1,5 +1,5 @@ { lib, ... }: { - clan.networking.deploymentAddress = "__CLAN_DEPLOYMENT_ADDRESS__"; + clan.networking.targetHost = "__CLAN_TARGET_ADDRESS__"; system.stateVersion = lib.version; sops.age.keyFile = "__CLAN_SOPS_KEY_PATH__"; clanCore.secretsUploadDirectory = "__CLAN_SOPS_KEY_DIR__"; diff --git a/pkgs/clan-cli/tests/machines/vm_without_secrets/default.nix b/pkgs/clan-cli/tests/machines/vm_without_secrets/default.nix index 96d980d34..db5b9eed3 100644 --- a/pkgs/clan-cli/tests/machines/vm_without_secrets/default.nix +++ b/pkgs/clan-cli/tests/machines/vm_without_secrets/default.nix @@ -1,5 +1,5 @@ { lib, ... }: { - clan.networking.deploymentAddress = "__CLAN_DEPLOYMENT_ADDRESS__"; + clan.networking.targetHost = "__CLAN_TARGET_ADDRESS__"; system.stateVersion = lib.version; clan.virtualisation.graphics = false; diff --git a/pkgs/clan-cli/tests/test_flake_with_core/flake.nix b/pkgs/clan-cli/tests/test_flake_with_core/flake.nix index a501c8975..631b5ae6e 100644 --- a/pkgs/clan-cli/tests/test_flake_with_core/flake.nix +++ b/pkgs/clan-cli/tests/test_flake_with_core/flake.nix @@ -12,7 +12,7 @@ clanName = "test_flake_with_core"; machines = { vm1 = { lib, ... }: { - clan.networking.deploymentAddress = "__CLAN_DEPLOYMENT_ADDRESS__"; + clan.networking.targetHost = "__CLAN_TARGET_ADDRESS__"; system.stateVersion = lib.version; sops.age.keyFile = "__CLAN_SOPS_KEY_PATH__"; clanCore.secretsUploadDirectory = "__CLAN_SOPS_KEY_DIR__"; @@ -32,7 +32,7 @@ }; }; vm2 = { lib, ... }: { - clan.networking.deploymentAddress = "__CLAN_DEPLOYMENT_ADDRESS__"; + clan.networking.targetHost = "__CLAN_TARGET_ADDRESS__"; system.stateVersion = lib.version; sops.age.keyFile = "__CLAN_SOPS_KEY_PATH__"; clanCore.secretsUploadDirectory = "__CLAN_SOPS_KEY_DIR__"; diff --git a/pkgs/clan-cli/tests/test_flake_with_core_and_pass/flake.nix b/pkgs/clan-cli/tests/test_flake_with_core_and_pass/flake.nix index 0714d2dfe..a7187d540 100644 --- a/pkgs/clan-cli/tests/test_flake_with_core_and_pass/flake.nix +++ b/pkgs/clan-cli/tests/test_flake_with_core_and_pass/flake.nix @@ -12,7 +12,7 @@ clanName = "test_flake_with_core_and_pass"; machines = { vm1 = { lib, ... }: { - clan.networking.deploymentAddress = "__CLAN_DEPLOYMENT_ADDRESS__"; + clan.networking.targetHost = "__CLAN_TARGET_ADDRESS__"; system.stateVersion = lib.version; clanCore.secretStore = "password-store"; clanCore.secretsUploadDirectory = lib.mkForce "__CLAN_SOPS_KEY_DIR__/secrets"; diff --git a/pkgs/clan-cli/tests/test_secrets_password_store.py b/pkgs/clan-cli/tests/test_secrets_password_store.py index ac9fc49ad..379fbc3f2 100644 --- a/pkgs/clan-cli/tests/test_secrets_password_store.py +++ b/pkgs/clan-cli/tests/test_secrets_password_store.py @@ -60,7 +60,7 @@ def test_upload_secret( flake = test_flake_with_core_and_pass.path.joinpath("flake.nix") host = host_group.hosts[0] addr = f"{host.user}@{host.host}:{host.port}?StrictHostKeyChecking=no&UserKnownHostsFile=/dev/null&IdentityFile={host.key}" - new_text = flake.read_text().replace("__CLAN_DEPLOYMENT_ADDRESS__", addr) + new_text = flake.read_text().replace("__CLAN_TARGET_ADDRESS__", addr) flake.write_text(new_text) cli.run(["secrets", "upload", "vm1"]) zerotier_identity_secret = ( diff --git a/pkgs/clan-cli/tests/test_secrets_upload.py b/pkgs/clan-cli/tests/test_secrets_upload.py index 18a6c51df..3593990ef 100644 --- a/pkgs/clan-cli/tests/test_secrets_upload.py +++ b/pkgs/clan-cli/tests/test_secrets_upload.py @@ -52,7 +52,7 @@ def test_secrets_upload( flake = test_flake_with_core.path.joinpath("flake.nix") host = host_group.hosts[0] addr = f"{host.user}@{host.host}:{host.port}?StrictHostKeyChecking=no&UserKnownHostsFile=/dev/null&IdentityFile={host.key}" - new_text = flake.read_text().replace("__CLAN_DEPLOYMENT_ADDRESS__", addr) + new_text = flake.read_text().replace("__CLAN_TARGET_ADDRESS__", addr) flake.write_text(new_text) cli.run(["--flake", str(test_flake_with_core.path), "secrets", "upload", "vm1"]) diff --git a/pkgs/clan-cli/tests/test_vms_cli.py b/pkgs/clan-cli/tests/test_vms_cli.py index 5e2d75b01..74e3c21f7 100644 --- a/pkgs/clan-cli/tests/test_vms_cli.py +++ b/pkgs/clan-cli/tests/test_vms_cli.py @@ -154,7 +154,10 @@ def test_vm_persistence( ), ) ), - clan=dict(virtualisation=dict(graphics=False)), + clan=dict( + virtualisation=dict(graphics=False), + networking=dict(targetHost="client"), + ), ) ), )