From 8d29d0e69c4f3cd93ee2ca69d2d2d971ddb150b3 Mon Sep 17 00:00:00 2001 From: lassulus Date: Thu, 14 Sep 2023 16:57:38 +0200 Subject: [PATCH] clan-cli: get deploymentAddress from clan.networking --- nixosModules/clanCore/flake-module.nix | 1 + nixosModules/clanCore/networking.nix | 15 +++++++ pkgs/clan-cli/clan_cli/machines/update.py | 51 ++++++++++++++++------- pkgs/clan-cli/clan_cli/secrets/upload.py | 24 +++++++---- 4 files changed, 68 insertions(+), 23 deletions(-) create mode 100644 nixosModules/clanCore/networking.nix diff --git a/nixosModules/clanCore/flake-module.nix b/nixosModules/clanCore/flake-module.nix index da174ff..868a523 100644 --- a/nixosModules/clanCore/flake-module.nix +++ b/nixosModules/clanCore/flake-module.nix @@ -3,6 +3,7 @@ imports = [ ./secrets ./zerotier.nix + ./networking.nix inputs.sops-nix.nixosModules.sops # just some example options. Can be removed later ./bloatware diff --git a/nixosModules/clanCore/networking.nix b/nixosModules/clanCore/networking.nix new file mode 100644 index 0000000..813939d --- /dev/null +++ b/nixosModules/clanCore/networking.nix @@ -0,0 +1,15 @@ +{ config, lib, ... }: +{ + options.clan.networking = { + deploymentAddress = lib.mkOption { + description = '' + The target SSH node for deployment. + + By default, the node's attribute name will be used. + If set to null, only local deployment will be supported. + ''; + type = lib.types.nullOr lib.types.str; + default = "root@${config.networking.hostName}"; + }; + }; +} diff --git a/pkgs/clan-cli/clan_cli/machines/update.py b/pkgs/clan-cli/clan_cli/machines/update.py index 30726b6..963b0a1 100644 --- a/pkgs/clan-cli/clan_cli/machines/update.py +++ b/pkgs/clan-cli/clan_cli/machines/update.py @@ -2,10 +2,13 @@ import argparse import json import os import subprocess +from typing import Optional -from ..ssh import Host, HostGroup, HostKeyCheck -from ..secrets.upload import upload_secrets +from ..dirs import get_clan_flake_toplevel +from ..nix import nix_eval from ..secrets.generate import generate_secrets +from ..secrets.upload import upload_secrets +from ..ssh import Host, HostGroup, HostKeyCheck def deploy_nixos(hosts: HostGroup) -> None: @@ -22,7 +25,7 @@ def deploy_nixos(hosts: HostGroup) -> None: ["nix", "flake", "archive", "--to", f"ssh://{target}", "--json"], check=True, stdout=subprocess.PIPE, - extra_env=env + extra_env=env, ) data = json.loads(res.stdout) path = data["path"] @@ -75,20 +78,36 @@ def deploy_nixos(hosts: HostGroup) -> None: # FIXME: we want some kind of inventory here. def update(args: argparse.Namespace) -> None: - meta = {} - if args.flake_uri: - meta["flake_uri"] = args.flake_uri - if args.flake_attr: - meta["flake_attr"] = args.flake_attr - deploy_nixos(HostGroup([Host(args.host, user=args.user, meta=meta)])) + clan_dir = get_clan_flake_toplevel().as_posix() + host = json.loads( + subprocess.run( + nix_eval( + [ + f'{clan_dir}#nixosConfigurations."{args.machine}".config.clan.networking.deploymentAddress' + ] + ), + stdout=subprocess.PIPE, + check=True, + text=True, + ).stdout + ) + parts = host.split("@") + user: Optional[str] = None + if len(parts) > 1: + user = parts[0] + hostname = parts[1] + else: + hostname = parts[0] + maybe_port = hostname.split(":") + port = None + if len(maybe_port) > 1: + hostname = maybe_port[0] + port = int(maybe_port[1]) + print(f"deploying {host}") + deploy_nixos(HostGroup([Host(host=hostname, port=port, user=user)])) def register_update_parser(parser: argparse.ArgumentParser) -> None: - # TODO pass all args we don't parse into ssh_args, currently it fails if arg starts with - - parser.add_argument("--flake-uri", type=str, default=".#", help="nix flake uri") - parser.add_argument( - "--flake-attr", type=str, help="nixos configuration in the flake" - ) - parser.add_argument("--user", type=str, default="root") - parser.add_argument("host", type=str) + parser.add_argument("--target-host", type=str, default="root") + parser.add_argument("machine", type=str) parser.set_defaults(func=update) diff --git a/pkgs/clan-cli/clan_cli/secrets/upload.py b/pkgs/clan-cli/clan_cli/secrets/upload.py index 8dc4afe..38a27b9 100644 --- a/pkgs/clan-cli/clan_cli/secrets/upload.py +++ b/pkgs/clan-cli/clan_cli/secrets/upload.py @@ -1,11 +1,11 @@ import argparse +import json import subprocess -import sys from clan_cli.errors import ClanError from ..dirs import get_clan_flake_toplevel -from ..nix import nix_build +from ..nix import nix_build, nix_eval def upload_secrets(machine: str) -> None: @@ -17,18 +17,28 @@ def upload_secrets(machine: str) -> None: f'{clan_dir}#nixosConfigurations."{machine}".config.system.clan.uploadSecrets' ] ), - capture_output=True, + stdout=subprocess.PIPE, text=True, + check=True, + ) + host = json.loads( + subprocess.run( + nix_eval( + [ + f'{clan_dir}#nixosConfigurations."{machine}".config.clan.networking.deploymentAddress' + ] + ), + stdout=subprocess.PIPE, + text=True, + check=True, + ).stdout ) - if proc.returncode != 0: - print(proc.stderr, file=sys.stderr) - raise ClanError(f"failed to upload secrets:\n{proc.stderr}") secret_upload_script = proc.stdout.strip() secret_upload = subprocess.run( [ secret_upload_script, - f"root@{machine}", + host, ], )