80 Commits
Author SHA1 Message Date
耗子andClaude Opus 5.5 b1dcf2b08f feat(file): 压缩、解压、远程下载改为任务队列窗口实时查看日志
- 提交后弹出任务队列窗口:左侧任务列表默认收起,右侧通过 websocket 实时显示当前任务日志;可最小化或关闭,任务照常在后台执行,工具栏按钮可重新打开
- 完成或取消的任务自动移出并切到下一个任务的日志,失败的留着看日志;每有任务结束就刷新文件列表,全部成功后自动关闭窗口并提示
- 队列存 localStorage,关掉文件管理再打开也能接着跟踪
- 文件管理的压缩、解压任务打开逐文件输出,备份等内部调用保持静默
- 压缩、解压、远程下载接口返回创建的任务,新增批量查询任务接口,已删除的任务不在结果里
- 可拖拽窗口统一管理层级和最小化停靠位:编辑器与任务队列同时最小化时横向排开,后展开的在上层,任一窗口展开时文件列表不响应快捷键

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-09-24 20:48:11 +08:00
耗子andClaude Fable 5.1 d51485bcf9 style: 精简注释
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
2026-09-23 02:17:40 +08:00
耗子andClaude Fable 5.1 3f0000cdb0 fix(io,shell): 审查修正
- 压缩命令的退出码 1 容错括在 tar/7z 自身上,不再把前面 cd/rm 的失败一起吞掉
- Mv 拒绝互为祖先的目录合并,目标是源的父目录时交给 mv 报错,不再把自己搬进自己
- Chmod/ChmodR 起点是符号链接时跟随到目标,与 chmod 命令一致
- webhook 脚本输出落文件而不是管道,脚本留下的后台进程不会触发宽限期报错,也不会死于 SIGPIPE

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
2026-09-23 02:17:40 +08:00
耗子andClaude Fable 5.1 cc4b8d5acb refactor(io): 路径统一引号转义,Mv/Cp 改合并语义,Chmod/Chown 拆递归版
- Mv/Cp 用 -T 语义,目标已存在的目录合并而非嵌套;rename 撞上 +i/+a 时解锁重试并把属性落到新路径
- Chmod/Chown 改原生且只改自身,递归版 ChmodR/ChownR 按条目解锁重试,不再匹配 stderr 文本
- Remove 去掉装饰性 ctx,RemoveAll 撞 EPERM 才解锁子树重试;解锁逻辑覆盖目录
- compress.go 合并成两个命令构建器,路径过 shell.Quote,先删旧包,tar/7z 容忍退出码 1,7z 解压加 -snld,后缀识别不区分大小写
- UnCompressShell 不再自带 || true,网站还原改走严格解压
- 删除 WriteAppend/Search/Size/ListCompress,DownloadFile 迁到 tools 并接 ctx,LinkCLIBinaries 收进 service
- Write 父目录固定 0755,写失败也恢复 immutable
- 文件管理器修改权限可选递归;网站目录拒绝面板路径及其祖先;geo 库下载加超时

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
2026-09-23 02:17:40 +08:00
耗子andClaude Opus 5 2fc68ed98f fix: 修复 ctx 打通改造引入的回归与遗留缺陷
对上一轮改造做了一次 max-effort 代码审查(9 个角度约 70 条候选),
本次修掉其中确有实际影响的部分。

两个改造引入的回归,均有最小复现实测:

ExecfWithTimeout 从硬超时退化成软超时。旧实现 time.After 到期即 Kill 并
立刻返回,新实现的 cmd.Run() 要等 stdout/stderr 拷贝 goroutine 结束,而
孙子进程持有管道写端时永不返回。实测 1s 超时的命令实际 30.0s 才返回,
pkg/systemctl 的全部包装都继承了这个缺陷。改为设置 WaitDelay 并按进程组
kill,同一用例现在 1.00s 返回,孙子进程不再残留。

systemctl.Status 把 ctx 取消吞成「服务未运行」且不报错。原注释「is-active
在服务未启用时会返回 3」在加 ctx 之前成立,之后不再成立。这一处制造了三类
事故:webserver.ReloadIfRunning 据此静默返回 nil(证书和站点配置写盘后
nginx 从未 reload 却报成功)、告警采集把所有服务判定为 DOWN、改面板端口时
防火墙放行被跳过而后续的保存和重启照常执行,把管理员锁在面板外。

其余修复按性质分三类:

断链位置错误。replaceFirewallRule 只保护了回滚,取消落在「删旧规则之后、
reload 之前」会让端口新旧规则都消失;备份上传的 WithoutCancel 恰好关掉了
s3sdk 里唯一正确的取消清理,且对不看 ctx 的 Local/SFTP 是空操作,改为传
.partial 再 rename;UpdatePanel 的断链罩住了本该可取消的下载与备份。

保护遗漏。FileService.Move 失败时跳过 relock,把防篡改条目永久摘出登记表;
restoreWebsite 的替换阶段被取消会同时毁掉站点和暂存的还原内容;面板每日
备份直接写最终文件名,截断包会被 FixPanel 按 mtime 选中去覆盖运行中的面板;
websiteRepo.Create 失败无回滚,留下面板看不见的活站点。

停机与长连接。taskqueue 在面板停机时把任务标记为 Failed 并跳过清理命令,
与用户手动取消的语义不一致;关停顺序让 HTTP 比调度器多活 30 秒;WS 连接
hijack 后 r.Context() 不随客户端断开取消,长连接靠心跳回收,Exec 路径补上
管道关闭以免每次会话泄漏 goroutine 与僵尸进程。

顺带修掉两个与 ctx 无关的既有缺陷:证书自动续签从不执行用户的部署脚本;
nginx 与 apache 的 reload 失败路径用配置检查的返回值覆盖了原始错误,检查
恰好通过时错误信息变成 <nil>。

判定为误报未改:Copy 不调用 Unlock 所以没有需要恢复的状态;firewalld.Status
只是转调且三层都传播错误;UpdateSystemTime 的 date -s 是原子命令没有半状态;
finishUpdate 已被上游断链覆盖。

已知无法修复:WebDAV 后端不响应 ctx,gowebdav v0.13.0 没有任何接收 ctx 的
API,且其 WriteStream 会探测 io.Seeker,包一层 Reader 会导致整个备份被读进
内存计算 Content-Length,改为给 transport 装分阶段超时。

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-09-15 04:11:02 +08:00
耗子andClaude Opus 5 59f99cc8fc refactor: 把 context 打通到全部 shell 执行路径
原先 pkg/shell 的执行函数不接 context,整条链路上的命令都无法随请求取消,
靠一条文件级 //nolint:noctx 压着。本次自底向上打通:

- pkg/shell 8 个执行函数加 ctx 首参并改用 exec.CommandContext,
  删除与 Execf 重复的 ExecfWithContext
- pkg/{systemctl,tools,ntp,io,firewall,webserver,db,os} 的相关函数加 ctx,
  firewall.Firewall 接口 10 个方法同步改
- internal/{apps,biz,data,job,service} 逐层打通,biz 的 10 个 Repo 接口
  共 37 个方法加 ctx,mock 已重新生成
- types.App.Status 加 ctx:它经 loader 动态分发,contextcheck 看不穿,
  33 个实现里的 context.Background() 是静态分析发现不了的死角

327 个 shell 调用点全部接上真实 ctx,contextcheck 从 364 条降到 0,
darwin 与 linux 双平台 golangci-lint 均为 0 issues。

其中 104 处用 context.WithoutCancel 显式断开取消链,因为这些操作被中途
杀死会留下损坏状态:面板自更新与自杀式重启(靠 sleep 熬过响应返回,绑
请求 ctx 会永远重启不了)、mongodb 改密码时 fork 的 --noauth 临时实例、
pure-pw 之后的 mkdb、s3fs 挂载失败回滚、写配置后的服务重启、以及各处
defer 清理与回滚闭包。

ExecfWithTimeout 现为 min(ctx, timeout),已逐个核对调用点:面板 HTTP
服务器未设 WriteTimeout、中间件链无 Timeout,请求 ctx 只在客户端真断开
时取消,原有超时语义不变。

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-09-15 00:57:36 +08:00
耗子andClaude Opus 5 fe7cce6201 refactor: 对齐 libtnb/chi-skeleton 最新脚手架
- 依赖注入换到 libtnb/wire v0.3.0,各层包导出 Module 并逐类型 Export,
  wire.Struct 改用 Struct[T](),cleanup 签名改为 func() error
- 测试断言换到 libtnb/assert 的 must/check,20 个 testify suite 拆成标准测试函数
- mock 改用 matryer 模板输出到 internal/mocks,wire 走 go.mod tool 指令,
  mockery 用 go run 调用,避免它的依赖树污染 go.mod
- 引入 .golangci.yml 并修完全部告警,darwin 与 linux 双平台 0 issues
- 工作流改用 go-version-file、govulncheck 官方 action,
  wire 校验移入 test.yml,mockery 由自动提交改为 PR 校验

顺带修复:pkg/db 四处漏查 rows.Err()(DatabaseExists 查询出错会被当成库不存在)、
websitestat 负值转 uint64 污染流量统计、pty 终端尺寸超 uint16 截断、
文件权限位超 32 位静默截断、面板与 ACME challenge 服务器缺 ReadHeaderTimeout、
GetDefault 丢失操作人、三处对结构体值恒成立的假断言、两处带空格而失效的 nolint

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-09-14 23:36:21 +08:00
耗子andClaude ce50aa4653 feat: 备份恢复改为后台任务
Co-Authored-By: Claude <noreply@anthropic.com>
2026-07-25 01:45:48 +08:00
耗子andClaude Fable 5 b5bdfdb110 fix(file): 补全单文件格式压缩入口并适配压缩测试
.bz2/.xz/.zst 后缀已被识别为单文件压缩格式,但 Compress 未提供
对应入口导致报 unsupported format,与 .gz 一并收敛为统一分支,
解压侧同步收敛,测试改为表驱动覆盖归档与单文件两类格式

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-18 18:07:05 +08:00
耗子andClaude Fable 5 1450c00ec6 fix(file): 支持 .gz 单文件压缩并补全 zst 解压入口
压缩弹窗此前提供 .gz 选项但后端无对应实现,现后端按单文件 gzip 压缩,
前端多选文件时禁用 .gz 并自动回退 .zip;另补上前端 zst 后缀的解压入口

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-17 00:18:31 +08:00
耗子andClaude Fable 5 c2505688a6 fix(file): 兼容单独压缩的 .xz/.bz2/.zst 文件解压
此前 .xz/.bz2/.zst 后缀一律按 tar 归档解压,导致非 tar 打包的单独压缩文件
(如 gitea-xxx.xz、xxx.sql.bz2)报 This does not look like a tar archive,
现参照 .gz 的处理方式区分 .tar.* 与单独压缩格式

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-17 00:13:07 +08:00
耗子andClaude Opus 4.7 93e013ec56 feat(file): 文件压缩/解压改为后台任务 (close #1675)
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-07-03 00:51:27 +08:00
耗子andClaude Opus 4.7 c2a8200817 fix: 修复 CI lint 与前端类型检查报错
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-06-20 02:14:22 +08:00
耗子 c22d6a430d fix: Chmod/Chown 递归操作前解锁 immutable 文件 2026-06-17 18:24:15 +08:00
renovate[bot] 3e0c1dd574 chore(deps): Update non-major dependencies (#1653) 2026-06-08 17:24:42 +08:00
耗子andClaude Opus 4.7 292f22a1c2 feat: 压缩解压及面板备份支持 tar.zst 格式
Closes #1619

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-25 02:35:10 +08:00
耗子andClaude Opus 4.7 f6f22ecaf6 fix: zip 解压改用 7z 处理中文文件名
unzip 默认按 UTF-8 解析文件名,Windows GBK/CP936 编码的 zip 包会被转义成 #Uxxxx 形式
改用 7z x 替代,自动检测文件名编码

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-08 17:37:02 +08:00
耗子 c0d8642cb5 fix: 优化代码 2026-04-28 06:05:34 +08:00
Catsayer d96d83a5b7 合并拉取请求 #1441
*  refactor(service): 抽取环境 CLI 软链接公共能力并统一 SetCli 实现

* fix: 优化代码
2026-03-01 15:58:29 +08:00
半岛的蒟蒻bddjr e947259b86 fix: go.mod module github.com/acepanel/panel/v3 (#1423) 2026-02-25 18:07:00 +08:00
耗子 6809969b25 feat: 新增IP库保存下载 2026-02-20 03:13:32 +08:00
耗子 e77863d469 fix: run go fix ./... 2026-02-19 22:08:16 +08:00
耗子 2f2f17b1c7 refactor: 重构任务队列 2026-02-17 17:47:25 +08:00
Copilotanddevhaozi 57accdb5cf fix: preserve file ownership when copying via file manager (#1335)
* Initial plan

* fix: use cp -arf to preserve file ownership when copying

Co-authored-by: devhaozi <115467771+devhaozi@users.noreply.github.com>

---------

Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com>
Co-authored-by: devhaozi <115467771+devhaozi@users.noreply.github.com>
2026-02-06 16:50:44 +08:00
2fdb23a568 feat: 支持解压单独的 .gz 格式文件 (#1318)
* Initial plan

* feat: 支持解压 .gz 格式文件(如 .sql.gz)和优化压缩格式选项

Co-authored-by: devhaozi <115467771+devhaozi@users.noreply.github.com>

* fix: 修正压缩格式注释说明

Co-authored-by: devhaozi <115467771+devhaozi@users.noreply.github.com>

* fix: lint

---------

Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com>
Co-authored-by: devhaozi <115467771+devhaozi@users.noreply.github.com>
Co-authored-by: 耗子 <haozi@loli.email>
2026-02-01 17:25:01 +08:00
耗子 13f06322dd fix: 压缩时自动创建目标目录 2026-01-24 01:31:25 +08:00
耗子 edadc9b045 feat: 初步支持环境管理 2026-01-07 01:20:08 +08:00
耗子 5ee35cbd30 refactor: rename module 2025-09-18 23:24:03 +08:00
耗子 6916c02752 feat: 编码URL,解决一些极端问题 2025-09-18 01:49:48 +08:00
耗子 5632a5aa1d feat: 优化文件搜索体验,close #997 2025-09-18 01:29:54 +08:00
耗子 4b98079778 refactor: rename go-rat to libtnb 2025-08-02 03:33:20 +08:00
耗子 5584cc18cb refactor: 重命名项目 2025-07-23 04:50:25 +08:00
耗子 53fdcfb715 feat: 添加翻译 2025-04-12 17:35:22 +08:00
耗子 e6b3858937 fix: lint 2025-04-05 20:10:53 +08:00
耗子 dff0a61182 feat(#528): 证书支持部署脚本 2025-03-18 03:18:39 +08:00
耗子 06d620ac06 fix: lint 2025-02-04 20:40:47 +08:00
耗子 6de5e799ea fix: 文件重命名错误提示文件已存在 2025-01-05 20:33:19 +08:00
耗子 36d7575f0b fix: test 2025-01-05 19:56:58 +08:00
耗子 48a49db67b fix: 解压缩不支持.gz 2025-01-05 19:53:19 +08:00
耗子 8b0e7bcaa9 refactor: 新年快乐 2025-01-01 15:33:47 +08:00
耗子 1dc0042507 feat(文件): 图片支持预览 2024-11-28 20:32:16 +08:00
耗子 4450d2c8d1 fix: test 2024-11-12 12:56:17 +08:00
耗子 b5f7458344 fix: 带 i 属性的文件无法保存 2024-11-12 03:14:53 +08:00
耗子 60b9350625 feat: 优化删除和写入支持自动去除ia属性 2024-11-10 18:25:01 +08:00
耗子 ea3bf37687 fix: 7z list 2024-10-31 18:38:03 +08:00
耗子 79e09f9cb7 chore: debug 2024-10-31 18:32:08 +08:00
耗子 d73c988073 chore: debug 2024-10-31 18:32:01 +08:00
耗子 9641ae7f34 chore: debug 2024-10-31 18:31:56 +08:00
耗子 fd2c89a480 chore: debug 2024-10-31 18:27:01 +08:00
耗子 526f192200 feat(文件): 解压时只设置压缩包内文件的权限 2024-10-31 18:20:54 +08:00