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 调用
This commit is contained in:
@@ -27,18 +27,21 @@ func Builtin() *Registry {
|
||||
Variants: runtimeVariants("images"),
|
||||
},
|
||||
{
|
||||
ID: "docker.stats",
|
||||
Group: "docker",
|
||||
Summary: "一次性查看容器 CPU/内存/IO 占用",
|
||||
Action: "只读:等价 docker stats --no-stream,输出一次后退出",
|
||||
Variants: runtimeVariants("stats", "--no-stream"),
|
||||
ID: "docker.stats",
|
||||
Group: "docker",
|
||||
Summary: "一次性查看容器 CPU/内存/IO 占用",
|
||||
Action: "只读:等价 docker stats --no-stream,输出一次后退出;不给容器名时自动统计全部运行中的容器," +
|
||||
"给了名称或 ID 时只统计这些(需正在运行);--format 等选项可透传",
|
||||
Usage: "[容器...]",
|
||||
Variants: runtimeBuiltinVariants("stats"),
|
||||
},
|
||||
{
|
||||
ID: "docker.df",
|
||||
Group: "docker",
|
||||
Summary: "查看镜像/容器/卷/构建缓存的空间占用",
|
||||
Action: "只读:等价 docker system df",
|
||||
Variants: runtimeVariants("system", "df"),
|
||||
ID: "docker.df",
|
||||
Group: "docker",
|
||||
Summary: "磁盘占用排行(镜像/容器/卷/构建缓存)",
|
||||
Action: "只读:在 docker system df 之上按占用大小降序排列,输出「类型 / 项 / 可清理 / 大小 / 可回收」," +
|
||||
"并给出总计与一句可回收空间提示",
|
||||
Variants: runtimeBuiltinVariants("df"),
|
||||
},
|
||||
{
|
||||
ID: "docker.info",
|
||||
@@ -55,13 +58,14 @@ func Builtin() *Registry {
|
||||
Variants: runtimeVariants("version"),
|
||||
},
|
||||
{
|
||||
ID: "docker.logs",
|
||||
Group: "docker",
|
||||
Summary: "查看容器日志",
|
||||
Action: "只读:等价 docker logs <容器>;-f、--tail 等选项可透传",
|
||||
Usage: "<容器>",
|
||||
ID: "docker.logs",
|
||||
Group: "docker",
|
||||
Summary: "查看容器日志(可过滤、可落盘)",
|
||||
Action: "等价 docker logs <容器>,并增加 kopsc 选项:--since 只看某时间段、--grep 只显示匹配行、--save 把显示的日志追加写入文件;" +
|
||||
"--since/--grep/--save 必须写在容器名之前,容器名之后的 -f、--tail 等原样交给 docker",
|
||||
Usage: "<容器> [选项...]",
|
||||
MinArgs: 1,
|
||||
Variants: runtimeVariants("logs"),
|
||||
Variants: runtimeBuiltinVariants("logs"),
|
||||
},
|
||||
{
|
||||
ID: "docker.inspect",
|
||||
@@ -98,49 +102,59 @@ func Builtin() *Registry {
|
||||
Variants: runtimeVariants("start"),
|
||||
},
|
||||
{
|
||||
ID: "docker.stop",
|
||||
Group: "docker",
|
||||
Summary: "停止运行中的容器",
|
||||
Action: "向容器发送 SIGTERM,超时后由运行时强制结束",
|
||||
Usage: "<容器>",
|
||||
ID: "docker.stop",
|
||||
Group: "docker",
|
||||
Summary: "停止运行中的容器(按名称或 ID)",
|
||||
Action: "等价 docker stop:容器按名称、ID 或唯一 ID 前缀解析,一次可停多个;" +
|
||||
"先发送 SIGTERM,超时后由 docker 强制结束。-t/--time、-s/--signal 可透传",
|
||||
Usage: "<容器>...",
|
||||
MinArgs: 1,
|
||||
Variants: runtimeVariants("stop"),
|
||||
Variants: runtimeBuiltinVariants("stop"),
|
||||
},
|
||||
{
|
||||
ID: "docker.restart",
|
||||
Group: "docker",
|
||||
Summary: "重启容器",
|
||||
Action: "停止并重新启动一个或多个容器",
|
||||
Usage: "<容器>",
|
||||
ID: "docker.restart",
|
||||
Group: "docker",
|
||||
Summary: "重启容器(按名称或 ID)",
|
||||
Action: "等价 docker restart:容器按名称、ID 或唯一 ID 前缀解析,一次可重启多个;" +
|
||||
"-t/--time、-s/--signal 可透传",
|
||||
Usage: "<容器>...",
|
||||
MinArgs: 1,
|
||||
Variants: runtimeVariants("restart"),
|
||||
Variants: runtimeBuiltinVariants("restart"),
|
||||
},
|
||||
{
|
||||
ID: "docker.rm",
|
||||
Group: "docker",
|
||||
Summary: "删除已停止的容器",
|
||||
Action: "删除指定容器;运行中的容器需要先停止(不会自动加 -f)",
|
||||
Usage: "<容器>",
|
||||
MinArgs: 1,
|
||||
Variants: runtimeVariants("rm"),
|
||||
ID: "docker.rm",
|
||||
Group: "docker",
|
||||
Summary: "删除容器(按名称或 ID)",
|
||||
Action: "等价 docker rm:容器按名称、ID 或唯一 ID 前缀解析,一次可删多个;" +
|
||||
"运行中的容器不会被强制删除,需先 kopsc docker stop。不再接受 -f,需要强删请用 --yes 确认",
|
||||
Usage: "<容器>...",
|
||||
MinArgs: 1,
|
||||
RequiresYes: true,
|
||||
ConfirmBuiltin: "docker.rm.preview",
|
||||
Variants: runtimeBuiltinVariants("rm"),
|
||||
},
|
||||
{
|
||||
ID: "docker.rmi",
|
||||
Group: "docker",
|
||||
Summary: "删除本地镜像",
|
||||
Action: "删除指定镜像;被容器引用的镜像会被运行时拒绝删除",
|
||||
Usage: "<镜像>",
|
||||
MinArgs: 1,
|
||||
Variants: runtimeVariants("rmi"),
|
||||
ID: "docker.rmi",
|
||||
Group: "docker",
|
||||
Summary: "删除本地镜像(按名称或 ID)",
|
||||
Action: "等价 docker rmi:镜像按名称、ID、sha256:ID 或唯一 ID 前缀解析,一次可删多个;" +
|
||||
"未打标签的悬空镜像按 ID 删除。不再接受 -f,需要强删请用 --yes 确认",
|
||||
Usage: "<镜像名|镜像ID>...",
|
||||
MinArgs: 1,
|
||||
RequiresYes: true,
|
||||
ConfirmBuiltin: "docker.rmi.preview",
|
||||
Variants: runtimeBuiltinVariants("rmi"),
|
||||
},
|
||||
{
|
||||
ID: "docker.exec",
|
||||
Group: "docker",
|
||||
Summary: "在运行中的容器内执行命令",
|
||||
Action: "等价 docker exec <容器> <命令...>;交互场景可透传 -it",
|
||||
ID: "docker.exec",
|
||||
Group: "docker",
|
||||
Summary: "在运行中的容器内执行命令(默认交互)",
|
||||
Action: "等价 docker exec -it <容器> -- <命令...>:默认就是交互模式,无需再写 -it(显式传 -i/-t/-it 会报错);" +
|
||||
"容器名之后的参数一律作为在容器内执行的命令,其中的 -i、-p 等不会被当成 docker 选项;" +
|
||||
"容器名之前的选项(如 -u、-w、-e)原样透传给 docker",
|
||||
Usage: "<容器> <命令...>",
|
||||
MinArgs: 1,
|
||||
Variants: runtimeVariants("exec"),
|
||||
Variants: runtimeBuiltinVariants("exec"),
|
||||
},
|
||||
{
|
||||
ID: "docker.pull",
|
||||
|
||||
@@ -49,6 +49,11 @@ type Command struct {
|
||||
// RequiresYes marks destructive commands: without an explicit --yes they
|
||||
// print what they would do and exit non-zero instead of running.
|
||||
RequiresYes bool
|
||||
// ConfirmBuiltin names a builtin that lists exactly what the command would
|
||||
// touch (the containers or images about to be deleted). It runs before the
|
||||
// confirmation prompt and for --dry-run; its output is shown to the
|
||||
// caller. Empty means "no preview available".
|
||||
ConfirmBuiltin string
|
||||
// Namespaced marks Kubernetes-aware commands where -n means --namespace
|
||||
// (kubectl style) instead of the global --dry-run shorthand.
|
||||
Namespaced bool
|
||||
|
||||
@@ -213,6 +213,9 @@ func TestDockerCommandsWellFormed(t *testing.T) {
|
||||
destructive := map[string]bool{
|
||||
"docker.clearall": true,
|
||||
"docker.prunevolumes": true,
|
||||
// rm/rmi now list their targets and require an explicit --yes.
|
||||
"docker.rm": true,
|
||||
"docker.rmi": true,
|
||||
}
|
||||
needsArgs := map[string]int{
|
||||
"docker.logs": 1,
|
||||
@@ -231,8 +234,16 @@ func TestDockerCommandsWellFormed(t *testing.T) {
|
||||
}
|
||||
// Built from kopsc's own implementation rather than a fixed argv.
|
||||
builtin := map[string]string{
|
||||
"docker.save": "docker.save",
|
||||
"docker.load": "docker.load",
|
||||
"docker.df": "docker.df",
|
||||
"docker.exec": "docker.exec",
|
||||
"docker.logs": "docker.logs",
|
||||
"docker.stats": "docker.stats",
|
||||
"docker.load": "docker.load",
|
||||
"docker.restart": "docker.restart",
|
||||
"docker.rm": "docker.rm",
|
||||
"docker.rmi": "docker.rmi",
|
||||
"docker.save": "docker.save",
|
||||
"docker.stop": "docker.stop",
|
||||
}
|
||||
|
||||
for i := range reg.Commands {
|
||||
|
||||
Reference in New Issue
Block a user