feat: add v0.1 gitops ci templates
This commit is contained in:
@@ -2,6 +2,8 @@
|
|||||||
logs/
|
logs/
|
||||||
node_modules/
|
node_modules/
|
||||||
package-lock.json
|
package-lock.json
|
||||||
|
deploy/artifact-catalog.v01.json
|
||||||
|
deploy/gitops/g14/
|
||||||
dist/
|
dist/
|
||||||
build/
|
build/
|
||||||
coverage/
|
coverage/
|
||||||
|
|||||||
@@ -8,11 +8,11 @@ AgentRun 是面向 UniDesk 与 HWLAB 的共享 Agent 执行基础设施。本仓
|
|||||||
- P0: 代码标识符、API 路径、命令、配置键、日志字段、协议字段和必要英文专有名词可以保留英文,但解释性文字必须使用中文。
|
- P0: 代码标识符、API 路径、命令、配置键、日志字段、协议字段和必要英文专有名词可以保留英文,但解释性文字必须使用中文。
|
||||||
- P0: 外部英文资料只能作为引用或短摘录出现;落入本仓库的设计结论、验收标准和操作说明必须转写为中文。
|
- P0: 外部英文资料只能作为引用或短摘录出现;落入本仓库的设计结论、验收标准和操作说明必须转写为中文。
|
||||||
|
|
||||||
## Critical Source Workspace Rule
|
## Critical Source Worktree Rule
|
||||||
|
|
||||||
- P0: `v0.1` 长期 source workspace 是 `G14:/root/agentrun-v01`,固定使用 `v0.1` 分支,`origin` 固定为 `git@github.com:pikasTech/agentrun.git`。
|
- P0: `v0.1` 长期 source worktree 是 `G14:/root/agentrun-v01`,固定使用 `v0.1` 分支,`origin` 固定为 `git@github.com:pikasTech/agentrun.git`。
|
||||||
- P0: 每次开发、部署、恢复中断或上下文压缩后,都必须先从 UniDesk 执行 `tran G14:/root/agentrun-v01 script -- 'pwd; git status --short --branch; git remote -v'`,确认路径、分支、remote 和 clean 状态。
|
- P0: 每次开发、部署、恢复中断或上下文压缩后,都必须先从 UniDesk 执行 `tran G14:/root/agentrun-v01 script -- 'pwd; git status --short --branch; git remote -v'`,确认路径、分支、remote 和 clean 状态。
|
||||||
- P0: 固定 workspace 只用于预检、fetch、worktree 管理和最终同步。常规修改必须在 `/root/agentrun-v01/.worktree/{pr_branch}` 中完成,并从最新 `origin/v0.1` 创建。
|
- P0: 固定 source worktree 只用于预检、fetch、worktree 管理和最终同步。常规修改必须在 `/root/agentrun-v01/.worktree/{pr_branch}` 中完成,并从最新 `origin/v0.1` 创建。
|
||||||
- P0: 不得把 UniDesk、HWLAB、D601 workspace、临时 clone、pod 内副本或 runner checkout 当作 AgentRun source truth。
|
- P0: 不得把 UniDesk、HWLAB、D601 workspace、临时 clone、pod 内副本或 runner checkout 当作 AgentRun source truth。
|
||||||
|
|
||||||
## Critical Versioned Lane Rule
|
## Critical Versioned Lane Rule
|
||||||
@@ -49,7 +49,7 @@ AgentRun 是面向 UniDesk 与 HWLAB 的共享 Agent 执行基础设施。本仓
|
|||||||
|
|
||||||
- `docs/reference/spec-v01-documentation-governance.md`:v0.1 文档治理、唯一入口、spec 权威和过程材料承载规则。
|
- `docs/reference/spec-v01-documentation-governance.md`:v0.1 文档治理、唯一入口、spec 权威和过程材料承载规则。
|
||||||
- `docs/reference/spec-v01-services.md`:v0.1 服务总览、保留对象、deferred 对象和单服务规格索引。
|
- `docs/reference/spec-v01-services.md`:v0.1 服务总览、保留对象、deferred 对象和单服务规格索引。
|
||||||
- `docs/reference/spec-v01-cicd.md`:v0.1 分支、workspace、namespace、GitOps、registry、CI/CD 和发布验收规格。
|
- `docs/reference/spec-v01-cicd.md`:v0.1 分支、source worktree、namespace、GitOps、registry、CI/CD 和发布验收规格。
|
||||||
- `docs/reference/spec-v01-postgres.md`:v0.1 Postgres durable store、schema migration 和 SecretRef 规格。
|
- `docs/reference/spec-v01-postgres.md`:v0.1 Postgres durable store、schema migration 和 SecretRef 规格。
|
||||||
- `docs/reference/spec-v01-secret-distribution.md`:v0.1 Code Agent provider credential 和运行时 Secret 分发规格。
|
- `docs/reference/spec-v01-secret-distribution.md`:v0.1 Code Agent provider credential 和运行时 Secret 分发规格。
|
||||||
- `docs/reference/spec-v01-validation.md`:v0.1 两层验证模型,自测试允许 mock,综合联调必须 100% 真实。
|
- `docs/reference/spec-v01-validation.md`:v0.1 两层验证模型,自测试允许 mock,综合联调必须 100% 真实。
|
||||||
|
|||||||
@@ -0,0 +1,13 @@
|
|||||||
|
FROM oven/bun:1.2.15-alpine
|
||||||
|
|
||||||
|
WORKDIR /app
|
||||||
|
ENV NODE_ENV=production
|
||||||
|
ENV PORT=8080
|
||||||
|
|
||||||
|
COPY package.json tsconfig.json ./
|
||||||
|
COPY scripts ./scripts
|
||||||
|
COPY src ./src
|
||||||
|
COPY deploy/deploy.json ./deploy/deploy.json
|
||||||
|
|
||||||
|
EXPOSE 8080
|
||||||
|
CMD ["bun", "src/mgr/main.ts"]
|
||||||
@@ -0,0 +1,21 @@
|
|||||||
|
apiVersion: argoproj.io/v1alpha1
|
||||||
|
kind: Application
|
||||||
|
metadata:
|
||||||
|
name: agentrun-g14-v01
|
||||||
|
namespace: argocd
|
||||||
|
spec:
|
||||||
|
project: agentrun-v01
|
||||||
|
source:
|
||||||
|
repoURL: git@github.com:pikasTech/agentrun.git
|
||||||
|
targetRevision: v0.1-gitops
|
||||||
|
path: deploy/gitops/g14/runtime-v01
|
||||||
|
destination:
|
||||||
|
server: https://kubernetes.default.svc
|
||||||
|
namespace: agentrun-v01
|
||||||
|
syncPolicy:
|
||||||
|
automated:
|
||||||
|
prune: false
|
||||||
|
selfHeal: true
|
||||||
|
syncOptions:
|
||||||
|
- CreateNamespace=true
|
||||||
|
- ApplyOutOfSyncOnly=true
|
||||||
@@ -0,0 +1,18 @@
|
|||||||
|
apiVersion: argoproj.io/v1alpha1
|
||||||
|
kind: AppProject
|
||||||
|
metadata:
|
||||||
|
name: agentrun-v01
|
||||||
|
namespace: argocd
|
||||||
|
spec:
|
||||||
|
description: AgentRun v0.1 GitOps lane
|
||||||
|
sourceRepos:
|
||||||
|
- git@github.com:pikasTech/agentrun.git
|
||||||
|
destinations:
|
||||||
|
- server: https://kubernetes.default.svc
|
||||||
|
namespace: agentrun-v01
|
||||||
|
clusterResourceWhitelist:
|
||||||
|
- group: ""
|
||||||
|
kind: Namespace
|
||||||
|
namespaceResourceWhitelist:
|
||||||
|
- group: "*"
|
||||||
|
kind: "*"
|
||||||
@@ -0,0 +1,264 @@
|
|||||||
|
apiVersion: tekton.dev/v1
|
||||||
|
kind: Pipeline
|
||||||
|
metadata:
|
||||||
|
name: agentrun-v01-ci-image-publish
|
||||||
|
namespace: agentrun-ci
|
||||||
|
labels:
|
||||||
|
app.kubernetes.io/part-of: agentrun
|
||||||
|
agentrun.pikastech.local/lane: v0.1
|
||||||
|
spec:
|
||||||
|
params:
|
||||||
|
- name: git-url
|
||||||
|
type: string
|
||||||
|
default: git@github.com:pikasTech/agentrun.git
|
||||||
|
- name: source-branch
|
||||||
|
type: string
|
||||||
|
default: v0.1
|
||||||
|
- name: gitops-branch
|
||||||
|
type: string
|
||||||
|
default: v0.1-gitops
|
||||||
|
- name: revision
|
||||||
|
type: string
|
||||||
|
- name: registry-prefix
|
||||||
|
type: string
|
||||||
|
default: 127.0.0.1:5000/agentrun
|
||||||
|
- name: tools-image
|
||||||
|
type: string
|
||||||
|
default: oven/bun:1.2.15-alpine
|
||||||
|
workspaces:
|
||||||
|
- name: source
|
||||||
|
- name: git-ssh
|
||||||
|
tasks:
|
||||||
|
- name: prepare-source
|
||||||
|
workspaces:
|
||||||
|
- name: source
|
||||||
|
workspace: source
|
||||||
|
- name: git-ssh
|
||||||
|
workspace: git-ssh
|
||||||
|
taskSpec:
|
||||||
|
params:
|
||||||
|
- name: git-url
|
||||||
|
- name: source-branch
|
||||||
|
- name: revision
|
||||||
|
- name: tools-image
|
||||||
|
workspaces:
|
||||||
|
- name: source
|
||||||
|
- name: git-ssh
|
||||||
|
steps:
|
||||||
|
- name: clone-and-check
|
||||||
|
image: $(params.tools-image)
|
||||||
|
env:
|
||||||
|
- name: HTTP_PROXY
|
||||||
|
value: http://127.0.0.1:10808
|
||||||
|
- name: HTTPS_PROXY
|
||||||
|
value: http://127.0.0.1:10808
|
||||||
|
- name: NO_PROXY
|
||||||
|
value: hyueapi.com,.hyueapi.com,127.0.0.1,localhost,::1,10.42.0.0/16,10.43.0.0/16,.svc,.cluster.local
|
||||||
|
- name: http_proxy
|
||||||
|
value: http://127.0.0.1:10808
|
||||||
|
- name: https_proxy
|
||||||
|
value: http://127.0.0.1:10808
|
||||||
|
- name: no_proxy
|
||||||
|
value: hyueapi.com,.hyueapi.com,127.0.0.1,localhost,::1,10.42.0.0/16,10.43.0.0/16,.svc,.cluster.local
|
||||||
|
script: |
|
||||||
|
#!/bin/sh
|
||||||
|
set -eu
|
||||||
|
apk add --no-cache git openssh-client curl
|
||||||
|
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
|
||||||
|
rm -rf /workspace/source/repo
|
||||||
|
git clone --branch "$(params.source-branch)" "$(params.git-url)" /workspace/source/repo
|
||||||
|
cd /workspace/source/repo
|
||||||
|
git config --global --add safe.directory /workspace/source/repo
|
||||||
|
git checkout "$(params.revision)"
|
||||||
|
test "$(git rev-parse HEAD)" = "$(params.revision)"
|
||||||
|
bun install
|
||||||
|
bun run check
|
||||||
|
bun scripts/agentrun-gitops-render.ts --out /tmp/agentrun-gitops-render-check --source-commit "$(params.revision)" --check
|
||||||
|
bun run self-test
|
||||||
|
params:
|
||||||
|
- name: git-url
|
||||||
|
value: $(params.git-url)
|
||||||
|
- name: source-branch
|
||||||
|
value: $(params.source-branch)
|
||||||
|
- name: revision
|
||||||
|
value: $(params.revision)
|
||||||
|
- name: tools-image
|
||||||
|
value: $(params.tools-image)
|
||||||
|
- name: image-publish
|
||||||
|
runAfter: [prepare-source]
|
||||||
|
workspaces:
|
||||||
|
- name: source
|
||||||
|
workspace: source
|
||||||
|
taskSpec:
|
||||||
|
params:
|
||||||
|
- name: revision
|
||||||
|
- name: registry-prefix
|
||||||
|
results:
|
||||||
|
- name: image
|
||||||
|
- name: digest
|
||||||
|
- name: repository-digest
|
||||||
|
sidecars:
|
||||||
|
- name: buildkitd
|
||||||
|
image: moby/buildkit:rootless
|
||||||
|
args:
|
||||||
|
- --addr
|
||||||
|
- unix:///workspace/buildkit-run/buildkitd.sock
|
||||||
|
- --oci-worker-no-process-sandbox
|
||||||
|
env:
|
||||||
|
- name: HTTP_PROXY
|
||||||
|
value: http://127.0.0.1:10808
|
||||||
|
- name: HTTPS_PROXY
|
||||||
|
value: http://127.0.0.1:10808
|
||||||
|
- name: NO_PROXY
|
||||||
|
value: hyueapi.com,.hyueapi.com,127.0.0.1,localhost,::1,10.42.0.0/16,10.43.0.0/16,.svc,.cluster.local
|
||||||
|
- name: http_proxy
|
||||||
|
value: http://127.0.0.1:10808
|
||||||
|
- name: https_proxy
|
||||||
|
value: http://127.0.0.1:10808
|
||||||
|
- name: no_proxy
|
||||||
|
value: hyueapi.com,.hyueapi.com,127.0.0.1,localhost,::1,10.42.0.0/16,10.43.0.0/16,.svc,.cluster.local
|
||||||
|
securityContext:
|
||||||
|
seccompProfile:
|
||||||
|
type: Unconfined
|
||||||
|
runAsUser: 1000
|
||||||
|
runAsGroup: 1000
|
||||||
|
volumeMounts:
|
||||||
|
- name: buildkit-run
|
||||||
|
mountPath: /workspace/buildkit-run
|
||||||
|
steps:
|
||||||
|
- name: prepare-buildctl
|
||||||
|
image: moby/buildkit:rootless
|
||||||
|
script: |
|
||||||
|
#!/bin/sh
|
||||||
|
set -eu
|
||||||
|
mkdir -p /workspace/buildkit-bin
|
||||||
|
cp /usr/bin/buildctl /workspace/buildkit-bin/buildctl
|
||||||
|
chmod +x /workspace/buildkit-bin/buildctl
|
||||||
|
volumeMounts:
|
||||||
|
- name: buildkit-bin
|
||||||
|
mountPath: /workspace/buildkit-bin
|
||||||
|
- name: build-and-push
|
||||||
|
image: oven/bun:1.2.15-alpine
|
||||||
|
env:
|
||||||
|
- name: HTTP_PROXY
|
||||||
|
value: http://127.0.0.1:10808
|
||||||
|
- name: HTTPS_PROXY
|
||||||
|
value: http://127.0.0.1:10808
|
||||||
|
- name: NO_PROXY
|
||||||
|
value: hyueapi.com,.hyueapi.com,127.0.0.1,localhost,::1,10.42.0.0/16,10.43.0.0/16,.svc,.cluster.local
|
||||||
|
script: |
|
||||||
|
#!/bin/sh
|
||||||
|
set -eu
|
||||||
|
apk add --no-cache curl
|
||||||
|
cd /workspace/source/repo
|
||||||
|
image="$(params.registry-prefix)/agentrun-mgr:$(params.revision)"
|
||||||
|
buildctl=/workspace/buildkit-bin/buildctl
|
||||||
|
for attempt in $(seq 1 60); do
|
||||||
|
if "$buildctl" --addr unix:///workspace/buildkit-run/buildkitd.sock debug workers >/dev/null 2>&1; then break; fi
|
||||||
|
sleep 1
|
||||||
|
done
|
||||||
|
"$buildctl" --addr unix:///workspace/buildkit-run/buildkitd.sock build \
|
||||||
|
--frontend dockerfile.v0 \
|
||||||
|
--local context=. \
|
||||||
|
--local dockerfile=deploy/container \
|
||||||
|
--opt filename=Containerfile \
|
||||||
|
--output type=image,name="$image",push=true
|
||||||
|
digest="$(curl -fsSI "http://127.0.0.1:5000/v2/agentrun/agentrun-mgr/manifests/$(params.revision)" | awk -F': ' 'tolower($1)=="docker-content-digest" {gsub(/\r/,"",$2); print $2; exit}')"
|
||||||
|
test -n "$digest"
|
||||||
|
printf '%s' "$image" > /tekton/results/image
|
||||||
|
printf '%s' "$digest" > /tekton/results/digest
|
||||||
|
printf '%s' "$(params.registry-prefix)/agentrun-mgr@$digest" > /tekton/results/repository-digest
|
||||||
|
volumeMounts:
|
||||||
|
- name: buildkit-bin
|
||||||
|
mountPath: /workspace/buildkit-bin
|
||||||
|
- name: buildkit-run
|
||||||
|
mountPath: /workspace/buildkit-run
|
||||||
|
volumes:
|
||||||
|
- name: buildkit-bin
|
||||||
|
emptyDir: {}
|
||||||
|
- name: buildkit-run
|
||||||
|
emptyDir: {}
|
||||||
|
params:
|
||||||
|
- name: revision
|
||||||
|
value: $(params.revision)
|
||||||
|
- name: registry-prefix
|
||||||
|
value: $(params.registry-prefix)
|
||||||
|
- name: gitops-promote
|
||||||
|
runAfter: [image-publish]
|
||||||
|
workspaces:
|
||||||
|
- name: source
|
||||||
|
workspace: source
|
||||||
|
- name: git-ssh
|
||||||
|
workspace: git-ssh
|
||||||
|
taskSpec:
|
||||||
|
params:
|
||||||
|
- name: git-url
|
||||||
|
- name: gitops-branch
|
||||||
|
- name: revision
|
||||||
|
- name: registry-prefix
|
||||||
|
- name: image
|
||||||
|
- name: digest
|
||||||
|
- name: repository-digest
|
||||||
|
workspaces:
|
||||||
|
- name: source
|
||||||
|
- name: git-ssh
|
||||||
|
steps:
|
||||||
|
- name: promote
|
||||||
|
image: oven/bun:1.2.15-alpine
|
||||||
|
env:
|
||||||
|
- name: HTTP_PROXY
|
||||||
|
value: http://127.0.0.1:10808
|
||||||
|
- name: HTTPS_PROXY
|
||||||
|
value: http://127.0.0.1:10808
|
||||||
|
- name: NO_PROXY
|
||||||
|
value: hyueapi.com,.hyueapi.com,127.0.0.1,localhost,::1,10.42.0.0/16,10.43.0.0/16,.svc,.cluster.local
|
||||||
|
script: |
|
||||||
|
#!/bin/sh
|
||||||
|
set -eu
|
||||||
|
apk add --no-cache git openssh-client
|
||||||
|
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
|
||||||
|
cd /workspace/source/repo
|
||||||
|
cat > /workspace/source/artifact-catalog.v01.json <<EOF
|
||||||
|
{"lane":"v0.1","sourceBranch":"v0.1","gitopsBranch":"$(params.gitops-branch)","sourceCommitId":"$(params.revision)","services":[{"serviceId":"agentrun-mgr","image":"$(params.image)","digest":"$(params.digest)","repositoryDigest":"$(params.repository-digest)","imageTag":"$(params.revision)"}]}
|
||||||
|
EOF
|
||||||
|
rm -rf /workspace/source/rendered
|
||||||
|
bun scripts/agentrun-gitops-render.ts --out /workspace/source/rendered --source-commit "$(params.revision)" --registry-prefix "$(params.registry-prefix)" --catalog /workspace/source/artifact-catalog.v01.json --require-catalog
|
||||||
|
rm -rf /workspace/source/gitops
|
||||||
|
git clone --branch "$(params.gitops-branch)" "$(params.git-url)" /workspace/source/gitops || {
|
||||||
|
git clone "$(params.git-url)" /workspace/source/gitops
|
||||||
|
cd /workspace/source/gitops
|
||||||
|
git checkout --orphan "$(params.gitops-branch)"
|
||||||
|
git rm -rf . >/dev/null 2>&1 || true
|
||||||
|
}
|
||||||
|
cd /workspace/source/gitops
|
||||||
|
git config user.email agentrun-ci@g14.local
|
||||||
|
git config user.name agentrun-ci
|
||||||
|
mkdir -p deploy/gitops/g14 deploy
|
||||||
|
rm -rf deploy/gitops/g14/runtime-v01 deploy/gitops/g14/argocd
|
||||||
|
cp -a /workspace/source/rendered/runtime-v01 deploy/gitops/g14/runtime-v01
|
||||||
|
cp -a /workspace/source/rendered/argocd deploy/gitops/g14/argocd
|
||||||
|
cp /workspace/source/rendered/artifact-catalog.v01.json deploy/artifact-catalog.v01.json
|
||||||
|
git add deploy
|
||||||
|
git commit -m "gitops: promote agentrun v0.1 $(params.revision)" || true
|
||||||
|
git push origin "$(params.gitops-branch)"
|
||||||
|
params:
|
||||||
|
- name: git-url
|
||||||
|
value: $(params.git-url)
|
||||||
|
- name: gitops-branch
|
||||||
|
value: $(params.gitops-branch)
|
||||||
|
- name: revision
|
||||||
|
value: $(params.revision)
|
||||||
|
- name: registry-prefix
|
||||||
|
value: $(params.registry-prefix)
|
||||||
|
- name: image
|
||||||
|
value: $(tasks.image-publish.results.image)
|
||||||
|
- name: digest
|
||||||
|
value: $(tasks.image-publish.results.digest)
|
||||||
|
- name: repository-digest
|
||||||
|
value: $(tasks.image-publish.results.repository-digest)
|
||||||
@@ -0,0 +1,29 @@
|
|||||||
|
apiVersion: tekton.dev/v1
|
||||||
|
kind: PipelineRun
|
||||||
|
metadata:
|
||||||
|
generateName: agentrun-v01-ci-
|
||||||
|
namespace: agentrun-ci
|
||||||
|
spec:
|
||||||
|
pipelineRef:
|
||||||
|
name: agentrun-v01-ci-image-publish
|
||||||
|
taskRunTemplate:
|
||||||
|
serviceAccountName: agentrun-v01-tekton-runner
|
||||||
|
podTemplate:
|
||||||
|
hostNetwork: true
|
||||||
|
dnsPolicy: ClusterFirstWithHostNet
|
||||||
|
securityContext:
|
||||||
|
fsGroup: 1000
|
||||||
|
params:
|
||||||
|
- name: revision
|
||||||
|
value: REPLACE_WITH_FULL_SOURCE_COMMIT
|
||||||
|
workspaces:
|
||||||
|
- name: source
|
||||||
|
volumeClaimTemplate:
|
||||||
|
spec:
|
||||||
|
accessModes: ["ReadWriteOnce"]
|
||||||
|
resources:
|
||||||
|
requests:
|
||||||
|
storage: 5Gi
|
||||||
|
- name: git-ssh
|
||||||
|
secret:
|
||||||
|
secretName: agentrun-git-ssh
|
||||||
@@ -0,0 +1,36 @@
|
|||||||
|
apiVersion: v1
|
||||||
|
kind: Namespace
|
||||||
|
metadata:
|
||||||
|
name: agentrun-ci
|
||||||
|
---
|
||||||
|
apiVersion: v1
|
||||||
|
kind: ServiceAccount
|
||||||
|
metadata:
|
||||||
|
name: agentrun-v01-tekton-runner
|
||||||
|
namespace: agentrun-ci
|
||||||
|
---
|
||||||
|
apiVersion: rbac.authorization.k8s.io/v1
|
||||||
|
kind: Role
|
||||||
|
metadata:
|
||||||
|
name: agentrun-v01-tekton-runner
|
||||||
|
namespace: agentrun-ci
|
||||||
|
rules:
|
||||||
|
- apiGroups: ["tekton.dev"]
|
||||||
|
resources: ["pipelineruns", "taskruns"]
|
||||||
|
verbs: ["get", "list", "watch", "create", "patch", "update"]
|
||||||
|
- apiGroups: [""]
|
||||||
|
resources: ["pods", "pods/log", "secrets", "configmaps", "persistentvolumeclaims"]
|
||||||
|
verbs: ["get", "list", "watch", "create", "patch", "update", "delete"]
|
||||||
|
---
|
||||||
|
apiVersion: rbac.authorization.k8s.io/v1
|
||||||
|
kind: RoleBinding
|
||||||
|
metadata:
|
||||||
|
name: agentrun-v01-tekton-runner
|
||||||
|
namespace: agentrun-ci
|
||||||
|
subjects:
|
||||||
|
- kind: ServiceAccount
|
||||||
|
name: agentrun-v01-tekton-runner
|
||||||
|
roleRef:
|
||||||
|
apiGroup: rbac.authorization.k8s.io
|
||||||
|
kind: Role
|
||||||
|
name: agentrun-v01-tekton-runner
|
||||||
@@ -212,7 +212,7 @@ Postgres DSN、provider credential 和未来 tenant credential 的分发边界
|
|||||||
|
|
||||||
## 部署方向
|
## 部署方向
|
||||||
|
|
||||||
AgentRun 从 `v0.1` 开始按版本 lane 滚动,废弃 `dev/prod` 管理口径。`v0.1` 的固定 source workspace 是 `G14:/root/agentrun-v01`,固定 source branch 是 `v0.1`,固定运行目标是 G14 原生 k3s namespace `agentrun-v01`。后续 `v0.2`、`v0.3` 必须拥有自己的 branch、workspace、namespace、GitOps branch、runtime path 和发布验收。
|
AgentRun 从 `v0.1` 开始按版本 lane 滚动,废弃 `dev/prod` 管理口径。`v0.1` 的固定 source worktree 是 `G14:/root/agentrun-v01`,固定 source branch 是 `v0.1`,固定运行目标是 G14 原生 k3s namespace `agentrun-v01`。后续 `v0.2`、`v0.3` 必须拥有自己的 branch、source worktree、namespace、GitOps branch、runtime path 和发布验收。
|
||||||
|
|
||||||
Control-plane service 应是长驻服务;runner 应是短生命周期 Job 或受控 host-native process。Backend adapter 可以作为 pod 或 host-native service 运行,但必须通过 AgentRun 注册 capability 和 health,不能通过临时地址被 ad hoc 调用。
|
Control-plane service 应是长驻服务;runner 应是短生命周期 Job 或受控 host-native process。Backend adapter 可以作为 pod 或 host-native service 运行,但必须通过 AgentRun 注册 capability 和 health,不能通过临时地址被 ad hoc 调用。
|
||||||
|
|
||||||
|
|||||||
@@ -5,11 +5,11 @@
|
|||||||
## 设计目标
|
## 设计目标
|
||||||
|
|
||||||
- `v0.1` 是独立 lane,不复用 `agentrun_dev` 或 `agentrun_prod` 作为当前运行面。
|
- `v0.1` 是独立 lane,不复用 `agentrun_dev` 或 `agentrun_prod` 作为当前运行面。
|
||||||
- 每条版本 lane 拥有独立 source branch、source workspace、GitOps branch、runtime namespace、artifact catalog、runtime path、CI pipeline 和发布验收。
|
- 每条版本 lane 拥有独立 source branch、source worktree、GitOps branch、runtime namespace、artifact catalog、runtime path、CI pipeline 和发布验收。
|
||||||
- `v0.1` 只能部署到 `agentrun-v01` namespace;`v0.2`、`v0.3` 后续使用自己的 namespace 和 GitOps 路径。
|
- `v0.1` 只能部署到 `agentrun-v01` namespace;`v0.2`、`v0.3` 后续使用自己的 namespace 和 GitOps 路径。
|
||||||
- CI/CD 必须使用 G14 原生 k3s、纯 Tekton Pipeline/Task/PipelineRun 和 Argo CD;不得引入自定义 runner、CI.json runner、长期自研 poller/reconciler、D601 legacy、临时 clone、手工 Pod patch 或本地镜像作为发布真相。
|
- CI/CD 必须使用 G14 原生 k3s、纯 Tekton Pipeline/Task/PipelineRun 和 Argo CD;不得引入自定义 runner、CI.json runner、长期自研 poller/reconciler、D601 legacy、临时 clone、手工 Pod patch 或本地镜像作为发布真相。
|
||||||
- `v0.1` 的 CD 唯一手写真相源是 source branch 内的 `deploy/deploy.json`;Tekton 生成的 artifact catalog 和 Argo desired state 必须与 source branch 分离,只写入 `v0.1-gitops`。
|
- `v0.1` 的 CD 唯一手写真相源是 source branch 内的 `deploy/deploy.json`;Tekton 生成的 artifact catalog 和 Argo desired state 必须与 source branch 分离,只写入 `v0.1-gitops`。
|
||||||
- 发布证据以 live runtime、Argo desired state、GitOps branch、Tekton 证据和干净 source workspace 顺序判断。
|
- 发布证据以 live runtime、Argo desired state、GitOps branch、Tekton 证据和干净 source worktree 顺序判断。
|
||||||
|
|
||||||
## 固定命名
|
## 固定命名
|
||||||
|
|
||||||
@@ -17,7 +17,7 @@
|
|||||||
| --- | --- |
|
| --- | --- |
|
||||||
| Source repo | `git@github.com:pikasTech/agentrun.git` |
|
| Source repo | `git@github.com:pikasTech/agentrun.git` |
|
||||||
| Source branch | `v0.1` |
|
| Source branch | `v0.1` |
|
||||||
| Source workspace | `G14:/root/agentrun-v01` |
|
| Source worktree | `G14:/root/agentrun-v01` |
|
||||||
| Worktree root | `G14:/root/agentrun-v01/.worktree/{task}` |
|
| Worktree root | `G14:/root/agentrun-v01/.worktree/{task}` |
|
||||||
| Runtime namespace | `agentrun-v01` |
|
| Runtime namespace | `agentrun-v01` |
|
||||||
| GitOps branch | `v0.1-gitops` |
|
| GitOps branch | `v0.1-gitops` |
|
||||||
@@ -34,7 +34,9 @@
|
|||||||
|
|
||||||
## Bun + TypeScript CI 边界
|
## Bun + TypeScript CI 边界
|
||||||
|
|
||||||
`v0.1` 自研代码的 CI/CD 工具链以 Bun + TypeScript 为准。Tekton task 必须在受控容器内安装或使用固定 Bun 运行时,执行依赖安装、类型检查、自测试和镜像构建;不得把 master server、G14 固定 source workspace 或手工 host shell 作为构建机。
|
`v0.1` 自研代码的 CI/CD 工具链以 Bun + TypeScript 为准。Tekton task 必须在受控容器内安装或使用固定 Bun 运行时,执行依赖安装、类型检查、自测试和镜像构建;不得把 master server、G14 固定 source worktree 或手工 host shell 作为构建机。
|
||||||
|
|
||||||
|
G14 依赖拉取和镜像发布沿用 HWLAB 成熟 lane 的运行面假设:`PipelineRun.spec.taskRunTemplate.podTemplate.hostNetwork=true` 且 `dnsPolicy=ClusterFirstWithHostNet`。因此 Tekton task 内的 `127.0.0.1:10808` 指向 G14 host bootstrap proxy,`127.0.0.1:5000` 指向 G14 host-managed registry;`NO_PROXY` 必须保留 `hyueapi.com`、`.hyueapi.com`、cluster service CIDR、`.svc` 和 `.cluster.local`。如果未来改成 cluster Service proxy 或 registry DNS,必须同步更新 Tekton template、render 脚本和本文规格,不得只改某个 PipelineRun 实例。
|
||||||
|
|
||||||
CI 的最小检查应覆盖:
|
CI 的最小检查应覆盖:
|
||||||
|
|
||||||
@@ -53,9 +55,9 @@ CI 的最小检查应覆盖:
|
|||||||
2. Argo desired state:`argocd/agentrun-g14-v01` 的 revision、sync、health、source branch 和 runtime path。
|
2. Argo desired state:`argocd/agentrun-g14-v01` 的 revision、sync、health、source branch 和 runtime path。
|
||||||
3. GitOps branch:`v0.1-gitops` 中的 `deploy/artifact-catalog.v01.json` 与 `deploy/gitops/g14/runtime-v01/**`。
|
3. GitOps branch:`v0.1-gitops` 中的 `deploy/artifact-catalog.v01.json` 与 `deploy/gitops/g14/runtime-v01/**`。
|
||||||
4. Tekton 执行证据:PipelineRun、TaskRun result、image digest 和 promotion 终态。
|
4. Tekton 执行证据:PipelineRun、TaskRun result、image digest 和 promotion 终态。
|
||||||
5. 干净 source workspace:`G14:/root/agentrun-v01`、`origin/v0.1`、render 脚本、deploy intent 和 `--no-write` 输出。
|
5. 干净 source worktree:`G14:/root/agentrun-v01`、`origin/v0.1`、render 脚本、deploy intent 和 `--no-write` 输出。
|
||||||
|
|
||||||
旧 `master` 记忆、`/root/agentrun` 固定工作区、`agentrun_dev`、`agentrun_prod`、D601 legacy 路径、临时 worktree 或本地容器只能作为线索,不能作为 `v0.1` 发布通过证据。
|
旧 `master` 记忆、`/root/agentrun` 历史固定目录、`agentrun_dev`、`agentrun_prod`、D601 legacy 路径、临时 worktree 或本地容器只能作为线索,不能作为 `v0.1` 发布通过证据。
|
||||||
|
|
||||||
## Source 与 GitOps 分层
|
## Source 与 GitOps 分层
|
||||||
|
|
||||||
@@ -140,7 +142,7 @@ Tekton promotion 可以读取 `deploy/deploy.json` 来 render runtime desired st
|
|||||||
|
|
||||||
## 验收标准
|
## 验收标准
|
||||||
|
|
||||||
- `G14:/root/agentrun-v01` 为 `v0.1...origin/v0.1` 且 clean。
|
- `G14:/root/agentrun-v01` source worktree 为 `v0.1...origin/v0.1` 且 clean。
|
||||||
- `AGENTS.md` 和 `docs/reference/` 不得把 `agentrun_dev` 或 `agentrun_prod` 写成 `v0.1` 当前 namespace、Argo destination、Pipeline target 或验收目标;只允许在废弃说明和历史背景中提及。
|
- `AGENTS.md` 和 `docs/reference/` 不得把 `agentrun_dev` 或 `agentrun_prod` 写成 `v0.1` 当前 namespace、Argo destination、Pipeline target 或验收目标;只允许在废弃说明和历史背景中提及。
|
||||||
- `agentrun-v01` namespace 存在,且 `agentrun_dev`/`agentrun_prod` 不参与 `v0.1` 发布判定。
|
- `agentrun-v01` namespace 存在,且 `agentrun_dev`/`agentrun_prod` 不参与 `v0.1` 发布判定。
|
||||||
- `v0.1-gitops` branch 和 `deploy/gitops/g14/runtime-v01` 成为 Argo desired state 来源。
|
- `v0.1-gitops` branch 和 `deploy/gitops/g14/runtime-v01` 成为 Argo desired state 来源。
|
||||||
@@ -154,7 +156,7 @@ Tekton promotion 可以读取 `deploy/deploy.json` 来 render runtime desired st
|
|||||||
| 规格项 | 状态 | 说明 |
|
| 规格项 | 状态 | 说明 |
|
||||||
| --- | --- | --- |
|
| --- | --- | --- |
|
||||||
| `v0.1` source branch | 已建立 | `origin/v0.1` 存在。 |
|
| `v0.1` source branch | 已建立 | `origin/v0.1` 存在。 |
|
||||||
| `G14:/root/agentrun-v01` workspace | 已建立 | 固定工作区使用 `v0.1` 分支。 |
|
| `G14:/root/agentrun-v01` source worktree | 已建立 | 固定 source worktree 使用 `v0.1` 分支。 |
|
||||||
| `agentrun-v01` namespace | 未实现 | 需要后续初始化。 |
|
| `agentrun-v01` namespace | 未实现 | 需要后续初始化。 |
|
||||||
| `v0.1-gitops` branch | 未实现 | 需要后续初始化。 |
|
| `v0.1-gitops` branch | 未实现 | 需要后续初始化。 |
|
||||||
| 纯 Tekton/Argo lane | 未实现 | 需要后续按本文补齐;不得引入自定义 runner。 |
|
| 纯 Tekton/Argo lane | 未实现 | 需要后续按本文补齐;不得引入自定义 runner。 |
|
||||||
|
|||||||
@@ -45,14 +45,14 @@
|
|||||||
1. 发现 `README.md`、`docs/*.md`、`docs/*.json` 或计划文档时,先判断是否有长期价值。
|
1. 发现 `README.md`、`docs/*.md`、`docs/*.json` 或计划文档时,先判断是否有长期价值。
|
||||||
2. 有长期价值的,只把稳定结论吸收到对应 `docs/reference/spec-v01-*.md`;不要整篇搬入 reference。
|
2. 有长期价值的,只把稳定结论吸收到对应 `docs/reference/spec-v01-*.md`;不要整篇搬入 reference。
|
||||||
3. 属于计划、里程碑、阶段迁移、报告、一次性排障或历史验收的,全文迁入 GitHub issue 或 PR 评论,再删除源文件。
|
3. 属于计划、里程碑、阶段迁移、报告、一次性排障或历史验收的,全文迁入 GitHub issue 或 PR 评论,再删除源文件。
|
||||||
4. 与 `v0.1` 规格冲突的旧 `dev/prod`、`/root/agentrun` 默认工作区、`agentrun_dev`、`agentrun_prod` 说法必须删除或改为历史背景。
|
4. 与 `v0.1` 规格冲突的旧 `dev/prod`、`/root/agentrun` 默认 source 目录、`agentrun_dev`、`agentrun_prod` 说法必须删除或改为历史背景。
|
||||||
5. 发现独立 `TEST.md` 或测试计划文档时,先把仍有效的测试场景蒸馏到对应 `spec-v01-*.md` 的“测试规格”小节,再删除源文件。
|
5. 发现独立 `TEST.md` 或测试计划文档时,先把仍有效的测试场景蒸馏到对应 `spec-v01-*.md` 的“测试规格”小节,再删除源文件。
|
||||||
6. 未实现规格必须在对应 spec 的“规格的实现情况”中明确写成 `未实现` 或 `未完全实现`,不要用散落 TODO 代替。
|
6. 未实现规格必须在对应 spec 的“规格的实现情况”中明确写成 `未实现` 或 `未完全实现`,不要用散落 TODO 代替。
|
||||||
|
|
||||||
## v0.1 当前权威入口
|
## v0.1 当前权威入口
|
||||||
|
|
||||||
- Source branch:`v0.1`。
|
- Source branch:`v0.1`。
|
||||||
- Source workspace:`G14:/root/agentrun-v01`。
|
- Source worktree:`G14:/root/agentrun-v01`。
|
||||||
- Worktree 根:`G14:/root/agentrun-v01/.worktree/{task}`。
|
- Worktree 根:`G14:/root/agentrun-v01/.worktree/{task}`。
|
||||||
- Runtime namespace:`agentrun-v01`。
|
- Runtime namespace:`agentrun-v01`。
|
||||||
- 发布和验收规格:[spec-v01-cicd.md](spec-v01-cicd.md)。
|
- 发布和验收规格:[spec-v01-cicd.md](spec-v01-cicd.md)。
|
||||||
@@ -71,7 +71,7 @@
|
|||||||
|
|
||||||
- `AGENTS.md` 索引本文和其他 `spec-v01-*` 规格。
|
- `AGENTS.md` 索引本文和其他 `spec-v01-*` 规格。
|
||||||
- `docs/reference/` 中存在 `spec-v01-documentation-governance.md`、`spec-v01-services.md`、`spec-v01-cicd.md`、`spec-v01-postgres.md`、`spec-v01-secret-distribution.md`、`spec-v01-validation.md`、`spec-v01-agentrun-mgr.md`、`spec-v01-agentrun-runner.md`、`spec-v01-backend-adapter.md`、`spec-v01-backend-codex.md`、`spec-v01-cli.md` 和 `spec-v01-scheduler.md`。
|
- `docs/reference/` 中存在 `spec-v01-documentation-governance.md`、`spec-v01-services.md`、`spec-v01-cicd.md`、`spec-v01-postgres.md`、`spec-v01-secret-distribution.md`、`spec-v01-validation.md`、`spec-v01-agentrun-mgr.md`、`spec-v01-agentrun-runner.md`、`spec-v01-backend-adapter.md`、`spec-v01-backend-codex.md`、`spec-v01-cli.md` 和 `spec-v01-scheduler.md`。
|
||||||
- `AGENTS.md` 和 `docs/reference/` 不得把旧 `agentrun_dev`、`agentrun_prod`、`G14:/root/agentrun` 或 `/root/agentrun` 写成当前工作区、namespace、发布目标或验收目标;只允许在废弃说明和历史背景中提及。
|
- `AGENTS.md` 和 `docs/reference/` 不得把旧 `agentrun_dev`、`agentrun_prod`、`G14:/root/agentrun` 或 `/root/agentrun` 写成当前 source worktree、namespace、发布目标或验收目标;只允许在废弃说明和历史背景中提及。
|
||||||
- `docs/` 根目录不新增临时 Markdown 报告或 JSON dump。
|
- `docs/` 根目录不新增临时 Markdown 报告或 JSON dump。
|
||||||
- 仓库根目录不存在 `TEST.md`;测试场景维护在对应 `spec-v01-*.md` 的“测试规格”小节。
|
- 仓库根目录不存在 `TEST.md`;测试场景维护在对应 `spec-v01-*.md` 的“测试规格”小节。
|
||||||
- 后续实现任务先更新或引用对应 `spec-v01-*`,再修改代码和测试。
|
- 后续实现任务先更新或引用对应 `spec-v01-*`,再修改代码和测试。
|
||||||
|
|||||||
@@ -0,0 +1,4 @@
|
|||||||
|
#!/usr/bin/env bun
|
||||||
|
import { runGitopsRenderCli } from "./src/gitops-render.js";
|
||||||
|
|
||||||
|
await runGitopsRenderCli(process.argv.slice(2));
|
||||||
@@ -0,0 +1,355 @@
|
|||||||
|
import { mkdir, readFile, rm, writeFile } from "node:fs/promises";
|
||||||
|
import path from "node:path";
|
||||||
|
import type { JsonRecord } from "../../src/common/types.js";
|
||||||
|
import { AgentRunError, errorToJson } from "../../src/common/errors.js";
|
||||||
|
|
||||||
|
interface RenderOptions {
|
||||||
|
outDir: string;
|
||||||
|
deployFile: string;
|
||||||
|
catalogFile?: string;
|
||||||
|
sourceCommit: string;
|
||||||
|
registryPrefix: string;
|
||||||
|
requireCatalog: boolean;
|
||||||
|
check: boolean;
|
||||||
|
}
|
||||||
|
|
||||||
|
interface ArtifactCatalog {
|
||||||
|
lane: string;
|
||||||
|
sourceBranch: string;
|
||||||
|
gitopsBranch: string;
|
||||||
|
sourceCommitId: string;
|
||||||
|
services: Array<{ serviceId: string; image: string; digest: string; repositoryDigest: string; imageTag: string }>;
|
||||||
|
}
|
||||||
|
|
||||||
|
export async function runGitopsRenderCli(argv: string[]): Promise<void> {
|
||||||
|
try {
|
||||||
|
const options = parseArgs(argv);
|
||||||
|
const summary = await renderGitops(options);
|
||||||
|
console.log(JSON.stringify({ ok: true, data: summary }));
|
||||||
|
} catch (error) {
|
||||||
|
console.log(JSON.stringify({ ok: false, failureKind: error instanceof AgentRunError ? error.failureKind : "infra-failed", message: error instanceof Error ? error.message : String(error), error: errorToJson(error) }));
|
||||||
|
process.exitCode = 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export async function renderGitops(options: RenderOptions): Promise<JsonRecord> {
|
||||||
|
const deploy = JSON.parse(await readFile(options.deployFile, "utf8")) as JsonRecord;
|
||||||
|
const runtimeNamespace = stringField(deploy, "runtimeNamespace", "agentrun-v01");
|
||||||
|
const gitopsBranch = stringField(deploy, "gitopsBranch", "v0.1-gitops");
|
||||||
|
const runtimePath = stringField(deploy, "runtimePath", "deploy/gitops/g14/runtime-v01");
|
||||||
|
const catalog = await loadCatalog(options, gitopsBranch);
|
||||||
|
const image = imageForService(catalog, "agentrun-mgr", options);
|
||||||
|
|
||||||
|
if (options.check) await rm(options.outDir, { recursive: true, force: true });
|
||||||
|
await mkdir(path.join(options.outDir, "argocd"), { recursive: true });
|
||||||
|
await mkdir(path.join(options.outDir, "runtime-v01"), { recursive: true });
|
||||||
|
await writeFile(path.join(options.outDir, "source.json"), `${JSON.stringify({ lane: "v0.1", sourceCommit: options.sourceCommit, generatedBy: "scripts/agentrun-gitops-render.ts" }, null, 2)}\n`);
|
||||||
|
await writeFile(path.join(options.outDir, "artifact-catalog.v01.json"), `${JSON.stringify(catalog, null, 2)}\n`);
|
||||||
|
await writeFile(path.join(options.outDir, "argocd", "project.yaml"), projectYaml(runtimeNamespace));
|
||||||
|
await writeFile(path.join(options.outDir, "argocd", "application-v01.yaml"), applicationYaml(gitopsBranch, runtimePath, runtimeNamespace));
|
||||||
|
await writeFile(path.join(options.outDir, "runtime-v01", "kustomization.yaml"), kustomizationYaml());
|
||||||
|
await writeFile(path.join(options.outDir, "runtime-v01", "namespace.yaml"), namespaceYaml(runtimeNamespace));
|
||||||
|
await writeFile(path.join(options.outDir, "runtime-v01", "postgres.yaml"), postgresYaml(runtimeNamespace));
|
||||||
|
await writeFile(path.join(options.outDir, "runtime-v01", "mgr.yaml"), managerYaml(runtimeNamespace, image));
|
||||||
|
await writeFile(path.join(options.outDir, "runtime-v01", "runner-rbac.yaml"), runnerRbacYaml(runtimeNamespace));
|
||||||
|
return { outDir: options.outDir, runtimeNamespace, gitopsBranch, runtimePath, image: image.repositoryDigest, sourceCommit: options.sourceCommit };
|
||||||
|
}
|
||||||
|
|
||||||
|
async function loadCatalog(options: RenderOptions, gitopsBranch: string): Promise<ArtifactCatalog> {
|
||||||
|
if (options.catalogFile) return JSON.parse(await readFile(options.catalogFile, "utf8")) as ArtifactCatalog;
|
||||||
|
if (options.requireCatalog) throw new AgentRunError("schema-invalid", "artifact catalog is required for promotion render", { httpStatus: 2 });
|
||||||
|
const digest = `sha256:${"0".repeat(64)}`;
|
||||||
|
const image = `${options.registryPrefix}/agentrun-mgr:${options.sourceCommit}`;
|
||||||
|
return {
|
||||||
|
lane: "v0.1",
|
||||||
|
sourceBranch: "v0.1",
|
||||||
|
gitopsBranch,
|
||||||
|
sourceCommitId: options.sourceCommit,
|
||||||
|
services: [{ serviceId: "agentrun-mgr", image, digest, repositoryDigest: `${options.registryPrefix}/agentrun-mgr@${digest}`, imageTag: options.sourceCommit }],
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
function imageForService(catalog: ArtifactCatalog, serviceId: string, options: RenderOptions): { repositoryDigest: string } {
|
||||||
|
const service = catalog.services.find((item) => item.serviceId === serviceId);
|
||||||
|
if (!service) throw new AgentRunError("schema-invalid", `catalog missing service ${serviceId}`, { httpStatus: 2 });
|
||||||
|
if (!/^sha256:[a-f0-9]{64}$/u.test(service.digest)) throw new AgentRunError("schema-invalid", `catalog service ${serviceId} has invalid digest`, { httpStatus: 2 });
|
||||||
|
if (options.requireCatalog && service.digest === `sha256:${"0".repeat(64)}`) throw new AgentRunError("schema-invalid", "placeholder digest is not allowed in promotion render", { httpStatus: 2 });
|
||||||
|
return { repositoryDigest: service.repositoryDigest || `${service.image.slice(0, service.image.lastIndexOf(":"))}@${service.digest}` };
|
||||||
|
}
|
||||||
|
|
||||||
|
function projectYaml(namespace: string): string {
|
||||||
|
return `apiVersion: argoproj.io/v1alpha1
|
||||||
|
kind: AppProject
|
||||||
|
metadata:
|
||||||
|
name: agentrun-v01
|
||||||
|
namespace: argocd
|
||||||
|
spec:
|
||||||
|
description: AgentRun v0.1 GitOps lane
|
||||||
|
sourceRepos:
|
||||||
|
- git@github.com:pikasTech/agentrun.git
|
||||||
|
destinations:
|
||||||
|
- server: https://kubernetes.default.svc
|
||||||
|
namespace: ${namespace}
|
||||||
|
clusterResourceWhitelist:
|
||||||
|
- group: ""
|
||||||
|
kind: Namespace
|
||||||
|
namespaceResourceWhitelist:
|
||||||
|
- group: "*"
|
||||||
|
kind: "*"
|
||||||
|
`;
|
||||||
|
}
|
||||||
|
|
||||||
|
function applicationYaml(gitopsBranch: string, runtimePath: string, namespace: string): string {
|
||||||
|
return `apiVersion: argoproj.io/v1alpha1
|
||||||
|
kind: Application
|
||||||
|
metadata:
|
||||||
|
name: agentrun-g14-v01
|
||||||
|
namespace: argocd
|
||||||
|
spec:
|
||||||
|
project: agentrun-v01
|
||||||
|
source:
|
||||||
|
repoURL: git@github.com:pikasTech/agentrun.git
|
||||||
|
targetRevision: ${gitopsBranch}
|
||||||
|
path: ${runtimePath}
|
||||||
|
destination:
|
||||||
|
server: https://kubernetes.default.svc
|
||||||
|
namespace: ${namespace}
|
||||||
|
syncPolicy:
|
||||||
|
automated:
|
||||||
|
prune: false
|
||||||
|
selfHeal: true
|
||||||
|
syncOptions:
|
||||||
|
- CreateNamespace=true
|
||||||
|
- ApplyOutOfSyncOnly=true
|
||||||
|
`;
|
||||||
|
}
|
||||||
|
|
||||||
|
function kustomizationYaml(): string {
|
||||||
|
return `apiVersion: kustomize.config.k8s.io/v1beta1
|
||||||
|
kind: Kustomization
|
||||||
|
resources:
|
||||||
|
- namespace.yaml
|
||||||
|
- postgres.yaml
|
||||||
|
- mgr.yaml
|
||||||
|
- runner-rbac.yaml
|
||||||
|
`;
|
||||||
|
}
|
||||||
|
|
||||||
|
function namespaceYaml(namespace: string): string {
|
||||||
|
return `apiVersion: v1
|
||||||
|
kind: Namespace
|
||||||
|
metadata:
|
||||||
|
name: ${namespace}
|
||||||
|
labels:
|
||||||
|
app.kubernetes.io/part-of: agentrun
|
||||||
|
agentrun.pikastech.local/lane: v0.1
|
||||||
|
`;
|
||||||
|
}
|
||||||
|
|
||||||
|
function postgresYaml(namespace: string): string {
|
||||||
|
return `apiVersion: v1
|
||||||
|
kind: Service
|
||||||
|
metadata:
|
||||||
|
name: agentrun-v01-postgres
|
||||||
|
namespace: ${namespace}
|
||||||
|
spec:
|
||||||
|
selector:
|
||||||
|
app.kubernetes.io/name: agentrun-v01-postgres
|
||||||
|
ports:
|
||||||
|
- name: postgres
|
||||||
|
port: 5432
|
||||||
|
targetPort: postgres
|
||||||
|
---
|
||||||
|
apiVersion: apps/v1
|
||||||
|
kind: StatefulSet
|
||||||
|
metadata:
|
||||||
|
name: agentrun-v01-postgres
|
||||||
|
namespace: ${namespace}
|
||||||
|
spec:
|
||||||
|
serviceName: agentrun-v01-postgres
|
||||||
|
replicas: 1
|
||||||
|
selector:
|
||||||
|
matchLabels:
|
||||||
|
app.kubernetes.io/name: agentrun-v01-postgres
|
||||||
|
template:
|
||||||
|
metadata:
|
||||||
|
labels:
|
||||||
|
app.kubernetes.io/name: agentrun-v01-postgres
|
||||||
|
spec:
|
||||||
|
containers:
|
||||||
|
- name: postgres
|
||||||
|
image: postgres:16-alpine
|
||||||
|
ports:
|
||||||
|
- name: postgres
|
||||||
|
containerPort: 5432
|
||||||
|
env:
|
||||||
|
- name: POSTGRES_DB
|
||||||
|
value: agentrun_v01
|
||||||
|
- name: POSTGRES_USER
|
||||||
|
valueFrom:
|
||||||
|
secretKeyRef:
|
||||||
|
name: agentrun-v01-postgres
|
||||||
|
key: username
|
||||||
|
- name: POSTGRES_PASSWORD
|
||||||
|
valueFrom:
|
||||||
|
secretKeyRef:
|
||||||
|
name: agentrun-v01-postgres
|
||||||
|
key: password
|
||||||
|
volumeMounts:
|
||||||
|
- name: data
|
||||||
|
mountPath: /var/lib/postgresql/data
|
||||||
|
volumeClaimTemplates:
|
||||||
|
- metadata:
|
||||||
|
name: data
|
||||||
|
spec:
|
||||||
|
accessModes: ["ReadWriteOnce"]
|
||||||
|
resources:
|
||||||
|
requests:
|
||||||
|
storage: 5Gi
|
||||||
|
`;
|
||||||
|
}
|
||||||
|
|
||||||
|
function managerYaml(namespace: string, image: { repositoryDigest: string }): string {
|
||||||
|
return `apiVersion: v1
|
||||||
|
kind: ServiceAccount
|
||||||
|
metadata:
|
||||||
|
name: agentrun-v01-mgr
|
||||||
|
namespace: ${namespace}
|
||||||
|
---
|
||||||
|
apiVersion: v1
|
||||||
|
kind: Service
|
||||||
|
metadata:
|
||||||
|
name: agentrun-mgr
|
||||||
|
namespace: ${namespace}
|
||||||
|
spec:
|
||||||
|
selector:
|
||||||
|
app.kubernetes.io/name: agentrun-mgr
|
||||||
|
ports:
|
||||||
|
- name: http
|
||||||
|
port: 8080
|
||||||
|
targetPort: http
|
||||||
|
---
|
||||||
|
apiVersion: apps/v1
|
||||||
|
kind: Deployment
|
||||||
|
metadata:
|
||||||
|
name: agentrun-mgr
|
||||||
|
namespace: ${namespace}
|
||||||
|
spec:
|
||||||
|
replicas: 1
|
||||||
|
selector:
|
||||||
|
matchLabels:
|
||||||
|
app.kubernetes.io/name: agentrun-mgr
|
||||||
|
template:
|
||||||
|
metadata:
|
||||||
|
labels:
|
||||||
|
app.kubernetes.io/name: agentrun-mgr
|
||||||
|
annotations:
|
||||||
|
agentrun.pikastech.local/lane: v0.1
|
||||||
|
spec:
|
||||||
|
serviceAccountName: agentrun-v01-mgr
|
||||||
|
containers:
|
||||||
|
- name: mgr
|
||||||
|
image: ${image.repositoryDigest}
|
||||||
|
imagePullPolicy: IfNotPresent
|
||||||
|
ports:
|
||||||
|
- name: http
|
||||||
|
containerPort: 8080
|
||||||
|
env:
|
||||||
|
- name: AGENTRUN_LANE
|
||||||
|
value: v0.1
|
||||||
|
- name: DATABASE_URL
|
||||||
|
valueFrom:
|
||||||
|
secretKeyRef:
|
||||||
|
name: agentrun-v01-mgr-db
|
||||||
|
key: DATABASE_URL
|
||||||
|
readinessProbe:
|
||||||
|
httpGet:
|
||||||
|
path: /health/readiness
|
||||||
|
port: http
|
||||||
|
livenessProbe:
|
||||||
|
httpGet:
|
||||||
|
path: /health/live
|
||||||
|
port: http
|
||||||
|
resources:
|
||||||
|
requests:
|
||||||
|
cpu: 100m
|
||||||
|
memory: 256Mi
|
||||||
|
limits:
|
||||||
|
cpu: 800m
|
||||||
|
memory: 1Gi
|
||||||
|
`;
|
||||||
|
}
|
||||||
|
|
||||||
|
function runnerRbacYaml(namespace: string): string {
|
||||||
|
return `apiVersion: v1
|
||||||
|
kind: ServiceAccount
|
||||||
|
metadata:
|
||||||
|
name: agentrun-v01-runner
|
||||||
|
namespace: ${namespace}
|
||||||
|
---
|
||||||
|
apiVersion: rbac.authorization.k8s.io/v1
|
||||||
|
kind: Role
|
||||||
|
metadata:
|
||||||
|
name: agentrun-v01-runner-secret-reader
|
||||||
|
namespace: ${namespace}
|
||||||
|
rules:
|
||||||
|
- apiGroups: [""]
|
||||||
|
resources: ["secrets"]
|
||||||
|
resourceNames: ["agentrun-v01-provider-codex"]
|
||||||
|
verbs: ["get"]
|
||||||
|
---
|
||||||
|
apiVersion: rbac.authorization.k8s.io/v1
|
||||||
|
kind: RoleBinding
|
||||||
|
metadata:
|
||||||
|
name: agentrun-v01-runner-secret-reader
|
||||||
|
namespace: ${namespace}
|
||||||
|
subjects:
|
||||||
|
- kind: ServiceAccount
|
||||||
|
name: agentrun-v01-runner
|
||||||
|
roleRef:
|
||||||
|
apiGroup: rbac.authorization.k8s.io
|
||||||
|
kind: Role
|
||||||
|
name: agentrun-v01-runner-secret-reader
|
||||||
|
`;
|
||||||
|
}
|
||||||
|
|
||||||
|
function parseArgs(argv: string[]): RenderOptions {
|
||||||
|
const flags = new Map<string, string | boolean>();
|
||||||
|
for (let index = 0; index < argv.length; index += 1) {
|
||||||
|
const item = argv[index] ?? "";
|
||||||
|
if (!item.startsWith("--")) continue;
|
||||||
|
const key = item.slice(2);
|
||||||
|
const next = argv[index + 1];
|
||||||
|
if (next === undefined || next.startsWith("--")) flags.set(key, true);
|
||||||
|
else {
|
||||||
|
flags.set(key, next);
|
||||||
|
index += 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
const options: RenderOptions = {
|
||||||
|
outDir: stringFlag(flags, "out", "deploy/gitops/g14"),
|
||||||
|
deployFile: stringFlag(flags, "deploy-file", "deploy/deploy.json"),
|
||||||
|
sourceCommit: stringFlag(flags, "source-commit", "source-check"),
|
||||||
|
registryPrefix: stringFlag(flags, "registry-prefix", "127.0.0.1:5000/agentrun"),
|
||||||
|
requireCatalog: flags.get("require-catalog") === true,
|
||||||
|
check: flags.get("check") === true,
|
||||||
|
};
|
||||||
|
const catalogFile = optionalStringFlag(flags, "catalog");
|
||||||
|
if (catalogFile) options.catalogFile = catalogFile;
|
||||||
|
return options;
|
||||||
|
}
|
||||||
|
|
||||||
|
function stringFlag(flags: Map<string, string | boolean>, key: string, fallback: string): string {
|
||||||
|
const value = flags.get(key);
|
||||||
|
return typeof value === "string" && value.length > 0 ? value : fallback;
|
||||||
|
}
|
||||||
|
|
||||||
|
function optionalStringFlag(flags: Map<string, string | boolean>, key: string): string | undefined {
|
||||||
|
const value = flags.get(key);
|
||||||
|
return typeof value === "string" && value.length > 0 ? value : undefined;
|
||||||
|
}
|
||||||
|
|
||||||
|
function stringField(record: JsonRecord, key: string, fallback: string): string {
|
||||||
|
const value = record[key];
|
||||||
|
return typeof value === "string" && value.length > 0 ? value : fallback;
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user