Skip to content

Commit 0ebe401

Browse files
committed
fix(vms): refactoring and code fixes
1 parent 14e2636 commit 0ebe401

File tree

6 files changed

+77
-93
lines changed

6 files changed

+77
-93
lines changed

packages/actions/src/helpers/ec2.ts

+21-80
Original file line numberDiff line numberDiff line change
@@ -103,86 +103,15 @@ export const generateVMCommand = (zKeyPath: string, ptauPath: string): string[]
103103

104104
/**
105105
* Determine the VM specs based on the circuit constraints (TODO)
106-
* @param circuitConstraints <string> the constraints of the circuit
106+
* @param requiredSpace <string> the required disk space
107+
* @return <any> the disk space and ram requirements
107108
*/
108-
// export const determineVMSpecs = async (circuitConstraints: string) => {}
109-
110-
// // RAM -> instanceId
111-
// const instancesTypes = {
112-
// "t3.nano": {
113-
// RAM: "0.5 GiB",
114-
// VCPU: "2"
115-
// },
116-
// "t3.micro": {
117-
// RAM: "1 GiB",
118-
// VCPU: "2"
119-
// },
120-
// "t3.small": {
121-
// RAM: "2 GiB",
122-
// VCPU: "2"
123-
// },
124-
// "t3.medium": {
125-
// RAM: "4 GiB",
126-
// VCPU: "2"
127-
// },
128-
// "t3.large": {
129-
// RAM: "8 GiB",
130-
// VCPU: "2"
131-
// },
132-
// "t3.xlarge": {
133-
// RAM: "16 GiB",
134-
// VCPU: "4"
135-
// },
136-
// "t3.2xlarge": {
137-
// RAM: "32 GiB",
138-
// VCPU: "8"
139-
// },
140-
// "c5.9xlarge": {
141-
// RAM: "36 GiB",
142-
// VCPU: "36"
143-
// },
144-
// "c5.18xlarge": {
145-
// RAM: "72 GiB",
146-
// VCPU: "72"
147-
// },
148-
// "c5a.8xlarge": {
149-
// RAM: "64 GiB",
150-
// VCPU: "32"
151-
// },
152-
// "c5.12xlarge": {
153-
// RAM: "96 GiB",
154-
// VCPU: "48"
155-
// },
156-
// "c5a.16xlarge": {
157-
// RAM: "128 GiB",
158-
// VCPU: "64"
159-
// },
160-
// "c6i.32xlarge": {
161-
// RAM: "256 GiB",
162-
// VCPU: "128"
163-
// },
164-
// "m6a.32xlarge": {
165-
// RAM: "512 GiB",
166-
// VCPU: "128"
167-
// }
168-
// }
169-
170-
// 1. create ssh key in ec2 tab -> save the name
171-
// 2. IAM role: access to ssh key ("iam:GetSSHPublicKey",)
172-
// 3. IAM role: ec2 access
173-
// 4. ec2 give role for s3 access
174-
// 5. have an api (express) running on the vm
175-
// 6. have a script that runs on the vm that does the verification
176-
// 7. JWT Authorization: Bearer <token>
177-
// each circuit document needs to have the instance id of the vm
178-
/*
179-
{
180-
bucket: "x",
181-
action: "verify/checkStatus",
182-
"zKeyIndex": 0,
183-
"zKeyStoragePath": /circuit/..,
109+
export const determineVMSpecs = (requiredSpace: string) => {
110+
return {
111+
"vm": "c5.x9large",
112+
"disk": 32
113+
}
184114
}
185-
*/
186115

187116
/**
188117
* Creates a new EC2 instance
@@ -192,6 +121,7 @@ export const generateVMCommand = (zKeyPath: string, ptauPath: string): string[]
192121
* @param amiId <string> the AMI ID to be used
193122
* @param keyName <string> the name of the key to be used
194123
* @param roleArn <string> the ARN of the role to be used
124+
* @param volumeSize <number> the size of the volume to be used
195125
* @returns <Promise<P0tionEC2Instance>> the instance that was created
196126
*/
197127
export const createEC2Instance = async (
@@ -200,7 +130,8 @@ export const createEC2Instance = async (
200130
instanceType: string,
201131
amiId: string,
202132
keyName: string,
203-
roleArn: string
133+
roleArn: string,
134+
volumeSize: number
204135
): Promise<P0tionEC2Instance> => {
205136
// create the params
206137
const params = {
@@ -214,7 +145,17 @@ export const createEC2Instance = async (
214145
Arn: roleArn
215146
},
216147
// how to run commands on startup
217-
UserData: Buffer.from(commands.join("\n")).toString("base64")
148+
UserData: Buffer.from(commands.join("\n")).toString("base64"),
149+
BlockDeviceMappings: [
150+
{
151+
DeviceName: '/dev/xvda',
152+
Ebs: {
153+
DeleteOnTermination: true,
154+
VolumeSize: volumeSize, // size in GB
155+
VolumeType: 'gp2', // change this as per your needs
156+
},
157+
},
158+
],
218159
}
219160

220161
// create command

packages/actions/src/index.ts

+2-1
Original file line numberDiff line numberDiff line change
@@ -143,5 +143,6 @@ export {
143143
getEC2Ip,
144144
generateVMCommand,
145145
runCommandOnEC2,
146-
retrieveCommandOutput
146+
retrieveCommandOutput,
147+
determineVMSpecs
147148
} from "./helpers/ec2"

packages/actions/test/unit/ec2.test.ts

+10-2
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ import chai, { expect } from "chai"
22
import chaiAsPromised from "chai-as-promised"
33
import { EC2Client } from "@aws-sdk/client-ec2"
44
import fetch from "@adobe/node-fetch-retry"
5-
import { cleanUpMockUsers, cleanUpRecursively, createMockUser, envType, generateUserPasswords, getStorageConfiguration, getTranscriptLocalFilePath, initializeAdminServices, initializeUserServices, sleep } from "../utils"
5+
import { cleanUpMockUsers, cleanUpRecursively, createMockUser, deleteBucket, deleteObjectFromS3, envType, generateUserPasswords, getStorageConfiguration, getTranscriptLocalFilePath, initializeAdminServices, initializeUserServices, sleep } from "../utils"
66
import {
77
checkEC2Status,
88
createEC2Client,
@@ -191,6 +191,7 @@ describe("VMs", () => {
191191

192192
// 1 create a bucket for the ceremony
193193
await signInWithEmailAndPassword(userAuth, users[1].data.email, passwords[1])
194+
console.log("LOGGED IN")
194195
await createS3Bucket(userFunctions, ceremonyBucket)
195196

196197
// zkey upload
@@ -204,8 +205,13 @@ describe("VMs", () => {
204205
await terminateEC2Instance(ec2, instanceId)
205206
}
206207

208+
for (const objectToDelete of objectsToDelete) {
209+
await deleteObjectFromS3(ceremonyBucket, objectToDelete)
210+
}
211+
await deleteBucket(ceremonyBucket)
212+
207213
await cleanUpMockUsers(adminAuth, adminFirestore, users)
208-
await cleanUpRecursively(adminFirestore, ceremonyId)
214+
// await cleanUpRecursively(adminFirestore, ceremonyId)
209215
})
210216

211217
it("should create a ceremony and two VMs should spin up", async () => {
@@ -337,5 +343,7 @@ describe("VMs", () => {
337343
String(process.env.FIREBASE_CF_URL_VERIFY_CONTRIBUTION)
338344
)
339345
})
346+
347+
it("should terminate the VM(s) when finalizaing the ceremony", async () => {})
340348
})
341349
})

packages/backend/src/functions/ceremony.ts

+10-7
Original file line numberDiff line numberDiff line change
@@ -28,10 +28,13 @@ import {
2828
createEC2Client,
2929
getAWSVariables,
3030
sleep,
31-
uploadFileToBucket
31+
uploadFileToBucket,
32+
createTemporaryLocalPath,
33+
uploadFileToBucketNoFile
3234
} from "../lib/utils"
3335
import { LogLevel } from "../types/enums"
3436
import { writeFileSync, unlinkSync } from "fs"
37+
import { determineVMSpecs } from "@p0tion/actions"
3538

3639
dotenv.config()
3740

@@ -151,20 +154,20 @@ export const setupCeremony = functions
151154
)
152155

153156
// upload the instructions file the bucket and clean up
154-
const startupScriptPath = `/var/tmp/${startupScript}`
155-
writeFileSync(startupScriptPath, vmCommands.join("\n"))
156-
await uploadFileToBucket(bucketName, startupScript, startupScriptPath)
157-
unlinkSync(startupScriptPath)
157+
await uploadFileToBucketNoFile(bucketName, startupScript, vmCommands.join("\n"))
158158

159159
const { amiId, keyName, roleArn } = getAWSVariables()
160+
161+
const vmSpecs = determineVMSpecs("32")
160162
// as well as the VM configuration
161163
const instance = await createEC2Instance(
162164
ec2Client,
163165
userData,
164-
"t3.small",
166+
"t3.xlarge",
165167
amiId,
166168
keyName,
167-
roleArn
169+
roleArn,
170+
Number(vmSpecs.disk)
168171
)
169172

170173
// html encode circuit data.

packages/backend/src/functions/storage.ts

+3-3
Original file line numberDiff line numberDiff line change
@@ -146,9 +146,9 @@ export const createBucket = functions
146146
// Prepare S3 command.
147147
const command = new CreateBucketCommand({
148148
Bucket: data.bucketName,
149-
CreateBucketConfiguration: {
150-
LocationConstraint: String(process.env.AWS_REGION)
151-
},
149+
// CreateBucketConfiguration: {
150+
// LocationConstraint: String(process.env.AWS_REGION)
151+
// },
152152
ObjectOwnership: "BucketOwnerPreferred"
153153
})
154154

packages/backend/src/lib/utils.ts

+31
Original file line numberDiff line numberDiff line change
@@ -258,6 +258,37 @@ export const uploadFileToBucket = async (
258258
if (response.status !== 200 || !response.ok) logAndThrowError(SPECIFIC_ERRORS.SE_STORAGE_UPLOAD_FAILED)
259259
}
260260

261+
export const uploadFileToBucketNoFile = async (
262+
bucketName: string,
263+
objectKey: string,
264+
data: string,
265+
isPublic: boolean = false
266+
) => {
267+
// Prepare AWS S3 client instance.
268+
const client = await getS3Client()
269+
270+
// Prepare command.
271+
const command = new PutObjectCommand({
272+
Bucket: bucketName,
273+
Key: objectKey,
274+
ContentType: "text/plain",
275+
ACL: isPublic ? "public-read" : "private"
276+
})
277+
278+
// Generate a pre-signed url for uploading the file.
279+
const url = await getSignedUrl(client, command, { expiresIn: Number(process.env.AWS_PRESIGNED_URL_EXPIRATION) })
280+
281+
// Execute upload request.
282+
// @ts-ignore
283+
const response = await fetch(url, {
284+
method: "PUT",
285+
body: data,
286+
headers: { "Content-Type": "text/plain" }
287+
})
288+
289+
if (response.status !== 200 || !response.ok) logAndThrowError(SPECIFIC_ERRORS.SE_STORAGE_UPLOAD_FAILED)
290+
}
291+
261292
/**
262293
* Upload an artifact from the AWS S3 bucket.
263294
* @param bucketName <string> - the name of the bucket.

0 commit comments

Comments
 (0)