summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorOpenShift Merge Robot <openshift-merge-robot@users.noreply.github.com>2019-02-11 16:26:46 +0100
committerGitHub <noreply@github.com>2019-02-11 16:26:46 +0100
commit921f98f8795eb9fcb19ce581020cfdeff6dee09f (patch)
tree82dc53e3c61fec956eef1efa3e540d1abe5df7f4
parentdc5c061cdcad2f815d9f8c0556a3e13824e6ba75 (diff)
parentcbeca379250932f01fa4e2ffc70e9c2ecd6701bc (diff)
downloadpodman-921f98f8795eb9fcb19ce581020cfdeff6dee09f.tar.gz
podman-921f98f8795eb9fcb19ce581020cfdeff6dee09f.tar.bz2
podman-921f98f8795eb9fcb19ce581020cfdeff6dee09f.zip
Merge pull request #2294 from mheon/v1.0_backports
V1.0 backports
-rw-r--r--.cirrus.yml2
-rwxr-xr-xAPI.md8
-rw-r--r--changelog.txt17
-rw-r--r--cmd/podman/create.go41
-rw-r--r--cmd/podman/formats/formats.go13
-rw-r--r--cmd/podman/images_prune.go21
-rw-r--r--cmd/podman/inspect.go6
-rw-r--r--cmd/podman/shared/prune.go24
-rw-r--r--cmd/podman/varlink/io.podman.varlink4
-rw-r--r--completions/bash/podman2
-rw-r--r--contrib/spec/podman.spec.in2
-rw-r--r--docs/podman-image-prune.1.md21
-rw-r--r--libpod/container.go7
-rw-r--r--libpod/container_easyjson.go2
-rw-r--r--libpod/container_internal.go6
-rw-r--r--libpod/container_internal_linux.go2
-rw-r--r--libpod/image/image.go6
-rw-r--r--libpod/image/prune.go39
-rw-r--r--libpod/oci.go17
-rw-r--r--libpod/runtime.go6
-rw-r--r--pkg/spec/spec.go4
-rw-r--r--pkg/varlinkapi/images.go9
-rw-r--r--test/e2e/prune_test.go3
-rw-r--r--test/e2e/rootless_test.go4
-rw-r--r--vendor.conf2
-rw-r--r--vendor/github.com/opencontainers/selinux/go-selinux/label/label.go4
-rw-r--r--vendor/github.com/opencontainers/selinux/go-selinux/label/label_selinux.go62
-rw-r--r--vendor/github.com/opencontainers/selinux/go-selinux/selinux_linux.go36
-rw-r--r--vendor/github.com/opencontainers/selinux/go-selinux/selinux_stub.go8
-rw-r--r--version/version.go2
30 files changed, 284 insertions, 96 deletions
diff --git a/.cirrus.yml b/.cirrus.yml
index 67af6f69a..443410847 100644
--- a/.cirrus.yml
+++ b/.cirrus.yml
@@ -115,7 +115,7 @@ build_each_commit_task:
matrix:
image_name: "fedora-29-libpod-9afa57a9"
- timeout_in: 20m
+ timeout_in: 40m
script:
- $SCRIPT_BASE/setup_environment.sh
diff --git a/API.md b/API.md
index 3722c2864..e4576850b 100755
--- a/API.md
+++ b/API.md
@@ -57,6 +57,8 @@ in the [API.md](https://github.com/containers/libpod/blob/master/API.md) file in
[func ImageExists(name: string) int](#ImageExists)
+[func ImagesPrune(all: bool) []string](#ImagesPrune)
+
[func ImportImage(source: string, reference: string, message: string, changes: []string) string](#ImportImage)
[func InspectContainer(name: string) string](#InspectContainer)
@@ -543,6 +545,12 @@ $ varlink call -m unix:/run/podman/io.podman/io.podman.ImageExists '{"name": "im
"exists": 1
}
~~~
+### <a name="ImagesPrune"></a>func ImagesPrune
+<div style="background-color: #E8E8E8; padding: 15px; margin: 10px; border-radius: 10px;">
+
+method ImagesPrune(all: [bool](https://godoc.org/builtin#bool)) [[]string](#[]string)</div>
+ImagesPrune removes all unused images from the local store. Upon successful pruning,
+the IDs of the removed images are returned.
### <a name="ImportImage"></a>func ImportImage
<div style="background-color: #E8E8E8; padding: 15px; margin: 10px; border-radius: 10px;">
diff --git a/changelog.txt b/changelog.txt
index 8ee11cdc4..836ff7ed7 100644
--- a/changelog.txt
+++ b/changelog.txt
@@ -1,3 +1,20 @@
+- Changelog for v1.0.1 (2019-02-11):
+ * Fix tests after cherry-picking
+ * rootless: join both userns and mount namespace with --pod
+ * spec: add nosuid,noexec,nodev to ro bind mount
+ * rootless: create the userns immediately when creating a new pod
+ * Preserve exited state across reboot
+ * libpod/image: Use RepoDigests() in Inspect()
+ * podman image prune -- implement all flag
+ * Add varlink support for prune
+ * Make --quiet work in podman create/run
+ * Show a better error message when podman info fails during a refresh
+ * Vendor in latest opencontainers/selinux
+ * rootless: fix --pid=host without --privileged
+ * Do not unmarshal into c.config.Spec
+ * podman-inspect: don't ignore errors
+ * Ensure that wait exits on state transition
+
- Changelog for v1.0.0 (2018-1-11)
* Update release notes for v1.0
* Remove clientintegration from Makefile
diff --git a/cmd/podman/create.go b/cmd/podman/create.go
index d98b78bd4..8c45b568a 100644
--- a/cmd/podman/create.go
+++ b/cmd/podman/create.go
@@ -4,6 +4,8 @@ import (
"context"
"encoding/json"
"fmt"
+ "io"
+ "io/ioutil"
"os"
"path/filepath"
"strconv"
@@ -127,7 +129,12 @@ func createContainer(c *cli.Context, runtime *libpod.Runtime) (*libpod.Container
var data *inspect.ImageData = nil
if rootfs == "" && !rootless.SkipStorageSetup() {
- newImage, err := runtime.ImageRuntime().New(ctx, c.Args()[0], rtc.SignaturePolicyPath, "", os.Stderr, nil, image.SigningOptions{}, false)
+ var writer io.Writer
+ if !c.Bool("quiet") {
+ writer = os.Stderr
+ }
+
+ newImage, err := runtime.ImageRuntime().New(ctx, c.Args()[0], rtc.SignaturePolicyPath, "", writer, nil, image.SigningOptions{}, false)
if err != nil {
return nil, nil, err
}
@@ -172,7 +179,11 @@ func parseSecurityOpt(config *cc.CreateConfig, securityOpts []string) error {
if err != nil {
return errors.Wrapf(err, "container %q not found", config.PidMode.Container())
}
- labelOpts = append(labelOpts, label.DupSecOpt(ctr.ProcessLabel())...)
+ secopts, err := label.DupSecOpt(ctr.ProcessLabel())
+ if err != nil {
+ return errors.Wrapf(err, "failed to duplicate label %q ", ctr.ProcessLabel())
+ }
+ labelOpts = append(labelOpts, secopts...)
}
if config.IpcMode.IsHost() {
@@ -182,7 +193,11 @@ func parseSecurityOpt(config *cc.CreateConfig, securityOpts []string) error {
if err != nil {
return errors.Wrapf(err, "container %q not found", config.IpcMode.Container())
}
- labelOpts = append(labelOpts, label.DupSecOpt(ctr.ProcessLabel())...)
+ secopts, err := label.DupSecOpt(ctr.ProcessLabel())
+ if err != nil {
+ return errors.Wrapf(err, "failed to duplicate label %q ", ctr.ProcessLabel())
+ }
+ labelOpts = append(labelOpts, secopts...)
}
for _, opt := range securityOpts {
@@ -421,6 +436,16 @@ func parseCreateOpts(ctx context.Context, c *cli.Context, runtime *libpod.Runtim
}
if c.IsSet("pod") {
if strings.HasPrefix(originalPodName, "new:") {
+ if rootless.IsRootless() {
+ // To create a new pod, we must immediately create the userns.
+ became, ret, err := rootless.BecomeRootInUserNS()
+ if err != nil {
+ return nil, err
+ }
+ if became {
+ os.Exit(ret)
+ }
+ }
// pod does not exist; lets make it
var podOptions []libpod.PodCreateOption
podOptions = append(podOptions, libpod.WithPodName(podName), libpod.WithInfraContainer(), libpod.WithPodCgroups())
@@ -785,11 +810,15 @@ func joinOrCreateRootlessUserNamespace(createConfig *cc.CreateConfig, runtime *l
if s != libpod.ContainerStateRunning && s != libpod.ContainerStatePaused {
continue
}
- pid, err := prevCtr.PID()
+ data, err := ioutil.ReadFile(prevCtr.Config().ConmonPidFile)
if err != nil {
- return false, -1, err
+ return false, -1, errors.Wrapf(err, "cannot read conmon PID file %q", prevCtr.Config().ConmonPidFile)
}
- return rootless.JoinNS(uint(pid))
+ conmonPid, err := strconv.Atoi(string(data))
+ if err != nil {
+ return false, -1, errors.Wrapf(err, "cannot parse PID %q", data)
+ }
+ return rootless.JoinDirectUserAndMountNS(uint(conmonPid))
}
}
diff --git a/cmd/podman/formats/formats.go b/cmd/podman/formats/formats.go
index 3da0ea385..c454c39bd 100644
--- a/cmd/podman/formats/formats.go
+++ b/cmd/podman/formats/formats.go
@@ -20,6 +20,8 @@ const (
JSONString = "json"
// IDString const to save on duplicates for Go templates
IDString = "{{.ID}}"
+
+ parsingErrorStr = "Template parsing error"
)
// Writer interface for outputs
@@ -96,7 +98,7 @@ func (t StdoutTemplateArray) Out() error {
t.Template = strings.Replace(strings.TrimSpace(t.Template[5:]), " ", "\t", -1)
headerTmpl, err := template.New("header").Funcs(headerFunctions).Parse(t.Template)
if err != nil {
- return errors.Wrapf(err, "Template parsing error")
+ return errors.Wrapf(err, parsingErrorStr)
}
err = headerTmpl.Execute(w, t.Fields)
if err != nil {
@@ -107,13 +109,12 @@ func (t StdoutTemplateArray) Out() error {
t.Template = strings.Replace(t.Template, " ", "\t", -1)
tmpl, err := template.New("image").Funcs(basicFunctions).Parse(t.Template)
if err != nil {
- return errors.Wrapf(err, "Template parsing error")
+ return errors.Wrapf(err, parsingErrorStr)
}
- for i, img := range t.Output {
+ for i, raw := range t.Output {
basicTmpl := tmpl.Funcs(basicFunctions)
- err = basicTmpl.Execute(w, img)
- if err != nil {
- return err
+ if err := basicTmpl.Execute(w, raw); err != nil {
+ return errors.Wrapf(err, parsingErrorStr)
}
if i != len(t.Output)-1 {
fmt.Fprintln(w, "")
diff --git a/cmd/podman/images_prune.go b/cmd/podman/images_prune.go
index cb72a498f..7310137e7 100644
--- a/cmd/podman/images_prune.go
+++ b/cmd/podman/images_prune.go
@@ -1,8 +1,9 @@
package main
import (
+ "fmt"
+
"github.com/containers/libpod/cmd/podman/libpodruntime"
- "github.com/containers/libpod/cmd/podman/shared"
"github.com/pkg/errors"
"github.com/urfave/cli"
)
@@ -13,13 +14,19 @@ var (
Removes all unnamed images from local storage
`
-
+ pruneImageFlags = []cli.Flag{
+ cli.BoolFlag{
+ Name: "all, a",
+ Usage: "remove all unused images, not just dangling ones",
+ },
+ }
pruneImagesCommand = cli.Command{
Name: "prune",
Usage: "Remove unused images",
Description: pruneImagesDescription,
Action: pruneImagesCmd,
OnUsageError: usageErrorHandler,
+ Flags: pruneImageFlags,
}
)
@@ -30,5 +37,13 @@ func pruneImagesCmd(c *cli.Context) error {
}
defer runtime.Shutdown(false)
- return shared.Prune(runtime.ImageRuntime())
+ // Call prune; if any cids are returned, print them and then
+ // return err in case an error also came up
+ pruneCids, err := runtime.ImageRuntime().PruneImages(c.Bool("all"))
+ if len(pruneCids) > 0 {
+ for _, cid := range pruneCids {
+ fmt.Println(cid)
+ }
+ }
+ return err
}
diff --git a/cmd/podman/inspect.go b/cmd/podman/inspect.go
index 6ffcde55f..2f1e97c6c 100644
--- a/cmd/podman/inspect.go
+++ b/cmd/podman/inspect.go
@@ -87,6 +87,9 @@ func inspectCmd(c *cli.Context) error {
}
inspectedObjects, iterateErr := iterateInput(getContext(), c, args, runtime, inspectType)
+ if iterateErr != nil {
+ return iterateErr
+ }
var out formats.Writer
if outputFormat != "" && outputFormat != formats.JSONString {
@@ -97,8 +100,7 @@ func inspectCmd(c *cli.Context) error {
out = formats.JSONStructArray{Output: inspectedObjects}
}
- formats.Writer(out).Out()
- return iterateErr
+ return formats.Writer(out).Out()
}
// func iterateInput iterates the images|containers the user has requested and returns the inspect data and error
diff --git a/cmd/podman/shared/prune.go b/cmd/podman/shared/prune.go
deleted file mode 100644
index 90cfe4475..000000000
--- a/cmd/podman/shared/prune.go
+++ /dev/null
@@ -1,24 +0,0 @@
-package shared
-
-import (
- "fmt"
- "github.com/pkg/errors"
-
- "github.com/containers/libpod/libpod/image"
-)
-
-// Prune removes all unnamed and unused images from the local store
-func Prune(ir *image.Runtime) error {
- pruneImages, err := ir.GetPruneImages()
- if err != nil {
- return err
- }
-
- for _, i := range pruneImages {
- if err := i.Remove(true); err != nil {
- return errors.Wrapf(err, "failed to remove %s", i.ID())
- }
- fmt.Println(i.ID())
- }
- return nil
-}
diff --git a/cmd/podman/varlink/io.podman.varlink b/cmd/podman/varlink/io.podman.varlink
index 4e8b69faf..6f3bf34a2 100644
--- a/cmd/podman/varlink/io.podman.varlink
+++ b/cmd/podman/varlink/io.podman.varlink
@@ -1015,6 +1015,10 @@ method MountContainer(name: string) -> (path: string)
# ~~~
method UnmountContainer(name: string, force: bool) -> ()
+# ImagesPrune removes all unused images from the local store. Upon successful pruning,
+# the IDs of the removed images are returned.
+method ImagesPrune(all: bool) -> (pruned: []string)
+
# This function is not implemented yet.
method ListContainerPorts(name: string) -> (notimplemented: NotImplemented)
diff --git a/completions/bash/podman b/completions/bash/podman
index 6333dfdf2..410180638 100644
--- a/completions/bash/podman
+++ b/completions/bash/podman
@@ -2453,6 +2453,8 @@ _podman_images_prune() {
"
local boolean_options="
+ -a
+ --all
-h
--help
"
diff --git a/contrib/spec/podman.spec.in b/contrib/spec/podman.spec.in
index bf75522dc..acc12fc8c 100644
--- a/contrib/spec/podman.spec.in
+++ b/contrib/spec/podman.spec.in
@@ -39,7 +39,7 @@
%global shortcommit_conmon %(c=%{commit_conmon}; echo ${c:0:7})
Name: podman
-Version: 1.0.1
+Version: 1.0.2
Release: #COMMITDATE#.git%{shortcommit0}%{?dist}
Summary: Manage Pods, Containers and Container Images
License: ASL 2.0
diff --git a/docs/podman-image-prune.1.md b/docs/podman-image-prune.1.md
index db76b26e0..df912c380 100644
--- a/docs/podman-image-prune.1.md
+++ b/docs/podman-image-prune.1.md
@@ -6,23 +6,38 @@ podman-image-prune - Remove all unused images
# SYNOPSIS
**podman image prune**
+[**-a**|**--all**]
[**-h**|**--help**]
# DESCRIPTION
-**podman image prune** removes all unused images from local storage. An unused image
-is defined as an image that does not have any containers based on it.
+**podman image prune** removes all dangling images from local storage. With the `all` option,
+you can delete all unused images. Unused images are dangling images as well as any image that
+does not have any containers based on it.
+
+## OPTIONS
+**--all, -a**
+
+Remove dangling images and images that have no associated containers.
## Examples ##
-Remove all unused images from local storage
+Remove all dangling images from local storage
```
$ sudo podman image prune
f3e20dc537fb04cb51672a5cb6fdf2292e61d411315549391a0d1f64e4e3097e
324a7a3b2e0135f4226ffdd473e4099fd9e477a74230cdc35de69e84c0f9d907
+```
+
+Remove all unused images from local storage
+```
+$ sudo podman image prune -a
+f3e20dc537fb04cb51672a5cb6fdf2292e61d411315549391a0d1f64e4e3097e
+324a7a3b2e0135f4226ffdd473e4099fd9e477a74230cdc35de69e84c0f9d907
6125002719feb1ddf3030acab1df6156da7ce0e78e571e9b6e9c250424d6220c
91e732da5657264c6f4641b8d0c4001c218ae6c1adb9dcef33ad00cafd37d8b6
e4e5109420323221f170627c138817770fb64832da7d8fe2babd863148287fca
77a57fa8285e9656dbb7b23d9efa837a106957409ddd702f995605af27a45ebe
+
```
## SEE ALSO
diff --git a/libpod/container.go b/libpod/container.go
index f18f36160..c15633d34 100644
--- a/libpod/container.go
+++ b/libpod/container.go
@@ -410,14 +410,15 @@ func (c *Container) Spec() *spec.Spec {
// config does not exist (e.g., because the container was never started) return
// the spec from the config.
func (c *Container) specFromState() (*spec.Spec, error) {
- spec := c.config.Spec
+ returnSpec := c.config.Spec
if f, err := os.Open(c.state.ConfigPath); err == nil {
+ returnSpec = new(spec.Spec)
content, err := ioutil.ReadAll(f)
if err != nil {
return nil, errors.Wrapf(err, "error reading container config")
}
- if err := json.Unmarshal([]byte(content), &spec); err != nil {
+ if err := json.Unmarshal([]byte(content), &returnSpec); err != nil {
return nil, errors.Wrapf(err, "error unmarshalling container config")
}
} else {
@@ -427,7 +428,7 @@ func (c *Container) specFromState() (*spec.Spec, error) {
}
}
- return spec, nil
+ return returnSpec, nil
}
// ID returns the container's ID
diff --git a/libpod/container_easyjson.go b/libpod/container_easyjson.go
index 8bf5cb64f..61ee83231 100644
--- a/libpod/container_easyjson.go
+++ b/libpod/container_easyjson.go
@@ -1,6 +1,6 @@
// +build seccomp ostree selinux varlink exclude_graphdriver_devicemapper
-// Code generated by easyjson for marshaling/unmarshaling. DO NOT EDIT.
+// Code generated by easyjson for marshaling/unmarshaling. DO NOT EDIT .
package libpod
diff --git a/libpod/container_internal.go b/libpod/container_internal.go
index 04d67b1aa..89ca59bbb 100644
--- a/libpod/container_internal.go
+++ b/libpod/container_internal.go
@@ -393,7 +393,9 @@ func resetState(state *containerState) error {
state.PID = 0
state.Mountpoint = ""
state.Mounted = false
- state.State = ContainerStateConfigured
+ if state.State != ContainerStateExited {
+ state.State = ContainerStateConfigured
+ }
state.ExecSessions = make(map[string]*ExecSession)
state.NetworkStatus = nil
state.BindMounts = make(map[string]string)
@@ -531,7 +533,7 @@ func (c *Container) isStopped() (bool, error) {
if err != nil {
return true, err
}
- return (c.state.State == ContainerStateStopped || c.state.State == ContainerStateExited), nil
+ return (c.state.State != ContainerStateRunning && c.state.State != ContainerStatePaused), nil
}
// save container state to the database
diff --git a/libpod/container_internal_linux.go b/libpod/container_internal_linux.go
index 2f03d45ea..9c343d051 100644
--- a/libpod/container_internal_linux.go
+++ b/libpod/container_internal_linux.go
@@ -227,7 +227,7 @@ func (c *Container) generateSpec(ctx context.Context) (*spec.Spec, error) {
Options: []string{"bind", "private"},
}
if c.IsReadOnly() && dstPath != "/dev/shm" {
- newMount.Options = append(newMount.Options, "ro")
+ newMount.Options = append(newMount.Options, "ro", "nosuid", "noexec", "nodev")
}
if !MountExists(g.Mounts(), dstPath) {
g.AddMount(newMount)
diff --git a/libpod/image/image.go b/libpod/image/image.go
index 2e12adb70..8b650f25f 100644
--- a/libpod/image/image.go
+++ b/libpod/image/image.go
@@ -824,9 +824,9 @@ func (i *Image) Inspect(ctx context.Context) (*inspect.ImageData, error) {
return nil, err
}
- var repoDigests []string
- for _, name := range i.Names() {
- repoDigests = append(repoDigests, strings.SplitN(name, ":", 2)[0]+"@"+i.Digest().String())
+ repoDigests, err := i.RepoDigests()
+ if err != nil {
+ return nil, err
}
driver, err := i.DriverData()
diff --git a/libpod/image/prune.go b/libpod/image/prune.go
index 6a1f160d5..8602c222c 100644
--- a/libpod/image/prune.go
+++ b/libpod/image/prune.go
@@ -1,9 +1,11 @@
package image
+import "github.com/pkg/errors"
+
// GetPruneImages returns a slice of images that have no names/unused
-func (ir *Runtime) GetPruneImages() ([]*Image, error) {
+func (ir *Runtime) GetPruneImages(all bool) ([]*Image, error) {
var (
- unamedImages []*Image
+ pruneImages []*Image
)
allImages, err := ir.GetImages()
if err != nil {
@@ -11,16 +13,35 @@ func (ir *Runtime) GetPruneImages() ([]*Image, error) {
}
for _, i := range allImages {
if len(i.Names()) == 0 {
- unamedImages = append(unamedImages, i)
+ pruneImages = append(pruneImages, i)
continue
}
- containers, err := i.Containers()
- if err != nil {
- return nil, err
+ if all {
+ containers, err := i.Containers()
+ if err != nil {
+ return nil, err
+ }
+ if len(containers) < 1 {
+ pruneImages = append(pruneImages, i)
+ }
}
- if len(containers) < 1 {
- unamedImages = append(unamedImages, i)
+ }
+ return pruneImages, nil
+}
+
+// PruneImages prunes dangling and optionally all unused images from the local
+// image store
+func (ir *Runtime) PruneImages(all bool) ([]string, error) {
+ var prunedCids []string
+ pruneImages, err := ir.GetPruneImages(all)
+ if err != nil {
+ return nil, errors.Wrap(err, "unable to get images to prune")
+ }
+ for _, p := range pruneImages {
+ if err := p.Remove(true); err != nil {
+ return nil, errors.Wrap(err, "failed to prune image")
}
+ prunedCids = append(prunedCids, p.ID())
}
- return unamedImages, nil
+ return prunedCids, nil
}
diff --git a/libpod/oci.go b/libpod/oci.go
index 31c1a7e85..a1894b52f 100644
--- a/libpod/oci.go
+++ b/libpod/oci.go
@@ -357,18 +357,25 @@ func (r *OCIRuntime) createOCIContainer(ctr *Container, cgroupParent string, res
// Set the label of the conmon process to be level :s0
// This will allow the container processes to talk to fifo-files
// passed into the container by conmon
- var plabel string
+ var (
+ plabel string
+ con selinux.Context
+ )
plabel, err = selinux.CurrentLabel()
if err != nil {
childPipe.Close()
return errors.Wrapf(err, "Failed to get current SELinux label")
}
- c := selinux.NewContext(plabel)
+ con, err = selinux.NewContext(plabel)
+ if err != nil {
+ return errors.Wrapf(err, "Failed to get new context from SELinux label")
+ }
+
runtime.LockOSThread()
- if c["level"] != "s0" && c["level"] != "" {
- c["level"] = "s0"
- if err = label.SetProcessLabel(c.Get()); err != nil {
+ if con["level"] != "s0" && con["level"] != "" {
+ con["level"] = "s0"
+ if err = label.SetProcessLabel(con.Get()); err != nil {
runtime.UnlockOSThread()
return err
}
diff --git a/libpod/runtime.go b/libpod/runtime.go
index facbe5d66..11c90166d 100644
--- a/libpod/runtime.go
+++ b/libpod/runtime.go
@@ -772,7 +772,11 @@ func (r *Runtime) refreshRootless() error {
// Take advantage of a command that requires a new userns
// so that we are running as the root user and able to use refresh()
cmd := exec.Command(os.Args[0], "info")
- return cmd.Run()
+ err := cmd.Run()
+ if err != nil {
+ return errors.Wrapf(err, "Error running %s info while refreshing state", os.Args[0])
+ }
+ return nil
}
// Reconfigures the runtime after a reboot
diff --git a/pkg/spec/spec.go b/pkg/spec/spec.go
index 9ef0223f2..46105af4a 100644
--- a/pkg/spec/spec.go
+++ b/pkg/spec/spec.go
@@ -376,6 +376,10 @@ func CreateConfigToOCISpec(config *CreateConfig) (*spec.Spec, error) { //nolint
}
func blockAccessToKernelFilesystems(config *CreateConfig, g *generate.Generator) {
+ if config.PidMode.IsHost() && rootless.IsRootless() {
+ return
+ }
+
if !config.Privileged {
for _, mp := range []string{
"/proc/acpi",
diff --git a/pkg/varlinkapi/images.go b/pkg/varlinkapi/images.go
index 8f8934025..cfcdde6ef 100644
--- a/pkg/varlinkapi/images.go
+++ b/pkg/varlinkapi/images.go
@@ -620,3 +620,12 @@ func (i *LibpodAPI) ContainerRunlabel(call iopodman.VarlinkCall, input iopodman.
}
return call.ReplyContainerRunlabel()
}
+
+// ImagesPrune ....
+func (i *LibpodAPI) ImagesPrune(call iopodman.VarlinkCall, all bool) error {
+ prunedImages, err := i.Runtime.ImageRuntime().PruneImages(all)
+ if err != nil {
+ return call.ReplyErrorOccurred(err.Error())
+ }
+ return call.ReplyImagesPrune(prunedImages)
+}
diff --git a/test/e2e/prune_test.go b/test/e2e/prune_test.go
index 6679a676c..149f1ac60 100644
--- a/test/e2e/prune_test.go
+++ b/test/e2e/prune_test.go
@@ -72,10 +72,11 @@ var _ = Describe("Podman rm", func() {
Expect(none.ExitCode()).To(Equal(0))
hasNoneAfter, _ := after.GrepString("<none>")
Expect(hasNoneAfter).To(BeFalse())
+ Expect(len(after.OutputToStringArray()) > 1).To(BeTrue())
})
It("podman image prune unused images", func() {
- prune := podmanTest.Podman([]string{"image", "prune"})
+ prune := podmanTest.Podman([]string{"image", "prune", "-a"})
prune.WaitWithDefaultTimeout()
Expect(prune.ExitCode()).To(Equal(0))
diff --git a/test/e2e/rootless_test.go b/test/e2e/rootless_test.go
index 8e9f9fc8d..e9606f859 100644
--- a/test/e2e/rootless_test.go
+++ b/test/e2e/rootless_test.go
@@ -274,6 +274,10 @@ var _ = Describe("Podman rootless", func() {
runRootlessHelper([]string{"--net", "host"})
})
+ It("podman rootless rootfs --pid host", func() {
+ runRootlessHelper([]string{"--pid", "host"})
+ })
+
It("podman rootless rootfs --privileged", func() {
runRootlessHelper([]string{"--privileged"})
})
diff --git a/vendor.conf b/vendor.conf
index 18283cae6..82ae1260e 100644
--- a/vendor.conf
+++ b/vendor.conf
@@ -51,7 +51,7 @@ github.com/opencontainers/image-spec v1.0.0
github.com/opencontainers/runc bbb17efcb4c0ab986407812a31ba333a7450064c
github.com/opencontainers/runtime-spec d810dbc60d8c5aeeb3d054bd1132fab2121968ce
github.com/opencontainers/runtime-tools master
-github.com/opencontainers/selinux 51c6c0a5dbc675792e953298cb9871819d6f9bb8
+github.com/opencontainers/selinux v1.1
github.com/ostreedev/ostree-go master
github.com/pkg/errors v0.8.0
github.com/pmezard/go-difflib 792786c7400a136282c1664665ae0a8db921c6c2
diff --git a/vendor/github.com/opencontainers/selinux/go-selinux/label/label.go b/vendor/github.com/opencontainers/selinux/go-selinux/label/label.go
index bb27ac936..4e9a8c54f 100644
--- a/vendor/github.com/opencontainers/selinux/go-selinux/label/label.go
+++ b/vendor/github.com/opencontainers/selinux/go-selinux/label/label.go
@@ -75,8 +75,8 @@ func ReleaseLabel(label string) error {
// DupSecOpt takes a process label and returns security options that
// can be used to set duplicate labels on future container processes
-func DupSecOpt(src string) []string {
- return nil
+func DupSecOpt(src string) ([]string, error) {
+ return nil, nil
}
// DisableSecOpt returns a security opt that can disable labeling
diff --git a/vendor/github.com/opencontainers/selinux/go-selinux/label/label_selinux.go b/vendor/github.com/opencontainers/selinux/go-selinux/label/label_selinux.go
index de214b2d5..d4e26909d 100644
--- a/vendor/github.com/opencontainers/selinux/go-selinux/label/label_selinux.go
+++ b/vendor/github.com/opencontainers/selinux/go-selinux/label/label_selinux.go
@@ -4,6 +4,8 @@ package label
import (
"fmt"
+ "os"
+ "os/user"
"strings"
"github.com/opencontainers/selinux/go-selinux"
@@ -35,8 +37,15 @@ func InitLabels(options []string) (plabel string, mlabel string, Err error) {
ReleaseLabel(mountLabel)
}
}()
- pcon := selinux.NewContext(processLabel)
- mcon := selinux.NewContext(mountLabel)
+ pcon, err := selinux.NewContext(processLabel)
+ if err != nil {
+ return "", "", err
+ }
+
+ mcon, err := selinux.NewContext(mountLabel)
+ if err != nil {
+ return "", "", err
+ }
for _, opt := range options {
if opt == "disable" {
return "", mountLabel, nil
@@ -146,13 +155,56 @@ func Relabel(path string, fileLabel string, shared bool) error {
return nil
}
- exclude_paths := map[string]bool{"/": true, "/usr": true, "/etc": true, "/tmp": true, "/home": true, "/run": true, "/var": true, "/root": true}
+ exclude_paths := map[string]bool{
+ "/": true,
+ "/bin": true,
+ "/boot": true,
+ "/dev": true,
+ "/etc": true,
+ "/etc/passwd": true,
+ "/etc/pki": true,
+ "/etc/shadow": true,
+ "/home": true,
+ "/lib": true,
+ "/lib64": true,
+ "/media": true,
+ "/opt": true,
+ "/proc": true,
+ "/root": true,
+ "/run": true,
+ "/sbin": true,
+ "/srv": true,
+ "/sys": true,
+ "/tmp": true,
+ "/usr": true,
+ "/var": true,
+ "/var/lib": true,
+ "/var/log": true,
+ }
+
+ if home := os.Getenv("HOME"); home != "" {
+ exclude_paths[home] = true
+ }
+
+ if sudoUser := os.Getenv("SUDO_USER"); sudoUser != "" {
+ if usr, err := user.Lookup(sudoUser); err == nil {
+ exclude_paths[usr.HomeDir] = true
+ }
+ }
+
+ if path != "/" {
+ path = strings.TrimSuffix(path, "/")
+ }
if exclude_paths[path] {
return fmt.Errorf("SELinux relabeling of %s is not allowed", path)
}
if shared {
- c := selinux.NewContext(fileLabel)
+ c, err := selinux.NewContext(fileLabel)
+ if err != nil {
+ return err
+ }
+
c["level"] = "s0"
fileLabel = c.Get()
}
@@ -195,7 +247,7 @@ func ReleaseLabel(label string) error {
// DupSecOpt takes a process label and returns security options that
// can be used to set duplicate labels on future container processes
-func DupSecOpt(src string) []string {
+func DupSecOpt(src string) ([]string, error) {
return selinux.DupSecOpt(src)
}
diff --git a/vendor/github.com/opencontainers/selinux/go-selinux/selinux_linux.go b/vendor/github.com/opencontainers/selinux/go-selinux/selinux_linux.go
index 7832f7497..5adafd317 100644
--- a/vendor/github.com/opencontainers/selinux/go-selinux/selinux_linux.go
+++ b/vendor/github.com/opencontainers/selinux/go-selinux/selinux_linux.go
@@ -52,6 +52,8 @@ var (
ErrMCSAlreadyExists = errors.New("MCS label already exists")
// ErrEmptyPath is returned when an empty path has been specified.
ErrEmptyPath = errors.New("empty path")
+ // InvalidLabel is returned when an invalid label is specified.
+ InvalidLabel = errors.New("Invalid Label")
assignRegex = regexp.MustCompile(`^([^=]+)=(.*)$`)
roFileLabel string
@@ -405,11 +407,14 @@ func (c Context) Get() string {
}
// NewContext creates a new Context struct from the specified label
-func NewContext(label string) Context {
+func NewContext(label string) (Context, error) {
c := make(Context)
if len(label) != 0 {
con := strings.SplitN(label, ":", 4)
+ if len(con) < 3 {
+ return c, InvalidLabel
+ }
c["user"] = con[0]
c["role"] = con[1]
c["type"] = con[2]
@@ -417,7 +422,7 @@ func NewContext(label string) Context {
c["level"] = con[3]
}
}
- return c
+ return c, nil
}
// ClearLabels clears all reserved labels
@@ -630,12 +635,12 @@ func ContainerLabels() (processLabel string, fileLabel string) {
roFileLabel = fileLabel
}
exit:
- scon := NewContext(processLabel)
+ scon, _ := NewContext(processLabel)
if scon["level"] != "" {
mcs := uniqMcs(1024)
scon["level"] = mcs
processLabel = scon.Get()
- scon = NewContext(fileLabel)
+ scon, _ = NewContext(fileLabel)
scon["level"] = mcs
fileLabel = scon.Get()
}
@@ -661,8 +666,14 @@ func CopyLevel(src, dest string) (string, error) {
if err := SecurityCheckContext(dest); err != nil {
return "", err
}
- scon := NewContext(src)
- tcon := NewContext(dest)
+ scon, err := NewContext(src)
+ if err != nil {
+ return "", err
+ }
+ tcon, err := NewContext(dest)
+ if err != nil {
+ return "", err
+ }
mcsDelete(tcon["level"])
mcsAdd(scon["level"])
tcon["level"] = scon["level"]
@@ -714,15 +725,18 @@ func Chcon(fpath string, label string, recurse bool) error {
// DupSecOpt takes an SELinux process label and returns security options that
// can be used to set the SELinux Type and Level for future container processes.
-func DupSecOpt(src string) []string {
+func DupSecOpt(src string) ([]string, error) {
if src == "" {
- return nil
+ return nil, nil
+ }
+ con, err := NewContext(src)
+ if err != nil {
+ return nil, err
}
- con := NewContext(src)
if con["user"] == "" ||
con["role"] == "" ||
con["type"] == "" {
- return nil
+ return nil, nil
}
dup := []string{"user:" + con["user"],
"role:" + con["role"],
@@ -733,7 +747,7 @@ func DupSecOpt(src string) []string {
dup = append(dup, "level:"+con["level"])
}
- return dup
+ return dup, nil
}
// DisableSecOpt returns a security opt that can be used to disable SELinux
diff --git a/vendor/github.com/opencontainers/selinux/go-selinux/selinux_stub.go b/vendor/github.com/opencontainers/selinux/go-selinux/selinux_stub.go
index 99efa155a..9497acbd0 100644
--- a/vendor/github.com/opencontainers/selinux/go-selinux/selinux_stub.go
+++ b/vendor/github.com/opencontainers/selinux/go-selinux/selinux_stub.go
@@ -115,9 +115,9 @@ func (c Context) Get() string {
}
// NewContext creates a new Context struct from the specified label
-func NewContext(label string) Context {
+func NewContext(label string) (Context, error) {
c := make(Context)
- return c
+ return c, nil
}
// ClearLabels clears all reserved MLS/MCS levels
@@ -195,8 +195,8 @@ func Chcon(fpath string, label string, recurse bool) error {
// DupSecOpt takes an SELinux process label and returns security options that
// can be used to set the SELinux Type and Level for future container processes.
-func DupSecOpt(src string) []string {
- return nil
+func DupSecOpt(src string) ([]string, error) {
+ return nil, nil
}
// DisableSecOpt returns a security opt that can be used to disable SELinux
diff --git a/version/version.go b/version/version.go
index ea5a92286..99e30f002 100644
--- a/version/version.go
+++ b/version/version.go
@@ -4,4 +4,4 @@ package version
// NOTE: remember to bump the version at the top
// of the top-level README.md file when this is
// bumped.
-const Version = "1.0.1-dev"
+const Version = "1.0.2-dev"