diff --git a/daemon/daemon.go b/daemon/daemon.go index 76e9dff906..4faefcf310 100755 --- a/daemon/daemon.go +++ b/daemon/daemon.go @@ -182,6 +182,10 @@ func (daemon *Daemon) restore() error { wg.Add(1) go func(c *container.Container) { defer wg.Done() + if err := backportMountSpec(c); err != nil { + logrus.Errorf("Failed to migrate old mounts to use new spec format") + } + rm := c.RestartManager(false) if c.IsRunning() || c.IsPaused() { if err := daemon.containerd.Restore(c.ID, libcontainerd.WithRestartManager(rm)); err != nil { diff --git a/daemon/volumes.go b/daemon/volumes.go index 1deddcc94c..2f50bdb492 100644 --- a/daemon/volumes.go +++ b/daemon/volumes.go @@ -230,3 +230,47 @@ func (daemon *Daemon) lazyInitializeVolume(containerID string, m *volume.MountPo } return nil } + +func backportMountSpec(container *container.Container) error { + for target, m := range container.MountPoints { + if m.Spec.Type != "" { + // if type is set on even one mount, no need to migrate + return nil + } + if m.Name != "" { + m.Type = mounttypes.TypeVolume + m.Spec.Type = mounttypes.TypeVolume + + // make sure this is not an anyonmous volume before setting the spec source + if _, exists := container.Config.Volumes[target]; !exists { + m.Spec.Source = m.Name + } + if container.HostConfig.VolumeDriver != "" { + m.Spec.VolumeOptions = &mounttypes.VolumeOptions{ + DriverConfig: &mounttypes.Driver{Name: container.HostConfig.VolumeDriver}, + } + } + if strings.Contains(m.Mode, "nocopy") { + if m.Spec.VolumeOptions == nil { + m.Spec.VolumeOptions = &mounttypes.VolumeOptions{} + } + m.Spec.VolumeOptions.NoCopy = true + } + } else { + m.Type = mounttypes.TypeBind + m.Spec.Type = mounttypes.TypeBind + m.Spec.Source = m.Source + if m.Propagation != "" { + m.Spec.BindOptions = &mounttypes.BindOptions{ + Propagation: m.Propagation, + } + } + } + + m.Spec.Target = m.Destination + if !m.RW { + m.Spec.ReadOnly = true + } + } + return container.ToDiskLocking() +}