Bläddra i källkod

Use local compose implementation for local ecs simulation context

Signed-off-by: Nicolas De Loof <[email protected]>
Nicolas De Loof 5 år sedan
förälder
incheckning
db5467ce22
3 ändrade filer med 47 tillägg och 95 borttagningar
  1. 1 1
      cli/cmd/compose/up.go
  2. 7 3
      ecs/local/backend.go
  3. 39 91
      ecs/local/compose.go

+ 1 - 1
cli/cmd/compose/up.go

@@ -40,7 +40,7 @@ func upCommand(contextType string) *cobra.Command {
 		Short: "Create and start containers",
 		RunE: func(cmd *cobra.Command, args []string) error {
 			switch contextType {
-			case store.LocalContextType, store.DefaultContextType:
+			case store.LocalContextType, store.DefaultContextType, store.EcsLocalSimulationContextType:
 				return runCreateStart(cmd.Context(), opts, args)
 			default:
 				return runUp(cmd.Context(), opts, args)

+ 7 - 3
ecs/local/backend.go

@@ -19,6 +19,8 @@ package local
 import (
 	"context"
 
+	local_compose "github.com/docker/compose-cli/local/compose"
+
 	"github.com/docker/docker/client"
 
 	"github.com/docker/compose-cli/api/compose"
@@ -38,17 +40,19 @@ func init() {
 }
 
 type ecsLocalSimulation struct {
-	moby *client.Client
+	moby    *client.Client
+	compose compose.Service
 }
 
 func service(ctx context.Context) (backend.Service, error) {
-	apiClient, err := client.NewClientWithOpts(client.FromEnv)
+	apiClient, err := client.NewClientWithOpts(client.FromEnv, client.WithAPIVersionNegotiation())
 	if err != nil {
 		return nil, err
 	}
 
 	return &ecsLocalSimulation{
-		moby: apiClient,
+		moby:    apiClient,
+		compose: local_compose.NewComposeService(apiClient),
 	}, nil
 }
 

+ 39 - 91
ecs/local/compose.go

@@ -17,80 +17,76 @@
 package local
 
 import (
-	"bufio"
-	"bytes"
 	"context"
 	"encoding/json"
 	"fmt"
 	"os"
-	"os/exec"
 	"path/filepath"
-	"strings"
 
 	"github.com/aws/aws-sdk-go/aws"
 	"github.com/compose-spec/compose-go/types"
-	types2 "github.com/docker/docker/api/types"
-	"github.com/docker/docker/api/types/filters"
-	"github.com/pkg/errors"
-	"github.com/sanathkr/go-yaml"
-	"golang.org/x/mod/semver"
-
 	"github.com/docker/compose-cli/api/compose"
 	"github.com/docker/compose-cli/errdefs"
+	"github.com/sanathkr/go-yaml"
 )
 
 func (e ecsLocalSimulation) Build(ctx context.Context, project *types.Project) error {
-	return errdefs.ErrNotImplemented
+	return e.compose.Build(ctx, project)
 }
 
 func (e ecsLocalSimulation) Push(ctx context.Context, project *types.Project) error {
-	return errdefs.ErrNotImplemented
+	return e.compose.Push(ctx, project)
 }
 
 func (e ecsLocalSimulation) Pull(ctx context.Context, project *types.Project) error {
-	return errdefs.ErrNotImplemented
+	return e.compose.Pull(ctx, project)
 }
 
 func (e ecsLocalSimulation) Create(ctx context.Context, project *types.Project) error {
-	return errdefs.ErrNotImplemented
+	enhanced, err := e.enhanceForLocalSimulation(project)
+	if err != nil {
+		return err
+	}
+
+	return e.compose.Create(ctx, enhanced)
 }
 
 func (e ecsLocalSimulation) Start(ctx context.Context, project *types.Project, consumer compose.LogConsumer) error {
-	return errdefs.ErrNotImplemented
+	return e.compose.Start(ctx, project, consumer)
 }
 
 func (e ecsLocalSimulation) Up(ctx context.Context, project *types.Project, detach bool) error {
+	return errdefs.ErrNotImplemented
+}
 
-	cmd := exec.Command("docker-compose", "version", "--short")
-	b := bytes.Buffer{}
-	b.WriteString("v")
-	cmd.Stdout = bufio.NewWriter(&b)
-	err := cmd.Run()
+func (e ecsLocalSimulation) Convert(ctx context.Context, project *types.Project, format string) ([]byte, error) {
+	enhanced, err := e.enhanceForLocalSimulation(project)
 	if err != nil {
-		return errors.Wrap(err, "ECS simulation mode require Docker-compose 1.27")
-	}
-	version := semver.MajorMinor(strings.TrimSpace(b.String()))
-	if version == "" {
-		return fmt.Errorf("can't parse docker-compose version: %s", b.String())
-	}
-	if semver.Compare(version, "v1.27") < 0 {
-		return fmt.Errorf("ECS simulation mode require Docker-compose 1.27, found %s", version)
+		return nil, err
 	}
 
-	converted, err := e.Convert(ctx, project, "json")
-	if err != nil {
-		return err
+	delete(enhanced.Networks, "default")
+	config := map[string]interface{}{
+		"services": enhanced.Services,
+		"networks": enhanced.Networks,
+		"volumes":  enhanced.Volumes,
+		"secrets":  enhanced.Secrets,
+		"configs":  enhanced.Configs,
+	}
+	switch format {
+	case "json":
+		return json.MarshalIndent(config, "", "  ")
+	case "yaml":
+		return yaml.Marshal(config)
+	default:
+		return nil, fmt.Errorf("unsupported format %q", format)
 	}
 
-	cmd = exec.Command("docker-compose", "--context", "default", "--project-directory", project.WorkingDir, "--project-name", project.Name, "-f", "-", "up")
-	cmd.Stdin = strings.NewReader(string(converted))
-	cmd.Stdout = os.Stdout
-	cmd.Stderr = os.Stderr
-	return cmd.Run()
 }
 
-func (e ecsLocalSimulation) Convert(ctx context.Context, project *types.Project, format string) ([]byte, error) {
+func (e ecsLocalSimulation) enhanceForLocalSimulation(project *types.Project) (*types.Project, error) {
 	project.Networks["credentials_network"] = types.NetworkConfig{
+		Name:   "credentials_network",
 		Driver: "bridge",
 		Ipam: types.IPAMConfig{
 			Config: []*types.IPAMPool{
@@ -148,68 +144,20 @@ func (e ecsLocalSimulation) Convert(ctx context.Context, project *types.Project,
 			},
 		},
 	})
-
-	delete(project.Networks, "default")
-	config := map[string]interface{}{
-		"services": project.Services,
-		"networks": project.Networks,
-		"volumes":  project.Volumes,
-		"secrets":  project.Secrets,
-		"configs":  project.Configs,
-	}
-	switch format {
-	case "json":
-		return json.MarshalIndent(config, "", "  ")
-	case "yaml":
-		return yaml.Marshal(config)
-	default:
-		return nil, fmt.Errorf("unsupported format %q", format)
-	}
-
+	return project, nil
 }
 
 func (e ecsLocalSimulation) Down(ctx context.Context, projectName string) error {
-	cmd := exec.Command("docker-compose", "--context", "default", "--project-name", projectName, "-f", "-", "down", "--remove-orphans")
-	cmd.Stdin = strings.NewReader(string(`
-services:
-   ecs-local-endpoints:
-      image: "amazon/amazon-ecs-local-container-endpoints"
-`))
-	cmd.Stdout = os.Stdout
-	cmd.Stderr = os.Stderr
-	return cmd.Run()
+	return e.compose.Down(ctx, projectName)
 }
 
-func (e ecsLocalSimulation) Logs(ctx context.Context, projectName string, consumer compose.LogConsumer, options compose.LogOptions) error {
-	list, err := e.moby.ContainerList(ctx, types2.ContainerListOptions{
-		Filters: filters.NewArgs(filters.Arg("label", "com.docker.compose.project="+projectName)),
-	})
-	if err != nil {
-		return err
-	}
-	services := map[string]types.ServiceConfig{}
-	for _, c := range list {
-		services[c.Labels["com.docker.compose.service"]] = types.ServiceConfig{
-			Image: "unused",
-		}
-	}
-
-	marshal, err := yaml.Marshal(map[string]interface{}{
-		"services": services,
-	})
-	if err != nil {
-		return err
-	}
-	cmd := exec.Command("docker-compose", "--context", "default", "--project-name", projectName, "-f", "-", "logs", "-f")
-	cmd.Stdin = strings.NewReader(string(marshal))
-	cmd.Stdout = os.Stdout
-	cmd.Stderr = os.Stderr
-	return cmd.Run()
+func (e ecsLocalSimulation) Logs(ctx context.Context, projectName string, consumer compose.LogConsumer, options componse.LogOptions) error {
+	return e.compose.Logs(ctx, projectName, consumer, options)
 }
 
 func (e ecsLocalSimulation) Ps(ctx context.Context, projectName string) ([]compose.ContainerSummary, error) {
-	return nil, errors.Wrap(errdefs.ErrNotImplemented, "use docker-compose ps")
+	return e.compose.Ps(ctx, projectName)
 }
 func (e ecsLocalSimulation) List(ctx context.Context, projectName string) ([]compose.Stack, error) {
-	return nil, errors.Wrap(errdefs.ErrNotImplemented, "use docker-compose ls")
+	return e.compose.List(ctx, projectName)
 }