Skip to content

Commit

Permalink
feat: store code package to oss for large size of code package (#9)
Browse files Browse the repository at this point in the history
#Context

- store code package to oss for large size of code package 
- create bucket resource when needed
- upload zip code to bucket
- assign bucket link to fc code

Refers #5

---------

Signed-off-by: seven <[email protected]>
  • Loading branch information
Blankll authored Dec 2, 2024
1 parent e4d68cf commit af91ea7
Show file tree
Hide file tree
Showing 11 changed files with 7,722 additions and 4,432 deletions.
11,686 changes: 7,265 additions & 4,421 deletions package-lock.json

Large diffs are not rendered by default.

4 changes: 3 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,8 @@
"@alicloud/ros-cdk-apigateway": "^1.4.0",
"@alicloud/ros-cdk-core": "^1.4.0",
"@alicloud/ros-cdk-fc3": "^1.4.0",
"@alicloud/ros-cdk-oss": "^1.4.0",
"@alicloud/ros-cdk-ossdeployment": "^1.4.0",
"@alicloud/ros-cdk-ram": "^1.4.0",
"@alicloud/ros20190910": "^3.5.0",
"ajv": "^8.17.1",
Expand All @@ -67,8 +69,8 @@
"devDependencies": {
"@types/i18n": "^0.13.12",
"@types/jest": "^29.5.13",
"@types/node": "^22.7.4",
"@types/lodash": "^4.17.12",
"@types/node": "^22.7.4",
"@typescript-eslint/eslint-plugin": "^8.8.0",
"@typescript-eslint/parser": "^8.8.0",
"eslint": "^8.57.1",
Expand Down
1 change: 1 addition & 0 deletions src/common/constants.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export const CODE_ZIP_SIZE_LIMIT = 15 * 1024 * 1024;
24 changes: 24 additions & 0 deletions src/common/iacHelper.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,13 +2,37 @@ import path from 'node:path';
import fs from 'node:fs';
import * as ros from '@alicloud/ros-cdk-core';
import { ActionContext } from '../types';
import * as ossDeployment from '@alicloud/ros-cdk-ossdeployment';
import crypto from 'node:crypto';

export const resolveCode = (location: string): string => {
const filePath = path.resolve(process.cwd(), location);
const fileContent = fs.readFileSync(filePath);

return fileContent.toString('base64');
};
export const readCodeSize = (location: string): number => {
const filePath = path.resolve(process.cwd(), location);
const stats = fs.statSync(filePath);
return stats.size;
};

export const getFileSource = (
fcName: string,
location: string,
): { source: ossDeployment.ISource; objectKey: string } => {
const filePath = path.resolve(process.cwd(), location);
if (fs.lstatSync(filePath).isDirectory()) {
throw new Error('The provided path is a directory, not a file.');
}

const hash = crypto.createHash('md5').update(fs.readFileSync(filePath)).digest('hex');

const objectKey = `${fcName}/${hash}.${filePath.split('.').pop()}`;
const source = ossDeployment.Source.asset(filePath, {}, objectKey);

return { source, objectKey };
};

const evalCtx = (value: string, ctx: ActionContext): string => {
const containsStage = value.match(/\$\{ctx.\w+}/);
Expand Down
1 change: 1 addition & 0 deletions src/common/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,3 +4,4 @@ export * from './getVersion';
export * from './rosClient';
export * from './actionContext';
export * from './iacHelper';
export * from './constants';
53 changes: 49 additions & 4 deletions src/stack/iacStack.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,18 @@ import * as ros from '@alicloud/ros-cdk-core';
import { RosParameterType } from '@alicloud/ros-cdk-core';
import { ActionContext, EventTypes, ServerlessIac } from '../types';
import * as fc from '@alicloud/ros-cdk-fc3';
import { RosFunction } from '@alicloud/ros-cdk-fc3/lib/fc3.generated';
import * as ram from '@alicloud/ros-cdk-ram';
import * as agw from '@alicloud/ros-cdk-apigateway';
import { replaceReference, resolveCode } from '../common';
import * as oss from '@alicloud/ros-cdk-oss';
import * as ossDeployment from '@alicloud/ros-cdk-ossdeployment';
import {
CODE_ZIP_SIZE_LIMIT,
getFileSource,
readCodeSize,
replaceReference,
resolveCode,
} from '../common';

export class IacStack extends ros.Stack {
private readonly service: string;
Expand Down Expand Up @@ -41,7 +50,45 @@ export class IacStack extends ros.Stack {
replaceReference(`${this.service} stack`, context),
);

const fileSources = iac.functions
.filter(({ code }) => readCodeSize(code) > CODE_ZIP_SIZE_LIMIT)
.map(({ code, name }) => ({ fcName: name, ...getFileSource(name, code) }));

let destinationBucket: oss.Bucket;
if (fileSources.length > 0) {
// creat oss to store code
destinationBucket = new oss.Bucket(
this,
replaceReference(`${this.service}_artifacts_bucket`, context),
{
bucketName: replaceReference(`${this.service}-artifacts-bucket`, context),
serverSideEncryptionConfiguration: { sseAlgorithm: 'KMS' },
},
true,
);
new ossDeployment.BucketDeployment(
this,
`${this.service}_artifacts_code_deployment`,
{
sources: fileSources.map(({ source }) => source),
destinationBucket,
timeout: 300,
logMonitoring: false, // 是否开启日志监控,设为false则不开启
},
true,
);
}

iac.functions.forEach((fnc) => {
let code: RosFunction.CodeProperty = {
zipFile: resolveCode(fnc.code),
};
if (readCodeSize(fnc.code) > CODE_ZIP_SIZE_LIMIT) {
code = {
ossBucketName: destinationBucket.attrName,
ossObjectName: fileSources.find(({ fcName }) => fcName === fnc.name)?.objectKey,
};
}
new fc.RosFunction(
this,
fnc.key,
Expand All @@ -52,9 +99,7 @@ export class IacStack extends ros.Stack {
memorySize: replaceReference(fnc.memory, context),
timeout: replaceReference(fnc.timeout, context),
environmentVariables: replaceReference(fnc.environment, context),
code: {
zipFile: resolveCode(fnc.code),
},
code,
},
true,
);
Expand Down
27 changes: 27 additions & 0 deletions tests/common/iacHelper.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
import * as ossDeployment from '@alicloud/ros-cdk-ossdeployment';
import { getFileSource } from '../../src/common';
import fs from 'node:fs';

jest.mock('@alicloud/ros-cdk-ossdeployment');

const fcName = 'testFunction';
const location = 'tests/fixtures/artifacts/artifact.zip';

describe('getFileSource', () => {
it('should return the correct ossDeployment source', () => {
getFileSource(fcName, location);
expect(ossDeployment.Source.asset).toHaveBeenCalledWith(
`${process.cwd()}/${location}`,
{},
`${fcName}/50861cd99a3a678356030f5f189300af.zip`,
);
});

it('should throw an error if the path is a directory', () => {
jest.spyOn(fs, 'lstatSync').mockReturnValue({ isDirectory: () => true } as fs.Stats);

expect(() => getFileSource(fcName, location)).toThrow(
'The provided path is a directory, not a file.',
);
});
});
Binary file added tests/fixtures/artifacts/artifact.zip
Binary file not shown.
Binary file added tests/fixtures/artifacts/large-artifact.zip
Binary file not shown.
Loading

0 comments on commit af91ea7

Please sign in to comment.