Browse Source

Merge pull request #508 from docker/aci_container_status

Aci container status
Guillaume Tardif 5 years ago
parent
commit
8e84e09bdc
4 changed files with 67 additions and 39 deletions
  1. 4 26
      aci/backend.go
  2. 15 6
      aci/convert/convert.go
  3. 41 2
      aci/convert/convert_test.go
  4. 7 5
      tests/aci-e2e/e2e-aci_test.go

+ 4 - 26
aci/backend.go

@@ -49,7 +49,6 @@ const (
 	singleContainerTag        = "docker-single-container"
 	singleContainerTag        = "docker-single-container"
 	composeContainerTag       = "docker-compose-application"
 	composeContainerTag       = "docker-compose-application"
 	composeContainerSeparator = "_"
 	composeContainerSeparator = "_"
-	statusUnknown             = "Unknown"
 	statusRunning             = "Running"
 	statusRunning             = "Running"
 )
 )
 
 
@@ -166,38 +165,20 @@ func (cs *aciContainerService) List(ctx context.Context, all bool) ([]containers
 			if *container.Name == convert.ComposeDNSSidecarName {
 			if *container.Name == convert.ComposeDNSSidecarName {
 				continue
 				continue
 			}
 			}
-			if !all && getStatus(container) != statusRunning {
+			if !all && convert.GetStatus(container, group) != statusRunning {
 				continue
 				continue
 			}
 			}
 			containerID := *containerGroup.Name + composeContainerSeparator + *container.Name
 			containerID := *containerGroup.Name + composeContainerSeparator + *container.Name
 			if _, ok := group.Tags[singleContainerTag]; ok {
 			if _, ok := group.Tags[singleContainerTag]; ok {
 				containerID = *containerGroup.Name
 				containerID = *containerGroup.Name
 			}
 			}
-			c := getContainer(containerID, group.IPAddress, container)
+			c := convert.ContainerGroupToContainer(containerID, group, container)
 			res = append(res, c)
 			res = append(res, c)
 		}
 		}
 	}
 	}
 	return res, nil
 	return res, nil
 }
 }
 
 
-func getContainer(containerID string, ipAddress *containerinstance.IPAddress, container containerinstance.Container) containers.Container {
-	status := getStatus(container)
-	return containers.Container{
-		ID:     containerID,
-		Image:  *container.Image,
-		Status: status,
-		Ports:  convert.ToPorts(ipAddress, *container.Ports),
-	}
-}
-
-func getStatus(container containerinstance.Container) string {
-	status := statusUnknown
-	if container.InstanceView != nil && container.InstanceView.CurrentState != nil {
-		status = *container.InstanceView.CurrentState.State
-	}
-	return status
-}
-
 func (cs *aciContainerService) Run(ctx context.Context, r containers.ContainerConfig) error {
 func (cs *aciContainerService) Run(ctx context.Context, r containers.ContainerConfig) error {
 	if strings.Contains(r.ID, composeContainerSeparator) {
 	if strings.Contains(r.ID, composeContainerSeparator) {
 		return errors.New(fmt.Sprintf("invalid container name. ACI container name cannot include %q", composeContainerSeparator))
 		return errors.New(fmt.Sprintf("invalid container name. ACI container name cannot include %q", composeContainerSeparator))
@@ -350,10 +331,7 @@ func (cs *aciContainerService) Delete(ctx context.Context, containerID string, r
 		}
 		}
 
 
 		for _, container := range *cg.Containers {
 		for _, container := range *cg.Containers {
-			status := statusUnknown
-			if container.InstanceView != nil && container.InstanceView.CurrentState != nil {
-				status = *container.InstanceView.CurrentState.State
-			}
+			status := convert.GetStatus(container, cg)
 
 
 			if status == statusRunning {
 			if status == statusRunning {
 				return errdefs.ErrForbidden
 				return errdefs.ErrForbidden
@@ -397,7 +375,7 @@ func (cs *aciContainerService) Inspect(ctx context.Context, containerID string)
 		return containers.Container{}, errdefs.ErrNotFound
 		return containers.Container{}, errdefs.ErrNotFound
 	}
 	}
 
 
-	return convert.ContainerGroupToContainer(containerID, cg, cc)
+	return convert.ContainerGroupToContainer(containerID, cg, cc), nil
 }
 }
 
 
 type aciComposeService struct {
 type aciComposeService struct {

+ 15 - 6
aci/convert/convert.go

@@ -386,7 +386,7 @@ func bytesToGb(b types.UnitBytes) float64 {
 }
 }
 
 
 // ContainerGroupToContainer composes a Container from an ACI container definition
 // ContainerGroupToContainer composes a Container from an ACI container definition
-func ContainerGroupToContainer(containerID string, cg containerinstance.ContainerGroup, cc containerinstance.Container) (containers.Container, error) {
+func ContainerGroupToContainer(containerID string, cg containerinstance.ContainerGroup, cc containerinstance.Container) containers.Container {
 	memLimits := 0.
 	memLimits := 0.
 	if cc.Resources != nil &&
 	if cc.Resources != nil &&
 		cc.Resources.Limits != nil &&
 		cc.Resources.Limits != nil &&
@@ -406,10 +406,7 @@ func ContainerGroupToContainer(containerID string, cg containerinstance.Containe
 		command = strings.Join(*cc.Command, " ")
 		command = strings.Join(*cc.Command, " ")
 	}
 	}
 
 
-	status := "Unknown"
-	if cc.InstanceView != nil && cc.InstanceView.CurrentState != nil {
-		status = *cc.InstanceView.CurrentState.State
-	}
+	status := GetStatus(cc, cg)
 	platform := string(cg.OsType)
 	platform := string(cg.OsType)
 
 
 	c := containers.Container{
 	c := containers.Container{
@@ -429,5 +426,17 @@ func ContainerGroupToContainer(containerID string, cg containerinstance.Containe
 		RestartPolicyCondition: toContainerRestartPolicy(cg.RestartPolicy),
 		RestartPolicyCondition: toContainerRestartPolicy(cg.RestartPolicy),
 	}
 	}
 
 
-	return c, nil
+	return c
+}
+
+// GetStatus returns status for the specified container
+func GetStatus(container containerinstance.Container, group containerinstance.ContainerGroup) string {
+	status := "Unknown"
+	if group.InstanceView != nil && group.InstanceView.State != nil {
+		status = "Node " + *group.InstanceView.State
+	}
+	if container.InstanceView != nil && container.InstanceView.CurrentState != nil {
+		status = *container.InstanceView.CurrentState.State
+	}
+	return status
 }
 }

+ 41 - 2
aci/convert/convert_test.go

@@ -99,8 +99,7 @@ func TestContainerGroupToContainer(t *testing.T) {
 		RestartPolicyCondition: "any",
 		RestartPolicyCondition: "any",
 	}
 	}
 
 
-	container, err := ContainerGroupToContainer("myContainerID", myContainerGroup, myContainer)
-	assert.NilError(t, err)
+	container := ContainerGroupToContainer("myContainerID", myContainerGroup, myContainer)
 	assert.DeepEqual(t, container, expectedContainer)
 	assert.DeepEqual(t, container, expectedContainer)
 }
 }
 
 
@@ -408,3 +407,43 @@ func TestConvertToDockerRestartPolicyCondition(t *testing.T) {
 	assert.Equal(t, toContainerRestartPolicy(containerinstance.OnFailure), "on-failure")
 	assert.Equal(t, toContainerRestartPolicy(containerinstance.OnFailure), "on-failure")
 	assert.Equal(t, toContainerRestartPolicy(""), "any")
 	assert.Equal(t, toContainerRestartPolicy(""), "any")
 }
 }
+
+func TestConvertContainerGroupStatus(t *testing.T) {
+	assert.Equal(t, "Running", GetStatus(container(to.StringPtr("Running")), group(to.StringPtr("Started"))))
+	assert.Equal(t, "Terminated", GetStatus(container(to.StringPtr("Terminated")), group(to.StringPtr("Stopped"))))
+	assert.Equal(t, "Node Stopped", GetStatus(container(nil), group(to.StringPtr("Stopped"))))
+	assert.Equal(t, "Node Started", GetStatus(container(nil), group(to.StringPtr("Started"))))
+
+	assert.Equal(t, "Running", GetStatus(container(to.StringPtr("Running")), group(nil)))
+	assert.Equal(t, "Unknown", GetStatus(container(nil), group(nil)))
+}
+
+func container(status *string) containerinstance.Container {
+	var state *containerinstance.ContainerState = nil
+	if status != nil {
+		state = &containerinstance.ContainerState{
+			State: status,
+		}
+	}
+	return containerinstance.Container{
+		ContainerProperties: &containerinstance.ContainerProperties{
+			InstanceView: &containerinstance.ContainerPropertiesInstanceView{
+				CurrentState: state,
+			},
+		},
+	}
+}
+
+func group(status *string) containerinstance.ContainerGroup {
+	var view *containerinstance.ContainerGroupPropertiesInstanceView = nil
+	if status != nil {
+		view = &containerinstance.ContainerGroupPropertiesInstanceView{
+			State: status,
+		}
+	}
+	return containerinstance.ContainerGroup{
+		ContainerGroupProperties: &containerinstance.ContainerGroupProperties{
+			InstanceView: view,
+		},
+	}
+}

+ 7 - 5
tests/aci-e2e/e2e-aci_test.go

@@ -394,7 +394,7 @@ func TestContainerRunAttached(t *testing.T) {
 	t.Run("rm stopped container", func(t *testing.T) {
 	t.Run("rm stopped container", func(t *testing.T) {
 		res := c.RunDockerCmd("stop", container)
 		res := c.RunDockerCmd("stop", container)
 		res.Assert(t, icmd.Expected{Out: container})
 		res.Assert(t, icmd.Expected{Out: container})
-		waitForStatus(t, c, container, "Terminated")
+		waitForStatus(t, c, container, "Terminated", "Node Stopped")
 
 
 		res = c.RunDockerCmd("rm", container)
 		res = c.RunDockerCmd("rm", container)
 		res.Assert(t, icmd.Expected{Out: container})
 		res.Assert(t, icmd.Expected{Out: container})
@@ -664,15 +664,17 @@ func getContainerName(stdout string) string {
 	return strings.TrimSpace(out[len(out)-1])
 	return strings.TrimSpace(out[len(out)-1])
 }
 }
 
 
-func waitForStatus(t *testing.T, c *E2eCLI, containerID string, status string) {
+func waitForStatus(t *testing.T, c *E2eCLI, containerID string, statuses ...string) {
 	checkStopped := func(logt poll.LogT) poll.Result {
 	checkStopped := func(logt poll.LogT) poll.Result {
 		res := c.RunDockerCmd("inspect", containerID)
 		res := c.RunDockerCmd("inspect", containerID)
 		containerInspect, err := ParseContainerInspect(res.Stdout())
 		containerInspect, err := ParseContainerInspect(res.Stdout())
 		assert.NilError(t, err)
 		assert.NilError(t, err)
-		if containerInspect.Status == status {
-			return poll.Success()
+		for _, status := range statuses {
+			if containerInspect.Status == status {
+				return poll.Success()
+			}
 		}
 		}
-		return poll.Continue("Status %s != %s (expected) for container %s", containerInspect.Status, status, containerID)
+		return poll.Continue("Status %s != %s (expected) for container %s", containerInspect.Status, statuses, containerID)
 	}
 	}
 
 
 	poll.WaitOn(t, checkStopped, poll.WithDelay(5*time.Second), poll.WithTimeout(90*time.Second))
 	poll.WaitOn(t, checkStopped, poll.WithDelay(5*time.Second), poll.WithTimeout(90*time.Second))