Merge pull request #926 from gtardif/compose_ps

compose ps implementation
This commit is contained in:
Guillaume Tardif 2020-11-19 16:27:09 +01:00 committed by GitHub
commit 922a2e6296
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 96 additions and 29 deletions

View File

@ -247,19 +247,51 @@ func (s *local) Ps(ctx context.Context, projectName string) ([]compose.ServiceSt
if err != nil {
return nil, err
}
var status []compose.ServiceStatus
for _, c := range list {
// TODO group by service
status = append(status, compose.ServiceStatus{
ID: c.ID,
Name: c.Labels[serviceLabel],
Replicas: 0,
Desired: 0,
Ports: nil,
Publishers: nil,
return containersToServiceStatus(list)
}
func containersToServiceStatus(containers []moby.Container) ([]compose.ServiceStatus, error) {
containersByLabel, keys, err := groupContainerByLabel(containers, serviceLabel)
if err != nil {
return nil, err
}
var services []compose.ServiceStatus
for _, service := range keys {
containers := containersByLabel[service]
runnningContainers := []moby.Container{}
for _, container := range containers {
if container.State == "running" {
runnningContainers = append(runnningContainers, container)
}
}
services = append(services, compose.ServiceStatus{
ID: service,
Name: service,
Desired: len(containers),
Replicas: len(runnningContainers),
})
}
return status, nil
return services, nil
}
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
}
func (s *local) List(ctx context.Context, projectName string) ([]compose.Stack, error) {
@ -274,35 +306,29 @@ func (s *local) List(ctx context.Context, projectName string) ([]compose.Stack,
}
func containersToStacks(containers []moby.Container) ([]compose.Stack, error) {
statusesByProject := map[string][]string{}
keys := []string{}
for _, c := range containers {
project, ok := c.Labels[projectLabel]
if !ok {
return nil, fmt.Errorf("No label %q set on container %q of compose project", serviceLabel, c.ID)
}
projectStatuses, ok := statusesByProject[project]
if !ok {
projectStatuses = []string{}
keys = append(keys, project)
}
projectStatuses = append(projectStatuses, c.State)
statusesByProject[project] = projectStatuses
containersByLabel, keys, err := groupContainerByLabel(containers, projectLabel)
if err != nil {
return nil, err
}
sort.Strings(keys)
var projects []compose.Stack
for _, project := range keys {
statuses := statusesByProject[project]
projects = append(projects, compose.Stack{
ID: project,
Name: project,
Status: combinedStatus(statuses),
Status: combinedStatus(containerToState(containersByLabel[project])),
})
}
return projects, 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{}

View File

@ -61,6 +61,47 @@ func TestContainersToStacks(t *testing.T) {
})
}
func TestContainersToServiceStatus(t *testing.T) {
containers := []types.Container{
{
ID: "c1",
State: "running",
Labels: map[string]string{serviceLabel: "service1"},
},
{
ID: "c2",
State: "exited",
Labels: map[string]string{serviceLabel: "service1"},
},
{
ID: "c3",
State: "running",
Labels: map[string]string{serviceLabel: "service1"},
},
{
ID: "c4",
State: "running",
Labels: map[string]string{serviceLabel: "service2"},
},
}
services, err := containersToServiceStatus(containers)
assert.NilError(t, err)
assert.DeepEqual(t, services, []compose.ServiceStatus{
{
ID: "service1",
Name: "service1",
Replicas: 2,
Desired: 3,
},
{
ID: "service2",
Name: "service2",
Replicas: 1,
Desired: 1,
},
})
}
func TestStacksMixedStatus(t *testing.T) {
assert.Equal(t, combinedStatus([]string{"running"}), "running(1)")
assert.Equal(t, combinedStatus([]string{"running", "running", "running"}), "running(3)")