Files
2025-11-18 09:55:07 +08:00

89 lines
7.0 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# Feature Specification: APT/APK 包缓存模块
**Feature Branch**: `007-apt-apk-cache`
**Created**: 2025-11-17
**Status**: Draft
**Input**: User description: "Title: 设计并实现 APT/APK 包缓存模块以加速 Docker 构建 Goal: 为 any-hub 新增一个 debian/apk 模块,代理本地 Docker 构建中的 apt-get/apk add 请求,支持缓存索引与包文件并透明回源。 Constraints: - 适配 Debian/Ubuntu APT 路径Release/InRelease、Packages(.gz|.xz)、pool/*.deb及 Alpine APKINDEX/packages。 - 索引/Release 需 RequireRevalidate=true二进制包 AllowStore=true签名文件透传。 - 兼容 Acquire-By-HashAPT与 APKINDEX 签名校验,不破坏客户端校验。 - 复用现有缓存架构hooks.go + module.go + CacheStrategyProfile不得影响现有 docker/npm/pypi/go/composer 模块。 Inputs: - 代码库路径:/home/rogee/Projects/any-hub - 参考模块internal/hubmodule/docker/hooks.go (cachePolicy)、internal/hubmodule/golang/hooks.go、internal/proxy/handler.go (ETag/Last-Modified 再验证) Deliverables: - 新增 internal/hubmodule/debian或 alpine下的 hooks.go、module.go 实现 - 配套测试(模拟 apt-get update/install 或 apk update/add 的最小集) - 使用说明(简要配置示例,如何在 config.toml 添加 Hub AcceptanceCriteria: - “apt-get update” 或 “apk update” 指向代理时,首次 miss 回源,二次命中缓存;索引文件可被最新上游版本触发再验证;二进制包稳定命中缓存。 新分支开头数字是 007"
## User Scenarios & Testing *(mandatory)*
### User Story 1 - APT 更新通过代理 (Priority: P1)
本地构建镜像的开发者将 apt 源指向代理,运行 `apt-get update` 获取最新索引并希望后续重复构建无需再次访问官方仓。
**Why this priority**: APT 更新是后续安装的前提,需保证首次拉取成功且缓存生效以降低构建时间与外网依赖。
**Independent Test**: 将 apt 源指向代理后执行两次 `apt-get update`,验证首轮回源、次轮命中缓存且返回内容与官方一致。
**Acceptance Scenarios**:
1. **Given** 缓存为空,**When** 运行 `apt-get update` 指向代理,**Then** 返回官方索引内容且缓存写入成功Release/InRelease/Packages
2. **Given** 同一索引已缓存,**When** 再次运行 `apt-get update`**Then** 返回 200/304 且无额外上游 GET仅必要的条件请求输出内容与首轮一致。
---
### User Story 2 - APT 安装包命中缓存 (Priority: P2)
在构建步骤中安装常用 `.deb` 包,希望重复构建时直接从本地缓存提供 pool 下的包体。
**Why this priority**: 包文件体积大、下载耗时,命中缓存可显著缩短镜像构建时长。
**Independent Test**: 在完成 User Story 1 后,执行 `apt-get install <常见包>` 两次,确认首轮回源、次轮包体命中缓存,且校验/签名不受影响。
**Acceptance Scenarios**:
1. **Given** 缓存已有对应索引且无包体,**When** 首次安装某包,**Then** 包体成功下载并写入缓存,安装过程不因代理失败。
2. **Given** 同一包体已缓存,**When** 再次安装,**Then** 不触发上游包体下载,安装成功且校验通过。
---
### User Story 3 - Alpine APK 加速 (Priority: P3)
将 Alpine 利用代理执行 `apk update && apk add`,希望索引与包体同样缓存并可重复命中。
**Why this priority**: Alpine 镜像在容器场景常用,通过同一代理获得一致的构建加速。
**Independent Test**: 将 `/etc/apk/repositories` 指向代理,执行两轮 `apk update && apk add <常用包>`,验证首轮回源、次轮命中缓存且 APKINDEX/包体校验正常。
**Acceptance Scenarios**:
1. **Given** 代理配置完毕,**When** 首次执行 `apk update`**Then** 获取 APKINDEX 并写入缓存,随后 `apk add` 成功下载包体。
2. **Given** 同一索引与包体已缓存,**When** 再次执行 `apk update && apk add`**Then** 索引再验证后命中,包体直接命中缓存且安装成功。
---
### Edge Cases
- 上游索引更新Release/InRelease 或 APKINDEX 发生变更时,代理应通过条件请求检测到并刷新缓存。
- 校验失败Acquire-By-Hash 校验或 APKINDEX 签名不匹配时,应返回上游原始错误而非吞掉错误。
- 离线/超时:上游暂不可达时,若有缓存且策略允许,应优先返回缓存;无缓存则向客户端返回明确错误。
- 部分源未配置:多源场景下,某源缺失或路径拼写错误时,代理应返回与上游一致的 404/403。
- 大文件/磁盘不足:缓存写入包体时磁盘不足,应优雅失败并告警,不影响后续直接透传回源。
## Requirements *(mandatory)*
### Functional Requirements
- **FR-001**: 代理必须支持 APT 获取与缓存 Release/InRelease、Packages(.gz/.xz) 及 pool 下的包体;索引请求需携带条件请求并可根据上游变更刷新缓存。
- **FR-002**: 代理必须支持 Acquire-By-Hash 路径,若哈希不匹配需返回上游一致的错误,不得用缓存污染返回。
- **FR-003**: 代理必须支持 Alpine APKINDEX 与 packages 路径的获取与缓存,索引需再验证,包体可直接命中缓存。
- **FR-004**: 首次命中失败的索引/包体要回源写入缓存;后续同一路径在缓存有效期内应直接命中,除非索引再验证判定有新版本。
- **FR-005**: 代理行为须保持透明:返回状态码、头信息、签名/校验文件与上游一致,日志需记录命中/回源/失败原因,便于构建诊断。
- **FR-006**: 新增 Hub 配置字段(如仓类型、上游地址)需有默认值与示例,且不得影响现有 docker/npm/pypi/go/composer 的配置与行为。
### Key Entities *(include if feature involves data)*
- **索引文件**APT 的 Release/InRelease/Packages*Alpine 的 APKINDEX含校验或签名信息需可再验证。
- **包体文件**`pool/*/*.deb`、Alpine `packages/*`;内容不可变,按路径/哈希缓存。
- **签名/校验文件**APT 的 Release.gpg、Acquire-By-Hash 路径;用于客户端校验,需原样透传。
- **缓存条目**:存储索引或包体的本地副本,包含写入时间与可选校验标识,用于命中与再验证判定。
## Success Criteria *(mandatory)*
### Measurable Outcomes
- **SC-001**: 在同一构建机器上,第二次执行 `apt-get update``apk update` 对同一源时,上游请求数较首次减少 ≥90%(仅保留必要条件请求),且耗时降低至少 50%。
- **SC-002**: 已缓存的包体再次安装时,不触发上游下载,安装成功率达到 100%(以连续 20 次同包安装为样本)。
- **SC-003**: 当上游索引有新版本发布时,下一次索引请求能够在一次交互内获取最新数据(无旧数据残留),并保持客户端校验/签名通过率 100%。
- **SC-004**: 引入新模块后,现有 docker/npm/pypi/go/composer 代理的功能及配置使用无变化,回归用例全部通过。