diff --git a/action.yml b/action.yml index ea032bbd..d251568b 100644 --- a/action.yml +++ b/action.yml @@ -86,7 +86,14 @@ inputs: startup-timeout-seconds: description: >- Specifies the timeout in seconds to register the runner after the quiet period. + run-runner-as-service: + type: boolean + description: >- + Start the runner as a service rather than using ./run.sh as root. required: false + run-runner-as-user: + description: >- + Specify user under whom the runner service should run outputs: label: description: >- diff --git a/dist/index.js b/dist/index.js index a60ce0aa..3a53f8b0 100644 --- a/dist/index.js +++ b/dist/index.js @@ -145013,21 +145013,23 @@ const config = __nccwpck_require__(4570); // User data scripts are run as the root user function buildUserDataScript(githubRegistrationToken, label) { + let userData; if (config.input.runnerHomeDir) { // If runner home directory is specified, we expect the actions-runner software (and dependencies) // to be pre-installed in the AMI, so we simply cd into that directory and then start the runner - return [ + userData = [ '#!/bin/bash', + 'exec > >(tee /var/log/user-data.log|logger -t user-data -s 2>/dev/console) 2>&1', `cd "${config.input.runnerHomeDir}"`, `echo "${config.input.preRunnerScript}" > pre-runner-script.sh`, 'source pre-runner-script.sh', 'export RUNNER_ALLOW_RUNASROOT=1', `./config.sh --url https://github.com/${config.githubContext.owner}/${config.githubContext.repo} --token ${githubRegistrationToken} --labels ${label}`, - './run.sh', ]; } else { - return [ + userData = [ '#!/bin/bash', + 'exec > >(tee /var/log/user-data.log|logger -t user-data -s 2>/dev/console) 2>&1', 'mkdir actions-runner && cd actions-runner', `echo "${config.input.preRunnerScript}" > pre-runner-script.sh`, 'source pre-runner-script.sh', @@ -145036,9 +145038,18 @@ function buildUserDataScript(githubRegistrationToken, label) { 'tar xzf ./actions-runner-linux-${RUNNER_ARCH}-2.313.0.tar.gz', 'export RUNNER_ALLOW_RUNASROOT=1', `./config.sh --url https://github.com/${config.githubContext.owner}/${config.githubContext.repo} --token ${githubRegistrationToken} --labels ${label}`, - './run.sh', ]; } + if (config.input.runAsUser) { + userData.push(`chown -R ${config.input.runAsUser} .`); + } + if (config.input.runAsService) { + userData.push(`./svc.sh install ${config.input.runAsUser || ''}`); + userData.push('./svc.sh start'); + } else { + userData.push(`${config.input.runAsUser ? `su ${config.input.runAsUser} -c` : ''} ./run.sh`); + } + return userData; } function buildMarketOptions() { @@ -145160,6 +145171,8 @@ class Config { startupRetryIntervalSeconds: core.getInput('startup-retry-interval-seconds'), startupTimeoutMinutes: core.getInput('startup-timeout-minutes'), subnetId: core.getInput('subnet-id'), + runAsService: core.getInput('run-runner-as-service') === 'true', + runAsUser: core.getInput('run-runner-as-user') }; const tags = JSON.parse(core.getInput('aws-resource-tags')); diff --git a/package.json b/package.json index e560f3bd..382c351e 100644 --- a/package.json +++ b/package.json @@ -27,4 +27,4 @@ "dotenv": "^8.6.0", "eslint": "^7.32.0" } -} +} \ No newline at end of file diff --git a/src/aws.js b/src/aws.js index ac83394a..82375921 100644 --- a/src/aws.js +++ b/src/aws.js @@ -5,21 +5,23 @@ const config = require('./config'); // User data scripts are run as the root user function buildUserDataScript(githubRegistrationToken, label) { + let userData; if (config.input.runnerHomeDir) { // If runner home directory is specified, we expect the actions-runner software (and dependencies) // to be pre-installed in the AMI, so we simply cd into that directory and then start the runner - return [ + userData = [ '#!/bin/bash', + 'exec > >(tee /var/log/user-data.log|logger -t user-data -s 2>/dev/console) 2>&1', `cd "${config.input.runnerHomeDir}"`, `echo "${config.input.preRunnerScript}" > pre-runner-script.sh`, 'source pre-runner-script.sh', 'export RUNNER_ALLOW_RUNASROOT=1', `./config.sh --url https://github.com/${config.githubContext.owner}/${config.githubContext.repo} --token ${githubRegistrationToken} --labels ${label}`, - './run.sh', ]; } else { - return [ + userData = [ '#!/bin/bash', + 'exec > >(tee /var/log/user-data.log|logger -t user-data -s 2>/dev/console) 2>&1', 'mkdir actions-runner && cd actions-runner', `echo "${config.input.preRunnerScript}" > pre-runner-script.sh`, 'source pre-runner-script.sh', @@ -28,9 +30,18 @@ function buildUserDataScript(githubRegistrationToken, label) { 'tar xzf ./actions-runner-linux-${RUNNER_ARCH}-2.313.0.tar.gz', 'export RUNNER_ALLOW_RUNASROOT=1', `./config.sh --url https://github.com/${config.githubContext.owner}/${config.githubContext.repo} --token ${githubRegistrationToken} --labels ${label}`, - './run.sh', ]; } + if (config.input.runAsUser) { + userData.push(`chown -R ${config.input.runAsUser} .`); + } + if (config.input.runAsService) { + userData.push(`./svc.sh install ${config.input.runAsUser || ''}`); + userData.push('./svc.sh start'); + } else { + userData.push(`${config.input.runAsUser ? `su ${config.input.runAsUser} -c` : ''} ./run.sh`); + } + return userData; } function buildMarketOptions() { diff --git a/src/config.js b/src/config.js index 53dc7f07..59f1d17b 100644 --- a/src/config.js +++ b/src/config.js @@ -19,6 +19,8 @@ class Config { startupRetryIntervalSeconds: core.getInput('startup-retry-interval-seconds'), startupTimeoutMinutes: core.getInput('startup-timeout-minutes'), subnetId: core.getInput('subnet-id'), + runAsService: core.getInput('run-runner-as-service') === 'true', + runAsUser: core.getInput('run-runner-as-user') }; const tags = JSON.parse(core.getInput('aws-resource-tags'));