From ee770ad5b54845e345384be3e01c700e93926b44 Mon Sep 17 00:00:00 2001 From: Matthew Heon Date: Fri, 22 Mar 2019 14:23:18 -0400 Subject: Create non-existing named volumes at container create Replaces old functionality we used for handling image volumes. Signed-off-by: Matthew Heon --- libpod/options.go | 53 ++++++++++++++++++++++++++------------------------- libpod/runtime_ctr.go | 49 ++++++++++++++++++++++------------------------- 2 files changed, 50 insertions(+), 52 deletions(-) diff --git a/libpod/options.go b/libpod/options.go index 86f1747ce..4f35a5c8c 100644 --- a/libpod/options.go +++ b/libpod/options.go @@ -1265,14 +1265,11 @@ func WithNamedVolumes(volumes []*ContainerNamedVolume) CtrCreateOption { destinations := make(map[string]bool) for _, vol := range volumes { - // First check if libpod has the volumes - _, err := ctr.runtime.GetVolume(vol.Name) - if err != nil { - return errors.Wrapf(err, "error retrieving volume %s to add to container", vol.Name) - } + // Don't check if they already exist. + // If they don't we will automatically create them. if _, ok := destinations[vol.Dest]; ok { - return errors.Wrapf(err, "two volumes found with destination %s", vol.Dest) + return errors.Wrapf(ErrInvalidArg, "two volumes found with destination %s", vol.Dest) } destinations[vol.Dest] = true @@ -1306,68 +1303,72 @@ func WithVolumeName(name string) VolumeCreateOption { } } -// WithVolumeUID sets the uid of the owner. -func WithVolumeUID(uid int) VolumeCreateOption { +// WithVolumeLabels sets the labels of the volume. +func WithVolumeLabels(labels map[string]string) VolumeCreateOption { return func(volume *Volume) error { if volume.valid { return ErrVolumeFinalized } - volume.config.UID = uid + + volume.config.Labels = make(map[string]string) + for key, value := range labels { + volume.config.Labels[key] = value + } + return nil } } -// WithVolumeGID sets the gid of the owner. -func WithVolumeGID(gid int) VolumeCreateOption { +// WithVolumeDriver sets the driver of the volume. +func WithVolumeDriver(driver string) VolumeCreateOption { return func(volume *Volume) error { if volume.valid { return ErrVolumeFinalized } - volume.config.GID = gid + + volume.config.Driver = driver + return nil } } -// WithVolumeLabels sets the labels of the volume. -func WithVolumeLabels(labels map[string]string) VolumeCreateOption { +// WithVolumeOptions sets the options of the volume. +func WithVolumeOptions(options map[string]string) VolumeCreateOption { return func(volume *Volume) error { if volume.valid { return ErrVolumeFinalized } - volume.config.Labels = make(map[string]string) - for key, value := range labels { - volume.config.Labels[key] = value + volume.config.Options = make(map[string]string) + for key, value := range options { + volume.config.Options[key] = value } return nil } } -// WithVolumeDriver sets the driver of the volume. -func WithVolumeDriver(driver string) VolumeCreateOption { +// WithVolumeUID sets the UID that the volume will be created as. +func WithVolumeUID(uid int) VolumeCreateOption { return func(volume *Volume) error { if volume.valid { return ErrVolumeFinalized } - volume.config.Driver = driver + volume.config.UID = uid return nil } } -// WithVolumeOptions sets the options of the volume. -func WithVolumeOptions(options map[string]string) VolumeCreateOption { +// WithVolumeGID sets the GID that the volume will be created as. +func WithVolumeGID(gid int) VolumeCreateOption { return func(volume *Volume) error { if volume.valid { return ErrVolumeFinalized } - volume.config.Options = make(map[string]string) - for key, value := range options { - volume.config.Options[key] = value - } + volume.config.GID = gid return nil } diff --git a/libpod/runtime_ctr.go b/libpod/runtime_ctr.go index ec43d5dcb..fafbc9969 100644 --- a/libpod/runtime_ctr.go +++ b/libpod/runtime_ctr.go @@ -99,9 +99,6 @@ func (r *Runtime) newContainer(ctx context.Context, rSpec *spec.Spec, options .. ctr.state.State = ContainerStateConfigured ctr.runtime = r - ctr.valid = true - ctr.state.State = ContainerStateConfigured - var pod *Pod if ctr.config.Pod != "" { // Get the pod from state @@ -173,29 +170,29 @@ func (r *Runtime) newContainer(ctx context.Context, rSpec *spec.Spec, options .. ctr.config.ConmonPidFile = filepath.Join(ctr.config.StaticDir, "conmon.pid") } - // // Go through the volume mounts and check for named volumes - // // If the named volme already exists continue, otherwise create - // // the storage for the named volume. - // for i, vol := range ctr.config.Spec.Mounts { - // if vol.Source[0] != '/' && isNamedVolume(vol.Source) { - // volInfo, err := r.state.Volume(vol.Source) - // if err != nil { - // newVol, err := r.newVolume(ctx, WithVolumeName(vol.Source), withSetCtrSpecific()) - // if err != nil { - // return nil, errors.Wrapf(err, "error creating named volume %q", vol.Source) - // } - // ctr.config.Spec.Mounts[i].Source = newVol.MountPoint() - // if err := os.Chown(ctr.config.Spec.Mounts[i].Source, ctr.RootUID(), ctr.RootGID()); err != nil { - // return nil, errors.Wrapf(err, "cannot chown %q to %d:%d", ctr.config.Spec.Mounts[i].Source, ctr.RootUID(), ctr.RootGID()) - // } - // if err := ctr.copyWithTarFromImage(ctr.config.Spec.Mounts[i].Destination, ctr.config.Spec.Mounts[i].Source); err != nil && !os.IsNotExist(err) { - // return nil, errors.Wrapf(err, "Failed to copy content into new volume mount %q", vol.Source) - // } - // continue - // } - // ctr.config.Spec.Mounts[i].Source = volInfo.MountPoint() - // } - // } + // Go through named volumes and add them. + // If they don't exist they will be created using basic options. + for _, vol := range ctr.config.NamedVolumes { + // Check if it exists already + _, err := r.state.Volume(vol.Name) + if err == nil { + // The volume exists, we're good + continue + } else if errors.Cause(err) != ErrNoSuchVolume { + return nil, errors.Wrapf(err, "error retrieving named volume %s for new container", vol.Name) + } + + // The volume does not exist, so we need to create it. + newVol, err := r.newVolume(ctx, WithVolumeName(vol.Name), withSetCtrSpecific(), + WithVolumeUID(ctr.RootUID()), WithVolumeGID(ctr.RootGID())) + if err != nil { + return nil, errors.Wrapf(err, "error creating named volume %q", vol.Name) + } + + if err := ctr.copyWithTarFromImage(vol.Dest, newVol.MountPoint()); err != nil && !os.IsNotExist(err) { + return nil, errors.Wrapf(err, "Failed to copy content into new volume mount %q", vol.Name) + } + } if ctr.config.LogPath == "" { ctr.config.LogPath = filepath.Join(ctr.config.StaticDir, "ctr.log") -- cgit v1.2.3-54-g00ecf