-
Notifications
You must be signed in to change notification settings - Fork 352
/
Copy pathaws.js
126 lines (112 loc) · 3.94 KB
/
aws.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
const { EC2Client, RunInstancesCommand, TerminateInstancesCommand, waitUntilInstanceRunning } = require('@aws-sdk/client-ec2');
const core = require('@actions/core');
const config = require('./config');
// User data scripts are run as the root user
function buildUserDataScript(githubRegistrationToken, label) {
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 [
'#!/bin/bash',
`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 [
'#!/bin/bash',
'mkdir actions-runner && cd actions-runner',
`echo "${config.input.preRunnerScript}" > pre-runner-script.sh`,
'source pre-runner-script.sh',
'case $(uname -m) in aarch64) ARCH="arm64" ;; amd64|x86_64) ARCH="x64" ;; esac && export RUNNER_ARCH=${ARCH}',
'curl -O -L https://github.com/actions/runner/releases/download/v2.313.0/actions-runner-linux-${RUNNER_ARCH}-2.313.0.tar.gz',
'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',
];
}
}
function buildMarketOptions() {
if (config.input.marketType !== 'spot') {
return undefined;
}
return {
MarketType: config.input.marketType,
SpotOptions: {
SpotInstanceType: 'one-time',
},
};
}
async function startEc2Instance(label, githubRegistrationToken) {
const ec2 = new EC2Client();
const userData = buildUserDataScript(githubRegistrationToken, label);
const params = {
ImageId: config.input.ec2ImageId,
InstanceType: config.input.ec2InstanceType,
MaxCount: 1,
MinCount: 1,
SecurityGroupIds: [config.input.securityGroupId],
SubnetId: config.input.subnetId,
UserData: Buffer.from(userData.join('\n')).toString('base64'),
IamInstanceProfile: { Name: config.input.iamRoleName },
TagSpecifications: config.tagSpecifications,
InstanceMarketOptions: buildMarketOptions(),
};
try {
const result = await ec2.send(new RunInstancesCommand(params));
const ec2InstanceId = result.Instances[0].InstanceId;
core.info(`AWS EC2 instance ${ec2InstanceId} is started`);
return ec2InstanceId;
} catch (error) {
core.error('AWS EC2 instance starting error');
throw error;
}
}
async function terminateEc2Instance() {
const ec2 = new EC2Client();
const params = {
InstanceIds: [config.input.ec2InstanceId],
};
try {
await ec2.send(new TerminateInstancesCommand(params));
core.info(`AWS EC2 instance ${config.input.ec2InstanceId} is terminated`);
return;
} catch (error) {
core.error(`AWS EC2 instance ${config.input.ec2InstanceId} termination error`);
throw error;
}
}
async function waitForInstanceRunning(ec2InstanceId) {
const ec2 = new EC2Client();
try {
core.info(`Checking for instance ${ec2InstanceId} to be up and running`);
await waitUntilInstanceRunning(
{
client: ec2,
maxWaitTime: 300,
},
{
Filters: [
{
Name: 'instance-id',
Values: [ec2InstanceId],
},
],
},
);
core.info(`AWS EC2 instance ${ec2InstanceId} is up and running`);
return;
} catch (error) {
core.error(`AWS EC2 instance ${ec2InstanceId} initialization error`);
throw error;
}
}
module.exports = {
startEc2Instance,
terminateEc2Instance,
waitForInstanceRunning,
};