@@ -42,11 +42,19 @@ func BuildBootstrapJob(instance *paperclipv1alpha1.Instance) *batchv1.Job {
4242 // 1. Wait for the server to accept connections
4343 // 2. Run bootstrap-ceo to get the invite token
4444 // 3. Call the sign-up API with the token and admin credentials
45+ svcURL := fmt .Sprintf ("http://%s.%s.svc.cluster.local:%d" , svcName , instance .Namespace , port )
46+
47+ // Follow the same flow as Paperclip's docker-onboard-smoke.sh:
48+ // 1. Wait for server
49+ // 2. Sign up admin user (creates account without admin role)
50+ // 3. Generate bootstrap invite via CLI
51+ // 4. Accept the invite with the authenticated session (promotes to admin/CEO)
4552 script := fmt .Sprintf (`
4653set -e
4754
4855SERVER_URL="%s"
49- SVC_URL="http://%s.%s.svc.cluster.local:%d"
56+ SVC_URL="%s"
57+ COOKIE_JAR=$(mktemp /tmp/cookies.XXXXXX)
5058
5159echo "Waiting for Paperclip server..."
5260for i in $(seq 1 60); do
@@ -59,39 +67,75 @@ for i in $(seq 1 60); do
5967 sleep 5
6068done
6169
62- echo "Running bootstrap-ceo..."
70+ # Step 1: Sign up the admin user (or sign in if already exists)
71+ echo "Creating admin account..."
72+ SIGNUP_STATUS=$(curl -sS -o /tmp/signup.json -w '%%{http_code}' \
73+ -c "$COOKIE_JAR" -b "$COOKIE_JAR" \
74+ -H "Content-Type: application/json" \
75+ -H "Origin: $SERVER_URL" \
76+ -X POST "$SVC_URL/api/auth/sign-up/email" \
77+ -d "{\"name\":\"%s\",\"email\":\"$ADMIN_EMAIL\",\"password\":\"$ADMIN_PASSWORD\"}") || true
78+
79+ if echo "$SIGNUP_STATUS" | grep -q '^2'; then
80+ echo "Admin account created."
81+ else
82+ echo "Sign-up returned HTTP $SIGNUP_STATUS, trying sign-in..."
83+ SIGNIN_STATUS=$(curl -sS -o /tmp/signin.json -w '%%{http_code}' \
84+ -c "$COOKIE_JAR" -b "$COOKIE_JAR" \
85+ -H "Content-Type: application/json" \
86+ -H "Origin: $SERVER_URL" \
87+ -X POST "$SVC_URL/api/auth/sign-in/email" \
88+ -d "{\"email\":\"$ADMIN_EMAIL\",\"password\":\"$ADMIN_PASSWORD\"}") || true
89+ if echo "$SIGNIN_STATUS" | grep -q '^2'; then
90+ echo "Signed in as existing admin."
91+ else
92+ echo "Could not sign up or sign in. Sign-up: $(cat /tmp/signup.json 2>/dev/null), Sign-in: $(cat /tmp/signin.json 2>/dev/null)"
93+ exit 1
94+ fi
95+ fi
96+
97+ # Step 2: Check if instance is already bootstrapped
98+ HEALTH=$(curl -sS -c "$COOKIE_JAR" -b "$COOKIE_JAR" "$SVC_URL/api/health" 2>/dev/null) || true
99+ if echo "$HEALTH" | grep -q '"bootstrapStatus":"ready"'; then
100+ echo "Instance already bootstrapped. Nothing to do."
101+ rm -f "$COOKIE_JAR"
102+ exit 0
103+ fi
104+
105+ # Step 3: Generate bootstrap invite
106+ echo "Generating bootstrap invite..."
63107BOOTSTRAP_OUTPUT=$(pnpm paperclipai auth bootstrap-ceo --base-url "$SERVER_URL" 2>&1) || true
64108echo "$BOOTSTRAP_OUTPUT"
65109
66- # Extract the invite token from the output
67110INVITE_TOKEN=$(echo "$BOOTSTRAP_OUTPUT" | grep -o 'pcp_bootstrap_[a-f0-9]*' | head -1)
68-
69111if [ -z "$INVITE_TOKEN" ]; then
70- if echo "$BOOTSTRAP_OUTPUT" | grep -qi "already exists\|already been"; then
71- echo "Admin user already exists. Nothing to do."
72- exit 0
73- fi
74112 echo "Could not extract invite token."
113+ rm -f "$COOKIE_JAR"
75114 exit 1
76115fi
77116
78- echo "Creating admin user with invite token..."
79- RESPONSE=$(curl -s -X POST "$SERVER_URL/api/auth/sign-up/email" \
117+ # Step 4: Accept the invite with the authenticated session
118+ echo "Accepting bootstrap invite..."
119+ ACCEPT_STATUS=$(curl -sS -o /tmp/accept.json -w '%%{http_code}' \
120+ -c "$COOKIE_JAR" -b "$COOKIE_JAR" \
80121 -H "Content-Type: application/json" \
81- -d "{\"email\":\"$ADMIN_EMAIL\",\"password\":\"$ADMIN_PASSWORD\",\"name\":\"%s\",\"inviteToken\":\"$INVITE_TOKEN\"}") || true
122+ -H "Origin: $SERVER_URL" \
123+ -X POST "$SVC_URL/api/invites/$INVITE_TOKEN/accept" \
124+ -d '{"requestType":"human"}') || true
82125
83- if echo "$RESPONSE" | grep -q '"user"'; then
84- echo "Admin user created successfully."
85- elif echo "$RESPONSE" | grep -qi "already exists\|duplicate"; then
86- echo "Admin user already exists."
87- exit 0
126+ if echo "$ACCEPT_STATUS" | grep -q '^2'; then
127+ echo "Bootstrap complete. Admin user promoted to CEO."
88128else
89- echo "Sign-up response: $RESPONSE"
129+ echo "Invite acceptance returned HTTP $ACCEPT_STATUS: $(cat /tmp/accept.json 2>/dev/null)"
130+ rm -f "$COOKIE_JAR"
90131 exit 1
91132fi
133+
134+ rm -f "$COOKIE_JAR"
135+ echo "Admin bootstrap finished successfully."
92136` ,
93137 baseURL ,
94- svcName , instance . Namespace , port ,
138+ svcURL ,
95139 adminName ,
96140 )
97141
0 commit comments