From 510ba707adc1b2a43ea3ee283727d90a38457f2c Mon Sep 17 00:00:00 2001 From: MichaelFisher1997 Date: Sat, 28 Feb 2026 12:09:40 +0000 Subject: [PATCH 1/2] fix: stabilize tailscale enrollment without cloud-init rollback Create /etc/tailscale before writing runtime key, add progress logging and unbuffered output in enroll script, and shorten guest-agent wait to fail faster when enrollment cannot run. --- .gitea/workflows/terraform-apply.yml | 11 +++++++++-- nixos/template-base/configuration.nix | 3 +++ 2 files changed, 12 insertions(+), 2 deletions(-) diff --git a/.gitea/workflows/terraform-apply.yml b/.gitea/workflows/terraform-apply.yml index 2fef320..5e0b392 100644 --- a/.gitea/workflows/terraform-apply.yml +++ b/.gitea/workflows/terraform-apply.yml @@ -144,15 +144,21 @@ jobs: payload = resp.read().decode("utf-8") return json.loads(payload) - def wait_for_guest_agent(vmid, timeout_seconds=900): + def wait_for_guest_agent(vmid, timeout_seconds=300): deadline = time.time() + timeout_seconds + tries = 0 while time.time() < deadline: + tries += 1 try: res = api_request("GET", f"/api2/json/nodes/{target_node}/qemu/{vmid}/agent/ping") if res.get("data") == "pong": + print(f"Guest agent ready for vmid {vmid}", flush=True) return True except Exception: pass + if tries % 6 == 0: + remaining = int(deadline - time.time()) + print(f"Waiting for guest agent on vmid {vmid} ({remaining}s left)", flush=True) time.sleep(5) return False @@ -193,6 +199,7 @@ jobs: safe_hostname = hostname.replace("'", "'\"'\"'") cmd = ( "set -e; " + "install -d -m 700 /etc/tailscale; " f"printf '%s' '{safe_key}' > /etc/tailscale/authkey; " f"printf '%s' '{safe_hostname}' > /etc/tailscale/hostname; " "chmod 600 /etc/tailscale/authkey; " @@ -227,4 +234,4 @@ jobs: print("\nTailscale enrollment completed for all managed VMs") PY - python3 enroll_tailscale.py + python3 -u enroll_tailscale.py diff --git a/nixos/template-base/configuration.nix b/nixos/template-base/configuration.nix index 781adc7..3ec6384 100644 --- a/nixos/template-base/configuration.nix +++ b/nixos/template-base/configuration.nix @@ -49,6 +49,8 @@ RemainAfterExit = true; }; script = '' + install -d -m 0700 /etc/tailscale + if [ ! -s /etc/tailscale/authkey ]; then exit 0 fi @@ -59,6 +61,7 @@ ts_hostname="--hostname=$(cat /etc/tailscale/hostname)" fi + install -d -m 0700 /var/lib/tailscale rm -f /var/lib/tailscale/tailscaled.state ${pkgs.tailscale}/bin/tailscale up --reset --auth-key="$key" $ts_hostname From 6fada2f32a5b00cd0d0b88d7451c570554d570f4 Mon Sep 17 00:00:00 2001 From: MichaelFisher1997 Date: Sat, 28 Feb 2026 12:12:58 +0000 Subject: [PATCH 2/2] refactor: use direct tailscale auth-key enrollment Stop writing auth keys to guest files and enroll nodes by running tailscale up directly via Proxmox guest agent with VM-name hostnames. --- .gitea/workflows/terraform-apply.yml | 10 ++++----- nixos/template-base/configuration.nix | 31 --------------------------- 2 files changed, 4 insertions(+), 37 deletions(-) diff --git a/.gitea/workflows/terraform-apply.yml b/.gitea/workflows/terraform-apply.yml index 5e0b392..dbd7c00 100644 --- a/.gitea/workflows/terraform-apply.yml +++ b/.gitea/workflows/terraform-apply.yml @@ -199,14 +199,12 @@ jobs: safe_hostname = hostname.replace("'", "'\"'\"'") cmd = ( "set -e; " - "install -d -m 700 /etc/tailscale; " - f"printf '%s' '{safe_key}' > /etc/tailscale/authkey; " - f"printf '%s' '{safe_hostname}' > /etc/tailscale/hostname; " - "chmod 600 /etc/tailscale/authkey; " f"hostnamectl set-hostname '{safe_hostname}' || true; " + "install -d -m 700 /var/lib/tailscale; " + "rm -f /var/lib/tailscale/tailscaled.state; " "systemctl restart tailscaled; " - "systemctl start tailscale-firstboot.service; " - "tailscale status || true" + f"/run/current-system/sw/bin/tailscale up --reset --auth-key='{safe_key}' --hostname='{safe_hostname}'; " + "/run/current-system/sw/bin/tailscale status || true" ) exitcode, stdout, stderr = exec_guest(vmid, cmd) diff --git a/nixos/template-base/configuration.nix b/nixos/template-base/configuration.nix index 3ec6384..7475bc4 100644 --- a/nixos/template-base/configuration.nix +++ b/nixos/template-base/configuration.nix @@ -39,37 +39,6 @@ security.sudo.wheelNeedsPassword = false; - systemd.services.tailscale-firstboot = { - description = "One-time Tailscale enrollment"; - after = [ "network-online.target" "tailscaled.service" ]; - wants = [ "network-online.target" "tailscaled.service" ]; - wantedBy = [ "multi-user.target" ]; - serviceConfig = { - Type = "oneshot"; - RemainAfterExit = true; - }; - script = '' - install -d -m 0700 /etc/tailscale - - if [ ! -s /etc/tailscale/authkey ]; then - exit 0 - fi - - key="$(cat /etc/tailscale/authkey)" - ts_hostname="" - if [ -s /etc/tailscale/hostname ]; then - ts_hostname="--hostname=$(cat /etc/tailscale/hostname)" - fi - - install -d -m 0700 /var/lib/tailscale - rm -f /var/lib/tailscale/tailscaled.state - ${pkgs.tailscale}/bin/tailscale up --reset --auth-key="$key" $ts_hostname - - rm -f /etc/tailscale/authkey - rm -f /etc/tailscale/hostname - ''; - }; - environment.systemPackages = with pkgs; [ btop curl