summaryrefslogtreecommitdiff
path: root/libpod
diff options
context:
space:
mode:
authorW. Trevor King <wking@tremily.us>2018-11-19 09:22:32 -0800
committerW. Trevor King <wking@tremily.us>2019-01-08 21:06:17 -0800
commitf6a2b6bf2b923a148792cc141ec4c27b5889c077 (patch)
treee4f6ba1dff72d3e597edcc2bce304fdd5b3849eb /libpod
parentc9d63fe89d0a79b069b56249aaa4c168b47649c0 (diff)
downloadpodman-f6a2b6bf2b923a148792cc141ec4c27b5889c077.tar.gz
podman-f6a2b6bf2b923a148792cc141ec4c27b5889c077.tar.bz2
podman-f6a2b6bf2b923a148792cc141ec4c27b5889c077.zip
hooks: Add pre-create hooks for runtime-config manipulation
There's been a lot of discussion over in [1] about how to support the NVIDIA folks and others who want to be able to create devices (possibly after having loaded kernel modules) and bind userspace libraries into the container. Currently that's happening in the middle of runc's create-time mount handling before the container pivots to its new root directory with runc's incorrectly-timed prestart hook trigger [2]. With this commit, we extend hooks with a 'precreate' stage to allow trusted parties to manipulate the config JSON before calling the runtime's 'create'. I'm recycling the existing Hook schema from pkg/hooks for this, because we'll want Timeout for reliability and When to avoid the expense of fork/exec when a given hook does not need to make config changes [3]. [1]: https://github.com/opencontainers/runc/pull/1811 [2]: https://github.com/opencontainers/runc/issues/1710 [3]: https://github.com/containers/libpod/issues/1828#issuecomment-439888059 Signed-off-by: W. Trevor King <wking@tremily.us>
Diffstat (limited to 'libpod')
-rw-r--r--libpod/container_internal.go30
-rw-r--r--libpod/container_internal_linux.go10
2 files changed, 28 insertions, 12 deletions
diff --git a/libpod/container_internal.go b/libpod/container_internal.go
index cc4c36bc9..69df33bc9 100644
--- a/libpod/container_internal.go
+++ b/libpod/container_internal.go
@@ -1181,6 +1181,7 @@ func (c *Container) saveSpec(spec *spec.Spec) error {
return nil
}
+// Warning: precreate hooks may alter 'config' in place.
func (c *Container) setupOCIHooks(ctx context.Context, config *spec.Spec) (extensionStageHooks map[string][]spec.Hook, err error) {
var locale string
var ok bool
@@ -1209,13 +1210,13 @@ func (c *Container) setupOCIHooks(ctx context.Context, config *spec.Spec) (exten
}
}
+ allHooks := make(map[string][]spec.Hook)
if c.runtime.config.HooksDir == nil {
if rootless.IsRootless() {
return nil, nil
}
- allHooks := make(map[string][]spec.Hook)
for _, hDir := range []string{hooks.DefaultDir, hooks.OverrideDir} {
- manager, err := hooks.New(ctx, []string{hDir}, []string{"poststop"}, lang)
+ manager, err := hooks.New(ctx, []string{hDir}, []string{"precreate", "poststop"}, lang)
if err != nil {
if os.IsNotExist(err) {
continue
@@ -1233,19 +1234,32 @@ func (c *Container) setupOCIHooks(ctx context.Context, config *spec.Spec) (exten
allHooks[i] = hook
}
}
- return allHooks, nil
+ } else {
+ manager, err := hooks.New(ctx, c.runtime.config.HooksDir, []string{"precreate", "poststop"}, lang)
+ if err != nil {
+ if os.IsNotExist(err) {
+ logrus.Warnf("Requested OCI hooks directory %q does not exist", c.runtime.config.HooksDir)
+ return nil, nil
+ }
+ return nil, err
+ }
+
+ allHooks, err = manager.Hooks(config, c.Spec().Annotations, len(c.config.UserVolumes) > 0)
+ if err != nil {
+ return nil, err
+ }
}
- manager, err := hooks.New(ctx, c.runtime.config.HooksDir, []string{"poststop"}, lang)
+ hookErr, err := exec.RuntimeConfigFilter(ctx, allHooks["precreate"], config, exec.DefaultPostKillTimeout)
if err != nil {
- if os.IsNotExist(err) {
- logrus.Warnf("Requested OCI hooks directory %q does not exist", c.runtime.config.HooksDir)
- return nil, nil
+ logrus.Warnf("container %s: precreate hook: %v", c.ID(), err)
+ if hookErr != nil && hookErr != err {
+ logrus.Debugf("container %s: precreate hook (hook error): %v", c.ID(), hookErr)
}
return nil, err
}
- return manager.Hooks(config, c.Spec().Annotations, len(c.config.UserVolumes) > 0)
+ return allHooks, nil
}
// mount mounts the container's root filesystem
diff --git a/libpod/container_internal_linux.go b/libpod/container_internal_linux.go
index 0745b7732..c66be1061 100644
--- a/libpod/container_internal_linux.go
+++ b/libpod/container_internal_linux.go
@@ -228,10 +228,6 @@ func (c *Container) generateSpec(ctx context.Context) (*spec.Spec, error) {
}
}
- 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
if c.config.Rootfs == "" && c.config.ImageVolumes {
if err := c.addLocalVolumes(ctx, &g, execUser); err != nil {
@@ -384,6 +380,12 @@ func (c *Container) generateSpec(ctx context.Context) (*spec.Spec, error) {
logrus.Debugf("set root propagation to %q", rootPropagation)
g.SetLinuxRootPropagation(rootPropagation)
}
+
+ // Warning: precreate hooks may alter g.Config in place.
+ if c.state.ExtensionStageHooks, err = c.setupOCIHooks(ctx, g.Config); err != nil {
+ return nil, errors.Wrapf(err, "error setting up OCI Hooks")
+ }
+
return g.Config, nil
}