Lazy initialize Volume on container Mount object

Currently on daemon start volumes are "created" which involves invoking
a volume driver if needed.  If this process fails the mount is left in a
bad state in which there is no source or Volume set.  This now becomes
an unrecoverable state in which that container can not be started.  The
only way to fix is to restart the daemon and hopefully you don't get
another error on startup.

This change moves "createVolume" to be done at container start.  If the
start fails it leaves it in the state in which you can try another
start.  If the second start can contact the volume driver everything
will recover fine.

Signed-off-by: Darren Shepherd <darren@rancher.com>
Upstream-commit: 2aa673aed7cd10497d578a14a9550c75789e0a43
Component: engine
This commit is contained in:
Darren Shepherd
2015-12-09 12:39:31 -07:00
committed by David Calavera
parent 683a1e1423
commit ae6533484c
4 changed files with 16 additions and 18 deletions

View File

@ -283,10 +283,6 @@ func (daemon *Daemon) Register(container *container.Container) error {
}
}
if err := daemon.prepareMountPoints(container); err != nil {
return err
}
return nil
}

View File

@ -8,20 +8,6 @@ import (
volumestore "github.com/docker/docker/volume/store"
)
func (daemon *Daemon) prepareMountPoints(container *container.Container) error {
for _, config := range container.MountPoints {
if len(config.Driver) > 0 {
v, err := daemon.volumes.GetWithRef(config.Name, config.Driver, container.ID)
if err != nil {
return err
}
config.Volume = v
}
}
return nil
}
func (daemon *Daemon) removeMountPoints(container *container.Container, rm bool) error {
var rmErrors []string
for _, m := range container.MountPoints {

View File

@ -20,6 +20,14 @@ import (
func (daemon *Daemon) setupMounts(container *container.Container) ([]execdriver.Mount, error) {
var mounts []execdriver.Mount
for _, m := range container.MountPoints {
// Lazy initialize m.Volume if needed. This happens after a daemon restart
if len(m.Driver) > 0 && m.Volume == nil {
v, err := daemon.createVolume(m.Name, m.Driver, nil)
if err != nil {
return nil, err
}
m.Volume = v
}
path, err := m.Setup()
if err != nil {
return nil, err

View File

@ -18,6 +18,14 @@ import (
func (daemon *Daemon) setupMounts(container *container.Container) ([]execdriver.Mount, error) {
var mnts []execdriver.Mount
for _, mount := range container.MountPoints { // type is volume.MountPoint
// Lazy initialize m.Volume if needed. This happens after a daemon restart
if len(m.Driver) > 0 && m.Volume == nil {
v, err := daemon.createVolume(m.Name, m.Driver, nil)
if err != nil {
return nil, err
}
m.Volume = v
}
// If there is no source, take it from the volume path
s := mount.Source
if s == "" && mount.Volume != nil {