diff options
author | Matthew Heon <matthew.heon@gmail.com> | 2018-03-12 15:32:10 -0400 |
---|---|---|
committer | Atomic Bot <atomic-devel@projectatomic.io> | 2018-03-13 13:54:45 +0000 |
commit | 40d302be8f9e3d1832d851cb016b2f568780a950 (patch) | |
tree | 1ea7a7e09f5b6fab2a456855d9eb437286cb16b1 /libpod/container_internal.go | |
parent | 58c35daea279bc4cac35fe7acc943315ec584bfd (diff) | |
download | podman-40d302be8f9e3d1832d851cb016b2f568780a950.tar.gz podman-40d302be8f9e3d1832d851cb016b2f568780a950.tar.bz2 podman-40d302be8f9e3d1832d851cb016b2f568780a950.zip |
Modify pod API to move Init() into Start()
Separate Init() and Start() does not make sense on the pod side,
where we may have to start containers in order to initialize
others due to dependency orders.
Also adjusts internal containers API for more code sharing.
Signed-off-by: Matthew Heon <matthew.heon@gmail.com>
Closes: #478
Approved by: rhatdan
Diffstat (limited to 'libpod/container_internal.go')
-rw-r--r-- | libpod/container_internal.go | 107 |
1 files changed, 101 insertions, 6 deletions
diff --git a/libpod/container_internal.go b/libpod/container_internal.go index 3c7637717..ba11dd2c6 100644 --- a/libpod/container_internal.go +++ b/libpod/container_internal.go @@ -313,16 +313,111 @@ func (c *Container) save() error { return nil } +// Initialize a container, creating it in the runtime +func (c *Container) init() error { + if err := c.makeBindMounts(); err != nil { + return err + } + + // Generate the OCI spec + spec, err := c.generateSpec() + if err != nil { + return err + } + + // Save the OCI spec to disk + if err := c.saveSpec(spec); err != nil { + return err + } + + // With the spec complete, do an OCI create + if err := c.runtime.ociRuntime.createContainer(c, c.config.CgroupParent); err != nil { + return err + } + + logrus.Debugf("Created container %s in OCI runtime", c.ID()) + + c.state.State = ContainerStateCreated + + return c.save() +} + +// Initialize (if necessary) and start a container +// Performs all necessary steps to start a container that is not running +// Does not lock or check validity +func (c *Container) initAndStart() (err error) { + // If we are ContainerStateUnknown, throw an error + if c.state.State == ContainerStateUnknown { + return errors.Wrapf(ErrCtrStateInvalid, "container %s is in an unknown state", c.ID()) + } + + // If we are running, do nothing + if c.state.State == ContainerStateRunning { + return nil + } + // If we are paused, throw an error + if c.state.State == ContainerStatePaused { + return errors.Wrapf(ErrCtrStateInvalid, "cannot start paused container %s", c.ID()) + } + // TODO remove this once we can restart containers + if c.state.State == ContainerStateStopped { + return errors.Wrapf(ErrNotImplemented, "restarting containers is not yet implemented") + } + + // Mount if necessary + if err := c.mountStorage(); err != nil { + return err + } + defer func() { + if err != nil { + if err2 := c.cleanupStorage(); err2 != nil { + logrus.Errorf("Error cleaning up storage for container %s: %v", c.ID(), err2) + } + } + }() + + // Create a network namespace if necessary + if c.config.CreateNetNS && c.state.NetNS == nil { + if err := c.runtime.createNetNS(c); err != nil { + return err + } + } + defer func() { + if err != nil { + if err2 := c.runtime.teardownNetNS(c); err2 != nil { + logrus.Errorf("Error tearing down network namespace for container %s: %v", c.ID(), err2) + } + } + }() + + // If we are ContainerStateConfigured we need to init() + if c.state.State == ContainerStateConfigured { + if err := c.init(); err != nil { + return err + } + } + + // Now start the container + return c.start() +} + +// Internal, non-locking function to start a container +func (c *Container) start() error { + if err := c.runtime.ociRuntime.startContainer(c); err != nil { + return err + } + + logrus.Debugf("Started container %s", c.ID()) + + c.state.State = ContainerStateRunning + + return c.save() +} + // Internal, non-locking function to stop container func (c *Container) stop(timeout uint) error { logrus.Debugf("Stopping ctr %s with timeout %d", c.ID(), timeout) - if c.state.State == ContainerStateConfigured || - c.state.State == ContainerStateUnknown || - c.state.State == ContainerStatePaused { - return errors.Wrapf(ErrCtrStateInvalid, "can only stop created, running, or stopped containers") - } - if err := c.runtime.ociRuntime.stopContainer(c, timeout); err != nil { return err } |