Files
odboy f5ae80c1a8 feat: 将更多 Docker 命令改为内置实现,统一按名称/ID 解析目标
- exec/rm/rmi/stop/restart 支持名称、ID 或唯一 ID 前缀,目标不存在或
  前缀有歧义时在调用 docker 前报错;exec 默认 -it 并以 -- 分隔命令
- logs 新增 --since/--grep/--save;df 改为按占用排序的可读排行;
  stats 默认单次快照,无参数时统计全部运行中容器
- 破坏性确认:Command.ConfirmBuiltin 提供将删除对象的清单,
  rm/rmi 无 --yes 时列清单并退出码 2,拒绝 -f,运行中容器提示先 stop
- 抽出 executor/dockertargets.go 统一镜像/容器解析与 docker 调用
2026-11-01 08:01:12 +08:00

53 lines
1.6 KiB
Go

package executor
import (
"context"
"errors"
)
// runDockerStop and runDockerRestart implement `docker stop` / `docker
// restart` over kopsc-resolved containers: a name, ID or unique ID prefix is
// mapped to the container's name before docker runs, so a typo is reported by
// kopsc (pointing at `kopsc docker psall`) instead of by docker.
func runDockerStop(ctx context.Context, req BuiltinRequest) error {
return runContainerLifecycle(ctx, req, "stop", "kopsc docker stop <容器>...")
}
func runDockerRestart(ctx context.Context, req BuiltinRequest) error {
return runContainerLifecycle(ctx, req, "restart", "kopsc docker restart <容器>...")
}
func runContainerLifecycle(ctx context.Context, req BuiltinRequest, subcommand, usage string) error {
targets, passthrough, err := splitDockerTargets(req.Args, lifecycleValueOption)
if err != nil {
return err
}
if len(targets) == 0 {
return errors.New("缺少容器;用法: " + usage)
}
names := make([]string, 0, len(targets))
for _, target := range targets {
ref, err := resolveContainerRef(ctx, target)
if err != nil {
return err
}
names = append(names, ref.Names)
}
args := append([]string{subcommand}, names...)
args = append(args, passthrough...)
return dockerRun(ctx, args, req)
}
// lifecycleValueOption lists stop/restart options that take a separate value,
// keyed the way splitDockerTargets looks them up (short and long spellings).
var lifecycleValueOption = map[string]bool{
"t": true,
"time": true,
"s": true,
"signal": true,
"timeout": true,
"signals": true,
}