@cloudbase/manager-node 5.8.3 → 5.8.5
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +18 -0
- package/lib/cloudrun/index.js +9 -5
- package/lib/deploy/DeployOrchestrator.js +165 -287
- package/lib/deploy/FunctionDeployer.js +61 -33
- package/lib/deploy/function/artifact.js +55 -41
- package/lib/deploy/function/builders/cloud.js +13 -11
- package/lib/deploy/function/cam-preflight.js +2 -1
- package/lib/deploy/function/config-guard.js +181 -36
- package/lib/deploy/function/enterprise-tcr.js +7 -6
- package/lib/deploy/function/local-builder.js +10 -9
- package/lib/deploy/function/preflight.js +3 -2
- package/lib/projectValidator/index.js +0 -3
- package/package.json +1 -1
- package/types/cloudrun/index.d.ts +1 -1
- package/types/deploy/DeployOrchestrator.d.ts +9 -25
- package/types/deploy/FunctionDeployer.d.ts +15 -1
- package/types/deploy/function/artifact.d.ts +0 -5
- package/types/deploy/function/config-guard.d.ts +18 -0
- package/types/deploy/function/enterprise-tcr.d.ts +2 -2
- package/types/deploy/types.d.ts +76 -20
- package/types/projectValidator/types.d.ts +0 -1
- package/lib/deploy/StateStore.js +0 -328
- package/types/deploy/StateStore.d.ts +0 -174
|
@@ -14,7 +14,7 @@ var __exportStar = (this && this.__exportStar) || function(m, exports) {
|
|
|
14
14
|
for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
|
|
15
15
|
};
|
|
16
16
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
17
|
-
exports.IMAGE_PULL_GRANT_URL = exports.REQUIRED_IMAGE_PULL_POLICY = exports.SCF_PULL_IMAGE_ROLE = exports.isCamPermissionError = exports.runImagePullAuthPreflight = exports.runImageRemotePreflight = exports.runLocalPreflight = exports.createCloudBuildService = exports.buildImageOnCloud = exports.toCloudFunction = exports.createImageArtifactFromConfig = exports.createCodeArtifact = exports.toCurrentState = exports.createDeployPlan = exports.parseImageReference = exports.normalizeGatewayPath = exports.normalizeDeployConfig = exports.isCustomImageRuntime = exports.checkDeployConfig = exports.assertDeployConfig = exports.FunctionDeployer = void 0;
|
|
17
|
+
exports.IMAGE_PULL_GRANT_URL = exports.REQUIRED_IMAGE_PULL_POLICY = exports.SCF_PULL_IMAGE_ROLE = exports.isCamPermissionError = exports.runImagePullAuthPreflight = exports.runImageRemotePreflight = exports.runLocalPreflight = exports.createCloudBuildService = exports.buildImageOnCloud = exports.toCloudFunction = exports.createImageArtifactFromConfig = exports.createCodeArtifact = exports.toCurrentState = exports.createDeployPlan = exports.parseImageReference = exports.normalizeGatewayPath = exports.normalizeDeployConfig = exports.isCustomImageRuntime = exports.prepareMinimalDeployConfig = exports.getMissingDeployInputs = exports.applyMinimalDeployConfigDefaults = exports.checkDeployConfig = exports.assertDeployConfig = exports.FunctionDeployer = void 0;
|
|
18
18
|
const error_1 = require("../error");
|
|
19
19
|
const artifact_1 = require("./function/artifact");
|
|
20
20
|
const config_guard_1 = require("./function/config-guard");
|
|
@@ -95,7 +95,12 @@ class FunctionDeployer {
|
|
|
95
95
|
return;
|
|
96
96
|
}
|
|
97
97
|
const rule = this.buildPublicAccessRego(functionName);
|
|
98
|
-
|
|
98
|
+
// 云端 Rego 校验器要求首条有效语句(注释不计)必须是 package 声明。
|
|
99
|
+
// currentRego 非空时已含 package authz.user,直接追加规则体即可;
|
|
100
|
+
// 为空(新环境首次配置)时需补齐 package 声明,否则触发 2:1: package expected。
|
|
101
|
+
const mergedRego = currentRego.trim()
|
|
102
|
+
? `${currentRego.trim()}\n\n${rule}`
|
|
103
|
+
: `package authz.user\n\n${rule}`;
|
|
99
104
|
await permissionService.modifyEnvAuthzConfig({
|
|
100
105
|
key: AUTHZ_USER_REGO_KEY,
|
|
101
106
|
value: mergedRego
|
|
@@ -176,6 +181,24 @@ class FunctionDeployer {
|
|
|
176
181
|
checkConfig(config) {
|
|
177
182
|
return (0, config_guard_1.checkDeployConfig)(config);
|
|
178
183
|
}
|
|
184
|
+
/**
|
|
185
|
+
* 计算最小化部署配置的默认值,不执行网络或云端变更。
|
|
186
|
+
*/
|
|
187
|
+
applyMinimalConfigDefaults(config, context = {}) {
|
|
188
|
+
return (0, config_guard_1.applyMinimalDeployConfigDefaults)(config, context);
|
|
189
|
+
}
|
|
190
|
+
/**
|
|
191
|
+
* 返回最小化配置仍缺失的字段,不执行网络或云端变更。
|
|
192
|
+
*/
|
|
193
|
+
getMissingConfigInputs(config, context = {}) {
|
|
194
|
+
return (0, config_guard_1.getMissingDeployInputs)(config, context);
|
|
195
|
+
}
|
|
196
|
+
/**
|
|
197
|
+
* 应用安全默认值并返回缺失字段,供 CLI/MCP 逐步收集用户输入。
|
|
198
|
+
*/
|
|
199
|
+
prepareMinimalConfig(config, context = {}) {
|
|
200
|
+
return (0, config_guard_1.prepareMinimalDeployConfig)(config, context);
|
|
201
|
+
}
|
|
179
202
|
/**
|
|
180
203
|
* 生成部署计划
|
|
181
204
|
*
|
|
@@ -202,13 +225,14 @@ class FunctionDeployer {
|
|
|
202
225
|
* @param options 部署选项,dryRun 时只生成计划不做任何变更
|
|
203
226
|
*/
|
|
204
227
|
async deployFunction(config, options = {}) {
|
|
228
|
+
const deployConfig = config;
|
|
205
229
|
const startTime = Date.now();
|
|
206
230
|
const ctx = { steps: [], options };
|
|
207
231
|
const warnings = [];
|
|
208
|
-
const report = (0, config_guard_1.checkDeployConfig)(
|
|
232
|
+
const report = (0, config_guard_1.checkDeployConfig)(deployConfig);
|
|
209
233
|
this.appendWarnings(warnings, report);
|
|
210
234
|
const normalized = await this.runStep(ctx, 'validate', async () => {
|
|
211
|
-
return (0, config_guard_1.assertDeployConfig)(
|
|
235
|
+
return (0, config_guard_1.assertDeployConfig)(deployConfig);
|
|
212
236
|
});
|
|
213
237
|
const plan = await this.runStep(ctx, 'plan', async () => {
|
|
214
238
|
const current = await this.getCurrentFunction(normalized.name, normalized.codeSecret);
|
|
@@ -298,7 +322,7 @@ class FunctionDeployer {
|
|
|
298
322
|
* 将既有声明式调用补齐为完整部署配置
|
|
299
323
|
*/
|
|
300
324
|
withLegacyDeployContext(func, functionRootPath, functionPath) {
|
|
301
|
-
var _a, _b;
|
|
325
|
+
var _a, _b, _c, _d, _e;
|
|
302
326
|
const config = Object.assign({}, func);
|
|
303
327
|
const strategy = this.resolveStrategy(config);
|
|
304
328
|
if (functionPath) {
|
|
@@ -316,16 +340,14 @@ class FunctionDeployer {
|
|
|
316
340
|
(effectiveFunctionRootPath
|
|
317
341
|
? `${effectiveFunctionRootPath}/${config.name}`
|
|
318
342
|
: undefined);
|
|
319
|
-
|
|
320
|
-
|
|
343
|
+
const existingCwd = (_b = (_a = config.imageConfig) === null || _a === void 0 ? void 0 : _a.build) === null || _b === void 0 ? void 0 : _b.cwd;
|
|
344
|
+
if (buildCwd || existingCwd) {
|
|
345
|
+
config.imageConfig = Object.assign(Object.assign({}, (config.imageConfig || {})), { build: Object.assign(Object.assign({}, (((_c = config.imageConfig) === null || _c === void 0 ? void 0 : _c.build) || {})), { cwd: existingCwd || buildCwd }) });
|
|
321
346
|
}
|
|
322
347
|
}
|
|
323
|
-
//
|
|
324
|
-
if (strategy === 'image' && config.imageUri && !config.imageConfig) {
|
|
325
|
-
config.imageType = config.imageType || 'personal';
|
|
326
|
-
config.imageConfig = {
|
|
327
|
-
imageUri: config.imageUri
|
|
328
|
-
};
|
|
348
|
+
// 兼容旧声明式顶层 imageUri 字段,统一收敛到 imageConfig 契约
|
|
349
|
+
if (strategy === 'image' && config.imageUri && !((_d = config.imageConfig) === null || _d === void 0 ? void 0 : _d.imageUri)) {
|
|
350
|
+
config.imageConfig = Object.assign(Object.assign({ imageType: ((_e = config.imageConfig) === null || _e === void 0 ? void 0 : _e.imageType) || 'personal' }, (config.imageConfig || {})), { imageUri: config.imageUri });
|
|
329
351
|
delete config.imageUri;
|
|
330
352
|
}
|
|
331
353
|
return config;
|
|
@@ -448,9 +470,10 @@ class FunctionDeployer {
|
|
|
448
470
|
}
|
|
449
471
|
}
|
|
450
472
|
async prepareEnterpriseBuildConfig(ctx, config) {
|
|
451
|
-
const
|
|
452
|
-
const
|
|
453
|
-
|
|
473
|
+
const build = config.imageConfig.build;
|
|
474
|
+
const repository = build.repository || '';
|
|
475
|
+
const hasPreparedTarget = Boolean((config.imageConfig.registryId || build.registryId) && repository.split('/').length >= 3);
|
|
476
|
+
if (config.imageConfig.imageType !== 'enterprise' || hasPreparedTarget) {
|
|
454
477
|
return { config };
|
|
455
478
|
}
|
|
456
479
|
const prepared = await this.runLabeledStep(ctx, {
|
|
@@ -466,13 +489,14 @@ class FunctionDeployer {
|
|
|
466
489
|
}
|
|
467
490
|
async preparePersonalBuildConfig(ctx, config) {
|
|
468
491
|
var _a, _b, _c;
|
|
469
|
-
if (config.imageType !== 'personal') {
|
|
492
|
+
if (config.imageConfig.imageType !== 'personal') {
|
|
470
493
|
return config;
|
|
471
494
|
}
|
|
472
495
|
const envId = this.resolveEnvironmentId();
|
|
473
|
-
const
|
|
474
|
-
const
|
|
475
|
-
const
|
|
496
|
+
const build = config.imageConfig.build;
|
|
497
|
+
const configuredNamespace = (_a = build.namespace) === null || _a === void 0 ? void 0 : _a.trim();
|
|
498
|
+
const hasConfiguredRepository = Boolean((_b = build.repository) === null || _b === void 0 ? void 0 : _b.trim());
|
|
499
|
+
const configuredRepository = ((_c = build.repository) === null || _c === void 0 ? void 0 : _c.trim()) || config.name;
|
|
476
500
|
const parsedRepository = (0, config_guard_1.parseImageReference)(configuredRepository);
|
|
477
501
|
if (!parsedRepository || parsedRepository.tag || parsedRepository.digest) {
|
|
478
502
|
throw new error_1.CloudBaseError('个人版 TCR repository 不合法。', {
|
|
@@ -485,7 +509,7 @@ class FunctionDeployer {
|
|
|
485
509
|
const namespace = configuredNamespace || repositoryNamespace || envId;
|
|
486
510
|
const hasConfiguredNamespace = Boolean(configuredNamespace || repositoryNamespace);
|
|
487
511
|
const registry = parsedRepository.registry || personal_tcr_1.DEFAULT_PERSONAL_TCR_REGISTRY;
|
|
488
|
-
const credential =
|
|
512
|
+
const credential = build.registryCredential;
|
|
489
513
|
if (!(credential === null || credential === void 0 ? void 0 : credential.username) || !credential.password) {
|
|
490
514
|
throw new error_1.CloudBaseError('个人版 TCR 构建缺少推送凭证。', {
|
|
491
515
|
code: types_1.FUNCTION_DEPLOY_ERROR.CLOUD_REGISTRY_CREDENTIAL_MISSING
|
|
@@ -502,7 +526,7 @@ class FunctionDeployer {
|
|
|
502
526
|
})
|
|
503
527
|
});
|
|
504
528
|
const targetRepository = `${registry}/${namespace}/${repository}`;
|
|
505
|
-
const preparedConfig = Object.assign(Object.assign({}, config), {
|
|
529
|
+
const preparedConfig = Object.assign(Object.assign({}, config), { imageConfig: Object.assign(Object.assign({}, config.imageConfig), { build: Object.assign(Object.assign({}, build), { namespace, repository: targetRepository, registryCredential: credential }) }) });
|
|
506
530
|
return preparedConfig;
|
|
507
531
|
}
|
|
508
532
|
/**
|
|
@@ -520,9 +544,9 @@ class FunctionDeployer {
|
|
|
520
544
|
// 企业版登录凭证在触发 CloudApp 构建前换取,构建容器只消费 Secrets,
|
|
521
545
|
// 不再自行签名调用 TCR API。
|
|
522
546
|
const cloudRegistryId = ((_a = prepared.target) === null || _a === void 0 ? void 0 : _a.registryId) ||
|
|
523
|
-
cloudConfig.build.registryId ||
|
|
524
|
-
cloudConfig.registryId;
|
|
525
|
-
const enterpriseCredential = cloudConfig.imageType === 'enterprise' && cloudRegistryId
|
|
547
|
+
cloudConfig.imageConfig.build.registryId ||
|
|
548
|
+
cloudConfig.imageConfig.registryId;
|
|
549
|
+
const enterpriseCredential = cloudConfig.imageConfig.imageType === 'enterprise' && cloudRegistryId
|
|
526
550
|
? await this.runLabeledStep(ctx, {
|
|
527
551
|
stage: 'preflight',
|
|
528
552
|
label: '获取企业版 TCR 临时登录凭证',
|
|
@@ -560,7 +584,7 @@ class FunctionDeployer {
|
|
|
560
584
|
try {
|
|
561
585
|
if (credential) {
|
|
562
586
|
await this.runStep(ctx, 'login', async () => {
|
|
563
|
-
await (0, local_builder_1.loginDockerRegistry)(this.resolveRegistryFromRepository(localConfig.build.repository), credential, { deps: this.localBuilderDeps, commandOptions });
|
|
587
|
+
await (0, local_builder_1.loginDockerRegistry)(this.resolveRegistryFromRepository(localConfig.imageConfig.build.repository), credential, { deps: this.localBuilderDeps, commandOptions });
|
|
564
588
|
});
|
|
565
589
|
}
|
|
566
590
|
const buildResult = await this.runStep(ctx, 'build', async () => {
|
|
@@ -577,14 +601,14 @@ class FunctionDeployer {
|
|
|
577
601
|
message: line
|
|
578
602
|
}), { deps: this.localBuilderDeps, commandOptions });
|
|
579
603
|
});
|
|
580
|
-
if (localConfig.imageType === 'personal') {
|
|
604
|
+
if (localConfig.imageConfig.imageType === 'personal') {
|
|
581
605
|
await this.runLabeledStep(ctx, {
|
|
582
606
|
stage: 'push',
|
|
583
607
|
label: '清理历史镜像标签',
|
|
584
608
|
handler: () => this.personalTcrServiceFactory().cleanupTags({
|
|
585
|
-
namespace: localConfig.build.namespace,
|
|
586
|
-
repository: localConfig.build.repository,
|
|
587
|
-
retain: localConfig.build.retainedTags
|
|
609
|
+
namespace: localConfig.imageConfig.build.namespace,
|
|
610
|
+
repository: localConfig.imageConfig.build.repository,
|
|
611
|
+
retain: localConfig.imageConfig.build.retainedTags
|
|
588
612
|
})
|
|
589
613
|
});
|
|
590
614
|
}
|
|
@@ -603,9 +627,10 @@ class FunctionDeployer {
|
|
|
603
627
|
}
|
|
604
628
|
async resolveLocalRegistryCredential(config) {
|
|
605
629
|
var _a, _b, _c;
|
|
606
|
-
const
|
|
630
|
+
const build = config.imageConfig.build;
|
|
631
|
+
const imageType = (_a = config.imageConfig.imageType) !== null && _a !== void 0 ? _a : (((_b = config.imageConfig.registryId) !== null && _b !== void 0 ? _b : build.registryId) ? 'enterprise' : 'personal');
|
|
607
632
|
if (imageType === 'enterprise') {
|
|
608
|
-
const registryId = (_c = config.registryId) !== null && _c !== void 0 ? _c :
|
|
633
|
+
const registryId = (_c = config.imageConfig.registryId) !== null && _c !== void 0 ? _c : build.registryId;
|
|
609
634
|
if (!registryId) {
|
|
610
635
|
throw new error_1.CloudBaseError('企业版 TCR local 构建缺少 registryId。', {
|
|
611
636
|
code: types_1.FUNCTION_DEPLOY_ERROR.IMAGE_REGISTRY_ID_MISSING
|
|
@@ -614,7 +639,7 @@ class FunctionDeployer {
|
|
|
614
639
|
const credential = await (0, enterprise_tcr_1.createEnterpriseTcrCredential)(this.tcrServiceFactory(), registryId);
|
|
615
640
|
return { username: credential.username, secret: credential.token };
|
|
616
641
|
}
|
|
617
|
-
const credential =
|
|
642
|
+
const credential = build.registryCredential;
|
|
618
643
|
if (!credential) {
|
|
619
644
|
return undefined;
|
|
620
645
|
}
|
|
@@ -809,6 +834,9 @@ __exportStar(require("./types"), exports);
|
|
|
809
834
|
var config_guard_2 = require("./function/config-guard");
|
|
810
835
|
Object.defineProperty(exports, "assertDeployConfig", { enumerable: true, get: function () { return config_guard_2.assertDeployConfig; } });
|
|
811
836
|
Object.defineProperty(exports, "checkDeployConfig", { enumerable: true, get: function () { return config_guard_2.checkDeployConfig; } });
|
|
837
|
+
Object.defineProperty(exports, "applyMinimalDeployConfigDefaults", { enumerable: true, get: function () { return config_guard_2.applyMinimalDeployConfigDefaults; } });
|
|
838
|
+
Object.defineProperty(exports, "getMissingDeployInputs", { enumerable: true, get: function () { return config_guard_2.getMissingDeployInputs; } });
|
|
839
|
+
Object.defineProperty(exports, "prepareMinimalDeployConfig", { enumerable: true, get: function () { return config_guard_2.prepareMinimalDeployConfig; } });
|
|
812
840
|
Object.defineProperty(exports, "isCustomImageRuntime", { enumerable: true, get: function () { return config_guard_2.isCustomImageRuntime; } });
|
|
813
841
|
Object.defineProperty(exports, "normalizeDeployConfig", { enumerable: true, get: function () { return config_guard_2.normalizeDeployConfig; } });
|
|
814
842
|
Object.defineProperty(exports, "normalizeGatewayPath", { enumerable: true, get: function () { return config_guard_2.normalizeGatewayPath; } });
|
|
@@ -5,12 +5,30 @@ exports.createImageArtifactFromConfig = createImageArtifactFromConfig;
|
|
|
5
5
|
exports.createImageArtifactFromBuild = createImageArtifactFromBuild;
|
|
6
6
|
exports.createImageArtifactFromCloudBuild = createImageArtifactFromCloudBuild;
|
|
7
7
|
exports.toCloudFunction = toCloudFunction;
|
|
8
|
+
const error_1 = require("../../error");
|
|
8
9
|
const types_1 = require("../types");
|
|
9
10
|
/**
|
|
10
|
-
*
|
|
11
|
+
* 解析构建类镜像部署物的 SCF RegistryId
|
|
11
12
|
*
|
|
12
|
-
*
|
|
13
|
+
* 个人版镜像(personal,如个人版 CCR)不携带 registryId;企业版优先取
|
|
14
|
+
* imageConfig.registryId,回退到构建配置 imageConfig.build.registryId。
|
|
15
|
+
* 正常流程下企业版 registryId 已由 prepareEnterpriseTcrTarget 在构建前解析补齐,
|
|
16
|
+
* 此处对缺失场景 fail-fast 并给出明确错误:避免产出缺少 RegistryId 的部署物,
|
|
17
|
+
* 导致后续 SCF 拉取企业版镜像时失败且难以排查。
|
|
13
18
|
*/
|
|
19
|
+
function resolveBuildRegistryId(imageConfig) {
|
|
20
|
+
var _a, _b;
|
|
21
|
+
if (imageConfig.imageType !== 'enterprise') {
|
|
22
|
+
return undefined;
|
|
23
|
+
}
|
|
24
|
+
const registryId = (_a = imageConfig.registryId) !== null && _a !== void 0 ? _a : (_b = imageConfig.build) === null || _b === void 0 ? void 0 : _b.registryId;
|
|
25
|
+
if (!registryId) {
|
|
26
|
+
throw new error_1.CloudBaseError('企业版镜像缺少 TCR 实例 ID(registryId),无法生成镜像部署物。', {
|
|
27
|
+
code: types_1.FUNCTION_DEPLOY_ERROR.IMAGE_REGISTRY_ID_MISSING
|
|
28
|
+
});
|
|
29
|
+
}
|
|
30
|
+
return registryId;
|
|
31
|
+
}
|
|
14
32
|
/** 由本地代码来源构造代码类部署物 */
|
|
15
33
|
function createCodeArtifact(config) {
|
|
16
34
|
const functionRootPath = 'functionRootPath' in config ? config.functionRootPath : undefined;
|
|
@@ -28,28 +46,26 @@ function createCodeArtifact(config) {
|
|
|
28
46
|
}
|
|
29
47
|
/** 由已有镜像配置构造镜像类部署物 */
|
|
30
48
|
function createImageArtifactFromConfig(config) {
|
|
31
|
-
var _a
|
|
49
|
+
var _a;
|
|
32
50
|
const { imageConfig } = config;
|
|
33
|
-
//
|
|
34
|
-
// 与 local/cloud 策略一致;imageConfig 内的同名字段仅作向后兼容兜底。
|
|
51
|
+
// 直接读取 cloudbaserc 嵌套形状:镜像字段全部位于 imageConfig。
|
|
35
52
|
// 个人版镜像(personal,如个人版 CCR)不应携带 registryId。
|
|
36
|
-
const
|
|
37
|
-
const
|
|
38
|
-
const registryId = imageType === 'enterprise' ? configuredRegistryId : undefined;
|
|
53
|
+
const imageType = imageConfig.imageType;
|
|
54
|
+
const registryId = imageType === 'enterprise' ? imageConfig.registryId : undefined;
|
|
39
55
|
return {
|
|
40
56
|
kind: 'image',
|
|
41
57
|
deployMode: 'image',
|
|
42
58
|
imageUri: imageConfig.imageUri,
|
|
43
59
|
imageType,
|
|
44
60
|
registryId,
|
|
45
|
-
imagePort: types_1.IMAGE_FUNCTION_PORT,
|
|
61
|
+
imagePort: (_a = imageConfig.imagePort) !== null && _a !== void 0 ? _a : types_1.IMAGE_FUNCTION_PORT,
|
|
46
62
|
effectiveStrategy: 'image',
|
|
47
|
-
entryPoint:
|
|
48
|
-
command:
|
|
49
|
-
args:
|
|
50
|
-
commandList:
|
|
51
|
-
argsList:
|
|
52
|
-
containerImageAccelerate:
|
|
63
|
+
entryPoint: imageConfig.entryPoint,
|
|
64
|
+
command: imageConfig.command,
|
|
65
|
+
args: imageConfig.args,
|
|
66
|
+
commandList: imageConfig.commandList,
|
|
67
|
+
argsList: imageConfig.argsList,
|
|
68
|
+
containerImageAccelerate: imageConfig.containerImageAccelerate
|
|
53
69
|
};
|
|
54
70
|
}
|
|
55
71
|
/**
|
|
@@ -59,11 +75,10 @@ function createImageArtifactFromConfig(config) {
|
|
|
59
75
|
* 此处仅承载最终 imageUri/digest 与容器启动配置,之后复用镜像部署链。
|
|
60
76
|
*/
|
|
61
77
|
function createImageArtifactFromBuild(config, build) {
|
|
62
|
-
var _a
|
|
63
|
-
const
|
|
64
|
-
const
|
|
65
|
-
|
|
66
|
-
: undefined;
|
|
78
|
+
var _a;
|
|
79
|
+
const { imageConfig } = config;
|
|
80
|
+
const imageType = imageConfig.imageType;
|
|
81
|
+
const registryId = resolveBuildRegistryId(imageConfig);
|
|
67
82
|
return {
|
|
68
83
|
kind: 'image',
|
|
69
84
|
deployMode: 'image',
|
|
@@ -71,14 +86,14 @@ function createImageArtifactFromBuild(config, build) {
|
|
|
71
86
|
imageDigest: build.imageDigest,
|
|
72
87
|
imageType,
|
|
73
88
|
registryId,
|
|
74
|
-
imagePort: types_1.IMAGE_FUNCTION_PORT,
|
|
89
|
+
imagePort: (_a = imageConfig.imagePort) !== null && _a !== void 0 ? _a : types_1.IMAGE_FUNCTION_PORT,
|
|
75
90
|
effectiveStrategy: 'local',
|
|
76
|
-
entryPoint:
|
|
77
|
-
command:
|
|
78
|
-
args:
|
|
79
|
-
commandList:
|
|
80
|
-
argsList:
|
|
81
|
-
containerImageAccelerate:
|
|
91
|
+
entryPoint: imageConfig.entryPoint,
|
|
92
|
+
command: imageConfig.command,
|
|
93
|
+
args: imageConfig.args,
|
|
94
|
+
commandList: imageConfig.commandList,
|
|
95
|
+
argsList: imageConfig.argsList,
|
|
96
|
+
containerImageAccelerate: imageConfig.containerImageAccelerate
|
|
82
97
|
};
|
|
83
98
|
}
|
|
84
99
|
/**
|
|
@@ -89,30 +104,29 @@ function createImageArtifactFromBuild(config, build) {
|
|
|
89
104
|
* effectiveStrategy 标记为 cloud,便于结果层如实回传实际生效的策略。
|
|
90
105
|
*/
|
|
91
106
|
function createImageArtifactFromCloudBuild(config, build) {
|
|
92
|
-
var _a
|
|
93
|
-
const
|
|
94
|
-
const
|
|
95
|
-
|
|
96
|
-
|
|
107
|
+
var _a;
|
|
108
|
+
const { imageConfig } = config;
|
|
109
|
+
const imageType = imageConfig.imageType;
|
|
110
|
+
// 云端构建默认推送到个人版 TCR(CCR);企业版实例 ID 位于 imageConfig.build.registryId,
|
|
111
|
+
// 需继续透传到 Stage B 的 SCF ImageConfig,避免构建成功后拉取镜像时丢失 RegistryId。
|
|
112
|
+
const registryId = resolveBuildRegistryId(imageConfig);
|
|
97
113
|
return {
|
|
98
114
|
kind: 'image',
|
|
99
115
|
deployMode: 'image',
|
|
100
116
|
imageUri: build.imageUri,
|
|
101
117
|
imageDigest: build.imageDigest,
|
|
102
|
-
// 云端构建默认推送到个人版 TCR(CCR);企业版实例 ID 位于 build.registryId,
|
|
103
|
-
// 需继续透传到 Stage B 的 SCF ImageConfig,避免构建成功后拉取镜像时丢失 RegistryId。
|
|
104
118
|
imageType,
|
|
105
119
|
registryId,
|
|
106
|
-
imagePort: types_1.IMAGE_FUNCTION_PORT,
|
|
120
|
+
imagePort: (_a = imageConfig.imagePort) !== null && _a !== void 0 ? _a : types_1.IMAGE_FUNCTION_PORT,
|
|
107
121
|
effectiveStrategy: 'cloud',
|
|
108
122
|
buildId: build.buildId,
|
|
109
123
|
logsUrl: build.logsUrl,
|
|
110
|
-
entryPoint:
|
|
111
|
-
command:
|
|
112
|
-
args:
|
|
113
|
-
commandList:
|
|
114
|
-
argsList:
|
|
115
|
-
containerImageAccelerate:
|
|
124
|
+
entryPoint: imageConfig.entryPoint,
|
|
125
|
+
command: imageConfig.command,
|
|
126
|
+
args: imageConfig.args,
|
|
127
|
+
commandList: imageConfig.commandList,
|
|
128
|
+
argsList: imageConfig.argsList,
|
|
129
|
+
containerImageAccelerate: imageConfig.containerImageAccelerate
|
|
116
130
|
};
|
|
117
131
|
}
|
|
118
132
|
/** 将构建产出的 tag 地址与 digest 合成为 SCF 支持的不可变镜像引用 */
|
|
@@ -109,11 +109,12 @@ function assertSafeBuildArgs(buildArgs) {
|
|
|
109
109
|
/** 个人版 CCR 默认域名 */
|
|
110
110
|
const DEFAULT_PERSONAL_REGISTRY = 'ccr.ccs.tencentyun.com';
|
|
111
111
|
function resolveTarget(config) {
|
|
112
|
-
const build = config.build;
|
|
112
|
+
const build = config.imageConfig.build;
|
|
113
|
+
const imageType = config.imageConfig.imageType;
|
|
113
114
|
const repository = (build.repository || config.name).trim();
|
|
114
115
|
const rawRegistryId = build.registryId;
|
|
115
116
|
const registryId = typeof rawRegistryId === 'string' ? rawRegistryId.trim() : rawRegistryId;
|
|
116
|
-
const isEnterprise =
|
|
117
|
+
const isEnterprise = imageType === 'enterprise' || Boolean(registryId);
|
|
117
118
|
// CloudApp custom 构建与推送必须使用同一个平台版本 tag。
|
|
118
119
|
// 若允许自定义 tag,build-image 会构建自定义 tag,而固定推送脚本会推
|
|
119
120
|
// $CLOUDBASE_VERSION_NAME,最终必然找不到本地镜像。
|
|
@@ -155,10 +156,10 @@ function resolveTarget(config) {
|
|
|
155
156
|
throw new error_1.CloudBaseError('cloud 策略缺少 TCR 命名空间,请配置 build.namespace 或在完整 repository 中声明', { code: types_1.FUNCTION_DEPLOY_ERROR.BUILD_REPOSITORY_INVALID });
|
|
156
157
|
}
|
|
157
158
|
assertSafeRegistryToken(namespace, 'TCR namespace');
|
|
158
|
-
if (
|
|
159
|
+
if (imageType === 'personal' && registryId) {
|
|
159
160
|
throw new error_1.CloudBaseError('cloud 策略的 personal 镜像不能配置 build.registryId;请移除该字段或改用 enterprise', { code: types_1.FUNCTION_DEPLOY_ERROR.IMAGE_TYPE_INVALID });
|
|
160
161
|
}
|
|
161
|
-
if (
|
|
162
|
+
if (imageType === 'enterprise') {
|
|
162
163
|
if (rawRegistryId === undefined || rawRegistryId === null) {
|
|
163
164
|
throw new error_1.CloudBaseError('cloud 策略的企业版 TCR 未配置 build.registryId;如果当前没有企业版实例,请改用 imageType=personal', { code: types_1.FUNCTION_DEPLOY_ERROR.IMAGE_REGISTRY_ID_MISSING });
|
|
164
165
|
}
|
|
@@ -183,9 +184,10 @@ function resolveTarget(config) {
|
|
|
183
184
|
* CustomSteps 只包含 SDK 固定命令和经过白名单校验的 build arg key。
|
|
184
185
|
*/
|
|
185
186
|
function resolveCloudBuildOptions(config) {
|
|
186
|
-
const
|
|
187
|
-
const
|
|
188
|
-
const
|
|
187
|
+
const build = config.imageConfig.build;
|
|
188
|
+
const dockerfile = build.dockerfile || types_1.DEFAULT_DOCKERFILE;
|
|
189
|
+
const platform = build.platform || types_1.DEFAULT_IMAGE_PLATFORM;
|
|
190
|
+
const buildArgs = build.buildArgs || {};
|
|
189
191
|
assertSafeDockerfile(dockerfile);
|
|
190
192
|
if (platform !== types_1.DEFAULT_IMAGE_PLATFORM) {
|
|
191
193
|
throw new error_1.CloudBaseError(`当前仅支持构建 ${types_1.DEFAULT_IMAGE_PLATFORM} 镜像`, {
|
|
@@ -197,7 +199,7 @@ function resolveCloudBuildOptions(config) {
|
|
|
197
199
|
dockerfile,
|
|
198
200
|
platform,
|
|
199
201
|
buildArgs,
|
|
200
|
-
forceBuild:
|
|
202
|
+
forceBuild: build.forceBuild === true
|
|
201
203
|
};
|
|
202
204
|
}
|
|
203
205
|
/**
|
|
@@ -270,9 +272,9 @@ function buildRegistryCredentials(config, target, enterpriseCredential) {
|
|
|
270
272
|
]
|
|
271
273
|
};
|
|
272
274
|
}
|
|
273
|
-
const credential = config.build.registryCredential;
|
|
275
|
+
const credential = config.imageConfig.build.registryCredential;
|
|
274
276
|
if (!credential) {
|
|
275
|
-
throw new error_1.CloudBaseError('个人版 TCR 云端构建缺少 build.registryCredential;请在 cloudbaserc 中显式声明 ' +
|
|
277
|
+
throw new error_1.CloudBaseError('个人版 TCR 云端构建缺少 imageConfig.build.registryCredential;请在 cloudbaserc 中显式声明 ' +
|
|
276
278
|
'username/password,推荐分别使用 "{{env.TCB_TCR_USERNAME}}" 和 ' +
|
|
277
279
|
'"{{env.TCB_TCR_PASSWORD}}"', { code: types_1.FUNCTION_DEPLOY_ERROR.CLOUD_REGISTRY_CREDENTIAL_MISSING });
|
|
278
280
|
}
|
|
@@ -296,7 +298,7 @@ function buildRegistryCredentials(config, target, enterpriseCredential) {
|
|
|
296
298
|
};
|
|
297
299
|
}
|
|
298
300
|
function resolveCloudBuildContext(config, dockerfile) {
|
|
299
|
-
const cwd = path_1.default.resolve(config.build.cwd || config.functionPath || process.cwd());
|
|
301
|
+
const cwd = path_1.default.resolve(config.imageConfig.build.cwd || config.functionPath || process.cwd());
|
|
300
302
|
const dockerfilePath = path_1.default.resolve(cwd, dockerfile);
|
|
301
303
|
let stat = null;
|
|
302
304
|
try {
|
|
@@ -74,9 +74,10 @@ function needsImagePullAuth(config) {
|
|
|
74
74
|
}
|
|
75
75
|
/** 只有企业版 cloud 策略需要 CloudApp 向企业版 TCR 推送镜像 */
|
|
76
76
|
function needsEnterpriseTcrPushAuth(config) {
|
|
77
|
+
var _a;
|
|
77
78
|
return (config.type === 'HTTP' &&
|
|
78
79
|
config.buildStrategy === 'cloud' &&
|
|
79
|
-
config.imageType === 'enterprise');
|
|
80
|
+
((_a = config.imageConfig) === null || _a === void 0 ? void 0 : _a.imageType) === 'enterprise');
|
|
80
81
|
}
|
|
81
82
|
function resolveRequirements(config) {
|
|
82
83
|
const requirements = [];
|