diff --git a/README.md b/README.md index c4f4024..4731c4e 100644 --- a/README.md +++ b/README.md @@ -22,5 +22,6 @@ done in a separate Github Action. - `--ip` - `--ip6` - `--network-alias` +- `--cgroupns` and `--ipc` are currently disabled, as they have have one of two options set a default depending on the Docker daemon version. - `--link-local-ip`: Deprecated and ignored by Docker so there's no reason to support. - `--env-file` and `--label-file` don't exist in `docker inspect` settings because they are merged with `--env` and `--label` diff --git a/main.go b/main.go index cac198f..345f1ba 100644 --- a/main.go +++ b/main.go @@ -5,9 +5,7 @@ import ( "encoding/json" "fmt" "log" - "maps" "os" - "slices" "strings" "time" @@ -30,7 +28,7 @@ func parseFromJSON(cli *client.Client, ct *types.ContainerJSON) ([]string, error // TODO: --platform, --disable-content-trust (untrusted), --pull, --quiet, --detach, --sig-proxy, and --detach-keys are not stored in the container config so we cannot inspect them, how should this be solved? namesplit := strings.Split(ct.Name, "/") - flags := []string{"docker", "run", "--name=" + namesplit[len(namesplit)-1]} + flags := []string{"docker run", "--name=" + namesplit[len(namesplit)-1]} enabledCaps := caps.DefaultCapabilities() @@ -54,7 +52,7 @@ func parseFromJSON(cli *client.Client, ct *types.ContainerJSON) ([]string, error // Volumes optSlice[string]{ct.HostConfig.Binds, nil, "--volume="}, - optSlice[string]{slices.Collect(maps.Keys(ct.Config.Volumes)), slices.Collect(maps.Keys(imgdata.Config.Volumes)), "--volume="}, + // optSlice[string]{slices.Collect(maps.Keys(ct.Config.Volumes)), slices.Collect(maps.Keys(imgdata.Config.Volumes)), "--volume="}, optSlice[string]{ct.HostConfig.VolumesFrom, nil, "--volumes-from="}, opt[string]{ct.HostConfig.VolumeDriver, "", "--volume-driver="}, @@ -108,18 +106,19 @@ func parseFromJSON(cli *client.Client, ct *types.ContainerJSON) ([]string, error opt[opts.MemBytes]{opts.MemBytes(ct.HostConfig.Memory), 0, "--memory="}, opt[opts.MemBytes]{opts.MemBytes(ct.HostConfig.MemoryReservation), 0, "--memory-reservation="}, - opt[opts.MemSwapBytes]{opts.MemSwapBytes(ct.HostConfig.MemorySwap), -1, "--memory-swap="}, + opt[opts.MemSwapBytes]{opts.MemSwapBytes(ct.HostConfig.MemorySwap), 0, "--memory-swap="}, optPtr[int64]{ct.HostConfig.MemorySwappiness, -1, "--memory-swappiness="}, opt[opts.MemBytes]{opts.MemBytes(ct.HostConfig.KernelMemory), 0, "--kernel-memory="}, optPtr[bool]{ct.HostConfig.OomKillDisable, false, "--oom-kill-disable"}, opt[int]{ct.HostConfig.OomScoreAdj, 0, "--oom-score-adj="}, - opt[opts.MemBytes]{opts.MemBytes(ct.HostConfig.ShmSize), 0, "--shm-size="}, + // TODO: Seems to be no way to find the default for this + //opt[opts.MemBytes]{opts.MemBytes(ct.HostConfig.ShmSize), 0, "--shm-size="}, optSlice[string]{ct.HostConfig.DeviceCgroupRules, nil, "--device-cgroup-rule="}, opt[string]{ct.HostConfig.CgroupParent, "", "--cgroup-parent="}, - opt[container.CgroupnsMode]{ct.HostConfig.CgroupnsMode, "", "--cgroupns="}, + //opt[container.CgroupnsMode]{ct.HostConfig.CgroupnsMode, "", "--cgroupns="}, opt[container.UsernsMode]{ct.HostConfig.UsernsMode, "", "--userns="}, opt[container.UTSMode]{ct.HostConfig.UTSMode, "", "--uts="}, optSlice[string]{ct.HostConfig.GroupAdd, nil, "--group-add "}, @@ -142,14 +141,11 @@ func parseFromJSON(cli *client.Client, ct *types.ContainerJSON) ([]string, error optFunc[container.Isolation]{ct.HostConfig.Isolation, handleIsolation}, - opt[container.IpcMode]{ct.HostConfig.IpcMode, "", "--ipc="}, + //opt[container.IpcMode]{ct.HostConfig.IpcMode, "", "--ipc="}, optMap{ct.HostConfig.Annotations, "--annotation "}, ////////////////////////////////////////////////////////////////////////// - - opt[string]{ct.Config.Image, "", ""}, - opt[string]{strings.Join(ct.Config.Cmd, " "), "", ""}, } for _, v := range options { @@ -158,6 +154,12 @@ func parseFromJSON(cli *client.Client, ct *types.ContainerJSON) ([]string, error } } + flags = append(flags, ct.Config.Image) + + if cmd := ct.Config.Cmd; cmd != nil { + flags = append(flags, strings.Join(cmd, " ")) + } + return flags, nil } @@ -209,7 +211,7 @@ func _main(ctx *cli.Context) error { sep := " " if ctx.Bool("pretty") { - sep = "\\\n\t" + sep = " \\\n\t" } fmt.Println(strings.Join(flags, sep)) diff --git a/parse.go b/parse.go index 4321734..83bce89 100644 --- a/parse.go +++ b/parse.go @@ -65,7 +65,7 @@ func (o optSlice[T]) Values() (ret []string) { for _, val := range o.v { // We only want to add capabilities to the disable list if we know they are enabled by default normally contains := slices.Contains(o.def, val) - if contains || (o.name == "--cap-drop=" && !contains) { // TODO: This is dumb, don't hardcode + if !contains || (o.name == "--cap-drop=" && contains) { // TODO: This is dumb, don't hardcode ret = append(ret, o.name+strings.ReplaceAll(fmt.Sprintf("%v", val), "\"", "\\\"")) // TODO } } @@ -168,9 +168,9 @@ func handleHealthcheck(health *container.HealthConfig) (ret []string) { ret = append(ret, "--no-healthcheck") return } - ret = append(ret, "--health-cmd=\""+strings.Join(health.Test[1:], " ")+"\"") // TODO: This is probably not right + ret = append(ret, "--health-cmd="+strconv.Quote(strings.Join(health.Test[1:], " "))) // TODO: This is probably not right } - return nil + return } func handlePorts(ctdata *types.ContainerJSON) (ret []string) { @@ -179,12 +179,8 @@ func handlePorts(ctdata *types.ContainerJSON) (ret []string) { return } - ports := ctdata.NetworkSettings.Ports - // for k, v := range ctdata.HostConfig.PortBindings { - // ports[k] = v - // } + ports := ctdata.HostConfig.PortBindings - // FIXME: Currently no way to determine if a port was given with --expose because Docker assigns in a random port for ctport, bindings := range ports { protocol := "" if ctport.Proto() == "udp" { // TODO: "sctp" is listed as an option, should that be included? @@ -192,17 +188,20 @@ func handlePorts(ctdata *types.ContainerJSON) (ret []string) { } for _, b := range bindings { - host_ip := "" + host := "" if !(b.HostIP == "0.0.0.0" || b.HostIP == "" || b.HostIP == "::") { - host_ip = b.HostIP + ":" + host = b.HostIP + ":" } - host_port := "" - if !(b.HostPort == "0" || b.HostPort == "") { - host_port = b.HostPort + ":" + // If no host port mapping is defined then we know to expose it + if b.HostPort == "" { + ret = append(ret, "--expose "+ctport.Port()) + break + } else if b.HostPort != "0" { + host += b.HostPort + ":" } - ret = append(ret, "-p "+host_ip+host_port+ctport.Port()+protocol) + ret = append(ret, "-p "+host+ctport.Port()+protocol) } }