| 1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374 |
- package docker
- import (
- "context"
- "fmt"
- "strings"
- "github.com/docker/docker/api/types"
- "github.com/docker/docker/api/types/filters"
- "github.com/docker/docker/api/types/volume"
- "github.com/docker/docker/client"
- )
- // Agent is a Docker client for performing operations that interact
- // with the Docker engine over REST
- type Agent struct {
- client *client.Client
- ctx context.Context
- label string
- }
- // CreateLocalVolumeIfNotExist creates a volume using driver type "local" with the
- // given name if it does not exist. If the volume does exist but does not contain
- // the required label (a.label), an error is thrown.
- func (a *Agent) CreateLocalVolumeIfNotExist(name string) (*types.Volume, error) {
- volListBody, err := a.client.VolumeList(a.ctx, filters.Args{})
- if err != nil {
- return nil, a.handleDockerClientErr(err, "Could not list volumes")
- }
- for _, _vol := range volListBody.Volumes {
- if contains, ok := _vol.Labels[a.label]; ok && contains == "true" && _vol.Name == name {
- return _vol, nil
- } else if !ok && _vol.Name == name {
- return nil, fmt.Errorf("volume conflict for %s: please remove existing volume and try again", name)
- }
- }
- return a.CreateLocalVolume(name)
- }
- // CreateLocalVolume creates a volume using driver type "local" with no
- // configured options. The equivalent of:
- //
- // docker volume create --driver local [name]
- func (a *Agent) CreateLocalVolume(name string) (*types.Volume, error) {
- labels := make(map[string]string)
- labels[a.label] = "true"
- opts := volume.VolumeCreateBody{
- Name: name,
- Driver: "local",
- Labels: labels,
- }
- vol, err := a.client.VolumeCreate(a.ctx, opts)
- if err != nil {
- return nil, a.handleDockerClientErr(err, "Could not create volume "+name)
- }
- return &vol, err
- }
- // ------------------------- AGENT HELPER FUNCTIONS ------------------------- //
- func (a *Agent) handleDockerClientErr(err error, errPrefix string) error {
- if strings.Contains(err.Error(), "Cannot connect to the Docker daemon") {
- return fmt.Errorf("The Docker daemon must be running in order to start Porter: connection to %s failed", a.client.DaemonHost())
- }
- return fmt.Errorf("%s:%s", errPrefix, err.Error())
- }
|