From c4fffc9bd242acf331cad6ab699fde14fb528e40 Mon Sep 17 00:00:00 2001 From: Michael Meyer Date: Thu, 17 Oct 2024 02:40:41 +1100 Subject: [PATCH] fix: python docker build architecture (#1082) * fix: python docker build architecture * sync --------- Co-authored-by: Michael Meyer <9434150+mtmeyer@users.noreply.github.com> Co-authored-by: Frank --- platform/src/components/aws/function.ts | 356 ++++++++++++------------ 1 file changed, 178 insertions(+), 178 deletions(-) diff --git a/platform/src/components/aws/function.ts b/platform/src/components/aws/function.ts index fd2487d4e..311faed1a 100644 --- a/platform/src/components/aws/function.ts +++ b/platform/src/components/aws/function.ts @@ -495,53 +495,53 @@ export interface FunctionArgs { logging?: Input< | false | { - /** - * The duration the function logs are kept in CloudWatch. - * - * Not application when an existing log group is provided. - * - * @default `forever` - * @example - * ```js - * { - * logging: { - * retention: "1 week" - * } - * } - * ``` - */ - retention?: Input; - /** - * Assigns the given CloudWatch log group name to the function. This allows you to pass in a previously created log group. - * - * By default, the function creates a new log group when it's created. - * - * @default Creates a log group - * @example - * ```js - * { - * logging: { - * logGroup: "/existing/log-group" - * } - * } - * ``` - */ - logGroup?: Input; - /** - * The [log format](https://docs.aws.amazon.com/lambda/latest/dg/monitoring-cloudwatchlogs-advanced.html) - * of the Lambda function. - * @default `"text"` - * @example - * ```js - * { - * logging: { - * format: "json" - * } - * } - * ``` - */ - format?: Input<"text" | "json">; - } + /** + * The duration the function logs are kept in CloudWatch. + * + * Not application when an existing log group is provided. + * + * @default `forever` + * @example + * ```js + * { + * logging: { + * retention: "1 week" + * } + * } + * ``` + */ + retention?: Input; + /** + * Assigns the given CloudWatch log group name to the function. This allows you to pass in a previously created log group. + * + * By default, the function creates a new log group when it's created. + * + * @default Creates a log group + * @example + * ```js + * { + * logging: { + * logGroup: "/existing/log-group" + * } + * } + * ``` + */ + logGroup?: Input; + /** + * The [log format](https://docs.aws.amazon.com/lambda/latest/dg/monitoring-cloudwatchlogs-advanced.html) + * of the Lambda function. + * @default `"text"` + * @example + * ```js + * { + * logging: { + * format: "json" + * } + * } + * ``` + */ + format?: Input<"text" | "json">; + } >; /** * The [architecture](https://docs.aws.amazon.com/lambda/latest/dg/foundation-arch.html) @@ -603,45 +603,45 @@ export interface FunctionArgs { url?: Input< | boolean | { - /** - * The authorization used for the function URL. Supports [IAM authorization](https://docs.aws.amazon.com/lambda/latest/dg/urls-auth.html). - * @default `"none"` - * @example - * ```js - * { - * url: { - * authorization: "iam" - * } - * } - * ``` - */ - authorization?: Input<"none" | "iam">; - /** - * Customize the CORS (Cross-origin resource sharing) settings for the function URL. - * @default `true` - * @example - * Disable CORS. - * ```js - * { - * url: { - * cors: false - * } - * } - * ``` - * Only enable the `GET` and `POST` methods for `https://example.com`. - * ```js - * { - * url: { - * cors: { - * allowMethods: ["GET", "POST"], - * allowOrigins: ["https://example.com"] - * } - * } - * } - * ``` - */ - cors?: Input>; - } + /** + * The authorization used for the function URL. Supports [IAM authorization](https://docs.aws.amazon.com/lambda/latest/dg/urls-auth.html). + * @default `"none"` + * @example + * ```js + * { + * url: { + * authorization: "iam" + * } + * } + * ``` + */ + authorization?: Input<"none" | "iam">; + /** + * Customize the CORS (Cross-origin resource sharing) settings for the function URL. + * @default `true` + * @example + * Disable CORS. + * ```js + * { + * url: { + * cors: false + * } + * } + * ``` + * Only enable the `GET` and `POST` methods for `https://example.com`. + * ```js + * { + * url: { + * cors: { + * allowMethods: ["GET", "POST"], + * allowOrigins: ["https://example.com"] + * } + * } + * } + * ``` + */ + cors?: Input>; + } >; /** * Configure how your function is bundled. @@ -1189,7 +1189,7 @@ export class Function extends Component implements Link.Linkable { const runtime = normalizeRuntime(); const timeout = normalizeTimeout(); const memory = normalizeMemory(); - const architectures = normalizeArchitectures(); + const architecture = output(args.architecture).apply((v) => v ?? "x86_64"); const environment = normalizeEnvironment(); const streaming = normalizeStreaming(); const logging = normalizeLogging(); @@ -1296,12 +1296,6 @@ export class Function extends Component implements Link.Linkable { return output(args.memory).apply((memory) => memory ?? "1024 MB"); } - function normalizeArchitectures() { - return all([args.architecture]).apply(([arc]) => - arc === "arm64" ? ["arm64"] : ["x86_64"], - ); - } - function normalizeEnvironment() { return all([ args.environment, @@ -1374,10 +1368,10 @@ export class Function extends Component implements Link.Linkable { : url.cors === true || url.cors === undefined ? defaultCors : { - ...defaultCors, - ...url.cors, - maxAge: url.cors.maxAge && toSeconds(url.cors.maxAge), - }; + ...defaultCors, + ...url.cors, + maxAge: url.cors.maxAge && toSeconds(url.cors.maxAge), + }; return { authorization, cors }; }); @@ -1464,7 +1458,7 @@ export class Function extends Component implements Link.Linkable { if (result.type === "error") { throw new VisibleError( `Failed to build function "${args.handler}": ` + - result.errors.join("\n").trim(), + result.errors.join("\n").trim(), ); } return result; @@ -1476,7 +1470,7 @@ export class Function extends Component implements Link.Linkable { if (result.type === "error") { throw new VisibleError( `Failed to build function "${args.handler}": ` + - result.errors.join("\n").trim(), + result.errors.join("\n").trim(), ); } return result; @@ -1574,21 +1568,21 @@ export class Function extends Component implements Link.Linkable { name: path.posix.join(handlerDir, `${newHandlerFileName}.mjs`), content: streaming ? [ - ...split.outer, - `export const ${newHandlerFunction} = awslambda.streamifyResponse(async (event, responseStream, context) => {`, - ...split.inner, - ` const { ${oldHandlerFunction}: rawHandler} = await import("./${oldHandlerFileName}${newHandlerFileExt}");`, - ` return rawHandler(event, responseStream, context);`, - `});`, - ].join("\n") + ...split.outer, + `export const ${newHandlerFunction} = awslambda.streamifyResponse(async (event, responseStream, context) => {`, + ...split.inner, + ` const { ${oldHandlerFunction}: rawHandler} = await import("./${oldHandlerFileName}${newHandlerFileExt}");`, + ` return rawHandler(event, responseStream, context);`, + `});`, + ].join("\n") : [ - ...split.outer, - `export const ${newHandlerFunction} = async (event, context) => {`, - ...split.inner, - ` const { ${oldHandlerFunction}: rawHandler} = await import("./${oldHandlerFileName}${newHandlerFileExt}");`, - ` return rawHandler(event, context);`, - `};`, - ].join("\n"), + ...split.outer, + `export const ${newHandlerFunction} = async (event, context) => {`, + ...split.inner, + ` const { ${oldHandlerFunction}: rawHandler} = await import("./${oldHandlerFileName}${newHandlerFileExt}");`, + ` return rawHandler(event, context);`, + `};`, + ].join("\n"), }, }; }, @@ -1619,18 +1613,18 @@ export class Function extends Component implements Link.Linkable { })), ...(dev ? [ - { - actions: ["iot:*"], - resources: ["*"], - }, - { - actions: ["s3:*"], - resources: [ - interpolate`arn:aws:s3:::${bootstrapData.asset}`, - interpolate`arn:aws:s3:::${bootstrapData.asset}/*`, - ], - }, - ] + { + actions: ["iot:*"], + resources: ["*"], + }, + { + actions: ["s3:*"], + resources: [ + interpolate`arn:aws:s3:::${bootstrapData.asset}`, + interpolate`arn:aws:s3:::${bootstrapData.asset}/*`, + ], + }, + ] : []), ], }), @@ -1643,28 +1637,29 @@ export class Function extends Component implements Link.Linkable { { assumeRolePolicy: !$dev ? iam.assumeRolePolicyForPrincipal({ - Service: "lambda.amazonaws.com", - }) + Service: "lambda.amazonaws.com", + }) : iam.getPolicyDocumentOutput({ - statements: [ - { - actions: ["sts:AssumeRole"], - principals: [ - { - type: "Service", - identifiers: ["lambda.amazonaws.com"], - }, - { - type: "AWS", - identifiers: [ - interpolate`arn:aws:iam::${getCallerIdentityOutput().accountId + statements: [ + { + actions: ["sts:AssumeRole"], + principals: [ + { + type: "Service", + identifiers: ["lambda.amazonaws.com"], + }, + { + type: "AWS", + identifiers: [ + interpolate`arn:aws:iam::${ + getCallerIdentityOutput().accountId }:root`, - ], - }, - ], - }, - ], - }).json, + ], + }, + ], + }, + ], + }).json, // if there are no statements, do not add an inline policy. // adding an inline policy with no statements will cause an error. inlinePolicies: policy.apply(({ statements }) => @@ -1673,13 +1668,13 @@ export class Function extends Component implements Link.Linkable { managedPolicyArns: logging.apply((logging) => [ ...(logging ? [ - "arn:aws:iam::aws:policy/service-role/AWSLambdaBasicExecutionRole", - ] + "arn:aws:iam::aws:policy/service-role/AWSLambdaBasicExecutionRole", + ] : []), ...(vpc ? [ - "arn:aws:iam::aws:policy/service-role/AWSLambdaVPCAccessExecutionRole", - ] + "arn:aws:iam::aws:policy/service-role/AWSLambdaVPCAccessExecutionRole", + ] : []), ]), }, @@ -1736,7 +1731,11 @@ export class Function extends Component implements Link.Linkable { inline: {}, }, ], - /// TODO: walln - enable arm64 builds by using architecture args + platforms: [ + architecture.apply((v) => + v === "arm64" ? "linux/arm64" : "linux/amd64", + ), + ], push: true, registries: [ authToken.apply((authToken) => ({ @@ -1807,9 +1806,9 @@ export class Function extends Component implements Link.Linkable { entry.isDir ? archive.directory(entry.from, entry.to, { date: new Date(0) }) : archive.file(entry.from, { - name: entry.to, - date: new Date(0), - }); + name: entry.to, + date: new Date(0), + }); }); await archive.finalize(); }); @@ -1844,8 +1843,9 @@ export class Function extends Component implements Link.Linkable { args.transform?.logGroup, `${name}LogGroup`, { - name: interpolate`/aws/lambda/${args.name ?? physicalName(64, `${name}Function`) - }`, + name: interpolate`/aws/lambda/${ + args.name ?? physicalName(64, `${name}Function`) + }`, retentionInDays: RETENTION[logging.retention], }, { parent }, @@ -1889,7 +1889,7 @@ export class Function extends Component implements Link.Linkable { environment: { variables: environment, }, - architectures, + architectures: [architecture], loggingConfig: logging && { logFormat: logging.format === "json" ? "JSON" : "Text", logGroup: logging.logGroup ?? logGroup!.name, @@ -1904,21 +1904,21 @@ export class Function extends Component implements Link.Linkable { reservedConcurrentExecutions: concurrency?.reserved, ...(isContainer ? { - packageType: "Image", - imageUri: imageAsset!.ref.apply( - (ref) => ref?.replace(":latest", ""), - ), - imageConfig: { - commands: [handler], - }, - } + packageType: "Image", + imageUri: imageAsset!.ref.apply( + (ref) => ref?.replace(":latest", ""), + ), + imageConfig: { + commands: [handler], + }, + } : { - packageType: "Zip", - s3Bucket: zipAsset!.bucket, - s3Key: zipAsset!.key, - handler: unsecret(handler), - runtime, - }), + packageType: "Zip", + s3Bucket: zipAsset!.bucket, + s3Key: zipAsset!.key, + handler: unsecret(handler), + runtime, + }), }, { parent }, ); @@ -1928,14 +1928,14 @@ export class Function extends Component implements Link.Linkable { ...transformed[1], ...(dev ? { - description: transformed[1].description - ? output(transformed[1].description).apply( - (v) => `${v.substring(0, 240)} (live)`, - ) - : "live", - runtime: "provided.al2023", - architectures: ["x86_64"], - } + description: transformed[1].description + ? output(transformed[1].description).apply( + (v) => `${v.substring(0, 240)} (live)`, + ) + : "live", + runtime: "provided.al2023", + architectures: ["x86_64"], + } : {}), }, transformed[2],