소스 검색

Ignore missing containers when compose down -p

Signed-off-by: koooge <[email protected]>
koooge 1 년 전
부모
커밋
8ceaf49296
4개의 변경된 파일59개의 추가작업 그리고 9개의 파일을 삭제
  1. 5 5
      pkg/compose/dependencies.go
  2. 52 2
      pkg/compose/dependencies_test.go
  3. 1 1
      pkg/compose/down.go
  4. 1 1
      pkg/compose/stop.go

+ 5 - 5
pkg/compose/dependencies.go

@@ -77,7 +77,7 @@ func downDirectionTraversal(visitorFn func(context.Context, string) error) *grap
 
 // InDependencyOrder applies the function to the services of the project taking in account the dependency order
 func InDependencyOrder(ctx context.Context, project *types.Project, fn func(context.Context, string) error, options ...func(*graphTraversal)) error {
-	graph, err := NewGraph(project, ServiceStopped)
+	graph, err := NewGraph(project, ServiceStopped, false)
 	if err != nil {
 		return err
 	}
@@ -89,8 +89,8 @@ func InDependencyOrder(ctx context.Context, project *types.Project, fn func(cont
 }
 
 // InReverseDependencyOrder applies the function to the services of the project in reverse order of dependencies
-func InReverseDependencyOrder(ctx context.Context, project *types.Project, fn func(context.Context, string) error, options ...func(*graphTraversal)) error {
-	graph, err := NewGraph(project, ServiceStarted)
+func InReverseDependencyOrder(ctx context.Context, project *types.Project, ignoreMissing bool, fn func(context.Context, string) error, options ...func(*graphTraversal)) error {
+	graph, err := NewGraph(project, ServiceStarted, ignoreMissing)
 	if err != nil {
 		return err
 	}
@@ -257,7 +257,7 @@ func (v *Vertex) GetChildren() []*Vertex {
 }
 
 // NewGraph returns the dependency graph of the services
-func NewGraph(project *types.Project, initialStatus ServiceStatus) (*Graph, error) {
+func NewGraph(project *types.Project, initialStatus ServiceStatus, ignoreMissing bool) (*Graph, error) {
 	graph := &Graph{
 		lock:     sync.RWMutex{},
 		Vertices: map[string]*Vertex{},
@@ -271,7 +271,7 @@ func NewGraph(project *types.Project, initialStatus ServiceStatus) (*Graph, erro
 		for _, name := range s.GetDependencies() {
 			err := graph.AddEdge(s.Name, name)
 			if err != nil {
-				if !s.DependsOn[name].Required {
+				if ignoreMissing || !s.DependsOn[name].Required {
 					delete(s.DependsOn, name)
 					project.Services[index] = s
 					continue

+ 52 - 2
pkg/compose/dependencies_test.go

@@ -115,7 +115,7 @@ func TestInDependencyReverseDownCommandOrder(t *testing.T) {
 	t.Cleanup(cancel)
 
 	var order []string
-	err := InReverseDependencyOrder(ctx, createTestProject(), func(ctx context.Context, service string) error {
+	err := InReverseDependencyOrder(ctx, createTestProject(), false, func(ctx context.Context, service string) error {
 		order = append(order, service)
 		return nil
 	})
@@ -270,7 +270,57 @@ func TestBuildGraph(t *testing.T) {
 				Services: tC.services,
 			}
 
-			graph, err := NewGraph(&project, ServiceStopped)
+			graph, err := NewGraph(&project, ServiceStopped, false)
+			assert.NilError(t, err, fmt.Sprintf("failed to build graph for: %s", tC.desc))
+
+			for k, vertex := range graph.Vertices {
+				expected, ok := tC.expectedVertices[k]
+				assert.Equal(t, true, ok)
+				assert.Equal(t, true, isVertexEqual(*expected, *vertex))
+			}
+		})
+	}
+}
+
+func TestBuildGraphIgnoreMissing(t *testing.T) {
+	testCases := []struct {
+		desc             string
+		services         types.Services
+		expectedVertices map[string]*Vertex
+	}{
+		{
+			desc: "service depends on init container which is already removed",
+			services: types.Services{
+				"test": {
+					Name: "test",
+					DependsOn: types.DependsOnConfig{
+						"test-removed-init-container": types.ServiceDependency{
+							Condition:  "service_completed_successfully",
+							Restart:    false,
+							Extensions: types.Extensions(nil),
+							Required:   true,
+						},
+					},
+				},
+			},
+			expectedVertices: map[string]*Vertex{
+				"test": {
+					Key:      "test",
+					Service:  "test",
+					Status:   ServiceStopped,
+					Children: map[string]*Vertex{},
+					Parents:  map[string]*Vertex{},
+				},
+			},
+		},
+	}
+	for _, tC := range testCases {
+		t.Run(tC.desc, func(t *testing.T) {
+			project := types.Project{
+				Services: tC.services,
+			}
+
+			graph, err := NewGraph(&project, ServiceStopped, true)
 			assert.NilError(t, err, fmt.Sprintf("failed to build graph for: %s", tC.desc))
 
 			for k, vertex := range graph.Vertices {

+ 1 - 1
pkg/compose/down.go

@@ -74,7 +74,7 @@ func (s *composeService) down(ctx context.Context, projectName string, options a
 		resourceToRemove = true
 	}
 
-	err = InReverseDependencyOrder(ctx, project, func(c context.Context, service string) error {
+	err = InReverseDependencyOrder(ctx, project, true, func(c context.Context, service string) error {
 		serviceContainers := containers.filter(isService(service))
 		err := s.removeContainers(ctx, serviceContainers, options.Timeout, options.Volumes)
 		return err

+ 1 - 1
pkg/compose/stop.go

@@ -50,7 +50,7 @@ func (s *composeService) stop(ctx context.Context, projectName string, options a
 	}
 
 	w := progress.ContextWriter(ctx)
-	return InReverseDependencyOrder(ctx, project, func(c context.Context, service string) error {
+	return InReverseDependencyOrder(ctx, project, false, func(c context.Context, service string) error {
 		if !utils.StringContains(options.Services, service) {
 			return nil
 		}