feat: split G14 GitOps promotion branch
This commit is contained in:
@@ -36,3 +36,6 @@ yarn-error.log*
|
||||
# Deploy/runtime state
|
||||
*.local.json
|
||||
.state/
|
||||
|
||||
# G14 generated GitOps desired state is stored on the G14-gitops branch.
|
||||
/deploy/gitops/g14/
|
||||
|
||||
@@ -1,10 +0,0 @@
|
||||
# HWLAB G14 GitOps CI/CD
|
||||
|
||||
This directory is generated from `CI.json`, `deploy/deploy.json`, and `deploy/k8s/*` by `scripts/g14-gitops-render.mjs`.
|
||||
|
||||
- Target: G14 k3s only.
|
||||
- CI: Tekton Pipeline `hwlab-ci/hwlab-g14-ci-image-publish`.
|
||||
- Artifact contract: images are tagged by source git commit `bec4109` and pushed to `127.0.0.1:5000/hwlab`.
|
||||
- CD: Argo CD Application `argocd/hwlab-g14-dev` consumes `deploy/gitops/g14/runtime`.
|
||||
- D601 boundary: this path does not target D601, does not use UniDesk Code Queue, and does not change D601 production traffic.
|
||||
- Concurrency: CI builds are per source commit and do not acquire the legacy DEV CD Lease; Argo CD reconciles the Git desired state.
|
||||
@@ -1,34 +0,0 @@
|
||||
{
|
||||
"apiVersion": "argoproj.io/v1alpha1",
|
||||
"kind": "Application",
|
||||
"metadata": {
|
||||
"name": "hwlab-g14-dev",
|
||||
"namespace": "argocd",
|
||||
"labels": {
|
||||
"app.kubernetes.io/part-of": "hwlab",
|
||||
"hwlab.pikastech.local/gitops-target": "g14"
|
||||
}
|
||||
},
|
||||
"spec": {
|
||||
"project": "hwlab-g14",
|
||||
"source": {
|
||||
"repoURL": "git@github.com:pikasTech/HWLAB.git",
|
||||
"targetRevision": "G14",
|
||||
"path": "deploy/gitops/g14/runtime"
|
||||
},
|
||||
"destination": {
|
||||
"server": "https://kubernetes.default.svc",
|
||||
"namespace": "hwlab-dev"
|
||||
},
|
||||
"syncPolicy": {
|
||||
"automated": {
|
||||
"prune": false,
|
||||
"selfHeal": true
|
||||
},
|
||||
"syncOptions": [
|
||||
"CreateNamespace=true",
|
||||
"ApplyOutOfSyncOnly=true"
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,32 +0,0 @@
|
||||
{
|
||||
"apiVersion": "argoproj.io/v1alpha1",
|
||||
"kind": "AppProject",
|
||||
"metadata": {
|
||||
"name": "hwlab-g14",
|
||||
"namespace": "argocd"
|
||||
},
|
||||
"spec": {
|
||||
"description": "HWLAB G14 GitOps project; D601 remains outside this project.",
|
||||
"sourceRepos": [
|
||||
"git@github.com:pikasTech/HWLAB.git"
|
||||
],
|
||||
"destinations": [
|
||||
{
|
||||
"server": "https://kubernetes.default.svc",
|
||||
"namespace": "hwlab-dev"
|
||||
}
|
||||
],
|
||||
"clusterResourceWhitelist": [
|
||||
{
|
||||
"group": "",
|
||||
"kind": "Namespace"
|
||||
}
|
||||
],
|
||||
"namespaceResourceWhitelist": [
|
||||
{
|
||||
"group": "*",
|
||||
"kind": "*"
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
@@ -1,113 +0,0 @@
|
||||
{
|
||||
"apiVersion": "v1",
|
||||
"kind": "List",
|
||||
"items": [
|
||||
{
|
||||
"apiVersion": "v1",
|
||||
"kind": "Namespace",
|
||||
"metadata": {
|
||||
"name": "hwlab-ci"
|
||||
}
|
||||
},
|
||||
{
|
||||
"apiVersion": "apps/v1",
|
||||
"kind": "Deployment",
|
||||
"metadata": {
|
||||
"name": "hwlab-registry",
|
||||
"namespace": "hwlab-ci",
|
||||
"labels": {
|
||||
"app.kubernetes.io/name": "hwlab-registry"
|
||||
}
|
||||
},
|
||||
"spec": {
|
||||
"replicas": 1,
|
||||
"selector": {
|
||||
"matchLabels": {
|
||||
"app.kubernetes.io/name": "hwlab-registry"
|
||||
}
|
||||
},
|
||||
"template": {
|
||||
"metadata": {
|
||||
"labels": {
|
||||
"app.kubernetes.io/name": "hwlab-registry"
|
||||
}
|
||||
},
|
||||
"spec": {
|
||||
"hostNetwork": true,
|
||||
"dnsPolicy": "ClusterFirstWithHostNet",
|
||||
"containers": [
|
||||
{
|
||||
"name": "registry",
|
||||
"image": "registry:2.8.3",
|
||||
"imagePullPolicy": "IfNotPresent",
|
||||
"ports": [
|
||||
{
|
||||
"name": "registry",
|
||||
"containerPort": 5000,
|
||||
"hostPort": 5000
|
||||
}
|
||||
],
|
||||
"env": [
|
||||
{
|
||||
"name": "REGISTRY_STORAGE_DELETE_ENABLED",
|
||||
"value": "true"
|
||||
}
|
||||
],
|
||||
"volumeMounts": [
|
||||
{
|
||||
"name": "storage",
|
||||
"mountPath": "/var/lib/registry"
|
||||
}
|
||||
],
|
||||
"readinessProbe": {
|
||||
"httpGet": {
|
||||
"path": "/v2/",
|
||||
"port": "registry"
|
||||
}
|
||||
},
|
||||
"livenessProbe": {
|
||||
"httpGet": {
|
||||
"path": "/v2/",
|
||||
"port": "registry"
|
||||
}
|
||||
}
|
||||
}
|
||||
],
|
||||
"volumes": [
|
||||
{
|
||||
"name": "storage",
|
||||
"hostPath": {
|
||||
"path": "/var/lib/hwlab/registry",
|
||||
"type": "DirectoryOrCreate"
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"apiVersion": "v1",
|
||||
"kind": "Service",
|
||||
"metadata": {
|
||||
"name": "hwlab-registry",
|
||||
"namespace": "hwlab-ci",
|
||||
"labels": {
|
||||
"app.kubernetes.io/name": "hwlab-registry"
|
||||
}
|
||||
},
|
||||
"spec": {
|
||||
"selector": {
|
||||
"app.kubernetes.io/name": "hwlab-registry"
|
||||
},
|
||||
"ports": [
|
||||
{
|
||||
"name": "registry",
|
||||
"port": 5000,
|
||||
"targetPort": "registry"
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -1,20 +0,0 @@
|
||||
{
|
||||
"apiVersion": "v1",
|
||||
"kind": "ConfigMap",
|
||||
"metadata": {
|
||||
"name": "hwlab-code-agent-codex-config",
|
||||
"namespace": "hwlab-dev",
|
||||
"labels": {
|
||||
"app.kubernetes.io/name": "hwlab-code-agent-codex-config",
|
||||
"hwlab.pikastech.local/service-id": "hwlab-cloud-api",
|
||||
"hwlab.pikastech.local/gitops-target": "g14",
|
||||
"hwlab.pikastech.local/source-commit": "bec4109af1bddd606683821c60186c0c89f72584"
|
||||
},
|
||||
"annotations": {
|
||||
"hwlab.pikastech.local/rendered-by": "scripts/g14-gitops-render.mjs"
|
||||
}
|
||||
},
|
||||
"data": {
|
||||
"config.toml": "model_provider = \"OpenAI\"\nmodel = \"gpt-5.4\"\nreview_model = \"gpt-5.4\"\nmodel_reasoning_effort = \"xhigh\"\ndisable_response_storage = true\nnetwork_access = \"enabled\"\nmodel_context_window = 1000000\nmodel_auto_compact_token_limit = 900000\n\n[model_providers.OpenAI]\nname = \"OpenAI\"\nbase_url = \"https://hyueapi.com\"\nwire_api = \"responses\"\nrequires_openai_auth = true\n\n[model_providers.crs]\nrequest_max_retries = 1000\nstream_max_retries = 1000\nname = \"crs\"\nbase_url = \"https://api.gptclubapi.xyz/openai\"\nwire_api = \"responses\"\nrequires_openai_auth = true\nenv_key = \"CRS_OAI_KEY\"\n"
|
||||
}
|
||||
}
|
||||
@@ -1,30 +0,0 @@
|
||||
{
|
||||
"apiVersion": "v1",
|
||||
"kind": "ConfigMap",
|
||||
"metadata": {
|
||||
"name": "hwlab-dev-health-contract",
|
||||
"namespace": "hwlab-dev",
|
||||
"labels": {
|
||||
"app.kubernetes.io/name": "hwlab-dev-health-contract",
|
||||
"hwlab.pikastech.local/profile": "dev",
|
||||
"hwlab.pikastech.local/gitops-target": "g14",
|
||||
"hwlab.pikastech.local/source-commit": "bec4109af1bddd606683821c60186c0c89f72584"
|
||||
},
|
||||
"annotations": {
|
||||
"hwlab.pikastech.local/rendered-by": "scripts/g14-gitops-render.mjs"
|
||||
}
|
||||
},
|
||||
"data": {
|
||||
"endpoint": "http://hwlab-edge-proxy.hwlab-dev.svc.cluster.local:6667",
|
||||
"cloud-api": "GET /health/live through http://hwlab-edge-proxy.hwlab-dev.svc.cluster.local:6667",
|
||||
"cloud-api-db": "DEV DB config gate requires HWLAB_CLOUD_DB_URL from Secret hwlab-cloud-api-dev-db/database-url and HWLAB_CLOUD_DB_SSL_MODE=disable. Runtime readiness dials the redacted host parsed from the Secret URL and reports endpointSource=secret-url-host. cloud-api-db is an optional desired alias only until this repo owns Service plus Endpoint or EndpointSlice manifests and rollout/apply contract; health reports env presence, env injection, redacted connection attempt/result, and liveConnected without exposing secret values",
|
||||
"cloud-web": "GET /health/live on http://hwlab-cloud-web.hwlab-dev.svc.cluster.local:8080; consumes cloud-api only",
|
||||
"agent": "hwlab-agent-mgr readiness gates worker template creation; hwlab-agent-worker is suspended until a session is scheduled",
|
||||
"sim": "hwlab-gateway-simu:7101 and hwlab-box-simu:7201 expose /health/live for DEV smoke",
|
||||
"patch-panel": "hwlab-patch-panel:7301 exposes /health/live and owns patch panel state",
|
||||
"router": "hwlab-router:7401 exposes /health/live and owns edge reachability routing",
|
||||
"tunnel-client": "disabled for G14 GitOps; no FRP or production traffic tunnel is required",
|
||||
"edge-proxy": "hwlab-edge-proxy:6667 exposes /health/live and proxies DEV endpoint traffic to hwlab-cloud-api",
|
||||
"runtime-substitute-policy": "Do not replace HWLAB runtime with UniDesk backend, provider-gateway, or microservice proxy"
|
||||
}
|
||||
}
|
||||
@@ -1,12 +0,0 @@
|
||||
{
|
||||
"apiVersion": "kustomize.config.k8s.io/v1beta1",
|
||||
"kind": "Kustomization",
|
||||
"namespace": "hwlab-dev",
|
||||
"resources": [
|
||||
"namespace.yaml",
|
||||
"code-agent-codex-config.yaml",
|
||||
"services.yaml",
|
||||
"health-contract.yaml",
|
||||
"workloads.yaml"
|
||||
]
|
||||
}
|
||||
@@ -1,16 +0,0 @@
|
||||
{
|
||||
"apiVersion": "v1",
|
||||
"kind": "Namespace",
|
||||
"metadata": {
|
||||
"name": "hwlab-dev",
|
||||
"labels": {
|
||||
"app.kubernetes.io/part-of": "hwlab",
|
||||
"hwlab.pikastech.local/profile": "dev",
|
||||
"hwlab.pikastech.local/gitops-target": "g14",
|
||||
"hwlab.pikastech.local/source-commit": "bec4109af1bddd606683821c60186c0c89f72584"
|
||||
},
|
||||
"annotations": {
|
||||
"hwlab.pikastech.local/rendered-by": "scripts/g14-gitops-render.mjs"
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,492 +0,0 @@
|
||||
{
|
||||
"apiVersion": "v1",
|
||||
"kind": "List",
|
||||
"items": [
|
||||
{
|
||||
"apiVersion": "v1",
|
||||
"kind": "Service",
|
||||
"metadata": {
|
||||
"name": "hwlab-cloud-api",
|
||||
"namespace": "hwlab-dev",
|
||||
"labels": {
|
||||
"app.kubernetes.io/name": "hwlab-cloud-api",
|
||||
"hwlab.pikastech.local/service-id": "hwlab-cloud-api",
|
||||
"hwlab.pikastech.local/gitops-target": "g14",
|
||||
"hwlab.pikastech.local/source-commit": "bec4109af1bddd606683821c60186c0c89f72584"
|
||||
},
|
||||
"annotations": {
|
||||
"hwlab.pikastech.local/rendered-by": "scripts/g14-gitops-render.mjs"
|
||||
}
|
||||
},
|
||||
"spec": {
|
||||
"type": "ClusterIP",
|
||||
"selector": {
|
||||
"app.kubernetes.io/name": "hwlab-cloud-api"
|
||||
},
|
||||
"ports": [
|
||||
{
|
||||
"name": "http",
|
||||
"port": 6667,
|
||||
"targetPort": "http"
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
{
|
||||
"apiVersion": "v1",
|
||||
"kind": "Service",
|
||||
"metadata": {
|
||||
"name": "hwlab-gateway-simu-1",
|
||||
"namespace": "hwlab-dev",
|
||||
"labels": {
|
||||
"app.kubernetes.io/name": "hwlab-gateway-simu",
|
||||
"hwlab.pikastech.local/service-id": "hwlab-gateway-simu",
|
||||
"hwlab.pikastech.local/instance-id": "gwsimu_1",
|
||||
"hwlab.pikastech.local/gitops-target": "g14",
|
||||
"hwlab.pikastech.local/source-commit": "bec4109af1bddd606683821c60186c0c89f72584"
|
||||
},
|
||||
"annotations": {
|
||||
"hwlab.pikastech.local/rendered-by": "scripts/g14-gitops-render.mjs"
|
||||
}
|
||||
},
|
||||
"spec": {
|
||||
"type": "ClusterIP",
|
||||
"selector": {
|
||||
"statefulset.kubernetes.io/pod-name": "hwlab-gateway-simu-0"
|
||||
},
|
||||
"ports": [
|
||||
{
|
||||
"name": "http",
|
||||
"port": 7101,
|
||||
"targetPort": "http"
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
{
|
||||
"apiVersion": "v1",
|
||||
"kind": "Service",
|
||||
"metadata": {
|
||||
"name": "hwlab-gateway-simu-2",
|
||||
"namespace": "hwlab-dev",
|
||||
"labels": {
|
||||
"app.kubernetes.io/name": "hwlab-gateway-simu",
|
||||
"hwlab.pikastech.local/service-id": "hwlab-gateway-simu",
|
||||
"hwlab.pikastech.local/instance-id": "gwsimu_2",
|
||||
"hwlab.pikastech.local/gitops-target": "g14",
|
||||
"hwlab.pikastech.local/source-commit": "bec4109af1bddd606683821c60186c0c89f72584"
|
||||
},
|
||||
"annotations": {
|
||||
"hwlab.pikastech.local/rendered-by": "scripts/g14-gitops-render.mjs"
|
||||
}
|
||||
},
|
||||
"spec": {
|
||||
"type": "ClusterIP",
|
||||
"selector": {
|
||||
"statefulset.kubernetes.io/pod-name": "hwlab-gateway-simu-1"
|
||||
},
|
||||
"ports": [
|
||||
{
|
||||
"name": "http",
|
||||
"port": 7101,
|
||||
"targetPort": "http"
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
{
|
||||
"apiVersion": "v1",
|
||||
"kind": "Service",
|
||||
"metadata": {
|
||||
"name": "hwlab-cloud-web",
|
||||
"namespace": "hwlab-dev",
|
||||
"labels": {
|
||||
"app.kubernetes.io/name": "hwlab-cloud-web",
|
||||
"hwlab.pikastech.local/service-id": "hwlab-cloud-web",
|
||||
"hwlab.pikastech.local/gitops-target": "g14",
|
||||
"hwlab.pikastech.local/source-commit": "bec4109af1bddd606683821c60186c0c89f72584"
|
||||
},
|
||||
"annotations": {
|
||||
"hwlab.pikastech.local/rendered-by": "scripts/g14-gitops-render.mjs"
|
||||
}
|
||||
},
|
||||
"spec": {
|
||||
"type": "ClusterIP",
|
||||
"selector": {
|
||||
"app.kubernetes.io/name": "hwlab-cloud-web"
|
||||
},
|
||||
"ports": [
|
||||
{
|
||||
"name": "http",
|
||||
"port": 8080,
|
||||
"targetPort": "http"
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
{
|
||||
"apiVersion": "v1",
|
||||
"kind": "Service",
|
||||
"metadata": {
|
||||
"name": "hwlab-box-simu-1",
|
||||
"namespace": "hwlab-dev",
|
||||
"labels": {
|
||||
"app.kubernetes.io/name": "hwlab-box-simu",
|
||||
"hwlab.pikastech.local/service-id": "hwlab-box-simu",
|
||||
"hwlab.pikastech.local/instance-id": "res_boxsimu_1",
|
||||
"hwlab.pikastech.local/gitops-target": "g14",
|
||||
"hwlab.pikastech.local/source-commit": "bec4109af1bddd606683821c60186c0c89f72584"
|
||||
},
|
||||
"annotations": {
|
||||
"hwlab.pikastech.local/rendered-by": "scripts/g14-gitops-render.mjs"
|
||||
}
|
||||
},
|
||||
"spec": {
|
||||
"type": "ClusterIP",
|
||||
"selector": {
|
||||
"statefulset.kubernetes.io/pod-name": "hwlab-box-simu-0"
|
||||
},
|
||||
"ports": [
|
||||
{
|
||||
"name": "http",
|
||||
"port": 7201,
|
||||
"targetPort": "http"
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
{
|
||||
"apiVersion": "v1",
|
||||
"kind": "Service",
|
||||
"metadata": {
|
||||
"name": "hwlab-box-simu-2",
|
||||
"namespace": "hwlab-dev",
|
||||
"labels": {
|
||||
"app.kubernetes.io/name": "hwlab-box-simu",
|
||||
"hwlab.pikastech.local/service-id": "hwlab-box-simu",
|
||||
"hwlab.pikastech.local/instance-id": "res_boxsimu_2",
|
||||
"hwlab.pikastech.local/gitops-target": "g14",
|
||||
"hwlab.pikastech.local/source-commit": "bec4109af1bddd606683821c60186c0c89f72584"
|
||||
},
|
||||
"annotations": {
|
||||
"hwlab.pikastech.local/rendered-by": "scripts/g14-gitops-render.mjs"
|
||||
}
|
||||
},
|
||||
"spec": {
|
||||
"type": "ClusterIP",
|
||||
"selector": {
|
||||
"statefulset.kubernetes.io/pod-name": "hwlab-box-simu-1"
|
||||
},
|
||||
"ports": [
|
||||
{
|
||||
"name": "http",
|
||||
"port": 7201,
|
||||
"targetPort": "http"
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
{
|
||||
"apiVersion": "v1",
|
||||
"kind": "Service",
|
||||
"metadata": {
|
||||
"name": "hwlab-gateway",
|
||||
"namespace": "hwlab-dev",
|
||||
"labels": {
|
||||
"app.kubernetes.io/name": "hwlab-gateway",
|
||||
"hwlab.pikastech.local/service-id": "hwlab-gateway",
|
||||
"hwlab.pikastech.local/activation": "manual",
|
||||
"hwlab.pikastech.local/gitops-target": "g14",
|
||||
"hwlab.pikastech.local/source-commit": "bec4109af1bddd606683821c60186c0c89f72584"
|
||||
},
|
||||
"annotations": {
|
||||
"hwlab.pikastech.local/rendered-by": "scripts/g14-gitops-render.mjs"
|
||||
}
|
||||
},
|
||||
"spec": {
|
||||
"type": "ClusterIP",
|
||||
"selector": {
|
||||
"app.kubernetes.io/name": "hwlab-gateway"
|
||||
},
|
||||
"ports": [
|
||||
{
|
||||
"name": "http",
|
||||
"port": 7001,
|
||||
"targetPort": "http"
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
{
|
||||
"apiVersion": "v1",
|
||||
"kind": "Service",
|
||||
"metadata": {
|
||||
"name": "hwlab-cli",
|
||||
"namespace": "hwlab-dev",
|
||||
"labels": {
|
||||
"app.kubernetes.io/name": "hwlab-cli",
|
||||
"hwlab.pikastech.local/service-id": "hwlab-cli",
|
||||
"hwlab.pikastech.local/activation": "manual",
|
||||
"hwlab.pikastech.local/gitops-target": "g14",
|
||||
"hwlab.pikastech.local/source-commit": "bec4109af1bddd606683821c60186c0c89f72584"
|
||||
},
|
||||
"annotations": {
|
||||
"hwlab.pikastech.local/rendered-by": "scripts/g14-gitops-render.mjs"
|
||||
}
|
||||
},
|
||||
"spec": {
|
||||
"type": "ClusterIP",
|
||||
"selector": {
|
||||
"app.kubernetes.io/name": "hwlab-cli"
|
||||
},
|
||||
"ports": [
|
||||
{
|
||||
"name": "http",
|
||||
"port": 7501,
|
||||
"targetPort": "http"
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
{
|
||||
"apiVersion": "v1",
|
||||
"kind": "Service",
|
||||
"metadata": {
|
||||
"name": "hwlab-agent-skills",
|
||||
"namespace": "hwlab-dev",
|
||||
"labels": {
|
||||
"app.kubernetes.io/name": "hwlab-agent-skills",
|
||||
"hwlab.pikastech.local/service-id": "hwlab-agent-skills",
|
||||
"hwlab.pikastech.local/gitops-target": "g14",
|
||||
"hwlab.pikastech.local/source-commit": "bec4109af1bddd606683821c60186c0c89f72584"
|
||||
},
|
||||
"annotations": {
|
||||
"hwlab.pikastech.local/rendered-by": "scripts/g14-gitops-render.mjs"
|
||||
}
|
||||
},
|
||||
"spec": {
|
||||
"type": "ClusterIP",
|
||||
"selector": {
|
||||
"app.kubernetes.io/name": "hwlab-agent-skills"
|
||||
},
|
||||
"ports": [
|
||||
{
|
||||
"name": "http",
|
||||
"port": 7430,
|
||||
"targetPort": "http"
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
{
|
||||
"apiVersion": "v1",
|
||||
"kind": "Service",
|
||||
"metadata": {
|
||||
"name": "hwlab-agent-mgr",
|
||||
"namespace": "hwlab-dev",
|
||||
"labels": {
|
||||
"app.kubernetes.io/name": "hwlab-agent-mgr",
|
||||
"hwlab.pikastech.local/service-id": "hwlab-agent-mgr",
|
||||
"hwlab.pikastech.local/gitops-target": "g14",
|
||||
"hwlab.pikastech.local/source-commit": "bec4109af1bddd606683821c60186c0c89f72584"
|
||||
},
|
||||
"annotations": {
|
||||
"hwlab.pikastech.local/rendered-by": "scripts/g14-gitops-render.mjs"
|
||||
}
|
||||
},
|
||||
"spec": {
|
||||
"type": "ClusterIP",
|
||||
"selector": {
|
||||
"app.kubernetes.io/name": "hwlab-agent-mgr"
|
||||
},
|
||||
"ports": [
|
||||
{
|
||||
"name": "http",
|
||||
"port": 7410,
|
||||
"targetPort": "http"
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
{
|
||||
"apiVersion": "v1",
|
||||
"kind": "Service",
|
||||
"metadata": {
|
||||
"name": "hwlab-gateway-simu",
|
||||
"namespace": "hwlab-dev",
|
||||
"labels": {
|
||||
"app.kubernetes.io/name": "hwlab-gateway-simu",
|
||||
"hwlab.pikastech.local/service-id": "hwlab-gateway-simu",
|
||||
"hwlab.pikastech.local/gitops-target": "g14",
|
||||
"hwlab.pikastech.local/source-commit": "bec4109af1bddd606683821c60186c0c89f72584"
|
||||
},
|
||||
"annotations": {
|
||||
"hwlab.pikastech.local/rendered-by": "scripts/g14-gitops-render.mjs"
|
||||
}
|
||||
},
|
||||
"spec": {
|
||||
"type": "ClusterIP",
|
||||
"selector": {
|
||||
"app.kubernetes.io/name": "hwlab-gateway-simu"
|
||||
},
|
||||
"ports": [
|
||||
{
|
||||
"name": "http",
|
||||
"port": 7101,
|
||||
"targetPort": "http"
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
{
|
||||
"apiVersion": "v1",
|
||||
"kind": "Service",
|
||||
"metadata": {
|
||||
"name": "hwlab-box-simu",
|
||||
"namespace": "hwlab-dev",
|
||||
"labels": {
|
||||
"app.kubernetes.io/name": "hwlab-box-simu",
|
||||
"hwlab.pikastech.local/service-id": "hwlab-box-simu",
|
||||
"hwlab.pikastech.local/gitops-target": "g14",
|
||||
"hwlab.pikastech.local/source-commit": "bec4109af1bddd606683821c60186c0c89f72584"
|
||||
},
|
||||
"annotations": {
|
||||
"hwlab.pikastech.local/rendered-by": "scripts/g14-gitops-render.mjs"
|
||||
}
|
||||
},
|
||||
"spec": {
|
||||
"type": "ClusterIP",
|
||||
"selector": {
|
||||
"app.kubernetes.io/name": "hwlab-box-simu"
|
||||
},
|
||||
"ports": [
|
||||
{
|
||||
"name": "http",
|
||||
"port": 7201,
|
||||
"targetPort": "http"
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
{
|
||||
"apiVersion": "v1",
|
||||
"kind": "Service",
|
||||
"metadata": {
|
||||
"name": "hwlab-patch-panel",
|
||||
"namespace": "hwlab-dev",
|
||||
"labels": {
|
||||
"app.kubernetes.io/name": "hwlab-patch-panel",
|
||||
"hwlab.pikastech.local/service-id": "hwlab-patch-panel",
|
||||
"hwlab.pikastech.local/gitops-target": "g14",
|
||||
"hwlab.pikastech.local/source-commit": "bec4109af1bddd606683821c60186c0c89f72584"
|
||||
},
|
||||
"annotations": {
|
||||
"hwlab.pikastech.local/rendered-by": "scripts/g14-gitops-render.mjs"
|
||||
}
|
||||
},
|
||||
"spec": {
|
||||
"type": "ClusterIP",
|
||||
"selector": {
|
||||
"app.kubernetes.io/name": "hwlab-patch-panel"
|
||||
},
|
||||
"ports": [
|
||||
{
|
||||
"name": "http",
|
||||
"port": 7301,
|
||||
"targetPort": "http"
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
{
|
||||
"apiVersion": "v1",
|
||||
"kind": "Service",
|
||||
"metadata": {
|
||||
"name": "hwlab-router",
|
||||
"namespace": "hwlab-dev",
|
||||
"labels": {
|
||||
"app.kubernetes.io/name": "hwlab-router",
|
||||
"hwlab.pikastech.local/service-id": "hwlab-router",
|
||||
"hwlab.pikastech.local/gitops-target": "g14",
|
||||
"hwlab.pikastech.local/source-commit": "bec4109af1bddd606683821c60186c0c89f72584"
|
||||
},
|
||||
"annotations": {
|
||||
"hwlab.pikastech.local/rendered-by": "scripts/g14-gitops-render.mjs"
|
||||
}
|
||||
},
|
||||
"spec": {
|
||||
"type": "ClusterIP",
|
||||
"selector": {
|
||||
"app.kubernetes.io/name": "hwlab-router"
|
||||
},
|
||||
"ports": [
|
||||
{
|
||||
"name": "http",
|
||||
"port": 7401,
|
||||
"targetPort": "http"
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
{
|
||||
"apiVersion": "v1",
|
||||
"kind": "Service",
|
||||
"metadata": {
|
||||
"name": "hwlab-tunnel-client",
|
||||
"namespace": "hwlab-dev",
|
||||
"labels": {
|
||||
"app.kubernetes.io/name": "hwlab-tunnel-client",
|
||||
"hwlab.pikastech.local/service-id": "hwlab-tunnel-client",
|
||||
"hwlab.pikastech.local/gitops-target": "g14",
|
||||
"hwlab.pikastech.local/source-commit": "bec4109af1bddd606683821c60186c0c89f72584"
|
||||
},
|
||||
"annotations": {
|
||||
"hwlab.pikastech.local/rendered-by": "scripts/g14-gitops-render.mjs"
|
||||
}
|
||||
},
|
||||
"spec": {
|
||||
"type": "ClusterIP",
|
||||
"selector": {
|
||||
"app.kubernetes.io/name": "hwlab-tunnel-client"
|
||||
},
|
||||
"ports": [
|
||||
{
|
||||
"name": "http",
|
||||
"port": 7402,
|
||||
"targetPort": "http"
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
{
|
||||
"apiVersion": "v1",
|
||||
"kind": "Service",
|
||||
"metadata": {
|
||||
"name": "hwlab-edge-proxy",
|
||||
"namespace": "hwlab-dev",
|
||||
"labels": {
|
||||
"app.kubernetes.io/name": "hwlab-edge-proxy",
|
||||
"hwlab.pikastech.local/service-id": "hwlab-edge-proxy",
|
||||
"hwlab.pikastech.local/gitops-target": "g14",
|
||||
"hwlab.pikastech.local/source-commit": "bec4109af1bddd606683821c60186c0c89f72584"
|
||||
},
|
||||
"annotations": {
|
||||
"hwlab.pikastech.local/rendered-by": "scripts/g14-gitops-render.mjs"
|
||||
}
|
||||
},
|
||||
"spec": {
|
||||
"type": "ClusterIP",
|
||||
"selector": {
|
||||
"app.kubernetes.io/name": "hwlab-edge-proxy"
|
||||
},
|
||||
"ports": [
|
||||
{
|
||||
"name": "http",
|
||||
"port": 6667,
|
||||
"targetPort": "http"
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,11 +0,0 @@
|
||||
{
|
||||
"kind": "hwlab-g14-gitops-source",
|
||||
"sourceCommit": "bec4109af1bddd606683821c60186c0c89f72584",
|
||||
"sourceShortCommit": "bec4109",
|
||||
"sourceBranch": "G14",
|
||||
"sourceRepo": "git@github.com:pikasTech/HWLAB.git",
|
||||
"registryPrefix": "127.0.0.1:5000/hwlab",
|
||||
"runtimePath": "deploy/gitops/g14/runtime",
|
||||
"tektonPipeline": "hwlab-ci/hwlab-g14-ci-image-publish",
|
||||
"argoApplication": "argocd/hwlab-g14-dev"
|
||||
}
|
||||
@@ -1,326 +0,0 @@
|
||||
{
|
||||
"apiVersion": "tekton.dev/v1",
|
||||
"kind": "Pipeline",
|
||||
"metadata": {
|
||||
"name": "hwlab-g14-ci-image-publish",
|
||||
"namespace": "hwlab-ci",
|
||||
"labels": {
|
||||
"app.kubernetes.io/part-of": "hwlab",
|
||||
"hwlab.pikastech.local/gitops-target": "g14"
|
||||
},
|
||||
"annotations": {
|
||||
"hwlab.pikastech.local/source-config": "CI.json",
|
||||
"hwlab.pikastech.local/policy": "parallel-no-lock-ci-image-publish"
|
||||
}
|
||||
},
|
||||
"spec": {
|
||||
"params": [
|
||||
{
|
||||
"name": "git-url",
|
||||
"type": "string",
|
||||
"default": "git@github.com:pikasTech/HWLAB.git"
|
||||
},
|
||||
{
|
||||
"name": "source-branch",
|
||||
"type": "string",
|
||||
"default": "G14"
|
||||
},
|
||||
{
|
||||
"name": "revision",
|
||||
"type": "string",
|
||||
"description": "Full git commit SHA; the only source truth for image tags."
|
||||
},
|
||||
{
|
||||
"name": "registry-prefix",
|
||||
"type": "string",
|
||||
"default": "127.0.0.1:5000/hwlab"
|
||||
},
|
||||
{
|
||||
"name": "services",
|
||||
"type": "string",
|
||||
"default": "hwlab-cloud-api,hwlab-cloud-web,hwlab-agent-mgr,hwlab-agent-worker,hwlab-gateway,hwlab-gateway-simu,hwlab-box-simu,hwlab-patch-panel,hwlab-router,hwlab-tunnel-client,hwlab-edge-proxy,hwlab-cli,hwlab-agent-skills"
|
||||
},
|
||||
{
|
||||
"name": "base-image",
|
||||
"type": "string",
|
||||
"default": "node:20-bookworm-slim"
|
||||
},
|
||||
{
|
||||
"name": "concurrency",
|
||||
"type": "string",
|
||||
"default": "4"
|
||||
}
|
||||
],
|
||||
"workspaces": [
|
||||
{
|
||||
"name": "source"
|
||||
},
|
||||
{
|
||||
"name": "git-ssh"
|
||||
}
|
||||
],
|
||||
"tasks": [
|
||||
{
|
||||
"name": "ci-json",
|
||||
"workspaces": [
|
||||
{
|
||||
"name": "source",
|
||||
"workspace": "source"
|
||||
},
|
||||
{
|
||||
"name": "git-ssh",
|
||||
"workspace": "git-ssh"
|
||||
}
|
||||
],
|
||||
"taskSpec": {
|
||||
"params": [
|
||||
{
|
||||
"name": "git-url"
|
||||
},
|
||||
{
|
||||
"name": "source-branch"
|
||||
},
|
||||
{
|
||||
"name": "revision"
|
||||
}
|
||||
],
|
||||
"workspaces": [
|
||||
{
|
||||
"name": "source"
|
||||
},
|
||||
{
|
||||
"name": "git-ssh"
|
||||
}
|
||||
],
|
||||
"steps": [
|
||||
{
|
||||
"name": "ci-json",
|
||||
"image": "node:22-bookworm-slim",
|
||||
"env": [
|
||||
{
|
||||
"name": "HTTP_PROXY",
|
||||
"value": "http://127.0.0.1:10808"
|
||||
},
|
||||
{
|
||||
"name": "HTTPS_PROXY",
|
||||
"value": "http://127.0.0.1:10808"
|
||||
},
|
||||
{
|
||||
"name": "ALL_PROXY",
|
||||
"value": "socks5h://127.0.0.1:10808"
|
||||
},
|
||||
{
|
||||
"name": "NO_PROXY",
|
||||
"value": "127.0.0.1,localhost,::1,10.0.0.0/8,10.42.0.0/16,10.43.0.0/16,192.168.0.0/16,.svc,.cluster.local,kubernetes.default.svc,registry.hwlab-ci.svc,hwlab-registry.hwlab-ci.svc"
|
||||
},
|
||||
{
|
||||
"name": "http_proxy",
|
||||
"value": "http://127.0.0.1:10808"
|
||||
},
|
||||
{
|
||||
"name": "https_proxy",
|
||||
"value": "http://127.0.0.1:10808"
|
||||
},
|
||||
{
|
||||
"name": "all_proxy",
|
||||
"value": "socks5h://127.0.0.1:10808"
|
||||
},
|
||||
{
|
||||
"name": "no_proxy",
|
||||
"value": "127.0.0.1,localhost,::1,10.0.0.0/8,10.42.0.0/16,10.43.0.0/16,192.168.0.0/16,.svc,.cluster.local,kubernetes.default.svc,registry.hwlab-ci.svc,hwlab-registry.hwlab-ci.svc"
|
||||
}
|
||||
],
|
||||
"script": "#!/bin/sh\nset -eu\nif ! command -v git >/dev/null 2>&1 || ! command -v python3 >/dev/null 2>&1 || ! command -v ssh >/dev/null 2>&1; then\n export DEBIAN_FRONTEND=noninteractive\n apt-get update\n apt-get install -y --no-install-recommends git python3 openssh-client ca-certificates\n rm -rf /var/lib/apt/lists/*\nfi\nmkdir -p /root/.ssh\ncp /workspace/git-ssh/ssh-privatekey /root/.ssh/id_rsa\nchmod 600 /root/.ssh/id_rsa\nssh-keyscan github.com >> /root/.ssh/known_hosts 2>/dev/null\nrm -rf /workspace/source/repo\ngit clone --branch \"$(params.source-branch)\" \"$(params.git-url)\" /workspace/source/repo\ncd /workspace/source/repo\ngit checkout \"$(params.revision)\"\ntest \"$(git rev-parse HEAD)\" = \"$(params.revision)\"\nnpm ci --ignore-scripts\nnpx playwright install --with-deps chromium\necho 'CI.json hwlab-deploy-skeleton-ci command count=6'\necho 'CI.json command: repo-reports-guard'\nnode scripts/repo-reports-guard.mjs\necho 'CI.json command: contract-check'\nnpm run check\necho 'CI.json command: dev-artifact-publish-static-check'\nnode --check scripts/dev-artifact-publish.mjs\necho 'CI.json command: parse-deploy-json'\nnode -e \"JSON.parse(require('node:fs').readFileSync('deploy/deploy.json','utf8'))\"\necho 'CI.json command: parse-k8s-json-yaml'\nnode -e \"const fs=require('node:fs'); for (const f of fs.readdirSync('deploy/k8s/base').concat(fs.readdirSync('deploy/k8s/dev').map(x=>'../dev/'+x), fs.readdirSync('deploy/k8s/prod').map(x=>'../prod/'+x))) { if (!f.endsWith('.yaml')) continue; const p=f.startsWith('..')?'deploy/k8s/'+f.replace('../',''):'deploy/k8s/base/'+f; JSON.parse(fs.readFileSync(p,'utf8')); }\"\necho 'CI.json command: parse-frp-toml'\npython3 - <<'PY'\nimport pathlib, tomllib\nfor path in pathlib.Path('deploy/frp').glob('*.toml'):\n tomllib.loads(path.read_text())\nPY\n"
|
||||
}
|
||||
]
|
||||
},
|
||||
"params": [
|
||||
{
|
||||
"name": "git-url",
|
||||
"value": "$(params.git-url)"
|
||||
},
|
||||
{
|
||||
"name": "source-branch",
|
||||
"value": "$(params.source-branch)"
|
||||
},
|
||||
{
|
||||
"name": "revision",
|
||||
"value": "$(params.revision)"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "image-publish",
|
||||
"runAfter": [
|
||||
"ci-json"
|
||||
],
|
||||
"workspaces": [
|
||||
{
|
||||
"name": "source",
|
||||
"workspace": "source"
|
||||
}
|
||||
],
|
||||
"taskSpec": {
|
||||
"params": [
|
||||
{
|
||||
"name": "revision"
|
||||
},
|
||||
{
|
||||
"name": "registry-prefix"
|
||||
},
|
||||
{
|
||||
"name": "services"
|
||||
},
|
||||
{
|
||||
"name": "base-image"
|
||||
},
|
||||
{
|
||||
"name": "concurrency"
|
||||
}
|
||||
],
|
||||
"workspaces": [
|
||||
{
|
||||
"name": "source"
|
||||
}
|
||||
],
|
||||
"volumes": [
|
||||
{
|
||||
"name": "docker-run",
|
||||
"emptyDir": {}
|
||||
}
|
||||
],
|
||||
"sidecars": [
|
||||
{
|
||||
"name": "docker",
|
||||
"image": "docker:29-dind",
|
||||
"args": [
|
||||
"--host=unix:///var/run/docker.sock",
|
||||
"--storage-driver=vfs"
|
||||
],
|
||||
"env": [
|
||||
{
|
||||
"name": "DOCKER_TLS_CERTDIR",
|
||||
"value": ""
|
||||
},
|
||||
{
|
||||
"name": "HTTP_PROXY",
|
||||
"value": "http://127.0.0.1:10808"
|
||||
},
|
||||
{
|
||||
"name": "HTTPS_PROXY",
|
||||
"value": "http://127.0.0.1:10808"
|
||||
},
|
||||
{
|
||||
"name": "ALL_PROXY",
|
||||
"value": "socks5h://127.0.0.1:10808"
|
||||
},
|
||||
{
|
||||
"name": "NO_PROXY",
|
||||
"value": "127.0.0.1,localhost,::1,10.0.0.0/8,10.42.0.0/16,10.43.0.0/16,192.168.0.0/16,.svc,.cluster.local,kubernetes.default.svc,registry.hwlab-ci.svc,hwlab-registry.hwlab-ci.svc"
|
||||
},
|
||||
{
|
||||
"name": "http_proxy",
|
||||
"value": "http://127.0.0.1:10808"
|
||||
},
|
||||
{
|
||||
"name": "https_proxy",
|
||||
"value": "http://127.0.0.1:10808"
|
||||
},
|
||||
{
|
||||
"name": "all_proxy",
|
||||
"value": "socks5h://127.0.0.1:10808"
|
||||
},
|
||||
{
|
||||
"name": "no_proxy",
|
||||
"value": "127.0.0.1,localhost,::1,10.0.0.0/8,10.42.0.0/16,10.43.0.0/16,192.168.0.0/16,.svc,.cluster.local,kubernetes.default.svc,registry.hwlab-ci.svc,hwlab-registry.hwlab-ci.svc"
|
||||
}
|
||||
],
|
||||
"securityContext": {
|
||||
"privileged": true
|
||||
},
|
||||
"volumeMounts": [
|
||||
{
|
||||
"name": "docker-run",
|
||||
"mountPath": "/var/run"
|
||||
}
|
||||
]
|
||||
}
|
||||
],
|
||||
"steps": [
|
||||
{
|
||||
"name": "publish",
|
||||
"image": "node:22-alpine",
|
||||
"env": [
|
||||
{
|
||||
"name": "DOCKER_HOST",
|
||||
"value": "unix:///var/run/docker.sock"
|
||||
},
|
||||
{
|
||||
"name": "HTTP_PROXY",
|
||||
"value": "http://127.0.0.1:10808"
|
||||
},
|
||||
{
|
||||
"name": "HTTPS_PROXY",
|
||||
"value": "http://127.0.0.1:10808"
|
||||
},
|
||||
{
|
||||
"name": "ALL_PROXY",
|
||||
"value": "socks5h://127.0.0.1:10808"
|
||||
},
|
||||
{
|
||||
"name": "NO_PROXY",
|
||||
"value": "127.0.0.1,localhost,::1,10.0.0.0/8,10.42.0.0/16,10.43.0.0/16,192.168.0.0/16,.svc,.cluster.local,kubernetes.default.svc,registry.hwlab-ci.svc,hwlab-registry.hwlab-ci.svc"
|
||||
},
|
||||
{
|
||||
"name": "http_proxy",
|
||||
"value": "http://127.0.0.1:10808"
|
||||
},
|
||||
{
|
||||
"name": "https_proxy",
|
||||
"value": "http://127.0.0.1:10808"
|
||||
},
|
||||
{
|
||||
"name": "all_proxy",
|
||||
"value": "socks5h://127.0.0.1:10808"
|
||||
},
|
||||
{
|
||||
"name": "no_proxy",
|
||||
"value": "127.0.0.1,localhost,::1,10.0.0.0/8,10.42.0.0/16,10.43.0.0/16,192.168.0.0/16,.svc,.cluster.local,kubernetes.default.svc,registry.hwlab-ci.svc,hwlab-registry.hwlab-ci.svc"
|
||||
}
|
||||
],
|
||||
"volumeMounts": [
|
||||
{
|
||||
"name": "docker-run",
|
||||
"mountPath": "/var/run"
|
||||
}
|
||||
],
|
||||
"script": "#!/bin/sh\nset -eu\napk add --no-cache docker-cli git openssh-client python3\nexport DOCKER_HOST=unix:///var/run/docker.sock\nexport HWLAB_CI_ARTIFACT_RUN_ID=\"$(context.pipelineRun.name)\"\nexport HWLAB_CI_ARTIFACT_RUN_OWNER=\"tekton\"\nexport HWLAB_DEV_REGISTRY_PREFIX=\"$(params.registry-prefix)\"\nexport HWLAB_DEV_REGISTRY_K8S_NATIVE=1\nif [ -n \"$(params.base-image)\" ]; then export HWLAB_DEV_BASE_IMAGE=\"$(params.base-image)\"; fi\nfor i in $(seq 1 90); do docker info >/dev/null 2>&1 && break; sleep 2; done\ndocker info >/dev/null\nif [ -n \"${HWLAB_DEV_BASE_IMAGE:-}\" ]; then\n docker pull \"$HWLAB_DEV_BASE_IMAGE\"\nfi\ncd /workspace/source/repo\ntest \"$(git rev-parse HEAD)\" = \"$(params.revision)\"\nnode scripts/dev-artifact-publish.mjs --publish --registry-prefix \"$(params.registry-prefix)\" --report /workspace/source/dev-artifacts.json --quiet-build --concurrency \"$(params.concurrency)\" --services \"$(params.services)\"\nnode scripts/refresh-artifact-catalog.mjs --target-ref HEAD --publish-report /workspace/source/dev-artifacts.json --no-write\n"
|
||||
}
|
||||
]
|
||||
},
|
||||
"params": [
|
||||
{
|
||||
"name": "revision",
|
||||
"value": "$(params.revision)"
|
||||
},
|
||||
{
|
||||
"name": "registry-prefix",
|
||||
"value": "$(params.registry-prefix)"
|
||||
},
|
||||
{
|
||||
"name": "services",
|
||||
"value": "$(params.services)"
|
||||
},
|
||||
{
|
||||
"name": "base-image",
|
||||
"value": "$(params.base-image)"
|
||||
},
|
||||
{
|
||||
"name": "concurrency",
|
||||
"value": "$(params.concurrency)"
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
@@ -1,74 +0,0 @@
|
||||
{
|
||||
"apiVersion": "tekton.dev/v1",
|
||||
"kind": "PipelineRun",
|
||||
"metadata": {
|
||||
"generateName": "hwlab-g14-ci-",
|
||||
"namespace": "hwlab-ci",
|
||||
"labels": {
|
||||
"app.kubernetes.io/part-of": "hwlab",
|
||||
"hwlab.pikastech.local/gitops-target": "g14",
|
||||
"hwlab.pikastech.local/source-commit": "bec4109af1bddd606683821c60186c0c89f72584"
|
||||
}
|
||||
},
|
||||
"spec": {
|
||||
"pipelineRef": {
|
||||
"name": "hwlab-g14-ci-image-publish"
|
||||
},
|
||||
"taskRunTemplate": {
|
||||
"serviceAccountName": "hwlab-tekton-runner",
|
||||
"podTemplate": {
|
||||
"hostNetwork": true,
|
||||
"dnsPolicy": "ClusterFirstWithHostNet"
|
||||
}
|
||||
},
|
||||
"params": [
|
||||
{
|
||||
"name": "git-url",
|
||||
"value": "git@github.com:pikasTech/HWLAB.git"
|
||||
},
|
||||
{
|
||||
"name": "source-branch",
|
||||
"value": "G14"
|
||||
},
|
||||
{
|
||||
"name": "revision",
|
||||
"value": "bec4109af1bddd606683821c60186c0c89f72584"
|
||||
},
|
||||
{
|
||||
"name": "registry-prefix",
|
||||
"value": "127.0.0.1:5000/hwlab"
|
||||
},
|
||||
{
|
||||
"name": "base-image",
|
||||
"value": "node:20-bookworm-slim"
|
||||
},
|
||||
{
|
||||
"name": "concurrency",
|
||||
"value": "4"
|
||||
}
|
||||
],
|
||||
"workspaces": [
|
||||
{
|
||||
"name": "source",
|
||||
"volumeClaimTemplate": {
|
||||
"spec": {
|
||||
"accessModes": [
|
||||
"ReadWriteOnce"
|
||||
],
|
||||
"resources": {
|
||||
"requests": {
|
||||
"storage": "8Gi"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "git-ssh",
|
||||
"secret": {
|
||||
"secretName": "hwlab-git-ssh"
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
@@ -1,93 +0,0 @@
|
||||
{
|
||||
"apiVersion": "v1",
|
||||
"kind": "List",
|
||||
"items": [
|
||||
{
|
||||
"apiVersion": "v1",
|
||||
"kind": "Namespace",
|
||||
"metadata": {
|
||||
"name": "hwlab-ci"
|
||||
}
|
||||
},
|
||||
{
|
||||
"apiVersion": "v1",
|
||||
"kind": "ServiceAccount",
|
||||
"metadata": {
|
||||
"name": "hwlab-tekton-runner",
|
||||
"namespace": "hwlab-ci"
|
||||
}
|
||||
},
|
||||
{
|
||||
"apiVersion": "rbac.authorization.k8s.io/v1",
|
||||
"kind": "Role",
|
||||
"metadata": {
|
||||
"name": "hwlab-tekton-runtime-observer",
|
||||
"namespace": "hwlab-dev"
|
||||
},
|
||||
"rules": [
|
||||
{
|
||||
"apiGroups": [
|
||||
""
|
||||
],
|
||||
"resources": [
|
||||
"pods",
|
||||
"services",
|
||||
"configmaps"
|
||||
],
|
||||
"verbs": [
|
||||
"get",
|
||||
"list",
|
||||
"watch"
|
||||
]
|
||||
},
|
||||
{
|
||||
"apiGroups": [
|
||||
"apps"
|
||||
],
|
||||
"resources": [
|
||||
"deployments",
|
||||
"statefulsets"
|
||||
],
|
||||
"verbs": [
|
||||
"get",
|
||||
"list",
|
||||
"watch"
|
||||
]
|
||||
},
|
||||
{
|
||||
"apiGroups": [
|
||||
"batch"
|
||||
],
|
||||
"resources": [
|
||||
"jobs"
|
||||
],
|
||||
"verbs": [
|
||||
"get",
|
||||
"list",
|
||||
"watch"
|
||||
]
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"apiVersion": "rbac.authorization.k8s.io/v1",
|
||||
"kind": "RoleBinding",
|
||||
"metadata": {
|
||||
"name": "hwlab-tekton-runtime-observer",
|
||||
"namespace": "hwlab-dev"
|
||||
},
|
||||
"subjects": [
|
||||
{
|
||||
"kind": "ServiceAccount",
|
||||
"name": "hwlab-tekton-runner",
|
||||
"namespace": "hwlab-ci"
|
||||
}
|
||||
],
|
||||
"roleRef": {
|
||||
"apiGroup": "rbac.authorization.k8s.io",
|
||||
"kind": "Role",
|
||||
"name": "hwlab-tekton-runtime-observer"
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -7,7 +7,8 @@ G14 是 HWLAB 的旁路 DEV 集群目标。G14 CI/CD 必须只作用于 G14 k3s
|
||||
- Source of truth:业务版本以 Git source commit 为唯一身份;镜像 tag、OCI labels、runtime annotation 和 Argo CD desired state 都必须记录同一个 source commit。
|
||||
- CI:Tekton 在 G14 k3s 内运行 `hwlab-g14-ci-image-publish` Pipeline,读取 `CI.json` 命令,按 source commit 构建镜像并推送到 G14 registry。
|
||||
- Artifact:镜像使用 commit tag,例如 `127.0.0.1:5000/hwlab/hwlab-cloud-api:<shortCommit>`;digest 由 registry 返回,CI report 只作为审计证据,不作为 CD 真相。
|
||||
- CD:Argo CD 只消费 `deploy/gitops/g14/runtime` 的 Git desired state,不重新构建镜像,不读取 D601 状态,不获取 legacy DEV CD Lease。
|
||||
- Branch split:`G14` 是源码监控分支;`G14-gitops` 是 Tekton promotion 写入的生成分支,保存 `deploy/gitops/g14/**` desired state。
|
||||
- CD:Argo CD 只消费 `G14-gitops:deploy/gitops/g14/runtime` 的 Git desired state,不重新构建镜像,不读取 D601 状态,不获取 legacy DEV CD Lease。
|
||||
- 并行性:不同 source commit 的 CI build 不共享发布锁;并行安全由 immutable commit tag/digest 和 Git desired state 保证。最终运行版本由 Argo CD 当前同步的 Git revision 决定。
|
||||
|
||||
## 生成入口
|
||||
@@ -16,7 +17,9 @@ G14 是 HWLAB 的旁路 DEV 集群目标。G14 CI/CD 必须只作用于 G14 k3s
|
||||
|
||||
- 读取 `CI.json`,生成 Tekton Pipeline 和 PipelineRun 样板。
|
||||
- 读取 `deploy/deploy.json` 与 `deploy/k8s/*`,生成 Argo CD 可消费的 G14 runtime Kustomize path。
|
||||
- 生成 `hwlab-g14-branch-poller` CronJob:它使用 G14 集群内的 Git SSH Secret 轮询 `G14` 分支,按 source commit 创建确定命名的 Tekton PipelineRun。
|
||||
- 默认输出到 `deploy/gitops/g14/`。
|
||||
- 默认 GitOps 生成分支是 `G14-gitops`;Pipeline 成功后把本次 source commit 对应的 `deploy/gitops/g14/**` 推送到该分支,避免把生成提交继续写回 `G14`。
|
||||
- 默认 registry prefix 是 `127.0.0.1:5000/hwlab`,用于 G14 单节点 k3s 的 node-local registry。
|
||||
- 默认 CI/CD proxy 是 G14 本机 `http://127.0.0.1:10808` / `socks5h://127.0.0.1:10808`。Tekton CI step、Docker-in-Docker sidecar 和 publish step 都注入 proxy/no_proxy;publish step 必须先在 DIND 内 `docker pull $HWLAB_DEV_BASE_IMAGE`,再进入 DEV base-image preflight、build 和 registry push,保证 npm、Playwright Chromium 安装、base image 拉取和 registry push 走 G14 本机代理边界。CI step 固定使用 Node 22 Debian 镜像,避免 Playwright 官方镜像内 Node 版本漂移影响 `node --test`。
|
||||
|
||||
@@ -27,9 +30,17 @@ npm run g14:gitops:render -- --source-revision <sourceCommit>
|
||||
npm run g14:gitops:check
|
||||
```
|
||||
|
||||
## Polling 触发
|
||||
|
||||
G14 不要求 GitHub webhook 或 GitHub Actions 配置。`hwlab-ci/hwlab-g14-branch-poller` CronJob 每 5 分钟通过 Git SSH 拉取 `G14` HEAD,并用 source commit 的前 12 位生成 PipelineRun 名称 `hwlab-g14-ci-poll-<short12>`。
|
||||
|
||||
如果同名 PipelineRun 已存在,poller 直接跳过;如果不存在,则创建新的 PipelineRun。这样可以用 Kubernetes 原生 CronJob、ServiceAccount、RBAC 和 Tekton API 实现无 GitHub webhook 的分支监控,同时避免同一个 commit 被反复派单。历史上的 `chore: promote G14 GitOps source ...` 生成提交会被 poller 跳过。
|
||||
|
||||
Pipeline 的标准路径是:`G14` source commit -> `CI.json` Tekton 测试 -> commit-tagged image push 到 G14 registry -> render `deploy/gitops/g14/**` -> push `G14-gitops` -> Argo CD 同步 runtime。CD 只消费已经构建好的镜像和 Git desired state,不在 Argo CD 内构建镜像。
|
||||
|
||||
## 集群资源
|
||||
|
||||
- `hwlab-ci`:registry、Tekton runner RBAC、Pipeline/PipelineRun 所在 namespace。
|
||||
- `hwlab-ci`:registry、Tekton runner RBAC、Polling CronJob、Pipeline/PipelineRun 所在 namespace。
|
||||
- `argocd`:Argo CD 控制面和 `hwlab-g14-dev` Application 所在 namespace。
|
||||
- `hwlab-dev`:HWLAB runtime namespace,由 Argo CD 应用 `deploy/gitops/g14/runtime`。
|
||||
|
||||
|
||||
@@ -12,6 +12,7 @@ const defaultOutDir = "deploy/gitops/g14";
|
||||
const defaultRegistryPrefix = process.env.HWLAB_G14_REGISTRY_PREFIX || "127.0.0.1:5000/hwlab";
|
||||
const defaultSourceRepo = process.env.HWLAB_G14_GIT_URL || "git@github.com:pikasTech/HWLAB.git";
|
||||
const defaultBranch = process.env.HWLAB_G14_BRANCH || "G14";
|
||||
const defaultGitopsBranch = process.env.HWLAB_G14_GITOPS_BRANCH || "G14-gitops";
|
||||
const defaultRuntimeEndpoint = "http://hwlab-edge-proxy.hwlab-dev.svc.cluster.local:6667";
|
||||
const defaultWebEndpoint = "http://hwlab-cloud-web.hwlab-dev.svc.cluster.local:8080";
|
||||
const defaultProxyUrl = process.env.HWLAB_G14_PROXY_URL || "http://127.0.0.1:10808";
|
||||
@@ -38,6 +39,7 @@ function parseArgs(argv) {
|
||||
registryPrefix: defaultRegistryPrefix,
|
||||
sourceRevision: null,
|
||||
sourceBranch: defaultBranch,
|
||||
gitopsBranch: defaultGitopsBranch,
|
||||
sourceRepo: defaultSourceRepo,
|
||||
runtimeEndpoint: defaultRuntimeEndpoint,
|
||||
webEndpoint: defaultWebEndpoint,
|
||||
@@ -51,6 +53,7 @@ function parseArgs(argv) {
|
||||
else if (arg === "--registry-prefix") args.registryPrefix = readOption(argv, ++index, arg).replace(/\/+$/u, "");
|
||||
else if (arg === "--source-revision") args.sourceRevision = readOption(argv, ++index, arg);
|
||||
else if (arg === "--source-branch") args.sourceBranch = readOption(argv, ++index, arg);
|
||||
else if (arg === "--gitops-branch") args.gitopsBranch = readOption(argv, ++index, arg);
|
||||
else if (arg === "--source-repo") args.sourceRepo = readOption(argv, ++index, arg);
|
||||
else if (arg === "--runtime-endpoint") args.runtimeEndpoint = readOption(argv, ++index, arg);
|
||||
else if (arg === "--web-endpoint") args.webEndpoint = readOption(argv, ++index, arg);
|
||||
@@ -80,6 +83,7 @@ function usage() {
|
||||
` --out DIR default: ${defaultOutDir}`,
|
||||
` --source-repo URL default: ${defaultSourceRepo}`,
|
||||
` --source-branch BRANCH default: ${defaultBranch}`,
|
||||
` --gitops-branch BRANCH default: ${defaultGitopsBranch}`,
|
||||
" --source-revision SHA source commit used for image tags and runtime annotations; default: git rev-parse HEAD",
|
||||
` --registry-prefix PREFIX default: ${defaultRegistryPrefix}`,
|
||||
` --runtime-endpoint URL default: ${defaultRuntimeEndpoint}`,
|
||||
@@ -344,6 +348,184 @@ node scripts/refresh-artifact-catalog.mjs --target-ref HEAD --publish-report /wo
|
||||
`;
|
||||
}
|
||||
|
||||
function gitopsPromoteScript() {
|
||||
return `#!/bin/sh
|
||||
set -eu
|
||||
if ! command -v git >/dev/null 2>&1 || ! command -v ssh >/dev/null 2>&1; then
|
||||
export DEBIAN_FRONTEND=noninteractive
|
||||
apt-get update
|
||||
apt-get install -y --no-install-recommends git openssh-client ca-certificates
|
||||
rm -rf /var/lib/apt/lists/*
|
||||
fi
|
||||
mkdir -p /root/.ssh
|
||||
cp /workspace/git-ssh/ssh-privatekey /root/.ssh/id_rsa
|
||||
chmod 600 /root/.ssh/id_rsa
|
||||
ssh-keyscan github.com >> /root/.ssh/known_hosts 2>/dev/null || true
|
||||
export GIT_SSH_COMMAND="ssh -i /root/.ssh/id_rsa -o IdentitiesOnly=yes -o StrictHostKeyChecking=accept-new"
|
||||
cd /workspace/source/repo
|
||||
test "$(git rev-parse HEAD)" = "$(params.revision)"
|
||||
node scripts/g14-gitops-render.mjs --source-revision "$(params.revision)" --source-repo "$(params.git-url)" --source-branch "$(params.source-branch)" --gitops-branch "$(params.gitops-branch)" --registry-prefix "$(params.registry-prefix)"
|
||||
node scripts/g14-gitops-render.mjs --source-revision "$(params.revision)" --source-repo "$(params.git-url)" --source-branch "$(params.source-branch)" --gitops-branch "$(params.gitops-branch)" --registry-prefix "$(params.registry-prefix)" --check
|
||||
git config --global user.name "HWLAB G14 GitOps Bot"
|
||||
git config --global user.email "hwlab-g14-gitops-bot@users.noreply.github.com"
|
||||
workdir="$(mktemp -d)"
|
||||
git clone --no-checkout "$(params.git-url)" "$workdir/gitops"
|
||||
cd "$workdir/gitops"
|
||||
if git ls-remote --exit-code --heads origin "$(params.gitops-branch)" >/dev/null 2>&1; then
|
||||
git fetch origin "$(params.gitops-branch)"
|
||||
git checkout -B "$(params.gitops-branch)" "origin/$(params.gitops-branch)"
|
||||
rm -rf deploy/gitops/g14
|
||||
else
|
||||
git checkout --orphan "$(params.gitops-branch)"
|
||||
git rm -rf . >/dev/null 2>&1 || true
|
||||
fi
|
||||
mkdir -p deploy/gitops
|
||||
cp -a /workspace/source/repo/deploy/gitops/g14 deploy/gitops/g14
|
||||
git add deploy/gitops/g14
|
||||
if git diff --cached --quiet; then
|
||||
echo '{"status":"unchanged","gitopsBranch":"'"$(params.gitops-branch)"'","sourceRevision":"'"$(params.revision)"'"}'
|
||||
exit 0
|
||||
fi
|
||||
short="$(printf '%.7s' "$(params.revision)")"
|
||||
git commit -m "chore: promote G14 GitOps source $short"
|
||||
git push origin "HEAD:$(params.gitops-branch)"
|
||||
echo '{"status":"pushed","gitopsBranch":"'"$(params.gitops-branch)"'","sourceRevision":"'"$(params.revision)"'"}'
|
||||
`;
|
||||
}
|
||||
|
||||
function pollerScript() {
|
||||
return `#!/bin/sh
|
||||
set -eu
|
||||
apk add --no-cache git openssh-client ca-certificates
|
||||
mkdir -p /root/.ssh
|
||||
cp /workspace/git-ssh/ssh-privatekey /root/.ssh/id_rsa
|
||||
chmod 600 /root/.ssh/id_rsa
|
||||
ssh-keyscan github.com >> /root/.ssh/known_hosts 2>/dev/null || true
|
||||
export GIT_SSH_COMMAND="ssh -i /root/.ssh/id_rsa -o IdentitiesOnly=yes -o StrictHostKeyChecking=accept-new"
|
||||
workdir="$(mktemp -d)"
|
||||
git clone --depth 1 --branch "$SOURCE_BRANCH" "$GIT_URL" "$workdir/repo"
|
||||
cd "$workdir/repo"
|
||||
revision="$(git rev-parse HEAD)"
|
||||
subject="$(git log -1 --pretty=%s)"
|
||||
case "$subject" in
|
||||
"chore: promote G14 GitOps source "*)
|
||||
echo "Skipping generated GitOps promotion commit $revision"
|
||||
exit 0
|
||||
;;
|
||||
esac
|
||||
short="$(printf '%.12s' "$revision")"
|
||||
name="hwlab-g14-ci-poll-$short"
|
||||
export POLLER_REVISION="$revision"
|
||||
export POLLER_PIPELINERUN="$name"
|
||||
export POLLER_SOURCE_SUBJECT="$subject"
|
||||
echo "Checking G14 source $revision with PipelineRun $name"
|
||||
node <<'NODE'
|
||||
const fs = require("node:fs");
|
||||
const https = require("node:https");
|
||||
|
||||
function env(name, fallback) {
|
||||
return process.env[name] || fallback;
|
||||
}
|
||||
|
||||
const namespace = env("POD_NAMESPACE", "hwlab-ci");
|
||||
const name = env("POLLER_PIPELINERUN", "");
|
||||
const revision = env("POLLER_REVISION", "");
|
||||
const host = process.env.KUBERNETES_SERVICE_HOST;
|
||||
const port = process.env.KUBERNETES_SERVICE_PORT || "443";
|
||||
if (!name || !revision) throw new Error("poller did not resolve a PipelineRun name and revision");
|
||||
if (!host) throw new Error("KUBERNETES_SERVICE_HOST is not available");
|
||||
|
||||
const token = fs.readFileSync("/var/run/secrets/kubernetes.io/serviceaccount/token", "utf8");
|
||||
const ca = fs.readFileSync("/var/run/secrets/kubernetes.io/serviceaccount/ca.crt");
|
||||
|
||||
function request(method, path, body) {
|
||||
const payload = body ? JSON.stringify(body) : "";
|
||||
const headers = { Authorization: "Bearer " + token };
|
||||
if (payload) {
|
||||
headers["Content-Type"] = "application/json";
|
||||
headers["Content-Length"] = Buffer.byteLength(payload);
|
||||
}
|
||||
return new Promise((resolve, reject) => {
|
||||
const req = https.request({ host, port, method, path, ca, headers }, (res) => {
|
||||
let data = "";
|
||||
res.setEncoding("utf8");
|
||||
res.on("data", (chunk) => { data += chunk; });
|
||||
res.on("end", () => resolve({ statusCode: res.statusCode || 0, body: data }));
|
||||
});
|
||||
req.on("error", reject);
|
||||
if (payload) req.write(payload);
|
||||
req.end();
|
||||
});
|
||||
}
|
||||
|
||||
const labels = {
|
||||
"app.kubernetes.io/part-of": "hwlab",
|
||||
"hwlab.pikastech.local/gitops-target": "g14",
|
||||
"hwlab.pikastech.local/source-commit": revision,
|
||||
"hwlab.pikastech.local/trigger": "polling"
|
||||
};
|
||||
|
||||
const pipelineRun = {
|
||||
apiVersion: "tekton.dev/v1",
|
||||
kind: "PipelineRun",
|
||||
metadata: {
|
||||
name,
|
||||
namespace,
|
||||
labels,
|
||||
annotations: {
|
||||
"hwlab.pikastech.local/source-subject": env("POLLER_SOURCE_SUBJECT", ""),
|
||||
"hwlab.pikastech.local/source-branch": env("SOURCE_BRANCH", "G14"),
|
||||
"hwlab.pikastech.local/gitops-branch": env("GITOPS_BRANCH", "G14-gitops")
|
||||
}
|
||||
},
|
||||
spec: {
|
||||
pipelineRef: { name: env("PIPELINE_NAME", "hwlab-g14-ci-image-publish") },
|
||||
taskRunTemplate: {
|
||||
serviceAccountName: "hwlab-tekton-runner",
|
||||
podTemplate: { hostNetwork: true, dnsPolicy: "ClusterFirstWithHostNet" }
|
||||
},
|
||||
params: [
|
||||
{ name: "git-url", value: env("GIT_URL", "git@github.com:pikasTech/HWLAB.git") },
|
||||
{ name: "source-branch", value: env("SOURCE_BRANCH", "G14") },
|
||||
{ name: "gitops-branch", value: env("GITOPS_BRANCH", "G14-gitops") },
|
||||
{ name: "revision", value: revision },
|
||||
{ name: "registry-prefix", value: env("REGISTRY_PREFIX", "127.0.0.1:5000/hwlab") },
|
||||
{ name: "services", value: env("SERVICES", "hwlab-cloud-api,hwlab-cloud-web,hwlab-agent-mgr,hwlab-agent-worker,hwlab-gateway,hwlab-gateway-simu,hwlab-box-simu,hwlab-patch-panel,hwlab-router,hwlab-tunnel-client,hwlab-edge-proxy,hwlab-cli,hwlab-agent-skills") },
|
||||
{ name: "base-image", value: env("BASE_IMAGE", "node:20-bookworm-slim") },
|
||||
{ name: "concurrency", value: env("CONCURRENCY", "4") }
|
||||
],
|
||||
workspaces: [
|
||||
{ name: "source", volumeClaimTemplate: { spec: { accessModes: ["ReadWriteOnce"], resources: { requests: { storage: "8Gi" } } } } },
|
||||
{ name: "git-ssh", secret: { secretName: "hwlab-git-ssh" } }
|
||||
]
|
||||
}
|
||||
};
|
||||
|
||||
const base = "/apis/tekton.dev/v1/namespaces/" + encodeURIComponent(namespace) + "/pipelineruns";
|
||||
const item = base + "/" + encodeURIComponent(name);
|
||||
|
||||
(async () => {
|
||||
const existing = await request("GET", item);
|
||||
if (existing.statusCode === 200) {
|
||||
console.log(JSON.stringify({ status: "exists", pipelineRun: name, revision }));
|
||||
return;
|
||||
}
|
||||
if (existing.statusCode !== 404) {
|
||||
throw new Error("unexpected PipelineRun lookup status " + existing.statusCode + ": " + existing.body.slice(0, 500));
|
||||
}
|
||||
const created = await request("POST", base, pipelineRun);
|
||||
if (created.statusCode < 200 || created.statusCode > 299) {
|
||||
throw new Error("PipelineRun create failed with status " + created.statusCode + ": " + created.body.slice(0, 1000));
|
||||
}
|
||||
console.log(JSON.stringify({ status: "created", pipelineRun: name, revision }));
|
||||
})().catch((error) => {
|
||||
console.error(error.stack || error.message);
|
||||
process.exitCode = 1;
|
||||
});
|
||||
NODE
|
||||
`;
|
||||
}
|
||||
|
||||
function tektonRbac() {
|
||||
return {
|
||||
apiVersion: "v1",
|
||||
@@ -367,6 +549,21 @@ function tektonRbac() {
|
||||
metadata: { name: "hwlab-tekton-runtime-observer", namespace: "hwlab-dev" },
|
||||
subjects: [{ kind: "ServiceAccount", name: "hwlab-tekton-runner", namespace: "hwlab-ci" }],
|
||||
roleRef: { apiGroup: "rbac.authorization.k8s.io", kind: "Role", name: "hwlab-tekton-runtime-observer" }
|
||||
},
|
||||
{
|
||||
apiVersion: "rbac.authorization.k8s.io/v1",
|
||||
kind: "Role",
|
||||
metadata: { name: "hwlab-tekton-pipelinerun-writer", namespace: "hwlab-ci" },
|
||||
rules: [
|
||||
{ apiGroups: ["tekton.dev"], resources: ["pipelineruns"], verbs: ["get", "list", "create"] }
|
||||
]
|
||||
},
|
||||
{
|
||||
apiVersion: "rbac.authorization.k8s.io/v1",
|
||||
kind: "RoleBinding",
|
||||
metadata: { name: "hwlab-tekton-pipelinerun-writer", namespace: "hwlab-ci" },
|
||||
subjects: [{ kind: "ServiceAccount", name: "hwlab-tekton-runner", namespace: "hwlab-ci" }],
|
||||
roleRef: { apiGroup: "rbac.authorization.k8s.io", kind: "Role", name: "hwlab-tekton-pipelinerun-writer" }
|
||||
}
|
||||
]
|
||||
};
|
||||
@@ -392,6 +589,7 @@ function tektonPipeline(ci) {
|
||||
params: [
|
||||
{ name: "git-url", type: "string", default: defaultSourceRepo },
|
||||
{ name: "source-branch", type: "string", default: defaultBranch },
|
||||
{ name: "gitops-branch", type: "string", default: defaultGitopsBranch },
|
||||
{ name: "revision", type: "string", description: "Full git commit SHA; the only source truth for image tags." },
|
||||
{ name: "registry-prefix", type: "string", default: defaultRegistryPrefix },
|
||||
{ name: "services", type: "string", default: "hwlab-cloud-api,hwlab-cloud-web,hwlab-agent-mgr,hwlab-agent-worker,hwlab-gateway,hwlab-gateway-simu,hwlab-box-simu,hwlab-patch-panel,hwlab-router,hwlab-tunnel-client,hwlab-edge-proxy,hwlab-cli,hwlab-agent-skills" },
|
||||
@@ -461,6 +659,32 @@ function tektonPipeline(ci) {
|
||||
{ name: "base-image", value: "$(params.base-image)" },
|
||||
{ name: "concurrency", value: "$(params.concurrency)" }
|
||||
]
|
||||
},
|
||||
{
|
||||
name: "gitops-promote",
|
||||
runAfter: ["image-publish"],
|
||||
workspaces: [
|
||||
{ name: "source", workspace: "source" },
|
||||
{ name: "git-ssh", workspace: "git-ssh" }
|
||||
],
|
||||
taskSpec: {
|
||||
params: [
|
||||
{ name: "git-url" },
|
||||
{ name: "source-branch" },
|
||||
{ name: "gitops-branch" },
|
||||
{ name: "revision" },
|
||||
{ name: "registry-prefix" }
|
||||
],
|
||||
workspaces: [{ name: "source" }, { name: "git-ssh" }],
|
||||
steps: [{ name: "promote", image: "node:22-bookworm-slim", env: proxyEnv(), script: gitopsPromoteScript() }]
|
||||
},
|
||||
params: [
|
||||
{ name: "git-url", value: "$(params.git-url)" },
|
||||
{ name: "source-branch", value: "$(params.source-branch)" },
|
||||
{ name: "gitops-branch", value: "$(params.gitops-branch)" },
|
||||
{ name: "revision", value: "$(params.revision)" },
|
||||
{ name: "registry-prefix", value: "$(params.registry-prefix)" }
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -492,6 +716,7 @@ function tektonPipelineRunTemplate({ source, args }) {
|
||||
params: [
|
||||
{ name: "git-url", value: args.sourceRepo },
|
||||
{ name: "source-branch", value: args.sourceBranch },
|
||||
{ name: "gitops-branch", value: args.gitopsBranch },
|
||||
{ name: "revision", value: source.full },
|
||||
{ name: "registry-prefix", value: args.registryPrefix },
|
||||
{ name: "base-image", value: "node:20-bookworm-slim" },
|
||||
@@ -505,6 +730,71 @@ function tektonPipelineRunTemplate({ source, args }) {
|
||||
};
|
||||
}
|
||||
|
||||
function tektonPollerCronJob(args) {
|
||||
return {
|
||||
apiVersion: "batch/v1",
|
||||
kind: "CronJob",
|
||||
metadata: {
|
||||
name: "hwlab-g14-branch-poller",
|
||||
namespace: "hwlab-ci",
|
||||
labels: {
|
||||
"app.kubernetes.io/part-of": "hwlab",
|
||||
"hwlab.pikastech.local/gitops-target": "g14"
|
||||
},
|
||||
annotations: {
|
||||
"hwlab.pikastech.local/source-branch": args.sourceBranch,
|
||||
"hwlab.pikastech.local/gitops-branch": args.gitopsBranch
|
||||
}
|
||||
},
|
||||
spec: {
|
||||
schedule: "*/5 * * * *",
|
||||
concurrencyPolicy: "Forbid",
|
||||
successfulJobsHistoryLimit: 3,
|
||||
failedJobsHistoryLimit: 3,
|
||||
jobTemplate: {
|
||||
spec: {
|
||||
backoffLimit: 1,
|
||||
template: {
|
||||
metadata: {
|
||||
labels: {
|
||||
"app.kubernetes.io/part-of": "hwlab",
|
||||
"hwlab.pikastech.local/gitops-target": "g14"
|
||||
}
|
||||
},
|
||||
spec: {
|
||||
serviceAccountName: "hwlab-tekton-runner",
|
||||
restartPolicy: "Never",
|
||||
hostNetwork: true,
|
||||
dnsPolicy: "ClusterFirstWithHostNet",
|
||||
containers: [{
|
||||
name: "poll",
|
||||
image: "node:22-alpine",
|
||||
imagePullPolicy: "IfNotPresent",
|
||||
env: [
|
||||
...proxyEnv(),
|
||||
{ name: "POD_NAMESPACE", valueFrom: { fieldRef: { fieldPath: "metadata.namespace" } } },
|
||||
{ name: "PIPELINE_NAME", value: "hwlab-g14-ci-image-publish" },
|
||||
{ name: "GIT_URL", value: args.sourceRepo },
|
||||
{ name: "SOURCE_BRANCH", value: args.sourceBranch },
|
||||
{ name: "GITOPS_BRANCH", value: args.gitopsBranch },
|
||||
{ name: "REGISTRY_PREFIX", value: args.registryPrefix },
|
||||
{ name: "SERVICES", value: "hwlab-cloud-api,hwlab-cloud-web,hwlab-agent-mgr,hwlab-agent-worker,hwlab-gateway,hwlab-gateway-simu,hwlab-box-simu,hwlab-patch-panel,hwlab-router,hwlab-tunnel-client,hwlab-edge-proxy,hwlab-cli,hwlab-agent-skills" },
|
||||
{ name: "BASE_IMAGE", value: "node:20-bookworm-slim" },
|
||||
{ name: "CONCURRENCY", value: "4" }
|
||||
],
|
||||
volumeMounts: [{ name: "git-ssh", mountPath: "/workspace/git-ssh", readOnly: true }],
|
||||
command: ["/bin/sh", "-c"],
|
||||
args: [pollerScript()]
|
||||
}],
|
||||
volumes: [{ name: "git-ssh", secret: { secretName: "hwlab-git-ssh" } }]
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
function registryManifest() {
|
||||
return {
|
||||
apiVersion: "v1",
|
||||
@@ -574,7 +864,7 @@ function argoApplication(args) {
|
||||
},
|
||||
spec: {
|
||||
project: "hwlab-g14",
|
||||
source: { repoURL: args.sourceRepo, targetRevision: args.sourceBranch, path: "deploy/gitops/g14/runtime" },
|
||||
source: { repoURL: args.sourceRepo, targetRevision: args.gitopsBranch, path: "deploy/gitops/g14/runtime" },
|
||||
destination: { server: "https://kubernetes.default.svc", namespace: "hwlab-dev" },
|
||||
syncPolicy: { automated: { prune: false, selfHeal: true }, syncOptions: ["CreateNamespace=true", "ApplyOutOfSyncOnly=true"] }
|
||||
}
|
||||
@@ -598,7 +888,8 @@ This directory is generated from \`CI.json\`, \`deploy/deploy.json\`, and \`depl
|
||||
- Target: G14 k3s only.
|
||||
- CI: Tekton Pipeline \`hwlab-ci/hwlab-g14-ci-image-publish\`.
|
||||
- Artifact contract: images are tagged by source git commit \`${source.short}\` and pushed to \`${args.registryPrefix}\`.
|
||||
- CD: Argo CD Application \`argocd/hwlab-g14-dev\` consumes \`deploy/gitops/g14/runtime\`.
|
||||
- Branch split: source branch \`${args.sourceBranch}\` remains the watched code branch; generated desired state is promoted to \`${args.gitopsBranch}\`.
|
||||
- CD: Argo CD Application \`argocd/hwlab-g14-dev\` consumes \`${args.gitopsBranch}:deploy/gitops/g14/runtime\`.
|
||||
- D601 boundary: this path does not target D601, does not use UniDesk Code Queue, and does not change D601 production traffic.
|
||||
- Concurrency: CI builds are per source commit and do not acquire the legacy DEV CD Lease; Argo CD reconciles the Git desired state.
|
||||
`;
|
||||
@@ -630,6 +921,7 @@ async function plannedFiles(args) {
|
||||
sourceCommit: source.full,
|
||||
sourceShortCommit: source.short,
|
||||
sourceBranch: args.sourceBranch,
|
||||
gitopsBranch: args.gitopsBranch,
|
||||
sourceRepo: args.sourceRepo,
|
||||
registryPrefix: args.registryPrefix,
|
||||
runtimePath: "deploy/gitops/g14/runtime",
|
||||
@@ -640,6 +932,7 @@ async function plannedFiles(args) {
|
||||
putJson("registry/registry.yaml", registryManifest());
|
||||
putJson("tekton/rbac.yaml", tektonRbac());
|
||||
putJson("tekton/pipeline.yaml", tektonPipeline(ci));
|
||||
putJson("tekton/poller.yaml", tektonPollerCronJob(args));
|
||||
putJson("tekton/pipelinerun.sample.yaml", tektonPipelineRunTemplate({ source, args }));
|
||||
putJson("argocd/project.yaml", argoProject());
|
||||
putJson("argocd/application.yaml", argoApplication(args));
|
||||
|
||||
Reference in New Issue
Block a user