diff options
Diffstat (limited to 'libpod/container.go')
-rw-r--r-- | libpod/container.go | 141 |
1 files changed, 61 insertions, 80 deletions
diff --git a/libpod/container.go b/libpod/container.go index 8e84a1f3e..ffc4c6314 100644 --- a/libpod/container.go +++ b/libpod/container.go @@ -87,21 +87,17 @@ type containerConfig struct { Spec *spec.Spec `json:"spec"` ID string `json:"id"` Name string `json:"name"` - // RootfsFromImage indicates whether the container uses a root - // filesystem from an image, or from a user-provided directory - RootfsFromImage bool - // Directory used as a root filesystem if not configured with an image - RootfsDir string `json:"rootfsDir,omitempty"` // Information on the image used for the root filesystem RootfsImageID string `json:"rootfsImageID,omitempty"` RootfsImageName string `json:"rootfsImageName,omitempty"` - MountLabel string `json:"MountLabel,omitempty"` UseImageConfig bool `json:"useImageConfig"` - // Whether to keep container STDIN open - Stdin bool + // SELinux mount label for root filesystem + MountLabel string `json:"MountLabel,omitempty"` // Static directory for container content that will persist across // reboot StaticDir string `json:"staticDir"` + // Whether to keep container STDIN open + Stdin bool // Pod the container belongs to Pod string `json:"pod,omitempty"` // Labels is a set of key-value pairs providing additional information @@ -154,10 +150,9 @@ func (c *Container) State() (ContainerState, error) { c.lock.Lock() defer c.lock.Unlock() - // TODO uncomment when working - // if err := c.runtime.ociRuntime.updateContainerStatus(c); err != nil { - // return ContainerStateUnknown, err - // } + if err := c.runtime.state.UpdateContainer(c); err != nil { + return ContainerStateUnknown, errors.Wrapf(err, "error updating container %s state", c.ID()) + } return c.state.State, nil } @@ -207,18 +202,6 @@ func (c *Container) setupStorage() error { return errors.Wrapf(ErrCtrStateInvalid, "container %s must be in Configured state to have storage set up", c.ID()) } - // If we're configured to use a directory, perform that setup - if !c.config.RootfsFromImage { - // TODO implement directory-based root filesystems - return ErrNotImplemented - } - - // Not using a directory, so call into containers/storage - return c.setupImageRootfs() -} - -// Set up an image as root filesystem using containers/storage -func (c *Container) setupImageRootfs() error { // Need both an image ID and image name, plus a bool telling us whether to use the image configuration if c.config.RootfsImageID == "" || c.config.RootfsImageName == "" { return errors.Wrapf(ErrInvalidArg, "must provide image ID and image name to use an image") @@ -248,16 +231,6 @@ func (c *Container) teardownStorage() error { return errors.Wrapf(ErrCtrStateInvalid, "cannot remove storage for container %s as it is running or paused", c.ID()) } - if !c.config.RootfsFromImage { - // TODO implement directory-based root filesystems - return ErrNotImplemented - } - - return c.teardownImageRootfs() -} - -// Completely remove image-based root filesystem for a container -func (c *Container) teardownImageRootfs() error { if c.state.Mounted { if err := c.runtime.storageService.StopContainer(c.ID()); err != nil { return errors.Wrapf(err, "error unmounting container %s root filesystem", c.ID()) @@ -273,11 +246,15 @@ func (c *Container) teardownImageRootfs() error { return nil } -// Create creates a container in the OCI runtime -func (c *Container) Create() (err error) { +// Init creates a container in the OCI runtime +func (c *Container) Init() (err error) { c.lock.Lock() defer c.lock.Unlock() + if err := c.runtime.state.UpdateContainer(c); err != nil { + return errors.Wrapf(err, "error updating container %s state", c.ID()) + } + if !c.valid { return errors.Wrapf(ErrCtrRemoved, "container %s is not valid", c.ID()) } @@ -286,33 +263,25 @@ func (c *Container) Create() (err error) { return errors.Wrapf(ErrCtrExists, "container %s has already been created in runtime", c.ID()) } - // If using containers/storage, mount the container - if !c.config.RootfsFromImage { - // TODO implement directory-based root filesystems - if !c.state.Mounted { - return ErrNotImplemented - } - } else { - mountPoint, err := c.runtime.storageService.StartContainer(c.ID()) - if err != nil { - return errors.Wrapf(err, "error mounting storage for container %s", c.ID()) - } - c.state.Mounted = true - c.state.Mountpoint = mountPoint - - logrus.Debugf("Created root filesystem for container %s at %s", c.ID(), c.state.Mountpoint) + mountPoint, err := c.runtime.storageService.StartContainer(c.ID()) + if err != nil { + return errors.Wrapf(err, "error mounting storage for container %s", c.ID()) + } + c.state.Mounted = true + c.state.Mountpoint = mountPoint - defer func() { - if err != nil { - if err2 := c.runtime.storageService.StopContainer(c.ID()); err2 != nil { - logrus.Errorf("Error unmounting storage for container %s: %v", c.ID(), err2) - } + logrus.Debugf("Created root filesystem for container %s at %s", c.ID(), c.state.Mountpoint) - c.state.Mounted = false - c.state.Mountpoint = "" + defer func() { + if err != nil { + if err2 := c.runtime.storageService.StopContainer(c.ID()); err2 != nil { + logrus.Errorf("Error unmounting storage for container %s: %v", c.ID(), err2) } - }() - } + + c.state.Mounted = false + c.state.Mountpoint = "" + } + }() // Make the OCI runtime spec we will use c.runningSpec = new(spec.Spec) @@ -342,9 +311,12 @@ func (c *Container) Create() (err error) { logrus.Debugf("Created container %s in runc", c.ID()) - // TODO should flush this state to disk here c.state.State = ContainerStateCreated + if err := c.runtime.state.SaveContainer(c); err != nil { + return errors.Wrapf(err, "error saving container %s state", c.ID()) + } + return nil } @@ -353,6 +325,10 @@ func (c *Container) Start() error { c.lock.Lock() defer c.lock.Unlock() + if err := c.runtime.state.UpdateContainer(c); err != nil { + return errors.Wrapf(err, "error updating container %s state", c.ID()) + } + if !c.valid { return ErrCtrRemoved } @@ -368,10 +344,13 @@ func (c *Container) Start() error { logrus.Debugf("Started container %s", c.ID()) - // TODO should flush state to disk here c.state.StartedTime = time.Now() c.state.State = ContainerStateRunning + if err := c.runtime.state.SaveContainer(c); err != nil { + return errors.Wrapf(err, "error saving container %s state", c.ID()) + } + return nil } @@ -394,6 +373,25 @@ func (c *Container) Exec(cmd []string, tty bool, stdin bool) (string, error) { // 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.runtime.state.UpdateContainer(c); err != nil { + return errors.Wrapf(err, "error updating container %s state", c.ID()) + } + + if !c.valid { + return errors.Wrapf(ErrCtrRemoved, "container %s is not valid", c.ID()) + } + + if c.state.State == ContainerStateRunning || c.state.State == ContainerStatePaused { + return errors.Wrapf(ErrCtrStateInvalid, "cannot remove storage for container %s as it is running or paused", c.ID()) + } + + // TODO is it valid to attach to a frozen container? + if c.state.State == ContainerStateUnknown || + c.state.State == ContainerStateConfigured || + c.state.State == ContainerStatePaused { + return errors.Wrapf(ErrCtrStateInvalid, "can only attach to created, running, or stopped containers") + } + // Check the validity of the provided keys first var err error detachKeys := []byte{} @@ -403,25 +401,12 @@ func (c *Container) Attach(noStdin bool, keys string, attached chan<- bool) erro return errors.Wrapf(err, "invalid detach keys") } } - cStatus := c.state.State - if !(cStatus == ContainerStateRunning || cStatus == ContainerStateCreated) { - return errors.Errorf("%s is not created or running", c.Name()) - } resize := make(chan remotecommand.TerminalSize) defer close(resize) - err = c.attachContainerSocket(resize, noStdin, detachKeys, attached) + err = c.attachContainerSocket(resize, noStdin, detachKeys, attached) return err - - // TODO - // Re-enable this when mheon is done wth it - //if err != nil { - // return err - //} - //c.ContainerStateToDisk(c) - - //return err } // Mount mounts a container's filesystem on the host @@ -448,10 +433,6 @@ func (c *Container) Export(path string) error { // Commit commits the changes between a container and its image, creating a new // image -// If the container was not created from an image (for example, -// WithRootFSFromPath will create a container from a directory on the system), -// a new base image will be created from the contents of the container's -// filesystem func (c *Container) Commit() (*storage.Image, error) { return nil, ErrNotImplemented } |