1
0
mirror of https://github.com/kmein/niveum synced 2026-03-16 10:11:08 +01:00

try-connect: use for deploy scripts

This commit is contained in:
2025-12-29 13:17:42 +01:00
parent f70383c732
commit 6259075f40
3 changed files with 115 additions and 94 deletions

View File

@@ -94,7 +94,10 @@
{ {
${localSystem} = ${localSystem} =
let let
pkgs = nixpkgs.legacyPackages.${localSystem}; pkgs = import nixpkgs {
system = localSystem;
overlays = [ self.overlays.default ];
};
lib = nixpkgs.lib; lib = nixpkgs.lib;
in in
lib.mergeAttrsList [ lib.mergeAttrsList [
@@ -113,45 +116,31 @@
hostname: hostname:
let let
machines = import lib/machines.nix; 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}" '' deployScript = pkgs.writers.writeBash "deploy-${hostname}" ''
# try to connect to any of the known addresses reachable=$(${pkgs.try-connect.${hostname}}/bin/try-connect)
targets=(
${lib.concatStringsSep " " (map (addr: "\"root@${addr}\"") addresses.${hostname})} if [ -z "$reachable" ]; then
)
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
exit 1 exit 1
fi 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 \ ${pkgs.nixos-rebuild-ng}/bin/nixos-rebuild-ng switch \
--max-jobs 2 \ --max-jobs 2 \
--log-format internal-json \ --log-format internal-json \
--flake .#${hostname} \ --flake .#${hostname} \
--target-host "$reachable_target" \ --target-host "$target" \
${ ${lib.optionalString (localSystem != machines.${hostname}.system) "--build-host $target"} \
lib.optionalString (localSystem != machines.${hostname}.system) "--build-host $reachable_target"
} \
|& ${pkgs.nix-output-monitor}/bin/nom --json |& ${pkgs.nix-output-monitor}/bin/nom --json
''; '';
in in
@@ -321,6 +310,7 @@
tocharian-font = prev.callPackage packages/tocharian-font.nix { }; tocharian-font = prev.callPackage packages/tocharian-font.nix { };
ttspaste = prev.callPackage packages/ttspaste.nix { }; ttspaste = prev.callPackage packages/ttspaste.nix { };
niveum-ssh = prev.callPackage packages/niveum-ssh.nix { }; niveum-ssh = prev.callPackage packages/niveum-ssh.nix { };
try-connect = prev.callPackage packages/try-connect.nix {};
unicodmenu = prev.callPackage packages/unicodmenu.nix { }; unicodmenu = prev.callPackage packages/unicodmenu.nix { };
vg = prev.callPackage packages/vg.nix { }; vg = prev.callPackage packages/vg.nix { };
vim-kmein = prev.callPackage packages/vim-kmein { }; vim-kmein = prev.callPackage packages/vim-kmein { };
@@ -382,7 +372,10 @@
{ {
ful = nixpkgs.lib.nixosSystem { ful = nixpkgs.lib.nixosSystem {
system = "aarch64-linux"; system = "aarch64-linux";
modules = profiles.default ++ profiles.server ++ [ modules =
profiles.default
++ profiles.server
++ [
systems/ful/configuration.nix systems/ful/configuration.nix
self.nixosModules.panoptikon self.nixosModules.panoptikon
self.nixosModules.go-webring self.nixosModules.go-webring
@@ -393,7 +386,10 @@
}; };
zaatar = nixpkgs.lib.nixosSystem { zaatar = nixpkgs.lib.nixosSystem {
system = "x86_64-linux"; system = "x86_64-linux";
modules = profiles.default ++ profiles.server ++ [ modules =
profiles.default
++ profiles.server
++ [
systems/zaatar/configuration.nix systems/zaatar/configuration.nix
]; ];
}; };
@@ -408,7 +404,10 @@
}; };
makanek = nixpkgs.lib.nixosSystem { makanek = nixpkgs.lib.nixosSystem {
system = "x86_64-linux"; system = "x86_64-linux";
modules = profiles.default ++ profiles.server ++ [ modules =
profiles.default
++ profiles.server
++ [
systems/makanek/configuration.nix systems/makanek/configuration.nix
self.nixosModules.telegram-bot self.nixosModules.telegram-bot
nur.modules.nixos.default nur.modules.nixos.default
@@ -534,6 +533,7 @@
timer timer
tocharian-font tocharian-font
trans trans
try-connect
ttspaste ttspaste
unicodmenu unicodmenu
untilport untilport

View File

@@ -4,63 +4,31 @@
lib, lib,
netcat, netcat,
openssh, openssh,
try-connect,
}: }:
let let
inherit (lib.niveum) machines; inherit (lib.niveum) machines;
sshableMachines = lib.filterAttrs (name: value: value ? "sshPort") 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 in
symlinkJoin { symlinkJoin {
name = "niveum-ssh"; name = "niveum-ssh";
paths = lib.mapAttrsToList ( paths = lib.mapAttrsToList (
hostname: _: hostname: _:
writers.writeBashBin "niveum-ssh-${hostname}" '' writers.writeBashBin "niveum-ssh-${hostname}" ''
targets=( reachable=$(${try-connect.${hostname}}/bin/try-connect)
${lib.concatStringsSep " " (map (addr: "\"root@${addr}\"") addresses.${hostname})}
)
for target in "''${targets[@]}"; do if [ -z "$reachable" ]; then
host="$(echo $target | cut -d'@' -f2)" exit 1
fi
# Check if it's an onion address if [[ "$reachable" == *.onion ]]; then
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} \ exec ${openssh}/bin/ssh -p ${toString machines.${hostname}.sshPort} \
-o ProxyCommand="${netcat}/bin/nc -x localhost:9050 %h %p" \ -o ProxyCommand="${netcat}/bin/nc -x localhost:9050 %h %p" \
"$target" "$@" "root@$reachable" "$@"
fi
fi
else else
# For regular addresses, try direct connection exec ${openssh}/bin/ssh -p ${toString machines.${hostname}.sshPort} \
echo "Trying $target..." >&2 "root@$reachable" "$@"
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
fi
done
echo "No reachable target found for ${hostname}" >&2
exit 1
'' ''
) sshableMachines; ) sshableMachines;
} }

53
packages/try-connect.nix Normal file
View File

@@ -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