summaryrefslogtreecommitdiff
path: root/libpod/container_internal.go
diff options
context:
space:
mode:
Diffstat (limited to 'libpod/container_internal.go')
-rw-r--r--libpod/container_internal.go51
1 files changed, 39 insertions, 12 deletions
diff --git a/libpod/container_internal.go b/libpod/container_internal.go
index 928be52ae..39c1501da 100644
--- a/libpod/container_internal.go
+++ b/libpod/container_internal.go
@@ -3,7 +3,6 @@ package libpod
import (
"bytes"
"context"
- "encoding/json"
"fmt"
"io"
"io/ioutil"
@@ -389,7 +388,7 @@ func (c *Container) teardownStorage() error {
// Reset resets state fields to default values
// It is performed before a refresh and clears the state after a reboot
// It does not save the results - assumes the database will do that for us
-func resetState(state *containerState) error {
+func resetState(state *ContainerState) error {
state.PID = 0
state.Mountpoint = ""
state.Mounted = false
@@ -401,7 +400,10 @@ func resetState(state *containerState) error {
return nil
}
-// Refresh refreshes the container's state after a restart
+// Refresh refreshes the container's state after a restart.
+// Refresh cannot perform any operations that would lock another container.
+// We cannot guarantee any other container has a valid lock at the time it is
+// running.
func (c *Container) refresh() error {
// Don't need a full sync, but we do need to update from the database to
// pick up potentially-missing container state
@@ -447,6 +449,13 @@ func (c *Container) refresh() error {
c.state.DestinationRunDir = filepath.Join(c.state.UserNSRoot, "rundir")
}
+ // We need to pick up a new lock
+ lock, err := c.runtime.lockManager.RetrieveLock(c.config.LockID)
+ if err != nil {
+ return errors.Wrapf(err, "error acquiring lock for container %s", c.ID())
+ }
+ c.lock = lock
+
if err := c.save(); err != nil {
return errors.Wrapf(err, "error refreshing state for container %s", c.ID())
}
@@ -531,7 +540,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
@@ -748,6 +757,10 @@ func (c *Container) initAndStart(ctx context.Context) (err error) {
// Internal, non-locking function to start a container
func (c *Container) start() error {
+ if c.config.Spec.Process != nil {
+ logrus.Debugf("Starting container %s with command %v", c.ID(), c.config.Spec.Process.Args)
+ }
+
if err := c.runtime.ociRuntime.startContainer(c); err != nil {
return err
}
@@ -1167,6 +1180,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
@@ -1195,13 +1209,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
@@ -1219,19 +1233,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