Sfoglia il codice sorgente

daemon: containers list code refactor

Signed-off-by: Chiranjeevi Tirunagari <vchiranjeeviak.tirunagari@gmail.com>
Chiranjeevi Tirunagari 1 anno fa
parent
commit
0c66111c40
1 ha cambiato i file con 55 aggiunte e 79 eliminazioni
  1. 55 79
      daemon/list.go

+ 55 - 79
daemon/list.go

@@ -39,22 +39,15 @@ var acceptedPsFilterTags = map[string]bool{
 // iterationAction represents possible outcomes happening during the container iteration.
 // iterationAction represents possible outcomes happening during the container iteration.
 type iterationAction int
 type iterationAction int
 
 
-// containerReducer represents a reducer for a container.
-// Returns the object to serialize by the api.
-type containerReducer func(context.Context, *container.Snapshot) (*types.Container, error)
-
 const (
 const (
-	// includeContainer is the action to include a container in the reducer.
+	// includeContainer is the action to include a container.
 	includeContainer iterationAction = iota
 	includeContainer iterationAction = iota
-	// excludeContainer is the action to exclude a container in the reducer.
+	// excludeContainer is the action to exclude a container.
 	excludeContainer
 	excludeContainer
 	// stopIteration is the action to stop iterating over the list of containers.
 	// stopIteration is the action to stop iterating over the list of containers.
 	stopIteration
 	stopIteration
 )
 )
 
 
-// errStopIteration makes the iterator to stop without returning an error.
-var errStopIteration = errors.New("container list iteration stopped")
-
 // List returns an array of all containers registered in the daemon.
 // List returns an array of all containers registered in the daemon.
 func (daemon *Daemon) List() []*container.Container {
 func (daemon *Daemon) List() []*container.Container {
 	return daemon.containers.List()
 	return daemon.containers.List()
@@ -106,7 +99,59 @@ func (r byCreatedDescending) Less(i, j int) bool {
 
 
 // Containers returns the list of containers to show given the user's filtering.
 // Containers returns the list of containers to show given the user's filtering.
 func (daemon *Daemon) Containers(ctx context.Context, config *types.ContainerListOptions) ([]*types.Container, error) {
 func (daemon *Daemon) Containers(ctx context.Context, config *types.ContainerListOptions) ([]*types.Container, error) {
-	return daemon.reduceContainers(ctx, config, daemon.refreshImage)
+	if err := config.Filters.Validate(acceptedPsFilterTags); err != nil {
+		return nil, err
+	}
+
+	var (
+		view       = daemon.containersReplica.Snapshot()
+		containers = []*types.Container{}
+	)
+
+	filter, err := daemon.foldFilter(ctx, view, config)
+	if err != nil {
+		return nil, err
+	}
+
+	// fastpath to only look at a subset of containers if specific name
+	// or ID matches were provided by the user--otherwise we potentially
+	// end up querying many more containers than intended
+	containerList, err := daemon.filterByNameIDMatches(view, filter)
+	if err != nil {
+		return nil, err
+	}
+
+	for i := range containerList {
+		currentContainer := &containerList[i]
+		switch includeContainerInList(currentContainer, filter) {
+		case excludeContainer:
+			continue
+		case stopIteration:
+			return containers, nil
+		}
+
+		// transform internal container struct into api structs
+		newC, err := daemon.refreshImage(ctx, currentContainer)
+		if err != nil {
+			return nil, err
+		}
+
+		// release lock because size calculation is slow
+		if filter.Size {
+			sizeRw, sizeRootFs, err := daemon.imageService.GetContainerLayerSize(ctx, newC.ID)
+			if err != nil {
+				return nil, err
+			}
+			newC.SizeRw = sizeRw
+			newC.SizeRootFs = sizeRootFs
+		}
+		if newC != nil {
+			containers = append(containers, newC)
+			filter.idx++
+		}
+	}
+
+	return containers, nil
 }
 }
 
 
 func (daemon *Daemon) filterByNameIDMatches(view *container.View, filter *listContext) ([]container.Snapshot, error) {
 func (daemon *Daemon) filterByNameIDMatches(view *container.View, filter *listContext) ([]container.Snapshot, error) {
@@ -178,75 +223,6 @@ func (daemon *Daemon) filterByNameIDMatches(view *container.View, filter *listCo
 	return cntrs, nil
 	return cntrs, nil
 }
 }
 
 
-// reduceContainers parses the user's filtering options and generates the list of containers to return based on a reducer.
-func (daemon *Daemon) reduceContainers(ctx context.Context, config *types.ContainerListOptions, reducer containerReducer) ([]*types.Container, error) {
-	if err := config.Filters.Validate(acceptedPsFilterTags); err != nil {
-		return nil, err
-	}
-
-	var (
-		view       = daemon.containersReplica.Snapshot()
-		containers = []*types.Container{}
-	)
-
-	filter, err := daemon.foldFilter(ctx, view, config)
-	if err != nil {
-		return nil, err
-	}
-
-	// fastpath to only look at a subset of containers if specific name
-	// or ID matches were provided by the user--otherwise we potentially
-	// end up querying many more containers than intended
-	containerList, err := daemon.filterByNameIDMatches(view, filter)
-	if err != nil {
-		return nil, err
-	}
-
-	for i := range containerList {
-		t, err := daemon.reducePsContainer(ctx, &containerList[i], filter, reducer)
-		if err != nil {
-			if err != errStopIteration {
-				return nil, err
-			}
-			break
-		}
-		if t != nil {
-			containers = append(containers, t)
-			filter.idx++
-		}
-	}
-
-	return containers, nil
-}
-
-// reducePsContainer is the basic representation for a container as expected by the ps command.
-func (daemon *Daemon) reducePsContainer(ctx context.Context, container *container.Snapshot, filter *listContext, reducer containerReducer) (*types.Container, error) {
-	// filter containers to return
-	switch includeContainerInList(container, filter) {
-	case excludeContainer:
-		return nil, nil
-	case stopIteration:
-		return nil, errStopIteration
-	}
-
-	// transform internal container struct into api structs
-	newC, err := reducer(ctx, container)
-	if err != nil {
-		return nil, err
-	}
-
-	// release lock because size calculation is slow
-	if filter.Size {
-		sizeRw, sizeRootFs, err := daemon.imageService.GetContainerLayerSize(ctx, newC.ID)
-		if err != nil {
-			return nil, err
-		}
-		newC.SizeRw = sizeRw
-		newC.SizeRootFs = sizeRootFs
-	}
-	return newC, nil
-}
-
 // foldFilter generates the container filter based on the user's filtering options.
 // foldFilter generates the container filter based on the user's filtering options.
 func (daemon *Daemon) foldFilter(ctx context.Context, view *container.View, config *types.ContainerListOptions) (*listContext, error) {
 func (daemon *Daemon) foldFilter(ctx context.Context, view *container.View, config *types.ContainerListOptions) (*listContext, error) {
 	psFilters := config.Filters
 	psFilters := config.Filters