| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135 | 
							- /*
 
-    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 compose
 
- import (
 
- 	"context"
 
- 	"fmt"
 
- 	"sort"
 
- 	"strings"
 
- 	"github.com/docker/compose/v2/pkg/api"
 
- 	"github.com/docker/compose/v2/pkg/utils"
 
- 	moby "github.com/docker/docker/api/types"
 
- 	"github.com/docker/docker/api/types/filters"
 
- 	"github.com/sirupsen/logrus"
 
- )
 
- func (s *composeService) List(ctx context.Context, opts api.ListOptions) ([]api.Stack, error) {
 
- 	list, err := s.apiClient().ContainerList(ctx, moby.ContainerListOptions{
 
- 		Filters: filters.NewArgs(hasProjectLabelFilter(), hasConfigHashLabel()),
 
- 		All:     opts.All,
 
- 	})
 
- 	if err != nil {
 
- 		return nil, err
 
- 	}
 
- 	return containersToStacks(list)
 
- }
 
- func containersToStacks(containers []moby.Container) ([]api.Stack, error) {
 
- 	containersByLabel, keys, err := groupContainerByLabel(containers, api.ProjectLabel)
 
- 	if err != nil {
 
- 		return nil, err
 
- 	}
 
- 	var projects []api.Stack
 
- 	for _, project := range keys {
 
- 		configFiles, err := combinedConfigFiles(containersByLabel[project])
 
- 		if err != nil {
 
- 			logrus.Warn(err.Error())
 
- 			configFiles = "N/A"
 
- 		}
 
- 		projects = append(projects, api.Stack{
 
- 			ID:          project,
 
- 			Name:        project,
 
- 			Status:      combinedStatus(containerToState(containersByLabel[project])),
 
- 			ConfigFiles: configFiles,
 
- 		})
 
- 	}
 
- 	return projects, nil
 
- }
 
- func combinedConfigFiles(containers []moby.Container) (string, error) {
 
- 	configFiles := []string{}
 
- 	for _, c := range containers {
 
- 		files, ok := c.Labels[api.ConfigFilesLabel]
 
- 		if !ok {
 
- 			return "", fmt.Errorf("No label %q set on container %q of compose project", api.ConfigFilesLabel, c.ID)
 
- 		}
 
- 		for _, f := range strings.Split(files, ",") {
 
- 			if !utils.StringContains(configFiles, f) {
 
- 				configFiles = append(configFiles, f)
 
- 			}
 
- 		}
 
- 	}
 
- 	return strings.Join(configFiles, ","), nil
 
- }
 
- func containerToState(containers []moby.Container) []string {
 
- 	statuses := []string{}
 
- 	for _, c := range containers {
 
- 		statuses = append(statuses, c.State)
 
- 	}
 
- 	return statuses
 
- }
 
- func combinedStatus(statuses []string) string {
 
- 	nbByStatus := map[string]int{}
 
- 	keys := []string{}
 
- 	for _, status := range statuses {
 
- 		nb, ok := nbByStatus[status]
 
- 		if !ok {
 
- 			nb = 0
 
- 			keys = append(keys, status)
 
- 		}
 
- 		nbByStatus[status] = nb + 1
 
- 	}
 
- 	sort.Strings(keys)
 
- 	result := ""
 
- 	for _, status := range keys {
 
- 		nb := nbByStatus[status]
 
- 		if result != "" {
 
- 			result += ", "
 
- 		}
 
- 		result += fmt.Sprintf("%s(%d)", status, nb)
 
- 	}
 
- 	return result
 
- }
 
- func groupContainerByLabel(containers []moby.Container, labelName string) (map[string][]moby.Container, []string, error) {
 
- 	containersByLabel := map[string][]moby.Container{}
 
- 	keys := []string{}
 
- 	for _, c := range containers {
 
- 		label, ok := c.Labels[labelName]
 
- 		if !ok {
 
- 			return nil, nil, fmt.Errorf("No label %q set on container %q of compose project", labelName, c.ID)
 
- 		}
 
- 		labelContainers, ok := containersByLabel[label]
 
- 		if !ok {
 
- 			labelContainers = []moby.Container{}
 
- 			keys = append(keys, label)
 
- 		}
 
- 		labelContainers = append(labelContainers, c)
 
- 		containersByLabel[label] = labelContainers
 
- 	}
 
- 	sort.Strings(keys)
 
- 	return containersByLabel, keys, nil
 
- }
 
 
  |