import { S3Client } from "@aws-sdk/client-s3"; import { type BackupConfig } from "./config.js"; /** 读备份桶(用户自己的桶)的 S3 客户端。drill/restore 共用。 */ export declare function targetClient(config: BackupConfig): S3Client; /** * 列出 root(带尾斜杠)下的全部快照目录,返回带尾斜杠的前缀,未排序。只看 CommonPrefixes, * root 下直接放的对象不算快照。 */ export declare function listSnapshotPrefixes(s3: S3Client, bucket: string, root: string, abortSignal?: AbortSignal): Promise; /** 定位快照:显式指定,否则取字典序最大(时间戳格式天然可排序)。返回带尾斜杠的前缀。 */ export declare function resolveSnapshot(s3: S3Client, config: BackupConfig, explicit?: string): Promise; export declare function getObjectText(s3: S3Client, bucket: string, key: string): Promise; /** 下载对象到本地文件,顺带算 sha256(验证读回的归档没被损坏)。 */ export declare const DOWNLOAD_MAX_ATTEMPTS = 8; /** 最小的文件句柄接口:downloadToFile 只用这两样。测试可以注入假句柄(短写、慢写)。 */ export interface WritableHandle { write(buffer: Buffer, offset: number, length: number, position: number): Promise<{ bytesWritten: number; }>; close(): Promise; } /** * 把一整块写进 position 起的位置,**写满为止**。Node 的 `FileHandle.write` 合约允许一次只写 * 一部分(返回 bytesWritten),按整块计数会让校验和给一份少了字节的文件盖章(交叉审查 * 2026-09-12 故障注入:写进 3 字节、报了 8 字节、校验和照样"通过")。 * 返回真正落盘的字节数;中途抛错时把已确认的字节数挂在错误上,调用方据此对齐哈希与起点。 */ export declare function writeFully(fh: WritableHandle, chunk: Buffer, position: number): Promise; /** * 断点续传下载(2026-09-12):一个 12 GB 的 dump 走一条 HTTPS 流要 50 分钟,对端(用户的桶) * 在第 10 分钟关掉连接,整次演练就没了 —— 而且此前没有任何续传:一次事故、两封 FAILED * 邮件。这里按 HTTP Range 续传,三条铁律: * 1. 续传起点 = **已确认写进 fd 的字节数**,不是流过管道的字节数。pipeline 出错时 Writable * 缓冲区里的块会丢,按"流过多少"续传会在文件里留下一个洞;所以自写 Writable, * `fh.write` 返回之后才计数、才哈希,哈希与磁盘内容永远一致; * 2. 续传请求必须拿到 206:对端不认 Range 就会把整个对象再发一遍,追加上去就是脏文件, * 这种情况直接失败,绝不"看起来成功"; * 3. ETag 变了 = 对象在下载中途被替换,两半拼不成一份,直接失败。 * 重试 8 次,退避 1s→30s;每次续传写一行日志(worker 的 journal 能看到断在哪、续在哪)。 */ export declare function downloadToFile(s3: S3Client, bucket: string, key: string, dest: string, opts?: { maxAttempts?: number; openFile?: (path: string) => Promise; /** 可选:调用方叫停时中止请求和写盘、不再重试(Auth 附加校验用;不传时行为与之前一致) */ signal?: AbortSignal; }): Promise<{ bytes: number; sha256: string; }>; /** 只算对象校验和、不落盘(Storage 文件完整性校验用,省内存/磁盘)。 */ export declare function hashObject(s3: S3Client, bucket: string, key: string): Promise<{ bytes: number; sha256: string; }>;