Skip to content
This repository was archived by the owner on Mar 25, 2026. It is now read-only.

Commit a00f575

Browse files
authored
ensure docker is running (machulav#262)
1 parent d2173ed commit a00f575

File tree

3 files changed

+81
-88
lines changed

3 files changed

+81
-88
lines changed

dist/index.js

Lines changed: 36 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -145155,61 +145155,57 @@ function buildJitRunCommands(encodedJitConfig) {
145155145155
return userData;
145156145156
}
145157145157

145158-
// Build user data as a cloud-boothook (runs during cloud-init init stage,
145159-
// bypassing cloud_final_modules which may be empty on some AMIs)
145158+
// Build cloud-init YAML user data
145160145159
function buildUserDataScript(githubRegistrationToken, label, encodedJitConfig) {
145160+
// 1. Get the list of shell commands (keep your new buildRunCommands logic!)
145161145161
const runCommands = encodedJitConfig
145162145162
? buildJitRunCommands(encodedJitConfig)
145163145163
: buildRunCommands(githubRegistrationToken, label);
145164145164

145165-
const lines = [];
145165+
// 2. Start the YAML content
145166+
let yamlContent = '#cloud-config\n';
145166145167

145167-
// cloud-boothook header — processed during init stage, not final stage
145168-
lines.push('#cloud-boothook');
145169-
lines.push('#!/bin/bash');
145170-
lines.push('# Guard: only run once per boot');
145171-
lines.push('[ -f /run/runner-setup-started ] && exit 0');
145172-
lines.push('touch /run/runner-setup-started');
145173-
lines.push('');
145168+
// 3. Add packages if specified
145169+
if (config.input.packages && config.input.packages.length > 0) {
145170+
yamlContent += 'packages:\n';
145171+
config.input.packages.forEach(pkg => {
145172+
yamlContent += ` - ${pkg}\n`;
145173+
});
145174+
}
145175+
145176+
// 4. write_files section
145177+
yamlContent += 'write_files:\n';
145174145178

145175145179
// Write pre-runner script
145176-
lines.push("cat > /tmp/pre-runner-script.sh << 'PRERUNNEREOF'");
145180+
yamlContent += ' - path: /tmp/pre-runner-script.sh\n';
145181+
yamlContent += ' permissions: "0755"\n';
145182+
yamlContent += ' content: |\n';
145177145183
if (config.input.preRunnerScript) {
145178-
lines.push(config.input.preRunnerScript);
145184+
// Indent the script content for YAML
145185+
config.input.preRunnerScript.split('\n').forEach(line => {
145186+
yamlContent += ` ${line}\n`;
145187+
});
145179145188
} else {
145180-
lines.push('#!/bin/bash');
145189+
yamlContent += ' #!/bin/bash\n';
145181145190
}
145182-
lines.push('PRERUNNEREOF');
145183-
lines.push('chmod 755 /tmp/pre-runner-script.sh');
145184-
lines.push('');
145185145191

145186-
// Install packages if specified
145187-
if (config.input.packages && config.input.packages.length > 0) {
145188-
const pkgList = config.input.packages.join(' ');
145189-
lines.push(`echo "[BOOTHOOK] Installing packages: ${pkgList}"`);
145190-
lines.push(`yum install -y ${pkgList} || apt-get install -y ${pkgList} || echo "[BOOTHOOK] WARNING: package installation failed"`);
145191-
}
145192+
// Write main setup script
145193+
yamlContent += ' - path: /opt/runner-setup.sh\n';
145194+
yamlContent += ' permissions: "0755"\n';
145195+
yamlContent += ' content: |\n';
145192145196

145193-
// Write the setup script to /opt/ using heredoc (quoted delimiter = no variable expansion)
145194-
lines.push("cat > /opt/runner-setup.sh << 'RUNNERSETUPEOF'");
145195-
for (let i = 0; i < runCommands.length; i++) {
145196-
lines.push(runCommands[i]);
145197-
}
145198-
lines.push('RUNNERSETUPEOF');
145199-
lines.push('chmod 755 /opt/runner-setup.sh');
145200-
lines.push('');
145201-
145202-
// Execute setup in background so boothook returns quickly and doesn't block cloud-init
145203-
lines.push('nohup /opt/runner-setup.sh &');
145204-
145205-
const script = lines.join('\n') + '\n';
145197+
// Add each line of the command list (from buildRunCommands)
145198+
runCommands.forEach(line => {
145199+
yamlContent += ` ${line}\n`;
145200+
});
145206145201

145207-
core.info('User data script is built successfully');
145208-
if (config.input.runnerDebug) {
145209-
core.info(`User data script content:\n${script}`);
145210-
}
145202+
// 5. runcmd section - This runs AFTER Docker is up
145203+
yamlContent += 'runcmd:\n';
145204+
// We still use nohup just in case cloud-init kills the process group,
145205+
// but now the environment is fully ready.
145206+
yamlContent += ' - nohup /opt/runner-setup.sh &\n';
145211145207

145212-
return script;
145208+
return yamlContent;
145213145209
}
145214145210

145215145211
function buildMarketOptions() {

src/__tests__/jit.test.js

Lines changed: 9 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -226,19 +226,19 @@ describe('aws.js - user-data generation', () => {
226226
expect(userData).not.toContain('svc.sh');
227227
});
228228

229-
test('user-data uses cloud-boothook format with run-once guard', () => {
229+
test('user-data uses cloud-config format with write_files and runcmd', () => {
230230
const aws = loadFreshAws();
231231
const userData = aws._buildUserDataScriptForTest('regtoken123', 'testlabel', null);
232-
expect(userData).toMatch(/^#cloud-boothook\n/);
233-
expect(userData).toContain('[ -f /run/runner-setup-started ] && exit 0');
234-
expect(userData).toContain('touch /run/runner-setup-started');
232+
expect(userData).toMatch(/^#cloud-config\n/);
233+
expect(userData).toContain('write_files:');
234+
expect(userData).toContain('runcmd:');
235235
});
236236

237237
test('user-data writes setup script to /opt/ and runs with nohup', () => {
238238
const aws = loadFreshAws();
239239
const userData = aws._buildUserDataScriptForTest('regtoken123', 'testlabel', null);
240-
expect(userData).toContain("cat > /opt/runner-setup.sh << 'RUNNERSETUPEOF'");
241-
expect(userData).toContain('chmod 755 /opt/runner-setup.sh');
240+
expect(userData).toContain('path: /opt/runner-setup.sh');
241+
expect(userData).toContain('permissions: "0755"');
242242
expect(userData).toContain('nohup /opt/runner-setup.sh &');
243243
});
244244

@@ -270,8 +270,9 @@ describe('aws.js - user-data generation', () => {
270270
test('user-data installs packages when specified', () => {
271271
const aws = loadFreshAws({ 'packages': '["git", "docker.io"]' });
272272
const userData = aws._buildUserDataScriptForTest('regtoken123', 'testlabel', null);
273-
expect(userData).toContain('git docker.io');
274-
expect(userData).toContain('yum install -y');
273+
expect(userData).toContain('packages:');
274+
expect(userData).toContain(' - git');
275+
expect(userData).toContain(' - docker.io');
275276
});
276277
});
277278

src/aws.js

Lines changed: 36 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -147,61 +147,57 @@ function buildJitRunCommands(encodedJitConfig) {
147147
return userData;
148148
}
149149

150-
// Build user data as a cloud-boothook (runs during cloud-init init stage,
151-
// bypassing cloud_final_modules which may be empty on some AMIs)
150+
// Build cloud-init YAML user data
152151
function buildUserDataScript(githubRegistrationToken, label, encodedJitConfig) {
152+
// 1. Get the list of shell commands (keep your new buildRunCommands logic!)
153153
const runCommands = encodedJitConfig
154154
? buildJitRunCommands(encodedJitConfig)
155155
: buildRunCommands(githubRegistrationToken, label);
156156

157-
const lines = [];
157+
// 2. Start the YAML content
158+
let yamlContent = '#cloud-config\n';
158159

159-
// cloud-boothook header — processed during init stage, not final stage
160-
lines.push('#cloud-boothook');
161-
lines.push('#!/bin/bash');
162-
lines.push('# Guard: only run once per boot');
163-
lines.push('[ -f /run/runner-setup-started ] && exit 0');
164-
lines.push('touch /run/runner-setup-started');
165-
lines.push('');
160+
// 3. Add packages if specified
161+
if (config.input.packages && config.input.packages.length > 0) {
162+
yamlContent += 'packages:\n';
163+
config.input.packages.forEach(pkg => {
164+
yamlContent += ` - ${pkg}\n`;
165+
});
166+
}
167+
168+
// 4. write_files section
169+
yamlContent += 'write_files:\n';
166170

167171
// Write pre-runner script
168-
lines.push("cat > /tmp/pre-runner-script.sh << 'PRERUNNEREOF'");
172+
yamlContent += ' - path: /tmp/pre-runner-script.sh\n';
173+
yamlContent += ' permissions: "0755"\n';
174+
yamlContent += ' content: |\n';
169175
if (config.input.preRunnerScript) {
170-
lines.push(config.input.preRunnerScript);
176+
// Indent the script content for YAML
177+
config.input.preRunnerScript.split('\n').forEach(line => {
178+
yamlContent += ` ${line}\n`;
179+
});
171180
} else {
172-
lines.push('#!/bin/bash');
181+
yamlContent += ' #!/bin/bash\n';
173182
}
174-
lines.push('PRERUNNEREOF');
175-
lines.push('chmod 755 /tmp/pre-runner-script.sh');
176-
lines.push('');
177183

178-
// Install packages if specified
179-
if (config.input.packages && config.input.packages.length > 0) {
180-
const pkgList = config.input.packages.join(' ');
181-
lines.push(`echo "[BOOTHOOK] Installing packages: ${pkgList}"`);
182-
lines.push(`yum install -y ${pkgList} || apt-get install -y ${pkgList} || echo "[BOOTHOOK] WARNING: package installation failed"`);
183-
}
184+
// Write main setup script
185+
yamlContent += ' - path: /opt/runner-setup.sh\n';
186+
yamlContent += ' permissions: "0755"\n';
187+
yamlContent += ' content: |\n';
184188

185-
// Write the setup script to /opt/ using heredoc (quoted delimiter = no variable expansion)
186-
lines.push("cat > /opt/runner-setup.sh << 'RUNNERSETUPEOF'");
187-
for (let i = 0; i < runCommands.length; i++) {
188-
lines.push(runCommands[i]);
189-
}
190-
lines.push('RUNNERSETUPEOF');
191-
lines.push('chmod 755 /opt/runner-setup.sh');
192-
lines.push('');
193-
194-
// Execute setup in background so boothook returns quickly and doesn't block cloud-init
195-
lines.push('nohup /opt/runner-setup.sh &');
189+
// Add each line of the command list (from buildRunCommands)
190+
runCommands.forEach(line => {
191+
yamlContent += ` ${line}\n`;
192+
});
196193

197-
const script = lines.join('\n') + '\n';
198-
199-
core.info('User data script is built successfully');
200-
if (config.input.runnerDebug) {
201-
core.info(`User data script content:\n${script}`);
202-
}
194+
// 5. runcmd section - This runs AFTER Docker is up
195+
yamlContent += 'runcmd:\n';
196+
// We still use nohup just in case cloud-init kills the process group,
197+
// but now the environment is fully ready.
198+
yamlContent += ' - nohup /opt/runner-setup.sh &\n';
203199

204-
return script;
200+
return yamlContent;
205201
}
206202

207203
function buildMarketOptions() {

0 commit comments

Comments
 (0)