1
1
import {
2
- EC2Client ,
3
2
DescribeInstanceStatusCommand ,
4
- RunInstancesCommand ,
5
- StartInstancesCommand ,
6
- StopInstancesCommand ,
3
+ RunInstancesCommand ,
4
+ StartInstancesCommand ,
5
+ StopInstancesCommand ,
7
6
TerminateInstancesCommand ,
8
- DescribeInstancesCommand
7
+ DescribeInstancesCommand ,
8
+ EC2Client
9
9
} from "@aws-sdk/client-ec2"
10
- import { GetCommandInvocationCommand , SSMClient , SendCommandCommand , SendCommandCommandInput } from "@aws-sdk/client-ssm"
11
- import { P0tionEC2Instance } from "../types"
10
+ import {
11
+ GetCommandInvocationCommand ,
12
+ SSMClient ,
13
+ SendCommandCommand ,
14
+ SendCommandCommandInput
15
+ } from "@aws-sdk/client-ssm"
12
16
import dotenv from "dotenv"
17
+ import { P0tionEC2Instance } from "../types"
18
+
13
19
dotenv . config ( )
14
20
15
21
/**
16
22
* Extract AWS related environment variables
17
23
*/
18
24
export const getAWSVariables = ( ) => {
19
25
if (
20
- ! process . env . AWS_ACCESS_KEY_ID ||
21
- ! process . env . AWS_SECRET_ACCESS_KEY ||
26
+ ! process . env . AWS_ACCESS_KEY_ID ||
27
+ ! process . env . AWS_SECRET_ACCESS_KEY ||
22
28
! process . env . AWS_ROLE_ARN ||
23
29
! process . env . AWS_AMI_ID ||
24
- ! process . env . AWS_KEY_NAME
25
- )
30
+ ! process . env . AWS_KEY_NAME
31
+ )
26
32
throw new Error ( "AWS related environment variables are not set. Please check your env file and try again." )
27
33
28
34
return {
@@ -44,13 +50,13 @@ export const createEC2Client = async (): Promise<EC2Client> => {
44
50
45
51
const ec2 : EC2Client = new EC2Client ( {
46
52
credentials : {
47
- accessKeyId : accessKeyId ,
48
- secretAccessKey : secretAccessKey
53
+ accessKeyId,
54
+ secretAccessKey
49
55
} ,
50
- region : region
56
+ region
51
57
} )
52
58
53
- return ec2
59
+ return ec2
54
60
}
55
61
56
62
/**
@@ -62,10 +68,10 @@ export const createSSMClient = async (): Promise<SSMClient> => {
62
68
63
69
const ssm : SSMClient = new SSMClient ( {
64
70
credentials : {
65
- accessKeyId : accessKeyId ,
66
- secretAccessKey : secretAccessKey
71
+ accessKeyId,
72
+ secretAccessKey
67
73
} ,
68
- region : region
74
+ region
69
75
} )
70
76
71
77
return ssm
@@ -77,14 +83,11 @@ export const createSSMClient = async (): Promise<SSMClient> => {
77
83
* @param ptauPath <string> path to ptau file
78
84
* @returns <string[]> array of commands to be run by the EC2 instance
79
85
*/
80
- export const generateVMCommand = (
81
- zKeyPath : string ,
82
- ptauPath : string ,
83
- ) : string [ ] => {
86
+ export const generateVMCommand = ( zKeyPath : string , ptauPath : string ) : string [ ] => {
84
87
const command = [
85
88
"#!/usr/bin/env bash" ,
86
89
"sudo apt update" ,
87
- "sudo apt install awscli -y" , // install aws cli
90
+ "sudo apt install awscli -y" , // install aws cli
88
91
"curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.39.3/install.sh | bash" , // install nvm
89
92
"source ~/.bashrc" ,
90
93
"nvm install 16" ,
@@ -93,84 +96,84 @@ export const generateVMCommand = (
93
96
`aws s3 cp s3://${ zKeyPath } ./genesisZkey.zkey` ,
94
97
`aws s3 cp s3://${ ptauPath } ./pot.ptau`
95
98
]
96
-
99
+
97
100
return command
98
101
}
99
102
100
103
/**
101
104
* Determine the VM specs based on the circuit constraints (TODO)
102
105
* @param circuitConstraints <string> the constraints of the circuit
103
106
*/
104
- export const determineVMSpecs = async ( circuitConstraints : string ) => { }
105
-
106
- // RAM -> instanceId
107
- const instancesTypes = {
108
- "t3.nano" : {
109
- RAM : "0.5 GiB" ,
110
- VCPU : "2"
111
- } ,
112
- "t3.micro" : {
113
- RAM : "1 GiB" ,
114
- VCPU : "2"
115
- } ,
116
- "t3.small" : {
117
- RAM : "2 GiB" ,
118
- VCPU : "2"
119
- } ,
120
- "t3.medium" : {
121
- RAM : "4 GiB" ,
122
- VCPU : "2"
123
- } ,
124
- "t3.large" : {
125
- RAM : "8 GiB" ,
126
- VCPU : "2"
127
- } ,
128
- "t3.xlarge" : {
129
- RAM : "16 GiB" ,
130
- VCPU : "4"
131
- } ,
132
- "t3.2xlarge" : {
133
- RAM : "32 GiB" ,
134
- VCPU : "8"
135
- } ,
136
- "c5.9xlarge" : {
137
- RAM : "36 GiB" ,
138
- VCPU : "36"
139
- } ,
140
- "c5.18xlarge" : {
141
- RAM : "72 GiB" ,
142
- VCPU : "72"
143
- } ,
144
- "c5a.8xlarge" : {
145
- RAM : "64 GiB" ,
146
- VCPU : "32"
147
- } ,
148
- "c5.12xlarge" : {
149
- RAM : "96 GiB" ,
150
- VCPU : "48"
151
- } ,
152
- "c5a.16xlarge" : {
153
- RAM : "128 GiB" ,
154
- VCPU : "64"
155
- } ,
156
- "c6i.32xlarge" : {
157
- RAM : "256 GiB" ,
158
- VCPU : "128"
159
- } ,
160
- "m6a.32xlarge" : {
161
- RAM : "512 GiB" ,
162
- VCPU : "128"
163
- }
164
- }
165
-
166
- // 1. create ssh key in ec2 tab -> save the name
107
+ // export const determineVMSpecs = async (circuitConstraints: string) => {}
108
+
109
+ // // RAM -> instanceId
110
+ // const instancesTypes = {
111
+ // "t3.nano": {
112
+ // RAM: "0.5 GiB",
113
+ // VCPU: "2"
114
+ // },
115
+ // "t3.micro": {
116
+ // RAM: "1 GiB",
117
+ // VCPU: "2"
118
+ // },
119
+ // "t3.small": {
120
+ // RAM: "2 GiB",
121
+ // VCPU: "2"
122
+ // },
123
+ // "t3.medium": {
124
+ // RAM: "4 GiB",
125
+ // VCPU: "2"
126
+ // },
127
+ // "t3.large": {
128
+ // RAM: "8 GiB",
129
+ // VCPU: "2"
130
+ // },
131
+ // "t3.xlarge": {
132
+ // RAM: "16 GiB",
133
+ // VCPU: "4"
134
+ // },
135
+ // "t3.2xlarge": {
136
+ // RAM: "32 GiB",
137
+ // VCPU: "8"
138
+ // },
139
+ // "c5.9xlarge": {
140
+ // RAM: "36 GiB",
141
+ // VCPU: "36"
142
+ // },
143
+ // "c5.18xlarge": {
144
+ // RAM: "72 GiB",
145
+ // VCPU: "72"
146
+ // },
147
+ // "c5a.8xlarge": {
148
+ // RAM: "64 GiB",
149
+ // VCPU: "32"
150
+ // },
151
+ // "c5.12xlarge": {
152
+ // RAM: "96 GiB",
153
+ // VCPU: "48"
154
+ // },
155
+ // "c5a.16xlarge": {
156
+ // RAM: "128 GiB",
157
+ // VCPU: "64"
158
+ // },
159
+ // "c6i.32xlarge": {
160
+ // RAM: "256 GiB",
161
+ // VCPU: "128"
162
+ // },
163
+ // "m6a.32xlarge": {
164
+ // RAM: "512 GiB",
165
+ // VCPU: "128"
166
+ // }
167
+ // }
168
+
169
+ // 1. create ssh key in ec2 tab -> save the name
167
170
// 2. IAM role: access to ssh key ("iam:GetSSHPublicKey",)
168
171
// 3. IAM role: ec2 access
169
172
// 4. ec2 give role for s3 access
170
- // 5. have an api (express) running on the vm
173
+ // 5. have an api (express) running on the vm
171
174
// 6. have a script that runs on the vm that does the verification
172
175
// 7. JWT Authorization: Bearer <token>
173
- // each circuit document needs to have the instance id of the vm
176
+ // each circuit document needs to have the instance id of the vm
174
177
/*
175
178
{
176
179
bucket: "x",
@@ -181,7 +184,7 @@ const instancesTypes = {
181
184
*/
182
185
183
186
/**
184
- * Creates a new EC2 instance
187
+ * Creates a new EC2 instance
185
188
* @param ec2 <EC2Client> the EC2 client to talk to AWS
186
189
* @param commands <string[]> the commands to be run on the EC2 instance
187
190
* @param instanceType <string> the type of instance to be created
@@ -191,46 +194,45 @@ const instancesTypes = {
191
194
* @returns <Promise<P0tionEC2Instance>> the instance that was created
192
195
*/
193
196
export const createEC2Instance = async (
194
- ec2 : EC2Client ,
195
- commands : string [ ] ,
197
+ ec2 : EC2Client ,
198
+ commands : string [ ] ,
196
199
instanceType : string ,
197
- amiId : string ,
200
+ amiId : string ,
198
201
keyName : string ,
199
202
roleArn : string
200
- ) : Promise < P0tionEC2Instance > => {
201
-
202
- // create the params
203
+ ) : Promise < P0tionEC2Instance > => {
204
+ // create the params
203
205
const params = {
204
206
ImageId : amiId ,
205
207
InstanceType : instanceType , // to be determined programmatically
206
208
MaxCount : 1 ,
207
209
MinCount : 1 ,
208
210
KeyName : keyName ,
209
211
// remember how to find this (iam -> roles -> role_name )
210
- IamInstanceProfile : {
211
- Arn : roleArn ,
212
+ IamInstanceProfile : {
213
+ Arn : roleArn
212
214
} ,
213
215
// how to run commands on startup
214
- UserData : Buffer . from ( commands . join ( "\n" ) ) . toString ( ' base64' )
216
+ UserData : Buffer . from ( commands . join ( "\n" ) ) . toString ( " base64" )
215
217
}
216
218
217
- // create command
219
+ // create command
218
220
try {
219
221
const command = new RunInstancesCommand ( params )
220
222
const response = await ec2 . send ( command )
221
-
223
+
222
224
if ( response . $metadata . httpStatusCode !== 200 ) {
223
225
throw new Error ( "Could not create a new EC2 instance" )
224
226
}
225
-
226
- const instance : P0tionEC2Instance = {
227
+
228
+ const instance : P0tionEC2Instance = {
227
229
InstanceId : response . Instances ! [ 0 ] . InstanceId ! ,
228
230
ImageId : response . Instances ! [ 0 ] . ImageId ! ,
229
231
InstanceType : response . Instances ! [ 0 ] . InstanceType ! ,
230
232
KeyName : response . Instances ! [ 0 ] . KeyName ! ,
231
233
LaunchTime : response . Instances ! [ 0 ] . LaunchTime ! . toISOString ( )
232
234
}
233
-
235
+
234
236
return instance
235
237
} catch ( error : any ) {
236
238
console . log ( "[*] Debug" , error )
@@ -248,11 +250,10 @@ export const checkEC2Status = async (ec2Client: EC2Client, instanceId: string):
248
250
const command = new DescribeInstanceStatusCommand ( {
249
251
InstanceIds : [ instanceId ]
250
252
} )
251
-
253
+
252
254
const response = await ec2Client . send ( command )
253
- if ( response . $metadata . httpStatusCode !== 200 )
254
- throw new Error ( "Could not get the status of the EC2 instance" )
255
-
255
+ if ( response . $metadata . httpStatusCode !== 200 ) throw new Error ( "Could not get the status of the EC2 instance" )
256
+
256
257
return response . InstanceStatuses ! [ 0 ] . InstanceState ! . Name === "running"
257
258
}
258
259
@@ -291,7 +292,7 @@ export const startEC2Instance = async (ec2: EC2Client, instanceId: string) => {
291
292
292
293
if ( response . $metadata . httpStatusCode !== 200 ) {
293
294
throw new Error ( "Could not start the EC2 instance" )
294
- }
295
+ }
295
296
}
296
297
297
298
/**
@@ -337,17 +338,13 @@ export const terminateEC2Instance = async (ec2: EC2Client, instanceId: string) =
337
338
* @param commands <string[]> the commands to run
338
339
* @return <Promise<any>> the command id
339
340
*/
340
- export const runCommandOnEC2 = async (
341
- ssmClient : SSMClient ,
342
- instanceId : string ,
343
- commands : string [ ]
344
- ) : Promise < any > => {
341
+ export const runCommandOnEC2 = async ( ssmClient : SSMClient , instanceId : string , commands : string [ ] ) : Promise < any > => {
345
342
// the params for the command
346
343
const params : SendCommandCommandInput = {
347
344
DocumentName : "AWS-RunShellScript" ,
348
345
InstanceIds : [ instanceId ] ,
349
346
Parameters : {
350
- "commands" : commands
347
+ commands
351
348
} ,
352
349
TimeoutSeconds : 1200
353
350
}
@@ -373,10 +370,10 @@ export const runCommandOnEC2 = async (
373
370
export const retrieveCommandOutput = async (
374
371
ssmClient : SSMClient ,
375
372
commandId : string ,
376
- instanceId : string
373
+ instanceId : string
377
374
) : Promise < any > => {
378
375
const command = new GetCommandInvocationCommand ( {
379
- CommandId : commandId ,
376
+ CommandId : commandId ,
380
377
InstanceId : instanceId
381
378
} )
382
379
@@ -386,4 +383,4 @@ export const retrieveCommandOutput = async (
386
383
} catch ( error : any ) {
387
384
throw new Error ( "Could not retrieve the output of the command" )
388
385
}
389
- }
386
+ }
0 commit comments