diff options
49 files changed, 802 insertions, 199 deletions
@@ -106,7 +106,11 @@ CROSS_BUILD_TARGETS := \ bin/podman.cross.linux.arm \ bin/podman.cross.linux.arm64 \ bin/podman.cross.linux.386 \ - bin/podman.cross.linux.s390x + bin/podman.cross.linux.s390x \ + bin/podman.cross.linux.mips \ + bin/podman.cross.linux.mipsle \ + bin/podman.cross.linux.mips64 \ + bin/podman.cross.linux.mips64le .PHONY: all all: binaries docs diff --git a/docs/source/markdown/podman-build.1.md b/docs/source/markdown/podman-build.1.md index 67513e386..5de3124bb 100644 --- a/docs/source/markdown/podman-build.1.md +++ b/docs/source/markdown/podman-build.1.md @@ -305,6 +305,11 @@ Recognized formats include *oci* (OCI image-spec v1.0, the default) and Note: You can also override the default format by setting the BUILDAH\_FORMAT environment variable. `export BUILDAH_FORMAT=docker` +#### **--from** + +Overrides the first `FROM` instruction within the Containerfile. If there are multiple +FROM instructions in a Containerfile, only the first is changed. + **-h**, **--help** Print usage statement @@ -524,6 +529,12 @@ layers are not squashed. Squash all of the new image's layers (including those inherited from a base image) into a single new layer. +#### **--stdin** + +Pass stdin into the RUN containers. Sometime commands being RUN within a Containerfile +want to request information from the user. For example apt asking for a confirmation for install. +Use --stdin to be able to interact from the terminal during the build. + #### **--tag**, **-t**=*imageName* Specifies the name which will be assigned to the resulting image if the build diff --git a/docs/source/markdown/podman.1.md b/docs/source/markdown/podman.1.md index 2688c1720..42054d075 100644 --- a/docs/source/markdown/podman.1.md +++ b/docs/source/markdown/podman.1.md @@ -122,7 +122,7 @@ Default root dir configured in `/etc/containers/storage.conf`. #### **--runroot**=*value* -Storage state directory where all state information is stored (default: "/var/run/containers/storage" for UID 0, "/var/run/user/$UID/run" for other users). +Storage state directory where all state information is stored (default: "/run/containers/storage" for UID 0, "/run/user/$UID/run" for other users). Default state dir configured in `/etc/containers/storage.conf`. #### **--runtime**=*value* diff --git a/docs/tutorials/podman_tutorial.md b/docs/tutorials/podman_tutorial.md index c15de67a6..7419f445e 100644 --- a/docs/tutorials/podman_tutorial.md +++ b/docs/tutorials/podman_tutorial.md @@ -21,7 +21,7 @@ For installing or building Podman, please see the [installation instructions](ht This sample container will run a very basic httpd server that serves only its index page. ```console -podman run -dt -p 8080:8080/tcp -e HTTPD_VAR_RUN=/var/run/httpd -e HTTPD_MAIN_CONF_D_PATH=/etc/httpd/conf.d \ +podman run -dt -p 8080:8080/tcp -e HTTPD_VAR_RUN=/run/httpd -e HTTPD_MAIN_CONF_D_PATH=/etc/httpd/conf.d \ -e HTTPD_MAIN_CONF_PATH=/etc/httpd/conf \ -e HTTPD_CONTAINER_SCRIPTS_PATH=/usr/share/container-scripts/httpd/ \ registry.fedoraproject.org/f29/httpd /usr/bin/run-httpd diff --git a/docs/tutorials/rootless_tutorial.md b/docs/tutorials/rootless_tutorial.md index 9d8851bc8..cb73fc519 100644 --- a/docs/tutorials/rootless_tutorial.md +++ b/docs/tutorials/rootless_tutorial.md @@ -130,7 +130,7 @@ graphroot="" Default directory to store all writable content created by container storage programs. runroot="" - container storage run dir (default: "/var/run/containers/storage") + container storage run dir (default: "/run/containers/storage") Default directory to store all temporary writable content created by container storage programs. ``` In rootless podman these fields default to @@ -10,7 +10,7 @@ require ( github.com/codahale/hdrhistogram v0.0.0-20161010025455-3a0bb77429bd // indirect github.com/containernetworking/cni v0.8.0 github.com/containernetworking/plugins v0.9.0 - github.com/containers/buildah v1.18.1-0.20201217112226-67470615779c + github.com/containers/buildah v1.18.1-0.20201222143428-b9fdee076426 github.com/containers/common v0.31.2 github.com/containers/conmon v2.0.20+incompatible github.com/containers/image/v5 v5.9.0 @@ -29,7 +29,7 @@ require ( github.com/ghodss/yaml v1.0.0 github.com/godbus/dbus/v5 v5.0.3 github.com/google/shlex v0.0.0-20181106134648-c34317bd91bf - github.com/google/uuid v1.1.3 + github.com/google/uuid v1.1.4 github.com/gorilla/mux v1.8.0 github.com/gorilla/schema v1.2.0 github.com/hashicorp/go-multierror v1.1.0 @@ -23,12 +23,10 @@ github.com/BurntSushi/xgb v0.0.0-20160522181843-27f122750802/go.mod h1:IVnqGOEym github.com/Microsoft/go-winio v0.4.11/go.mod h1:VhR8bwka0BXejwEJY73c50VrPtXAaKcyvVC4A4RozmA= github.com/Microsoft/go-winio v0.4.15-0.20190919025122-fc70bd9a86b5/go.mod h1:tTuCMEN+UleMWgg9dVx4Hu52b1bJo+59jBh3ajtinzw= github.com/Microsoft/go-winio v0.4.15-0.20200113171025-3fe6c5262873/go.mod h1:tTuCMEN+UleMWgg9dVx4Hu52b1bJo+59jBh3ajtinzw= -github.com/Microsoft/go-winio v0.4.15 h1:qkLXKzb1QoVatRyd/YlXZ/Kg0m5K3SPuoD82jjSOaBc= github.com/Microsoft/go-winio v0.4.15/go.mod h1:tTuCMEN+UleMWgg9dVx4Hu52b1bJo+59jBh3ajtinzw= github.com/Microsoft/go-winio v0.4.16-0.20201130162521-d1ffc52c7331 h1:3YnB7Hpmh1lPecPE8doMOtYCrMdrpedZOvxfuNES/Vk= github.com/Microsoft/go-winio v0.4.16-0.20201130162521-d1ffc52c7331/go.mod h1:XB6nPKklQyQ7GC9LdcBEcBl8PF76WugXOPRXwdLnMv0= github.com/Microsoft/hcsshim v0.8.6/go.mod h1:Op3hHsoHPAvb6lceZHDtd9OkTew38wNoXnJs8iY7rUg= -github.com/Microsoft/hcsshim v0.8.9 h1:VrfodqvztU8YSOvygU+DN1BGaSGxmrNfqOv5oOuX2Bk= github.com/Microsoft/hcsshim v0.8.9/go.mod h1:5692vkUqntj1idxauYlpoINNKeqCiG6Sg38RRsjT5y8= github.com/Microsoft/hcsshim v0.8.14 h1:lbPVK25c1cu5xTLITwpUcxoA9vKrKErASPYygvouJns= github.com/Microsoft/hcsshim v0.8.14/go.mod h1:NtVKoYxQuTLx6gEq0L96c9Ju4JbRJ4nY2ow3VK6a9Lg= @@ -76,7 +74,6 @@ github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDk github.com/cncf/udpa/go v0.0.0-20191209042840-269d4d468f6f/go.mod h1:M8M6+tZqaGXZJjfX53e64911xZQV5JYwmTeXPW+k8Sc= github.com/codahale/hdrhistogram v0.0.0-20161010025455-3a0bb77429bd h1:qMd81Ts1T2OTKmB4acZcyKaMtRnY5Y44NuXGX2GFJ1w= github.com/codahale/hdrhistogram v0.0.0-20161010025455-3a0bb77429bd/go.mod h1:sE/e/2PUdi/liOCUjSTXgM1o87ZssimdTWN964YiIeI= -github.com/containerd/cgroups v0.0.0-20190919134610-bf292b21730f h1:tSNMc+rJDfmYntojat8lljbt1mgKNpTxUZJsSzJ9Y1s= github.com/containerd/cgroups v0.0.0-20190919134610-bf292b21730f/go.mod h1:OApqhQ4XNSNC13gXIwDjhOQxjWa/NxkwZXJ1EvqT0ko= github.com/containerd/cgroups v0.0.0-20200531161412-0dbf7f05ba59 h1:qWj4qVYZ95vLWwqyNJCQg7rDsG5wPdze0UaPolH7DUk= github.com/containerd/cgroups v0.0.0-20200531161412-0dbf7f05ba59/go.mod h1:pA0z1pT8KYB3TCXK/ocprsh7MAkoW8bZVzPdih9snmM= @@ -96,18 +93,16 @@ github.com/containerd/typeurl v0.0.0-20180627222232-a93fcdb778cd/go.mod h1:Cm3kw github.com/containernetworking/cni v0.7.2-0.20190904153231-83439463f784/go.mod h1:LGwApLUm2FpoOfxTDEeq8T9ipbpZ61X79hmU3w8FmsY= github.com/containernetworking/cni v0.8.0 h1:BT9lpgGoH4jw3lFC7Odz2prU5ruiYKcgAjMCbgybcKI= github.com/containernetworking/cni v0.8.0/go.mod h1:LGwApLUm2FpoOfxTDEeq8T9ipbpZ61X79hmU3w8FmsY= -github.com/containernetworking/plugins v0.8.7 h1:bU7QieuAp+sACI2vCzESJ3FoT860urYP+lThyZkb/2M= github.com/containernetworking/plugins v0.8.7/go.mod h1:R7lXeZaBzpfqapcAbHRW8/CYwm0dHzbz0XEjofx0uB0= github.com/containernetworking/plugins v0.9.0 h1:c+1gegKhR7+d0Caum9pEHugZlyhXPOG6v3V6xJgIGCI= github.com/containernetworking/plugins v0.9.0/go.mod h1:dbWv4dI0QrBGuVgj+TuVQ6wJRZVOhrCQj91YyC92sxg= -github.com/containers/buildah v1.18.1-0.20201217112226-67470615779c h1:DnJiPjBKeoZbzjkUA6YMf/r5ShYpNacK+EcQ/ui1Mxo= -github.com/containers/buildah v1.18.1-0.20201217112226-67470615779c/go.mod h1:hvIoL3urgYPL0zX8XlK05aWP6qfUnBNqTrsedsYw6OY= -github.com/containers/common v0.31.0/go.mod h1:yT4GTUHsKRmpaDb+mecXRnIMre7W3ZgwXqaYMywXlaA= +github.com/containers/buildah v1.18.1-0.20201222143428-b9fdee076426 h1:hgNSbIO7KUJ9jHSEHwM5D2qii5t/5f2yfxZepJFYm18= +github.com/containers/buildah v1.18.1-0.20201222143428-b9fdee076426/go.mod h1:AM7JcGaUtTJgR6fZL2zBg5PCSCSDiX/sNdMSyrkoJ10= +github.com/containers/common v0.31.1/go.mod h1:Fehe82hQfJQvDspnRrV9rcdAWG3IalNHEt0F6QWNBHQ= github.com/containers/common v0.31.2 h1:sNYwvLA4B7SpEiAWTUvkItPlCrUa2vcxh0FTKXKoC3Q= github.com/containers/common v0.31.2/go.mod h1:Fehe82hQfJQvDspnRrV9rcdAWG3IalNHEt0F6QWNBHQ= github.com/containers/conmon v2.0.20+incompatible h1:YbCVSFSCqFjjVwHTPINGdMX1F6JXHGTUje2ZYobNrkg= github.com/containers/conmon v2.0.20+incompatible/go.mod h1:hgwZ2mtuDrppv78a/cOBNiCm6O0UMWGx1mu7P00nu5I= -github.com/containers/image/v5 v5.8.1/go.mod h1:blOEFd/iFdeyh891ByhCVUc+xAcaI3gBegXECwz9UbQ= github.com/containers/image/v5 v5.9.0 h1:dRmUtcluQcmasNo3DpnRoZjfU0rOu1qZeL6wlDJr10Q= github.com/containers/image/v5 v5.9.0/go.mod h1:blOEFd/iFdeyh891ByhCVUc+xAcaI3gBegXECwz9UbQ= github.com/containers/libtrust v0.0.0-20190913040956-14b96171aa3b h1:Q8ePgVfHDplZ7U33NwHZkrVELsZP5fYj9pM5WBZB2GE= @@ -117,8 +112,6 @@ github.com/containers/ocicrypt v1.0.3/go.mod h1:CUBa+8MRNL/VkpxYIpaMtgn1WgXGyvPQ github.com/containers/psgo v1.5.2 h1:3aoozst/GIwsrr/5jnFy3FrJay98uujPCu9lTuSZ/Cw= github.com/containers/psgo v1.5.2/go.mod h1:2ubh0SsreMZjSXW1Hif58JrEcFudQyIy9EzPUWfawVU= github.com/containers/storage v1.23.7/go.mod h1:cUT2zHjtx+WlVri30obWmM2gpqpi8jfPsmIzP1TVpEI= -github.com/containers/storage v1.24.1/go.mod h1:0xJL06Dmd+ZYXIUdnBUPN0JnhHGgwMkLvnnAonJfWJU= -github.com/containers/storage v1.24.3 h1:8UB4S62l4hrU6Yw3dbsLCJtLg7Ofo39IN2HdckBIX4E= github.com/containers/storage v1.24.3/go.mod h1:0xJL06Dmd+ZYXIUdnBUPN0JnhHGgwMkLvnnAonJfWJU= github.com/containers/storage v1.24.4 h1:QJn/C/4eNbYNpxYdnIn1u4lElIB7V9IesRraLf68JjY= github.com/containers/storage v1.24.4/go.mod h1:Y793GKrV3RVM1Jt4QejXtCJHGUPLrDvQ9LAbCyJ9OKs= @@ -266,8 +259,8 @@ github.com/google/uuid v1.0.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+ github.com/google/uuid v1.1.1/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/google/uuid v1.1.2 h1:EVhdT+1Kseyi1/pUmXKaFxYsDNy9RQYkMWRH68J/W7Y= github.com/google/uuid v1.1.2/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= -github.com/google/uuid v1.1.3 h1:twObb+9XcuH5B9V1TBCvvvZoO6iEdILi2a76PYn5rJI= -github.com/google/uuid v1.1.3/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= +github.com/google/uuid v1.1.4 h1:0ecGp3skIrHWPNGPJDaBIghfA6Sp7Ruo2Io8eLKzWm0= +github.com/google/uuid v1.1.4/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/googleapis/gax-go/v2 v2.0.4/go.mod h1:0Wqv26UfaUD9n4G6kQubkQ+KchISgw+vpHVxEJEs9eg= github.com/googleapis/gax-go/v2 v2.0.5/go.mod h1:DWXyrwAJ9X0FpwwEdw+IPEYBICEFu5mhpdKc/us6bOk= github.com/googleapis/gnostic v0.0.0-20170729233727-0c5108395e2d/go.mod h1:sJBsCZ4ayReDTBIg8b9dl28c5xFWyhBTVRp3pOg5EKY= @@ -335,7 +328,6 @@ github.com/kisielk/errcheck v1.1.0/go.mod h1:EZBBE59ingxPouuu3KfxchcWSUPOHkagtvW github.com/kisielk/errcheck v1.2.0/go.mod h1:/BMXB+zMLi60iA8Vv6Ksmxu/1UDYcXs4uQLJ+jE2L00= github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck= github.com/klauspost/compress v1.11.1/go.mod h1:aoV0uJVorq1K+umq18yTdKaF57EivdYsUV+/s2qKfXs= -github.com/klauspost/compress v1.11.3 h1:dB4Bn0tN3wdCzQxnS8r06kV74qN/TAfaIS0bVE8h3jc= github.com/klauspost/compress v1.11.3/go.mod h1:aoV0uJVorq1K+umq18yTdKaF57EivdYsUV+/s2qKfXs= github.com/klauspost/compress v1.11.4 h1:kz40R/YWls3iqT9zX9AHN3WoVsrAWVyui5sxuLqiXqU= github.com/klauspost/compress v1.11.4/go.mod h1:aoV0uJVorq1K+umq18yTdKaF57EivdYsUV+/s2qKfXs= @@ -719,7 +711,6 @@ golang.org/x/sys v0.0.0-20200909081042-eff7692f9009/go.mod h1:h1NjWce9XRLGQEsW7w golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20201018230417-eeed37f84f13/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20201112073958-5cba982894dd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20201117170446-d9b008d0a637 h1:O5hKNaGxIT4A8OTMnuh6UpmBdI3SAPxlZ3g0olDrJVM= golang.org/x/sys v0.0.0-20201117170446-d9b008d0a637/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20201201145000-ef89a241ccb3 h1:kzM6+9dur93BcC2kVlYl34cHU+TYZLanmpSJHVMmL64= golang.org/x/sys v0.0.0-20201201145000-ef89a241ccb3/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= diff --git a/libpod/container_exec.go b/libpod/container_exec.go index fce26acb0..5aee847e1 100644 --- a/libpod/container_exec.go +++ b/libpod/container_exec.go @@ -8,7 +8,6 @@ import ( "strconv" "time" - "github.com/containers/common/pkg/capabilities" "github.com/containers/podman/v2/libpod/define" "github.com/containers/podman/v2/libpod/events" "github.com/containers/storage/pkg/stringid" @@ -973,20 +972,12 @@ func (c *Container) removeAllExecSessions() error { // Make an ExecOptions struct to start the OCI runtime and prepare its exec // bundle. func prepareForExec(c *Container, session *ExecSession) (*ExecOptions, error) { - // TODO: check logic here - should we set Privileged if the container is - // privileged? - var capList []string - if session.Config.Privileged || c.config.Privileged { - capList = capabilities.AllCapabilities() - } - if err := c.createExecBundle(session.ID()); err != nil { return nil, err } opts := new(ExecOptions) opts.Cmd = session.Config.Command - opts.CapAdd = capList opts.Env = session.Config.Environment opts.Terminal = session.Config.Terminal opts.Cwd = session.Config.WorkDir @@ -995,6 +986,7 @@ func prepareForExec(c *Container, session *ExecSession) (*ExecOptions, error) { opts.DetachKeys = session.Config.DetachKeys opts.ExitCommand = session.Config.ExitCommand opts.ExitCommandDelay = session.Config.ExitCommandDelay + opts.Privileged = session.Config.Privileged return opts, nil } diff --git a/libpod/container_internal_linux.go b/libpod/container_internal_linux.go index f947d1ed9..ac20e1f25 100644 --- a/libpod/container_internal_linux.go +++ b/libpod/container_internal_linux.go @@ -529,6 +529,13 @@ func (c *Container) generateSpec(ctx context.Context) (*spec.Spec, error) { } } + availableUIDs, availableGIDs, err := rootless.GetAvailableIDMaps() + if err != nil { + return nil, err + } + g.Config.Linux.UIDMappings = rootless.MaybeSplitMappings(g.Config.Linux.UIDMappings, availableUIDs) + g.Config.Linux.GIDMappings = rootless.MaybeSplitMappings(g.Config.Linux.GIDMappings, availableGIDs) + // Hostname handling: // If we have a UTS namespace, set Hostname in the OCI spec. // Set the HOSTNAME environment variable unless explicitly overridden by @@ -536,6 +543,7 @@ func (c *Container) generateSpec(ctx context.Context) (*spec.Spec, error) { // set it to the host's hostname instead. hostname := c.Hostname() foundUTS := false + for _, i := range c.config.Spec.Linux.Namespaces { if i.Type == spec.UTSNamespace && i.Path == "" { foundUTS = true diff --git a/libpod/container_log.go b/libpod/container_log.go index e58503bd3..f16e08353 100644 --- a/libpod/container_log.go +++ b/libpod/container_log.go @@ -82,7 +82,7 @@ func (c *Container) readFromLogFile(ctx context.Context, options *logs.LogOption if nll.Partial() { partial += nll.Msg continue - } else if !nll.Partial() && len(partial) > 1 { + } else if !nll.Partial() && len(partial) > 0 { nll.Msg = partial + nll.Msg partial = "" } diff --git a/libpod/networking_linux.go b/libpod/networking_linux.go index be6867399..addf1814c 100644 --- a/libpod/networking_linux.go +++ b/libpod/networking_linux.go @@ -685,7 +685,7 @@ func (r *Runtime) setupNetNS(ctr *Container) error { return errors.Wrapf(err, "failed to generate random netns name") } - nsPath := fmt.Sprintf("/var/run/netns/cni-%x-%x-%x-%x-%x", b[0:4], b[4:6], b[6:8], b[8:10], b[10:]) + nsPath := fmt.Sprintf("/run/netns/cni-%x-%x-%x-%x-%x", b[0:4], b[4:6], b[6:8], b[8:10], b[10:]) if err := os.MkdirAll(filepath.Dir(nsPath), 0711); err != nil { return err diff --git a/libpod/oci.go b/libpod/oci.go index 157c42c38..6948e6425 100644 --- a/libpod/oci.go +++ b/libpod/oci.go @@ -151,8 +151,6 @@ type OCIRuntime interface { type ExecOptions struct { // Cmd is the command to execute. Cmd []string - // CapAdd is a set of capabilities to add to the executed command. - CapAdd []string // Env is a set of environment variables to add to the container. Env map[string]string // Terminal is whether to create a new TTY for the exec session. @@ -181,6 +179,8 @@ type ExecOptions struct { // ExitCommandDelay is a delay (in seconds) between the exec session // exiting, and the exit command being invoked. ExitCommandDelay uint + // Privileged indicates the execed process will be launched in Privileged mode + Privileged bool } // HTTPAttachStreams informs the HTTPAttach endpoint which of the container's diff --git a/libpod/oci_conmon_exec_linux.go b/libpod/oci_conmon_exec_linux.go index 4546acefb..d6b63f25e 100644 --- a/libpod/oci_conmon_exec_linux.go +++ b/libpod/oci_conmon_exec_linux.go @@ -398,10 +398,6 @@ func (r *ConmonOCIRuntime) startExec(c *Container, sessionID string, options *Ex args = append(args, formatRuntimeOpts("--preserve-fds", fmt.Sprintf("%d", options.PreserveFDs))...) } - for _, capability := range options.CapAdd { - args = append(args, formatRuntimeOpts("--cap", capability)...) - } - if options.Terminal { args = append(args, "-t") } diff --git a/libpod/oci_conmon_linux.go b/libpod/oci_conmon_linux.go index e7cb5a802..6b5da439a 100644 --- a/libpod/oci_conmon_linux.go +++ b/libpod/oci_conmon_linux.go @@ -22,6 +22,7 @@ import ( "text/template" "time" + "github.com/containers/common/pkg/capabilities" "github.com/containers/common/pkg/config" conmonConfig "github.com/containers/conmon/runner/config" "github.com/containers/podman/v2/libpod/define" @@ -1201,13 +1202,7 @@ func prepareProcessExec(c *Container, options *ExecOptions, env []string, sessio } pspec.SelinuxLabel = c.config.ProcessLabel pspec.Args = options.Cmd - for _, cap := range options.CapAdd { - pspec.Capabilities.Bounding = append(pspec.Capabilities.Bounding, cap) - pspec.Capabilities.Effective = append(pspec.Capabilities.Effective, cap) - pspec.Capabilities.Inheritable = append(pspec.Capabilities.Inheritable, cap) - pspec.Capabilities.Permitted = append(pspec.Capabilities.Permitted, cap) - pspec.Capabilities.Ambient = append(pspec.Capabilities.Ambient, cap) - } + // We need to default this to false else it will inherit terminal as true // from the container. pspec.Terminal = false @@ -1263,6 +1258,31 @@ func prepareProcessExec(c *Container, options *ExecOptions, env []string, sessio pspec.User = processUser } + ctrSpec, err := c.specFromState() + if err != nil { + return nil, err + } + + allCaps := capabilities.AllCapabilities() + if options.Privileged { + pspec.Capabilities.Bounding = allCaps + } else { + pspec.Capabilities.Bounding = ctrSpec.Process.Capabilities.Bounding + } + if execUser.Uid == 0 { + pspec.Capabilities.Effective = pspec.Capabilities.Bounding + pspec.Capabilities.Inheritable = pspec.Capabilities.Bounding + pspec.Capabilities.Permitted = pspec.Capabilities.Bounding + pspec.Capabilities.Ambient = pspec.Capabilities.Bounding + } else { + if user == c.config.User { + pspec.Capabilities.Effective = ctrSpec.Process.Capabilities.Effective + pspec.Capabilities.Inheritable = ctrSpec.Process.Capabilities.Effective + pspec.Capabilities.Permitted = ctrSpec.Process.Capabilities.Effective + pspec.Capabilities.Ambient = ctrSpec.Process.Capabilities.Effective + } + } + hasHomeSet := false for _, s := range pspec.Env { if strings.HasPrefix(s, "HOME=") { diff --git a/libpod/options.go b/libpod/options.go index 8100eee62..ef7db3235 100644 --- a/libpod/options.go +++ b/libpod/options.go @@ -306,7 +306,7 @@ func WithDefaultMountsFile(mountsFile string) RuntimeOption { // WithTmpDir sets the directory that temporary runtime files which are not // expected to survive across reboots will be stored. -// This should be located on a tmpfs mount (/tmp or /var/run for example). +// This should be located on a tmpfs mount (/tmp or /run for example). func WithTmpDir(dir string) RuntimeOption { return func(rt *Runtime) error { if rt.valid { diff --git a/pkg/api/handlers/compat/containers_prune.go b/pkg/api/handlers/compat/containers_prune.go index b3d26b8f4..7bba38475 100644 --- a/pkg/api/handlers/compat/containers_prune.go +++ b/pkg/api/handlers/compat/containers_prune.go @@ -1,9 +1,11 @@ package compat import ( + "bytes" "net/http" "github.com/containers/podman/v2/libpod" + "github.com/containers/podman/v2/pkg/api/handlers" "github.com/containers/podman/v2/pkg/api/handlers/utils" "github.com/containers/podman/v2/pkg/domain/entities/reports" "github.com/containers/podman/v2/pkg/domain/filters" @@ -32,33 +34,45 @@ func PruneContainers(w http.ResponseWriter, r *http.Request) { filterFuncs = append(filterFuncs, generatedFunc) } + report, err := PruneContainersHelper(r, filterFuncs) + if err != nil { + utils.InternalServerError(w, err) + return + } + // Libpod response differs if utils.IsLibpodRequest(r) { - report, err := PruneContainersHelper(w, r, filterFuncs) - if err != nil { - utils.InternalServerError(w, err) - return - } - utils.WriteResponse(w, http.StatusOK, report) return } - report, err := runtime.PruneContainers(filterFuncs) - if err != nil { - utils.InternalServerError(w, err) + var payload handlers.ContainersPruneReport + var errorMsg bytes.Buffer + for _, pr := range report { + if pr.Err != nil { + // Docker stops on first error vs. libpod which keeps going. Given API constraints, concatenate all errors + // and return that string. + errorMsg.WriteString(pr.Err.Error()) + errorMsg.WriteString("; ") + continue + } + payload.ContainersDeleted = append(payload.ContainersDeleted, pr.Id) + payload.SpaceReclaimed += pr.Size + } + if errorMsg.Len() > 0 { + utils.InternalServerError(w, errors.New(errorMsg.String())) return } - utils.WriteResponse(w, http.StatusOK, report) + + utils.WriteResponse(w, http.StatusOK, payload) } -func PruneContainersHelper(w http.ResponseWriter, r *http.Request, filterFuncs []libpod.ContainerFilter) ( - []*reports.PruneReport, error) { +func PruneContainersHelper(r *http.Request, filterFuncs []libpod.ContainerFilter) ([]*reports.PruneReport, error) { runtime := r.Context().Value("runtime").(*libpod.Runtime) - reports, err := runtime.PruneContainers(filterFuncs) + + report, err := runtime.PruneContainers(filterFuncs) if err != nil { - utils.InternalServerError(w, err) return nil, err } - return reports, nil + return report, nil } diff --git a/pkg/api/handlers/compat/images.go b/pkg/api/handlers/compat/images.go index 9d7503aba..0ae0f3bcf 100644 --- a/pkg/api/handlers/compat/images.go +++ b/pkg/api/handlers/compat/images.go @@ -18,7 +18,6 @@ import ( "github.com/containers/podman/v2/pkg/api/handlers/utils" "github.com/containers/podman/v2/pkg/auth" "github.com/containers/podman/v2/pkg/domain/entities" - "github.com/docker/docker/api/types" "github.com/gorilla/schema" "github.com/opencontainers/go-digest" "github.com/pkg/errors" @@ -74,52 +73,6 @@ func ExportImage(w http.ResponseWriter, r *http.Request) { utils.WriteResponse(w, http.StatusOK, rdr) } -func PruneImages(w http.ResponseWriter, r *http.Request) { - var ( - filters []string - ) - decoder := r.Context().Value("decoder").(*schema.Decoder) - runtime := r.Context().Value("runtime").(*libpod.Runtime) - - query := struct { - All bool - Filters map[string][]string `schema:"filters"` - }{ - // This is where you can override the golang default value for one of fields - } - - if err := decoder.Decode(&query, r.URL.Query()); err != nil { - utils.Error(w, "Something went wrong.", http.StatusBadRequest, errors.Wrapf(err, "failed to parse parameters for %s", r.URL.String())) - return - } - - idr := []types.ImageDeleteResponseItem{} - for k, v := range query.Filters { - for _, val := range v { - filters = append(filters, fmt.Sprintf("%s=%s", k, val)) - } - } - imagePruneReports, err := runtime.ImageRuntime().PruneImages(r.Context(), query.All, filters) - if err != nil { - utils.InternalServerError(w, err) - return - } - reclaimedSpace := uint64(0) - for _, p := range imagePruneReports { - idr = append(idr, types.ImageDeleteResponseItem{ - Deleted: p.Id, - }) - reclaimedSpace = reclaimedSpace + p.Size - } - - // FIXME/TODO to do this exactly correct, pruneimages needs to return idrs and space-reclaimed, then we are golden - ipr := types.ImagesPruneReport{ - ImagesDeleted: idr, - SpaceReclaimed: reclaimedSpace, - } - utils.WriteResponse(w, http.StatusOK, handlers.ImagesPruneReport{ImagesPruneReport: ipr}) -} - func CommitContainer(w http.ResponseWriter, r *http.Request) { var ( destImage string diff --git a/pkg/api/handlers/compat/images_prune.go b/pkg/api/handlers/compat/images_prune.go new file mode 100644 index 000000000..c7e84804b --- /dev/null +++ b/pkg/api/handlers/compat/images_prune.go @@ -0,0 +1,75 @@ +package compat + +import ( + "bytes" + "fmt" + "net/http" + + "github.com/containers/podman/v2/libpod" + "github.com/containers/podman/v2/pkg/api/handlers" + "github.com/containers/podman/v2/pkg/api/handlers/utils" + "github.com/docker/docker/api/types" + "github.com/gorilla/schema" + "github.com/pkg/errors" +) + +func PruneImages(w http.ResponseWriter, r *http.Request) { + var ( + filters []string + ) + decoder := r.Context().Value("decoder").(*schema.Decoder) + runtime := r.Context().Value("runtime").(*libpod.Runtime) + + query := struct { + All bool + Filters map[string][]string `schema:"filters"` + }{ + // This is where you can override the golang default value for one of fields + } + + if err := decoder.Decode(&query, r.URL.Query()); err != nil { + utils.Error(w, "Something went wrong.", http.StatusBadRequest, errors.Wrapf(err, "failed to parse parameters for %s", r.URL.String())) + return + } + + for k, v := range query.Filters { + for _, val := range v { + filters = append(filters, fmt.Sprintf("%s=%s", k, val)) + } + } + imagePruneReports, err := runtime.ImageRuntime().PruneImages(r.Context(), query.All, filters) + if err != nil { + utils.InternalServerError(w, err) + return + } + + idr := make([]types.ImageDeleteResponseItem, len(imagePruneReports)) + var reclaimedSpace uint64 + var errorMsg bytes.Buffer + for _, p := range imagePruneReports { + if p.Err != nil { + // Docker stops on first error vs. libpod which keeps going. Given API constraints, concatenate all errors + // and return that string. + errorMsg.WriteString(p.Err.Error()) + errorMsg.WriteString("; ") + continue + } + + idr = append(idr, types.ImageDeleteResponseItem{ + Deleted: p.Id, + }) + reclaimedSpace = reclaimedSpace + p.Size + } + if errorMsg.Len() > 0 { + utils.InternalServerError(w, errors.New(errorMsg.String())) + return + } + + payload := handlers.ImagesPruneReport{ + ImagesPruneReport: types.ImagesPruneReport{ + ImagesDeleted: idr, + SpaceReclaimed: reclaimedSpace, + }, + } + utils.WriteResponse(w, http.StatusOK, payload) +} diff --git a/pkg/api/handlers/compat/volumes.go b/pkg/api/handlers/compat/volumes.go index 1188d8f84..4903bbad4 100644 --- a/pkg/api/handlers/compat/volumes.go +++ b/pkg/api/handlers/compat/volumes.go @@ -1,6 +1,7 @@ package compat import ( + "bytes" "encoding/json" "net/http" "net/url" @@ -8,6 +9,7 @@ import ( "github.com/containers/podman/v2/libpod" "github.com/containers/podman/v2/libpod/define" + "github.com/containers/podman/v2/pkg/api/handlers" "github.com/containers/podman/v2/pkg/api/handlers/utils" "github.com/containers/podman/v2/pkg/domain/filters" "github.com/containers/podman/v2/pkg/domain/infra/abi/parse" @@ -268,17 +270,29 @@ func PruneVolumes(w http.ResponseWriter, r *http.Request) { utils.InternalServerError(w, err) return } + + var errorMsg bytes.Buffer + var reclaimedSpace uint64 prunedIds := make([]string, 0, len(pruned)) for _, v := range pruned { - // XXX: This drops any pruning per-volume error messages on the floor + if v.Err != nil { + errorMsg.WriteString(v.Err.Error()) + errorMsg.WriteString("; ") + continue + } prunedIds = append(prunedIds, v.Id) + reclaimedSpace += v.Size } - pruneResponse := docker_api_types.VolumesPruneReport{ - VolumesDeleted: prunedIds, - // TODO: We don't have any insight into how much space was reclaimed - // from `PruneVolumes()` but it's not nullable - SpaceReclaimed: 0, + if errorMsg.Len() > 0 { + utils.InternalServerError(w, errors.New(errorMsg.String())) + return } - utils.WriteResponse(w, http.StatusOK, pruneResponse) + payload := handlers.VolumesPruneReport{ + VolumesPruneReport: docker_api_types.VolumesPruneReport{ + VolumesDeleted: prunedIds, + SpaceReclaimed: reclaimedSpace, + }, + } + utils.WriteResponse(w, http.StatusOK, payload) } diff --git a/pkg/api/handlers/libpod/pods.go b/pkg/api/handlers/libpod/pods.go index 5422411cf..de373f05f 100644 --- a/pkg/api/handlers/libpod/pods.go +++ b/pkg/api/handlers/libpod/pods.go @@ -235,7 +235,7 @@ func PodRestart(w http.ResponseWriter, r *http.Request) { } func PodPrune(w http.ResponseWriter, r *http.Request) { - reports, err := PodPruneHelper(w, r) + reports, err := PodPruneHelper(r) if err != nil { utils.InternalServerError(w, err) return @@ -243,7 +243,7 @@ func PodPrune(w http.ResponseWriter, r *http.Request) { utils.WriteResponse(w, http.StatusOK, reports) } -func PodPruneHelper(w http.ResponseWriter, r *http.Request) ([]*entities.PodPruneReport, error) { +func PodPruneHelper(r *http.Request) ([]*entities.PodPruneReport, error) { var ( runtime = r.Context().Value("runtime").(*libpod.Runtime) ) diff --git a/pkg/api/handlers/libpod/system.go b/pkg/api/handlers/libpod/system.go index 130e563ae..c48c186ed 100644 --- a/pkg/api/handlers/libpod/system.go +++ b/pkg/api/handlers/libpod/system.go @@ -30,7 +30,7 @@ func SystemPrune(w http.ResponseWriter, r *http.Request) { return } - podPruneReport, err := PodPruneHelper(w, r) + podPruneReport, err := PodPruneHelper(r) if err != nil { utils.InternalServerError(w, err) return @@ -38,7 +38,7 @@ func SystemPrune(w http.ResponseWriter, r *http.Request) { systemPruneReport.PodPruneReport = podPruneReport // We could parallelize this, should we? - containerPruneReports, err := compat.PruneContainersHelper(w, r, nil) + containerPruneReports, err := compat.PruneContainersHelper(r, nil) if err != nil { utils.InternalServerError(w, err) return diff --git a/pkg/api/server/docs.go b/pkg/api/server/docs.go index 1aaf31117..a99fefd7b 100644 --- a/pkg/api/server/docs.go +++ b/pkg/api/server/docs.go @@ -13,7 +13,7 @@ // You can then use cURL on the socket using requests documented below. // // NOTE: if you install the package podman-docker, it will create a symbolic -// link for /var/run/docker.sock to /run/podman/podman.sock +// link for /run/docker.sock to /run/podman/podman.sock // // See podman-service(1) for more information. // diff --git a/pkg/api/server/register_networks.go b/pkg/api/server/register_networks.go index e6c85d244..967d7da76 100644 --- a/pkg/api/server/register_networks.go +++ b/pkg/api/server/register_networks.go @@ -9,6 +9,19 @@ import ( ) func (s *APIServer) registerNetworkHandlers(r *mux.Router) error { + // swagger:operation POST /networks/prune compat compatPruneNetwork + // --- + // tags: + // - networks (compat) + // Summary: Delete unused networks + // description: Not supported + // produces: + // - application/json + // responses: + // 404: + // $ref: "#/responses/NoSuchNetwork" + r.HandleFunc(VersionedPath("/networks/prune"), compat.UnsupportedHandler).Methods(http.MethodPost) + r.HandleFunc("/networks/prune", compat.UnsupportedHandler).Methods(http.MethodPost) // swagger:operation DELETE /networks/{name} compat compatRemoveNetwork // --- // tags: diff --git a/pkg/netns/netns_linux.go b/pkg/netns/netns_linux.go index ed5241632..6817a3abd 100644 --- a/pkg/netns/netns_linux.go +++ b/pkg/netns/netns_linux.go @@ -45,7 +45,7 @@ func getNSRunDir() (string, error) { } return filepath.Join(rootlessDir, "netns"), nil } - return "/var/run/netns", nil + return "/run/netns", nil } // NewNS creates a new persistent (bind-mounted) network namespace and returns @@ -80,7 +80,7 @@ func NewNS() (ns.NetNS, error) { return nil, fmt.Errorf("mount --make-rshared %s failed: %q", nsRunDir, err) } - // Recursively remount /var/run/netns on itself. The recursive flag is + // Recursively remount /run/netns on itself. The recursive flag is // so that any existing netns bindmounts are carried over. err = unix.Mount(nsRunDir, nsRunDir, "none", unix.MS_BIND|unix.MS_REC, "") if err != nil { diff --git a/pkg/rootless/rootless.go b/pkg/rootless/rootless.go index 799c793d8..df35c0d6b 100644 --- a/pkg/rootless/rootless.go +++ b/pkg/rootless/rootless.go @@ -2,10 +2,12 @@ package rootless import ( "os" + "sort" "sync" "github.com/containers/storage" "github.com/opencontainers/runc/libcontainer/user" + spec "github.com/opencontainers/runtime-spec/specs-go" "github.com/pkg/errors" ) @@ -50,24 +52,151 @@ func TryJoinPauseProcess(pausePidPath string) (bool, int, error) { } var ( - availableGids int64 - availableGidsErr error - availableGidsOnce sync.Once + uidMap []user.IDMap + uidMapError error + uidMapOnce sync.Once + + gidMap []user.IDMap + gidMapError error + gidMapOnce sync.Once ) -// GetAvailableGids returns how many GIDs are available in the +// GetAvailableUidMap returns the UID mappings in the // current user namespace. -func GetAvailableGids() (int64, error) { - availableGidsOnce.Do(func() { - idMap, err := user.ParseIDMapFile("/proc/self/gid_map") +func GetAvailableUidMap() ([]user.IDMap, error) { + uidMapOnce.Do(func() { + var err error + uidMap, err = user.ParseIDMapFile("/proc/self/uid_map") if err != nil { - availableGidsErr = err + uidMapError = err return } - availableGids = int64(0) - for _, r := range idMap { - availableGids += r.Count + }) + return uidMap, uidMapError +} + +// GetAvailableGidMap returns the GID mappings in the +// current user namespace. +func GetAvailableGidMap() ([]user.IDMap, error) { + gidMapOnce.Do(func() { + var err error + gidMap, err = user.ParseIDMapFile("/proc/self/gid_map") + if err != nil { + gidMapError = err + return } }) - return availableGids, availableGidsErr + return gidMap, gidMapError +} + +// GetAvailableIDMaps returns the UID and GID mappings in the +// current user namespace. +func GetAvailableIDMaps() ([]user.IDMap, []user.IDMap, error) { + u, err := GetAvailableUidMap() + if err != nil { + return nil, nil, err + } + g, err := GetAvailableGidMap() + if err != nil { + return nil, nil, err + } + return u, g, nil +} + +func countAvailableIDs(mappings []user.IDMap) int64 { + availableUids := int64(0) + for _, r := range mappings { + availableUids += r.Count + } + return availableUids +} + +// GetAvailableUids returns how many UIDs are available in the +// current user namespace. +func GetAvailableUids() (int64, error) { + uids, err := GetAvailableUidMap() + if err != nil { + return -1, err + } + + return countAvailableIDs(uids), nil +} + +// GetAvailableGids returns how many GIDs are available in the +// current user namespace. +func GetAvailableGids() (int64, error) { + gids, err := GetAvailableGidMap() + if err != nil { + return -1, err + } + + return countAvailableIDs(gids), nil +} + +// findIDInMappings find the the mapping that contains the specified ID. +// It assumes availableMappings is sorted by ID. +func findIDInMappings(id int64, availableMappings []user.IDMap) *user.IDMap { + i := sort.Search(len(availableMappings), func(i int) bool { + return availableMappings[i].ID >= id + }) + if i < 0 || i >= len(availableMappings) { + return nil + } + r := &availableMappings[i] + if id >= r.ID && id < r.ID+r.Count { + return r + } + return nil +} + +// MaybeSplitMappings checks whether the specified OCI mappings are possible +// in the current user namespace or the specified ranges must be split. +func MaybeSplitMappings(mappings []spec.LinuxIDMapping, availableMappings []user.IDMap) []spec.LinuxIDMapping { + var ret []spec.LinuxIDMapping + var overflow spec.LinuxIDMapping + overflow.Size = 0 + consumed := 0 + sort.Slice(availableMappings, func(i, j int) bool { + return availableMappings[i].ID < availableMappings[j].ID + }) + for { + cur := overflow + // if there is no overflow left from the previous request, get the next one + if cur.Size == 0 { + if consumed == len(mappings) { + // all done + return ret + } + cur = mappings[consumed] + consumed++ + } + + // Find the range where the first specified ID is present + r := findIDInMappings(int64(cur.HostID), availableMappings) + if r == nil { + // The requested range is not available. Just return the original request + // and let other layers deal with it. + return mappings + } + + offsetInRange := cur.HostID - uint32(r.ID) + + usableIDs := uint32(r.Count) - offsetInRange + + // the current range can satisfy the whole request + if usableIDs >= cur.Size { + // reset the overflow + overflow.Size = 0 + } else { + // the current range can satisfy the request partially + // so move the rest to overflow + overflow.Size = cur.Size - usableIDs + overflow.ContainerID = cur.ContainerID + usableIDs + overflow.HostID = cur.HostID + usableIDs + + // and cap to the usableIDs count + cur.Size = usableIDs + } + ret = append(ret, cur) + } } diff --git a/pkg/rootless/rootless_test.go b/pkg/rootless/rootless_test.go new file mode 100644 index 000000000..ef574099c --- /dev/null +++ b/pkg/rootless/rootless_test.go @@ -0,0 +1,101 @@ +package rootless + +import ( + "reflect" + "testing" + + "github.com/opencontainers/runc/libcontainer/user" + spec "github.com/opencontainers/runtime-spec/specs-go" +) + +func TestMaybeSplitMappings(t *testing.T) { + mappings := []spec.LinuxIDMapping{ + { + ContainerID: 0, + HostID: 0, + Size: 2, + }, + } + desiredMappings := []spec.LinuxIDMapping{ + { + ContainerID: 0, + HostID: 0, + Size: 1, + }, + { + ContainerID: 1, + HostID: 1, + Size: 1, + }, + } + availableMappings := []user.IDMap{ + { + ID: 1, + ParentID: 1000000, + Count: 65536, + }, + { + ID: 0, + ParentID: 1000, + Count: 1, + }, + } + newMappings := MaybeSplitMappings(mappings, availableMappings) + if !reflect.DeepEqual(newMappings, desiredMappings) { + t.Fatal("wrong mappings generated") + } + + mappings = []spec.LinuxIDMapping{ + { + ContainerID: 0, + HostID: 0, + Size: 2, + }, + } + desiredMappings = []spec.LinuxIDMapping{ + { + ContainerID: 0, + HostID: 0, + Size: 2, + }, + } + availableMappings = []user.IDMap{ + { + ID: 0, + ParentID: 1000000, + Count: 65536, + }, + } + newMappings = MaybeSplitMappings(mappings, availableMappings) + + if !reflect.DeepEqual(newMappings, desiredMappings) { + t.Fatal("wrong mappings generated") + } + + mappings = []spec.LinuxIDMapping{ + { + ContainerID: 0, + HostID: 0, + Size: 1, + }, + } + desiredMappings = []spec.LinuxIDMapping{ + { + ContainerID: 0, + HostID: 0, + Size: 1, + }, + } + availableMappings = []user.IDMap{ + { + ID: 10000, + ParentID: 10000, + Count: 65536, + }, + } + + newMappings = MaybeSplitMappings(mappings, availableMappings) + if !reflect.DeepEqual(newMappings, desiredMappings) { + t.Fatal("wrong mappings generated") + } +} diff --git a/pkg/signal/signal_linux_mipsx.go b/pkg/signal/signal_linux_mipsx.go index 67638e30a..45c9d5af1 100644 --- a/pkg/signal/signal_linux_mipsx.go +++ b/pkg/signal/signal_linux_mipsx.go @@ -19,6 +19,8 @@ import ( const ( sigrtmin = 34 sigrtmax = 127 + + SIGWINCH = syscall.SIGWINCH ) // signalMap is a map of Linux signals. diff --git a/pkg/specgen/generate/container.go b/pkg/specgen/generate/container.go index 42fea0277..c771e8bc8 100644 --- a/pkg/specgen/generate/container.go +++ b/pkg/specgen/generate/container.go @@ -282,8 +282,8 @@ func finishThrottleDevices(s *specgen.SpecGenerator) error { if err := unix.Stat(k, &statT); err != nil { return err } - v.Major = (int64(unix.Major(statT.Rdev))) - v.Minor = (int64(unix.Minor(statT.Rdev))) + v.Major = (int64(unix.Major(uint64(statT.Rdev)))) + v.Minor = (int64(unix.Minor(uint64(statT.Rdev)))) s.ResourceLimits.BlockIO.ThrottleReadBpsDevice = append(s.ResourceLimits.BlockIO.ThrottleReadBpsDevice, v) } } @@ -293,8 +293,8 @@ func finishThrottleDevices(s *specgen.SpecGenerator) error { if err := unix.Stat(k, &statT); err != nil { return err } - v.Major = (int64(unix.Major(statT.Rdev))) - v.Minor = (int64(unix.Minor(statT.Rdev))) + v.Major = (int64(unix.Major(uint64(statT.Rdev)))) + v.Minor = (int64(unix.Minor(uint64(statT.Rdev)))) s.ResourceLimits.BlockIO.ThrottleWriteBpsDevice = append(s.ResourceLimits.BlockIO.ThrottleWriteBpsDevice, v) } } @@ -304,8 +304,8 @@ func finishThrottleDevices(s *specgen.SpecGenerator) error { if err := unix.Stat(k, &statT); err != nil { return err } - v.Major = (int64(unix.Major(statT.Rdev))) - v.Minor = (int64(unix.Minor(statT.Rdev))) + v.Major = (int64(unix.Major(uint64(statT.Rdev)))) + v.Minor = (int64(unix.Minor(uint64(statT.Rdev)))) s.ResourceLimits.BlockIO.ThrottleReadIOPSDevice = append(s.ResourceLimits.BlockIO.ThrottleReadIOPSDevice, v) } } @@ -315,8 +315,8 @@ func finishThrottleDevices(s *specgen.SpecGenerator) error { if err := unix.Stat(k, &statT); err != nil { return err } - v.Major = (int64(unix.Major(statT.Rdev))) - v.Minor = (int64(unix.Minor(statT.Rdev))) + v.Major = (int64(unix.Major(uint64(statT.Rdev)))) + v.Minor = (int64(unix.Minor(uint64(statT.Rdev)))) s.ResourceLimits.BlockIO.ThrottleWriteIOPSDevice = append(s.ResourceLimits.BlockIO.ThrottleWriteIOPSDevice, v) } } diff --git a/pkg/specgen/generate/security.go b/pkg/specgen/generate/security.go index 9fceec7b3..390b19beb 100644 --- a/pkg/specgen/generate/security.go +++ b/pkg/specgen/generate/security.go @@ -133,13 +133,13 @@ func securityConfigureGenerator(s *specgen.SpecGenerator, g *generate.Generator, configSpec := g.Config configSpec.Process.Capabilities.Ambient = []string{} configSpec.Process.Capabilities.Bounding = caplist - configSpec.Process.Capabilities.Inheritable = caplist user := strings.Split(s.User, ":")[0] if (user == "" && s.UserNS.NSMode != specgen.KeepID) || user == "root" || user == "0" { configSpec.Process.Capabilities.Effective = caplist configSpec.Process.Capabilities.Permitted = caplist + configSpec.Process.Capabilities.Inheritable = caplist } else { userCaps, err := capabilities.MergeCapabilities(nil, s.CapAdd, nil) if err != nil { @@ -147,6 +147,7 @@ func securityConfigureGenerator(s *specgen.SpecGenerator, g *generate.Generator, } configSpec.Process.Capabilities.Effective = userCaps configSpec.Process.Capabilities.Permitted = userCaps + configSpec.Process.Capabilities.Inheritable = userCaps // Ambient capabilities were added to Linux 4.3. Set ambient // capabilities only when the kernel supports them. diff --git a/pkg/systemd/generate/containers_test.go b/pkg/systemd/generate/containers_test.go index b9fb8fee6..b8f3a90f9 100644 --- a/pkg/systemd/generate/containers_test.go +++ b/pkg/systemd/generate/containers_test.go @@ -53,7 +53,7 @@ TimeoutStopSec=82 ExecStart=/usr/bin/podman start 639c53578af4d84b8800b4635fa4e680ee80fd67e0e6a2d4eea48d1e3230f401 ExecStop=/usr/bin/podman stop -t 22 639c53578af4d84b8800b4635fa4e680ee80fd67e0e6a2d4eea48d1e3230f401 ExecStopPost=/usr/bin/podman stop -t 22 639c53578af4d84b8800b4635fa4e680ee80fd67e0e6a2d4eea48d1e3230f401 -PIDFile=/var/run/containers/storage/overlay-containers/639c53578af4d84b8800b4635fa4e680ee80fd67e0e6a2d4eea48d1e3230f401/userdata/conmon.pid +PIDFile=/run/containers/storage/overlay-containers/639c53578af4d84b8800b4635fa4e680ee80fd67e0e6a2d4eea48d1e3230f401/userdata/conmon.pid Type=forking [Install] @@ -76,7 +76,7 @@ TimeoutStopSec=70 ExecStart=/usr/bin/podman start foobar ExecStop=/usr/bin/podman stop -t 10 foobar ExecStopPost=/usr/bin/podman stop -t 10 foobar -PIDFile=/var/run/containers/storage/overlay-containers/639c53578af4d84b8800b4635fa4e680ee80fd67e0e6a2d4eea48d1e3230f401/userdata/conmon.pid +PIDFile=/run/containers/storage/overlay-containers/639c53578af4d84b8800b4635fa4e680ee80fd67e0e6a2d4eea48d1e3230f401/userdata/conmon.pid Type=forking [Install] @@ -101,7 +101,7 @@ TimeoutStopSec=70 ExecStart=/usr/bin/podman start foobar ExecStop=/usr/bin/podman stop -t 10 foobar ExecStopPost=/usr/bin/podman stop -t 10 foobar -PIDFile=/var/run/containers/storage/overlay-containers/639c53578af4d84b8800b4635fa4e680ee80fd67e0e6a2d4eea48d1e3230f401/userdata/conmon.pid +PIDFile=/run/containers/storage/overlay-containers/639c53578af4d84b8800b4635fa4e680ee80fd67e0e6a2d4eea48d1e3230f401/userdata/conmon.pid Type=forking [Install] @@ -242,7 +242,7 @@ WantedBy=multi-user.target default.target ServiceName: "container-639c53578af4d84b8800b4635fa4e680ee80fd67e0e6a2d4eea48d1e3230f401", ContainerNameOrID: "639c53578af4d84b8800b4635fa4e680ee80fd67e0e6a2d4eea48d1e3230f401", RestartPolicy: "always", - PIDFile: "/var/run/containers/storage/overlay-containers/639c53578af4d84b8800b4635fa4e680ee80fd67e0e6a2d4eea48d1e3230f401/userdata/conmon.pid", + PIDFile: "/run/containers/storage/overlay-containers/639c53578af4d84b8800b4635fa4e680ee80fd67e0e6a2d4eea48d1e3230f401/userdata/conmon.pid", StopTimeout: 22, PodmanVersion: "CI", EnvVariable: EnvVariable, @@ -257,7 +257,7 @@ WantedBy=multi-user.target default.target ServiceName: "container-foobar", ContainerNameOrID: "foobar", RestartPolicy: "always", - PIDFile: "/var/run/containers/storage/overlay-containers/639c53578af4d84b8800b4635fa4e680ee80fd67e0e6a2d4eea48d1e3230f401/userdata/conmon.pid", + PIDFile: "/run/containers/storage/overlay-containers/639c53578af4d84b8800b4635fa4e680ee80fd67e0e6a2d4eea48d1e3230f401/userdata/conmon.pid", StopTimeout: 10, PodmanVersion: "CI", EnvVariable: EnvVariable, @@ -272,7 +272,7 @@ WantedBy=multi-user.target default.target ServiceName: "container-foobar", ContainerNameOrID: "foobar", RestartPolicy: "always", - PIDFile: "/var/run/containers/storage/overlay-containers/639c53578af4d84b8800b4635fa4e680ee80fd67e0e6a2d4eea48d1e3230f401/userdata/conmon.pid", + PIDFile: "/run/containers/storage/overlay-containers/639c53578af4d84b8800b4635fa4e680ee80fd67e0e6a2d4eea48d1e3230f401/userdata/conmon.pid", StopTimeout: 10, PodmanVersion: "CI", BoundToServices: []string{"pod", "a", "b", "c"}, @@ -287,7 +287,7 @@ WantedBy=multi-user.target default.target Executable: "/usr/bin/podman", ServiceName: "639c53578af4d84b8800b4635fa4e680ee80fd67e0e6a2d4eea48d1e3230f401", RestartPolicy: "never", - PIDFile: "/var/run/containers/storage/overlay-containers/639c53578af4d84b8800b4635fa4e680ee80fd67e0e6a2d4eea48d1e3230f401/userdata/conmon.pid", + PIDFile: "/run/containers/storage/overlay-containers/639c53578af4d84b8800b4635fa4e680ee80fd67e0e6a2d4eea48d1e3230f401/userdata/conmon.pid", StopTimeout: 10, PodmanVersion: "CI", EnvVariable: EnvVariable, @@ -302,7 +302,7 @@ WantedBy=multi-user.target default.target ServiceName: "jadda-jadda", ContainerNameOrID: "jadda-jadda", RestartPolicy: "always", - PIDFile: "/var/run/containers/storage/overlay-containers/639c53578af4d84b8800b4635fa4e680ee80fd67e0e6a2d4eea48d1e3230f401/userdata/conmon.pid", + PIDFile: "/run/containers/storage/overlay-containers/639c53578af4d84b8800b4635fa4e680ee80fd67e0e6a2d4eea48d1e3230f401/userdata/conmon.pid", StopTimeout: 10, PodmanVersion: "CI", CreateCommand: []string{"I'll get stripped", "container", "run", "--name", "jadda-jadda", "--hostname", "hello-world", "awesome-image:latest", "command", "arg1", "...", "argN", "foo=arg \"with \" space"}, @@ -318,7 +318,7 @@ WantedBy=multi-user.target default.target ServiceName: "jadda-jadda", ContainerNameOrID: "jadda-jadda", RestartPolicy: "always", - PIDFile: "/var/run/containers/storage/overlay-containers/639c53578af4d84b8800b4635fa4e680ee80fd67e0e6a2d4eea48d1e3230f401/userdata/conmon.pid", + PIDFile: "/run/containers/storage/overlay-containers/639c53578af4d84b8800b4635fa4e680ee80fd67e0e6a2d4eea48d1e3230f401/userdata/conmon.pid", StopTimeout: 10, PodmanVersion: "CI", CreateCommand: []string{"I'll get stripped", "container", "run", "-d", "--name", "jadda-jadda", "--hostname", "hello-world", "awesome-image:latest", "command", "arg1", "...", "argN"}, @@ -334,7 +334,7 @@ WantedBy=multi-user.target default.target ServiceName: "jadda-jadda", ContainerNameOrID: "jadda-jadda", RestartPolicy: "always", - PIDFile: "/var/run/containers/storage/overlay-containers/639c53578af4d84b8800b4635fa4e680ee80fd67e0e6a2d4eea48d1e3230f401/userdata/conmon.pid", + PIDFile: "/run/containers/storage/overlay-containers/639c53578af4d84b8800b4635fa4e680ee80fd67e0e6a2d4eea48d1e3230f401/userdata/conmon.pid", StopTimeout: 10, PodmanVersion: "CI", CreateCommand: []string{"I'll get stripped", "container", "run", "-d", "--name", "jadda-jadda", "--hostname", "hello-world", "awesome-image:latest", "command", "arg1", "...", "argN"}, @@ -353,7 +353,7 @@ WantedBy=multi-user.target default.target ServiceName: "jadda-jadda", ContainerNameOrID: "jadda-jadda", RestartPolicy: "always", - PIDFile: "/var/run/containers/storage/overlay-containers/639c53578af4d84b8800b4635fa4e680ee80fd67e0e6a2d4eea48d1e3230f401/userdata/conmon.pid", + PIDFile: "/run/containers/storage/overlay-containers/639c53578af4d84b8800b4635fa4e680ee80fd67e0e6a2d4eea48d1e3230f401/userdata/conmon.pid", StopTimeout: 10, PodmanVersion: "CI", CreateCommand: []string{"I'll get stripped", "container", "run", "--detach", "--name", "jadda-jadda", "--hostname", "hello-world", "awesome-image:latest", "command", "arg1", "...", "argN"}, @@ -369,7 +369,7 @@ WantedBy=multi-user.target default.target ServiceName: "container-639c53578af4d84b8800b4635fa4e680ee80fd67e0e6a2d4eea48d1e3230f401", ContainerNameOrID: "639c53578af4d84b8800b4635fa4e680ee80fd67e0e6a2d4eea48d1e3230f401", RestartPolicy: "always", - PIDFile: "/var/run/containers/storage/overlay-containers/639c53578af4d84b8800b4635fa4e680ee80fd67e0e6a2d4eea48d1e3230f401/userdata/conmon.pid", + PIDFile: "/run/containers/storage/overlay-containers/639c53578af4d84b8800b4635fa4e680ee80fd67e0e6a2d4eea48d1e3230f401/userdata/conmon.pid", StopTimeout: 10, PodmanVersion: "CI", CreateCommand: []string{"I'll get stripped", "container", "run", "awesome-image:latest"}, diff --git a/pkg/systemd/generate/pods_test.go b/pkg/systemd/generate/pods_test.go index 6d925ecd2..93432ef96 100644 --- a/pkg/systemd/generate/pods_test.go +++ b/pkg/systemd/generate/pods_test.go @@ -55,7 +55,7 @@ TimeoutStopSec=102 ExecStart=/usr/bin/podman start jadda-jadda-infra ExecStop=/usr/bin/podman stop -t 42 jadda-jadda-infra ExecStopPost=/usr/bin/podman stop -t 42 jadda-jadda-infra -PIDFile=/var/run/containers/storage/overlay-containers/639c53578af4d84b8800b4635fa4e680ee80fd67e0e6a2d4eea48d1e3230f401/userdata/conmon.pid +PIDFile=/run/containers/storage/overlay-containers/639c53578af4d84b8800b4635fa4e680ee80fd67e0e6a2d4eea48d1e3230f401/userdata/conmon.pid Type=forking [Install] @@ -102,7 +102,7 @@ WantedBy=multi-user.target default.target ServiceName: "pod-123abc", InfraNameOrID: "jadda-jadda-infra", RestartPolicy: "always", - PIDFile: "/var/run/containers/storage/overlay-containers/639c53578af4d84b8800b4635fa4e680ee80fd67e0e6a2d4eea48d1e3230f401/userdata/conmon.pid", + PIDFile: "/run/containers/storage/overlay-containers/639c53578af4d84b8800b4635fa4e680ee80fd67e0e6a2d4eea48d1e3230f401/userdata/conmon.pid", StopTimeout: 42, PodmanVersion: "CI", RequiredServices: []string{"container-1", "container-2"}, @@ -117,7 +117,7 @@ WantedBy=multi-user.target default.target ServiceName: "pod-123abc", InfraNameOrID: "jadda-jadda-infra", RestartPolicy: "on-failure", - PIDFile: "/var/run/containers/storage/overlay-containers/639c53578af4d84b8800b4635fa4e680ee80fd67e0e6a2d4eea48d1e3230f401/userdata/conmon.pid", + PIDFile: "/run/containers/storage/overlay-containers/639c53578af4d84b8800b4635fa4e680ee80fd67e0e6a2d4eea48d1e3230f401/userdata/conmon.pid", StopTimeout: 10, PodmanVersion: "CI", RequiredServices: []string{"container-1", "container-2"}, diff --git a/test/apiv2/rest_api/test_rest_v2_0_0.py b/test/apiv2/rest_api/test_rest_v2_0_0.py index 2f9e62149..cc66dd5af 100644 --- a/test/apiv2/rest_api/test_rest_v2_0_0.py +++ b/test/apiv2/rest_api/test_rest_v2_0_0.py @@ -1,13 +1,15 @@ import json +import os import random +import shutil import string import subprocess +import sys +import time import unittest from multiprocessing import Process import requests -import sys -import time from dateutil.parser import parse from test.apiv2.rest_api import Podman @@ -449,7 +451,7 @@ class TestApi(unittest.TestCase): self.assertEqual(inspect.status_code, 404, inspect.content) prune = requests.post(PODMAN_URL + "/v1.40/networks/prune") - self.assertEqual(prune.status_code, 405, prune.content) + self.assertEqual(prune.status_code, 404, prune.content) def test_volumes_compat(self): name = "Volume_" + "".join(random.choice(string.ascii_letters) for i in range(10)) @@ -499,8 +501,18 @@ class TestApi(unittest.TestCase): rm = requests.delete(PODMAN_URL + f"/v1.40/volumes/{name}") self.assertEqual(rm.status_code, 204, rm.content) + # recreate volume with data and then prune it + r = requests.post(PODMAN_URL + "/v1.40/volumes/create", json={"Name": name}) + self.assertEqual(create.status_code, 201, create.content) + create = json.loads(r.content) + with open(os.path.join(create["Mountpoint"], "test_prune"), "w") as file: + file.writelines(["This is a test\n", "This is a good test\n"]) + prune = requests.post(PODMAN_URL + "/v1.40/volumes/prune") self.assertEqual(prune.status_code, 200, prune.content) + payload = json.loads(prune.content) + self.assertIn(name, payload["VolumesDeleted"]) + self.assertGreater(payload["SpaceReclaimed"], 0) def test_auth_compat(self): r = requests.post( @@ -530,6 +542,50 @@ class TestApi(unittest.TestCase): self.assertIn("Volumes", obj) self.assertIn("BuildCache", obj) + def test_prune_compat(self): + name = "Ctnr_" + "".join(random.choice(string.ascii_letters) for i in range(10)) + + r = requests.post( + PODMAN_URL + f"/v1.40/containers/create?name={name}", + json={ + "Cmd": ["cp", "/etc/motd", "/motd.size_test"], + "Image": "alpine:latest", + "NetworkDisabled": True, + }, + ) + self.assertEqual(r.status_code, 201, r.text) + create = json.loads(r.text) + + r = requests.post(PODMAN_URL + f"/v1.40/containers/{create['Id']}/start") + self.assertEqual(r.status_code, 204, r.text) + + r = requests.post(PODMAN_URL + f"/v1.40/containers/{create['Id']}/wait") + self.assertEqual(r.status_code, 200, r.text) + wait = json.loads(r.text) + self.assertEqual(wait["StatusCode"], 0, wait["Error"]["Message"]) + + prune = requests.post(PODMAN_URL + "/v1.40/containers/prune") + self.assertEqual(prune.status_code, 200, prune.status_code) + prune_payload = json.loads(prune.text) + self.assertGreater(prune_payload["SpaceReclaimed"], 0) + self.assertIn(create["Id"], prune_payload["ContainersDeleted"]) + + # Delete any orphaned containers + r = requests.get(PODMAN_URL + "/v1.40/containers/json?all=true") + self.assertEqual(r.status_code, 200, r.text) + for ctnr in json.loads(r.text): + requests.delete(PODMAN_URL + f"/v1.40/containers/{ctnr['Id']}?force=true") + + prune = requests.post(PODMAN_URL + "/v1.40/images/prune") + self.assertEqual(prune.status_code, 200, prune.text) + prune_payload = json.loads(prune.text) + self.assertGreater(prune_payload["SpaceReclaimed"], 0) + + # FIXME need method to determine which image is going to be "pruned" to fix test + # TODO should handler be recursive when deleting images? + # self.assertIn(img["Id"], prune_payload["ImagesDeleted"][1]["Deleted"]) + self.assertIsNotNone(prune_payload["ImagesDeleted"][1]["Deleted"]) + if __name__ == "__main__": unittest.main() diff --git a/test/e2e/common_test.go b/test/e2e/common_test.go index a076ada6b..18679dd53 100644 --- a/test/e2e/common_test.go +++ b/test/e2e/common_test.go @@ -378,10 +378,17 @@ func GetRandomIPAddress() string { // RunTopContainer runs a simple container in the background that // runs top. If the name passed != "", it will have a name func (p *PodmanTestIntegration) RunTopContainer(name string) *PodmanSessionIntegration { + return p.RunTopContainerWithArgs(name, nil) +} + +// RunTopContainerWithArgs runs a simple container in the background that +// runs top. If the name passed != "", it will have a name, command args can also be passed in +func (p *PodmanTestIntegration) RunTopContainerWithArgs(name string, args []string) *PodmanSessionIntegration { var podmanArgs = []string{"run"} if name != "" { podmanArgs = append(podmanArgs, "--name", name) } + podmanArgs = append(podmanArgs, args...) podmanArgs = append(podmanArgs, "-d", ALPINE, "top") return p.Podman(podmanArgs) } @@ -538,12 +545,7 @@ func (p *PodmanTestIntegration) CreatePodWithLabels(name string, labels map[stri } func (p *PodmanTestIntegration) RunTopContainerInPod(name, pod string) *PodmanSessionIntegration { - var podmanArgs = []string{"run", "--pod", pod} - if name != "" { - podmanArgs = append(podmanArgs, "--name", name) - } - podmanArgs = append(podmanArgs, "-d", ALPINE, "top") - return p.Podman(podmanArgs) + return p.RunTopContainerWithArgs(name, []string{"--pod", pod}) } func (p *PodmanTestIntegration) RunHealthCheck(cid string) error { diff --git a/test/e2e/exec_test.go b/test/e2e/exec_test.go index 18737105e..b180d881a 100644 --- a/test/e2e/exec_test.go +++ b/test/e2e/exec_test.go @@ -120,18 +120,200 @@ var _ = Describe("Podman exec", func() { }) It("podman exec --privileged", func() { - hostCap := SystemExec("awk", []string{"/^CapEff/ { print $2 }", "/proc/self/status"}) - Expect(hostCap.ExitCode()).To(Equal(0)) + session := podmanTest.Podman([]string{"run", "--privileged", "--rm", ALPINE, "sh", "-c", "grep ^CapBnd /proc/self/status | cut -f 2"}) + session.WaitWithDefaultTimeout() + Expect(session.ExitCode()).To(Equal(0)) + bndPerms := session.OutputToString() + + session = podmanTest.Podman([]string{"run", "--privileged", "--rm", ALPINE, "sh", "-c", "grep ^CapEff /proc/self/status | cut -f 2"}) + session.WaitWithDefaultTimeout() + Expect(session.ExitCode()).To(Equal(0)) + effPerms := session.OutputToString() + + setup := podmanTest.RunTopContainer("test-privileged") + setup.WaitWithDefaultTimeout() + Expect(setup.ExitCode()).To(Equal(0)) + + session = podmanTest.Podman([]string{"exec", "--privileged", "test-privileged", "sh", "-c", "grep ^CapEff /proc/self/status | cut -f 2"}) + session.WaitWithDefaultTimeout() + Expect(session.ExitCode()).To(Equal(0)) + Expect(session.OutputToString()).To(ContainSubstring(effPerms)) + + session = podmanTest.Podman([]string{"exec", "--privileged", "test-privileged", "sh", "-c", "grep ^CapBnd /proc/self/status | cut -f 2"}) + session.WaitWithDefaultTimeout() + Expect(session.ExitCode()).To(Equal(0)) + Expect(session.OutputToString()).To(ContainSubstring(bndPerms)) + + }) + + It("podman exec --privileged", func() { + session := podmanTest.Podman([]string{"run", "--privileged", "--user=bin", "--rm", ALPINE, "sh", "-c", "grep ^CapBnd /proc/self/status | cut -f 2"}) + session.WaitWithDefaultTimeout() + Expect(session.ExitCode()).To(Equal(0)) + bndPerms := session.OutputToString() + + session = podmanTest.Podman([]string{"run", "--privileged", "--user=bin", "--rm", ALPINE, "sh", "-c", "grep ^CapEff /proc/self/status | cut -f 2"}) + session.WaitWithDefaultTimeout() + Expect(session.ExitCode()).To(Equal(0)) + effPerms := session.OutputToString() + + setup := podmanTest.RunTopContainer("test-privileged") + setup.WaitWithDefaultTimeout() + Expect(setup.ExitCode()).To(Equal(0)) + + session = podmanTest.Podman([]string{"exec", "--privileged", "--user=bin", "test-privileged", "sh", "-c", "grep ^CapEff /proc/self/status | cut -f 2"}) + session.WaitWithDefaultTimeout() + Expect(session.ExitCode()).To(Equal(0)) + Expect(session.OutputToString()).To(ContainSubstring(effPerms)) + + session = podmanTest.Podman([]string{"exec", "--privileged", "--user=bin", "test-privileged", "sh", "-c", "grep ^CapBnd /proc/self/status | cut -f 2"}) + session.WaitWithDefaultTimeout() + Expect(session.ExitCode()).To(Equal(0)) + Expect(session.OutputToString()).To(ContainSubstring(bndPerms)) + + }) + + It("podman exec --privileged", func() { + session := podmanTest.Podman([]string{"run", "--privileged", "--rm", ALPINE, "sh", "-c", "grep ^CapBnd /proc/self/status | cut -f 2"}) + session.WaitWithDefaultTimeout() + Expect(session.ExitCode()).To(Equal(0)) + bndPerms := session.OutputToString() setup := podmanTest.RunTopContainer("test-privileged") setup.WaitWithDefaultTimeout() Expect(setup.ExitCode()).To(Equal(0)) - session := podmanTest.Podman([]string{"exec", "--privileged", "test-privileged", "sh", "-c", "grep ^CapEff /proc/self/status | cut -f 2"}) + session = podmanTest.Podman([]string{"exec", "--privileged", "--user=bin", "test-privileged", "sh", "-c", "grep ^CapEff /proc/self/status | cut -f 2"}) session.WaitWithDefaultTimeout() Expect(session.ExitCode()).To(Equal(0)) + Expect(session.OutputToString()).To(ContainSubstring("00000000")) + + session = podmanTest.Podman([]string{"exec", "--privileged", "--user=bin", "test-privileged", "sh", "-c", "grep ^CapBnd /proc/self/status | cut -f 2"}) + session.WaitWithDefaultTimeout() + Expect(session.ExitCode()).To(Equal(0)) + Expect(session.OutputToString()).To(ContainSubstring(bndPerms)) + }) - containerCapMatchesHost(session.OutputToString(), hostCap.OutputToString()) + It("podman exec --privileged container not running as root", func() { + session := podmanTest.Podman([]string{"run", "--privileged", "--rm", ALPINE, "sh", "-c", "grep ^CapBnd /proc/self/status | cut -f 2"}) + session.WaitWithDefaultTimeout() + Expect(session.ExitCode()).To(Equal(0)) + bndPerms := session.OutputToString() + + setup := podmanTest.RunTopContainerWithArgs("test-privileged", []string{"--user=bin"}) + setup.WaitWithDefaultTimeout() + Expect(setup.ExitCode()).To(Equal(0)) + + session = podmanTest.Podman([]string{"exec", "--privileged", "test-privileged", "sh", "-c", "grep ^CapEff /proc/self/status | cut -f 2"}) + session.WaitWithDefaultTimeout() + Expect(session.ExitCode()).To(Equal(0)) + Expect(session.OutputToString()).To(ContainSubstring("00000000")) + + session = podmanTest.Podman([]string{"exec", "--privileged", "--user=bin", "test-privileged", "sh", "-c", "grep ^CapEff /proc/self/status | cut -f 2"}) + session.WaitWithDefaultTimeout() + Expect(session.ExitCode()).To(Equal(0)) + Expect(session.OutputToString()).To(ContainSubstring("00000000")) + + session = podmanTest.Podman([]string{"exec", "--privileged", "--user=root", "test-privileged", "sh", "-c", "grep ^CapEff /proc/self/status | cut -f 2"}) + session.WaitWithDefaultTimeout() + Expect(session.ExitCode()).To(Equal(0)) + Expect(session.OutputToString()).To(ContainSubstring(bndPerms)) + + session = podmanTest.Podman([]string{"exec", "--privileged", "--user=bin", "test-privileged", "sh", "-c", "grep ^CapBnd /proc/self/status | cut -f 2"}) + session.WaitWithDefaultTimeout() + Expect(session.ExitCode()).To(Equal(0)) + Expect(session.OutputToString()).To(ContainSubstring(bndPerms)) + }) + + It("podman exec with user with cap-add", func() { + capAdd := "--cap-add=net_bind_service" + session := podmanTest.Podman([]string{"run", "--user=bin", capAdd, "--rm", ALPINE, "sh", "-c", "grep ^CapBnd /proc/self/status | cut -f 2"}) + session.WaitWithDefaultTimeout() + Expect(session.ExitCode()).To(Equal(0)) + bndPerms := session.OutputToString() + + session = podmanTest.Podman([]string{"run", "--user=bin", capAdd, "--rm", ALPINE, "sh", "-c", "grep ^CapEff /proc/self/status | cut -f 2"}) + session.WaitWithDefaultTimeout() + Expect(session.ExitCode()).To(Equal(0)) + effPerms := session.OutputToString() + + setup := podmanTest.RunTopContainerWithArgs("test-privileged", []string{"--user=bin", capAdd}) + setup.WaitWithDefaultTimeout() + Expect(setup.ExitCode()).To(Equal(0)) + + session = podmanTest.Podman([]string{"exec", "test-privileged", "sh", "-c", "grep ^CapBnd /proc/self/status | cut -f 2"}) + session.WaitWithDefaultTimeout() + Expect(session.ExitCode()).To(Equal(0)) + Expect(session.OutputToString()).To(ContainSubstring(bndPerms)) + + session = podmanTest.Podman([]string{"exec", "test-privileged", "sh", "-c", "grep ^CapEff /proc/self/status | cut -f 2"}) + session.WaitWithDefaultTimeout() + Expect(session.ExitCode()).To(Equal(0)) + Expect(session.OutputToString()).To(ContainSubstring(effPerms)) + }) + + It("podman exec with user with and cap-drop cap-add", func() { + capAdd := "--cap-add=net_bind_service" + capDrop := "--cap-drop=all" + session := podmanTest.Podman([]string{"run", "--user=bin", capDrop, capAdd, "--rm", ALPINE, "sh", "-c", "grep ^CapBnd /proc/self/status | cut -f 2"}) + session.WaitWithDefaultTimeout() + Expect(session.ExitCode()).To(Equal(0)) + bndPerms := session.OutputToString() + + session = podmanTest.Podman([]string{"run", "--user=bin", capDrop, capAdd, "--rm", ALPINE, "sh", "-c", "grep ^CapEff /proc/self/status | cut -f 2"}) + session.WaitWithDefaultTimeout() + Expect(session.ExitCode()).To(Equal(0)) + effPerms := session.OutputToString() + + setup := podmanTest.RunTopContainerWithArgs("test-privileged", []string{"--user=bin", capDrop, capAdd}) + setup.WaitWithDefaultTimeout() + Expect(setup.ExitCode()).To(Equal(0)) + + session = podmanTest.Podman([]string{"exec", "test-privileged", "sh", "-c", "grep ^CapBnd /proc/self/status | cut -f 2"}) + session.WaitWithDefaultTimeout() + Expect(session.ExitCode()).To(Equal(0)) + Expect(session.OutputToString()).To(ContainSubstring(bndPerms)) + + session = podmanTest.Podman([]string{"exec", "--privileged", "test-privileged", "sh", "-c", "grep ^CapInh /proc/self/status | cut -f 2"}) + session.WaitWithDefaultTimeout() + Expect(session.ExitCode()).To(Equal(0)) + Expect(session.OutputToString()).To(ContainSubstring(effPerms)) + + session = podmanTest.Podman([]string{"exec", "test-privileged", "sh", "-c", "grep ^CapEff /proc/self/status | cut -f 2"}) + session.WaitWithDefaultTimeout() + Expect(session.ExitCode()).To(Equal(0)) + Expect(session.OutputToString()).To(ContainSubstring(effPerms)) + + session = podmanTest.Podman([]string{"exec", "test-privileged", "sh", "-c", "grep ^CapPrm /proc/self/status | cut -f 2"}) + session.WaitWithDefaultTimeout() + Expect(session.ExitCode()).To(Equal(0)) + Expect(session.OutputToString()).To(ContainSubstring(effPerms)) + + session = podmanTest.Podman([]string{"exec", "test-privileged", "sh", "-c", "grep ^CapAmb /proc/self/status | cut -f 2"}) + session.WaitWithDefaultTimeout() + Expect(session.ExitCode()).To(Equal(0)) + Expect(session.OutputToString()).To(ContainSubstring(effPerms)) + }) + + It("podman exec --privileged with user", func() { + session := podmanTest.Podman([]string{"run", "--privileged", "--user=bin", "--rm", ALPINE, "sh", "-c", "grep ^CapBnd /proc/self/status | cut -f 2"}) + session.WaitWithDefaultTimeout() + Expect(session.ExitCode()).To(Equal(0)) + bindPerms := session.OutputToString() + + setup := podmanTest.RunTopContainerWithArgs("test-privileged", []string{"--privileged", "--user=bin"}) + setup.WaitWithDefaultTimeout() + Expect(setup.ExitCode()).To(Equal(0)) + + session = podmanTest.Podman([]string{"exec", "--privileged", "test-privileged", "sh", "-c", "grep ^CapBnd /proc/self/status | cut -f 2"}) + session.WaitWithDefaultTimeout() + Expect(session.ExitCode()).To(Equal(0)) + Expect(session.OutputToString()).To(ContainSubstring(bindPerms)) + + session = podmanTest.Podman([]string{"exec", "--privileged", "test-privileged", "sh", "-c", "grep ^CapEff /proc/self/status | cut -f 2"}) + session.WaitWithDefaultTimeout() + Expect(session.ExitCode()).To(Equal(0)) + Expect(session.OutputToString()).To(ContainSubstring("0000000000000000")) }) It("podman exec terminal doesn't hang", func() { diff --git a/test/e2e/run_test.go b/test/e2e/run_test.go index 92d7d222e..19060ecdc 100644 --- a/test/e2e/run_test.go +++ b/test/e2e/run_test.go @@ -342,6 +342,11 @@ var _ = Describe("Podman run", func() { Expect(session.ExitCode()).To(Equal(0)) Expect(session.OutputToString()).To(ContainSubstring("0000000000000000")) + session = podmanTest.Podman([]string{"run", "--rm", "--user", "bin", ALPINE, "grep", "CapInh", "/proc/self/status"}) + session.WaitWithDefaultTimeout() + Expect(session.ExitCode()).To(Equal(0)) + Expect(session.OutputToString()).To(ContainSubstring("0000000000000000")) + session = podmanTest.Podman([]string{"run", "--rm", "--user", "root", ALPINE, "grep", "CapBnd", "/proc/self/status"}) session.WaitWithDefaultTimeout() Expect(session.ExitCode()).To(Equal(0)) @@ -352,6 +357,11 @@ var _ = Describe("Podman run", func() { Expect(session.ExitCode()).To(Equal(0)) Expect(session.OutputToString()).To(ContainSubstring("00000000a80425fb")) + session = podmanTest.Podman([]string{"run", "--rm", "--user", "root", ALPINE, "grep", "CapInh", "/proc/self/status"}) + session.WaitWithDefaultTimeout() + Expect(session.ExitCode()).To(Equal(0)) + Expect(session.OutputToString()).To(ContainSubstring("00000000a80425fb")) + session = podmanTest.Podman([]string{"run", "--rm", ALPINE, "grep", "CapBnd", "/proc/self/status"}) session.WaitWithDefaultTimeout() Expect(session.ExitCode()).To(Equal(0)) @@ -367,10 +377,10 @@ var _ = Describe("Podman run", func() { Expect(session.ExitCode()).To(Equal(0)) Expect(session.OutputToString()).To(ContainSubstring("0000000000000002")) - session = podmanTest.Podman([]string{"run", "--user=1000:1000", "--rm", ALPINE, "grep", "CapAmb", "/proc/self/status"}) + session = podmanTest.Podman([]string{"run", "--user=1000:1000", "--cap-add=DAC_OVERRIDE", "--rm", ALPINE, "grep", "CapInh", "/proc/self/status"}) session.WaitWithDefaultTimeout() Expect(session.ExitCode()).To(Equal(0)) - Expect(session.OutputToString()).To(ContainSubstring("0000000000000000")) + Expect(session.OutputToString()).To(ContainSubstring("0000000000000002")) session = podmanTest.Podman([]string{"run", "--user=0", "--cap-add=DAC_OVERRIDE", "--rm", ALPINE, "grep", "CapAmb", "/proc/self/status"}) session.WaitWithDefaultTimeout() @@ -382,6 +392,11 @@ var _ = Describe("Podman run", func() { Expect(session.ExitCode()).To(Equal(0)) Expect(session.OutputToString()).To(ContainSubstring("0000000000000000")) + session = podmanTest.Podman([]string{"run", "--user=0:0", "--cap-add=DAC_OVERRIDE", "--rm", ALPINE, "grep", "CapInh", "/proc/self/status"}) + session.WaitWithDefaultTimeout() + Expect(session.ExitCode()).To(Equal(0)) + Expect(session.OutputToString()).To(ContainSubstring("00000000a80425fb")) + if os.Geteuid() > 0 { if os.Getenv("SKIP_USERNS") != "" { Skip("Skip userns tests.") @@ -393,6 +408,16 @@ var _ = Describe("Podman run", func() { session.WaitWithDefaultTimeout() Expect(session.ExitCode()).To(Equal(0)) Expect(session.OutputToString()).To(ContainSubstring("0000000000000002")) + + session = podmanTest.Podman([]string{"run", "--userns=keep-id", "--privileged", "--rm", ALPINE, "grep", "CapInh", "/proc/self/status"}) + session.WaitWithDefaultTimeout() + Expect(session.ExitCode()).To(Equal(0)) + Expect(session.OutputToString()).To(ContainSubstring("0000000000000000")) + + session = podmanTest.Podman([]string{"run", "--userns=keep-id", "--cap-add=DAC_OVERRIDE", "--rm", ALPINE, "grep", "CapInh", "/proc/self/status"}) + session.WaitWithDefaultTimeout() + Expect(session.ExitCode()).To(Equal(0)) + Expect(session.OutputToString()).To(ContainSubstring("0000000000000002")) } }) diff --git a/test/system/400-unprivileged-access.bats b/test/system/400-unprivileged-access.bats index 20fdd068f..6a89247e6 100644 --- a/test/system/400-unprivileged-access.bats +++ b/test/system/400-unprivileged-access.bats @@ -75,7 +75,7 @@ EOF is "$output" "/var/lib/containers/storage" "GraphRoot in expected place" GRAPH_ROOT="$output" run_podman info --format '{{.Store.RunRoot}}' - is "$output" "/var/run/containers/storage" "RunRoot in expected place" + is "$output" ".*/run/containers/storage" "RunRoot in expected place" RUN_ROOT="$output" # The main test: find all world-writable files or directories underneath diff --git a/troubleshooting.md b/troubleshooting.md index 78e22fa2f..c028a7714 100644 --- a/troubleshooting.md +++ b/troubleshooting.md @@ -344,7 +344,7 @@ After creating a container with Podman's storage directories mounted in from the When running Podman inside a container, it is recommended to mount at a minimum `/var/lib/containers/storage/` as a volume. Typically, you will not mount in the host version of the directory, but if you wish to share containers with the host, you can do so. -If you do mount in the host's `/var/lib/containers/storage`, however, you must also mount in the host's `/var/run/libpod` and `/var/run/containers/storage` directories. +If you do mount in the host's `/var/lib/containers/storage`, however, you must also mount in the host's `/run/libpod` and `/run/containers/storage` directories. Not doing this will cause Podman in the container to detect that temporary files have been cleared, leading it to assume a system restart has taken place. This can cause Podman to reset container states and lose track of running containers. diff --git a/vendor/github.com/containers/buildah/Makefile b/vendor/github.com/containers/buildah/Makefile index 45f8a8ec8..2768a2917 100644 --- a/vendor/github.com/containers/buildah/Makefile +++ b/vendor/github.com/containers/buildah/Makefile @@ -1,9 +1,8 @@ export GOPROXY=https://proxy.golang.org -SELINUXTAG := $(shell ./selinux_tag.sh) APPARMORTAG := $(shell hack/apparmor_tag.sh) STORAGETAGS := $(shell ./btrfs_tag.sh) $(shell ./btrfs_installed_tag.sh) $(shell ./libdm_tag.sh) -SECURITYTAGS ?= seccomp $(SELINUXTAG) $(APPARMORTAG) +SECURITYTAGS ?= seccomp $(APPARMORTAG) TAGS ?= $(SECURITYTAGS) $(STORAGETAGS) BUILDTAGS += $(TAGS) PREFIX := /usr/local @@ -52,7 +51,7 @@ all: bin/buildah bin/imgtype docs # Update nix/nixpkgs.json its latest stable commit .PHONY: nixpkgs nixpkgs: - @nix run -f channel:nixos-20.03 nix-prefetch-git -c nix-prefetch-git \ + @nix run -f channel:nixos-20.09 nix-prefetch-git -c nix-prefetch-git \ --no-deepClone https://github.com/nixos/nixpkgs > nix/nixpkgs.json # Build statically linked binary diff --git a/vendor/github.com/containers/buildah/chroot/selinux.go b/vendor/github.com/containers/buildah/chroot/selinux.go index 08e8f998b..ef96a0e7a 100644 --- a/vendor/github.com/containers/buildah/chroot/selinux.go +++ b/vendor/github.com/containers/buildah/chroot/selinux.go @@ -1,4 +1,4 @@ -// +build linux,selinux +// +build linux package chroot diff --git a/vendor/github.com/containers/buildah/chroot/selinux_unsupported.go b/vendor/github.com/containers/buildah/chroot/selinux_unsupported.go index 1c6f48912..41d2b86be 100644 --- a/vendor/github.com/containers/buildah/chroot/selinux_unsupported.go +++ b/vendor/github.com/containers/buildah/chroot/selinux_unsupported.go @@ -1,4 +1,4 @@ -// +build !linux !selinux +// +build !linux package chroot diff --git a/vendor/github.com/containers/buildah/go.mod b/vendor/github.com/containers/buildah/go.mod index ea9a956be..b5e2bc595 100644 --- a/vendor/github.com/containers/buildah/go.mod +++ b/vendor/github.com/containers/buildah/go.mod @@ -5,8 +5,8 @@ go 1.12 require ( github.com/containerd/containerd v1.4.1 // indirect github.com/containernetworking/cni v0.7.2-0.20190904153231-83439463f784 - github.com/containers/common v0.31.0 - github.com/containers/image/v5 v5.8.1 + github.com/containers/common v0.31.1 + github.com/containers/image/v5 v5.9.0 github.com/containers/ocicrypt v1.0.3 github.com/containers/storage v1.24.3 github.com/docker/distribution v2.7.1+incompatible @@ -27,7 +27,7 @@ require ( github.com/opencontainers/runc v1.0.0-rc91 github.com/opencontainers/runtime-spec v1.0.3-0.20200710190001-3e4195d92445 github.com/opencontainers/runtime-tools v0.9.0 - github.com/opencontainers/selinux v1.6.0 + github.com/opencontainers/selinux v1.8.0 github.com/openshift/imagebuilder v1.1.8 github.com/pkg/errors v0.9.1 github.com/seccomp/libseccomp-golang v0.9.2-0.20200616122406-847368b35ebf diff --git a/vendor/github.com/containers/buildah/go.sum b/vendor/github.com/containers/buildah/go.sum index c2082c5ef..c6c6f3c42 100644 --- a/vendor/github.com/containers/buildah/go.sum +++ b/vendor/github.com/containers/buildah/go.sum @@ -73,17 +73,15 @@ github.com/containerd/ttrpc v0.0.0-20190828154514-0e0f228740de/go.mod h1:PvCDdDG github.com/containerd/typeurl v0.0.0-20180627222232-a93fcdb778cd/go.mod h1:Cm3kwCdlkCfMSHURc+r6fwoGH6/F1hH3S4sg0rLFWPc= github.com/containernetworking/cni v0.7.2-0.20190904153231-83439463f784 h1:rqUVLD8I859xRgUx/WMC3v7QAFqbLKZbs+0kqYboRJc= github.com/containernetworking/cni v0.7.2-0.20190904153231-83439463f784/go.mod h1:LGwApLUm2FpoOfxTDEeq8T9ipbpZ61X79hmU3w8FmsY= -github.com/containers/common v0.31.0 h1:SRnjfoqbjfaojpY9YJq9JBPEslwB5hoXJbaE+5zMFwM= -github.com/containers/common v0.31.0/go.mod h1:yT4GTUHsKRmpaDb+mecXRnIMre7W3ZgwXqaYMywXlaA= -github.com/containers/image/v5 v5.8.1 h1:aHW8a/Kd0dTJ7PTL/fc6y12sJqHxWgqilu+XyHfjD8Q= -github.com/containers/image/v5 v5.8.1/go.mod h1:blOEFd/iFdeyh891ByhCVUc+xAcaI3gBegXECwz9UbQ= +github.com/containers/common v0.31.1 h1:oBINnZpYZ2u90HPMnVCXOhm/TsTaTB7wU/56l05hq44= +github.com/containers/common v0.31.1/go.mod h1:Fehe82hQfJQvDspnRrV9rcdAWG3IalNHEt0F6QWNBHQ= +github.com/containers/image/v5 v5.9.0 h1:dRmUtcluQcmasNo3DpnRoZjfU0rOu1qZeL6wlDJr10Q= +github.com/containers/image/v5 v5.9.0/go.mod h1:blOEFd/iFdeyh891ByhCVUc+xAcaI3gBegXECwz9UbQ= github.com/containers/libtrust v0.0.0-20190913040956-14b96171aa3b h1:Q8ePgVfHDplZ7U33NwHZkrVELsZP5fYj9pM5WBZB2GE= github.com/containers/libtrust v0.0.0-20190913040956-14b96171aa3b/go.mod h1:9rfv8iPl1ZP7aqh9YA68wnZv2NUDbXdcdPHVz0pFbPY= github.com/containers/ocicrypt v1.0.3 h1:vYgl+RZ9Q3DPMuTfxmN+qp0X2Bj52uuY2vnt6GzVe1c= github.com/containers/ocicrypt v1.0.3/go.mod h1:CUBa+8MRNL/VkpxYIpaMtgn1WgXGyvPQj8jcy0EVG6g= github.com/containers/storage v1.23.7/go.mod h1:cUT2zHjtx+WlVri30obWmM2gpqpi8jfPsmIzP1TVpEI= -github.com/containers/storage v1.24.1 h1:1+f8fy6ly35c8SLet5jzZ8t0WJJs5+xSpfMAYw0R3kc= -github.com/containers/storage v1.24.1/go.mod h1:0xJL06Dmd+ZYXIUdnBUPN0JnhHGgwMkLvnnAonJfWJU= github.com/containers/storage v1.24.3 h1:8UB4S62l4hrU6Yw3dbsLCJtLg7Ofo39IN2HdckBIX4E= github.com/containers/storage v1.24.3/go.mod h1:0xJL06Dmd+ZYXIUdnBUPN0JnhHGgwMkLvnnAonJfWJU= github.com/coreos/bbolt v1.3.2/go.mod h1:iRUV2dpdMOn7Bo10OQBFzIJO9kkE559Wcmn+qkEiiKk= @@ -303,8 +301,6 @@ github.com/onsi/ginkgo v1.14.2/go.mod h1:iSB4RoI2tjJc9BBv4NKIKWKya62Rps+oPG/Lv9k github.com/onsi/gomega v1.7.0/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY= github.com/onsi/gomega v1.7.1/go.mod h1:XdKZgCCFLUoM/7CFJVPcG8C1xQ1AJ0vpAezJrB7JYyY= github.com/onsi/gomega v1.10.1/go.mod h1:iN09h71vgCQne3DLsj+A5owkum+a2tYe+TOCB1ybHNo= -github.com/onsi/gomega v1.10.3 h1:gph6h/qe9GSUw1NhH1gp+qb+h8rXD8Cy60Z32Qw3ELA= -github.com/onsi/gomega v1.10.3/go.mod h1:V9xEwhxec5O8UDM77eCW8vLymOMltsqPVYWrpDsH8xc= github.com/onsi/gomega v1.10.4 h1:NiTx7EEvBzu9sFOD1zORteLSt3o8gnlvZZwSE9TnY9U= github.com/onsi/gomega v1.10.4/go.mod h1:g/HbgYopi++010VEqkFgJHKC09uJiW9UkXvMUuKHUCQ= github.com/opencontainers/go-digest v0.0.0-20180430190053-c9281466c8b2/go.mod h1:cMLVZDEM3+U2I4VmLI6N8jQYUd2OVphdqWwCJHrFt2s= @@ -327,6 +323,8 @@ github.com/opencontainers/runtime-tools v0.9.0/go.mod h1:r3f7wjNzSs2extwzU3Y+6pK github.com/opencontainers/selinux v1.5.1/go.mod h1:yTcKuYAh6R95iDpefGLQaPaRwJFwyzAJufJyiTt7s0g= github.com/opencontainers/selinux v1.6.0 h1:+bIAS/Za3q5FTwWym4fTB0vObnfCf3G/NC7K6Jx62mY= github.com/opencontainers/selinux v1.6.0/go.mod h1:VVGKuOLlE7v4PJyT6h7mNWvq1rzqiriPsEqVhc+svHE= +github.com/opencontainers/selinux v1.8.0 h1:+77ba4ar4jsCbL1GLbFL8fFM57w6suPfSS9PDLDY7KM= +github.com/opencontainers/selinux v1.8.0/go.mod h1:RScLhm78qiWa2gbVCcGkC7tCGdgk3ogry1nUQF8Evvo= github.com/openshift/imagebuilder v1.1.8 h1:gjiIl8pbNj0eC4XWvFJHATdDvYm64p9/pLDLQWoLZPA= github.com/openshift/imagebuilder v1.1.8/go.mod h1:9aJRczxCH0mvT6XQ+5STAQaPWz7OsWcU5/mRkt8IWeo= github.com/ostreedev/ostree-go v0.0.0-20190702140239-759a8c1ac913 h1:TnbXhKzrTOyuvWrjI8W6pcoI9XPbLHFXCdN2dtUw7Rw= @@ -418,6 +416,8 @@ github.com/vishvananda/netns v0.0.0-20191106174202-0a2b9b5464df h1:OviZH7qLw/7Zo github.com/vishvananda/netns v0.0.0-20191106174202-0a2b9b5464df/go.mod h1:JP3t17pCcGlemwknint6hfoeCVQrEMVwxRLRjXpq+BU= github.com/willf/bitset v1.1.11-0.20200630133818-d5bec3311243 h1:R43TdZy32XXSXjJn7M/HhALJ9imq6ztLnChfYJpVDnM= github.com/willf/bitset v1.1.11-0.20200630133818-d5bec3311243/go.mod h1:RjeCKbqT1RxIR/KWY6phxZiaY1IyutSBfGjNPySAYV4= +github.com/willf/bitset v1.1.11 h1:N7Z7E9UvjW+sGsEl7k/SJrvY2reP1A07MrGuCjIOjRE= +github.com/willf/bitset v1.1.11/go.mod h1:83CECat5yLh5zVOf4P1ErAgKA5UDvKtgyUABdr3+MjI= github.com/xeipuuv/gojsonpointer v0.0.0-20180127040702-4e3ac2762d5f/go.mod h1:N2zxlSyiKSe5eX1tZViRH5QA0qijqEDrYZiPEAiq3wU= github.com/xeipuuv/gojsonpointer v0.0.0-20190809123943-df4f5c81cb3b h1:6cLsL+2FW6dRAdl5iMtHgRogVCff0QpRi9653YmdcJA= github.com/xeipuuv/gojsonpointer v0.0.0-20190809123943-df4f5c81cb3b/go.mod h1:N2zxlSyiKSe5eX1tZViRH5QA0qijqEDrYZiPEAiq3wU= @@ -484,8 +484,6 @@ golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLL golang.org/x/net v0.0.0-20191004110552-13f9640d40b9/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20200324143707-d3edc9973b7e/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= golang.org/x/net v0.0.0-20200520004742-59133d7f0dd7/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= -golang.org/x/net v0.0.0-20201006153459-a7d1128ccaa0 h1:wBouT66WTYFXdxfVdz9sVWARVd/2vfGcmI45D2gj45M= -golang.org/x/net v0.0.0-20201006153459-a7d1128ccaa0/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= golang.org/x/net v0.0.0-20201202161906-c7110b5ffcbb h1:eBmm0M9fYhWpKZLjQUUKka/LtIxf46G4fxeEz5KJr9U= golang.org/x/net v0.0.0-20201202161906-c7110b5ffcbb/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= diff --git a/vendor/github.com/containers/buildah/imagebuildah/build.go b/vendor/github.com/containers/buildah/imagebuildah/build.go index 1ec21e786..a7b0f6eaa 100644 --- a/vendor/github.com/containers/buildah/imagebuildah/build.go +++ b/vendor/github.com/containers/buildah/imagebuildah/build.go @@ -187,6 +187,9 @@ type BuildOptions struct { LogRusage bool // Excludes is a list of excludes to be used instead of the .dockerignore file. Excludes []string + // From is the image name to use to replace the value specified in the first + // FROM instruction in the Containerfile + From string } // BuildDockerfiles parses a set of one or more Dockerfiles (which may be diff --git a/vendor/github.com/containers/buildah/imagebuildah/executor.go b/vendor/github.com/containers/buildah/imagebuildah/executor.go index 3c41ec1d2..a72e24eea 100644 --- a/vendor/github.com/containers/buildah/imagebuildah/executor.go +++ b/vendor/github.com/containers/buildah/imagebuildah/executor.go @@ -114,6 +114,7 @@ type Executor struct { logRusage bool imageInfoLock sync.Mutex imageInfoCache map[string]imageTypeAndHistoryAndDiffIDs + fromOverride string } type imageTypeAndHistoryAndDiffIDs struct { @@ -229,6 +230,7 @@ func NewExecutor(store storage.Store, options BuildOptions, mainNode *parser.Nod jobs: jobs, logRusage: options.LogRusage, imageInfoCache: make(map[string]imageTypeAndHistoryAndDiffIDs), + fromOverride: options.From, } if exec.err == nil { exec.err = os.Stderr @@ -245,6 +247,7 @@ func NewExecutor(store storage.Store, options BuildOptions, mainNode *parser.Nod fmt.Fprintf(exec.out, prefix+format+suffix, args...) } } + for arg := range options.Args { if _, isBuiltIn := builtinAllowedBuildArgs[arg]; !isBuiltIn { exec.unusedArgs[arg] = struct{}{} @@ -522,6 +525,12 @@ func (b *Executor) Build(ctx context.Context, stages imagebuilder.Stages) (image switch strings.ToUpper(child.Value) { // first token - instruction case "FROM": if child.Next != nil { // second token on this line + // If we have a fromOverride, replace the value of + // image name for the first FROM in the Containerfile. + if b.fromOverride != "" { + child.Next.Value = b.fromOverride + b.fromOverride = "" + } base := child.Next.Value if base != "scratch" { // TODO: this didn't undergo variable and arg diff --git a/vendor/github.com/containers/buildah/pkg/cli/common.go b/vendor/github.com/containers/buildah/pkg/cli/common.go index 1e2db58c4..ded553ac2 100644 --- a/vendor/github.com/containers/buildah/pkg/cli/common.go +++ b/vendor/github.com/containers/buildah/pkg/cli/common.go @@ -63,6 +63,7 @@ type BudResults struct { IgnoreFile string File []string Format string + From string Iidfile string Label []string Logfile string @@ -81,6 +82,7 @@ type BudResults struct { SignaturePolicy string SignBy string Squash bool + Stdin bool Tag []string Target string TLSVerify bool @@ -187,6 +189,7 @@ func GetBudFlags(flags *BudResults) pflag.FlagSet { fs.StringVar(&flags.Creds, "creds", "", "use `[username[:password]]` for accessing the registry") fs.BoolVarP(&flags.DisableCompression, "disable-compression", "D", true, "don't compress layers by default") fs.BoolVar(&flags.DisableContentTrust, "disable-content-trust", false, "This is a Docker specific option and is a NOOP") + fs.StringVar(&flags.From, "from", "", "image name used to replace the value in the first FROM instruction in the Containerfile") fs.StringVar(&flags.IgnoreFile, "ignorefile", "", "path to an alternate .dockerignore file") fs.StringSliceVarP(&flags.File, "file", "f", []string{}, "`pathname or URL` of a Dockerfile") fs.StringVar(&flags.Format, "format", DefaultFormat(), "`format` of the built image's manifest and metadata. Use BUILDAH_FORMAT environment variable to override.") @@ -215,6 +218,7 @@ func GetBudFlags(flags *BudResults) pflag.FlagSet { panic(fmt.Sprintf("error marking the signature-policy flag as hidden: %v", err)) } fs.BoolVar(&flags.Squash, "squash", false, "squash newly built layers into a single new layer") + fs.BoolVar(&flags.Stdin, "stdin", false, "pass stdin into containers") fs.StringArrayVarP(&flags.Tag, "tag", "t", []string{}, "tagged `name` to apply to the built image") fs.StringVar(&flags.Target, "target", "", "set the target build stage to build") fs.Int64Var(&flags.Timestamp, "timestamp", 0, "set created timestamp to the specified epoch seconds to allow for deterministic builds, defaults to current time") @@ -233,6 +237,7 @@ func GetBudFlagsCompletions() commonComp.FlagCompletions { flagCompletion["cert-dir"] = commonComp.AutocompleteDefault flagCompletion["creds"] = commonComp.AutocompleteNone flagCompletion["file"] = commonComp.AutocompleteDefault + flagCompletion["from"] = commonComp.AutocompleteDefault flagCompletion["format"] = commonComp.AutocompleteNone flagCompletion["ignorefile"] = commonComp.AutocompleteDefault flagCompletion["iidfile"] = commonComp.AutocompleteDefault diff --git a/vendor/github.com/containers/buildah/selinux.go b/vendor/github.com/containers/buildah/selinux.go index fea863165..00903203e 100644 --- a/vendor/github.com/containers/buildah/selinux.go +++ b/vendor/github.com/containers/buildah/selinux.go @@ -1,4 +1,4 @@ -// +build selinux,linux +// +build linux package buildah diff --git a/vendor/github.com/containers/buildah/selinux_unsupported.go b/vendor/github.com/containers/buildah/selinux_unsupported.go index fb9213e29..264614837 100644 --- a/vendor/github.com/containers/buildah/selinux_unsupported.go +++ b/vendor/github.com/containers/buildah/selinux_unsupported.go @@ -1,4 +1,4 @@ -// +build !selinux !linux +// +build !linux package buildah diff --git a/vendor/github.com/google/uuid/uuid.go b/vendor/github.com/google/uuid/uuid.go index daf3639c1..60d26bb50 100644 --- a/vendor/github.com/google/uuid/uuid.go +++ b/vendor/github.com/google/uuid/uuid.go @@ -37,7 +37,7 @@ var rander = rand.Reader // random function type invalidLengthError struct{ len int } -func (err *invalidLengthError) Error() string { +func (err invalidLengthError) Error() string { return fmt.Sprintf("invalid UUID length: %d", err.len) } @@ -74,7 +74,7 @@ func Parse(s string) (UUID, error) { } return uuid, nil default: - return uuid, &invalidLengthError{len(s)} + return uuid, invalidLengthError{len(s)} } // s is now at least 36 bytes long // it must be of the form xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx @@ -118,7 +118,7 @@ func ParseBytes(b []byte) (UUID, error) { } return uuid, nil default: - return uuid, &invalidLengthError{len(b)} + return uuid, invalidLengthError{len(b)} } // s is now at least 36 bytes long // it must be of the form xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx diff --git a/vendor/modules.txt b/vendor/modules.txt index 39771fbe8..141f62bf9 100644 --- a/vendor/modules.txt +++ b/vendor/modules.txt @@ -70,7 +70,7 @@ github.com/containernetworking/plugins/pkg/utils/hwaddr github.com/containernetworking/plugins/pkg/utils/sysctl github.com/containernetworking/plugins/plugins/ipam/host-local/backend github.com/containernetworking/plugins/plugins/ipam/host-local/backend/allocator -# github.com/containers/buildah v1.18.1-0.20201217112226-67470615779c +# github.com/containers/buildah v1.18.1-0.20201222143428-b9fdee076426 github.com/containers/buildah github.com/containers/buildah/bind github.com/containers/buildah/chroot @@ -318,7 +318,7 @@ github.com/golang/protobuf/ptypes/timestamp github.com/google/gofuzz # github.com/google/shlex v0.0.0-20181106134648-c34317bd91bf github.com/google/shlex -# github.com/google/uuid v1.1.3 +# github.com/google/uuid v1.1.4 github.com/google/uuid # github.com/gorilla/mux v1.8.0 github.com/gorilla/mux |