diff --git a/libpod/container_inspect.go b/libpod/container_inspect.go index 439aa47753..da858e820e 100644 --- a/libpod/container_inspect.go +++ b/libpod/container_inspect.go @@ -5,9 +5,7 @@ package libpod import ( "errors" "fmt" - "strconv" "strings" - "syscall" "github.com/containers/podman/v5/libpod/define" "github.com/containers/podman/v5/libpod/driver" @@ -407,11 +405,7 @@ func (c *Container) generateInspectContainerConfig(spec *spec.Spec) *define.Insp ctrConfig.Annotations[k] = v } } - var signal, err = signal.ParseSysSignalToName(syscall.Signal(c.config.StopSignal)) - if err != nil { - signal = strconv.FormatUint(uint64(c.config.StopSignal), 10) - } - ctrConfig.StopSignal = fmt.Sprintf("SIG%s", signal) + ctrConfig.StopSignal = signal.ToDockerFormat(c.config.StopSignal) // TODO: should JSON deep copy this to ensure internal pointers don't // leak. ctrConfig.Healthcheck = c.config.HealthCheckConfig diff --git a/libpod/define/container_inspect.go b/libpod/define/container_inspect.go index b6144de396..9a67e9b882 100644 --- a/libpod/define/container_inspect.go +++ b/libpod/define/container_inspect.go @@ -1,9 +1,12 @@ package define import ( + "encoding/json" + "fmt" "time" "github.com/containers/image/v5/manifest" + "github.com/containers/podman/v5/pkg/signal" ) type InspectIDMappings struct { @@ -87,6 +90,51 @@ type InspectContainerConfig struct { SdNotifySocket string `json:"sdNotifySocket,omitempty"` } +// UnmarshalJSON allow compatibility with podman V4 API +func (insp *InspectContainerConfig) UnmarshalJSON(data []byte) error { + type Alias InspectContainerConfig + aux := &struct { + Entrypoint interface{} `json:"Entrypoint"` + StopSignal interface{} `json:"StopSignal"` + *Alias + }{ + Alias: (*Alias)(insp), + } + if err := json.Unmarshal(data, &aux); err != nil { + return err + } + + switch entrypoint := aux.Entrypoint.(type) { + case string: + insp.Entrypoint = []string{entrypoint} + case []string: + insp.Entrypoint = entrypoint + case []interface{}: + insp.Entrypoint = []string{} + for _, entry := range entrypoint { + if str, ok := entry.(string); ok { + insp.Entrypoint = append(insp.Entrypoint, str) + } + } + case nil: + insp.Entrypoint = []string{} + default: + return fmt.Errorf("cannot unmarshal Config.Entrypoint of type %T", entrypoint) + } + + switch stopsignal := aux.StopSignal.(type) { + case string: + insp.StopSignal = stopsignal + case float64: + insp.StopSignal = signal.ToDockerFormat(uint(stopsignal)) + case nil: + break + default: + return fmt.Errorf("cannot unmarshal Config.StopSignal of type %T", stopsignal) + } + return nil +} + // InspectRestartPolicy holds information about the container's restart policy. type InspectRestartPolicy struct { // Name contains the container's restart policy. diff --git a/pkg/signal/signal_common.go b/pkg/signal/signal_common.go index a81d0461b5..068f8baffd 100644 --- a/pkg/signal/signal_common.go +++ b/pkg/signal/signal_common.go @@ -71,3 +71,11 @@ func ParseSysSignalToName(s syscall.Signal) (string, error) { } return "", fmt.Errorf("unknown syscall signal: %s", s) } + +func ToDockerFormat(s uint) string { + var signalStr, err = ParseSysSignalToName(syscall.Signal(s)) + if err != nil { + signalStr = strconv.FormatUint(uint64(s), 10) + } + return fmt.Sprintf("SIG%s", signalStr) +}