fix: 隔离 HWLAB production 交付身份
This commit is contained in:
@@ -299,7 +299,7 @@ lanes:
|
||||
install:
|
||||
stateDir: /tmp/hwlab-release-source-workspace-bootstrap
|
||||
sourceAuthority:
|
||||
giteaMirrorRepoKey: hwlab-nc01-v03
|
||||
giteaMirrorRepoKey: hwlab-nc01-production
|
||||
cicdRepo: /root/hwlab-release-cicd.git
|
||||
cicdRepoLock: /tmp/hwlab-release-cicd-repo.lock
|
||||
app: hwlab-node-production
|
||||
|
||||
@@ -375,6 +375,28 @@ sourceAuthority:
|
||||
readUrl: http://git-mirror-http.devops-infra.svc.cluster.local:8080/pikasTech/HWLAB.git
|
||||
configRef: config/hwlab-node-lanes.yaml#lanes.v03.targets.NC01.git.readUrl
|
||||
disposition: replaced-by-gitea
|
||||
- key: hwlab-nc01-production
|
||||
targetId: NC01
|
||||
upstream:
|
||||
repository: pikasTech/HWLAB
|
||||
cloneUrl: https://github.com/pikasTech/HWLAB.git
|
||||
branch: release
|
||||
gitea:
|
||||
owner: mirrors
|
||||
name: pikasTech-HWLAB
|
||||
mirrorMode: controlled-push
|
||||
publicRead: true
|
||||
readUrl: http://gitea-http.devops-infra.svc.cluster.local:3000/mirrors/pikasTech-HWLAB.git
|
||||
gitops:
|
||||
branch: release-gitops
|
||||
flushDisposition: retained-for-gitops-flush
|
||||
snapshot:
|
||||
naming: gitea-actions-immutable-source
|
||||
prefix: refs/unidesk/snapshots/gitea-actions/hwlab-node-runtime/release
|
||||
legacyGitMirror:
|
||||
readUrl: http://git-mirror-http.devops-infra.svc.cluster.local:8080/pikasTech/HWLAB.git
|
||||
configRef: config/hwlab-node-lanes.yaml#lanes.production.targets.NC01.git.readUrl
|
||||
disposition: replaced-by-gitea
|
||||
- key: selfmedia-nc01
|
||||
targetId: NC01
|
||||
credentialOverride:
|
||||
|
||||
@@ -214,6 +214,10 @@ repositories:
|
||||
variables:
|
||||
NODE: NC01
|
||||
LANE: v03
|
||||
- extends: templates.repositories.hwlabProduction
|
||||
variables:
|
||||
NODE: NC01
|
||||
LANE: production
|
||||
- id: selfmedia-nc01
|
||||
name: selfmedia-nc01
|
||||
namespace: selfmedia-ci
|
||||
@@ -434,20 +438,11 @@ consumers:
|
||||
NODE: NC01
|
||||
LANE: production
|
||||
id: hwlab-nc01-production
|
||||
repositoryRef: hwlab-nc01-v03
|
||||
repositoryRef: hwlab-nc01-production
|
||||
lane: production
|
||||
pipeline: hwlab-nc01-production-ci-image-publish
|
||||
pipelineRunPrefix: hwlab-nc01-production-ci-poll
|
||||
argoApplication: hwlab-node-production
|
||||
params:
|
||||
source_branch: release
|
||||
gitops_branch: release-gitops
|
||||
source_snapshot_prefix: refs/unidesk/snapshots/gitea-actions/hwlab-node-runtime/release
|
||||
pipeline_name: hwlab-nc01-production-ci-image-publish
|
||||
pipeline_run_prefix: hwlab-nc01-production-ci-poll
|
||||
service_account: hwlab-nc01-production-tekton-runner
|
||||
lane: production
|
||||
runtime_namespace: hwlab-production
|
||||
sourceArtifact:
|
||||
mode: remote-pipeline-annotation
|
||||
renderer: hwlab-runtime-lane
|
||||
@@ -758,6 +753,34 @@ templates:
|
||||
node: "${NODE}"
|
||||
lane: v03
|
||||
runtime_namespace: hwlab-v03
|
||||
hwlabProduction:
|
||||
id: "hwlab-${nodeLower}-production"
|
||||
name: "hwlab-${nodeLower}-production"
|
||||
namespace: hwlab-ci
|
||||
providerType: gitea
|
||||
url: https://gitea.pikapython.com/mirrors/pikasTech-HWLAB
|
||||
cloneUrl: http://gitea-http.devops-infra.svc.cluster.local:3000/mirrors/pikasTech-HWLAB.git
|
||||
owner: mirrors
|
||||
repo: pikasTech-HWLAB
|
||||
secretName: "pac-gitea-hwlab-${nodeLower}-production"
|
||||
tokenKey: token
|
||||
webhookSecretKey: webhook.secret
|
||||
concurrencyLimit: 1
|
||||
params:
|
||||
git_read_url: http://gitea-http.devops-infra.svc.cluster.local:3000/mirrors/pikasTech-HWLAB.git
|
||||
git_write_url: http://git-mirror-write.devops-infra.svc.cluster.local:8080/pikasTech/HWLAB.git
|
||||
source_branch: release
|
||||
gitops_branch: release-gitops
|
||||
source_snapshot_prefix: refs/unidesk/snapshots/gitea-actions/hwlab-node-runtime/release
|
||||
pipeline_name: "hwlab-${nodeLower}-production-ci-image-publish"
|
||||
pipeline_run_prefix: "hwlab-${nodeLower}-production-ci-poll"
|
||||
service_account: "hwlab-${nodeLower}-production-tekton-runner"
|
||||
workspace_pvc_size: 8Gi
|
||||
git_ssh_secret: hwlab-git-ssh
|
||||
pipeline_timeout: 1h0m0s
|
||||
node: "${NODE}"
|
||||
lane: production
|
||||
runtime_namespace: hwlab-production
|
||||
consumers:
|
||||
agentrunV02:
|
||||
id: "agentrun-${nodeLower}-v02"
|
||||
|
||||
@@ -19,23 +19,48 @@
|
||||
- `https://hwlab.pikapython.com` YAML publicExposure;
|
||||
- PostgreSQL database、role、Secret consumer 和 migration ledger;
|
||||
- Kafka client、direct publish、refresh replay、projector 和 live SSE consumer group。
|
||||
- production 与 development 共享同一个 HWLAB Gitea PaC Repository CR;两个 lane 使用独立 consumer,并由 consumer params 覆盖 source branch、snapshot、Pipeline 和 runtime identity。
|
||||
- 共享 Repository 避免同一镜像仓库重复声明 PaC Repository;独立 consumer 仍保持 production 自动交付路径与 development 完全隔离。
|
||||
- `lanes.production.targets.NC01.sourceAuthority.giteaMirrorRepoKey` 已统一为共享 authority `hwlab-nc01-v03`,不再引用不存在的 production repo key。
|
||||
- delivery authority parser 以 consumer params 解析 branch 与 snapshot:
|
||||
- 显式 consumer override 优先;
|
||||
- 未显式覆盖时继承 Repository 默认;
|
||||
- 多分支镜像优先匹配同 branch authority;
|
||||
- 唯一共享镜像允许 production consumer 复用同一 Repository。
|
||||
- production 与 development 复用同一个 Gitea 物理仓库
|
||||
`mirrors/pikasTech-HWLAB`,但分别声明独立 YAML source identity:
|
||||
- development:`hwlab-nc01-v03` / `v0.3` / `v0.3-gitops`;
|
||||
- production:`hwlab-nc01-production` / `release` / `release-gitops`。
|
||||
- production PaC consumer 精确引用 `hwlab-nc01-production` repository identity;
|
||||
branch、snapshot 和 GitOps revision 由该 repository identity 声明,
|
||||
不再由 consumer params 覆盖 development identity。
|
||||
- `lanes.production.targets.NC01.sourceAuthority.giteaMirrorRepoKey`
|
||||
精确引用 `hwlab-nc01-production`。
|
||||
- delivery authority parser 已删除同 target/owner/repo 的跨 branch fallback:
|
||||
- 必须同时精确匹配 target、Gitea owner/name 和 source branch;
|
||||
- 缺少或冲突时 fail-closed;
|
||||
- 禁止把 `v0.3` identity 猜作 `release` authority。
|
||||
- 通用 HWLAB lane parser 和 plan 已投影 migration ledger,并从 owning YAML 动态生成合法 lane 提示。
|
||||
- `config/platform-infra/kafka.yaml` 已声明 production Cloud API Kafka ACL,未改变 topic、实时和回放架构。
|
||||
|
||||
## 方案依据
|
||||
|
||||
- OpenGitOps 原则要求 desired state 声明式、版本化且不可变,并由软件代理自动拉取和持续 reconcile;因此 branch identity 与 immutable snapshot 必须由 owning YAML 明确声明,不能依赖运行时猜测。
|
||||
- Tekton Pipelines 将 Git revision 作为显式输入:
|
||||
- source branch 只负责选择受控镜像入口;
|
||||
- 实际构建继续使用受控 snapshot/commit revision;
|
||||
- mutable branch 名不直接充当构建 provenance。
|
||||
- Argo CD 的 `targetRevision` 明确选择 Git branch、tag 或 commit;production 使用独立 `release-gitops`,避免与 `v0.3-gitops` 共用可变 desired state。
|
||||
- Kubernetes 建议以不可变 image digest 或等价内容寻址 revision
|
||||
固定工作负载版本:
|
||||
- Pipeline 继续产出 commit-pinned artifact;
|
||||
- GitOps/Argo 只消费已固定 revision;
|
||||
- 禁止从运行面或脏 workspace 构建。
|
||||
- 官方参考:
|
||||
- OpenGitOps principles:<https://opengitops.dev/>;
|
||||
- Tekton Git resolver revision:<https://tekton.dev/docs/pipelines/git-resolver/>;
|
||||
- Argo CD tracking strategies:<https://argo-cd.readthedocs.io/en/stable/user-guide/tracking_strategies/>;
|
||||
- Kubernetes image digest:<https://kubernetes.io/docs/concepts/containers/images/>。
|
||||
|
||||
## Target 原入口证据
|
||||
|
||||
以下命令均在 `NC01:/root/unidesk/.worktree/2010-hwlab-release-production-lane` 执行:
|
||||
|
||||
- `git diff --check`:通过。
|
||||
- `bun --check`:
|
||||
- `scripts/src/cicd-delivery-authority.ts`:通过;
|
||||
- `scripts/src/hwlab-fake-model-provider.ts`:通过;
|
||||
- `scripts/src/hwlab-node-lanes.ts`:通过;
|
||||
- `scripts/src/hwlab-node/entry.ts`:通过;
|
||||
@@ -50,19 +75,22 @@
|
||||
- namespace 为 `hwlab-v03`;
|
||||
- development 配置继续可解析。
|
||||
- `bun scripts/cli.ts platform-infra pipelines-as-code plan --target NC01 --consumer hwlab-nc01-production`:
|
||||
- Repository 为共享的 `hwlab-nc01-v03`;
|
||||
- Repository 为独立 identity `hwlab-nc01-production`;
|
||||
- consumer 为独立的 `hwlab-nc01-production`;
|
||||
- Tekton Pipeline 为 `hwlab-nc01-production-ci-image-publish`;
|
||||
- Argo Application 为 `hwlab-node-production`;
|
||||
- `single-path`、`yaml-source-of-truth`、`public-repository-url`、`gitea-internal-source` 和 `runtime-zero-docker` 均为 `true`。
|
||||
- `bun scripts/cli.ts platform-infra pipelines-as-code plan --target NC01 --consumer hwlab-nc01-v03`:通过,development consumer 保持独立。
|
||||
- delivery authority 与 renderer 定向断言通过:
|
||||
- NC01 只声明一个 HWLAB Gitea repository,key 为 `hwlab-nc01-v03`;
|
||||
- production 与 v03 的 `repositoryRef` 均为 `hwlab-nc01-v03`;
|
||||
- production consumer 保持 `hwlab-nc01-production`;
|
||||
- production branch 为 `release`,snapshot prefix 为 release 独立前缀;
|
||||
- authority 解析结果为 `pac-pr-merge`;
|
||||
- feature config renderer 使用 production consumer。
|
||||
- NC01 声明两个 HWLAB source identity,分别为
|
||||
`hwlab-nc01-v03` 与 `hwlab-nc01-production`;
|
||||
- 两个 identity 指向同一 Gitea 物理仓库;
|
||||
- production `repositoryRef` 为 `hwlab-nc01-production`,branch 为 `release`;
|
||||
- development `repositoryRef` 为 `hwlab-nc01-v03`,branch 为 `v0.3`;
|
||||
- 两个 lane 的 snapshot prefix 与 GitOps branch 独立;
|
||||
- production consumer 携带 `v0.3` source branch 查询时返回
|
||||
`authority-identity-mismatch`,证明跨 branch fail-closed;
|
||||
- parser 源码不再包含 `branchAuthorityRepositories` fallback。
|
||||
- 纯 Kafka 定向断言通过:
|
||||
- `directPublish`、`liveKafkaSse`、`kafkaRefreshReplay` 为 `true`;
|
||||
- `transactionalProjector`、`projectionOutboxRelay`、`projectionRealtime` 为 `false`;
|
||||
@@ -72,7 +100,18 @@
|
||||
- GitOps branch、runtime namespace、Argo Application、public origin;
|
||||
- PostgreSQL database、role、Secret、migration ledger;
|
||||
- Kafka direct publish、refresh replay 和 live SSE group;
|
||||
- shared Repository、independent consumer 和各 lane branch 参数。
|
||||
- shared physical Gitea repository、independent source/repository/consumer identity。
|
||||
|
||||
## 验证边界
|
||||
|
||||
- `platform-infra gitea validate --target NC01` 未能进入本任务新增 identity 的运行面校验:
|
||||
- 命令先被既有 `agentrun-nc01-release` 的
|
||||
`legacyGitMirror.configRef` 缺失阻断;
|
||||
- 该缺失存在于 `origin/master`,不属于本任务改动;
|
||||
- 本轮未扩大范围修复该独立问题。
|
||||
- 因用户明确禁止人工 mirror、PipelineRun、Argo 和创建 `release` branch,
|
||||
本轮证据证明的是 YAML 声明、controlled-push 选择、PaC binding 与 fail-closed 隔离;
|
||||
合并后的真实自动链仍由后续授权阶段通过正常 GitHub release 提交触发。
|
||||
|
||||
## Primary Workspace 边界
|
||||
|
||||
|
||||
@@ -21,6 +21,16 @@
|
||||
- patch 不得改变交付 authority 或冒充终态;
|
||||
- 结论必须写回 owning YAML/源码并由正常 PR 自动交付;
|
||||
- 临时 patch 随后撤销或由声明式交付覆盖。
|
||||
- HWLAB production release delivery authority:
|
||||
- development 与 production 复用同一个
|
||||
`mirrors/pikasTech-HWLAB` Gitea 物理仓库;
|
||||
- owning YAML 必须分别声明 `hwlab-nc01-v03` 与
|
||||
`hwlab-nc01-production` source identity;
|
||||
- production identity 固定选择 `release`、独立 immutable snapshot prefix
|
||||
与 `release-gitops`;
|
||||
- production PaC consumer 必须精确引用 production repository identity;
|
||||
- delivery authority parser 必须精确匹配 target、owner/name 与 branch,
|
||||
缺少 production identity 时 fail-closed,禁止回退到 `v0.3`。
|
||||
- 进入任何 HWLAB 工作前,按 `NC01/v03` 解析 route/workspace/sourceBranch/kubeRoute/runtime namespace 做预检、快进和验证:工作面是 `NC01:/root/hwlab-v03`、source branch 是 `v0.3`、k3s route 是 `NC01:k3s`、runtime namespace 是 `hwlab-v03`、公网入口由 YAML 的 NC01 target 声明。
|
||||
- NC01 的 node-local registry 是 k3s workload/PVC,不是 host Docker registry。`hwlab nodes control-plane infra status --node NC01 --lane v03` 应显示 registry workload ready、PVC bound 和 endpoint ready;必须通过受控 `runtime-image preload` 和 `infra tools-image build/status` 补齐 BuildKit、runtime/base 和 tools image,再把 HWLAB/AgentRun status 与 web-probe smoke 作为可用性证据。
|
||||
- HWLAB 项目内长期规则入口仍以目标 repo 的 `AGENTS.md` 为准。进入已解析的目标 workspace 后,必须重新读取该 workspace 的规则文件;不能只凭主 server 的压缩上下文继续操作。
|
||||
|
||||
@@ -149,20 +149,12 @@ export function readCicdDeliveryAuthorityCatalog(): CicdDeliveryAuthorityCatalog
|
||||
pacRepositories.filter((candidate) => same(candidate.id, repositoryRef)),
|
||||
`${path}.repositoryRef=${repositoryRef}`,
|
||||
);
|
||||
const params = item.params === undefined ? null : record(item.params, `${path}.params`);
|
||||
const sourceBranch = params === null
|
||||
? pacRepository.sourceBranch
|
||||
: requiredString(params.source_branch ?? pacRepository.sourceBranch, `${path}.params.source_branch`);
|
||||
const sourceSnapshotPrefix = params === null
|
||||
? pacRepository.sourceSnapshotPrefix
|
||||
: requiredString(params.source_snapshot_prefix ?? pacRepository.sourceSnapshotPrefix, `${path}.params.source_snapshot_prefix`);
|
||||
const authorityRepositories = giteaRepositories.filter((candidate) => same(candidate.targetId, node)
|
||||
&& same(candidate.owner, pacRepository.owner)
|
||||
&& same(candidate.repo, pacRepository.repo));
|
||||
const branchAuthorityRepositories = authorityRepositories.filter((candidate) => same(candidate.sourceBranch, sourceBranch));
|
||||
const authorityRepository = exactlyOne(
|
||||
branchAuthorityRepositories.length > 0 ? branchAuthorityRepositories : authorityRepositories,
|
||||
`${path} source authority ${node}/${pacRepository.owner}/${pacRepository.repo}@${sourceBranch}`,
|
||||
giteaRepositories.filter((candidate) => same(candidate.targetId, node)
|
||||
&& same(candidate.owner, pacRepository.owner)
|
||||
&& same(candidate.repo, pacRepository.repo)
|
||||
&& same(candidate.sourceBranch, pacRepository.sourceBranch)),
|
||||
`${path} source authority ${node}/${pacRepository.owner}/${pacRepository.repo}@${pacRepository.sourceBranch}`,
|
||||
);
|
||||
return {
|
||||
consumerId,
|
||||
@@ -172,8 +164,8 @@ export function readCicdDeliveryAuthorityCatalog(): CicdDeliveryAuthorityCatalog
|
||||
pipelineRunPrefix,
|
||||
repositoryRef,
|
||||
sourceRepository: authorityRepository.sourceRepository,
|
||||
sourceBranch,
|
||||
sourceSnapshotPrefix,
|
||||
sourceBranch: authorityRepository.sourceBranch,
|
||||
sourceSnapshotPrefix: pacRepository.sourceSnapshotPrefix,
|
||||
giteaOwner: pacRepository.owner,
|
||||
giteaRepository: pacRepository.repo,
|
||||
giteaRepositoryUrl: pacRepository.url,
|
||||
|
||||
Reference in New Issue
Block a user