Skip to content

Commit 7f32f02

Browse files
committed
fix: prevent network name ambiguity
`NetworkInspect` will match a network ID by prefix. While rare, it's possible that users might use a network name that is also a valid network ID prefix for a pre-existing Docker network. (In the reported case, the network was named `db`, for example.) Fixes docker#9496. Signed-off-by: Milas Bowman <[email protected]>
1 parent 335decc commit 7f32f02

File tree

1 file changed

+67
-60
lines changed

1 file changed

+67
-60
lines changed

pkg/compose/create.go

Lines changed: 67 additions & 60 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@ import (
3131
moby "github.com/docker/docker/api/types"
3232
"github.com/docker/docker/api/types/blkiodev"
3333
"github.com/docker/docker/api/types/container"
34+
"github.com/docker/docker/api/types/filters"
3435
"github.com/docker/docker/api/types/mount"
3536
"github.com/docker/docker/api/types/network"
3637
"github.com/docker/docker/api/types/strslice"
@@ -1001,75 +1002,81 @@ func getAliases(s types.ServiceConfig, c *types.ServiceNetworkConfig) []string {
10011002
}
10021003

10031004
func (s *composeService) ensureNetwork(ctx context.Context, n types.NetworkConfig) error {
1004-
_, err := s.apiClient().NetworkInspect(ctx, n.Name, moby.NetworkInspectOptions{})
1005+
// NetworkInspect will match on ID prefix, so NetworkList with a name
1006+
// filter is used to look for an exact match to prevent e.g. a network
1007+
// named `db` from getting erroneously matched to a network with an ID
1008+
// like `db9086999caf`
1009+
networks, err := s.apiClient().NetworkList(ctx, moby.NetworkListOptions{
1010+
Filters: filters.NewArgs(filters.Arg("name", n.Name)),
1011+
})
10051012
if err != nil {
1006-
if errdefs.IsNotFound(err) {
1007-
if n.External.External {
1008-
if n.Driver == "overlay" {
1009-
// Swarm nodes do not register overlay networks that were
1010-
// created on a different node unless they're in use.
1011-
// Here we assume `driver` is relevant for a network we don't manage
1012-
// which is a non-sense, but this is our legacy ¯\(ツ)/¯
1013-
// networkAttach will later fail anyway if network actually doesn't exists
1014-
return nil
1015-
}
1016-
return fmt.Errorf("network %s declared as external, but could not be found", n.Name)
1013+
return err
1014+
}
1015+
if len(networks) == 0 {
1016+
if n.External.External {
1017+
if n.Driver == "overlay" {
1018+
// Swarm nodes do not register overlay networks that were
1019+
// created on a different node unless they're in use.
1020+
// Here we assume `driver` is relevant for a network we don't manage
1021+
// which is a non-sense, but this is our legacy ¯\(ツ)/¯
1022+
// networkAttach will later fail anyway if network actually doesn't exists
1023+
return nil
10171024
}
1018-
var ipam *network.IPAM
1019-
if n.Ipam.Config != nil {
1020-
var config []network.IPAMConfig
1021-
for _, pool := range n.Ipam.Config {
1022-
config = append(config, network.IPAMConfig{
1023-
Subnet: pool.Subnet,
1024-
IPRange: pool.IPRange,
1025-
Gateway: pool.Gateway,
1026-
AuxAddress: pool.AuxiliaryAddresses,
1027-
})
1028-
}
1029-
ipam = &network.IPAM{
1030-
Driver: n.Ipam.Driver,
1031-
Config: config,
1032-
}
1025+
return fmt.Errorf("network %s declared as external, but could not be found", n.Name)
1026+
}
1027+
var ipam *network.IPAM
1028+
if n.Ipam.Config != nil {
1029+
var config []network.IPAMConfig
1030+
for _, pool := range n.Ipam.Config {
1031+
config = append(config, network.IPAMConfig{
1032+
Subnet: pool.Subnet,
1033+
IPRange: pool.IPRange,
1034+
Gateway: pool.Gateway,
1035+
AuxAddress: pool.AuxiliaryAddresses,
1036+
})
10331037
}
1034-
createOpts := moby.NetworkCreate{
1035-
// TODO NameSpace Labels
1036-
Labels: n.Labels,
1037-
Driver: n.Driver,
1038-
Options: n.DriverOpts,
1039-
Internal: n.Internal,
1040-
Attachable: n.Attachable,
1041-
IPAM: ipam,
1042-
EnableIPv6: n.EnableIPv6,
1038+
ipam = &network.IPAM{
1039+
Driver: n.Ipam.Driver,
1040+
Config: config,
10431041
}
1042+
}
1043+
createOpts := moby.NetworkCreate{
1044+
// TODO NameSpace Labels
1045+
Labels: n.Labels,
1046+
Driver: n.Driver,
1047+
Options: n.DriverOpts,
1048+
Internal: n.Internal,
1049+
Attachable: n.Attachable,
1050+
IPAM: ipam,
1051+
EnableIPv6: n.EnableIPv6,
1052+
}
10441053

1045-
if n.Ipam.Driver != "" || len(n.Ipam.Config) > 0 {
1046-
createOpts.IPAM = &network.IPAM{}
1047-
}
1054+
if n.Ipam.Driver != "" || len(n.Ipam.Config) > 0 {
1055+
createOpts.IPAM = &network.IPAM{}
1056+
}
10481057

1049-
if n.Ipam.Driver != "" {
1050-
createOpts.IPAM.Driver = n.Ipam.Driver
1051-
}
1058+
if n.Ipam.Driver != "" {
1059+
createOpts.IPAM.Driver = n.Ipam.Driver
1060+
}
10521061

1053-
for _, ipamConfig := range n.Ipam.Config {
1054-
config := network.IPAMConfig{
1055-
Subnet: ipamConfig.Subnet,
1056-
IPRange: ipamConfig.IPRange,
1057-
Gateway: ipamConfig.Gateway,
1058-
AuxAddress: ipamConfig.AuxiliaryAddresses,
1059-
}
1060-
createOpts.IPAM.Config = append(createOpts.IPAM.Config, config)
1062+
for _, ipamConfig := range n.Ipam.Config {
1063+
config := network.IPAMConfig{
1064+
Subnet: ipamConfig.Subnet,
1065+
IPRange: ipamConfig.IPRange,
1066+
Gateway: ipamConfig.Gateway,
1067+
AuxAddress: ipamConfig.AuxiliaryAddresses,
10611068
}
1062-
networkEventName := fmt.Sprintf("Network %s", n.Name)
1063-
w := progress.ContextWriter(ctx)
1064-
w.Event(progress.CreatingEvent(networkEventName))
1065-
if _, err := s.apiClient().NetworkCreate(ctx, n.Name, createOpts); err != nil {
1066-
w.Event(progress.ErrorEvent(networkEventName))
1067-
return errors.Wrapf(err, "failed to create network %s", n.Name)
1068-
}
1069-
w.Event(progress.CreatedEvent(networkEventName))
1070-
return nil
1069+
createOpts.IPAM.Config = append(createOpts.IPAM.Config, config)
10711070
}
1072-
return err
1071+
networkEventName := fmt.Sprintf("Network %s", n.Name)
1072+
w := progress.ContextWriter(ctx)
1073+
w.Event(progress.CreatingEvent(networkEventName))
1074+
if _, err := s.apiClient().NetworkCreate(ctx, n.Name, createOpts); err != nil {
1075+
w.Event(progress.ErrorEvent(networkEventName))
1076+
return errors.Wrapf(err, "failed to create network %s", n.Name)
1077+
}
1078+
w.Event(progress.CreatedEvent(networkEventName))
1079+
return nil
10731080
}
10741081
return nil
10751082
}

0 commit comments

Comments
 (0)