From 93cdbaac573472cf1a145e96d6b5ff82c0960c64 Mon Sep 17 00:00:00 2001 From: Gmer4Lfe Date: Sun, 16 Aug 2026 20:16:17 -0400 Subject: [PATCH] Give the mirror the terminal step its half of phase 1 actually needs, instead of a button that cannot answer a password prompt --- Partnership/partnership_onboard.sh | 15 ++++++ Plugin/unraid/include/partnership.php | 13 +++-- Plugin/unraid/pages/partnership.php | 72 +++++++++++++++++++++++---- 3 files changed, 86 insertions(+), 14 deletions(-) diff --git a/Partnership/partnership_onboard.sh b/Partnership/partnership_onboard.sh index 1f2e949..8f2d7cb 100755 --- a/Partnership/partnership_onboard.sh +++ b/Partnership/partnership_onboard.sh @@ -194,6 +194,7 @@ SKIP_WEBHOOK_SETUP=false SKIP_MEDIA_SEED=false SKIP_WEBHOOK_LISTENER=false PHASE1_ONLY=false # OWNER: SSH + conf push only (HOST2 not yet installed) + # MIRROR: SSH key install only, no owner notification PHASE2_ONLY=false # OWNER: containers/arr/onboard only (triggered by HOST2 after it onboards) SKIP_ARM=false # leave the sync gates as they are — see Step 9e FILTERED_ARGS=() @@ -342,6 +343,20 @@ if [[ "$AM_MIRROR" == true ]]; then exit 1 fi + # Stop after the key when asked. ssh_setup.sh runs ssh-copy-id, which prompts for the + # owner's root password on a first install — answerable in a terminal, never from the + # WebGUI button, which is why the mirror's panel sends the operator to a terminal for + # exactly this step and nothing more. The flag was parsed but only ever honoured on the + # owner path, so a mirror asked for phase 1 silently ran the whole thing. + if [[ "$PHASE1_ONLY" == true ]]; then + echo "" + echo "━━━━━ $ICON_SUMMARY MIRROR PHASE 1 COMPLETE ━━━━━" + echo " SSH key: ready" + echo " Next: press ▶ Onboard on the Partnership tab to notify $OWNER" + echo "━━━━━━━━━━━━━━━━━━━━━━━" + exit 0 + fi + echo "" echo "━━━ Step 2/2 — Notify Owner to Run Phase 2 ━━━" echo "" diff --git a/Plugin/unraid/include/partnership.php b/Plugin/unraid/include/partnership.php index c6776bf..e08f104 100644 --- a/Plugin/unraid/include/partnership.php +++ b/Plugin/unraid/include/partnership.php @@ -283,11 +283,16 @@ function vv_pt_nodes(): array { ? vv_pt_local_system() : ($ts['online'] && $ts['ip'] && $mySshKey ? vv_pt_remote_system($ts['ip'], $mySshKey) : []); - // Onboard phase from setup.db — null=self, 0=not started, 1=SSH+conf done, 2=fully onboarded + // Onboard phase from setup.db — 0=not started, 1=SSH+conf done, 2=fully onboarded. + // + // Computed for self as well as for partners. The flags are keyed to the host they + // describe, so on the mirror HOST2_PHASE*_DONE is the mirror's own progress — and the + // mirror's action panel needs it to know whether its SSH key step is still outstanding. + // This was forced to null for self, which left a mirror with no way to see its own + // phase and no way to render anything but a bare button. $nodeIdUpper = strtoupper($slot); - $onboardPhase = $isMe ? null - : (($setupDb[$nodeIdUpper . '_PHASE2_DONE'] ?? '') === 'true' ? 2 - : (($setupDb[$nodeIdUpper . '_PHASE1_DONE'] ?? '') === 'true' ? 1 : 0)); + $onboardPhase = ($setupDb[$nodeIdUpper . '_PHASE2_DONE'] ?? '') === 'true' ? 2 + : (($setupDb[$nodeIdUpper . '_PHASE1_DONE'] ?? '') === 'true' ? 1 : 0); // key_ready: local key generated but not yet installed on HOST2 (SSH pending manual step) $keyReady = !$isMe && ($setupDb[$nodeIdUpper . '_KEY_READY'] ?? '') === 'true'; // For self: local setup complete flag (set by partnership_manager --onboard --local-only) diff --git a/Plugin/unraid/pages/partnership.php b/Plugin/unraid/pages/partnership.php index f822db5..beba33e 100644 --- a/Plugin/unraid/pages/partnership.php +++ b/Plugin/unraid/pages/partnership.php @@ -1169,18 +1169,70 @@ function _renderActions(nodes, cfg) { } // ── Mirror onboard (non-owner) ───────────────────────────────────────────── + // + // The mirror's half of phase 1 is ssh_setup.sh doing ssh-copy-id *to the owner*, which + // prompts for the owner's root password on a first install. A WebGUI button cannot answer a + // password prompt, so until the key exists the only honest control here is the same + // terminal + copy-command pair the owner's phase 0 panel has always had. The bare button + // was the sole affordance on this side, which meant the mirror was offered the one route + // that structurally cannot work — it failed on ssh-copy-id every time. + // + // Once the key is in, the button is exactly right, and it becomes the whole panel. if (!isOwner) { - html += `
-
-
-
Join partnership
-
SSH key setup + notify owner
+ const ownerNode = remotes.find(n => n.is_owner) || remotes[0]; + const ownerName = ownerNode?.hostname || 'the owner'; + const myPhase = selfNode?.onboard_phase ?? 0; + + if (myPhase >= 1) { + html += `
+
+
+
Join partnership
+
SSH key ready · notifies ${vvEscHtml(ownerName)} to run Phase 2
+
+
- -
-
`; +
`; + } else { + html += `
+
+
+
+ Step 1 + Install SSH key on ${vvEscHtml(ownerName)} +
+
+ Open Terminal + ${termCmd} +
+
Enter ${vvEscHtml(ownerName)} root password when prompted · a button cannot answer that prompt
+
+
+
+
+
+ Step 2 + Join partnership +
+
Notifies ${vvEscHtml(ownerName)} to run Phase 2 · if key already installed
+
+ +
+
+
+
`; + } } // ── Offboard + Transfer ────────────────────────────────────────────────────