diff --git a/aci/backend.go b/aci/backend.go index 02b578bfe..2df3be63a 100644 --- a/aci/backend.go +++ b/aci/backend.go @@ -134,32 +134,14 @@ type aciContainerService struct { } func (cs *aciContainerService) List(ctx context.Context, all bool) ([]containers.Container, error) { - groupsClient, err := login.NewContainerGroupsClient(cs.ctx.SubscriptionID) - if err != nil { - return nil, err - } - var containerGroups []containerinstance.ContainerGroup - result, err := groupsClient.ListByResourceGroup(ctx, cs.ctx.ResourceGroup) + containerGroups, err := getContainerGroups(ctx, cs.ctx.SubscriptionID, cs.ctx.ResourceGroup) if err != nil { return []containers.Container{}, err } - - for result.NotDone() { - containerGroups = append(containerGroups, result.Values()...) - if err := result.NextWithContext(ctx); err != nil { - return []containers.Container{}, err - } - } - var res []containers.Container - for _, containerGroup := range containerGroups { - group, err := groupsClient.Get(ctx, cs.ctx.ResourceGroup, *containerGroup.Name) - if err != nil { - return []containers.Container{}, err - } - + for _, group := range containerGroups { if group.Containers == nil || len(*group.Containers) < 1 { - return []containers.Container{}, fmt.Errorf("no containers found in ACI container group %s", *containerGroup.Name) + return []containers.Container{}, fmt.Errorf("no containers found in ACI container group %s", *group.Name) } for _, container := range *group.Containers { @@ -173,6 +155,26 @@ func (cs *aciContainerService) List(ctx context.Context, all bool) ([]containers return res, nil } +func getContainerGroups(ctx context.Context, subscriptionID string, resourceGroup string) ([]containerinstance.ContainerGroup, error) { + groupsClient, err := login.NewContainerGroupsClient(subscriptionID) + if err != nil { + return nil, err + } + var containerGroups []containerinstance.ContainerGroup + result, err := groupsClient.ListByResourceGroup(ctx, resourceGroup) + if err != nil { + return []containerinstance.ContainerGroup{}, err + } + + for result.NotDone() { + containerGroups = append(containerGroups, result.Values()...) + if err := result.NextWithContext(ctx); err != nil { + return []containerinstance.ContainerGroup{}, err + } + } + return containerGroups, nil +} + func getContainerID(group containerinstance.ContainerGroup, container containerinstance.Container) string { containerID := *group.Name + composeContainerSeparator + *container.Name if _, ok := group.Tags[singleContainerTag]; ok { @@ -446,8 +448,33 @@ func (cs *aciComposeService) Ps(ctx context.Context, project string) ([]compose. } return res, nil } + func (cs *aciComposeService) List(ctx context.Context, project string) ([]compose.Stack, error) { - return nil, errdefs.ErrNotImplemented + containerGroups, err := getContainerGroups(ctx, cs.ctx.SubscriptionID, cs.ctx.ResourceGroup) + if err != nil { + return []compose.Stack{}, err + } + + stacks := []compose.Stack{} + for _, group := range containerGroups { + if _, found := group.Tags[composeContainerTag]; !found { + continue + } + state := compose.RUNNING + for _, container := range *group.ContainerGroupProperties.Containers { + containerState := convert.GetStatus(container, group) + if containerState != compose.RUNNING { + state = containerState + break + } + } + stacks = append(stacks, compose.Stack{ + ID: *group.ID, + Name: *group.Name, + Status: state, + }) + } + return stacks, nil } func (cs *aciComposeService) Logs(ctx context.Context, project string, w io.Writer) error { diff --git a/aci/convert/convert.go b/aci/convert/convert.go index 3df1ee055..f8da647f2 100644 --- a/aci/convert/convert.go +++ b/aci/convert/convert.go @@ -451,7 +451,16 @@ func ContainerGroupToContainer(containerID string, cg containerinstance.Containe // GetStatus returns status for the specified container func GetStatus(container containerinstance.Container, group containerinstance.ContainerGroup) string { - status := "Unknown" + status := compose.UNKNOWN + if group.ContainerGroupProperties != nil && group.ContainerGroupProperties.ProvisioningState != nil { + status = *group.ContainerGroupProperties.ProvisioningState + switch status { + case "Succeeded": + status = compose.RUNNING + case "Failed": + status = compose.FAILED + } + } if group.InstanceView != nil && group.InstanceView.State != nil { status = "Node " + *group.InstanceView.State } diff --git a/api/compose/api.go b/api/compose/api.go index 666290e71..98ed050e0 100644 --- a/api/compose/api.go +++ b/api/compose/api.go @@ -57,23 +57,24 @@ type ServiceStatus struct { Publishers []PortPublisher } -// State of a compose stack -type State string - const ( // STARTING indicates that stack is being deployed - STARTING State = "starting" + STARTING string = "Starting" // RUNNING indicates that stack is deployed and services are running - RUNNING State = "running" + RUNNING string = "Running" // UPDATING indicates that some stack resources are being recreated - UPDATING State = "updating" + UPDATING string = "Updating" // REMOVING indicates that stack is being deleted - REMOVING State = "removing" + REMOVING string = "Removing" + // UNKNOWN indicates unknown stack state + UNKNOWN string = "Unknown" + // FAILED indicates that stack deployment failed + FAILED string = "Failed" ) // Stack holds the name and state of a compose application/stack type Stack struct { ID string Name string - Status State + Status string } diff --git a/ecs/sdk.go b/ecs/sdk.go index 426081c52..0833f97f5 100644 --- a/ecs/sdk.go +++ b/ecs/sdk.go @@ -325,7 +325,7 @@ func (s sdk) ListStacks(ctx context.Context, name string) ([]compose.Stack, erro Name: aws.StringValue(stack.StackName), Status: status, }) - continue + break } } }