summaryrefslogtreecommitdiff
path: root/libpod/container.go
diff options
context:
space:
mode:
Diffstat (limited to 'libpod/container.go')
-rw-r--r--libpod/container.go255
1 files changed, 162 insertions, 93 deletions
diff --git a/libpod/container.go b/libpod/container.go
index a34394792..e26235e26 100644
--- a/libpod/container.go
+++ b/libpod/container.go
@@ -348,11 +348,13 @@ func (c *Container) LogPath() string {
// IPAddress returns the IP address of the container
// If the container does not have a network namespace, an error will be returned
func (c *Container) IPAddress() (net.IP, error) {
- c.lock.Lock()
- defer c.lock.Unlock()
+ if !c.locked {
+ c.lock.Lock()
+ defer c.lock.Unlock()
- if err := c.syncContainer(); err != nil {
- return nil, errors.Wrapf(err, "error updating container %s state", c.ID())
+ if err := c.syncContainer(); err != nil {
+ return nil, errors.Wrapf(err, "error updating container %s state", c.ID())
+ }
}
if !c.config.CreateNetNS || c.state.NetNS == nil {
@@ -365,10 +367,12 @@ func (c *Container) IPAddress() (net.IP, error) {
// ExitCode returns the exit code of the container as
// an int32
func (c *Container) ExitCode() (int32, error) {
- c.lock.Lock()
- defer c.lock.Unlock()
- if err := c.syncContainer(); err != nil {
- return 0, errors.Wrapf(err, "error updating container %s state", c.ID())
+ if !c.locked {
+ c.lock.Lock()
+ defer c.lock.Unlock()
+ if err := c.syncContainer(); err != nil {
+ return 0, errors.Wrapf(err, "error updating container %s state", c.ID())
+ }
}
return c.state.ExitCode, nil
}
@@ -376,10 +380,12 @@ func (c *Container) ExitCode() (int32, error) {
// Mounted returns a bool as to if the container's storage
// is mounted
func (c *Container) Mounted() (bool, error) {
- c.lock.Lock()
- defer c.lock.Unlock()
- if err := c.syncContainer(); err != nil {
- return false, errors.Wrapf(err, "error updating container %s state", c.ID())
+ if !c.locked {
+ c.lock.Lock()
+ defer c.lock.Unlock()
+ if err := c.syncContainer(); err != nil {
+ return false, errors.Wrapf(err, "error updating container %s state", c.ID())
+ }
}
return c.state.Mounted, nil
}
@@ -387,41 +393,49 @@ func (c *Container) Mounted() (bool, error) {
// Mountpoint returns the path to the container's mounted
// storage as a string
func (c *Container) Mountpoint() (string, error) {
- c.lock.Lock()
- defer c.lock.Unlock()
- if err := c.syncContainer(); err != nil {
- return "", errors.Wrapf(err, "error updating container %s state", c.ID())
+ if !c.locked {
+ c.lock.Lock()
+ defer c.lock.Unlock()
+ if err := c.syncContainer(); err != nil {
+ return "", errors.Wrapf(err, "error updating container %s state", c.ID())
+ }
}
return c.state.Mountpoint, nil
}
// StartedTime is the time the container was started
func (c *Container) StartedTime() (time.Time, error) {
- c.lock.Lock()
- defer c.lock.Unlock()
- if err := c.syncContainer(); err != nil {
- return time.Time{}, errors.Wrapf(err, "error updating container %s state", c.ID())
+ if !c.locked {
+ c.lock.Lock()
+ defer c.lock.Unlock()
+ if err := c.syncContainer(); err != nil {
+ return time.Time{}, errors.Wrapf(err, "error updating container %s state", c.ID())
+ }
}
return c.state.StartedTime, nil
}
// FinishedTime is the time the container was stopped
func (c *Container) FinishedTime() (time.Time, error) {
- c.lock.Lock()
- defer c.lock.Unlock()
- if err := c.syncContainer(); err != nil {
- return time.Time{}, errors.Wrapf(err, "error updating container %s state", c.ID())
+ if !c.locked {
+ c.lock.Lock()
+ defer c.lock.Unlock()
+ if err := c.syncContainer(); err != nil {
+ return time.Time{}, errors.Wrapf(err, "error updating container %s state", c.ID())
+ }
}
return c.state.FinishedTime, nil
}
// State returns the current state of the container
func (c *Container) State() (ContainerState, error) {
- c.lock.Lock()
- defer c.lock.Unlock()
+ if !c.locked {
+ c.lock.Lock()
+ defer c.lock.Unlock()
- if err := c.syncContainer(); err != nil {
- return ContainerStateUnknown, err
+ if err := c.syncContainer(); err != nil {
+ return ContainerStateUnknown, err
+ }
}
return c.state.State, nil
}
@@ -429,11 +443,13 @@ func (c *Container) State() (ContainerState, error) {
// PID returns the PID of the container
// An error is returned if the container is not running
func (c *Container) PID() (int, error) {
- c.lock.Lock()
- defer c.lock.Unlock()
+ if !c.locked {
+ c.lock.Lock()
+ defer c.lock.Unlock()
- if err := c.syncContainer(); err != nil {
- return -1, err
+ if err := c.syncContainer(); err != nil {
+ return -1, err
+ }
}
return c.state.PID, nil
@@ -441,10 +457,12 @@ func (c *Container) PID() (int, error) {
// MountPoint returns the mount point of the continer
func (c *Container) MountPoint() (string, error) {
- c.lock.Lock()
- defer c.lock.Unlock()
- if err := c.syncContainer(); err != nil {
- return "", errors.Wrapf(err, "error updating container %s state", c.ID())
+ if !c.locked {
+ c.lock.Lock()
+ defer c.lock.Unlock()
+ if err := c.syncContainer(); err != nil {
+ return "", errors.Wrapf(err, "error updating container %s state", c.ID())
+ }
}
return c.state.Mountpoint, nil
}
@@ -612,11 +630,13 @@ func (c *Container) refresh() error {
// Init creates a container in the OCI runtime
func (c *Container) Init() (err error) {
- c.lock.Lock()
- defer c.lock.Unlock()
+ if !c.locked {
+ c.lock.Lock()
+ defer c.lock.Unlock()
- if err := c.syncContainer(); err != nil {
- return err
+ if err := c.syncContainer(); err != nil {
+ return err
+ }
}
if c.state.State != ContainerStateConfigured {
@@ -761,11 +781,13 @@ func (c *Container) Init() (err error) {
// Start starts a container
func (c *Container) Start() error {
- c.lock.Lock()
- defer c.lock.Unlock()
+ if !c.locked {
+ c.lock.Lock()
+ defer c.lock.Unlock()
- if err := c.syncContainer(); err != nil {
- return err
+ if err := c.syncContainer(); err != nil {
+ return err
+ }
}
// Container must be created or stopped to be started
@@ -797,14 +819,17 @@ func (c *Container) Start() error {
// seconds), uses SIGKILL to attempt to forcibly stop the container.
// If timeout is 0, SIGKILL will be used immediately
func (c *Container) Stop(timeout uint) error {
- c.lock.Lock()
- defer c.lock.Unlock()
- logrus.Debugf("Stopping ctr %s with timeout %d", c.ID(), timeout)
+ if !c.locked {
+ c.lock.Lock()
+ defer c.lock.Unlock()
- if err := c.syncContainer(); err != nil {
- return err
+ if err := c.syncContainer(); err != nil {
+ return err
+ }
}
+ logrus.Debugf("Stopping ctr %s with timeout %d", c.ID(), timeout)
+
if c.state.State == ContainerStateConfigured ||
c.state.State == ContainerStateUnknown ||
c.state.State == ContainerStatePaused {
@@ -825,11 +850,13 @@ func (c *Container) Stop(timeout uint) error {
// Kill sends a signal to a container
func (c *Container) Kill(signal uint) error {
- c.lock.Lock()
- defer c.lock.Unlock()
+ if !c.locked {
+ c.lock.Lock()
+ defer c.lock.Unlock()
- if err := c.syncContainer(); err != nil {
- return err
+ if err := c.syncContainer(); err != nil {
+ return err
+ }
}
if c.state.State != ContainerStateRunning {
@@ -842,11 +869,14 @@ func (c *Container) Kill(signal uint) error {
// Exec starts a new process inside the container
func (c *Container) Exec(tty, privileged bool, env, cmd []string, user string) error {
var capList []string
- c.lock.Lock()
- defer c.lock.Unlock()
- if err := c.syncContainer(); err != nil {
- return err
+ if !c.locked {
+ c.lock.Lock()
+ defer c.lock.Unlock()
+
+ if err := c.syncContainer(); err != nil {
+ return err
+ }
}
conState := c.state.State
@@ -875,8 +905,13 @@ func (c *Container) Exec(tty, privileged bool, env, cmd []string, user string) e
// Attach attaches to a container
// Returns fully qualified URL of streaming server for the container
func (c *Container) Attach(noStdin bool, keys string, attached chan<- bool) error {
- if err := c.syncContainer(); err != nil {
- return err
+ if !c.locked {
+ c.lock.Lock()
+ if err := c.syncContainer(); err != nil {
+ c.lock.Unlock()
+ return err
+ }
+ c.lock.Unlock()
}
if c.state.State != ContainerStateCreated &&
@@ -904,11 +939,13 @@ func (c *Container) Attach(noStdin bool, keys string, attached chan<- bool) erro
// Mount mounts a container's filesystem on the host
// The path where the container has been mounted is returned
func (c *Container) Mount(label string) (string, error) {
- c.lock.Lock()
- defer c.lock.Unlock()
+ if !c.locked {
+ c.lock.Lock()
+ defer c.lock.Unlock()
- if err := c.syncContainer(); err != nil {
- return "", err
+ if err := c.syncContainer(); err != nil {
+ return "", err
+ }
}
// return mountpoint if container already mounted
@@ -937,11 +974,13 @@ func (c *Container) Mount(label string) (string, error) {
// Unmount unmounts a container's filesystem on the host
func (c *Container) Unmount() error {
- c.lock.Lock()
- defer c.lock.Unlock()
+ if !c.locked {
+ c.lock.Lock()
+ defer c.lock.Unlock()
- if err := c.syncContainer(); err != nil {
- return err
+ if err := c.syncContainer(); err != nil {
+ return err
+ }
}
if c.state.State == ContainerStateRunning || c.state.State == ContainerStatePaused {
@@ -953,11 +992,13 @@ func (c *Container) Unmount() error {
// Pause pauses a container
func (c *Container) Pause() error {
- c.lock.Lock()
- defer c.lock.Unlock()
+ if !c.locked {
+ c.lock.Lock()
+ defer c.lock.Unlock()
- if err := c.syncContainer(); err != nil {
- return err
+ if err := c.syncContainer(); err != nil {
+ return err
+ }
}
if c.state.State == ContainerStatePaused {
@@ -982,11 +1023,13 @@ func (c *Container) Pause() error {
// Unpause unpauses a container
func (c *Container) Unpause() error {
- c.lock.Lock()
- defer c.lock.Unlock()
+ if !c.locked {
+ c.lock.Lock()
+ defer c.lock.Unlock()
- if err := c.syncContainer(); err != nil {
- return err
+ if err := c.syncContainer(); err != nil {
+ return err
+ }
}
if c.state.State != ContainerStatePaused {
@@ -1009,11 +1052,13 @@ func (c *Container) Unpause() error {
// Export exports a container's root filesystem as a tar archive
// The archive will be saved as a file at the given path
func (c *Container) Export(path string) error {
- c.lock.Lock()
- defer c.lock.Unlock()
+ if !c.locked {
+ c.lock.Lock()
+ defer c.lock.Unlock()
- if err := c.syncContainer(); err != nil {
- return err
+ if err := c.syncContainer(); err != nil {
+ return err
+ }
}
return c.export(path)
@@ -1051,16 +1096,28 @@ func (c *Container) export(path string) error {
// AddArtifact creates and writes to an artifact file for the container
func (c *Container) AddArtifact(name string, data []byte) error {
+ if !c.valid {
+ return ErrCtrRemoved
+ }
+
return ioutil.WriteFile(c.getArtifactPath(name), data, 0740)
}
// GetArtifact reads the specified artifact file from the container
func (c *Container) GetArtifact(name string) ([]byte, error) {
+ if !c.valid {
+ return nil, ErrCtrRemoved
+ }
+
return ioutil.ReadFile(c.getArtifactPath(name))
}
// RemoveArtifact deletes the specified artifacts file
func (c *Container) RemoveArtifact(name string) error {
+ if !c.valid {
+ return ErrCtrRemoved
+ }
+
return os.Remove(c.getArtifactPath(name))
}
@@ -1070,11 +1127,13 @@ func (c *Container) getArtifactPath(name string) string {
// Inspect a container for low-level information
func (c *Container) Inspect(size bool) (*ContainerInspectData, error) {
- c.lock.Lock()
- defer c.lock.Unlock()
+ if !c.locked {
+ c.lock.Lock()
+ defer c.lock.Unlock()
- if err := c.syncContainer(); err != nil {
- return nil, err
+ if err := c.syncContainer(); err != nil {
+ return nil, err
+ }
}
storeCtr, err := c.runtime.store.Container(c.ID())
@@ -1096,11 +1155,13 @@ func (c *Container) Inspect(size bool) (*ContainerInspectData, error) {
// Commit commits the changes between a container and its image, creating a new
// image
func (c *Container) Commit(pause bool, options CopyOptions) error {
- c.lock.Lock()
- defer c.lock.Unlock()
+ if !c.locked {
+ c.lock.Lock()
+ defer c.lock.Unlock()
- if err := c.syncContainer(); err != nil {
- return err
+ if err := c.syncContainer(); err != nil {
+ return err
+ }
}
if c.state.State == ContainerStateRunning && pause {
@@ -1129,6 +1190,10 @@ func (c *Container) Commit(pause bool, options CopyOptions) error {
// Wait blocks on a container to exit and returns its exit code
func (c *Container) Wait() (int32, error) {
+ if !c.valid {
+ return -1, ErrCtrRemoved
+ }
+
err := wait.PollImmediateInfinite(1,
func() (bool, error) {
stopped, err := c.isStopped()
@@ -1150,8 +1215,10 @@ func (c *Container) Wait() (int32, error) {
}
func (c *Container) isStopped() (bool, error) {
- c.lock.Lock()
- defer c.lock.Unlock()
+ if !c.locked {
+ c.lock.Lock()
+ defer c.lock.Unlock()
+ }
err := c.syncContainer()
if err != nil {
return true, err
@@ -1215,10 +1282,12 @@ func (c *Container) mountStorage() (err error) {
// CleanupStorage unmounts all mount points in container and cleans up container storage
func (c *Container) CleanupStorage() error {
- c.lock.Lock()
- defer c.lock.Unlock()
- if err := c.syncContainer(); err != nil {
- return err
+ if !c.locked {
+ c.lock.Lock()
+ defer c.lock.Unlock()
+ if err := c.syncContainer(); err != nil {
+ return err
+ }
}
return c.cleanupStorage()
}