refactor: model runtime lanes by node config
This commit is contained in:
+9
-2
@@ -79,9 +79,15 @@ profiles:
|
|||||||
enabled: false
|
enabled: false
|
||||||
namespace: hwlab-prod
|
namespace: hwlab-prod
|
||||||
notes: Reserved placeholder only. PROD deployment and acceptance are explicitly out of scope.
|
notes: Reserved placeholder only. PROD deployment and acceptance are explicitly out of scope.
|
||||||
|
nodes:
|
||||||
|
G14:
|
||||||
|
gitopsRoot: deploy/gitops/g14
|
||||||
|
sourceRepo: git@github.com:pikasTech/HWLAB.git
|
||||||
|
publicHost: 74.48.78.17
|
||||||
lanes:
|
lanes:
|
||||||
v02:
|
v02:
|
||||||
name: v0.2
|
name: v0.2
|
||||||
|
node: G14
|
||||||
sourceBranch: v0.2
|
sourceBranch: v0.2
|
||||||
gitopsBranch: v0.2-gitops
|
gitopsBranch: v0.2-gitops
|
||||||
namespace: hwlab-v02
|
namespace: hwlab-v02
|
||||||
@@ -92,7 +98,7 @@ lanes:
|
|||||||
legacyFrontend: http://74.48.78.17:19666
|
legacyFrontend: http://74.48.78.17:19666
|
||||||
legacyApi: http://74.48.78.17:19667
|
legacyApi: http://74.48.78.17:19667
|
||||||
artifactCatalog: deploy/artifact-catalog.v02.json
|
artifactCatalog: deploy/artifact-catalog.v02.json
|
||||||
runtimePath: deploy/gitops/g14/runtime-v02
|
runtimePath: runtime-v02
|
||||||
imageTagMode: full
|
imageTagMode: full
|
||||||
envReuseServices:
|
envReuseServices:
|
||||||
- hwlab-cloud-api
|
- hwlab-cloud-api
|
||||||
@@ -232,6 +238,7 @@ lanes:
|
|||||||
HWLAB_CODE_AGENT_AGENTRUN_REPO_URL: http://git-mirror-http.devops-infra.svc.cluster.local/pikasTech/HWLAB.git
|
HWLAB_CODE_AGENT_AGENTRUN_REPO_URL: http://git-mirror-http.devops-infra.svc.cluster.local/pikasTech/HWLAB.git
|
||||||
v03:
|
v03:
|
||||||
name: v0.3
|
name: v0.3
|
||||||
|
node: G14
|
||||||
sourceBranch: v0.3
|
sourceBranch: v0.3
|
||||||
gitopsBranch: v0.3-gitops
|
gitopsBranch: v0.3-gitops
|
||||||
namespace: hwlab-v03
|
namespace: hwlab-v03
|
||||||
@@ -242,7 +249,7 @@ lanes:
|
|||||||
legacyFrontend: http://74.48.78.17:19766
|
legacyFrontend: http://74.48.78.17:19766
|
||||||
legacyApi: http://74.48.78.17:19767
|
legacyApi: http://74.48.78.17:19767
|
||||||
artifactCatalog: deploy/artifact-catalog.v03.json
|
artifactCatalog: deploy/artifact-catalog.v03.json
|
||||||
runtimePath: deploy/gitops/g14/runtime-v03
|
runtimePath: runtime-v03
|
||||||
imageTagMode: full
|
imageTagMode: full
|
||||||
envReuseServices:
|
envReuseServices:
|
||||||
- hwlab-cloud-api
|
- hwlab-cloud-api
|
||||||
|
|||||||
@@ -15,7 +15,7 @@ import {
|
|||||||
runtimeLaneMirrorSpecs,
|
runtimeLaneMirrorSpecs,
|
||||||
runtimeLaneConfig,
|
runtimeLaneConfig,
|
||||||
versionNameForRuntimeLane
|
versionNameForRuntimeLane
|
||||||
} from "./src/g14-gitops-lane.ts";
|
} from "./src/runtime-lane.ts";
|
||||||
import { readStructuredFile } from "./src/structured-config.mjs";
|
import { readStructuredFile } from "./src/structured-config.mjs";
|
||||||
|
|
||||||
const execFileAsync = promisify(execFile);
|
const execFileAsync = promisify(execFile);
|
||||||
@@ -136,7 +136,7 @@ const forbiddenCiFragments = [
|
|||||||
];
|
];
|
||||||
const scanTargets = [
|
const scanTargets = [
|
||||||
"scripts/g14-gitops-render.mjs",
|
"scripts/g14-gitops-render.mjs",
|
||||||
"scripts/src/g14-gitops-lane.ts",
|
"scripts/src/runtime-lane.ts",
|
||||||
"scripts/artifact-publish.mjs",
|
"scripts/artifact-publish.mjs",
|
||||||
"scripts/g14-artifact-publish.mjs",
|
"scripts/g14-artifact-publish.mjs",
|
||||||
"scripts/src/g14-ci-plan-lib.mjs",
|
"scripts/src/g14-ci-plan-lib.mjs",
|
||||||
@@ -203,6 +203,7 @@ function proxyEnv() {
|
|||||||
function parseArgs(argv) {
|
function parseArgs(argv) {
|
||||||
const args = {
|
const args = {
|
||||||
lane: process.env.HWLAB_GITOPS_LANE || "g14",
|
lane: process.env.HWLAB_GITOPS_LANE || "g14",
|
||||||
|
nodeId: process.env.HWLAB_NODE_ID || "G14",
|
||||||
outDir: defaultOutDir,
|
outDir: defaultOutDir,
|
||||||
catalogPath: defaultCatalogPath,
|
catalogPath: defaultCatalogPath,
|
||||||
imageTagMode: process.env.HWLAB_ARTIFACT_IMAGE_TAG_MODE || "short",
|
imageTagMode: process.env.HWLAB_ARTIFACT_IMAGE_TAG_MODE || "short",
|
||||||
@@ -225,6 +226,7 @@ function parseArgs(argv) {
|
|||||||
for (let index = 0; index < argv.length; index += 1) {
|
for (let index = 0; index < argv.length; index += 1) {
|
||||||
const arg = argv[index];
|
const arg = argv[index];
|
||||||
if (arg === "--lane") args.lane = readOption(argv, ++index, arg);
|
if (arg === "--lane") args.lane = readOption(argv, ++index, arg);
|
||||||
|
else if (arg === "--node") args.nodeId = readOption(argv, ++index, arg);
|
||||||
else if (arg === "--out") args.outDir = readOption(argv, ++index, arg);
|
else if (arg === "--out") args.outDir = readOption(argv, ++index, arg);
|
||||||
else if (arg === "--catalog-path") args.catalogPath = readOption(argv, ++index, arg);
|
else if (arg === "--catalog-path") args.catalogPath = readOption(argv, ++index, arg);
|
||||||
else if (arg === "--image-tag-mode") args.imageTagMode = readOption(argv, ++index, arg);
|
else if (arg === "--image-tag-mode") args.imageTagMode = readOption(argv, ++index, arg);
|
||||||
@@ -285,6 +287,7 @@ function usage() {
|
|||||||
"",
|
"",
|
||||||
"options:",
|
"options:",
|
||||||
" --lane LANE g14 or runtime lane such as v02/v03/v04; default: g14",
|
" --lane LANE g14 or runtime lane such as v02/v03/v04; default: g14",
|
||||||
|
` --node NODE deployment node id from deploy.nodes; default: ${process.env.HWLAB_NODE_ID || "G14"}`,
|
||||||
` --out DIR default: ${defaultOutDir}`,
|
` --out DIR default: ${defaultOutDir}`,
|
||||||
` --catalog-path PATH default: ${defaultCatalogPath}`,
|
` --catalog-path PATH default: ${defaultCatalogPath}`,
|
||||||
" --image-tag-mode MODE short or full; v02 uses full source commit IDs",
|
" --image-tag-mode MODE short or full; v02 uses full source commit IDs",
|
||||||
@@ -735,6 +738,18 @@ function gitopsTargetForProfile(profile) {
|
|||||||
return isRuntimeLane(profile) ? profile : "g14";
|
return isRuntimeLane(profile) ? profile : "g14";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function gitopsRootForArgs(args) {
|
||||||
|
return String(args.outDir || defaultOutDir).replace(/\/+$/u, "");
|
||||||
|
}
|
||||||
|
|
||||||
|
function gitopsPathForProfile(args, profile) {
|
||||||
|
return `${gitopsRootForArgs(args)}/${runtimePathForProfile(profile)}`;
|
||||||
|
}
|
||||||
|
|
||||||
|
function gitopsPathFor(args, relativePath) {
|
||||||
|
return `${gitopsRootForArgs(args)}/${String(relativePath).replace(/^\/+/, "")}`;
|
||||||
|
}
|
||||||
|
|
||||||
function profileEndpoint(args, profile) {
|
function profileEndpoint(args, profile) {
|
||||||
if (isRuntimeLane(profile)) return { runtimeEndpoint: args.runtimeEndpoint, webEndpoint: args.webEndpoint };
|
if (isRuntimeLane(profile)) return { runtimeEndpoint: args.runtimeEndpoint, webEndpoint: args.webEndpoint };
|
||||||
return profile === "prod"
|
return profile === "prod"
|
||||||
@@ -757,7 +772,7 @@ function laneNames(args) {
|
|||||||
serviceAccount: `${namespace}-tekton-runner`,
|
serviceAccount: `${namespace}-tekton-runner`,
|
||||||
pipelineRunPrefix: `${namespace}-ci-poll-`,
|
pipelineRunPrefix: `${namespace}-ci-poll-`,
|
||||||
runtimeNamespace: namespace,
|
runtimeNamespace: namespace,
|
||||||
runtimePath: `deploy/gitops/g14/runtime-${args.lane}`,
|
runtimePath: gitopsPathForProfile(args, args.lane),
|
||||||
argoApplications: [`argocd/hwlab-g14-${args.lane}`]
|
argoApplications: [`argocd/hwlab-g14-${args.lane}`]
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
@@ -769,7 +784,7 @@ function laneNames(args) {
|
|||||||
serviceAccount: "hwlab-tekton-runner",
|
serviceAccount: "hwlab-tekton-runner",
|
||||||
pipelineRunPrefix: "hwlab-g14-ci-poll-",
|
pipelineRunPrefix: "hwlab-g14-ci-poll-",
|
||||||
runtimeNamespace: "hwlab-dev",
|
runtimeNamespace: "hwlab-dev",
|
||||||
runtimePath: "deploy/gitops/g14/runtime-dev",
|
runtimePath: gitopsPathForProfile(args, "dev"),
|
||||||
argoApplications: ["argocd/hwlab-g14-dev", "argocd/hwlab-g14-prod"]
|
argoApplications: ["argocd/hwlab-g14-dev", "argocd/hwlab-g14-prod"]
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
@@ -3071,7 +3086,7 @@ function imagePublishTaskSet(args = { lane: "g14" }, deploy = null) {
|
|||||||
|
|
||||||
function tektonPipeline(args = { lane: "g14" }, deploy = null) {
|
function tektonPipeline(args = { lane: "g14" }, deploy = null) {
|
||||||
const settings = ciLaneSettings(args);
|
const settings = ciLaneSettings(args);
|
||||||
const runtimePath = `deploy/gitops/g14/${runtimePathForProfile(settings.profile)}`;
|
const runtimePath = gitopsPathForProfile(args, settings.profile);
|
||||||
return {
|
return {
|
||||||
apiVersion: "tekton.dev/v1",
|
apiVersion: "tekton.dev/v1",
|
||||||
kind: "Pipeline",
|
kind: "Pipeline",
|
||||||
@@ -3196,7 +3211,7 @@ function tektonPipeline(args = { lane: "g14" }, deploy = null) {
|
|||||||
|
|
||||||
function tektonPipelineRunTemplate({ source, args }) {
|
function tektonPipelineRunTemplate({ source, args }) {
|
||||||
const settings = ciLaneSettings(args);
|
const settings = ciLaneSettings(args);
|
||||||
const runtimePath = `deploy/gitops/g14/${runtimePathForProfile(settings.profile)}`;
|
const runtimePath = gitopsPathForProfile(args, settings.profile);
|
||||||
return {
|
return {
|
||||||
apiVersion: "tekton.dev/v1",
|
apiVersion: "tekton.dev/v1",
|
||||||
kind: "PipelineRun",
|
kind: "PipelineRun",
|
||||||
@@ -3293,7 +3308,7 @@ function tektonPollerCronJob(args, deploy) {
|
|||||||
{ name: "LANE", value: settings.lane },
|
{ name: "LANE", value: settings.lane },
|
||||||
{ name: "CATALOG_PATH", value: args.catalogPath || settings.catalogPath },
|
{ name: "CATALOG_PATH", value: args.catalogPath || settings.catalogPath },
|
||||||
{ name: "IMAGE_TAG_MODE", value: args.imageTagMode || settings.imageTagMode },
|
{ name: "IMAGE_TAG_MODE", value: args.imageTagMode || settings.imageTagMode },
|
||||||
{ name: "RUNTIME_PATH", value: `deploy/gitops/g14/${runtimePathForProfile(settings.profile)}` },
|
{ name: "RUNTIME_PATH", value: gitopsPathForProfile(args, settings.profile) },
|
||||||
{ name: "GIT_URL", value: args.sourceRepo },
|
{ name: "GIT_URL", value: args.sourceRepo },
|
||||||
{ name: "GIT_READ_URL", value: args.gitReadUrl },
|
{ name: "GIT_READ_URL", value: args.gitReadUrl },
|
||||||
{ name: "SOURCE_BRANCH", value: args.sourceBranch },
|
{ name: "SOURCE_BRANCH", value: args.sourceBranch },
|
||||||
@@ -3365,7 +3380,7 @@ function tektonControlPlaneReconcilerCronJob(args) {
|
|||||||
{ name: "CATALOG_PATH", value: args.catalogPath || settings.catalogPath },
|
{ name: "CATALOG_PATH", value: args.catalogPath || settings.catalogPath },
|
||||||
{ name: "IMAGE_TAG_MODE", value: args.imageTagMode || settings.imageTagMode },
|
{ name: "IMAGE_TAG_MODE", value: args.imageTagMode || settings.imageTagMode },
|
||||||
{ name: "TEKTON_DIR", value: settings.tektonDir },
|
{ name: "TEKTON_DIR", value: settings.tektonDir },
|
||||||
{ name: "ARGO_FILES", value: settings.lane === "v02" ? "deploy/gitops/g14/argocd/project.yaml,deploy/gitops/g14/argocd/application-v02.yaml" : "" },
|
{ name: "ARGO_FILES", value: settings.lane === "v02" ? `${gitopsPathFor(args, "argocd/project.yaml")},${gitopsPathFor(args, "argocd/application-v02.yaml")}` : "" },
|
||||||
{ name: "FIELD_MANAGER", value: settings.controlPlaneReconcilerName },
|
{ name: "FIELD_MANAGER", value: settings.controlPlaneReconcilerName },
|
||||||
{ name: "RECONCILE_EVENT", value: `${settings.gitopsTarget}-control-plane-reconciled` },
|
{ name: "RECONCILE_EVENT", value: `${settings.gitopsTarget}-control-plane-reconciled` },
|
||||||
{ name: "GIT_URL", value: args.sourceRepo },
|
{ name: "GIT_URL", value: args.sourceRepo },
|
||||||
@@ -3434,8 +3449,8 @@ function uniqueStrings(values) {
|
|||||||
return Array.from(new Set(values.filter((value) => typeof value === "string" && value.length > 0)));
|
return Array.from(new Set(values.filter((value) => typeof value === "string" && value.length > 0)));
|
||||||
}
|
}
|
||||||
|
|
||||||
function devopsInfraGitMirrorManifest(_args, deploy) {
|
function devopsInfraGitMirrorManifest(args, deploy) {
|
||||||
const mirrorSpecs = runtimeLaneMirrorSpecs(deploy);
|
const mirrorSpecs = runtimeLaneMirrorSpecs(deploy, { defaultNodeId: args.nodeId, defaultGitopsRoot: defaultOutDir });
|
||||||
assert.ok(mirrorSpecs.length > 0, "runtime lane git mirror requires at least one deploy.lanes entry");
|
assert.ok(mirrorSpecs.length > 0, "runtime lane git mirror requires at least one deploy.lanes entry");
|
||||||
const sourceBranches = uniqueStrings(mirrorSpecs.map((spec) => spec.sourceBranch));
|
const sourceBranches = uniqueStrings(mirrorSpecs.map((spec) => spec.sourceBranch));
|
||||||
const gitopsBranches = uniqueStrings(mirrorSpecs.map((spec) => spec.gitopsBranch));
|
const gitopsBranches = uniqueStrings(mirrorSpecs.map((spec) => spec.gitopsBranch));
|
||||||
@@ -4146,7 +4161,7 @@ function argoApplication(args, profile = "dev") {
|
|||||||
},
|
},
|
||||||
spec: {
|
spec: {
|
||||||
project,
|
project,
|
||||||
source: { repoURL, targetRevision: args.gitopsBranch, path: `deploy/gitops/g14/${runtimePath}` },
|
source: { repoURL, targetRevision: args.gitopsBranch, path: gitopsPathForProfile(args, profile) },
|
||||||
destination: { server: "https://kubernetes.default.svc", namespace },
|
destination: { server: "https://kubernetes.default.svc", namespace },
|
||||||
syncPolicy: { automated: { prune: isRuntimeLane(profile), selfHeal: true }, syncOptions: ["CreateNamespace=true", "ApplyOutOfSyncOnly=true"] }
|
syncPolicy: { automated: { prune: isRuntimeLane(profile), selfHeal: true }, syncOptions: ["CreateNamespace=true", "ApplyOutOfSyncOnly=true"] }
|
||||||
}
|
}
|
||||||
@@ -4789,6 +4804,7 @@ function v02OpenFgaManifest({ profile = "v02", source }) {
|
|||||||
{ name: "OPENFGA_GRPC_ADDR", value: "0.0.0.0:8081" }
|
{ name: "OPENFGA_GRPC_ADDR", value: "0.0.0.0:8081" }
|
||||||
];
|
];
|
||||||
const templateLabels = { ...labels, ...selector };
|
const templateLabels = { ...labels, ...selector };
|
||||||
|
const runtimeAnnotations = { ...annotations, "argocd.argoproj.io/sync-wave": "2" };
|
||||||
return {
|
return {
|
||||||
apiVersion: "v1",
|
apiVersion: "v1",
|
||||||
kind: "List",
|
kind: "List",
|
||||||
@@ -4802,7 +4818,8 @@ function v02OpenFgaManifest({ profile = "v02", source }) {
|
|||||||
labels,
|
labels,
|
||||||
annotations: {
|
annotations: {
|
||||||
...annotations,
|
...annotations,
|
||||||
"argocd.argoproj.io/hook": "PreSync",
|
"argocd.argoproj.io/hook": "Sync",
|
||||||
|
"argocd.argoproj.io/sync-wave": "1",
|
||||||
"argocd.argoproj.io/hook-delete-policy": "BeforeHookCreation,HookSucceeded"
|
"argocd.argoproj.io/hook-delete-policy": "BeforeHookCreation,HookSucceeded"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@@ -4820,7 +4837,7 @@ function v02OpenFgaManifest({ profile = "v02", source }) {
|
|||||||
{
|
{
|
||||||
apiVersion: "apps/v1",
|
apiVersion: "apps/v1",
|
||||||
kind: "Deployment",
|
kind: "Deployment",
|
||||||
metadata: { name, namespace, labels, annotations },
|
metadata: { name, namespace, labels, annotations: runtimeAnnotations },
|
||||||
spec: {
|
spec: {
|
||||||
replicas: 1,
|
replicas: 1,
|
||||||
selector: { matchLabels: selector },
|
selector: { matchLabels: selector },
|
||||||
@@ -4845,7 +4862,7 @@ function v02OpenFgaManifest({ profile = "v02", source }) {
|
|||||||
{
|
{
|
||||||
apiVersion: "v1",
|
apiVersion: "v1",
|
||||||
kind: "Service",
|
kind: "Service",
|
||||||
metadata: { name, namespace, labels, annotations },
|
metadata: { name, namespace, labels, annotations: runtimeAnnotations },
|
||||||
spec: { type: "ClusterIP", selector, ports: [{ name: "http", port: 8080, targetPort: "http" }, { name: "grpc", port: 8081, targetPort: "grpc" }] }
|
spec: { type: "ClusterIP", selector, ports: [{ name: "http", port: 8080, targetPort: "http" }, { name: "grpc", port: 8081, targetPort: "grpc" }] }
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
@@ -4915,6 +4932,7 @@ async function plannedFiles(args) {
|
|||||||
defaultBranch,
|
defaultBranch,
|
||||||
defaultGitopsBranch,
|
defaultGitopsBranch,
|
||||||
defaultCatalogPath,
|
defaultCatalogPath,
|
||||||
|
defaultGitopsRoot: defaultOutDir,
|
||||||
defaultRuntimeEndpoint,
|
defaultRuntimeEndpoint,
|
||||||
defaultWebEndpoint,
|
defaultWebEndpoint,
|
||||||
defaultV02RuntimeEndpoint,
|
defaultV02RuntimeEndpoint,
|
||||||
@@ -4956,7 +4974,7 @@ async function plannedFiles(args) {
|
|||||||
gitReadUrl: args.gitReadUrl,
|
gitReadUrl: args.gitReadUrl,
|
||||||
gitWriteUrl: args.gitWriteUrl,
|
gitWriteUrl: args.gitWriteUrl,
|
||||||
registryPrefix: args.registryPrefix,
|
registryPrefix: args.registryPrefix,
|
||||||
runtimePaths: profiles.map((profile) => `deploy/gitops/g14/${runtimePathForProfile(profile)}`),
|
runtimePaths: profiles.map((profile) => gitopsPathForProfile(args, profile)),
|
||||||
publicEndpoints,
|
publicEndpoints,
|
||||||
frpDeployments: Object.fromEntries(profiles.map((profile) => [profile, `${namespaceNameForProfile(profile)}/${isRuntimeLane(profile) ? `hwlab-${profile}-frpc` : profile === "prod" ? "hwlab-g14-prod-frpc" : "hwlab-g14-frpc"}`])),
|
frpDeployments: Object.fromEntries(profiles.map((profile) => [profile, `${namespaceNameForProfile(profile)}/${isRuntimeLane(profile) ? `hwlab-${profile}-frpc` : profile === "prod" ? "hwlab-g14-prod-frpc" : "hwlab-g14-frpc"}`])),
|
||||||
tektonPipeline: `hwlab-ci/${settings.pipelineName}`,
|
tektonPipeline: `hwlab-ci/${settings.pipelineName}`,
|
||||||
|
|||||||
@@ -136,6 +136,7 @@ async function configureLane(deploy, options) {
|
|||||||
const target = deepTransform(clone(source), replacements);
|
const target = deepTransform(clone(source), replacements);
|
||||||
|
|
||||||
target.name = targetInfo.versionName;
|
target.name = targetInfo.versionName;
|
||||||
|
target.node = target.node ?? source.node ?? "G14";
|
||||||
target.sourceBranch = targetInfo.sourceBranch;
|
target.sourceBranch = targetInfo.sourceBranch;
|
||||||
target.gitopsBranch = targetInfo.gitopsBranch;
|
target.gitopsBranch = targetInfo.gitopsBranch;
|
||||||
target.namespace = targetInfo.namespace;
|
target.namespace = targetInfo.namespace;
|
||||||
@@ -148,7 +149,7 @@ async function configureLane(deploy, options) {
|
|||||||
legacyApi: `http://${options.host}:${targetInfo.apiPort}`
|
legacyApi: `http://${options.host}:${targetInfo.apiPort}`
|
||||||
};
|
};
|
||||||
target.artifactCatalog = `deploy/artifact-catalog.${options.lane}.json`;
|
target.artifactCatalog = `deploy/artifact-catalog.${options.lane}.json`;
|
||||||
target.runtimePath = `deploy/gitops/g14/runtime-${options.lane}`;
|
target.runtimePath = `runtime-${options.lane}`;
|
||||||
target.imageTagMode = target.imageTagMode ?? "full";
|
target.imageTagMode = target.imageTagMode ?? "full";
|
||||||
|
|
||||||
deploy.lanes[options.lane] = target;
|
deploy.lanes[options.lane] = target;
|
||||||
|
|||||||
@@ -42,7 +42,7 @@ export const DEFAULT_GITOPS_ONLY_PATHS = Object.freeze([
|
|||||||
"deploy/gitops/",
|
"deploy/gitops/",
|
||||||
"deploy/frp/",
|
"deploy/frp/",
|
||||||
"scripts/g14-gitops-render.mjs",
|
"scripts/g14-gitops-render.mjs",
|
||||||
"scripts/src/g14-gitops-lane.ts",
|
"scripts/src/runtime-lane.ts",
|
||||||
"tsconfig.gitops.json"
|
"tsconfig.gitops.json"
|
||||||
]);
|
]);
|
||||||
|
|
||||||
|
|||||||
@@ -1,4 +1,6 @@
|
|||||||
type RuntimeLaneDefaults = {
|
type RuntimeLaneDefaults = {
|
||||||
|
defaultNodeId?: string;
|
||||||
|
defaultGitopsRoot?: string;
|
||||||
defaultBranch?: string;
|
defaultBranch?: string;
|
||||||
defaultGitopsBranch?: string;
|
defaultGitopsBranch?: string;
|
||||||
defaultCatalogPath?: string;
|
defaultCatalogPath?: string;
|
||||||
@@ -10,6 +12,8 @@ type RuntimeLaneDefaults = {
|
|||||||
|
|
||||||
export type GitOpsRenderArgs = {
|
export type GitOpsRenderArgs = {
|
||||||
lane: string;
|
lane: string;
|
||||||
|
nodeId?: string;
|
||||||
|
outDir: string;
|
||||||
sourceBranch: string;
|
sourceBranch: string;
|
||||||
gitopsBranch: string;
|
gitopsBranch: string;
|
||||||
catalogPath: string;
|
catalogPath: string;
|
||||||
@@ -21,9 +25,11 @@ export type GitOpsRenderArgs = {
|
|||||||
};
|
};
|
||||||
|
|
||||||
export type RuntimeLaneConfig = {
|
export type RuntimeLaneConfig = {
|
||||||
|
node?: string;
|
||||||
sourceBranch?: string;
|
sourceBranch?: string;
|
||||||
gitopsBranch?: string;
|
gitopsBranch?: string;
|
||||||
artifactCatalog?: string;
|
artifactCatalog?: string;
|
||||||
|
runtimePath?: string;
|
||||||
imageTagMode?: string;
|
imageTagMode?: string;
|
||||||
endpoint?: string;
|
endpoint?: string;
|
||||||
publicEndpoints?: {
|
publicEndpoints?: {
|
||||||
@@ -34,6 +40,12 @@ export type RuntimeLaneConfig = {
|
|||||||
sourceRepo?: string;
|
sourceRepo?: string;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
export type NodeConfig = {
|
||||||
|
gitopsRoot?: string;
|
||||||
|
sourceRepo?: string;
|
||||||
|
publicHost?: string;
|
||||||
|
};
|
||||||
|
|
||||||
export type RuntimeLaneMirrorSpec = {
|
export type RuntimeLaneMirrorSpec = {
|
||||||
lane: string;
|
lane: string;
|
||||||
sourceBranch: string;
|
sourceBranch: string;
|
||||||
@@ -43,9 +55,12 @@ export type RuntimeLaneMirrorSpec = {
|
|||||||
};
|
};
|
||||||
|
|
||||||
export type DeployConfig = {
|
export type DeployConfig = {
|
||||||
|
nodes?: Record<string, NodeConfig | undefined>;
|
||||||
lanes?: Record<string, RuntimeLaneConfig | undefined>;
|
lanes?: Record<string, RuntimeLaneConfig | undefined>;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const defaultNodeId = "G14";
|
||||||
|
const defaultGitopsRoot = "deploy/gitops/g14";
|
||||||
const defaultPublicHost = "74.48.78.17";
|
const defaultPublicHost = "74.48.78.17";
|
||||||
|
|
||||||
export function isRuntimeLane(lane: unknown): lane is string {
|
export function isRuntimeLane(lane: unknown): lane is string {
|
||||||
@@ -71,6 +86,28 @@ export function runtimePathForRuntimeLane(lane: string): string {
|
|||||||
return `runtime-${lane}`;
|
return `runtime-${lane}`;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export function nodeConfig(deploy: DeployConfig, nodeId: string): NodeConfig {
|
||||||
|
const config = deploy.nodes?.[nodeId];
|
||||||
|
return isObject(config) ? config : {};
|
||||||
|
}
|
||||||
|
|
||||||
|
export function nodeIdForRuntimeLane(deploy: DeployConfig, lane: string, defaults: RuntimeLaneDefaults = {}): string {
|
||||||
|
const laneConfig = runtimeLaneConfig(deploy, lane);
|
||||||
|
return laneConfig.node ?? defaults.defaultNodeId ?? defaultNodeId;
|
||||||
|
}
|
||||||
|
|
||||||
|
export function gitopsRootForNode(deploy: DeployConfig, nodeId: string, defaults: RuntimeLaneDefaults = {}): string {
|
||||||
|
const config = nodeConfig(deploy, nodeId);
|
||||||
|
return normalizeRepoPath(config.gitopsRoot ?? defaults.defaultGitopsRoot ?? defaultGitopsRoot);
|
||||||
|
}
|
||||||
|
|
||||||
|
export function runtimeGitopsPathForRuntimeLane(deploy: DeployConfig, lane: string, defaults: RuntimeLaneDefaults = {}): string {
|
||||||
|
const laneConfig = runtimeLaneConfig(deploy, lane);
|
||||||
|
const runtimePath = normalizeRepoPath(laneConfig.runtimePath ?? runtimePathForRuntimeLane(lane));
|
||||||
|
if (runtimePath.startsWith("deploy/")) return runtimePath;
|
||||||
|
return joinRepoPath(gitopsRootForNode(deploy, nodeIdForRuntimeLane(deploy, lane, defaults), defaults), runtimePath);
|
||||||
|
}
|
||||||
|
|
||||||
export function defaultPortForRuntimeLane(lane: string): number {
|
export function defaultPortForRuntimeLane(lane: string): number {
|
||||||
return 19466 + runtimeLaneMinor(lane) * 100;
|
return 19466 + runtimeLaneMinor(lane) * 100;
|
||||||
}
|
}
|
||||||
@@ -95,8 +132,12 @@ export function applyRuntimeLaneDeployConfig(args: GitOpsRenderArgs, deploy: Dep
|
|||||||
if (!isRuntimeLane(args.lane)) return args;
|
if (!isRuntimeLane(args.lane)) return args;
|
||||||
const result: GitOpsRenderArgs = { ...args };
|
const result: GitOpsRenderArgs = { ...args };
|
||||||
const laneConfig = runtimeLaneConfig(deploy, args.lane);
|
const laneConfig = runtimeLaneConfig(deploy, args.lane);
|
||||||
|
const nodeId = nodeIdForRuntimeLane(deploy, args.lane, defaults);
|
||||||
|
const node = nodeConfig(deploy, nodeId);
|
||||||
const versionName = versionNameForRuntimeLane(args.lane);
|
const versionName = versionNameForRuntimeLane(args.lane);
|
||||||
const defaultEndpointOptions = defaults.defaultV02RuntimeEndpoint ? { v02Endpoint: defaults.defaultV02RuntimeEndpoint } : {};
|
const defaultEndpointOptions: { host?: string; v02Endpoint?: string } = {};
|
||||||
|
if (node.publicHost) defaultEndpointOptions.host = node.publicHost;
|
||||||
|
if (defaults.defaultV02RuntimeEndpoint) defaultEndpointOptions.v02Endpoint = defaults.defaultV02RuntimeEndpoint;
|
||||||
const defaultEndpoint = defaultEndpointForRuntimeLane(args.lane, defaultEndpointOptions);
|
const defaultEndpoint = defaultEndpointForRuntimeLane(args.lane, defaultEndpointOptions);
|
||||||
const configuredEndpoint = laneConfig.endpoint ?? defaultEndpoint;
|
const configuredEndpoint = laneConfig.endpoint ?? defaultEndpoint;
|
||||||
const configuredWebEndpoint = laneConfig.publicEndpoints?.frontend ?? configuredEndpoint;
|
const configuredWebEndpoint = laneConfig.publicEndpoints?.frontend ?? configuredEndpoint;
|
||||||
@@ -107,19 +148,22 @@ export function applyRuntimeLaneDeployConfig(args: GitOpsRenderArgs, deploy: Dep
|
|||||||
const defaultRuntimeEndpoint = defaults.defaultRuntimeEndpoint ?? "http://74.48.78.17:17667";
|
const defaultRuntimeEndpoint = defaults.defaultRuntimeEndpoint ?? "http://74.48.78.17:17667";
|
||||||
const defaultWebEndpoint = defaults.defaultWebEndpoint ?? "http://74.48.78.17:17666";
|
const defaultWebEndpoint = defaults.defaultWebEndpoint ?? "http://74.48.78.17:17666";
|
||||||
const defaultSourceRepo = defaults.defaultSourceRepo ?? "git@github.com:pikasTech/HWLAB.git";
|
const defaultSourceRepo = defaults.defaultSourceRepo ?? "git@github.com:pikasTech/HWLAB.git";
|
||||||
|
const defaultOutDir = defaults.defaultGitopsRoot ?? defaultGitopsRoot;
|
||||||
const defaultCatalog = `deploy/artifact-catalog.${args.lane}.json`;
|
const defaultCatalog = `deploy/artifact-catalog.${args.lane}.json`;
|
||||||
|
|
||||||
|
if (!result.nodeId || result.nodeId === defaultNodeId) result.nodeId = nodeId;
|
||||||
|
if (result.outDir === defaultOutDir) result.outDir = gitopsRootForNode(deploy, nodeId, defaults);
|
||||||
if (result.sourceBranch === defaultBranch || result.sourceBranch === versionName) result.sourceBranch = laneConfig.sourceBranch ?? versionName;
|
if (result.sourceBranch === defaultBranch || result.sourceBranch === versionName) result.sourceBranch = laneConfig.sourceBranch ?? versionName;
|
||||||
if (result.gitopsBranch === defaultGitopsBranch || result.gitopsBranch === `${versionName}-gitops`) result.gitopsBranch = laneConfig.gitopsBranch ?? `${versionName}-gitops`;
|
if (result.gitopsBranch === defaultGitopsBranch || result.gitopsBranch === `${versionName}-gitops`) result.gitopsBranch = laneConfig.gitopsBranch ?? `${versionName}-gitops`;
|
||||||
if (result.catalogPath === defaultCatalogPath || result.catalogPath === defaultCatalog) result.catalogPath = laneConfig.artifactCatalog ?? defaultCatalog;
|
if (result.catalogPath === defaultCatalogPath || result.catalogPath === defaultCatalog) result.catalogPath = laneConfig.artifactCatalog ?? defaultCatalog;
|
||||||
if (result.imageTagMode === "full") result.imageTagMode = laneConfig.imageTagMode ?? result.imageTagMode;
|
if (result.imageTagMode === "full") result.imageTagMode = laneConfig.imageTagMode ?? result.imageTagMode;
|
||||||
if (result.runtimeEndpoint === defaultRuntimeEndpoint || result.runtimeEndpoint === defaultEndpoint) result.runtimeEndpoint = configuredRuntimeEndpoint;
|
if (result.runtimeEndpoint === defaultRuntimeEndpoint || result.runtimeEndpoint === defaultEndpoint) result.runtimeEndpoint = configuredRuntimeEndpoint;
|
||||||
if (result.webEndpoint === defaultWebEndpoint || result.webEndpoint === defaultEndpoint) result.webEndpoint = configuredWebEndpoint;
|
if (result.webEndpoint === defaultWebEndpoint || result.webEndpoint === defaultEndpoint) result.webEndpoint = configuredWebEndpoint;
|
||||||
if (result.sourceRepo === defaultSourceRepo && laneConfig.sourceRepo) result.sourceRepo = laneConfig.sourceRepo;
|
if (result.sourceRepo === defaultSourceRepo) result.sourceRepo = laneConfig.sourceRepo ?? node.sourceRepo ?? result.sourceRepo;
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
export function runtimeLaneMirrorSpecs(deploy: DeployConfig): RuntimeLaneMirrorSpec[] {
|
export function runtimeLaneMirrorSpecs(deploy: DeployConfig, defaults: RuntimeLaneDefaults = {}): RuntimeLaneMirrorSpec[] {
|
||||||
return Object.entries(deploy.lanes ?? {})
|
return Object.entries(deploy.lanes ?? {})
|
||||||
.filter(([lane, config]) => isRuntimeLane(lane) && isObject(config))
|
.filter(([lane, config]) => isRuntimeLane(lane) && isObject(config))
|
||||||
.sort(([left], [right]) => runtimeLaneMinor(left) - runtimeLaneMinor(right))
|
.sort(([left], [right]) => runtimeLaneMinor(left) - runtimeLaneMinor(right))
|
||||||
@@ -131,11 +175,19 @@ export function runtimeLaneMirrorSpecs(deploy: DeployConfig): RuntimeLaneMirrorS
|
|||||||
sourceBranch: laneConfig.sourceBranch ?? versionName,
|
sourceBranch: laneConfig.sourceBranch ?? versionName,
|
||||||
gitopsBranch: laneConfig.gitopsBranch ?? `${versionName}-gitops`,
|
gitopsBranch: laneConfig.gitopsBranch ?? `${versionName}-gitops`,
|
||||||
artifactCatalog: laneConfig.artifactCatalog ?? `deploy/artifact-catalog.${lane}.json`,
|
artifactCatalog: laneConfig.artifactCatalog ?? `deploy/artifact-catalog.${lane}.json`,
|
||||||
runtimePath: `deploy/gitops/g14/${runtimePathForRuntimeLane(lane)}`,
|
runtimePath: runtimeGitopsPathForRuntimeLane(deploy, lane, defaults),
|
||||||
};
|
};
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function normalizeRepoPath(value: string): string {
|
||||||
|
return value.replaceAll("\\\\", "/").replace(/^\.\//u, "").replace(/\/+$/u, "");
|
||||||
|
}
|
||||||
|
|
||||||
|
function joinRepoPath(left: string, right: string): string {
|
||||||
|
return `${normalizeRepoPath(left)}/${normalizeRepoPath(right).replace(/^\/+/, "")}`;
|
||||||
|
}
|
||||||
|
|
||||||
function isObject(value: unknown): value is Record<string, unknown> {
|
function isObject(value: unknown): value is Record<string, unknown> {
|
||||||
return typeof value === "object" && value !== null && !Array.isArray(value);
|
return typeof value === "object" && value !== null && !Array.isArray(value);
|
||||||
}
|
}
|
||||||
@@ -19,6 +19,6 @@
|
|||||||
"useUnknownInCatchVariables": true
|
"useUnknownInCatchVariables": true
|
||||||
},
|
},
|
||||||
"include": [
|
"include": [
|
||||||
"scripts/src/g14-gitops-lane.ts"
|
"scripts/src/runtime-lane.ts"
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user