diff options
25 files changed, 262 insertions, 143 deletions
diff --git a/cmd/podman/common/specgen.go b/cmd/podman/common/specgen.go index f17077484..8a265cedf 100644 --- a/cmd/podman/common/specgen.go +++ b/cmd/podman/common/specgen.go @@ -367,9 +367,10 @@ func FillOutSpecGen(s *specgen.SpecGenerator, c *ContainerCLIOpts, args []string s.Annotations = annotations s.WorkDir = c.Workdir - entrypoint := []string{} userCommand := []string{} + var command []string if c.Entrypoint != nil { + entrypoint := []string{} if ep := *c.Entrypoint; len(ep) > 0 { // Check if entrypoint specified is json if err := json.Unmarshal([]byte(*c.Entrypoint), &entrypoint); err != nil { @@ -377,17 +378,14 @@ func FillOutSpecGen(s *specgen.SpecGenerator, c *ContainerCLIOpts, args []string } } s.Entrypoint = entrypoint + // Build the command + // If we have an entry point, it goes first + command = entrypoint } - var command []string // Include the command used to create the container. s.ContainerCreateCommand = os.Args - // Build the command - // If we have an entry point, it goes first - if c.Entrypoint != nil { - command = entrypoint - } if len(inputCommand) > 0 { // User command overrides data CMD command = append(command, inputCommand...) diff --git a/cmd/podman/containers/start.go b/cmd/podman/containers/start.go index 941588137..21f22b986 100644 --- a/cmd/podman/containers/start.go +++ b/cmd/podman/containers/start.go @@ -82,6 +82,7 @@ func start(cmd *cobra.Command, args []string) error { if cmd.Flag("sig-proxy").Changed { sigProxy = startOptions.SigProxy } + startOptions.SigProxy = sigProxy if sigProxy && !startOptions.Attach { return errors.Wrapf(define.ErrInvalidArg, "you cannot use sig-proxy without --attach") @@ -15,7 +15,7 @@ require ( github.com/containers/conmon v2.0.18+incompatible github.com/containers/image/v5 v5.5.1 github.com/containers/psgo v1.5.1 - github.com/containers/storage v1.21.0 + github.com/containers/storage v1.21.1 github.com/coreos/go-systemd/v22 v22.1.0 github.com/cri-o/ocicni v0.2.0 github.com/cyphar/filepath-securejoin v0.2.2 @@ -86,8 +86,8 @@ github.com/containers/psgo v1.5.1 h1:MQNb7FLbXqBdqz6u4lI2QWizVz4RSTzs1+Nk9XT1iVA github.com/containers/psgo v1.5.1/go.mod h1:2ubh0SsreMZjSXW1Hif58JrEcFudQyIy9EzPUWfawVU= github.com/containers/storage v1.20.2 h1:tw/uKRPDnmVrluIzer3dawTFG/bTJLP8IEUyHFhltYk= github.com/containers/storage v1.20.2/go.mod h1:oOB9Ie8OVPojvoaKWEGSEtHbXUAs+tSyr7RO7ZGteMc= -github.com/containers/storage v1.21.0 h1:9VpsAmqwA9P+xQZc2sWZ3sj5NQojvg47P6orW34nYFU= -github.com/containers/storage v1.21.0/go.mod h1:I1EIAA7B4OwWRSA0b4yq2AW1wjvvfcY0zLWQuwTa4zw= +github.com/containers/storage v1.21.1 h1:FGA2c7+0Bn8ndrlrj+HHmKeVjFD3yVhvYa0gijsrg1M= +github.com/containers/storage v1.21.1/go.mod h1:I1EIAA7B4OwWRSA0b4yq2AW1wjvvfcY0zLWQuwTa4zw= github.com/coreos/bbolt v1.3.2/go.mod h1:iRUV2dpdMOn7Bo10OQBFzIJO9kkE559Wcmn+qkEiiKk= github.com/coreos/etcd v3.3.10+incompatible/go.mod h1:uF7uidLiAD3TWHmW31ZFd/JWoc32PjwdhPthX9715RE= github.com/coreos/go-iptables v0.4.5 h1:DpHb9vJrZQEFMcVLFKAAGMUVX0XoRC0ptCthinRYm38= diff --git a/libpod/container_inspect.go b/libpod/container_inspect.go index 94d5dc93b..680776dba 100644 --- a/libpod/container_inspect.go +++ b/libpod/container_inspect.go @@ -289,6 +289,7 @@ func (c *Container) generateInspectContainerConfig(spec *spec.Spec) *define.Insp ctrConfig.OpenStdin = c.config.Stdin ctrConfig.Image = c.config.RootfsImageName + ctrConfig.SystemdMode = c.config.Systemd // Leave empty is not explicitly overwritten by user if len(c.config.Command) != 0 { @@ -612,22 +613,11 @@ func (c *Container) generateInspectContainerHostConfig(ctrSpec *spec.Spec, named // Port bindings. // Only populate if we're using CNI to configure the network. - portBindings := make(map[string][]define.InspectHostPort) if c.config.CreateNetNS { - for _, port := range c.config.PortMappings { - key := fmt.Sprintf("%d/%s", port.ContainerPort, port.Protocol) - hostPorts := portBindings[key] - if hostPorts == nil { - hostPorts = []define.InspectHostPort{} - } - hostPorts = append(hostPorts, define.InspectHostPort{ - HostIP: port.HostIP, - HostPort: fmt.Sprintf("%d", port.HostPort), - }) - portBindings[key] = hostPorts - } + hostConfig.PortBindings = makeInspectPortBindings(c.config.PortMappings) + } else { + hostConfig.PortBindings = make(map[string][]define.InspectHostPort) } - hostConfig.PortBindings = portBindings // Cap add and cap drop. // We need a default set of capabilities to compare against. diff --git a/libpod/define/container_inspect.go b/libpod/define/container_inspect.go index 614882467..fbd9da3e7 100644 --- a/libpod/define/container_inspect.go +++ b/libpod/define/container_inspect.go @@ -57,6 +57,10 @@ type InspectContainerConfig struct { // Timezone is the timezone inside the container. // Local means it has the same timezone as the host machine Timezone string `json:"Timezone,omitempty"` + // SystemdMode is whether the container is running in systemd mode. In + // systemd mode, the container configuration is customized to optimize + // running systemd in the container. + SystemdMode bool `json:"SystemdMode,omitempty"` } // InspectRestartPolicy holds information about the container's restart policy. @@ -631,3 +635,56 @@ type InspectContainerData struct { Config *InspectContainerConfig `json:"Config"` HostConfig *InspectContainerHostConfig `json:"HostConfig"` } + +// InspectExecSession contains information about a given exec session. +type InspectExecSession struct { + // CanRemove is legacy and used purely for compatibility reasons. + // Will always be set to true, unless the exec session is running. + CanRemove bool `json:"CanRemove"` + // ContainerID is the ID of the container this exec session is attached + // to. + ContainerID string `json:"ContainerID"` + // DetachKeys are the detach keys used by the exec session. + // If set to "" the default keys are being used. + // Will show "<none>" if no detach keys are set. + DetachKeys string `json:"DetachKeys"` + // ExitCode is the exit code of the exec session. Will be set to 0 if + // the exec session has not yet exited. + ExitCode int `json:"ExitCode"` + // ID is the ID of the exec session. + ID string `json:"ID"` + // OpenStderr is whether the container's STDERR stream will be attached. + // Always set to true if the exec session created a TTY. + OpenStderr bool `json:"OpenStderr"` + // OpenStdin is whether the container's STDIN stream will be attached + // to. + OpenStdin bool `json:"OpenStdin"` + // OpenStdout is whether the container's STDOUT stream will be attached. + // Always set to true if the exec session created a TTY. + OpenStdout bool `json:"OpenStdout"` + // Running is whether the exec session is running. + Running bool `json:"Running"` + // Pid is the PID of the exec session's process. + // Will be set to 0 if the exec session is not running. + Pid int `json:"Pid"` + // ProcessConfig contains information about the exec session's process. + ProcessConfig *InspectExecProcess `json:"ProcessConfig"` +} + +// InspectExecProcess contains information about the process in a given exec +// session. +type InspectExecProcess struct { + // Arguments are the arguments to the entrypoint command of the exec + // session. + Arguments []string `json:"arguments"` + // Entrypoint is the entrypoint for the exec session (the command that + // will be executed in the container). + Entrypoint string `json:"entrypoint"` + // Privileged is whether the exec session will be started with elevated + // privileges. + Privileged bool `json:"privileged"` + // Tty is whether the exec session created a terminal. + Tty bool `json:"tty"` + // User is the user the exec session was started as. + User string `json:"user"` +} diff --git a/libpod/define/ctr_inspect.go b/libpod/define/ctr_inspect.go deleted file mode 100644 index b7cd13f82..000000000 --- a/libpod/define/ctr_inspect.go +++ /dev/null @@ -1,54 +0,0 @@ -package define - -// InspectExecSession contains information about a given exec session. -type InspectExecSession struct { - // CanRemove is legacy and used purely for compatibility reasons. - // Will always be set to true, unless the exec session is running. - CanRemove bool `json:"CanRemove"` - // ContainerID is the ID of the container this exec session is attached - // to. - ContainerID string `json:"ContainerID"` - // DetachKeys are the detach keys used by the exec session. - // If set to "" the default keys are being used. - // Will show "<none>" if no detach keys are set. - DetachKeys string `json:"DetachKeys"` - // ExitCode is the exit code of the exec session. Will be set to 0 if - // the exec session has not yet exited. - ExitCode int `json:"ExitCode"` - // ID is the ID of the exec session. - ID string `json:"ID"` - // OpenStderr is whether the container's STDERR stream will be attached. - // Always set to true if the exec session created a TTY. - OpenStderr bool `json:"OpenStderr"` - // OpenStdin is whether the container's STDIN stream will be attached - // to. - OpenStdin bool `json:"OpenStdin"` - // OpenStdout is whether the container's STDOUT stream will be attached. - // Always set to true if the exec session created a TTY. - OpenStdout bool `json:"OpenStdout"` - // Running is whether the exec session is running. - Running bool `json:"Running"` - // Pid is the PID of the exec session's process. - // Will be set to 0 if the exec session is not running. - Pid int `json:"Pid"` - // ProcessConfig contains information about the exec session's process. - ProcessConfig *InspectExecProcess `json:"ProcessConfig"` -} - -// InspectExecProcess contains information about the process in a given exec -// session. -type InspectExecProcess struct { - // Arguments are the arguments to the entrypoint command of the exec - // session. - Arguments []string `json:"arguments"` - // Entrypoint is the entrypoint for the exec session (the command that - // will be executed in the container). - Entrypoint string `json:"entrypoint"` - // Privileged is whether the exec session will be started with elevated - // privileges. - Privileged bool `json:"privileged"` - // Tty is whether the exec session created a terminal. - Tty bool `json:"tty"` - // User is the user the exec session was started as. - User string `json:"user"` -} diff --git a/libpod/define/pod_inspect.go b/libpod/define/pod_inspect.go index 7f06e16fc..634cbb728 100644 --- a/libpod/define/pod_inspect.go +++ b/libpod/define/pod_inspect.go @@ -3,8 +3,6 @@ package define import ( "net" "time" - - "github.com/cri-o/ocicni/pkg/ocicni" ) // InspectPodData contains detailed information on a pod's configuration and @@ -60,7 +58,7 @@ type InspectPodData struct { type InspectPodInfraConfig struct { // PortBindings are ports that will be forwarded to the infra container // and then shared with the pod. - PortBindings []ocicni.PortMapping + PortBindings map[string][]InspectHostPort // HostNetwork is whether the infra container (and thus the whole pod) // will use the host's network and not create a network namespace. HostNetwork bool @@ -89,6 +87,8 @@ type InspectPodInfraConfig struct { // HostAdd adds a number of hosts to the infra container's resolv.conf // which will be shared with the rest of the pod. HostAdd []string + // Networks is a list of CNI networks te pod will join. + Networks []string } // InspectPodContainerInfo contains information on a container in a pod. diff --git a/libpod/networking_linux.go b/libpod/networking_linux.go index 5a8faa7a4..1e79e8732 100644 --- a/libpod/networking_linux.go +++ b/libpod/networking_linux.go @@ -587,21 +587,7 @@ func getContainerNetIO(ctr *Container) (*netlink.LinkStatistics, error) { // network. func (c *Container) getContainerNetworkInfo() (*define.InspectNetworkSettings, error) { settings := new(define.InspectNetworkSettings) - settings.Ports = make(map[string][]define.InspectHostPort) - if c.config.PortMappings != nil { - for _, port := range c.config.PortMappings { - key := fmt.Sprintf("%d/%s", port.ContainerPort, port.Protocol) - mapping := settings.Ports[key] - if mapping == nil { - mapping = []define.InspectHostPort{} - } - mapping = append(mapping, define.InspectHostPort{ - HostIP: port.HostIP, - HostPort: fmt.Sprintf("%d", port.HostPort), - }) - settings.Ports[key] = mapping - } - } + settings.Ports = makeInspectPortBindings(c.config.PortMappings) // We can't do more if the network is down. if c.state.NetNS == nil { diff --git a/libpod/pod_api.go b/libpod/pod_api.go index a02b171e1..f2ef81bec 100644 --- a/libpod/pod_api.go +++ b/libpod/pod_api.go @@ -481,6 +481,41 @@ func (p *Pod) Inspect() (*define.InspectPodData, error) { } } + // Infra config contains detailed information on the pod's infra + // container. + var infraConfig *define.InspectPodInfraConfig + if p.config.InfraContainer != nil && p.config.InfraContainer.HasInfraContainer { + infraConfig = new(define.InspectPodInfraConfig) + infraConfig.HostNetwork = p.config.InfraContainer.HostNetwork + infraConfig.StaticIP = p.config.InfraContainer.StaticIP + infraConfig.StaticMAC = p.config.InfraContainer.StaticMAC + infraConfig.NoManageResolvConf = p.config.InfraContainer.UseImageResolvConf + infraConfig.NoManageHosts = p.config.InfraContainer.UseImageHosts + + if len(p.config.InfraContainer.DNSServer) > 0 { + infraConfig.DNSServer = make([]string, 0, len(p.config.InfraContainer.DNSServer)) + infraConfig.DNSServer = append(infraConfig.DNSServer, p.config.InfraContainer.DNSServer...) + } + if len(p.config.InfraContainer.DNSSearch) > 0 { + infraConfig.DNSSearch = make([]string, 0, len(p.config.InfraContainer.DNSSearch)) + infraConfig.DNSSearch = append(infraConfig.DNSSearch, p.config.InfraContainer.DNSSearch...) + } + if len(p.config.InfraContainer.DNSOption) > 0 { + infraConfig.DNSOption = make([]string, 0, len(p.config.InfraContainer.DNSOption)) + infraConfig.DNSOption = append(infraConfig.DNSOption, p.config.InfraContainer.DNSOption...) + } + if len(p.config.InfraContainer.HostAdd) > 0 { + infraConfig.HostAdd = make([]string, 0, len(p.config.InfraContainer.HostAdd)) + infraConfig.HostAdd = append(infraConfig.HostAdd, p.config.InfraContainer.HostAdd...) + } + if len(p.config.InfraContainer.Networks) > 0 { + infraConfig.Networks = make([]string, 0, len(p.config.InfraContainer.Networks)) + infraConfig.Networks = append(infraConfig.Networks, p.config.InfraContainer.Networks...) + } + + infraConfig.PortBindings = makeInspectPortBindings(p.config.InfraContainer.PortBindings) + } + inspectData := define.InspectPodData{ ID: p.ID(), Name: p.Name(), @@ -490,12 +525,12 @@ func (p *Pod) Inspect() (*define.InspectPodData, error) { State: podState, Hostname: p.config.Hostname, Labels: p.Labels(), - CreateCgroup: false, + CreateCgroup: p.config.UsePodCgroup, CgroupParent: p.CgroupParent(), CgroupPath: p.state.CgroupPath, - CreateInfra: false, + CreateInfra: infraConfig != nil, InfraContainerID: p.state.InfraContainerID, - InfraConfig: nil, + InfraConfig: infraConfig, SharedNamespaces: sharesNS, NumContainers: uint(len(containers)), Containers: ctrs, diff --git a/libpod/util.go b/libpod/util.go index 7504295f0..8c2d946ba 100644 --- a/libpod/util.go +++ b/libpod/util.go @@ -15,6 +15,7 @@ import ( "github.com/containers/common/pkg/config" "github.com/containers/libpod/v2/libpod/define" "github.com/containers/libpod/v2/utils" + "github.com/cri-o/ocicni/pkg/ocicni" "github.com/fsnotify/fsnotify" spec "github.com/opencontainers/runtime-spec/specs-go" "github.com/pkg/errors" @@ -254,3 +255,21 @@ func makeHTTPAttachHeader(stream byte, length uint32) []byte { binary.BigEndian.PutUint32(header[4:], length) return header } + +// Convert OCICNI port bindings into Inspect-formatted port bindings. +func makeInspectPortBindings(bindings []ocicni.PortMapping) map[string][]define.InspectHostPort { + portBindings := make(map[string][]define.InspectHostPort) + for _, port := range bindings { + key := fmt.Sprintf("%d/%s", port.ContainerPort, port.Protocol) + hostPorts := portBindings[key] + if hostPorts == nil { + hostPorts = []define.InspectHostPort{} + } + hostPorts = append(hostPorts, define.InspectHostPort{ + HostIP: port.HostIP, + HostPort: fmt.Sprintf("%d", port.HostPort), + }) + portBindings[key] = hostPorts + } + return portBindings +} diff --git a/pkg/api/handlers/compat/containers_create.go b/pkg/api/handlers/compat/containers_create.go index 031e30b7e..cbee8a8b6 100644 --- a/pkg/api/handlers/compat/containers_create.go +++ b/pkg/api/handlers/compat/containers_create.go @@ -81,7 +81,7 @@ func makeCreateConfig(ctx context.Context, containerConfig *config.Config, input workDir = input.WorkingDir } - if len(input.Entrypoint) == 0 { + if input.Entrypoint == nil { entrypointSlice, err := newImage.Entrypoint(ctx) if err != nil { return createconfig.CreateConfig{}, err diff --git a/pkg/specgen/generate/config_linux.go b/pkg/specgen/generate/config_linux.go index b2d79f01b..9b6bd2827 100644 --- a/pkg/specgen/generate/config_linux.go +++ b/pkg/specgen/generate/config_linux.go @@ -150,6 +150,7 @@ func BlockAccessToKernelFilesystems(privileged, pidModeIsHost bool, g *generate. "/proc/scsi", "/sys/firmware", "/sys/fs/selinux", + "/sys/dev", } { g.AddLinuxMaskedPaths(mp) } diff --git a/pkg/specgen/generate/container_create.go b/pkg/specgen/generate/container_create.go index 1bcd33672..c1ceac69e 100644 --- a/pkg/specgen/generate/container_create.go +++ b/pkg/specgen/generate/container_create.go @@ -106,11 +106,12 @@ func MakeContainer(ctx context.Context, rt *libpod.Runtime, s *specgen.SpecGener return nil, err } - if s.PreserveFDs > 0 { - options = append(options, libpod.WithPreserveFDs(s.PreserveFDs)) + command, err := makeCommand(ctx, s, newImage, rtc) + if err != nil { + return nil, err } - opts, err := createContainerOptions(ctx, rt, s, pod, finalVolumes, newImage) + opts, err := createContainerOptions(ctx, rt, s, pod, finalVolumes, newImage, command) if err != nil { return nil, err } @@ -122,17 +123,21 @@ func MakeContainer(ctx context.Context, rt *libpod.Runtime, s *specgen.SpecGener } options = append(options, libpod.WithExitCommand(exitCommandArgs)) - runtimeSpec, err := SpecGenToOCI(ctx, s, rt, rtc, newImage, finalMounts, pod) + runtimeSpec, err := SpecGenToOCI(ctx, s, rt, rtc, newImage, finalMounts, pod, command) if err != nil { return nil, err } return rt.NewContainer(ctx, runtimeSpec, options...) } -func createContainerOptions(ctx context.Context, rt *libpod.Runtime, s *specgen.SpecGenerator, pod *libpod.Pod, volumes []*specgen.NamedVolume, img *image.Image) ([]libpod.CtrCreateOption, error) { +func createContainerOptions(ctx context.Context, rt *libpod.Runtime, s *specgen.SpecGenerator, pod *libpod.Pod, volumes []*specgen.NamedVolume, img *image.Image, command []string) ([]libpod.CtrCreateOption, error) { var options []libpod.CtrCreateOption var err error + if s.PreserveFDs > 0 { + options = append(options, libpod.WithPreserveFDs(s.PreserveFDs)) + } + if s.Stdin { options = append(options, libpod.WithStdin()) } @@ -148,7 +153,6 @@ func createContainerOptions(ctx context.Context, rt *libpod.Runtime, s *specgen. case "false": break case "", "true": - command := s.Command if len(command) == 0 { command, err = img.Cmd(ctx) if err != nil { diff --git a/pkg/specgen/generate/oci.go b/pkg/specgen/generate/oci.go index 0a485e7cd..140dc5092 100644 --- a/pkg/specgen/generate/oci.go +++ b/pkg/specgen/generate/oci.go @@ -87,7 +87,7 @@ func makeCommand(ctx context.Context, s *specgen.SpecGenerator, img *image.Image finalCommand := []string{} entrypoint := s.Entrypoint - if len(entrypoint) == 0 && img != nil { + if entrypoint == nil && img != nil { newEntry, err := img.Entrypoint(ctx) if err != nil { return nil, err @@ -126,7 +126,7 @@ func makeCommand(ctx context.Context, s *specgen.SpecGenerator, img *image.Image return finalCommand, nil } -func SpecGenToOCI(ctx context.Context, s *specgen.SpecGenerator, rt *libpod.Runtime, rtc *config.Config, newImage *image.Image, mounts []spec.Mount, pod *libpod.Pod) (*spec.Spec, error) { +func SpecGenToOCI(ctx context.Context, s *specgen.SpecGenerator, rt *libpod.Runtime, rtc *config.Config, newImage *image.Image, mounts []spec.Mount, pod *libpod.Pod, finalCmd []string) (*spec.Spec, error) { var ( inUserNS bool ) @@ -252,10 +252,6 @@ func SpecGenToOCI(ctx context.Context, s *specgen.SpecGenerator, rt *libpod.Runt } g.SetProcessCwd(s.WorkDir) - finalCmd, err := makeCommand(ctx, s, newImage, rtc) - if err != nil { - return nil, err - } g.SetProcessArgs(finalCmd) g.SetProcessTerminal(s.Terminal) diff --git a/pkg/util/utils.go b/pkg/util/utils.go index 47d3e231d..8a78e3e3c 100644 --- a/pkg/util/utils.go +++ b/pkg/util/utils.go @@ -555,7 +555,7 @@ func ValidatePullType(pullType string) (PullType, error) { switch pullType { case "always": return PullImageAlways, nil - case "missing": + case "missing", "IfNotPresent": return PullImageMissing, nil case "never": return PullImageNever, nil diff --git a/test/apiv2/20-containers.at b/test/apiv2/20-containers.at index 9a1db5154..4bb00398e 100644 --- a/test/apiv2/20-containers.at +++ b/test/apiv2/20-containers.at @@ -51,17 +51,19 @@ cid=$(jq -r '.[0].Id' <<<"$output") t DELETE libpod/containers/$cid 204 -# Ensure that API does not occur: Create Container creates an invalid and the container fails to start -# https://github.com/containers/libpod/issues/6799 -CNAME=testArgs -t POST libpod/containers/create?name=${CNAME} Image=${IMAGE} 201 \ +# Issue #6799: it should be possible to start a container, even w/o args. +t POST libpod/containers/create?name=test_noargs Image=${IMAGE} 201 \ .Id~[0-9a-f]\\{64\\} -t GET libpod/containers/json?limit=1 200 \ - length=1 \ - .[0].Id~[0-9a-f]\\{64\\} -cid=$(jq -r '.[0].Id' <<<"$output") -# This step should start the container properly -t POST libpod/containers/${cid}/start '' 204 +cid=$(jq -r '.Id' <<<"$output") +# Prior to the fix in #6835, this would fail 500 "args must not be empty" +t POST libpod/containers/${cid}/start '' 204 +# Container should exit almost immediately. Wait for it, confirm successful run +t POST libpod/containers/${cid}/wait '' 200 '0' +t GET libpod/containers/${cid}/json 200 \ + .Id=$cid \ + .State.Status~\\\(exited\\\|stopped\\\) \ + .State.Running=false \ + .State.ExitCode=0 t DELETE libpod/containers/$cid 204 CNAME=myfoo @@ -75,7 +77,8 @@ t POST "libpod/commit?container=nonesuch" '' 404 # Comment can only be used with docker format, not OCI cparam="repo=newrepo&comment=foo&author=bob" -t POST "libpod/commit?container=$CNAME&$cparam" '' 500 +t POST "libpod/commit?container=$CNAME&$cparam" '' 500 \ + .cause="messages are only compatible with the docker image format (-f docker)" # Commit a new image from the container t POST "libpod/commit?container=$CNAME" '' 200 \ diff --git a/test/e2e/pod_inspect_test.go b/test/e2e/pod_inspect_test.go index 5e3634435..16bf1c4c9 100644 --- a/test/e2e/pod_inspect_test.go +++ b/test/e2e/pod_inspect_test.go @@ -1,8 +1,11 @@ package integration import ( + "encoding/json" "os" + "github.com/containers/libpod/v2/libpod/define" + . "github.com/containers/libpod/v2/test/utils" . "github.com/onsi/ginkgo" . "github.com/onsi/gomega" @@ -79,4 +82,22 @@ var _ = Describe("Podman pod inspect", func() { index := len(inspectCreateCommand) - len(createCommand) Expect(inspectCreateCommand[index:]).To(Equal(createCommand)) }) + + It("podman pod inspect outputs port bindings", func() { + podName := "testPod" + create := podmanTest.Podman([]string{"pod", "create", "--name", podName, "-p", "8080:80"}) + create.WaitWithDefaultTimeout() + Expect(create.ExitCode()).To(Equal(0)) + + inspectOut := podmanTest.Podman([]string{"pod", "inspect", podName}) + inspectOut.WaitWithDefaultTimeout() + Expect(inspectOut.ExitCode()).To(Equal(0)) + + inspectJSON := new(define.InspectPodData) + err := json.Unmarshal(inspectOut.Out.Contents(), inspectJSON) + Expect(err).To(BeNil()) + Expect(inspectJSON.InfraConfig).To(Not(BeNil())) + Expect(len(inspectJSON.InfraConfig.PortBindings["80/tcp"])).To(Equal(1)) + Expect(inspectJSON.InfraConfig.PortBindings["80/tcp"][0].HostPort).To(Equal("8080")) + }) }) diff --git a/test/e2e/run_entrypoint_test.go b/test/e2e/run_entrypoint_test.go index 76e021552..741019770 100644 --- a/test/e2e/run_entrypoint_test.go +++ b/test/e2e/run_entrypoint_test.go @@ -101,6 +101,11 @@ ENTRYPOINT ["grep", "Alpine", "/etc/os-release"] session.WaitWithDefaultTimeout() Expect(session.ExitCode()).To(Equal(0)) Expect(session.LineInOuputStartsWith("Linux")).To(BeTrue()) + + session = podmanTest.Podman([]string{"run", "--entrypoint", "", "foobar.com/entrypoint:latest", "uname"}) + session.WaitWithDefaultTimeout() + Expect(session.ExitCode()).To(Equal(0)) + Expect(session.LineInOuputStartsWith("Linux")).To(BeTrue()) }) It("podman run user entrypoint with command overrides image entrypoint and image cmd", func() { diff --git a/test/e2e/systemd_test.go b/test/e2e/systemd_test.go index a1cdff70e..7b9be2275 100644 --- a/test/e2e/systemd_test.go +++ b/test/e2e/systemd_test.go @@ -112,5 +112,40 @@ WantedBy=multi-user.target systemctl.WaitWithDefaultTimeout() Expect(systemctl.ExitCode()).To(Equal(0)) Expect(strings.Contains(systemctl.OutputToString(), "State:")).To(BeTrue()) + + result := podmanTest.Podman([]string{"inspect", ctrName}) + result.WaitWithDefaultTimeout() + Expect(result.ExitCode()).To(Equal(0)) + conData := result.InspectContainerToJSON() + Expect(len(conData)).To(Equal(1)) + Expect(conData[0].Config.SystemdMode).To(BeTrue()) + }) + + It("podman create container with systemd entrypoint triggers systemd mode", func() { + ctrName := "testCtr" + run := podmanTest.Podman([]string{"create", "--name", ctrName, "--entrypoint", "/sbin/init", ubi_init}) + run.WaitWithDefaultTimeout() + Expect(run.ExitCode()).To(Equal(0)) + + result := podmanTest.Podman([]string{"inspect", ctrName}) + result.WaitWithDefaultTimeout() + Expect(result.ExitCode()).To(Equal(0)) + conData := result.InspectContainerToJSON() + Expect(len(conData)).To(Equal(1)) + Expect(conData[0].Config.SystemdMode).To(BeTrue()) + }) + + It("podman create container with systemd=always triggers systemd mode", func() { + ctrName := "testCtr" + run := podmanTest.Podman([]string{"create", "--name", ctrName, "--systemd", "always", ALPINE}) + run.WaitWithDefaultTimeout() + Expect(run.ExitCode()).To(Equal(0)) + + result := podmanTest.Podman([]string{"inspect", ctrName}) + result.WaitWithDefaultTimeout() + Expect(result.ExitCode()).To(Equal(0)) + conData := result.InspectContainerToJSON() + Expect(len(conData)).To(Equal(1)) + Expect(conData[0].Config.SystemdMode).To(BeTrue()) }) }) diff --git a/vendor/github.com/containers/storage/VERSION b/vendor/github.com/containers/storage/VERSION index 3500250a4..284497740 100644 --- a/vendor/github.com/containers/storage/VERSION +++ b/vendor/github.com/containers/storage/VERSION @@ -1 +1 @@ -1.21.0 +1.21.1 diff --git a/vendor/github.com/containers/storage/drivers/overlay/overlay.go b/vendor/github.com/containers/storage/drivers/overlay/overlay.go index 930a57a97..fc7010645 100644 --- a/vendor/github.com/containers/storage/drivers/overlay/overlay.go +++ b/vendor/github.com/containers/storage/drivers/overlay/overlay.go @@ -892,19 +892,6 @@ func (d *Driver) get(id string, disableShifting bool, options graphdriver.MountO } } - // If the lowers list is still empty, use an empty lower so that we can still force an - // SELinux context for the mount. - - // if we are doing a readOnly mount, and there is only one lower - // We should just return the lower directory, no reason to mount. - if !readWrite && d.options.mountProgram == "" { - if len(absLowers) == 0 { - return path.Join(dir, "empty"), nil - } - if len(absLowers) == 1 { - return absLowers[0], nil - } - } if len(absLowers) == 0 { absLowers = append(absLowers, path.Join(dir, "empty")) relLowers = append(relLowers, path.Join(id, "empty")) diff --git a/vendor/github.com/containers/storage/layers.go b/vendor/github.com/containers/storage/layers.go index a8ebf9e1e..dc21f75fd 100644 --- a/vendor/github.com/containers/storage/layers.go +++ b/vendor/github.com/containers/storage/layers.go @@ -772,7 +772,20 @@ func (r *layerStore) Mounted(id string) (int, error) { } func (r *layerStore) Mount(id string, options drivers.MountOpts) (string, error) { - if !r.IsReadWrite() { + + // check whether options include ro option + hasReadOnlyOpt := func(opts []string) bool { + for _, item := range opts { + if item == "ro" { + return true + } + } + return false + } + + // You are not allowed to mount layers from readonly stores if they + // are not mounted read/only. + if !r.IsReadWrite() && !hasReadOnlyOpt(options.Options) { return "", errors.Wrapf(ErrStoreIsReadOnly, "not allowed to update mount locations for layers at %q", r.mountspath()) } r.mountsLockfile.Lock() @@ -1000,6 +1013,7 @@ func (r *layerStore) deleteInternal(id string) error { if layer.MountPoint != "" { delete(r.bymount, layer.MountPoint) } + r.deleteInDigestMap(id) toDeleteIndex := -1 for i, candidate := range r.layers { if candidate.ID == id { @@ -1031,6 +1045,27 @@ func (r *layerStore) deleteInternal(id string) error { return err } +func (r *layerStore) deleteInDigestMap(id string) { + for digest, layers := range r.bycompressedsum { + for i, layerID := range layers { + if layerID == id { + layers = append(layers[:i], layers[i+1:]...) + r.bycompressedsum[digest] = layers + break + } + } + } + for digest, layers := range r.byuncompressedsum { + for i, layerID := range layers { + if layerID == id { + layers = append(layers[:i], layers[i+1:]...) + r.byuncompressedsum[digest] = layers + break + } + } + } +} + func (r *layerStore) Delete(id string) error { layer, ok := r.lookup(id) if !ok { diff --git a/vendor/github.com/containers/storage/userns.go b/vendor/github.com/containers/storage/userns.go index 34ff6a77a..e2b56da2f 100644 --- a/vendor/github.com/containers/storage/userns.go +++ b/vendor/github.com/containers/storage/userns.go @@ -229,7 +229,7 @@ func subtractHostIDs(avail idtools.IDMap, used idtools.IDMap) []idtools.IDMap { case used.HostID <= avail.HostID && used.HostID+used.Size >= avail.HostID+avail.Size: return nil case used.HostID <= avail.HostID && used.HostID+used.Size > avail.HostID && used.HostID+used.Size < avail.HostID+avail.Size: - newContainerID := used.HostID + used.Size + newContainerID := avail.ContainerID + used.Size newHostID := used.HostID + used.Size r := idtools.IDMap{ ContainerID: newContainerID, @@ -275,7 +275,7 @@ func subtractContainerIDs(avail idtools.IDMap, used idtools.IDMap) []idtools.IDM return nil case used.ContainerID <= avail.ContainerID && used.ContainerID+used.Size > avail.ContainerID && used.ContainerID+used.Size < avail.ContainerID+avail.Size: newContainerID := used.ContainerID + used.Size - newHostID := used.HostID + used.Size + newHostID := avail.HostID + used.Size r := idtools.IDMap{ ContainerID: newContainerID, HostID: newHostID, @@ -297,7 +297,7 @@ func subtractContainerIDs(avail idtools.IDMap, used idtools.IDMap) []idtools.IDM } r2 := idtools.IDMap{ ContainerID: used.ContainerID + used.Size, - HostID: used.HostID + used.Size, + HostID: avail.HostID + used.Size, Size: avail.ContainerID + avail.Size - used.ContainerID - used.Size, } return []idtools.IDMap{r1, r2} diff --git a/vendor/modules.txt b/vendor/modules.txt index 689165af4..7122f5fb8 100644 --- a/vendor/modules.txt +++ b/vendor/modules.txt @@ -155,7 +155,7 @@ github.com/containers/psgo/internal/dev github.com/containers/psgo/internal/host github.com/containers/psgo/internal/proc github.com/containers/psgo/internal/process -# github.com/containers/storage v1.21.0 +# github.com/containers/storage v1.21.1 github.com/containers/storage github.com/containers/storage/drivers github.com/containers/storage/drivers/aufs |