Переглянути джерело

Introduce `removeOrphans` to cleanup injected AWS simulation container

Signed-off-by: Nicolas De Loof <[email protected]>
Nicolas De Loof 5 роки тому
батько
коміт
855a879a6a

+ 4 - 4
aci/compose.go

@@ -102,14 +102,14 @@ func (cs aciComposeService) warnKeepVolumeOnDown(ctx context.Context, projectNam
 	return nil
 }
 
-func (cs *aciComposeService) Down(ctx context.Context, project string) error {
-	logrus.Debugf("Down on project with name %q", project)
+func (cs *aciComposeService) Down(ctx context.Context, projectName string, removeOrphans bool) error {
+	logrus.Debugf("Down on projectName with name %q", projectName)
 
-	if err := cs.warnKeepVolumeOnDown(ctx, project); err != nil {
+	if err := cs.warnKeepVolumeOnDown(ctx, projectName); err != nil {
 		return err
 	}
 
-	cg, err := deleteACIContainerGroup(ctx, cs.ctx, project)
+	cg, err := deleteACIContainerGroup(ctx, cs.ctx, projectName)
 	if err != nil {
 		return err
 	}

+ 1 - 1
api/client/compose.go

@@ -52,7 +52,7 @@ func (c *composeService) Up(context.Context, *types.Project, bool) error {
 	return errdefs.ErrNotImplemented
 }
 
-func (c *composeService) Down(context.Context, string) error {
+func (c *composeService) Down(context.Context, string, bool) error {
 	return errdefs.ErrNotImplemented
 }
 

+ 1 - 1
api/compose/api.go

@@ -37,7 +37,7 @@ type Service interface {
 	// Up executes the equivalent to a `compose up`
 	Up(ctx context.Context, project *types.Project, detach bool) error
 	// Down executes the equivalent to a `compose down`
-	Down(ctx context.Context, projectName string) error
+	Down(ctx context.Context, projectName string, removeOrphans bool) error
 	// Logs executes the equivalent to a `compose logs`
 	Logs(ctx context.Context, projectName string, consumer LogConsumer, options LogOptions) error
 	// Ps executes the equivalent to a `compose ps`

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

@@ -52,7 +52,7 @@ func runDown(ctx context.Context, opts composeOptions) error {
 		if err != nil {
 			return "", err
 		}
-		return projectName, c.ComposeService().Down(ctx, projectName)
+		return projectName, c.ComposeService().Down(ctx, projectName, false)
 	})
 	return err
 }

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

@@ -96,7 +96,7 @@ func runCreateStart(ctx context.Context, opts composeOptions, services []string)
 		fmt.Println("Gracefully stopping...")
 		ctx = context.Background()
 		_, err = progress.Run(ctx, func(ctx context.Context) (string, error) {
-			return "", c.ComposeService().Down(ctx, project.Name)
+			return "", c.ComposeService().Down(ctx, project.Name, false)
 		})
 	}
 	return err

+ 5 - 5
ecs/down.go

@@ -22,8 +22,8 @@ import (
 	"github.com/docker/compose-cli/progress"
 )
 
-func (b *ecsAPIService) Down(ctx context.Context, project string) error {
-	resources, err := b.aws.ListStackResources(ctx, project)
+func (b *ecsAPIService) Down(ctx context.Context, projectName string, removeOrphans bool) error {
+	resources, err := b.aws.ListStackResources(ctx, projectName)
 	if err != nil {
 		return err
 	}
@@ -38,16 +38,16 @@ func (b *ecsAPIService) Down(ctx context.Context, project string) error {
 		return err
 	}
 
-	previousEvents, err := b.previousStackEvents(ctx, project)
+	previousEvents, err := b.previousStackEvents(ctx, projectName)
 	if err != nil {
 		return err
 	}
 
-	err = b.aws.DeleteStack(ctx, project)
+	err = b.aws.DeleteStack(ctx, projectName)
 	if err != nil {
 		return err
 	}
-	return b.WaitStackCompletion(ctx, project, stackDelete, previousEvents...)
+	return b.WaitStackCompletion(ctx, projectName, stackDelete, previousEvents...)
 }
 
 func (b *ecsAPIService) previousStackEvents(ctx context.Context, project string) ([]string, error) {

+ 2 - 2
ecs/local/compose.go

@@ -147,8 +147,8 @@ func (e ecsLocalSimulation) enhanceForLocalSimulation(project *types.Project) (*
 	return project, nil
 }
 
-func (e ecsLocalSimulation) Down(ctx context.Context, projectName string) error {
-	return e.compose.Down(ctx, projectName)
+func (e ecsLocalSimulation) Down(ctx context.Context, projectName string, removeOrphans bool) error {
+	return e.compose.Down(ctx, projectName, true)
 }
 
 func (e ecsLocalSimulation) Logs(ctx context.Context, projectName string, consumer compose.LogConsumer, options componse.LogOptions) error {

+ 1 - 1
ecs/up.go

@@ -90,7 +90,7 @@ func (b *ecsAPIService) Up(ctx context.Context, project *types.Project, detach b
 	go func() {
 		<-signalChan
 		fmt.Println("user interrupted deployment. Deleting stack...")
-		b.Down(ctx, project.Name) // nolint:errcheck
+		b.Down(ctx, project.Name, false) // nolint:errcheck
 	}()
 
 	err = b.WaitStackCompletion(ctx, project.Name, operation)

+ 2 - 2
example/backend.go

@@ -164,8 +164,8 @@ func (cs *composeService) Up(ctx context.Context, project *types.Project, detach
 	return nil
 }
 
-func (cs *composeService) Down(ctx context.Context, project string) error {
-	fmt.Printf("Down command on project %q", project)
+func (cs *composeService) Down(ctx context.Context, projectName string, removeOrphans bool) error {
+	fmt.Printf("Down command on project %q", projectName)
 	return nil
 }
 

+ 0 - 1
go.mod

@@ -51,7 +51,6 @@ require (
 	github.com/spf13/pflag v1.0.5
 	github.com/stretchr/testify v1.6.1
 	github.com/valyala/fasttemplate v1.2.1 // indirect
-	golang.org/x/mod v0.3.0
 	golang.org/x/net v0.0.0-20201110031124-69a78807bb2b
 	golang.org/x/oauth2 v0.0.0-20201109201403-9fd604954f58
 	golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9

+ 43 - 11
local/compose/down.go

@@ -30,7 +30,7 @@ import (
 	"golang.org/x/sync/errgroup"
 )
 
-func (s *composeService) Down(ctx context.Context, projectName string) error {
+func (s *composeService) Down(ctx context.Context, projectName string, removeOrphans bool) error {
 	eg, _ := errgroup.WithContext(ctx)
 	w := progress.ContextWriter(ctx)
 
@@ -39,11 +39,28 @@ func (s *composeService) Down(ctx context.Context, projectName string) error {
 		return err
 	}
 
+	containers, err := s.apiClient.ContainerList(ctx, moby.ContainerListOptions{
+		Filters: filters.NewArgs(projectFilter(project.Name)),
+		All:     true,
+	})
+	if err != nil {
+		return err
+	}
+
 	err = InReverseDependencyOrder(ctx, project, func(c context.Context, service types.ServiceConfig) error {
-		filter := filters.NewArgs(projectFilter(project.Name), serviceFilter(service.Name))
-		return s.removeContainers(ctx, w, eg, filter)
+		serviceContainers, others := split(containers, isService(service.Name))
+		err := s.removeContainers(ctx, w, eg, serviceContainers)
+		containers = others
+		return err
 	})
 
+	if removeOrphans {
+		err := s.removeContainers(ctx, w, eg, containers)
+		if err != nil {
+			return err
+		}
+	}
+
 	if err != nil {
 		return err
 	}
@@ -70,14 +87,7 @@ func (s *composeService) Down(ctx context.Context, projectName string) error {
 	return eg.Wait()
 }
 
-func (s *composeService) removeContainers(ctx context.Context, w progress.Writer, eg *errgroup.Group, filter filters.Args) error {
-	containers, err := s.apiClient.ContainerList(ctx, moby.ContainerListOptions{
-		Filters: filter,
-		All:     true,
-	})
-	if err != nil {
-		return err
-	}
+func (s *composeService) removeContainers(ctx context.Context, w progress.Writer, eg *errgroup.Group, containers []moby.Container) error {
 	for _, container := range containers {
 		eg.Go(func() error {
 			eventName := "Container " + getContainerName(container)
@@ -147,3 +157,25 @@ func loadProjectOptionsFromLabels(c moby.Container) (*cli.ProjectOptions, error)
 		cli.WithWorkingDirectory(c.Labels[workingDirLabel]),
 		cli.WithName(c.Labels[projectLabel]))
 }
+
+type containerPredicate func(c moby.Container) bool
+
+func isService(service string) containerPredicate {
+	return func(c moby.Container) bool {
+		return c.Labels[serviceLabel] == service
+	}
+}
+
+// split return a container slice with elements to match predicate
+func split(containers []moby.Container, predicate containerPredicate) ([]moby.Container, []moby.Container) {
+	var right []moby.Container
+	var left []moby.Container
+	for _, c := range containers {
+		if predicate(c) {
+			right = append(right, c)
+		} else {
+			left = append(left, c)
+		}
+	}
+	return right, left
+}

+ 1 - 1
server/proxy/compose.go

@@ -42,7 +42,7 @@ func (p *proxy) Down(ctx context.Context, request *composev1.ComposeDownRequest)
 		}
 		projectName = project.Name
 	}
-	return &composev1.ComposeDownResponse{ProjectName: projectName}, Client(ctx).ComposeService().Down(ctx, projectName)
+	return &composev1.ComposeDownResponse{ProjectName: projectName}, Client(ctx).ComposeService().Down(ctx, projectName, false)
 }
 
 func (p *proxy) Services(ctx context.Context, request *composev1.ComposeServicesRequest) (*composev1.ComposeServicesResponse, error) {