fix(v2): critical bug fixes — root SSH, bootstrap wait, SG deletion order, PAT masking
- EC2 bootstrap now enables root SSH (copies authorized_keys to root, sets PermitRootLogin without-password, reloads sshd) so all commands run as root and NVM at /root/.nvm is accessible - Added /var/lib/pp-bootstrap-done sentinel; deploy waits for it before running any user commands — prevents race between SSH availability and user-data completion (docker/nvm install can take 3-5+ min) - Fixed stopPreview: terminate instance first, delete key pair next, then delete security group with 30s delay — SG deletion was previously attempted before termination causing it to fail - Fixed redeploy to always fetch fresh instanceIp/sshPrivateKey from DB rather than using potentially-stale preview parameter - Fixed .env writing to use base64 encoding via echo|base64-d to safely handle values with special characters, single quotes, and newlines - PAT and git clone URL now masked in preview logs (shows **** for password) - Fixed inactivity cron: removed dead inactivityMs variable, use join on repoConfig to avoid N+1, deduplicate pending INACTIVITY_STOP jobs - Fixed IAM policy UI: ec2:CreateKeyPair (backend uses CreateKeyPair, not ImportKeyPair which is a different AWS operation) - Admin panel: added Edit button with username/password form for users - Privacy page: fetch and display admin contactEmail from settings - pnpm-workspace.yaml: fix allowBuilds→onlyBuiltDependencies for pnpm 9 Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -60,7 +60,7 @@ function tryConnect(host: string, privateKey: string, timeoutMs: number): Promis
|
||||
conn.connect({
|
||||
host,
|
||||
port: 22,
|
||||
username: "ubuntu",
|
||||
username: "root",
|
||||
privateKey,
|
||||
readyTimeout: timeoutMs,
|
||||
algorithms: {
|
||||
@@ -85,6 +85,16 @@ function execOnConn(conn: Client, command: string): Promise<{ stdout: string; st
|
||||
});
|
||||
}
|
||||
|
||||
export async function waitForBootstrap(session: SshSession, maxWaitMs = 600_000): Promise<void> {
|
||||
const start = Date.now();
|
||||
while (Date.now() - start < maxWaitMs) {
|
||||
const res = await session.exec("test -f /var/lib/pp-bootstrap-done && echo done || echo waiting");
|
||||
if (res.stdout.trim() === "done") return;
|
||||
await sleep(10_000);
|
||||
}
|
||||
throw new Error("EC2 bootstrap did not complete within timeout");
|
||||
}
|
||||
|
||||
function sleep(ms: number) {
|
||||
return new Promise(r => setTimeout(r, ms));
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user