浏览代码

backend.local: Add rudimentary volume support

Signed-off-by: Chris Crone <[email protected]>
Chris Crone 5 年之前
父节点
当前提交
42eb0ecc35
共有 3 个文件被更改,包括 101 次插入2 次删除
  1. 4 2
      local/backend.go
  2. 13 0
      local/containers.go
  3. 84 0
      local/volumes.go

+ 4 - 2
local/backend.go

@@ -34,6 +34,7 @@ import (
 
 type local struct {
 	*containerService
+	*volumeService
 }
 
 func init() {
@@ -48,6 +49,7 @@ func service(ctx context.Context) (backend.Service, error) {
 
 	return &local{
 		containerService: &containerService{apiClient},
+		volumeService:    &volumeService{apiClient},
 	}, nil
 }
 
@@ -63,8 +65,8 @@ func (ms *local) SecretsService() secrets.Service {
 	return nil
 }
 
-func (ms *local) VolumeService() volumes.Service {
-	return nil
+func (vs *volumeService) VolumeService() volumes.Service {
+	return vs
 }
 
 func (ms *local) ResourceService() resources.Service {

+ 13 - 0
local/containers.go

@@ -27,6 +27,7 @@ import (
 
 	"github.com/docker/docker/api/types"
 	"github.com/docker/docker/api/types/container"
+	"github.com/docker/docker/api/types/mount"
 	"github.com/docker/docker/client"
 	"github.com/docker/docker/pkg/stdcopy"
 	"github.com/docker/docker/pkg/stringid"
@@ -104,6 +105,17 @@ func (cs *containerService) Run(ctx context.Context, r containers.ContainerConfi
 		return err
 	}
 
+	var mounts []mount.Mount
+	for _, v := range r.Volumes {
+		tokens := strings.Split(v, ":")
+		if len(tokens) != 2 {
+			return errors.Wrapf(errdefs.ErrParsingFailed, "volume %q has invalid format", v)
+		}
+		src := tokens[0]
+		tgt := tokens[1]
+		mounts = append(mounts, mount.Mount{Type: "volume", Source: src, Target: tgt})
+	}
+
 	containerConfig := &container.Config{
 		Image:        r.Image,
 		Labels:       r.Labels,
@@ -112,6 +124,7 @@ func (cs *containerService) Run(ctx context.Context, r containers.ContainerConfi
 	}
 	hostConfig := &container.HostConfig{
 		PortBindings:  hostBindings,
+		Mounts:        mounts,
 		AutoRemove:    r.AutoRemove,
 		RestartPolicy: toRestartPolicy(r.RestartPolicyCondition),
 		Resources: container.Resources{

+ 84 - 0
local/volumes.go

@@ -0,0 +1,84 @@
+// +build local
+
+/*
+   Copyright 2020 Docker Compose CLI authors
+
+   Licensed under the Apache License, Version 2.0 (the "License");
+   you may not use this file except in compliance with the License.
+   You may obtain a copy of the License at
+
+       http://www.apache.org/licenses/LICENSE-2.0
+
+   Unless required by applicable law or agreed to in writing, software
+   distributed under the License is distributed on an "AS IS" BASIS,
+   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+   See the License for the specific language governing permissions and
+   limitations under the License.
+*/
+
+package local
+
+import (
+	"context"
+	"fmt"
+
+	"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"
+
+	"github.com/docker/compose-cli/api/volumes"
+)
+
+type volumeService struct {
+	apiClient *client.Client
+}
+
+func (vs *volumeService) List(ctx context.Context) ([]volumes.Volume, error) {
+	l, err := vs.apiClient.VolumeList(ctx, filters.NewArgs())
+	if err != nil {
+		return []volumes.Volume{}, err
+	}
+
+	res := []volumes.Volume{}
+	for _, v := range l.Volumes {
+		res = append(res, volumes.Volume{
+			ID:          v.Name,
+			Description: description(v),
+		})
+	}
+
+	return res, nil
+}
+
+func (vs *volumeService) Create(ctx context.Context, name string, options interface{}) (volumes.Volume, error) {
+	v, err := vs.apiClient.VolumeCreate(ctx, volume.VolumeCreateBody{
+		Driver:     "local",
+		DriverOpts: nil,
+		Labels:     nil,
+		Name:       name,
+	})
+	if err != nil {
+		return volumes.Volume{}, err
+	}
+	return volumes.Volume{ID: name, Description: description(&v)}, nil
+}
+
+func (vs *volumeService) Delete(ctx context.Context, volumeID string, options interface{}) error {
+	if err := vs.apiClient.VolumeRemove(ctx, volumeID, false); err != nil {
+		return err
+	}
+	return nil
+}
+
+func (vs *volumeService) Inspect(ctx context.Context, volumeID string) (volumes.Volume, error) {
+	v, err := vs.apiClient.VolumeInspect(ctx, volumeID)
+	if err != nil {
+		return volumes.Volume{}, err
+	}
+	return volumes.Volume{ID: volumeID, Description: description(&v)}, nil
+}
+
+func description(v *types.Volume) string {
+	return fmt.Sprintf("Created %s", v.CreatedAt)
+}