fix: include kubectl in CI tools images

This commit is contained in:
pikastech
2026-07-20 19:09:25 +02:00
parent ae824ebb31
commit c2fd4cb3f2
6 changed files with 46 additions and 7 deletions
+6 -1
View File
@@ -362,7 +362,12 @@ bun scripts/cli.ts hwlab nodes control-plane legacy-cicd --help
- 自动链单步测不通时,应在 Git-backed YAML、controller 或源码中修复根因,并由修复 PR 合并产生的新正常 webhook/PaC 事件复测;不得用 branch-follower 写状态或补跑当前交付。
- CI/CD 排障中再次踩到已暴露的运行面坑、工具误用、镜像假设或状态可见性缺口时,必须先把长期规则写入本 skill/reference,再继续只读定位。
- CI/CD 运行面验收必须在目标 NODE/k8s 内计算短摘要;本机只用于源码阅读、编辑和静态合同测试,不能替代正常 PR merge 自动事件产生的目标运行面证据。
- in-cluster/controller/native helper 不能假设镜像内存在 `kubectl` binary。目标 Pod/Job 内读取或写入 Kubernetes 对象必须走 serviceaccount token + Kubernetes HTTPS API 或已封装的 native helper`kubectl` 只允许在 operator 侧受控 CLI/trans 边界作为 transport/debug 包装,不得进入正式 controller 状态读写链路。
- CI tools image 默认必须包含 `kubectl`
- `kubectl` 与其他构建工具统一由 owning YAML 的 tools image Dockerfile 声明并随镜像交付;
- 镜像构建必须执行 `kubectl version --client` 自检;
- 禁止在 PipelineRun、Pod 或 Job 启动后临时安装 `kubectl`
- 使用 tools image 的有界 CI helper、cleanup 或 bootstrap 可以直接调用 `kubectl`
- 产品业务镜像和长期 controller 不得仅因本规则新增对 `kubectl` 的运行时依赖。
- 一旦发现 CI/CD CLI 被误用且可能写入错误状态、产生伪证据或绕过目标运行面,必须立刻先把用法改成更符合直觉的公开入口并更新本 skill/reference,再继续验证或交付;不要只靠口头记忆、隐藏 flag、手动约定或后续小心来避免复发。内部 in-cluster 模式必须只由目标 k8s Job/Pod 调用,操作者从本机只能用公开入口提交目标侧 Job 或读取目标侧摘要。
- PaC migrated consumer 的旧手动 publish/debug 命令不得作为正式 closeout 引导;调查命令默认只能指向只读的 `platform-infra pipelines-as-code status|history``closeout` 仅保留只读兼容能力,不得作为主代理、子代理或操作者的 PR 合并后步骤。需要保留的旧 mutation 命令只能属于 YAML 明确的 legacy authority 或独立平台维护,不得标记或引导 manual recovery;单步确认的自动链缺陷必须回到 YAML/controller/源码修复。
- Secret 只通过 YAML sourceRef/targetKey 和受控 CLI 下发;输出只披露 presence/fingerprint。
@@ -88,6 +88,13 @@ bun scripts/cli.ts hwlab g14 tools-image build \
tools image 构建只在目标 host 和本地 registry 的受控路径中执行,不把 master server 当通用构建机。
- 默认工具集:
- CI tools image 必须随镜像提供 `kubectl`
- `kubectl` 必须由 owning YAML 的内联 Dockerfile 构建,不得在 PipelineRun、Pod 或 Job 启动后安装;
- Dockerfile 构建自检必须包含 `kubectl version --client`
- 有界 CI helper、cleanup 和 bootstrap 可以直接调用镜像内的 `kubectl`
- 产品业务镜像和长期 controller 不继承该运行时依赖。
## PipelineRun 清理
```bash
+13 -4
View File
@@ -523,6 +523,8 @@ targets:
filename: hwlab-ci-node-tools.public.Dockerfile
lines:
- FROM docker.io/library/golang:1.24-bookworm AS golang-toolchain
- FROM docker.io/docker:29-cli AS docker-cli
- RUN apk add --no-cache kubectl
- FROM 127.0.0.1:5000/hwlab/hwlab-ci-node-tools:node22-alpine-bun-v1
- ARG HTTP_PROXY
- ARG HTTPS_PROXY
@@ -533,11 +535,12 @@ targets:
- ARG all_proxy
- ARG no_proxy
- COPY --from=golang-toolchain /usr/local/go /usr/local/go
- COPY --from=docker-cli /usr/bin/kubectl /usr/local/bin/kubectl
- ENV PATH=/usr/local/go/bin:$PATH
- RUN ln -sf /usr/local/bin/bun /usr/local/bin/bunx
- ENV HWLAB_CI_NODE_DEPS=/opt/hwlab-ci-node-deps/node_modules
- RUN set -eu; export HTTP_PROXY="${HTTP_PROXY:-${http_proxy:-}}"; export HTTPS_PROXY="${HTTPS_PROXY:-${https_proxy:-$HTTP_PROXY}}"; export ALL_PROXY="${ALL_PROXY:-${all_proxy:-}}"; export NO_PROXY="${NO_PROXY:-${no_proxy:-}}"; export http_proxy="$HTTP_PROXY"; export https_proxy="$HTTPS_PROXY"; export all_proxy="$ALL_PROXY"; export no_proxy="$NO_PROXY"; export npm_config_registry="https://registry.npmmirror.com/"; export BUN_CONFIG_REGISTRY="https://registry.npmmirror.com/"; export npm_config_noproxy="$NO_PROXY"; if [ -n "$HTTP_PROXY" ]; then export npm_config_proxy="$HTTP_PROXY"; fi; if [ -n "$HTTPS_PROXY" ]; then export npm_config_https_proxy="$HTTPS_PROXY"; fi; export npm_config_fetch_retries=2; export npm_config_fetch_retry_mintimeout=2000; export npm_config_fetch_retry_maxtimeout=16000; export npm_config_fetch_timeout=120000; proxy_label="${HTTP_PROXY:+HTTP_PROXY}"; proxy_label="${proxy_label:-none}"; mkdir -p /opt/hwlab-ci-node-deps; cd /opt/hwlab-ci-node-deps; printf '{"private":true,"dependencies":{}}\n' > package.json; ok=0; delay=2; for attempt in 1 2 3 4 5; do echo "{\"event\":\"tools-yaml-node-npm-install\",\"attempt\":\"$attempt/5\",\"registry\":\"$npm_config_registry\",\"proxy\":\"$proxy_label\"}" >&2; if timeout 180s npm install --package-lock=false --no-save --ignore-scripts --no-audit --no-fund --omit=dev yaml@2.8.3; then ok=1; break; fi; if [ "$attempt" = 5 ]; then break; fi; echo "{\"event\":\"tools-yaml-node-npm-install\",\"status\":\"retrying\",\"attempt\":\"$attempt/5\",\"sleepSeconds\":$delay}" >&2; sleep "$delay"; delay=$((delay * 2)); done; test "$ok" = 1; node --input-type=module -e 'import("/opt/hwlab-ci-node-deps/node_modules/yaml/browser/dist/index.js").then((yaml)=>console.log("yaml-ok", typeof yaml.parse))'
- RUN node --version && npm --version && bun --version && git --version && python3 --version && docker --version && ssh -V && go version
- RUN node --version && npm --version && bun --version && git --version && python3 --version && docker --version && kubectl version --client=true && ssh -V && go version
buildArgs: {}
buildNetwork: host
publicBaseImages:
@@ -729,6 +732,7 @@ targets:
lines:
- FROM docker.io/oven/bun:1.3.13 AS bun-runtime
- FROM docker.io/docker:29-cli AS docker-cli
- RUN apk add --no-cache kubectl
- FROM docker.io/library/golang:1.24-bookworm AS golang-toolchain
- FROM docker.io/library/node:22-bookworm-slim AS node-runtime
- FROM docker.io/library/python:3.12-bookworm
@@ -745,12 +749,13 @@ targets:
- COPY --from=node-runtime /usr/local/lib/node_modules /usr/local/lib/node_modules
- COPY --from=bun-runtime /usr/local/bin/bun /usr/local/bin/bun
- COPY --from=docker-cli /usr/local/bin/docker /usr/local/bin/docker
- COPY --from=docker-cli /usr/bin/kubectl /usr/local/bin/kubectl
- ENV PATH=/usr/local/go/bin:$PATH
- RUN ln -sf /usr/local/lib/node_modules/npm/bin/npm-cli.js /usr/local/bin/npm && ln -sf /usr/local/lib/node_modules/npm/bin/npx-cli.js /usr/local/bin/npx
- RUN ln -sf /usr/local/bin/bun /usr/local/bin/bunx
- ENV HWLAB_CI_NODE_DEPS=/opt/hwlab-ci-node-deps/node_modules
- RUN set -eu; export HTTP_PROXY="${HTTP_PROXY:-${http_proxy:-}}"; export HTTPS_PROXY="${HTTPS_PROXY:-${https_proxy:-$HTTP_PROXY}}"; export ALL_PROXY="${ALL_PROXY:-${all_proxy:-}}"; export NO_PROXY="${NO_PROXY:-${no_proxy:-}}"; export http_proxy="$HTTP_PROXY"; export https_proxy="$HTTPS_PROXY"; export all_proxy="$ALL_PROXY"; export no_proxy="$NO_PROXY"; export npm_config_registry="https://registry.npmmirror.com/"; export BUN_CONFIG_REGISTRY="https://registry.npmmirror.com/"; export npm_config_noproxy="$NO_PROXY"; if [ -n "$HTTP_PROXY" ]; then export npm_config_proxy="$HTTP_PROXY"; fi; if [ -n "$HTTPS_PROXY" ]; then export npm_config_https_proxy="$HTTPS_PROXY"; fi; export npm_config_fetch_retries=2; export npm_config_fetch_retry_mintimeout=2000; export npm_config_fetch_retry_maxtimeout=16000; export npm_config_fetch_timeout=120000; proxy_label="${HTTP_PROXY:+HTTP_PROXY}"; proxy_label="${proxy_label:-none}"; mkdir -p /opt/hwlab-ci-node-deps; cd /opt/hwlab-ci-node-deps; printf '{"private":true,"dependencies":{}}\n' > package.json; ok=0; delay=2; for attempt in 1 2 3 4 5; do echo "{\"event\":\"tools-yaml-node-npm-install\",\"attempt\":\"$attempt/5\",\"registry\":\"$npm_config_registry\",\"proxy\":\"$proxy_label\"}" >&2; if timeout 180s npm install --package-lock=false --no-save --ignore-scripts --no-audit --no-fund --omit=dev yaml@2.8.3; then ok=1; break; fi; if [ "$attempt" = 5 ]; then break; fi; echo "{\"event\":\"tools-yaml-node-npm-install\",\"status\":\"retrying\",\"attempt\":\"$attempt/5\",\"sleepSeconds\":$delay}" >&2; sleep "$delay"; delay=$((delay * 2)); done; test "$ok" = 1; node --input-type=module -e 'import("/opt/hwlab-ci-node-deps/node_modules/yaml/browser/dist/index.js").then((yaml)=>console.log("yaml-ok", typeof yaml.parse))'
- RUN node --version && npm --version && bun --version && git --version && python3 --version && docker --version && ssh -V && go version
- RUN node --version && npm --version && bun --version && git --version && python3 --version && docker --version && kubectl version --client=true && ssh -V && go version
buildArgs: {}
buildNetwork: host
publicBaseImages:
@@ -947,6 +952,7 @@ targets:
lines:
- FROM docker.io/oven/bun:1.3.13 AS bun-runtime
- FROM docker.io/docker:29-cli AS docker-cli
- RUN apk add --no-cache kubectl
- FROM docker.io/library/golang:1.24-bookworm AS golang-toolchain
- FROM docker.io/library/node:22-bookworm-slim AS node-runtime
- FROM docker.io/library/python:3.12-bookworm
@@ -963,12 +969,13 @@ targets:
- COPY --from=node-runtime /usr/local/lib/node_modules /usr/local/lib/node_modules
- COPY --from=bun-runtime /usr/local/bin/bun /usr/local/bin/bun
- COPY --from=docker-cli /usr/local/bin/docker /usr/local/bin/docker
- COPY --from=docker-cli /usr/bin/kubectl /usr/local/bin/kubectl
- ENV PATH=/usr/local/go/bin:$PATH
- RUN ln -sf /usr/local/lib/node_modules/npm/bin/npm-cli.js /usr/local/bin/npm && ln -sf /usr/local/lib/node_modules/npm/bin/npx-cli.js /usr/local/bin/npx
- RUN ln -sf /usr/local/bin/bun /usr/local/bin/bunx
- ENV HWLAB_CI_NODE_DEPS=/opt/hwlab-ci-node-deps/node_modules
- RUN set -eu; export HTTP_PROXY="${HTTP_PROXY:-${http_proxy:-}}"; export HTTPS_PROXY="${HTTPS_PROXY:-${https_proxy:-$HTTP_PROXY}}"; export ALL_PROXY="${ALL_PROXY:-${all_proxy:-}}"; export NO_PROXY="${NO_PROXY:-${no_proxy:-}}"; export http_proxy="$HTTP_PROXY"; export https_proxy="$HTTPS_PROXY"; export all_proxy="$ALL_PROXY"; export no_proxy="$NO_PROXY"; export npm_config_registry="https://registry.npmmirror.com/"; export BUN_CONFIG_REGISTRY="https://registry.npmmirror.com/"; export npm_config_noproxy="$NO_PROXY"; if [ -n "$HTTP_PROXY" ]; then export npm_config_proxy="$HTTP_PROXY"; fi; if [ -n "$HTTPS_PROXY" ]; then export npm_config_https_proxy="$HTTPS_PROXY"; fi; export npm_config_fetch_retries=2; export npm_config_fetch_retry_mintimeout=2000; export npm_config_fetch_retry_maxtimeout=16000; export npm_config_fetch_timeout=120000; proxy_label="${HTTP_PROXY:+HTTP_PROXY}"; proxy_label="${proxy_label:-none}"; mkdir -p /opt/hwlab-ci-node-deps; cd /opt/hwlab-ci-node-deps; printf '{"private":true,"dependencies":{}}\n' > package.json; ok=0; delay=2; for attempt in 1 2 3 4 5; do echo "{\"event\":\"tools-yaml-node-npm-install\",\"attempt\":\"$attempt/5\",\"registry\":\"$npm_config_registry\",\"proxy\":\"$proxy_label\"}" >&2; if timeout 180s npm install --package-lock=false --no-save --ignore-scripts --no-audit --no-fund --omit=dev yaml@2.8.3; then ok=1; break; fi; if [ "$attempt" = 5 ]; then break; fi; echo "{\"event\":\"tools-yaml-node-npm-install\",\"status\":\"retrying\",\"attempt\":\"$attempt/5\",\"sleepSeconds\":$delay}" >&2; sleep "$delay"; delay=$((delay * 2)); done; test "$ok" = 1; node --input-type=module -e 'import("/opt/hwlab-ci-node-deps/node_modules/yaml/browser/dist/index.js").then((yaml)=>console.log("yaml-ok", typeof yaml.parse))'
- RUN node --version && npm --version && bun --version && git --version && python3 --version && docker --version && ssh -V && go version
- RUN node --version && npm --version && bun --version && git --version && python3 --version && docker --version && kubectl version --client=true && ssh -V && go version
buildArgs: {}
buildNetwork: host
publicBaseImages:
@@ -1206,6 +1213,7 @@ targets:
lines:
- FROM docker.io/oven/bun:1.3.13 AS bun-runtime
- FROM docker.io/docker:29-cli AS docker-cli
- RUN apk add --no-cache kubectl
- FROM docker.io/library/golang:1.24-bookworm AS golang-toolchain
- FROM docker.io/library/node:22-bookworm-slim AS node-runtime
- FROM docker.io/library/python:3.12-bookworm
@@ -1222,12 +1230,13 @@ targets:
- COPY --from=node-runtime /usr/local/lib/node_modules /usr/local/lib/node_modules
- COPY --from=bun-runtime /usr/local/bin/bun /usr/local/bin/bun
- COPY --from=docker-cli /usr/local/bin/docker /usr/local/bin/docker
- COPY --from=docker-cli /usr/bin/kubectl /usr/local/bin/kubectl
- ENV PATH=/usr/local/go/bin:$PATH
- RUN ln -sf /usr/local/lib/node_modules/npm/bin/npm-cli.js /usr/local/bin/npm && ln -sf /usr/local/lib/node_modules/npm/bin/npx-cli.js /usr/local/bin/npx
- RUN ln -sf /usr/local/bin/bun /usr/local/bin/bunx
- ENV HWLAB_CI_NODE_DEPS=/opt/hwlab-ci-node-deps/node_modules
- RUN set -eu; unset HTTP_PROXY HTTPS_PROXY ALL_PROXY http_proxy https_proxy all_proxy; export npm_config_registry="https://registry.npmmirror.com/"; export BUN_CONFIG_REGISTRY="https://registry.npmmirror.com/"; export npm_config_fetch_retries=2; export npm_config_fetch_retry_mintimeout=2000; export npm_config_fetch_retry_maxtimeout=16000; export npm_config_fetch_timeout=120000; mkdir -p /opt/hwlab-ci-node-deps; cd /opt/hwlab-ci-node-deps; printf '{"private":true,"dependencies":{}}\n' > package.json; ok=0; delay=2; for attempt in 1 2 3 4 5; do echo "{\"event\":\"tools-yaml-node-npm-install\",\"attempt\":\"$attempt/5\",\"registry\":\"$npm_config_registry\",\"proxy\":\"none\"}" >&2; if timeout 180s npm install --package-lock=false --no-save --ignore-scripts --no-audit --no-fund --omit=dev yaml@2.8.3; then ok=1; break; fi; if [ "$attempt" = 5 ]; then break; fi; echo "{\"event\":\"tools-yaml-node-npm-install\",\"status\":\"retrying\",\"attempt\":\"$attempt/5\",\"sleepSeconds\":$delay}" >&2; sleep "$delay"; delay=$((delay * 2)); done; test "$ok" = 1; node --input-type=module -e 'import("/opt/hwlab-ci-node-deps/node_modules/yaml/browser/dist/index.js").then((yaml)=>console.log("yaml-ok", typeof yaml.parse))'
- RUN node --version && npm --version && bun --version && git --version && python3 --version && docker --version && ssh -V && go version
- RUN node --version && npm --version && bun --version && git --version && python3 --version && docker --version && kubectl version --client=true && ssh -V && go version
buildArgs: {}
buildNetwork: host
publicBaseImages:
+6 -1
View File
@@ -191,7 +191,12 @@ PipelineRun 失败或长时间未完成时,先按定点 `control-plane status
- `platform-infra observability plan|apply|status|validate|trace --target <node>``platform-infra` 内 OTel Collector 和 Tempo trace backend 的受控入口,`--target` 必须选择 trace 所属运行面节点;具体 trace 查询、噪声压制、Code Agent/AgentRun 排障和“先改进 OTel”的操作面统一见 `$unidesk-otel``.agents/skills/unidesk-otel/SKILL.md`)。
- `secrets plan|sync|status --config config/secrets-distribution.yaml --scope platform-infra` 是平台服务本地 Secret sourceRef 到 Kubernetes Secret key 的受控下发入口。`plan` 只读展示 sourceRef、必需 key、目标 Secret/key、missingKeys 和 fingerprint`sync --confirm` 只按 YAML 声明创建允许生成的本地 key 并下发到声明的目标 Secret;`status` 只验证 live Secret key presence。该入口禁止从 live pod 或 Kubernetes Secret 反推密码、API key、JWT secret、n8n encryption key 或 `DATABASE_URL`,输出也不得打印 base64、解码值或远端 raw transcript;即使显式 `--raw` 也只返回脱敏 summary 和 raw omission 标记。LangBot/n8n Secret 轮换和缺 key 修复规则见 `docs/reference/platform-infra.md#secret-distribution-boundary`
- `hwlab g14 observability status|apply|query|targets|boundary|closeout [--lane v02] [--promql <expr>] [--expect-count N] [--expect-value V] [--dry-run|--confirm]` 是 G14 `devops-infra` 共享监控基础设施和 HWLAB v0.2 监控 closeout 的受控入口。`apply` 固定安装 Prometheus Operator `v0.91.0`、Prometheus `v3.12.0`、Prometheus 发现 RBAC、`devops-infra` 内 Prometheus 实例和 ClusterIP query Service,并给被允许发现的 workload namespace 打低风险 label;它不把 Prometheus、Grafana 或 Alertmanager 部署到 `hwlab-v02`,也不接管 HWLAB runtime Deployment/Service。`status` 只读汇总 CRD、operator Deployment、Prometheus CR/pod/service、`hwlab-v02` ServiceMonitor/PrometheusRule 和 bounded `up` 查询;`query` 只通过 Kubernetes service proxy 查询 Prometheus,支持 `--expect-count` / `--expect-value` 输出 `assertion`、bad values 和 missing/extra series`targets` 汇总 ServiceMonitor/PrometheusRule、metrics sidecar readiness/restart、三层指标值和 `metrics.k8s.io` 当前 CPU/内存资源快照;`boundary` 验证 workload namespace 没有 Prometheus/Alertmanager,并对 `19666/19667` 公网 `/metrics` 做负向验证;`closeout` 聚合平台 ready、scrape reachable、sidecar serving、business health probe、resource snapshot、namespace boundary 和 public metrics exposure 语义结论。长期边界见 `docs/reference/g14-observability-infra.md`
- `hwlab g14 tools-image status|build --name ci-node-tools --tag <tag> [--dockerfile deploy/ci/hwlab-ci-node-tools.Dockerfile] [--dry-run|--confirm]` 是 G14 固定 HWLAB CI tools image 的受控 host build/push 入口;构建和 push 只发生在 G14 host 与本地 registry,不在 master server 构建,也不把 `apk add`/runtime install 塞进 Tekton PipelineRun。
- CI tools image
- legacy G14 入口为 `hwlab g14 tools-image status|build --name ci-node-tools --tag <tag> [--dockerfile deploy/ci/hwlab-ci-node-tools.Dockerfile] [--dry-run|--confirm]`
- node-scoped 入口为 `hwlab nodes control-plane infra tools-image status|build|logs --node <node> --lane <lane>`
- 构建和 push 只发生在目标 host 与 node-local registry,不在 master server 构建;
- 镜像默认提供 `kubectl`,并在 Dockerfile 构建阶段执行 `kubectl version --client`
- 禁止在 Tekton PipelineRun、Pod 或 Job 启动后临时安装工具。
- `trans gh:/owner/repo ...` 把 GitHub issue/PR 映射成只读、受控写入的虚拟文本目录:
- `ls` 展示 PR / issue 目录和有界条目摘要;`cat` 直接读取一楼正文;`rg` 在正文内检索。
- `apply-patch` 使用默认 v2 虚拟文件 executor,把正文一楼映射为 `body.md`,写回仍走 `bun scripts/cli.ts gh issue/pr update` 的 guard/concurrency 规则。
@@ -263,6 +263,18 @@ freshness 预判阻断 YAML-first 变更。入口应在停止服务后备份派
节点就绪或期望状态收敛失败才可使 apply 失败。不得重新引入凭据新旧
preflight、CI gate 或人工确认门禁。
### 6.9 OPS-TARGET-REQ-009 CI 工具镜像默认能力
| 编号 | 短名 | 主责模块 | 关联模块 |
| --- | --- | --- | --- |
| OPS-TARGET-REQ-009 | 工具镜像能力 | PJ2026-01060308 YAML目标治理 | [发布流水](PJ2026-010601-controlled-release.md)、[平台运维](PJ2026-0106-platform-ops.md) |
- CI tools image 必须默认包含 `kubectl`
- `kubectl` 必须由 owning YAML 声明的 Dockerfile 在镜像构建阶段安装和自检;
- 使用 tools image 的有界 CI helper、cleanup 和 bootstrap 可以调用镜像内的 `kubectl`
- 禁止在 PipelineRun、Pod 或 Job 启动后临时安装 `kubectl`
- 该默认能力只属于 CI tools image,不得隐式扩大为产品业务镜像或长期 controller 的运行时依赖。
## 7. 过程控制
本规格的执行 issue 为 [#911](https://github.com/pikasTech/unidesk/issues/911)。源码文件头部应标注 `SPEC: PJ2026-01060308 cicd-yaml-targets draft-2026-06-25-cicd-yaml-targets`;自动生成文件、纯配置、锁文件和无法承载注释头的二进制产物可例外。
+2 -1
View File
@@ -1217,7 +1217,7 @@ ${indentBlock(labels, 8)}
containers:
- name: cleanup
image: ${cleanup.image}
imagePullPolicy: IfNotPresent
imagePullPolicy: Always
command: ["kubectl"]
args:
- -n
@@ -1226,6 +1226,7 @@ ${indentBlock(labels, 8)}
- deployment/${cleanup.deploymentName}
- secret/${cleanup.secretName}
- --ignore-not-found
- --wait=false
`;
}