From 6bba5faad35f632ddee013c650fe6965fdbaf308 Mon Sep 17 00:00:00 2001 From: Dennis Staal Date: Wed, 28 Feb 2024 14:57:58 +0100 Subject: [PATCH 01/13] Updated README.md --- README.md | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 806b20c..794aadb 100644 --- a/README.md +++ b/README.md @@ -1,2 +1,8 @@ # Container manager -Used to ensure that containers is running. \ No newline at end of file +Used to ensure that containers listed in config.yml is running. + +- Start/stop containers listed in config.yml +- Add to network listed in config.yml +- Detach from network if it is not being used (attachAllNetwork only) + +See config.example.yaml for configutation example. From f57cdc5c7a205a3a4821c1fac0bef622830b5935 Mon Sep 17 00:00:00 2001 From: Dennis Staal Date: Thu, 14 Mar 2024 14:55:35 +0100 Subject: [PATCH 02/13] Update README Only attach new containers to networks if there is more than 0 containers already attached Detect if container-manager containers is connected to network as the only ones --- README.md | 3 ++- main.go | 45 ++++++++++++++++++++++++++++++++++++++++----- 2 files changed, 42 insertions(+), 6 deletions(-) diff --git a/README.md b/README.md index 794aadb..b072b92 100644 --- a/README.md +++ b/README.md @@ -1,5 +1,6 @@ # Container manager -Used to ensure that containers listed in config.yml is running. +Used to ensure that containers listed in config.yml is running and +is connected to Docker networks. - Start/stop containers listed in config.yml - Add to network listed in config.yml diff --git a/main.go b/main.go index a6e5970..9136e09 100644 --- a/main.go +++ b/main.go @@ -32,7 +32,7 @@ import ( var Build string const ( - appName = "container-manager" + appName string = "container-manager" ) var ( @@ -190,7 +190,13 @@ func NewManager(l *logrus.Logger) (*manager, error) { } func (m *manager) run(config *Config) { - networkNames, err := m.getNetworkNames() + // Create a list of container-manager containers + configNames := []string{} + for _, c := range config.Containers { + configNames = append(configNames, c.Name) + } + + networkNames, err := m.getNetworkNames(configNames) if err != nil { m.l.Error(err) return @@ -442,7 +448,7 @@ func (m *manager) stopContainers(config *Config) { } } -func (m *manager) getNetworkNames() ([]string, error) { +func (m *manager) getNetworkNames(configNames []string) ([]string, error) { names := []string{} networks, err := m.cli.NetworkList(m.ctx, types.NetworkListOptions{}) @@ -450,9 +456,38 @@ func (m *manager) getNetworkNames() ([]string, error) { return nil, err } + // fmt.Println(len(configNames)) + for _, network := range networks { - if (network.Attachable || network.Scope == "local") && !containsString(ignoredNetworkNames, network.Name) { - names = append(names, network.Name) + // Inspect each network to get attached containers + attached, err := m.cli.NetworkInspect(m.ctx, network.Name, types.NetworkInspectOptions{}) + if err != nil { + return nil, err + } + + // fmt.Printf("DEBUG: LIST ALL NETWORK CONTAINERS --> ") + // fmt.Printf(network.Name) + // fmt.Printf(": ") + + for _, container := range attached.Containers { + if containsString(configNames, container.Name) && network.Name != "bridge" { + // fmt.Println(attached.Containers) + // fmt.Print((len(attached.Containers) - len(configNames))) + if (len(attached.Containers) - len(configNames)) == 0 { + fmt.Printf("Okay, so %s is attached as the only container in %s...\n", container.Name, network.Name) + } + } + + // fmt.Println(containsString(configNames, container.Name)) + // fmt.Printf(container.Name) + } + // fmt.Println("...") + + // If more than 0 containers in a network, then add YAML containers to the network + if len(attached.Containers) > 0 { + if (network.Attachable || network.Scope == "local") && !containsString(ignoredNetworkNames, network.Name) { + names = append(names, network.Name) + } } } From 92eb21fabc9e4b581ff6f7213d243471ce0a70e4 Mon Sep 17 00:00:00 2001 From: Dennis Staal Date: Sat, 16 Mar 2024 08:23:04 +0100 Subject: [PATCH 03/13] Add detach network --- main.go | 43 ++++++++++++++++++++++++++++++++----------- 1 file changed, 32 insertions(+), 11 deletions(-) diff --git a/main.go b/main.go index 9136e09..ebdf6dc 100644 --- a/main.go +++ b/main.go @@ -456,8 +456,6 @@ func (m *manager) getNetworkNames(configNames []string) ([]string, error) { return nil, err } - // fmt.Println(len(configNames)) - for _, network := range networks { // Inspect each network to get attached containers attached, err := m.cli.NetworkInspect(m.ctx, network.Name, types.NetworkInspectOptions{}) @@ -465,25 +463,26 @@ func (m *manager) getNetworkNames(configNames []string) ([]string, error) { return nil, err } - // fmt.Printf("DEBUG: LIST ALL NETWORK CONTAINERS --> ") - // fmt.Printf(network.Name) - // fmt.Printf(": ") - for _, container := range attached.Containers { if containsString(configNames, container.Name) && network.Name != "bridge" { - // fmt.Println(attached.Containers) - // fmt.Print((len(attached.Containers) - len(configNames))) if (len(attached.Containers) - len(configNames)) == 0 { fmt.Printf("Okay, so %s is attached as the only container in %s...\n", container.Name, network.Name) + // Call detach network + m.detachNetwork(network.Name, container.Name) } } + } - // fmt.Println(containsString(configNames, container.Name)) - // fmt.Printf(container.Name) + // Inspect once more to get updated attached containers + attached, err = m.cli.NetworkInspect(m.ctx, network.Name, types.NetworkInspectOptions{}) + if err != nil { + return nil, err } - // fmt.Println("...") + + fmt.Printf("Num in %s: %v \n", network.Name, len(attached.Containers)) // If more than 0 containers in a network, then add YAML containers to the network + // if (len(attached.Containers) + len(configNames)) > len(configNames) { if len(attached.Containers) > 0 { if (network.Attachable || network.Scope == "local") && !containsString(ignoredNetworkNames, network.Name) { names = append(names, network.Name) @@ -493,9 +492,31 @@ func (m *manager) getNetworkNames(configNames []string) ([]string, error) { sort.Strings(names) + fmt.Printf("Network list: %s", names) + return names, nil } +func (m *manager) detachNetwork(network string, container string) { + err := m.cli.NetworkDisconnect(m.ctx, network, container, true) + + m.l.Infof("Detaching %s from network %s\n", container, network) + + if err != nil { + m.l.Error(err) + } +} + +// func (m *manager) attachNetwork(network string, container string) { +// err := m.cli.NetworkConnect(m.ctx, network, container, ) + +// m.l.Infof("Detaching %s from network %s\n", container, network) + +// if err != nil { +// m.l.Error(err) +// } +// } + func containsString(strings []string, s string) bool { for _, a := range strings { if s == a { From d91613955b7fba5fa7483de7fc1c56aeb92a7935 Mon Sep 17 00:00:00 2001 From: Dennis Staal Date: Mon, 18 Mar 2024 09:33:46 +0100 Subject: [PATCH 04/13] Add attach network+cleanup code --- main.go | 44 ++++++++++++++++++++++++++------------------ 1 file changed, 26 insertions(+), 18 deletions(-) diff --git a/main.go b/main.go index ebdf6dc..e36d010 100644 --- a/main.go +++ b/main.go @@ -465,9 +465,8 @@ func (m *manager) getNetworkNames(configNames []string) ([]string, error) { for _, container := range attached.Containers { if containsString(configNames, container.Name) && network.Name != "bridge" { + // Detach from network if config containers is the only ones if (len(attached.Containers) - len(configNames)) == 0 { - fmt.Printf("Okay, so %s is attached as the only container in %s...\n", container.Name, network.Name) - // Call detach network m.detachNetwork(network.Name, container.Name) } } @@ -479,43 +478,52 @@ func (m *manager) getNetworkNames(configNames []string) ([]string, error) { return nil, err } - fmt.Printf("Num in %s: %v \n", network.Name, len(attached.Containers)) - - // If more than 0 containers in a network, then add YAML containers to the network - // if (len(attached.Containers) + len(configNames)) > len(configNames) { + // If more than 0 containers in a network, then add config containers to the network if len(attached.Containers) > 0 { if (network.Attachable || network.Scope == "local") && !containsString(ignoredNetworkNames, network.Name) { names = append(names, network.Name) + + // Attach to network if not already attached + for _, container := range configNames { + if !containerInNetworks(container, attached) { + m.attachNetwork(network.Name, container) + } + } } } } sort.Strings(names) - fmt.Printf("Network list: %s", names) - return names, nil } +func containerInNetworks(containerName string, attached types.NetworkResource) bool { + for _, c := range attached.Containers { + if containerName == c.Name { + return true + } + } + return false +} + func (m *manager) detachNetwork(network string, container string) { err := m.cli.NetworkDisconnect(m.ctx, network, container, true) - m.l.Infof("Detaching %s from network %s\n", container, network) + m.l.Debugf("Detaching %s from network %s\n", container, network) if err != nil { m.l.Error(err) } } -// func (m *manager) attachNetwork(network string, container string) { -// err := m.cli.NetworkConnect(m.ctx, network, container, ) - -// m.l.Infof("Detaching %s from network %s\n", container, network) - -// if err != nil { -// m.l.Error(err) -// } -// } +func (m *manager) attachNetwork(network string, container string) { + err := m.cli.NetworkConnect(m.ctx, network, container, nil) + if err != nil { + m.l.Error(err) + } + m.l.Debugf("Attaching %s to network %s\n", container, network) +} func containsString(strings []string, s string) bool { for _, a := range strings { From 48f3ba92f00fb8bced812d29d152cb3c612643f8 Mon Sep 17 00:00:00 2001 From: Staal <48656753+staal0@users.noreply.github.com> Date: Tue, 19 Mar 2024 08:00:20 +0100 Subject: [PATCH 05/13] Reword comment Co-authored-by: Mads Jon Nielsen --- main.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/main.go b/main.go index e36d010..18c7842 100644 --- a/main.go +++ b/main.go @@ -478,7 +478,7 @@ func (m *manager) getNetworkNames(configNames []string) ([]string, error) { return nil, err } - // If more than 0 containers in a network, then add config containers to the network + // If more than 0 containers in a network excluding containers from config, then add containers in config to the network if len(attached.Containers) > 0 { if (network.Attachable || network.Scope == "local") && !containsString(ignoredNetworkNames, network.Name) { names = append(names, network.Name) From 1d5ff4f8136bc5916868cb46f6236c178f44ac4d Mon Sep 17 00:00:00 2001 From: Staal <48656753+staal0@users.noreply.github.com> Date: Tue, 19 Mar 2024 08:02:11 +0100 Subject: [PATCH 06/13] Rename configNames to containerNames Co-authored-by: Mads Jon Nielsen --- main.go | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/main.go b/main.go index 18c7842..c39eacd 100644 --- a/main.go +++ b/main.go @@ -191,12 +191,12 @@ func NewManager(l *logrus.Logger) (*manager, error) { func (m *manager) run(config *Config) { // Create a list of container-manager containers - configNames := []string{} + containerNames := []string{} for _, c := range config.Containers { - configNames = append(configNames, c.Name) + containerNames = append(containerNames, c.Name) } - networkNames, err := m.getNetworkNames(configNames) + networkNames, err := m.getNetworkNames(containerNames) if err != nil { m.l.Error(err) return From b669d548e3a5fafdb1923b13d5292990e41635a1 Mon Sep 17 00:00:00 2001 From: Staal <48656753+staal0@users.noreply.github.com> Date: Tue, 19 Mar 2024 08:02:45 +0100 Subject: [PATCH 07/13] Rename configNames to containerNames Co-authored-by: Mads Jon Nielsen --- main.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/main.go b/main.go index c39eacd..247e6df 100644 --- a/main.go +++ b/main.go @@ -448,7 +448,7 @@ func (m *manager) stopContainers(config *Config) { } } -func (m *manager) getNetworkNames(configNames []string) ([]string, error) { +func (m *manager) getNetworkNames(containerNames []string) ([]string, error) { names := []string{} networks, err := m.cli.NetworkList(m.ctx, types.NetworkListOptions{}) From 23af9cf14bd03111fda856c21fbbf259967dec17 Mon Sep 17 00:00:00 2001 From: Staal <48656753+staal0@users.noreply.github.com> Date: Tue, 19 Mar 2024 08:03:05 +0100 Subject: [PATCH 08/13] Rename configNames to containerNames Co-authored-by: Mads Jon Nielsen --- main.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/main.go b/main.go index 247e6df..8034900 100644 --- a/main.go +++ b/main.go @@ -464,9 +464,9 @@ func (m *manager) getNetworkNames(containerNames []string) ([]string, error) { } for _, container := range attached.Containers { - if containsString(configNames, container.Name) && network.Name != "bridge" { + if containsString(containerNames, container.Name) && network.Name != "bridge" { // Detach from network if config containers is the only ones - if (len(attached.Containers) - len(configNames)) == 0 { + if (len(attached.Containers) - len(containerNames)) == 0 { m.detachNetwork(network.Name, container.Name) } } From d1bc6a740cabc64b703c1607bd198b36403ce107 Mon Sep 17 00:00:00 2001 From: Staal <48656753+staal0@users.noreply.github.com> Date: Tue, 19 Mar 2024 08:03:20 +0100 Subject: [PATCH 09/13] Rename configNames to containerNames Co-authored-by: Mads Jon Nielsen --- main.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/main.go b/main.go index 8034900..0637fd2 100644 --- a/main.go +++ b/main.go @@ -484,7 +484,7 @@ func (m *manager) getNetworkNames(containerNames []string) ([]string, error) { names = append(names, network.Name) // Attach to network if not already attached - for _, container := range configNames { + for _, container := range containerNames { if !containerInNetworks(container, attached) { m.attachNetwork(network.Name, container) } From b0110b93004a8f30169cdcd99aa6008d54e71977 Mon Sep 17 00:00:00 2001 From: Dennis Staal Date: Wed, 20 Mar 2024 13:04:24 +0100 Subject: [PATCH 10/13] Moved attach/detach to a new function Check if attachAllNetwork is set when adding containers to containerNames --- main.go | 48 +++++++++++++++++++++++++++++++++++++----------- 1 file changed, 37 insertions(+), 11 deletions(-) diff --git a/main.go b/main.go index 0637fd2..7724fef 100644 --- a/main.go +++ b/main.go @@ -193,10 +193,16 @@ func (m *manager) run(config *Config) { // Create a list of container-manager containers containerNames := []string{} for _, c := range config.Containers { - containerNames = append(containerNames, c.Name) + if c.AttachAllNetwork { + containerNames = append(containerNames, c.Name) + } } - networkNames, err := m.getNetworkNames(containerNames) + // Attach / Detach networks + m.ensureNetwork(containerNames) + + // Returns a list of networks with more than 0 containers + networkNames, err := m.getNetworkNames() if err != nil { m.l.Error(err) return @@ -448,7 +454,7 @@ func (m *manager) stopContainers(config *Config) { } } -func (m *manager) getNetworkNames(containerNames []string) ([]string, error) { +func (m *manager) getNetworkNames() ([]string, error) { names := []string{} networks, err := m.cli.NetworkList(m.ctx, types.NetworkListOptions{}) @@ -463,6 +469,32 @@ func (m *manager) getNetworkNames(containerNames []string) ([]string, error) { return nil, err } + // If more than 0 containers in a network excluding containers from config, then add containers in config to the network + if len(attached.Containers) > 0 { + if (network.Attachable || network.Scope == "local") && !containsString(ignoredNetworkNames, network.Name) { + names = append(names, network.Name) + } + } + } + + sort.Strings(names) + + return names, nil +} + +func (m *manager) ensureNetwork(containerNames []string) { + networks, err := m.cli.NetworkList(m.ctx, types.NetworkListOptions{}) + if err != nil { + m.l.Error(err) + } + + for _, network := range networks { + // Inspect each network to get attached containers + attached, err := m.cli.NetworkInspect(m.ctx, network.Name, types.NetworkInspectOptions{}) + if err != nil { + m.l.Error(err) + } + for _, container := range attached.Containers { if containsString(containerNames, container.Name) && network.Name != "bridge" { // Detach from network if config containers is the only ones @@ -472,17 +504,15 @@ func (m *manager) getNetworkNames(containerNames []string) ([]string, error) { } } - // Inspect once more to get updated attached containers + // Inspect once more to get an updated attached containers attached, err = m.cli.NetworkInspect(m.ctx, network.Name, types.NetworkInspectOptions{}) if err != nil { - return nil, err + m.l.Error(err) } // If more than 0 containers in a network excluding containers from config, then add containers in config to the network if len(attached.Containers) > 0 { if (network.Attachable || network.Scope == "local") && !containsString(ignoredNetworkNames, network.Name) { - names = append(names, network.Name) - // Attach to network if not already attached for _, container := range containerNames { if !containerInNetworks(container, attached) { @@ -492,10 +522,6 @@ func (m *manager) getNetworkNames(containerNames []string) ([]string, error) { } } } - - sort.Strings(names) - - return names, nil } func containerInNetworks(containerName string, attached types.NetworkResource) bool { From 648dacb16c26726d8a0db74c89759b7486963802 Mon Sep 17 00:00:00 2001 From: Dennis Staal Date: Thu, 21 Mar 2024 07:20:31 +0100 Subject: [PATCH 11/13] Renamed attach/detach function --- main.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/main.go b/main.go index 7724fef..edf46c0 100644 --- a/main.go +++ b/main.go @@ -199,7 +199,7 @@ func (m *manager) run(config *Config) { } // Attach / Detach networks - m.ensureNetwork(containerNames) + m.updateContainerNetworks(containerNames) // Returns a list of networks with more than 0 containers networkNames, err := m.getNetworkNames() @@ -482,7 +482,7 @@ func (m *manager) getNetworkNames() ([]string, error) { return names, nil } -func (m *manager) ensureNetwork(containerNames []string) { +func (m *manager) updateContainerNetworks(containerNames []string) { networks, err := m.cli.NetworkList(m.ctx, types.NetworkListOptions{}) if err != nil { m.l.Error(err) From e718ce595055560e806753bd39d26b3773a3b0a4 Mon Sep 17 00:00:00 2001 From: Dennis Staal Date: Wed, 27 Mar 2024 11:09:38 +0100 Subject: [PATCH 12/13] Updated attach/detach functionality --- main.go | 108 +++++++++++++++++++++++++++++--------------------------- 1 file changed, 56 insertions(+), 52 deletions(-) diff --git a/main.go b/main.go index edf46c0..617e80a 100644 --- a/main.go +++ b/main.go @@ -198,11 +198,8 @@ func (m *manager) run(config *Config) { } } - // Attach / Detach networks - m.updateContainerNetworks(containerNames) - - // Returns a list of networks with more than 0 containers - networkNames, err := m.getNetworkNames() + // Returns a list of networks with more than 0 containers attached + networkNames, err := m.getNetworkNames(containerNames) if err != nil { m.l.Error(err) return @@ -265,9 +262,31 @@ func (m *manager) ensureContainer(config Container, networks []string) error { m.l.WithField("name", config.Name).Debugf("Networks expected: %s", networks) m.l.WithField("name", config.Name).Debugf("Networks current: %s", networkNames) + if !reflect.DeepEqual(networks, networkNames) { - m.l.WithField("name", config.Name).Debugf("Network config differ, recreate %s", config.Name) - reCreate = true + m.l.WithField("name", config.Name).Debugf("Network config differ, attach/detach %s", config.Name) + + // New networks attach + for _, network := range networks { + // Inspect each network to get attached containers + attached, err := m.cli.NetworkInspect(m.ctx, network, types.NetworkInspectOptions{}) + if err != nil { + m.l.Error(err) + } + + // If container is not already attached to network + if !containerInNetworks(config.Name, attached) { + m.attachNetwork(network, config.Name) + } + } + + m.l.WithField("name", config.Name).Debugf("Network detach diff: %s\n", difference(networkNames, networks)) + + // Old networks detach + for _, network := range difference(networkNames, networks) { + // Detach from network diff + m.detachNetwork(network, config.Name) + } } volumesExpected := make([]string, len(config.Volumes)) @@ -454,7 +473,7 @@ func (m *manager) stopContainers(config *Config) { } } -func (m *manager) getNetworkNames() ([]string, error) { +func (m *manager) getNetworkNames(containerNames []string) ([]string, error) { names := []string{} networks, err := m.cli.NetworkList(m.ctx, types.NetworkListOptions{}) @@ -469,8 +488,17 @@ func (m *manager) getNetworkNames() ([]string, error) { return nil, err } - // If more than 0 containers in a network excluding containers from config, then add containers in config to the network - if len(attached.Containers) > 0 { + // Count currently attached containerNames + attachedContainerNames := 0 + + for _, container := range containerNames { + if containerInNetworks(container, attached) { + attachedContainerNames = attachedContainerNames + 1 + } + } + + // If more than 0 containers in a network (excluding containers from config) + if (len(attached.Containers) - attachedContainerNames) > 0 { if (network.Attachable || network.Scope == "local") && !containsString(ignoredNetworkNames, network.Name) { names = append(names, network.Name) } @@ -482,48 +510,7 @@ func (m *manager) getNetworkNames() ([]string, error) { return names, nil } -func (m *manager) updateContainerNetworks(containerNames []string) { - networks, err := m.cli.NetworkList(m.ctx, types.NetworkListOptions{}) - if err != nil { - m.l.Error(err) - } - - for _, network := range networks { - // Inspect each network to get attached containers - attached, err := m.cli.NetworkInspect(m.ctx, network.Name, types.NetworkInspectOptions{}) - if err != nil { - m.l.Error(err) - } - - for _, container := range attached.Containers { - if containsString(containerNames, container.Name) && network.Name != "bridge" { - // Detach from network if config containers is the only ones - if (len(attached.Containers) - len(containerNames)) == 0 { - m.detachNetwork(network.Name, container.Name) - } - } - } - - // Inspect once more to get an updated attached containers - attached, err = m.cli.NetworkInspect(m.ctx, network.Name, types.NetworkInspectOptions{}) - if err != nil { - m.l.Error(err) - } - - // If more than 0 containers in a network excluding containers from config, then add containers in config to the network - if len(attached.Containers) > 0 { - if (network.Attachable || network.Scope == "local") && !containsString(ignoredNetworkNames, network.Name) { - // Attach to network if not already attached - for _, container := range containerNames { - if !containerInNetworks(container, attached) { - m.attachNetwork(network.Name, container) - } - } - } - } - } -} - +// validate if a container is in a given network func containerInNetworks(containerName string, attached types.NetworkResource) bool { for _, c := range attached.Containers { if containerName == c.Name { @@ -533,6 +520,22 @@ func containerInNetworks(containerName string, attached types.NetworkResource) b return false } +// difference returns the elements in `a` that aren't in `b`. +func difference(a, b []string) []string { + mb := make(map[string]struct{}, len(b)) + for _, x := range b { + mb[x] = struct{}{} + } + var diff []string + for _, x := range a { + if _, found := mb[x]; !found { + diff = append(diff, x) + } + } + return diff +} + +// detach from network from container func (m *manager) detachNetwork(network string, container string) { err := m.cli.NetworkDisconnect(m.ctx, network, container, true) @@ -543,6 +546,7 @@ func (m *manager) detachNetwork(network string, container string) { } } +// attach from network from container func (m *manager) attachNetwork(network string, container string) { err := m.cli.NetworkConnect(m.ctx, network, container, nil) if err != nil { From 061dba9b49825f9a67acc5f0d86a11e580418565 Mon Sep 17 00:00:00 2001 From: Staal <48656753+staal0@users.noreply.github.com> Date: Tue, 2 Apr 2024 13:14:26 +0200 Subject: [PATCH 13/13] Simplify network list criteria Co-authored-by: Simon Bengtsson --- main.go | 18 +++++------------- 1 file changed, 5 insertions(+), 13 deletions(-) diff --git a/main.go b/main.go index 617e80a..1dd6484 100644 --- a/main.go +++ b/main.go @@ -487,20 +487,12 @@ func (m *manager) getNetworkNames(containerNames []string) ([]string, error) { if err != nil { return nil, err } - - // Count currently attached containerNames - attachedContainerNames := 0 - - for _, container := range containerNames { - if containerInNetworks(container, attached) { - attachedContainerNames = attachedContainerNames + 1 - } - } - - // If more than 0 containers in a network (excluding containers from config) - if (len(attached.Containers) - attachedContainerNames) > 0 { - if (network.Attachable || network.Scope == "local") && !containsString(ignoredNetworkNames, network.Name) { + for _, endpoint := range attached.Containers { + if !containsString(containerNames, endpoint.Name) && + (network.Attachable || network.Scope == "local") && + !containsString(ignoredNetworkNames, network.Name) { names = append(names, network.Name) + break } } }