Give the mirror the terminal step its half of phase 1 actually needs, instead of a button that cannot answer a password prompt
This commit is contained in:
@@ -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)
|
||||
|
||||
@@ -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 += `<div style="padding:10px 12px;background:#0d0d0d;border:1px solid #1e1e1e;border-radius:4px;">
|
||||
<div style="display:flex;align-items:center;justify-content:space-between;gap:10px;">
|
||||
<div>
|
||||
<div style="font-size:11px;color:#888;margin-bottom:2px;">Join partnership</div>
|
||||
<div style="font-size:9px;color:#333;">SSH key setup + notify owner</div>
|
||||
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 += `<div style="padding:10px 12px;background:#0d0d0d;border:1px solid #1e1e1e;border-radius:4px;">
|
||||
<div style="display:flex;align-items:center;justify-content:space-between;gap:10px;">
|
||||
<div>
|
||||
<div style="font-size:11px;color:#888;margin-bottom:2px;">Join partnership</div>
|
||||
<div style="font-size:9px;color:#333;">SSH key ready · notifies ${vvEscHtml(ownerName)} to run Phase 2</div>
|
||||
</div>
|
||||
<button class="vv-pt-action-btn run" onclick="vvPtOnboard(this)"
|
||||
${!hasPartner ? 'disabled style="opacity:.35;cursor:default;"' : ''}
|
||||
style="font-size:11px;white-space:nowrap;">▶ Onboard</button>
|
||||
</div>
|
||||
<button class="vv-pt-action-btn run" onclick="vvPtOnboard(this)"
|
||||
${!hasPartner ? 'disabled style="opacity:.35;cursor:default;"' : ''}
|
||||
style="font-size:11px;white-space:nowrap;">▶ Onboard</button>
|
||||
</div>
|
||||
</div>`;
|
||||
</div>`;
|
||||
} else {
|
||||
html += `<div style="padding:10px 12px;background:#0d0d0d;border:1px solid #1e3a5a;border-radius:4px;">
|
||||
<div style="display:flex;flex-direction:column;gap:10px;">
|
||||
<div>
|
||||
<div style="display:flex;align-items:center;gap:6px;margin-bottom:6px;">
|
||||
<span style="font-size:9px;font-weight:700;color:#4a9eff;background:#0a1828;
|
||||
padding:2px 8px;border-radius:10px;border:1px solid #1a3a5a;">Step 1</span>
|
||||
<span style="font-size:11px;color:#888;">Install SSH key on ${vvEscHtml(ownerName)}</span>
|
||||
</div>
|
||||
<div style="display:flex;align-items:center;gap:8px;flex-wrap:wrap;margin-bottom:4px;">
|
||||
<a href="${termBase}" target="_blank" class="localURL"
|
||||
style="padding:3px 10px;background:#0e1a2a;color:#7ab;border:1px solid #1e3a5a;
|
||||
border-radius:3px;text-decoration:none;font-size:10px;white-space:nowrap;">Open Terminal</a>
|
||||
<code onclick="navigator.clipboard.writeText('${termCmd}').then(()=>{this.style.color='#4caf50';setTimeout(()=>this.style.color='#444',1500)})"
|
||||
style="font-size:9px;color:#444;background:#080808;padding:3px 8px;border-radius:3px;
|
||||
border:1px solid #181818;flex:1;min-width:0;overflow:hidden;text-overflow:ellipsis;
|
||||
white-space:nowrap;cursor:pointer;" title="Click to copy">${termCmd}</code>
|
||||
</div>
|
||||
<div style="font-size:9px;color:#2a2a2a;">Enter ${vvEscHtml(ownerName)} root password when prompted · a button cannot answer that prompt</div>
|
||||
</div>
|
||||
<div style="border-top:1px solid #1a1a1a;padding-top:10px;">
|
||||
<div style="display:flex;align-items:center;justify-content:space-between;gap:10px;">
|
||||
<div>
|
||||
<div style="display:flex;align-items:center;gap:6px;margin-bottom:2px;">
|
||||
<span style="font-size:9px;font-weight:700;color:#4caf50;background:#0a1a0a;
|
||||
padding:2px 8px;border-radius:10px;border:1px solid #1a3a1a;">Step 2</span>
|
||||
<span style="font-size:11px;color:#888;">Join partnership</span>
|
||||
</div>
|
||||
<div style="font-size:9px;color:#333;">Notifies ${vvEscHtml(ownerName)} to run Phase 2 · if key already installed</div>
|
||||
</div>
|
||||
<button class="vv-pt-action-btn run" onclick="vvPtOnboard(this)"
|
||||
${!hasPartner ? 'disabled style="opacity:.35;cursor:default;"' : ''}
|
||||
style="font-size:11px;white-space:nowrap;">▶ Onboard</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>`;
|
||||
}
|
||||
}
|
||||
|
||||
// ── Offboard + Transfer ────────────────────────────────────────────────────
|
||||
|
||||
Reference in New Issue
Block a user