From 6259075f405db7bb796abb8e6e4414f9282cbeba Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kier=C3=A1n=20Meinhardt?= Date: Mon, 29 Dec 2025 13:17:42 +0100 Subject: [PATCH] try-connect: use for deploy scripts --- flake.nix | 98 ++++++++++++++++++++-------------------- packages/niveum-ssh.nix | 58 ++++++------------------ packages/try-connect.nix | 53 ++++++++++++++++++++++ 3 files changed, 115 insertions(+), 94 deletions(-) create mode 100644 packages/try-connect.nix diff --git a/flake.nix b/flake.nix index fe4f785..d468763 100644 --- a/flake.nix +++ b/flake.nix @@ -94,7 +94,10 @@ { ${localSystem} = let - pkgs = nixpkgs.legacyPackages.${localSystem}; + pkgs = import nixpkgs { + system = localSystem; + overlays = [ self.overlays.default ]; + }; lib = nixpkgs.lib; in lib.mergeAttrsList [ @@ -113,45 +116,31 @@ hostname: let machines = import lib/machines.nix; - systemAddresses = - system: - lib.optionals (system ? "internalIp") [ system.internalIp ] - ++ lib.optionals (system ? "externalIp") [ system.externalIp ] - ++ lib.optionals (system ? "retiolum") [ - system.retiolum.ipv6 - system.retiolum.ipv4 - ] - ++ lib.optionals (system ? "mycelium") [ system.mycelium.ipv6 ]; - addresses = lib.listToAttrs ( - map (name: { - inherit name; - value = systemAddresses (machines.${hostname}); - }) (builtins.attrNames self.nixosConfigurations) - ); deployScript = pkgs.writers.writeBash "deploy-${hostname}" '' - # try to connect to any of the known addresses - targets=( - ${lib.concatStringsSep " " (map (addr: "\"root@${addr}\"") addresses.${hostname})} - ) - for target in "''${targets[@]}"; do - nc -z -w 2 "$(echo $target | cut -d'@' -f2)" ${ - toString machines.${hostname}.sshPort - } && reachable_target=$target && break - done - if [ -z "$reachable_target" ]; then - echo "No reachable target found for ${hostname}" >&2 + reachable=$(${pkgs.try-connect.${hostname}}/bin/try-connect) + + if [ -z "$reachable" ]; then exit 1 fi - echo "Deploying to ${hostname} via $reachable_target" - export NIX_SSHOPTS='-p ${toString machines.${hostname}.sshPort}' + + target="root@$reachable" + echo "Deploying to ${hostname} via $target" + + # Set SSH options based on address type + if [[ "$reachable" == *.onion ]]; then + export NIX_SSHOPTS="-p ${ + toString machines.${hostname}.sshPort + } -o ProxyCommand='${pkgs.netcat}/bin/nc -x localhost:9050 %h %p' -o ControlPath=none" + else + export NIX_SSHOPTS="-p ${toString machines.${hostname}.sshPort}" + fi + ${pkgs.nixos-rebuild-ng}/bin/nixos-rebuild-ng switch \ --max-jobs 2 \ --log-format internal-json \ --flake .#${hostname} \ - --target-host "$reachable_target" \ - ${ - lib.optionalString (localSystem != machines.${hostname}.system) "--build-host $reachable_target" - } \ + --target-host "$target" \ + ${lib.optionalString (localSystem != machines.${hostname}.system) "--build-host $target"} \ |& ${pkgs.nix-output-monitor}/bin/nom --json ''; in @@ -321,6 +310,7 @@ tocharian-font = prev.callPackage packages/tocharian-font.nix { }; ttspaste = prev.callPackage packages/ttspaste.nix { }; niveum-ssh = prev.callPackage packages/niveum-ssh.nix { }; + try-connect = prev.callPackage packages/try-connect.nix {}; unicodmenu = prev.callPackage packages/unicodmenu.nix { }; vg = prev.callPackage packages/vg.nix { }; vim-kmein = prev.callPackage packages/vim-kmein { }; @@ -382,20 +372,26 @@ { ful = nixpkgs.lib.nixosSystem { system = "aarch64-linux"; - modules = profiles.default ++ profiles.server ++ [ - systems/ful/configuration.nix - self.nixosModules.panoptikon - self.nixosModules.go-webring - stockholm.nixosModules.reaktor2 - nur.modules.nixos.default - { nixpkgs.overlays = [ stockholm.overlays.default ]; } - ]; + modules = + profiles.default + ++ profiles.server + ++ [ + systems/ful/configuration.nix + self.nixosModules.panoptikon + self.nixosModules.go-webring + stockholm.nixosModules.reaktor2 + nur.modules.nixos.default + { nixpkgs.overlays = [ stockholm.overlays.default ]; } + ]; }; zaatar = nixpkgs.lib.nixosSystem { system = "x86_64-linux"; - modules = profiles.default ++ profiles.server ++ [ - systems/zaatar/configuration.nix - ]; + modules = + profiles.default + ++ profiles.server + ++ [ + systems/zaatar/configuration.nix + ]; }; kibbeh = nixpkgs.lib.nixosSystem { system = "x86_64-linux"; @@ -408,11 +404,14 @@ }; makanek = nixpkgs.lib.nixosSystem { system = "x86_64-linux"; - modules = profiles.default ++ profiles.server ++ [ - systems/makanek/configuration.nix - self.nixosModules.telegram-bot - nur.modules.nixos.default - ]; + modules = + profiles.default + ++ profiles.server + ++ [ + systems/makanek/configuration.nix + self.nixosModules.telegram-bot + nur.modules.nixos.default + ]; }; tahina = nixpkgs.lib.nixosSystem { system = "x86_64-linux"; @@ -534,6 +533,7 @@ timer tocharian-font trans + try-connect ttspaste unicodmenu untilport diff --git a/packages/niveum-ssh.nix b/packages/niveum-ssh.nix index e6425d4..d861d7a 100644 --- a/packages/niveum-ssh.nix +++ b/packages/niveum-ssh.nix @@ -4,63 +4,31 @@ lib, netcat, openssh, + try-connect, }: let inherit (lib.niveum) machines; sshableMachines = lib.filterAttrs (name: value: value ? "sshPort") machines; - systemAddresses = - system: - lib.optionals (system ? "internalIp") [ system.internalIp ] - ++ lib.optionals (system ? "externalIp") [ system.externalIp ] - ++ lib.optionals (system ? "retiolum") [ - system.retiolum.ipv6 - system.retiolum.ipv4 - ] - ++ lib.optionals (system ? "mycelium") [ system.mycelium.ipv6 ] - ++ lib.optionals (system ? "torAddress") [ system.torAddress ]; - addresses = lib.listToAttrs ( - map (name: { - inherit name; - value = systemAddresses (machines.${name}); - }) (builtins.attrNames sshableMachines) - ); in symlinkJoin { name = "niveum-ssh"; paths = lib.mapAttrsToList ( hostname: _: writers.writeBashBin "niveum-ssh-${hostname}" '' - targets=( - ${lib.concatStringsSep " " (map (addr: "\"root@${addr}\"") addresses.${hostname})} - ) + reachable=$(${try-connect.${hostname}}/bin/try-connect) - for target in "''${targets[@]}"; do - host="$(echo $target | cut -d'@' -f2)" + if [ -z "$reachable" ]; then + exit 1 + fi - # Check if it's an onion address - if [[ "$host" == *.onion ]]; then - # For onion addresses, try connecting through Tor - if ${netcat}/bin/nc -z localhost 9050 2>/dev/null; then - echo "Trying $target via Tor..." >&2 - if echo | ${netcat}/bin/nc -x localhost:9050 -w 5 "$host" ${ - toString machines.${hostname}.sshPort - } 2>/dev/null; then - exec ${openssh}/bin/ssh -p ${toString machines.${hostname}.sshPort} \ - -o ProxyCommand="${netcat}/bin/nc -x localhost:9050 %h %p" \ - "$target" "$@" - fi - fi - else - # For regular addresses, try direct connection - echo "Trying $target..." >&2 - if ${netcat}/bin/nc -z -w 2 "$host" ${toString machines.${hostname}.sshPort} 2>/dev/null; then - exec ${openssh}/bin/ssh -p ${toString machines.${hostname}.sshPort} "$target" "$@" - fi - fi - done - - echo "No reachable target found for ${hostname}" >&2 - exit 1 + if [[ "$reachable" == *.onion ]]; then + exec ${openssh}/bin/ssh -p ${toString machines.${hostname}.sshPort} \ + -o ProxyCommand="${netcat}/bin/nc -x localhost:9050 %h %p" \ + "root@$reachable" "$@" + else + exec ${openssh}/bin/ssh -p ${toString machines.${hostname}.sshPort} \ + "root@$reachable" "$@" + fi '' ) sshableMachines; } diff --git a/packages/try-connect.nix b/packages/try-connect.nix new file mode 100644 index 0000000..cca52f8 --- /dev/null +++ b/packages/try-connect.nix @@ -0,0 +1,53 @@ +{ + lib, + writers, + netcat, +}: +let + inherit (lib.niveum) machines; + sshableMachines = lib.filterAttrs (name: value: value ? "sshPort") machines; + systemAddresses = + system: + lib.optionals (system ? "internalIp") [ system.internalIp ] + ++ lib.optionals (system ? "externalIp") [ system.externalIp ] + ++ lib.optionals (system ? "retiolum") [ + system.retiolum.ipv6 + system.retiolum.ipv4 + ] + ++ lib.optionals (system ? "mycelium") [ system.mycelium.ipv6 ] + ++ lib.optionals (system ? "torAddress") [ system.torAddress ]; + addresses = lib.listToAttrs ( + map (name: { + inherit name; + value = systemAddresses (machines.${name}); + }) (builtins.attrNames sshableMachines) + ); +in +lib.mapAttrs ( + name: _: + writers.writeBashBin "try-connect" '' + port=${toString machines.${name}.sshPort} + + for addr in ${lib.concatStringsSep " " addresses.${name}}; do + # Check if it's an onion address + if [[ "$addr" == *.onion ]]; then + if ${netcat}/bin/nc -z localhost 9050 2>/dev/null; then + echo "Trying $addr via Tor..." >&2 + if echo | ${netcat}/bin/nc -z -x localhost:9050 -w 5 "$addr" "$port" 2>/dev/null; then + echo "$addr" + exit 0 + fi + fi + else + echo "Trying $addr..." >&2 + if ${netcat}/bin/nc -z -w 2 "$addr" "$port" 2>/dev/null; then + echo "$addr" + exit 0 + fi + fi + done + + echo "No reachable address found for ${name}" >&2 + exit 1 + '' +) sshableMachines