From a87cd3fc2c1efa378091c82f1c5023dac8042995 Mon Sep 17 00:00:00 2001 From: Christophe Robin Date: Fri, 17 Feb 2017 01:50:41 +0900 Subject: [PATCH 1/2] Fix docker issues with global and dead tasks --- provider/docker.go | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) diff --git a/provider/docker.go b/provider/docker.go index 1871d1c1f..4b182a917 100644 --- a/provider/docker.go +++ b/provider/docker.go @@ -626,11 +626,12 @@ func (provider *Docker) listServices(ctx context.Context, dockerClient client.AP for _, service := range serviceList { dockerData := parseService(service, networkMap) useSwarmLB, _ := strconv.ParseBool(provider.getIsBackendLBSwarm(dockerData)) + isGlobalSvc := service.Spec.Mode.Global != nil if useSwarmLB { dockerDataList = append(dockerDataList, dockerData) } else { - dockerDataListTasks, err = listTasks(ctx, dockerClient, service.ID, dockerData, networkMap) + dockerDataListTasks, err = listTasks(ctx, dockerClient, service.ID, dockerData, networkMap, isGlobalSvc) for _, dockerDataTask := range dockerDataListTasks { dockerDataList = append(dockerDataList, dockerDataTask) @@ -675,9 +676,10 @@ func parseService(service swarmtypes.Service, networkMap map[string]*dockertypes } func listTasks(ctx context.Context, dockerClient client.APIClient, serviceID string, - serviceDockerData dockerData, networkMap map[string]*dockertypes.NetworkResource) ([]dockerData, error) { + serviceDockerData dockerData, networkMap map[string]*dockertypes.NetworkResource, isGlobalSvc bool) ([]dockerData, error) { serviceIDFilter := filters.NewArgs() serviceIDFilter.Add("service", serviceID) + serviceIDFilter.Add("desired-state", "running") taskList, err := dockerClient.TaskList(ctx, dockertypes.TaskListOptions{Filter: serviceIDFilter}) if err != nil { @@ -686,13 +688,13 @@ func listTasks(ctx context.Context, dockerClient client.APIClient, serviceID str var dockerDataList []dockerData for _, task := range taskList { - dockerData := parseTasks(task, serviceDockerData, networkMap) + dockerData := parseTasks(task, serviceDockerData, networkMap, isGlobalSvc) dockerDataList = append(dockerDataList, dockerData) } return dockerDataList, err } -func parseTasks(task swarmtypes.Task, serviceDockerData dockerData, networkMap map[string]*dockertypes.NetworkResource) dockerData { +func parseTasks(task swarmtypes.Task, serviceDockerData dockerData, networkMap map[string]*dockertypes.NetworkResource, isGlobalSvc bool) dockerData { dockerData := dockerData{ ServiceName: serviceDockerData.Name, Name: serviceDockerData.Name + "." + strconv.Itoa(task.Slot), @@ -700,6 +702,10 @@ func parseTasks(task swarmtypes.Task, serviceDockerData dockerData, networkMap m NetworkSettings: networkSettings{}, } + if isGlobalSvc == true { + dockerData.Name = serviceDockerData.Name + "." + task.ID + } + if task.NetworksAttachments != nil { dockerData.NetworkSettings.Networks = make(map[string]*networkData) for _, virtualIP := range task.NetworksAttachments { From d342ae68d8958ac540ee9c5189f2b73a4680fc6d Mon Sep 17 00:00:00 2001 From: Christophe Robin Date: Wed, 22 Feb 2017 01:45:13 +0900 Subject: [PATCH 2/2] Add task parser unit test for docker provider --- provider/docker_test.go | 87 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 87 insertions(+) diff --git a/provider/docker_test.go b/provider/docker_test.go index 4c10be819..7ed3fb9d8 100644 --- a/provider/docker_test.go +++ b/provider/docker_test.go @@ -2184,3 +2184,90 @@ func TestSwarmLoadDockerConfig(t *testing.T) { } } } + +func TestSwarmTaskParsing(t *testing.T) { + cases := []struct { + service swarm.Service + tasks []swarm.Task + isGlobalSvc bool + expectedNames map[string]string + networks map[string]*docker.NetworkResource + }{ + { + service: swarm.Service{ + Spec: swarm.ServiceSpec{ + Annotations: swarm.Annotations{ + Name: "container", + }, + }, + }, + tasks: []swarm.Task{ + { + ID: "id1", + Slot: 1, + }, + { + ID: "id2", + Slot: 2, + }, + { + ID: "id3", + Slot: 3, + }, + }, + isGlobalSvc: false, + expectedNames: map[string]string{ + "id1": "container.1", + "id2": "container.2", + "id3": "container.3", + }, + networks: map[string]*docker.NetworkResource{ + "1": { + Name: "foo", + }, + }, + }, + { + service: swarm.Service{ + Spec: swarm.ServiceSpec{ + Annotations: swarm.Annotations{ + Name: "container", + }, + }, + }, + tasks: []swarm.Task{ + { + ID: "id1", + }, + { + ID: "id2", + }, + { + ID: "id3", + }, + }, + isGlobalSvc: true, + expectedNames: map[string]string{ + "id1": "container.id1", + "id2": "container.id2", + "id3": "container.id3", + }, + networks: map[string]*docker.NetworkResource{ + "1": { + Name: "foo", + }, + }, + }, + } + + for _, e := range cases { + dockerData := parseService(e.service, e.networks) + + for _, task := range e.tasks { + taskDockerData := parseTasks(task, dockerData, map[string]*docker.NetworkResource{}, e.isGlobalSvc) + if !reflect.DeepEqual(taskDockerData.Name, e.expectedNames[task.ID]) { + t.Fatalf("expect %v, got %v", e.expectedNames[task.ID], taskDockerData.Name) + } + } + } +}