summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--.cirrus.yml2
-rw-r--r--Dockerfile2
-rw-r--r--cmd/podman/create.go2
-rw-r--r--cmd/podman/libpodruntime/runtime.go38
-rw-r--r--cmd/podman/main.go9
-rw-r--r--cmd/podman/rmi.go19
-rw-r--r--cmd/podman/run.go2
-rw-r--r--docs/libpod.conf.5.md12
-rw-r--r--docs/podman.1.md24
-rw-r--r--libpod/boltdb_state.go85
-rw-r--r--libpod/boltdb_state_internal.go47
-rw-r--r--libpod/container_internal.go48
-rw-r--r--libpod/container_internal_linux.go6
-rw-r--r--libpod/in_memory_state.go12
-rw-r--r--libpod/options.go58
-rw-r--r--libpod/runtime.go173
-rw-r--r--libpod/state.go26
-rw-r--r--libpod/state_test.go7
-rw-r--r--libpod/testdata/config.toml2
-rw-r--r--pkg/util/utils.go2
-rw-r--r--test/e2e/rmi_test.go21
-rw-r--r--test/e2e/run_test.go2
-rw-r--r--vendor.conf2
-rw-r--r--vendor/github.com/containers/storage/drivers/fsdiff.go5
-rw-r--r--vendor/github.com/containers/storage/drivers/overlay/overlay.go2
-rw-r--r--vendor/github.com/containers/storage/layers.go5
-rw-r--r--vendor/github.com/containers/storage/pkg/archive/archive.go5
-rw-r--r--vendor/github.com/containers/storage/pkg/archive/example_changes.go97
-rw-r--r--vendor/github.com/containers/storage/pkg/chrootarchive/archive.go2
29 files changed, 435 insertions, 282 deletions
diff --git a/.cirrus.yml b/.cirrus.yml
index 304efb2f4..625b96fdd 100644
--- a/.cirrus.yml
+++ b/.cirrus.yml
@@ -20,7 +20,7 @@ env:
CNI_COMMIT: "7480240de9749f9a0a5c8614b17f1f03e0c06ab9"
CRIO_COMMIT: "7a283c391abb7bd25086a8ff91dbb36ebdd24466"
CRIU_COMMIT: "c74b83cd49c00589c0c0468ba5fe685b67fdbd0a"
- RUNC_COMMIT: "869add33186caff4a22e3e11a7472a2d48d77889"
+ RUNC_COMMIT: "96ec2177ae841256168fcf76954f7177af9446eb"
# File to update in home-dir with task-specific env. var values
ENVLIB: ".bash_profile"
# Overrides default location (/tmp/cirrus) for repo clone
diff --git a/Dockerfile b/Dockerfile
index e1d7b4649..08af0f851 100644
--- a/Dockerfile
+++ b/Dockerfile
@@ -52,7 +52,7 @@ ADD . /go/src/github.com/containers/libpod
RUN set -x && cd /go/src/github.com/containers/libpod && make install.libseccomp.sudo
# Install runc
-ENV RUNC_COMMIT 869add33186caff4a22e3e11a7472a2d48d77889
+ENV RUNC_COMMIT 96ec2177ae841256168fcf76954f7177af9446eb
RUN set -x \
&& export GOPATH="$(mktemp -d)" \
&& git clone https://github.com/opencontainers/runc.git "$GOPATH/src/github.com/opencontainers/runc" \
diff --git a/cmd/podman/create.go b/cmd/podman/create.go
index c40650f83..228438d75 100644
--- a/cmd/podman/create.go
+++ b/cmd/podman/create.go
@@ -67,7 +67,7 @@ func createCmd(c *cli.Context) error {
rootless.SetSkipStorageSetup(true)
}
- runtime, err := libpodruntime.GetContainerRuntime(c)
+ runtime, err := libpodruntime.GetRuntime(c)
if err != nil {
return errors.Wrapf(err, "error creating libpod runtime")
}
diff --git a/cmd/podman/libpodruntime/runtime.go b/cmd/podman/libpodruntime/runtime.go
index a4b3581be..0dc6bcf18 100644
--- a/cmd/podman/libpodruntime/runtime.go
+++ b/cmd/podman/libpodruntime/runtime.go
@@ -11,32 +11,18 @@ import (
// GetRuntime generates a new libpod runtime configured by command line options
func GetRuntime(c *cli.Context) (*libpod.Runtime, error) {
- storageOpts, err := util.GetDefaultStoreOptions()
- if err != nil {
- return nil, err
- }
- return GetRuntimeWithStorageOpts(c, &storageOpts)
-}
-
-// GetContainerRuntime generates a new libpod runtime configured by command line options for containers
-func GetContainerRuntime(c *cli.Context) (*libpod.Runtime, error) {
- mappings, err := util.ParseIDMapping(c.StringSlice("uidmap"), c.StringSlice("gidmap"), c.String("subuidmap"), c.String("subgidmap"))
- if err != nil {
- return nil, err
- }
- storageOpts, err := util.GetDefaultStoreOptions()
- if err != nil {
- return nil, err
- }
- storageOpts.UIDMap = mappings.UIDMap
- storageOpts.GIDMap = mappings.GIDMap
- return GetRuntimeWithStorageOpts(c, &storageOpts)
-}
-
-// GetRuntime generates a new libpod runtime configured by command line options
-func GetRuntimeWithStorageOpts(c *cli.Context, storageOpts *storage.StoreOptions) (*libpod.Runtime, error) {
+ storageOpts := new(storage.StoreOptions)
options := []libpod.RuntimeOption{}
+ if c.IsSet("uidmap") || c.IsSet("gidmap") || c.IsSet("subuidmap") || c.IsSet("subgidmap") {
+ mappings, err := util.ParseIDMapping(c.StringSlice("uidmap"), c.StringSlice("gidmap"), c.String("subuidmap"), c.String("subgidmap"))
+ if err != nil {
+ return nil, err
+ }
+ storageOpts.UIDMap = mappings.UIDMap
+ storageOpts.GIDMap = mappings.GIDMap
+ }
+
if c.GlobalIsSet("root") {
storageOpts.GraphRoot = c.GlobalString("root")
}
@@ -90,8 +76,8 @@ func GetRuntimeWithStorageOpts(c *cli.Context, storageOpts *storage.StoreOptions
if c.GlobalIsSet("default-mounts-file") {
options = append(options, libpod.WithDefaultMountsFile(c.GlobalString("default-mounts-file")))
}
- if c.GlobalIsSet("hooks-dir-path") {
- options = append(options, libpod.WithHooksDir(c.GlobalString("hooks-dir-path")))
+ if c.GlobalIsSet("hooks-dir") {
+ options = append(options, libpod.WithHooksDir(c.GlobalStringSlice("hooks-dir")...))
}
// TODO flag to set CNI plugins dir?
diff --git a/cmd/podman/main.go b/cmd/podman/main.go
index 6be192593..bcae04575 100644
--- a/cmd/podman/main.go
+++ b/cmd/podman/main.go
@@ -8,7 +8,6 @@ import (
"syscall"
"github.com/containers/libpod/libpod"
- "github.com/containers/libpod/pkg/hooks"
_ "github.com/containers/libpod/pkg/hooks/0.1.0"
"github.com/containers/libpod/pkg/rootless"
"github.com/containers/libpod/version"
@@ -206,11 +205,9 @@ func main() {
Usage: "path to default mounts file",
Hidden: true,
},
- cli.StringFlag{
- Name: "hooks-dir-path",
- Usage: "set the OCI hooks directory path",
- Value: hooks.DefaultDir,
- Hidden: true,
+ cli.StringSliceFlag{
+ Name: "hooks-dir",
+ Usage: "set the OCI hooks directory path (may be set multiple times)",
},
cli.IntFlag{
Name: "max-workers",
diff --git a/cmd/podman/rmi.go b/cmd/podman/rmi.go
index c0a0d69df..0f4f8765b 100644
--- a/cmd/podman/rmi.go
+++ b/cmd/podman/rmi.go
@@ -91,8 +91,23 @@ func rmiCmd(c *cli.Context) error {
if err != nil {
return errors.Wrapf(err, "unable to query local images")
}
- for _, i := range imagesToDelete {
- removeImage(i)
+ lastNumberofImages := 0
+ for len(imagesToDelete) > 0 {
+ if lastNumberofImages == len(imagesToDelete) {
+ return errors.New("unable to delete all images; re-run the rmi command again.")
+ }
+ for _, i := range imagesToDelete {
+ isParent, err := i.IsParent()
+ if err != nil {
+ return err
+ }
+ if isParent {
+ continue
+ }
+ removeImage(i)
+ }
+ lastNumberofImages = len(imagesToDelete)
+ imagesToDelete, err = runtime.ImageRuntime().GetImages()
}
} else {
// Create image.image objects for deletion from user input.
diff --git a/cmd/podman/run.go b/cmd/podman/run.go
index af6ced45d..a4b5c918e 100644
--- a/cmd/podman/run.go
+++ b/cmd/podman/run.go
@@ -44,7 +44,7 @@ func runCmd(c *cli.Context) error {
rootless.SetSkipStorageSetup(true)
}
- runtime, err := libpodruntime.GetContainerRuntime(c)
+ runtime, err := libpodruntime.GetRuntime(c)
if err != nil {
return errors.Wrapf(err, "error creating libpod runtime")
}
diff --git a/docs/libpod.conf.5.md b/docs/libpod.conf.5.md
index 198e927ee..d63baeb88 100644
--- a/docs/libpod.conf.5.md
+++ b/docs/libpod.conf.5.md
@@ -24,6 +24,18 @@ libpod to manage containers.
**cgroup_manager**=""
Specify the CGroup Manager to use; valid values are "systemd" and "cgroupfs"
+**hooks_dir**=["*path*", ...]
+
+ Each `*.json` file in the path configures a hook for Podman containers. For more details on the syntax of the JSON files and the semantics of hook injection, see `oci-hooks(5)`. Podman and libpod currently support both the 1.0.0 and 0.1.0 hook schemas, although the 0.1.0 schema is deprecated.
+
+ Paths listed later in the array higher precedence (`oci-hooks(5)` discusses directory precedence).
+
+ For the annotation conditions, libpod uses any annotations set in the generated OCI configuration.
+
+ For the bind-mount conditions, only mounts explicitly requested by the caller via `--volume` are considered. Bind mounts that libpod inserts by default (e.g. `/dev/shm`) are not considered.
+
+ If `hooks_dir` is unset for root callers, Podman and libpod will currently default to `/usr/share/containers/oci/hooks.d` and `/etc/containers/oci/hooks.d` in order of increasing precedence. Using these defaults is deprecated, and callers should migrate to explicitly setting `hooks_dir`.
+
**static_dir**=""
Directory for persistent libpod files (database, etc)
By default this will be configured relative to where containers/storage
diff --git a/docs/podman.1.md b/docs/podman.1.md
index b7433d850..bde349e6f 100644
--- a/docs/podman.1.md
+++ b/docs/podman.1.md
@@ -31,6 +31,18 @@ CGroup manager to use for container cgroups. Supported values are cgroupfs or sy
Path to where the cpu performance results should be written
+**--hooks-dir**=**path**
+
+Each `*.json` file in the path configures a hook for Podman containers. For more details on the syntax of the JSON files and the semantics of hook injection, see `oci-hooks(5)`. Podman and libpod currently support both the 1.0.0 and 0.1.0 hook schemas, although the 0.1.0 schema is deprecated.
+
+This option may be set multiple times; paths from later options have higher precedence (`oci-hooks(5)` discusses directory precedence).
+
+For the annotation conditions, libpod uses any annotations set in the generated OCI configuration.
+
+For the bind-mount conditions, only mounts explicitly requested by the caller via `--volume` are considered. Bind mounts that libpod inserts by default (e.g. `/dev/shm`) are not considered.
+
+If `--hooks-dir` is unset for root callers, Podman and libpod will currently default to `/usr/share/containers/oci/hooks.d` and `/etc/containers/oci/hooks.d` in order of increasing precedence. Using these defaults is deprecated, and callers should migrate to explicitly setting `--hooks-dir`.
+
**--log-level**
Log messages above specified level: debug, info, warn, error (default), fatal or panic
@@ -161,18 +173,6 @@ the exit codes follow the `chroot` standard, see below:
The mounts.conf file specifies volume mount directories that are automatically mounted inside containers when executing the `podman run` or `podman start` commands. When Podman runs in rootless mode, the file `$HOME/.config/containers/mounts.conf` is also used. Please refer to containers-mounts.conf(5) for further details.
-**OCI hooks JSON** (`/etc/containers/oci/hooks.d/*.json`, `/usr/share/containers/oci/hooks.d/*.json`)
-
- Each `*.json` file in `/etc/containers/oci/hooks.d` and `/usr/share/containers/oci/hooks.d` configures a hook for Podman containers, with `/etc/containers/oci/hooks.d` having higher precedence. For more details on the syntax of the JSON files and the semantics of hook injection, see `oci-hooks(5)`.
-
- Podman and libpod currently support both the 1.0.0 and 0.1.0 hook schemas, although the 0.1.0 schema is deprecated.
-
- For the annotation conditions, libpod uses any annotations set in the generated OCI configuration.
-
- For the bind-mount conditions, only mounts explicitly requested by the caller via `--volume` are considered. Bind mounts that libpod inserts by default (e.g. `/dev/shm`) are not considered.
-
- Hooks are not used when running in rootless mode.
-
**policy.json** (`/etc/containers/policy.json`)
Signature verification policy files are used to specify policy, e.g. trusted keys, applicable when deciding whether to accept an image, or individual signatures of that image, as valid.
diff --git a/libpod/boltdb_state.go b/libpod/boltdb_state.go
index 42f029379..cb661d4e9 100644
--- a/libpod/boltdb_state.go
+++ b/libpod/boltdb_state.go
@@ -3,7 +3,6 @@ package libpod
import (
"bytes"
"encoding/json"
- "os"
"strings"
"sync"
@@ -19,7 +18,6 @@ type BoltState struct {
dbLock sync.Mutex
namespace string
namespaceBytes []byte
- lockDir string
runtime *Runtime
}
@@ -52,25 +50,15 @@ type BoltState struct {
// containers/storage do not occur.
// NewBoltState creates a new bolt-backed state database
-func NewBoltState(path, lockDir string, runtime *Runtime) (State, error) {
+func NewBoltState(path string, runtime *Runtime) (State, error) {
state := new(BoltState)
state.dbPath = path
- state.lockDir = lockDir
state.runtime = runtime
state.namespace = ""
state.namespaceBytes = nil
logrus.Debugf("Initializing boltdb state at %s", path)
- // Make the directory that will hold container lockfiles
- if err := os.MkdirAll(lockDir, 0750); err != nil {
- // The directory is allowed to exist
- if !os.IsExist(err) {
- return nil, errors.Wrapf(err, "error creating lockfiles dir %s", lockDir)
- }
- }
- state.lockDir = lockDir
-
db, err := bolt.Open(path, 0600, nil)
if err != nil {
return nil, errors.Wrapf(err, "error opening database %s", path)
@@ -115,11 +103,6 @@ func NewBoltState(path, lockDir string, runtime *Runtime) (State, error) {
return nil, errors.Wrapf(err, "error creating initial database layout")
}
- // Check runtime configuration
- if err := checkRuntimeConfig(db, runtime); err != nil {
- return nil, err
- }
-
state.valid = true
return state, nil
@@ -240,6 +223,72 @@ func (s *BoltState) Refresh() error {
return err
}
+// GetDBConfig retrieves runtime configuration fields that were created when
+// the database was first initialized
+func (s *BoltState) GetDBConfig() (*DBConfig, error) {
+ if !s.valid {
+ return nil, ErrDBClosed
+ }
+
+ cfg := new(DBConfig)
+
+ db, err := s.getDBCon()
+ if err != nil {
+ return nil, err
+ }
+ defer s.closeDBCon(db)
+
+ err = db.View(func(tx *bolt.Tx) error {
+ configBucket, err := getRuntimeConfigBucket(tx)
+ if err != nil {
+ return nil
+ }
+
+ // Some of these may be nil
+ // When we convert to string, Go will coerce them to ""
+ // That's probably fine - we could raise an error if the key is
+ // missing, but just not including it is also OK.
+ libpodRoot := configBucket.Get(staticDirKey)
+ libpodTmp := configBucket.Get(tmpDirKey)
+ storageRoot := configBucket.Get(graphRootKey)
+ storageTmp := configBucket.Get(runRootKey)
+ graphDriver := configBucket.Get(graphDriverKey)
+
+ cfg.LibpodRoot = string(libpodRoot)
+ cfg.LibpodTmp = string(libpodTmp)
+ cfg.StorageRoot = string(storageRoot)
+ cfg.StorageTmp = string(storageTmp)
+ cfg.GraphDriver = string(graphDriver)
+
+ return nil
+ })
+ if err != nil {
+ return nil, err
+ }
+
+ return cfg, nil
+}
+
+// ValidateDBConfig validates paths in the given runtime against the database
+func (s *BoltState) ValidateDBConfig(runtime *Runtime) error {
+ if !s.valid {
+ return ErrDBClosed
+ }
+
+ db, err := s.getDBCon()
+ if err != nil {
+ return err
+ }
+ defer s.closeDBCon(db)
+
+ // Check runtime configuration
+ if err := checkRuntimeConfig(db, runtime); err != nil {
+ return err
+ }
+
+ return nil
+}
+
// SetNamespace sets the namespace that will be used for container and pod
// retrieval
func (s *BoltState) SetNamespace(ns string) error {
diff --git a/libpod/boltdb_state_internal.go b/libpod/boltdb_state_internal.go
index cc7d106cc..3f00657ea 100644
--- a/libpod/boltdb_state_internal.go
+++ b/libpod/boltdb_state_internal.go
@@ -30,6 +30,13 @@ const (
containersName = "containers"
podIDName = "pod-id"
namespaceName = "namespace"
+
+ staticDirName = "static-dir"
+ tmpDirName = "tmp-dir"
+ runRootName = "run-root"
+ graphRootName = "graph-root"
+ graphDriverName = "graph-driver-name"
+ osName = "os"
)
var (
@@ -49,21 +56,19 @@ var (
containersBkt = []byte(containersName)
podIDKey = []byte(podIDName)
namespaceKey = []byte(namespaceName)
+
+ staticDirKey = []byte(staticDirName)
+ tmpDirKey = []byte(tmpDirName)
+ runRootKey = []byte(runRootName)
+ graphRootKey = []byte(graphRootName)
+ graphDriverKey = []byte(graphDriverName)
+ osKey = []byte(osName)
)
// Check if the configuration of the database is compatible with the
// configuration of the runtime opening it
// If there is no runtime configuration loaded, load our own
func checkRuntimeConfig(db *bolt.DB, rt *Runtime) error {
- var (
- staticDir = []byte("static-dir")
- tmpDir = []byte("tmp-dir")
- runRoot = []byte("run-root")
- graphRoot = []byte("graph-root")
- graphDriverName = []byte("graph-driver-name")
- osKey = []byte("os")
- )
-
err := db.Update(func(tx *bolt.Tx) error {
configBkt, err := getRuntimeConfigBucket(tx)
if err != nil {
@@ -74,31 +79,31 @@ func checkRuntimeConfig(db *bolt.DB, rt *Runtime) error {
return err
}
- if err := validateDBAgainstConfig(configBkt, "static dir",
- rt.config.StaticDir, staticDir, ""); err != nil {
+ if err := validateDBAgainstConfig(configBkt, "libpod root directory (staticdir)",
+ rt.config.StaticDir, staticDirKey, ""); err != nil {
return err
}
- if err := validateDBAgainstConfig(configBkt, "tmp dir",
- rt.config.TmpDir, tmpDir, ""); err != nil {
+ if err := validateDBAgainstConfig(configBkt, "libpod temporary files directory (tmpdir)",
+ rt.config.TmpDir, tmpDirKey, ""); err != nil {
return err
}
- if err := validateDBAgainstConfig(configBkt, "run root",
- rt.config.StorageConfig.RunRoot, runRoot,
+ if err := validateDBAgainstConfig(configBkt, "storage temporary directory (runroot)",
+ rt.config.StorageConfig.RunRoot, runRootKey,
storage.DefaultStoreOptions.RunRoot); err != nil {
return err
}
- if err := validateDBAgainstConfig(configBkt, "graph root",
- rt.config.StorageConfig.GraphRoot, graphRoot,
+ if err := validateDBAgainstConfig(configBkt, "storage graph root directory (graphroot)",
+ rt.config.StorageConfig.GraphRoot, graphRootKey,
storage.DefaultStoreOptions.GraphRoot); err != nil {
return err
}
- return validateDBAgainstConfig(configBkt, "graph driver name",
+ return validateDBAgainstConfig(configBkt, "storage graph driver",
rt.config.StorageConfig.GraphDriverName,
- graphDriverName,
+ graphDriverKey,
storage.DefaultStoreOptions.GraphDriverName)
})
@@ -261,7 +266,7 @@ func (s *BoltState) getContainerFromDB(id []byte, ctr *Container, ctrsBkt *bolt.
}
// Get the lock
- lockPath := filepath.Join(s.lockDir, string(id))
+ lockPath := filepath.Join(s.runtime.lockDir, string(id))
lock, err := storage.GetLockfile(lockPath)
if err != nil {
return errors.Wrapf(err, "error retrieving lockfile for container %s", string(id))
@@ -297,7 +302,7 @@ func (s *BoltState) getPodFromDB(id []byte, pod *Pod, podBkt *bolt.Bucket) error
}
// Get the lock
- lockPath := filepath.Join(s.lockDir, string(id))
+ lockPath := filepath.Join(s.runtime.lockDir, string(id))
lock, err := storage.GetLockfile(lockPath)
if err != nil {
return errors.Wrapf(err, "error retrieving lockfile for pod %s", string(id))
diff --git a/libpod/container_internal.go b/libpod/container_internal.go
index e31a8099c..934ad7a22 100644
--- a/libpod/container_internal.go
+++ b/libpod/container_internal.go
@@ -1168,10 +1168,6 @@ func (c *Container) saveSpec(spec *spec.Spec) error {
}
func (c *Container) setupOCIHooks(ctx context.Context, config *spec.Spec) (extensionStageHooks map[string][]spec.Hook, err error) {
- if len(c.runtime.config.HooksDir) == 0 {
- return nil, nil
- }
-
var locale string
var ok bool
for _, envVar := range []string{
@@ -1199,25 +1195,39 @@ func (c *Container) setupOCIHooks(ctx context.Context, config *spec.Spec) (exten
}
}
- allHooks := make(map[string][]spec.Hook)
- for _, hDir := range c.runtime.config.HooksDir {
- manager, err := hooks.New(ctx, []string{hDir}, []string{"poststop"}, lang)
- if err != nil {
- if c.runtime.config.HooksDirNotExistFatal || !os.IsNotExist(err) {
- return nil, err
- }
- logrus.Warnf("failed to load hooks: %q", err)
+ if c.runtime.config.HooksDir == nil {
+ if rootless.IsRootless() {
return nil, nil
}
- hooks, err := manager.Hooks(config, c.Spec().Annotations, len(c.config.UserVolumes) > 0)
- if err != nil {
- return nil, err
- }
- for i, hook := range hooks {
- allHooks[i] = hook
+ allHooks := make(map[string][]spec.Hook)
+ for _, hDir := range []string{hooks.DefaultDir, hooks.OverrideDir} {
+ manager, err := hooks.New(ctx, []string{hDir}, []string{"poststop"}, lang)
+ if err != nil {
+ if os.IsNotExist(err) {
+ continue
+ }
+ return nil, err
+ }
+ hooks, err := manager.Hooks(config, c.Spec().Annotations, len(c.config.UserVolumes) > 0)
+ if err != nil {
+ return nil, err
+ }
+ if len(hooks) > 0 || config.Hooks != nil {
+ logrus.Warnf("implicit hook directories are deprecated; set --hooks-dir=%q explicitly to continue to load hooks from this directory", hDir)
+ }
+ for i, hook := range hooks {
+ allHooks[i] = hook
+ }
}
+ return allHooks, nil
}
- return allHooks, nil
+
+ manager, err := hooks.New(ctx, c.runtime.config.HooksDir, []string{"poststop"}, lang)
+ if err != nil {
+ return nil, err
+ }
+
+ return manager.Hooks(config, c.Spec().Annotations, len(c.config.UserVolumes) > 0)
}
// mount mounts the container's root filesystem
diff --git a/libpod/container_internal_linux.go b/libpod/container_internal_linux.go
index b72eefdf1..b540bbeb8 100644
--- a/libpod/container_internal_linux.go
+++ b/libpod/container_internal_linux.go
@@ -224,10 +224,8 @@ func (c *Container) generateSpec(ctx context.Context) (*spec.Spec, error) {
}
}
- if !rootless.IsRootless() {
- if c.state.ExtensionStageHooks, err = c.setupOCIHooks(ctx, g.Config); err != nil {
- return nil, errors.Wrapf(err, "error setting up OCI Hooks")
- }
+ if c.state.ExtensionStageHooks, err = c.setupOCIHooks(ctx, g.Config); err != nil {
+ return nil, errors.Wrapf(err, "error setting up OCI Hooks")
}
// Bind builtin image volumes
diff --git a/libpod/in_memory_state.go b/libpod/in_memory_state.go
index 78e765ccd..77eba0cc6 100644
--- a/libpod/in_memory_state.go
+++ b/libpod/in_memory_state.go
@@ -73,6 +73,18 @@ func (s *InMemoryState) Refresh() error {
return nil
}
+// GetDBConfig is not implemented for in-memory state.
+// As we do not store a config, return an empty one.
+func (s *InMemoryState) GetDBConfig() (*DBConfig, error) {
+ return &DBConfig{}, nil
+}
+
+// ValidateDBConfig is not implemented for the in-memory state.
+// Since we do nothing just return no error.
+func (s *InMemoryState) ValidateDBConfig(runtime *Runtime) error {
+ return nil
+}
+
// SetNamespace sets the namespace for container and pod retrieval.
func (s *InMemoryState) SetNamespace(ns string) error {
s.namespace = ns
diff --git a/libpod/options.go b/libpod/options.go
index 7f4e3ac6b..3e43d73f0 100644
--- a/libpod/options.go
+++ b/libpod/options.go
@@ -29,19 +29,40 @@ func WithStorageConfig(config storage.StoreOptions) RuntimeOption {
return ErrRuntimeFinalized
}
- rt.config.StorageConfig.RunRoot = config.RunRoot
- rt.config.StorageConfig.GraphRoot = config.GraphRoot
- rt.config.StorageConfig.GraphDriverName = config.GraphDriverName
- rt.config.StaticDir = filepath.Join(config.GraphRoot, "libpod")
+ if config.RunRoot != "" {
+ rt.config.StorageConfig.RunRoot = config.RunRoot
+ rt.configuredFrom.storageRunRootSet = true
+ }
+
+ if config.GraphRoot != "" {
+ rt.config.StorageConfig.GraphRoot = config.GraphRoot
+ rt.configuredFrom.storageGraphRootSet = true
+
+ // Also set libpod static dir, so we are a subdirectory
+ // of the c/storage store by default
+ rt.config.StaticDir = filepath.Join(config.GraphRoot, "libpod")
+ rt.configuredFrom.libpodStaticDirSet = true
+ }
+
+ if config.GraphDriverName != "" {
+ rt.config.StorageConfig.GraphDriverName = config.GraphDriverName
+ rt.configuredFrom.storageGraphDriverSet = true
+ }
- rt.config.StorageConfig.GraphDriverOptions = make([]string, len(config.GraphDriverOptions))
- copy(rt.config.StorageConfig.GraphDriverOptions, config.GraphDriverOptions)
+ if config.GraphDriverOptions != nil {
+ rt.config.StorageConfig.GraphDriverOptions = make([]string, len(config.GraphDriverOptions))
+ copy(rt.config.StorageConfig.GraphDriverOptions, config.GraphDriverOptions)
+ }
- rt.config.StorageConfig.UIDMap = make([]idtools.IDMap, len(config.UIDMap))
- copy(rt.config.StorageConfig.UIDMap, config.UIDMap)
+ if config.UIDMap != nil {
+ rt.config.StorageConfig.UIDMap = make([]idtools.IDMap, len(config.UIDMap))
+ copy(rt.config.StorageConfig.UIDMap, config.UIDMap)
+ }
- rt.config.StorageConfig.GIDMap = make([]idtools.IDMap, len(config.GIDMap))
- copy(rt.config.StorageConfig.GIDMap, config.GIDMap)
+ if config.GIDMap != nil {
+ rt.config.StorageConfig.GIDMap = make([]idtools.IDMap, len(config.GIDMap))
+ copy(rt.config.StorageConfig.GIDMap, config.GIDMap)
+ }
return nil
}
@@ -174,26 +195,26 @@ func WithStaticDir(dir string) RuntimeOption {
}
rt.config.StaticDir = dir
+ rt.configuredFrom.libpodStaticDirSet = true
return nil
}
}
-// WithHooksDir sets the directory to look for OCI runtime hooks config.
-// Note we are not saving this in database, since this is really just for used
-// for testing.
-func WithHooksDir(hooksDir string) RuntimeOption {
+// WithHooksDir sets the directories to look for OCI runtime hook configuration.
+func WithHooksDir(hooksDirs ...string) RuntimeOption {
return func(rt *Runtime) error {
if rt.valid {
return ErrRuntimeFinalized
}
- if hooksDir == "" {
- return errors.Wrap(ErrInvalidArg, "empty-string hook directories are not supported")
+ for _, hooksDir := range hooksDirs {
+ if hooksDir == "" {
+ return errors.Wrap(ErrInvalidArg, "empty-string hook directories are not supported")
+ }
}
- rt.config.HooksDir = []string{hooksDir}
- rt.config.HooksDirNotExistFatal = true
+ rt.config.HooksDir = hooksDirs
return nil
}
}
@@ -226,6 +247,7 @@ func WithTmpDir(dir string) RuntimeOption {
}
rt.config.TmpDir = dir
+ rt.configuredFrom.libpodTmpDirSet = true
return nil
}
diff --git a/libpod/runtime.go b/libpod/runtime.go
index 9feae03fc..6b6a8cc2d 100644
--- a/libpod/runtime.go
+++ b/libpod/runtime.go
@@ -12,7 +12,6 @@ import (
"github.com/containers/image/types"
"github.com/containers/libpod/libpod/image"
"github.com/containers/libpod/pkg/firewall"
- "github.com/containers/libpod/pkg/hooks"
sysreg "github.com/containers/libpod/pkg/registries"
"github.com/containers/libpod/pkg/rootless"
"github.com/containers/libpod/pkg/util"
@@ -84,6 +83,7 @@ type Runtime struct {
lock sync.RWMutex
imageRuntime *image.Runtime
firewallBackend firewall.FirewallBackend
+ configuredFrom *runtimeConfiguredFrom
}
// RuntimeConfig contains configuration options used to set up the runtime
@@ -141,11 +141,11 @@ type RuntimeConfig struct {
// CNIDefaultNetwork is the network name of the default CNI network
// to attach pods to
CNIDefaultNetwork string `toml:"cni_default_network,omitempty"`
- // HooksDir Path to the directory containing hooks configuration files
+ // HooksDir holds paths to the directories containing hooks
+ // configuration files. When the same filename is present in in
+ // multiple directories, the file in the directory listed last in
+ // this slice takes precedence.
HooksDir []string `toml:"hooks_dir"`
- // HooksDirNotExistFatal switches between fatal errors and non-fatal
- // warnings if the configured HooksDir does not exist.
- HooksDirNotExistFatal bool `toml:"hooks_dir_not_exist_fatal"`
// DefaultMountsFile is the path to the default mounts file for testing
// purposes only
DefaultMountsFile string `toml:"-"`
@@ -175,6 +175,20 @@ type RuntimeConfig struct {
EnableLabeling bool `toml:"label"`
}
+// runtimeConfiguredFrom is a struct used during early runtime init to help
+// assemble the full RuntimeConfig struct from defaults.
+// It indicated whether several fields in the runtime configuration were set
+// explicitly.
+// If they were not, we may override them with information from the database,
+// if it exists and differs from what is present in the system already.
+type runtimeConfiguredFrom struct {
+ storageGraphDriverSet bool
+ storageGraphRootSet bool
+ storageRunRootSet bool
+ libpodStaticDirSet bool
+ libpodTmpDirSet bool
+}
+
var (
defaultRuntimeConfig = RuntimeConfig{
// Leave this empty so containers/storage will use its defaults
@@ -203,7 +217,6 @@ var (
"PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin",
},
CgroupManager: SystemdCgroupsManager,
- HooksDir: []string{hooks.DefaultDir, hooks.OverrideDir},
StaticDir: filepath.Join(storage.DefaultStoreOptions.GraphRoot, "libpod"),
TmpDir: "",
MaxLogSize: -1,
@@ -253,6 +266,7 @@ func SetXdgRuntimeDir(val string) error {
func NewRuntime(options ...RuntimeOption) (runtime *Runtime, err error) {
runtime = new(Runtime)
runtime.config = new(RuntimeConfig)
+ runtime.configuredFrom = new(runtimeConfiguredFrom)
// Copy the default configuration
tmpDir, err := getDefaultTmpDir()
@@ -262,6 +276,16 @@ func NewRuntime(options ...RuntimeOption) (runtime *Runtime, err error) {
deepcopier.Copy(defaultRuntimeConfig).To(runtime.config)
runtime.config.TmpDir = tmpDir
+ if rootless.IsRootless() {
+ // If we're rootless, override the default storage config
+ storageConf, err := util.GetDefaultStoreOptions()
+ if err != nil {
+ return nil, errors.Wrapf(err, "error retrieving rootless storage config")
+ }
+ runtime.config.StorageConfig = storageConf
+ runtime.config.StaticDir = filepath.Join(storageConf.GraphRoot, "libpod")
+ }
+
configPath := ConfigPath
foundConfig := true
rootlessConfigPath := ""
@@ -307,6 +331,25 @@ func NewRuntime(options ...RuntimeOption) (runtime *Runtime, err error) {
if err != nil {
return nil, errors.Wrapf(err, "error reading configuration file %s", configPath)
}
+
+ // This is ugly, but we need to decode twice.
+ // Once to check if libpod static and tmp dirs were explicitly
+ // set (not enough to check if they're not the default value,
+ // might have been explicitly configured to the default).
+ // A second time to actually get a usable config.
+ tmpConfig := new(RuntimeConfig)
+ if _, err := toml.Decode(string(contents), tmpConfig); err != nil {
+ return nil, errors.Wrapf(err, "error decoding configuration file %s",
+ configPath)
+ }
+
+ if tmpConfig.StaticDir != "" {
+ runtime.configuredFrom.libpodStaticDirSet = true
+ }
+ if tmpConfig.TmpDir != "" {
+ runtime.configuredFrom.libpodTmpDirSet = true
+ }
+
if _, err := toml.Decode(string(contents), runtime.config); err != nil {
return nil, errors.Wrapf(err, "error decoding configuration file %s", configPath)
}
@@ -348,6 +391,7 @@ func NewRuntime(options ...RuntimeOption) (runtime *Runtime, err error) {
func NewRuntimeFromConfig(configPath string, options ...RuntimeOption) (runtime *Runtime, err error) {
runtime = new(Runtime)
runtime.config = new(RuntimeConfig)
+ runtime.configuredFrom = new(runtimeConfiguredFrom)
// Set two fields not in the TOML config
runtime.config.StateType = defaultRuntimeConfig.StateType
@@ -426,6 +470,77 @@ func makeRuntime(runtime *Runtime) (err error) {
runtime.config.ConmonPath)
}
+ // Make the static files directory if it does not exist
+ if err := os.MkdirAll(runtime.config.StaticDir, 0700); err != nil {
+ // The directory is allowed to exist
+ if !os.IsExist(err) {
+ return errors.Wrapf(err, "error creating runtime static files directory %s",
+ runtime.config.StaticDir)
+ }
+ }
+
+ // Set up the state
+ switch runtime.config.StateType {
+ case InMemoryStateStore:
+ state, err := NewInMemoryState()
+ if err != nil {
+ return err
+ }
+ runtime.state = state
+ case SQLiteStateStore:
+ return errors.Wrapf(ErrInvalidArg, "SQLite state is currently disabled")
+ case BoltDBStateStore:
+ dbPath := filepath.Join(runtime.config.StaticDir, "bolt_state.db")
+
+ state, err := NewBoltState(dbPath, runtime)
+ if err != nil {
+ return err
+ }
+ runtime.state = state
+ default:
+ return errors.Wrapf(ErrInvalidArg, "unrecognized state type passed")
+ }
+
+ // Grab config from the database so we can reset some defaults
+ dbConfig, err := runtime.state.GetDBConfig()
+ if err != nil {
+ return errors.Wrapf(err, "error retrieving runtime configuration from database")
+ }
+
+ // Reset defaults if they were not explicitly set
+ if !runtime.configuredFrom.storageGraphDriverSet && dbConfig.GraphDriver != "" {
+ runtime.config.StorageConfig.GraphDriverName = dbConfig.GraphDriver
+ }
+ if !runtime.configuredFrom.storageGraphRootSet && dbConfig.StorageRoot != "" {
+ runtime.config.StorageConfig.GraphRoot = dbConfig.StorageRoot
+ }
+ if !runtime.configuredFrom.storageRunRootSet && dbConfig.StorageTmp != "" {
+ runtime.config.StorageConfig.RunRoot = dbConfig.StorageTmp
+ }
+ if !runtime.configuredFrom.libpodStaticDirSet && dbConfig.LibpodRoot != "" {
+ runtime.config.StaticDir = dbConfig.LibpodRoot
+ }
+ if !runtime.configuredFrom.libpodTmpDirSet && dbConfig.LibpodTmp != "" {
+ runtime.config.TmpDir = dbConfig.LibpodTmp
+ }
+
+ logrus.Debugf("Using graph driver %s", runtime.config.StorageConfig.GraphDriverName)
+ logrus.Debugf("Using graph root %s", runtime.config.StorageConfig.GraphRoot)
+ logrus.Debugf("Using run root %s", runtime.config.StorageConfig.RunRoot)
+ logrus.Debugf("Using static dir %s", runtime.config.StaticDir)
+ logrus.Debugf("Using tmp dir %s", runtime.config.TmpDir)
+
+ // Validate our config against the database, now that we've set our
+ // final storage configuration
+ if err := runtime.state.ValidateDBConfig(runtime); err != nil {
+ return err
+ }
+
+ if err := runtime.state.SetNamespace(runtime.config.Namespace); err != nil {
+ return errors.Wrapf(err, "error setting libpod namespace in state")
+ }
+ logrus.Debugf("Set libpod namespace to %q", runtime.config.Namespace)
+
// Set up containers/storage
var store storage.Store
if rootless.SkipStorageSetup() {
@@ -493,15 +608,6 @@ func makeRuntime(runtime *Runtime) (err error) {
}
runtime.ociRuntime = ociRuntime
- // Make the static files directory if it does not exist
- if err := os.MkdirAll(runtime.config.StaticDir, 0755); err != nil {
- // The directory is allowed to exist
- if !os.IsExist(err) {
- return errors.Wrapf(err, "error creating runtime static files directory %s",
- runtime.config.StaticDir)
- }
- }
-
// Make a directory to hold container lockfiles
lockDir := filepath.Join(runtime.config.TmpDir, "lock")
if err := os.MkdirAll(lockDir, 0755); err != nil {
@@ -523,11 +629,13 @@ func makeRuntime(runtime *Runtime) (err error) {
}
// Set up the CNI net plugin
- netPlugin, err := ocicni.InitCNI(runtime.config.CNIDefaultNetwork, runtime.config.CNIConfigDir, runtime.config.CNIPluginDir...)
- if err != nil {
- return errors.Wrapf(err, "error configuring CNI network plugin")
+ if !rootless.IsRootless() {
+ netPlugin, err := ocicni.InitCNI(runtime.config.CNIDefaultNetwork, runtime.config.CNIConfigDir, runtime.config.CNIPluginDir...)
+ if err != nil {
+ return errors.Wrapf(err, "error configuring CNI network plugin")
+ }
+ runtime.netPlugin = netPlugin
}
- runtime.netPlugin = netPlugin
// Set up a firewall backend
backendType := ""
@@ -540,33 +648,6 @@ func makeRuntime(runtime *Runtime) (err error) {
}
runtime.firewallBackend = fwBackend
- // Set up the state
- switch runtime.config.StateType {
- case InMemoryStateStore:
- state, err := NewInMemoryState()
- if err != nil {
- return err
- }
- runtime.state = state
- case SQLiteStateStore:
- return errors.Wrapf(ErrInvalidArg, "SQLite state is currently disabled")
- case BoltDBStateStore:
- dbPath := filepath.Join(runtime.config.StaticDir, "bolt_state.db")
-
- state, err := NewBoltState(dbPath, runtime.lockDir, runtime)
- if err != nil {
- return err
- }
- runtime.state = state
- default:
- return errors.Wrapf(ErrInvalidArg, "unrecognized state type passed")
- }
-
- if err := runtime.state.SetNamespace(runtime.config.Namespace); err != nil {
- return errors.Wrapf(err, "error setting libpod namespace in state")
- }
- logrus.Debugf("Set libpod namespace to %q", runtime.config.Namespace)
-
// We now need to see if the system has restarted
// We check for the presence of a file in our tmp directory to verify this
// This check must be locked to prevent races
diff --git a/libpod/state.go b/libpod/state.go
index 273e81318..06c2003d8 100644
--- a/libpod/state.go
+++ b/libpod/state.go
@@ -1,5 +1,15 @@
package libpod
+// DBConfig is a set of Libpod runtime configuration settings that are saved
+// in a State when it is first created, and can subsequently be retrieved.
+type DBConfig struct {
+ LibpodRoot string
+ LibpodTmp string
+ StorageRoot string
+ StorageTmp string
+ GraphDriver string
+}
+
// State is a storage backend for libpod's current state.
// A State is only initialized once per instance of libpod.
// As such, initialization methods for State implementations may safely assume
@@ -21,6 +31,22 @@ type State interface {
// Refresh clears container and pod states after a reboot
Refresh() error
+ // GetDBConfig retrieves several paths configured within the database
+ // when it was created - namely, Libpod root and tmp dirs, c/storage
+ // root and tmp dirs, and c/storage graph driver.
+ // This is not implemented by the in-memory state, as it has no need to
+ // validate runtime configuration.
+ GetDBConfig() (*DBConfig, error)
+
+ // ValidateDBConfig validates the config in the given Runtime struct
+ // against paths stored in the configured database.
+ // Libpod root and tmp dirs and c/storage root and tmp dirs and graph
+ // driver are validated.
+ // This is not implemented by the in-memory state, as it has no need to
+ // validate runtime configuration that may change over multiple runs of
+ // the program.
+ ValidateDBConfig(runtime *Runtime) error
+
// SetNamespace() sets the namespace for the store, and will determine
// what containers are retrieved with container and pod retrieval calls.
// A namespace of "", the empty string, acts as no namespace, and
diff --git a/libpod/state_test.go b/libpod/state_test.go
index 04572fb29..d93a371f3 100644
--- a/libpod/state_test.go
+++ b/libpod/state_test.go
@@ -45,11 +45,16 @@ func getEmptyBoltState() (s State, p string, p2 string, err error) {
dbPath := filepath.Join(tmpDir, "db.sql")
lockDir := filepath.Join(tmpDir, "locks")
+ if err := os.Mkdir(lockDir, 0755); err != nil {
+ return nil, "", "", err
+ }
+
runtime := new(Runtime)
runtime.config = new(RuntimeConfig)
runtime.config.StorageConfig = storage.StoreOptions{}
+ runtime.lockDir = lockDir
- state, err := NewBoltState(dbPath, lockDir, runtime)
+ state, err := NewBoltState(dbPath, runtime)
if err != nil {
return nil, "", "", err
}
diff --git a/libpod/testdata/config.toml b/libpod/testdata/config.toml
index e19d36017..1d78f2083 100644
--- a/libpod/testdata/config.toml
+++ b/libpod/testdata/config.toml
@@ -14,7 +14,7 @@
seccomp_profile = "/etc/crio/seccomp.json"
apparmor_profile = "crio-default"
cgroup_manager = "cgroupfs"
- hooks_dir_path = "/usr/share/containers/oci/hooks.d"
+ hooks_dir = ["/usr/share/containers/oci/hooks.d"]
pids_limit = 2048
container_exits_dir = "/var/run/podman/exits"
[crio.image]
diff --git a/pkg/util/utils.go b/pkg/util/utils.go
index de29bc5d8..e483253a4 100644
--- a/pkg/util/utils.go
+++ b/pkg/util/utils.go
@@ -313,7 +313,7 @@ func getTomlStorage(storeOptions *storage.StoreOptions) *tomlConfig {
return config
}
-// GetDefaultStoreOptions returns the storage ops for containers
+// GetDefaultStoreOptions returns the default storage options for containers.
func GetDefaultStoreOptions() (storage.StoreOptions, error) {
storageOpts := storage.DefaultStoreOptions
if rootless.IsRootless() {
diff --git a/test/e2e/rmi_test.go b/test/e2e/rmi_test.go
index c2eb8b7d7..22bfbbe8c 100644
--- a/test/e2e/rmi_test.go
+++ b/test/e2e/rmi_test.go
@@ -250,4 +250,25 @@ var _ = Describe("Podman rmi", func() {
session2.WaitWithDefaultTimeout()
Expect(session2.ExitCode()).To(Equal(0))
})
+
+ It("podman rmi -a with parent|child images", func() {
+ dockerfile := `FROM docker.io/library/alpine:latest AS base
+RUN touch /1
+ENV LOCAL=/1
+RUN find $LOCAL
+FROM base
+RUN find $LOCAL
+
+`
+ podmanTest.BuildImage(dockerfile, "test", "true")
+ session := podmanTest.Podman([]string{"rmi", "-a"})
+ session.WaitWithDefaultTimeout()
+ fmt.Println(session.OutputToString())
+ Expect(session.ExitCode()).To(Equal(0))
+
+ images := podmanTest.Podman([]string{"images", "--all"})
+ images.WaitWithDefaultTimeout()
+ Expect(images.ExitCode()).To(Equal(0))
+ Expect(len(images.OutputToStringArray())).To(Equal(0))
+ })
})
diff --git a/test/e2e/run_test.go b/test/e2e/run_test.go
index aaee7fa53..4a9bd4e46 100644
--- a/test/e2e/run_test.go
+++ b/test/e2e/run_test.go
@@ -336,7 +336,7 @@ var _ = Describe("Podman run", func() {
hooksDir := tempdir + "/hooks"
os.Mkdir(hooksDir, 0755)
fileutils.CopyFile("hooks/hooks.json", hooksDir)
- os.Setenv("HOOK_OPTION", fmt.Sprintf("--hooks-dir-path=%s", hooksDir))
+ os.Setenv("HOOK_OPTION", fmt.Sprintf("--hooks-dir=%s", hooksDir))
os.Remove(hcheck)
session := podmanTest.Podman([]string{"run", ALPINE, "ls"})
session.Wait(10)
diff --git a/vendor.conf b/vendor.conf
index be306a181..51907f763 100644
--- a/vendor.conf
+++ b/vendor.conf
@@ -12,7 +12,7 @@ github.com/containerd/continuity master
github.com/containernetworking/cni v0.7.0-alpha1
github.com/containernetworking/plugins 1562a1e60ed101aacc5e08ed9dbeba8e9f3d4ec1
github.com/containers/image bd10b1b53b2976f215b3f2f848fb8e7cad779aeb
-github.com/containers/storage 9d3838cd434d32042f9bdf1f9f4a2bf2d6ea8dc5
+github.com/containers/storage ad0f9c4dfa38fcb160f430ff1d653dc3dae03810
github.com/containers/psgo 5dde6da0bc8831b35243a847625bcf18183bd1ee
github.com/coreos/go-systemd v14
github.com/cri-o/ocicni 2d2983e40c242322a56c22a903785e7f83eb378c
diff --git a/vendor/github.com/containers/storage/drivers/fsdiff.go b/vendor/github.com/containers/storage/drivers/fsdiff.go
index 19da7d101..ab2c41e58 100644
--- a/vendor/github.com/containers/storage/drivers/fsdiff.go
+++ b/vendor/github.com/containers/storage/drivers/fsdiff.go
@@ -8,6 +8,7 @@ import (
"github.com/containers/storage/pkg/chrootarchive"
"github.com/containers/storage/pkg/idtools"
"github.com/containers/storage/pkg/ioutils"
+ rsystem "github.com/opencontainers/runc/libcontainer/system"
"github.com/sirupsen/logrus"
)
@@ -167,7 +168,9 @@ func (gdw *NaiveDiffDriver) ApplyDiff(id string, applyMappings *idtools.IDMappin
}
defer driver.Put(id)
- options := &archive.TarOptions{}
+ options := &archive.TarOptions{
+ InUserNS: rsystem.RunningInUserNS(),
+ }
if applyMappings != nil {
options.UIDMaps = applyMappings.UIDs()
options.GIDMaps = applyMappings.GIDs()
diff --git a/vendor/github.com/containers/storage/drivers/overlay/overlay.go b/vendor/github.com/containers/storage/drivers/overlay/overlay.go
index a165a13a3..df736c0a9 100644
--- a/vendor/github.com/containers/storage/drivers/overlay/overlay.go
+++ b/vendor/github.com/containers/storage/drivers/overlay/overlay.go
@@ -29,6 +29,7 @@ import (
"github.com/containers/storage/pkg/parsers"
"github.com/containers/storage/pkg/system"
units "github.com/docker/go-units"
+ rsystem "github.com/opencontainers/runc/libcontainer/system"
"github.com/opencontainers/selinux/go-selinux/label"
"github.com/pkg/errors"
"github.com/sirupsen/logrus"
@@ -876,6 +877,7 @@ func (d *Driver) ApplyDiff(id string, idMappings *idtools.IDMappings, parent str
UIDMaps: idMappings.UIDs(),
GIDMaps: idMappings.GIDs(),
WhiteoutFormat: d.getWhiteoutFormat(),
+ InUserNS: rsystem.RunningInUserNS(),
}); err != nil {
return 0, err
}
diff --git a/vendor/github.com/containers/storage/layers.go b/vendor/github.com/containers/storage/layers.go
index 6c8f59b8b..0b532eb77 100644
--- a/vendor/github.com/containers/storage/layers.go
+++ b/vendor/github.com/containers/storage/layers.go
@@ -28,9 +28,8 @@ import (
)
const (
- tarSplitSuffix = ".tar-split.gz"
- incompleteFlag = "incomplete"
- compressionFlag = "diff-compression"
+ tarSplitSuffix = ".tar-split.gz"
+ incompleteFlag = "incomplete"
)
// A Layer is a record of a copy-on-write layer that's stored by the lower
diff --git a/vendor/github.com/containers/storage/pkg/archive/archive.go b/vendor/github.com/containers/storage/pkg/archive/archive.go
index 4c4382625..8d6eaacf3 100644
--- a/vendor/github.com/containers/storage/pkg/archive/archive.go
+++ b/vendor/github.com/containers/storage/pkg/archive/archive.go
@@ -22,6 +22,7 @@ import (
"github.com/containers/storage/pkg/pools"
"github.com/containers/storage/pkg/promise"
"github.com/containers/storage/pkg/system"
+ rsystem "github.com/opencontainers/runc/libcontainer/system"
"github.com/sirupsen/logrus"
)
@@ -1054,6 +1055,7 @@ func (archiver *Archiver) TarUntar(src, dst string) error {
GIDMaps: tarMappings.GIDs(),
Compression: Uncompressed,
CopyPass: true,
+ InUserNS: rsystem.RunningInUserNS(),
}
archive, err := TarWithOptions(src, options)
if err != nil {
@@ -1068,6 +1070,7 @@ func (archiver *Archiver) TarUntar(src, dst string) error {
UIDMaps: untarMappings.UIDs(),
GIDMaps: untarMappings.GIDs(),
ChownOpts: archiver.ChownOpts,
+ InUserNS: rsystem.RunningInUserNS(),
}
return archiver.Untar(archive, dst, options)
}
@@ -1087,6 +1090,7 @@ func (archiver *Archiver) UntarPath(src, dst string) error {
UIDMaps: untarMappings.UIDs(),
GIDMaps: untarMappings.GIDs(),
ChownOpts: archiver.ChownOpts,
+ InUserNS: rsystem.RunningInUserNS(),
}
return archiver.Untar(archive, dst, options)
}
@@ -1186,6 +1190,7 @@ func (archiver *Archiver) CopyFileWithTar(src, dst string) (err error) {
UIDMaps: archiver.UntarIDMappings.UIDs(),
GIDMaps: archiver.UntarIDMappings.GIDs(),
ChownOpts: archiver.ChownOpts,
+ InUserNS: rsystem.RunningInUserNS(),
}
err = archiver.Untar(r, filepath.Dir(dst), options)
if err != nil {
diff --git a/vendor/github.com/containers/storage/pkg/archive/example_changes.go b/vendor/github.com/containers/storage/pkg/archive/example_changes.go
deleted file mode 100644
index 70f9c5564..000000000
--- a/vendor/github.com/containers/storage/pkg/archive/example_changes.go
+++ /dev/null
@@ -1,97 +0,0 @@
-// +build ignore
-
-// Simple tool to create an archive stream from an old and new directory
-//
-// By default it will stream the comparison of two temporary directories with junk files
-package main
-
-import (
- "flag"
- "fmt"
- "io"
- "io/ioutil"
- "os"
- "path"
-
- "github.com/containers/storage/pkg/archive"
- "github.com/sirupsen/logrus"
-)
-
-var (
- flDebug = flag.Bool("D", false, "debugging output")
- flNewDir = flag.String("newdir", "", "")
- flOldDir = flag.String("olddir", "", "")
- log = logrus.New()
-)
-
-func main() {
- flag.Usage = func() {
- fmt.Println("Produce a tar from comparing two directory paths. By default a demo tar is created of around 200 files (including hardlinks)")
- fmt.Printf("%s [OPTIONS]\n", os.Args[0])
- flag.PrintDefaults()
- }
- flag.Parse()
- log.Out = os.Stderr
- if (len(os.Getenv("DEBUG")) > 0) || *flDebug {
- logrus.SetLevel(logrus.DebugLevel)
- }
- var newDir, oldDir string
-
- if len(*flNewDir) == 0 {
- var err error
- newDir, err = ioutil.TempDir("", "storage-test-newDir")
- if err != nil {
- log.Fatal(err)
- }
- defer os.RemoveAll(newDir)
- if _, err := prepareUntarSourceDirectory(100, newDir, true); err != nil {
- log.Fatal(err)
- }
- } else {
- newDir = *flNewDir
- }
-
- if len(*flOldDir) == 0 {
- oldDir, err := ioutil.TempDir("", "storage-test-oldDir")
- if err != nil {
- log.Fatal(err)
- }
- defer os.RemoveAll(oldDir)
- } else {
- oldDir = *flOldDir
- }
-
- changes, err := archive.ChangesDirs(newDir, oldDir)
- if err != nil {
- log.Fatal(err)
- }
-
- a, err := archive.ExportChanges(newDir, changes)
- if err != nil {
- log.Fatal(err)
- }
- defer a.Close()
-
- i, err := io.Copy(os.Stdout, a)
- if err != nil && err != io.EOF {
- log.Fatal(err)
- }
- fmt.Fprintf(os.Stderr, "wrote archive of %d bytes", i)
-}
-
-func prepareUntarSourceDirectory(numberOfFiles int, targetPath string, makeLinks bool) (int, error) {
- fileData := []byte("fooo")
- for n := 0; n < numberOfFiles; n++ {
- fileName := fmt.Sprintf("file-%d", n)
- if err := ioutil.WriteFile(path.Join(targetPath, fileName), fileData, 0700); err != nil {
- return 0, err
- }
- if makeLinks {
- if err := os.Link(path.Join(targetPath, fileName), path.Join(targetPath, fileName+"-link")); err != nil {
- return 0, err
- }
- }
- }
- totalSize := numberOfFiles * len(fileData)
- return totalSize, nil
-}
diff --git a/vendor/github.com/containers/storage/pkg/chrootarchive/archive.go b/vendor/github.com/containers/storage/pkg/chrootarchive/archive.go
index b9fa228e6..dde8d44d3 100644
--- a/vendor/github.com/containers/storage/pkg/chrootarchive/archive.go
+++ b/vendor/github.com/containers/storage/pkg/chrootarchive/archive.go
@@ -9,6 +9,7 @@ import (
"github.com/containers/storage/pkg/archive"
"github.com/containers/storage/pkg/idtools"
+ rsystem "github.com/opencontainers/runc/libcontainer/system"
)
// NewArchiver returns a new Archiver which uses chrootarchive.Untar
@@ -52,6 +53,7 @@ func untarHandler(tarArchive io.Reader, dest string, options *archive.TarOptions
}
if options == nil {
options = &archive.TarOptions{}
+ options.InUserNS = rsystem.RunningInUserNS()
}
if options.ExcludePatterns == nil {
options.ExcludePatterns = []string{}