feat: rename skills/skiff to pouch and move ACK state under .pouch
Use ~/.pouch, the pouch CLI, and .pouch.yaml as the SSOT container. Keep the inner skills/ packages, and store ACK project state in .pouch/ack instead of docs/ack.
This commit is contained in:
@@ -5,9 +5,9 @@
|
||||
支持三种用法:
|
||||
|
||||
- **独立配置中心**:一个专门的 Git 仓库管所有机器的所有 Compose 服务(如 app00)
|
||||
- **项目内 Compose 环境**:在普通项目里放 `.skiff/deployer/{prod,test,dev}/`,
|
||||
- **项目内 Compose 环境**:在普通项目里放 `.pouch/deployer/{prod,test,dev}/`,
|
||||
把这个项目的生产/测试/开发环境用 rsync + docker compose 部署
|
||||
- **Argo CD / GitOps**:项目里放 `.skiff/deployer/argocd.yaml`;Agent 改 GitOps 并开 MR,
|
||||
- **Argo CD / GitOps**:项目里放 `.pouch/deployer/argocd.yaml`;Agent 改 GitOps 并开 MR,
|
||||
你合并后由 Argo CD 同步。仓库既可以只写 Git 地址(部署时浅 clone),也可以指定本机已有目录。
|
||||
|
||||
## 什么时候使用
|
||||
@@ -42,7 +42,7 @@ vhom1 上那个 naiveproxy 为什么 sync 失败?
|
||||
web1 能出网,直接让它从 https://... 把包拉下来装
|
||||
|
||||
# 项目内环境
|
||||
给这个项目建好 .skiff/deployer,prod 和 test 分别放到两台机器上
|
||||
给这个项目建好 .pouch/deployer,prod 和 test 分别放到两台机器上
|
||||
把 test 环境重新部署一下
|
||||
prod 的 compose 加个 redis,改完发上去
|
||||
|
||||
@@ -55,13 +55,13 @@ GitOps 我已经 clone 在 ../infra-gitops,用那个目录开 MR
|
||||
## Agent 会做什么
|
||||
|
||||
1. 读服务/环境目录(及共享的父目录)的 `_config.yaml`,确定目标机器和远程路径;
|
||||
项目内布局从 `.skiff/deployer/` 自动发现,无需额外配置
|
||||
项目内布局从 `.pouch/deployer/` 自动发现,无需额外配置
|
||||
2. 用 skill 自带脚本把本地目录同步到远程(rsync,自动排除 `data/`、`_data/`)
|
||||
3. 在远程执行对应的 `docker compose` 操作(启动 / 重建 / 升级 / 重启)
|
||||
4. deb 包安装走独立脚本:scp 上传到暂存目录后远程 apt 安装,失败自动修依赖
|
||||
5. 同步后查看容器状态和日志确认生效
|
||||
6. 只针对你指定的那一个服务操作,不会批量动整台机器
|
||||
7. Argo CD:读 `.skiff/deployer/argocd.yaml`,浅 clone 或使用 `repo_dir`,改清单,推分支开 MR,停下来等你合并;
|
||||
7. Argo CD:读 `.pouch/deployer/argocd.yaml`,浅 clone 或使用 `repo_dir`,改清单,推分支开 MR,停下来等你合并;
|
||||
不直接 kubectl 发布,不把 Harbor/TLS 密钥提交进 Git
|
||||
|
||||
项目内布局下,远程目录名自动带上项目前缀(如 `my-project-prod`),
|
||||
@@ -80,14 +80,14 @@ GitOps 我已经 clone 在 ../infra-gitops,用那个目录开 MR
|
||||
|
||||
## Argo CD 的两种接法
|
||||
|
||||
在业务项目里放 `.skiff/deployer/argocd.yaml`。Agent 只改 GitOps 并开 MR,**你合并之后** Argo CD 才部署。镜像、namespace、域名、Secret 名以 GitOps 清单为准,不必在这个文件里再抄一遍。
|
||||
在业务项目里放 `.pouch/deployer/argocd.yaml`。Agent 只改 GitOps 并开 MR,**你合并之后** Argo CD 才部署。镜像、namespace、域名、Secret 名以 GitOps 清单为准,不必在这个文件里再抄一遍。
|
||||
|
||||
### 1. 只写仓库地址(默认)
|
||||
|
||||
本机不用长期放 GitOps 仓库。部署时 Agent 浅 clone 到临时目录,改完开 MR,用完删掉。
|
||||
|
||||
```yaml
|
||||
# .skiff/deployer/argocd.yaml
|
||||
# .pouch/deployer/argocd.yaml
|
||||
repo: git@git.example.com:org/infra-gitops.git
|
||||
```
|
||||
|
||||
@@ -105,7 +105,7 @@ repo: git@git.example.com:org/infra-gitops.git
|
||||
GitOps 仓库已经 checkout 在旁边时,写 `repo_dir`,Agent 直接进这个目录改、推分支、开 MR。
|
||||
|
||||
```yaml
|
||||
# .skiff/deployer/argocd.yaml
|
||||
# .pouch/deployer/argocd.yaml
|
||||
repo: git@git.example.com:org/infra-gitops.git
|
||||
repo_dir: ../infra-gitops
|
||||
```
|
||||
|
||||
@@ -42,7 +42,7 @@ description: >-
|
||||
|
||||
| 信号 | 轨道 |
|
||||
|------|------|
|
||||
| ArgoCD / GitOps / 集群 / 开 MR 部署 / 项目有 `.skiff/deployer/argocd.yaml` | Argo CD,见 [argocd.md](references/argocd.md) |
|
||||
| ArgoCD / GitOps / 集群 / 开 MR 部署 / 项目有 `.pouch/deployer/argocd.yaml` | Argo CD,见 [argocd.md](references/argocd.md) |
|
||||
| sync、`TGT=`、某台机器、`compose.yaml` | Compose(下文布局与步骤) |
|
||||
| 两者都有且意图不清 | 先问 |
|
||||
|
||||
@@ -57,7 +57,7 @@ description: >-
|
||||
|
||||
### Argo CD
|
||||
|
||||
源项目 `.skiff/deployer/argocd.yaml`:`repo` 写 Git 地址(部署时浅 clone),或加 `repo_dir` 用已有 checkout。
|
||||
源项目 `.pouch/deployer/argocd.yaml`:`repo` 写 Git 地址(部署时浅 clone),或加 `repo_dir` 用已有 checkout。
|
||||
改 GitOps 清单,不要改 Compose 脚本。密钥不入库。两种接法见 skill README,步骤见 [argocd.md](references/argocd.md)。
|
||||
|
||||
### 两种 Compose 布局
|
||||
@@ -75,14 +75,14 @@ repo/
|
||||
|
||||
远程目录名 = 目录末级名:`vyyo1/naiveproxy` → `/opt/app/naiveproxy`。
|
||||
|
||||
**B. 项目内环境布局**:项目根放 `.skiff/deployer/{prod,test,dev}/`,
|
||||
**B. 项目内环境布局**:项目根放 `.pouch/deployer/{prod,test,dev}/`,
|
||||
每个环境一个目录。从项目内任意位置运行脚本即自动发现(也可用 `DEPLOYER_ROOT`
|
||||
显式指定),无需环境变量:
|
||||
|
||||
```
|
||||
my-project/
|
||||
├── src/ ... # 项目本体
|
||||
└── .skiff/deployer/
|
||||
└── .pouch/deployer/
|
||||
├── _config.yaml # 三个环境共享默认(node/base_path 等)
|
||||
├── argocd.yaml # 可选,Argo CD 指针(不是 compose 环境)
|
||||
├── prod/
|
||||
@@ -106,7 +106,7 @@ skill 目录下的 `scripts/deploy/` 是通用部署工具链(lib/sync/remote/
|
||||
不依赖具体项目路径。部署根按以下顺序解析:
|
||||
|
||||
1. 环境变量 `DEPLOYER_ROOT` 显式指定(独立配置中心仓库用这个)
|
||||
2. 从当前目录向上找 `.skiff/deployer/`(项目内环境布局自动发现)
|
||||
2. 从当前目录向上找 `.pouch/deployer/`(项目内环境布局自动发现)
|
||||
3. skill 安装位置兜底(仅用于查看,没有可部署服务)
|
||||
|
||||
```bash
|
||||
@@ -162,9 +162,9 @@ python3 <skill-dir>/scripts/deploy/sync.py <service-path>
|
||||
|
||||
项目环境布局:
|
||||
|
||||
1. 项目根建 `.skiff/deployer/{env}/`(env 通常为 prod/test/dev)
|
||||
1. 项目根建 `.pouch/deployer/{env}/`(env 通常为 prod/test/dev)
|
||||
2. 每个环境写 `compose.yaml`;三个环境共享的 node/base_path 放
|
||||
`.skiff/deployer/_config.yaml`
|
||||
`.pouch/deployer/_config.yaml`
|
||||
3. 环境有差异(不同主机、不同排除项)→ 在该环境的 `_config.yaml` 覆盖
|
||||
4. 同名冲突或需要固定远程目录名 → `_config.yaml` 写 `name:`
|
||||
5. 首次部署前确认目标主机的远程目录不存在旧内容(rsync `--delete` 会清掉)
|
||||
@@ -173,7 +173,7 @@ python3 <skill-dir>/scripts/deploy/sync.py <service-path>
|
||||
|
||||
独立仓库布局:配置移入 `unused/`(自动脱离发现体系),远程按需手动清理:
|
||||
`ssh <node> "cd <base_path>/<name> && docker compose down"`,数据卷按需保留或删除。
|
||||
项目环境布局:删除对应 `.skiff/deployer/{env}/` 目录即可脱离发现体系,远程清理同上。
|
||||
项目环境布局:删除对应 `.pouch/deployer/{env}/` 目录即可脱离发现体系,远程清理同上。
|
||||
|
||||
#### 7. 向节点安装 deb 包
|
||||
|
||||
@@ -204,7 +204,7 @@ python3 <skill-dir>/scripts/deploy/deb.py <target> apt https://example.com/foo_1
|
||||
|
||||
完整步骤与 `argocd.yaml` 字段见 [argocd.md](references/argocd.md)。
|
||||
|
||||
1. 读项目 `.skiff/deployer/argocd.yaml`(无则只问 Git 地址,写成 `repo:`)。
|
||||
1. 读项目 `.pouch/deployer/argocd.yaml`(无则只问 Git 地址,写成 `repo:`)。
|
||||
有 `repo_dir` 则用该目录;否则把 `repo` 浅 clone 到临时目录,用完删除。
|
||||
2. 在工作副本里按**已有应用惯例**新增 Application,或只改镜像 tag / 清单。
|
||||
3. 从最新默认分支拉出分支,commit、push,用 `glab`/`gh`/`tea` 开 MR;CLI 对项目 404 则把
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
|
||||
`_config.yaml` 供 **Compose 轨道**脚本解析,决定同步目标与排除规则。可放在**服务目录、部署根或其任意祖先目录**;子目录中的字段覆盖父目录(继承合并)。
|
||||
|
||||
Argo CD 轨道用独立文件 `.skiff/deployer/argocd.yaml`,字段见 [argocd.md](argocd.md)。
|
||||
Argo CD 轨道用独立文件 `.pouch/deployer/argocd.yaml`,字段见 [argocd.md](argocd.md)。
|
||||
不要把 `argocd:` 嵌进本文件(脚本解析器不支持嵌套映射)。
|
||||
|
||||
## 放置位置(两种布局)
|
||||
@@ -10,16 +10,16 @@ Argo CD 轨道用独立文件 `.skiff/deployer/argocd.yaml`,字段见 [argocd.
|
||||
| 布局 | 部署根 | `_config.yaml` 典型位置 |
|
||||
|------|--------|------------------------|
|
||||
| 独立配置中心仓库(`DEPLOYER_ROOT` 指向) | 仓库根 | 主机目录 `vyyo1/_config.yaml`、服务目录 |
|
||||
| 项目内环境 `.skiff/deployer/{env}/` | `.skiff/deployer/` | 根级共享默认、各环境目录覆盖 |
|
||||
| 项目内环境 `.pouch/deployer/{env}/` | `.pouch/deployer/` | 根级共享默认、各环境目录覆盖 |
|
||||
|
||||
项目布局示例:
|
||||
|
||||
```yaml
|
||||
# .skiff/deployer/_config.yaml — 三个环境共享
|
||||
# .pouch/deployer/_config.yaml — 三个环境共享
|
||||
node: my-vps
|
||||
base_path: /srv/apps
|
||||
|
||||
# .skiff/deployer/prod/_config.yaml — 仅生产环境差异
|
||||
# .pouch/deployer/prod/_config.yaml — 仅生产环境差异
|
||||
node: prod-vps # 覆盖父级
|
||||
name: my-project-api # 可选,覆盖默认的 {项目名}-{env}
|
||||
```
|
||||
@@ -111,7 +111,7 @@ sync_exclude:
|
||||
| 同一 SSH 主机多个服务 | 主机目录写一份 `node`/`base_path`,子服务免重复 |
|
||||
| 各服务目标不同 | 服务目录单独写 `_config.yaml` |
|
||||
| 个别覆盖 | 子目录只写差异字段 |
|
||||
| 项目三环境同主机 | `.skiff/deployer/_config.yaml` 写共享 node,各环境只放差异 |
|
||||
| 项目三环境同主机 | `.pouch/deployer/_config.yaml` 写共享 node,各环境只放差异 |
|
||||
| 项目环境分属不同主机 | 各环境 `_config.yaml` 分别写 `node` |
|
||||
|
||||
## 示例
|
||||
@@ -137,4 +137,4 @@ node: deploy@web2-backup
|
||||
- 目录内有 `compose.yaml`
|
||||
- 能通过继承或兜底解析出 `node`
|
||||
- 独立仓库布局:路径中不含 `unused/` 段
|
||||
- 项目环境布局:位于部署根 `.skiff/deployer/` 内(其外的项目文件不扫描)
|
||||
- 项目环境布局:位于部署根 `.pouch/deployer/` 内(其外的项目文件不扫描)
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
|
||||
支持两种布局:
|
||||
1. 独立配置中心仓库(DEPLOYER_ROOT 指向,或 skill 安装位置)
|
||||
2. 项目内环境目录 .skiff/deployer/{prod,test,dev}/(从 CWD 自动发现)
|
||||
2. 项目内环境目录 .pouch/deployer/{prod,test,dev}/(从 CWD 自动发现;兼容 .skiff/deployer)
|
||||
"""
|
||||
|
||||
from __future__ import annotations
|
||||
@@ -18,10 +18,11 @@ DEFAULT_BASE_PATH = "/opt/app"
|
||||
DEFAULT_SYNC_EXCLUDES = ("data", "_data")
|
||||
_SKILL_DIR = Path(__file__).resolve().parent.parent # scripts/
|
||||
PROJECT_ROOT: Path | None = None
|
||||
_PROJECT_LAYOUT_DIRS = (".pouch", ".skiff")
|
||||
|
||||
|
||||
def _find_project_root() -> Path:
|
||||
"""部署根:DEPLOYER_ROOT > 从 CWD 向上找 .skiff/deployer > skill 安装位置。"""
|
||||
"""部署根:DEPLOYER_ROOT > 从 CWD 向上找 .pouch/deployer > skill 安装位置。"""
|
||||
env = os.environ.get("DEPLOYER_ROOT", "").strip()
|
||||
if env:
|
||||
p = Path(env).expanduser().resolve()
|
||||
@@ -31,9 +32,10 @@ def _find_project_root() -> Path:
|
||||
return p
|
||||
cur = Path.cwd()
|
||||
while True:
|
||||
cand = cur / ".skiff" / "deployer"
|
||||
if cand.is_dir():
|
||||
return cand
|
||||
for dirname in _PROJECT_LAYOUT_DIRS:
|
||||
cand = cur / dirname / "deployer"
|
||||
if cand.is_dir():
|
||||
return cand
|
||||
if cur == cur.parent:
|
||||
break
|
||||
cur = cur.parent
|
||||
@@ -48,13 +50,13 @@ def project_root() -> Path:
|
||||
|
||||
|
||||
def in_project_layout(root: Path | None = None) -> bool:
|
||||
"""部署根是否为某项目内的 .skiff/deployer/。"""
|
||||
"""部署根是否为某项目内的 .pouch/deployer/。"""
|
||||
root = root or project_root()
|
||||
return root.name == "deployer" and root.parent.name == ".skiff"
|
||||
return root.name == "deployer" and root.parent.name in _PROJECT_LAYOUT_DIRS
|
||||
|
||||
|
||||
def project_display_name(root: Path | None = None) -> str:
|
||||
"""项目名:git 仓库名优先,否则 .skiff 的父目录名。"""
|
||||
"""项目名:git 仓库名优先,否则 .pouch 的父目录名。"""
|
||||
root = root or project_root()
|
||||
anchor = root.parent.parent if in_project_layout(root) else root
|
||||
try:
|
||||
@@ -111,7 +113,7 @@ def load_config(config_path: os.PathLike | str, *, required: bool = True) -> dic
|
||||
def config_paths_for_service(service_dir: str) -> list[Path]:
|
||||
"""收集部署根自身及服务目录各层 _config.yaml(祖先在前,服务目录在后)。
|
||||
|
||||
部署根的 _config.yaml(如 .skiff/deployer/_config.yaml)作为全局默认,
|
||||
部署根的 _config.yaml(如 .pouch/deployer/_config.yaml)作为全局默认,
|
||||
对所有环境/服务生效。
|
||||
"""
|
||||
root = project_root()
|
||||
@@ -333,7 +335,7 @@ def service_info(service_dir: str, *, strict: bool = True) -> dict | None:
|
||||
def is_deployable_dir(path: Path, root: Path) -> bool:
|
||||
if "unused" in path.parts or "__pycache__" in path.parts:
|
||||
return False
|
||||
if ".skiff" in path.parts and root.name != "deployer":
|
||||
if any(part in _PROJECT_LAYOUT_DIRS for part in path.parts) and root.name != "deployer":
|
||||
return False
|
||||
if not (path / "compose.yaml").is_file():
|
||||
return False
|
||||
|
||||
Reference in New Issue
Block a user