diff options
author | Matthew Heon <mheon@redhat.com> | 2019-06-17 15:09:24 -0400 |
---|---|---|
committer | Matthew Heon <mheon@redhat.com> | 2019-06-17 15:36:55 -0400 |
commit | 33b71944c072cd08841c05068aa010cfac3cbb4b (patch) | |
tree | a48f2d8820ff62255f71f7ba0397308d7132c173 | |
parent | 54b9c950050a4165cf1c142174a3cdc729d758fc (diff) | |
download | podman-33b71944c072cd08841c05068aa010cfac3cbb4b.tar.gz podman-33b71944c072cd08841c05068aa010cfac3cbb4b.tar.bz2 podman-33b71944c072cd08841c05068aa010cfac3cbb4b.zip |
Move the Config portion of Inspect into libpod
While we're at it, rewrite how we populate it. There were several
potential segfaults in the optional spec.Process block, and a few
fields not being populated correctly versus 'docker inspect'.
Signed-off-by: Matthew Heon <mheon@redhat.com>
-rw-r--r-- | cmd/podman/shared/container_inspect.go | 44 | ||||
-rw-r--r-- | libpod/container_inspect.go | 108 |
2 files changed, 108 insertions, 44 deletions
diff --git a/cmd/podman/shared/container_inspect.go b/cmd/podman/shared/container_inspect.go index 97a1d0238..f4031ae34 100644 --- a/cmd/podman/shared/container_inspect.go +++ b/cmd/podman/shared/container_inspect.go @@ -1,9 +1,6 @@ package shared import ( - "strings" - - "github.com/containers/image/manifest" "github.com/containers/libpod/libpod" cc "github.com/containers/libpod/pkg/spec" "github.com/docker/go-connections/nat" @@ -17,7 +14,6 @@ import ( type InspectContainer struct { *libpod.InspectContainerData HostConfig *InspectContainerHostConfig `json:"HostConfig"` - Config *InspectContainerConfig `json:"Config"` } // InspectContainerHostConfig holds Container configuration that is not specific @@ -82,31 +78,6 @@ type InspectContainerHostConfig struct { Tmpfs []string `json:"Tmpfs"` } -// InspectContainerConfig holds further data about a container, again mostly -// not directly stored in Libpod. This struct is matched to the output of -// `docker inspect`. -type InspectContainerConfig struct { - Hostname string `json:"Hostname"` - DomainName string `json:"Domainname"` //TODO - User specs.User `json:"User"` - AttachStdin bool `json:"AttachStdin"` //TODO - AttachStdout bool `json:"AttachStdout"` //TODO - AttachStderr bool `json:"AttachStderr"` //TODO - Tty bool `json:"Tty"` - OpenStdin bool `json:"OpenStdin"` - StdinOnce bool `json:"StdinOnce"` //TODO - Env []string `json:"Env"` - Cmd []string `json:"Cmd"` - Image string `json:"Image"` - Volumes map[string]struct{} `json:"Volumes"` - WorkingDir string `json:"WorkingDir"` - Entrypoint string `json:"Entrypoint"` - Labels map[string]string `json:"Labels"` - Annotations map[string]string `json:"Annotations"` - StopSignal uint `json:"StopSignal"` - Healthcheck *manifest.Schema2HealthConfig `json:"Healthcheck,omitempty"` -} - // InspectLogConfig holds information about a container's configured log driver // and is presently unused. It is retained for Docker compatability. type InspectLogConfig struct { @@ -181,21 +152,6 @@ func GetCtrInspectInfo(config *libpod.ContainerConfig, ctrInspectData *libpod.In SecurityOpt: createArtifact.SecurityOpts, Tmpfs: createArtifact.Tmpfs, }, - &InspectContainerConfig{ - Hostname: spec.Hostname, - User: spec.Process.User, - Env: spec.Process.Env, - Image: config.RootfsImageName, - WorkingDir: spec.Process.Cwd, - Labels: config.Labels, - Annotations: spec.Annotations, - Tty: spec.Process.Terminal, - OpenStdin: config.Stdin, - StopSignal: config.StopSignal, - Cmd: config.Spec.Process.Args, - Entrypoint: strings.Join(createArtifact.Entrypoint, " "), - Healthcheck: config.HealthCheckConfig, - }, } return data, nil } diff --git a/libpod/container_inspect.go b/libpod/container_inspect.go index 0a62ceb7c..8b3a18e41 100644 --- a/libpod/container_inspect.go +++ b/libpod/container_inspect.go @@ -1,8 +1,10 @@ package libpod import ( + "strings" "time" + "github.com/containers/image/manifest" "github.com/containers/libpod/libpod/driver" "github.com/cri-o/ocicni/pkg/ocicni" spec "github.com/opencontainers/runtime-spec/specs-go" @@ -49,6 +51,53 @@ type InspectContainerData struct { ExitCommand []string `json:"ExitCommand"` Namespace string `json:"Namespace"` IsInfra bool `json:"IsInfra"` + Config *InspectContainerConfig `json:"Config"` +} + +// InspectContainerConfig holds further data about how a container was initially +// configured. +type InspectContainerConfig struct { + // Container hostname + Hostname string `json:"Hostname"` + // Container domain name - unused at present + DomainName string `json:"Domainname"` + // User the container was launched with + User string `json:"User"` + // Unused, at present + AttachStdin bool `json:"AttachStdin"` + // Unused, at present + AttachStdout bool `json:"AttachStdout"` + // Unused, at present + AttachStderr bool `json:"AttachStderr"` + // Whether the container creates a TTY + Tty bool `json:"Tty"` + // Whether the container leaves STDIN open + OpenStdin bool `json:"OpenStdin"` + // Whether STDIN is only left open once. + // Presently not supported by Podman, unused. + StdinOnce bool `json:"StdinOnce"` + // Container environment variables + Env []string `json:"Env"` + // Container command + Cmd []string `json:"Cmd"` + // Container image + Image string `json:"Image"` + // Unused, at present. I've never seen this field populated. + Volumes map[string]struct{} `json:"Volumes"` + // Container working directory + WorkingDir string `json:"WorkingDir"` + // Container entrypoint + Entrypoint string `json:"Entrypoint"` + // On-build arguments - presently unused. More of Buildah's domain. + OnBuild *string `json:"OnBuild"` + // Container labels + Labels map[string]string `json:"Labels"` + // Container annotations + Annotations map[string]string `json:"Annotations"` + // Container stop signal + StopSignal uint `json:"StopSignal"` + // Configured healthcheck for the container + Healthcheck *manifest.Schema2HealthConfig `json:"Healthcheck,omitempty"` } // InspectMount provides a record of a single mount in a container. It contains @@ -284,6 +333,12 @@ func (c *Container) getContainerInspectData(size bool, driverData *driver.Data) // Get information on the container's network namespace (if present) data = c.getContainerNetworkInfo(data) + inspectConfig, err := c.generateInspectContainerConfig(spec) + if err != nil { + return nil, err + } + data.Config = inspectConfig + if size { rootFsSize, err := c.rootFsSize() if err != nil { @@ -401,3 +456,56 @@ func parseMountOptionsForInspect(options []string, mount *InspectMount) { mount.Mode = zZ mount.Options = otherOpts } + +// Generate the InspectContainerConfig struct for the Config field of Inspect. +func (c *Container) generateInspectContainerConfig(spec *spec.Spec) (*InspectContainerConfig, error) { + ctrConfig := new(InspectContainerConfig) + + ctrConfig.Hostname = c.Hostname() + ctrConfig.User = c.config.User + if spec.Process != nil { + ctrConfig.Tty = spec.Process.Terminal + ctrConfig.Env = []string{} + for _, val := range spec.Process.Env { + ctrConfig.Env = append(ctrConfig.Env, val) + } + ctrConfig.WorkingDir = spec.Process.Cwd + } + + ctrConfig.OpenStdin = c.config.Stdin + ctrConfig.Image = c.config.RootfsImageName + + // Leave empty is not explicitly overwritten by user + if len(c.config.Command) != 0 { + ctrConfig.Cmd = []string{} + for _, val := range c.config.Command { + ctrConfig.Cmd = append(ctrConfig.Cmd, val) + } + } + + // Leave empty if not explicitly overwritten by user + if len(c.config.Entrypoint) != 0 { + ctrConfig.Entrypoint = strings.Join(c.config.Entrypoint, " ") + } + + if len(c.config.Labels) != 0 { + ctrConfig.Labels = make(map[string]string) + for k, v := range c.config.Labels { + ctrConfig.Labels[k] = v + } + } + + if len(spec.Annotations) != 0 { + ctrConfig.Annotations = make(map[string]string) + for k, v := range spec.Annotations { + ctrConfig.Annotations[k] = v + } + } + + ctrConfig.StopSignal = c.config.StopSignal + // TODO: should JSON deep copy this to ensure internal pointers don't + // leak. + ctrConfig.Healthcheck = c.config.HealthCheckConfig + + return ctrConfig, nil +} |