feat(v2): full spec implementation — root SSH, bootstrap sentinel, HMAC webhook, all parametric routes fixed #1
@@ -227,7 +227,7 @@ async function firstDeploy(
|
||||
|
||||
checkAbort(previewId);
|
||||
|
||||
// Connect as root. Ubuntu user-data copies authorized_keys to root and enables root SSH.
|
||||
// Ubuntu cloud images support command execution through their provisioned user.
|
||||
const sshSession = await connectSsh(instanceIp, privateKey, 300_000);
|
||||
activeSshSessions.set(previewId, sshSession);
|
||||
|
||||
@@ -239,7 +239,7 @@ async function firstDeploy(
|
||||
await appendLog(previewId, `[PP] Bootstrap complete. Starting setup...\n`);
|
||||
|
||||
if (repoConfig.aptPackages.length > 0) {
|
||||
await runSshStep(previewId, sshSession, `DEBIAN_FRONTEND=noninteractive apt-get install -y ${repoConfig.aptPackages.join(" ")}`);
|
||||
await runSshStep(previewId, sshSession, `sudo DEBIAN_FRONTEND=noninteractive apt-get install -y ${repoConfig.aptPackages.join(" ")}`);
|
||||
}
|
||||
|
||||
const giteaPat = user.giteaPAT ? decrypt(user.giteaPAT) : "";
|
||||
@@ -344,7 +344,7 @@ async function redeploy(
|
||||
}
|
||||
}
|
||||
|
||||
const NVM_PREFIX = `export NVM_DIR="/root/.nvm"; source "$NVM_DIR/nvm.sh" 2>/dev/null;`;
|
||||
const NVM_PREFIX = `export NVM_DIR="$HOME/.nvm"; source "$NVM_DIR/nvm.sh" 2>/dev/null;`;
|
||||
|
||||
function withNvm(cmd: string): string {
|
||||
return `bash -c '${NVM_PREFIX} ${cmd.replace(/'/g, `'"'"'`)}'`;
|
||||
|
||||
@@ -127,26 +127,13 @@ systemctl enable docker
|
||||
systemctl start docker
|
||||
apt-get install -y docker-compose-plugin
|
||||
|
||||
# NVM + Node LTS (installed as root, available to root SSH sessions)
|
||||
export HOME=/root
|
||||
curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.39.7/install.sh | bash
|
||||
export NVM_DIR="/root/.nvm"
|
||||
source "$NVM_DIR/nvm.sh"
|
||||
nvm install --lts
|
||||
nvm alias default lts/*
|
||||
# PP deploys as the image's supported SSH user. Give it Docker access and its
|
||||
# own Node runtime rather than attempting to override Ubuntu's root SSH policy.
|
||||
usermod -aG docker ubuntu
|
||||
sudo -u ubuntu -H bash -lc 'curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.39.7/install.sh | bash'
|
||||
sudo -u ubuntu -H bash -lc 'export NVM_DIR="$HOME/.nvm"; source "$NVM_DIR/nvm.sh"; nvm install --lts; nvm alias default lts/*'
|
||||
|
||||
# Do not permit PP's root SSH session until every bootstrap step succeeded.
|
||||
# That prevents PP from seeing SSH as ready while cloud-init is still mutating
|
||||
# the host and turns the completion marker into a reliable readiness signal.
|
||||
touch /var/lib/pp-bootstrap-done
|
||||
sed -i 's/^#*PermitRootLogin.*/PermitRootLogin without-password/' /etc/ssh/sshd_config
|
||||
mkdir -p /root/.ssh
|
||||
chmod 700 /root/.ssh
|
||||
if [ -f /home/ubuntu/.ssh/authorized_keys ]; then
|
||||
cp /home/ubuntu/.ssh/authorized_keys /root/.ssh/authorized_keys
|
||||
chmod 600 /root/.ssh/authorized_keys
|
||||
fi
|
||||
systemctl reload sshd || service ssh reload
|
||||
`;
|
||||
|
||||
export async function launchInstance(opts: {
|
||||
|
||||
@@ -60,7 +60,7 @@ function tryConnect(host: string, privateKey: string, timeoutMs: number): Promis
|
||||
conn.connect({
|
||||
host,
|
||||
port: 22,
|
||||
username: "root",
|
||||
username: "ubuntu",
|
||||
privateKey,
|
||||
readyTimeout: timeoutMs,
|
||||
keepaliveInterval: 10000,
|
||||
|
||||
Reference in New Issue
Block a user