diff options
author | Matthew Heon <matthew.heon@pm.me> | 2020-11-10 14:54:09 -0500 |
---|---|---|
committer | Matthew Heon <matthew.heon@pm.me> | 2020-11-11 16:37:54 -0500 |
commit | 8d56eb5342ad8afa35750f7f14791c44e37a8c30 (patch) | |
tree | 6ecf970bc4bf409ce76013d91db2a1520dbf06eb /libpod/in_memory_state.go | |
parent | ea753128952e1a6d4b56cc80d232f6dbfb420ba5 (diff) | |
download | podman-8d56eb5342ad8afa35750f7f14791c44e37a8c30.tar.gz podman-8d56eb5342ad8afa35750f7f14791c44e37a8c30.tar.bz2 podman-8d56eb5342ad8afa35750f7f14791c44e37a8c30.zip |
Add support for network connect / disconnect to DB
Convert the existing network aliases set/remove code to network
connect and disconnect. We can no longer modify aliases for an
existing network, but we can add and remove entire networks. As
part of this, we need to add a new function to retrieve current
aliases the container is connected to (we had a table for this
as of the first aliases PR, but it was not externally exposed).
At the same time, remove all deconflicting logic for aliases.
Docker does absolutely no checks of this nature, and allows two
containers to have the same aliases, aliases that conflict with
container names, etc - it's just left to DNS to return all the
IP addresses, and presumably we round-robin from there? Most
tests for the existing code had to be removed because of this.
Convert all uses of the old container config.Networks field,
which previously included all networks in the container, to use
the new DB table. This ensures we actually get an up-to-date list
of in-use networks. Also, add network aliases to the output of
`podman inspect`.
Signed-off-by: Matthew Heon <matthew.heon@pm.me>
Diffstat (limited to 'libpod/in_memory_state.go')
-rw-r--r-- | libpod/in_memory_state.go | 281 |
1 files changed, 75 insertions, 206 deletions
diff --git a/libpod/in_memory_state.go b/libpod/in_memory_state.go index ba4c70c6b..6c0cde531 100644 --- a/libpod/in_memory_state.go +++ b/libpod/in_memory_state.go @@ -31,8 +31,7 @@ type InMemoryState struct { ctrExecSessions map[string][]string // Maps pod ID to a map of container ID to container struct. podContainers map[string]map[string]*Container - // Maps network name to alias to container ID - networkAliases map[string]map[string]string + ctrNetworks map[string][]string // Maps container ID to network name to list of aliases. ctrNetworkAliases map[string]map[string][]string // Global name registry - ensures name uniqueness and performs lookups. @@ -69,7 +68,7 @@ func NewInMemoryState() (State, error) { state.podContainers = make(map[string]map[string]*Container) - state.networkAliases = make(map[string]map[string]string) + state.ctrNetworks = make(map[string][]string) state.ctrNetworkAliases = make(map[string]map[string][]string) state.nameIndex = registrar.NewRegistrar() @@ -293,7 +292,7 @@ func (s *InMemoryState) AddContainer(ctr *Container) error { } // Check network aliases - for network, aliases := range ctr.config.NetworkAliases { + for network := range ctr.config.NetworkAliases { inNet := false for _, net := range ctr.config.Networks { if net == network { @@ -304,19 +303,6 @@ func (s *InMemoryState) AddContainer(ctr *Container) error { if !inNet { return errors.Wrapf(define.ErrInvalidArg, "container %s has network aliases for network %q but is not joined to network", ctr.ID(), network) } - - allNetAliases, ok := s.networkAliases[network] - if ok { - for _, alias := range aliases { - // Check if alias is a name - if _, err := s.nameIndex.Get(alias); err == nil { - return define.ErrInvalidArg - } - if _, ok := allNetAliases[alias]; ok { - return define.ErrAliasExists - } - } - } } // There are potential race conditions with this @@ -375,46 +361,17 @@ func (s *InMemoryState) AddContainer(ctr *Container) error { s.addCtrToVolDependsMap(ctr.ID(), vol.Name) } - for _, network := range ctr.config.Networks { - allNetAliases, ok := s.networkAliases[network] - if !ok { - continue - } - otherCtrID, ok := allNetAliases[ctr.Name()] - if !ok { - continue - } - delete(allNetAliases, ctr.Name()) - - otherCtrAliases, ok := s.ctrNetworkAliases[otherCtrID] - if !ok { - continue - } - otherCtrNetAliases, ok := otherCtrAliases[network] - if !ok { - continue - } - newAliases := []string{} - for _, alias := range otherCtrNetAliases { - if alias != ctr.Name() { - newAliases = append(newAliases, alias) - } + // Add networks + newNets := make([]string, 0, len(ctr.config.Networks)) + for _, net := range ctr.config.Networks { + if net == "" { + return define.ErrInvalidArg } - otherCtrAliases[network] = newAliases + newNets = append(newNets, net) } + s.ctrNetworks[ctr.ID()] = newNets // Add network aliases - for network, aliases := range ctr.config.NetworkAliases { - allNetAliases, ok := s.networkAliases[network] - if !ok { - allNetAliases = make(map[string]string) - s.networkAliases[network] = allNetAliases - } - - for _, alias := range aliases { - allNetAliases[alias] = ctr.ID() - } - } s.ctrNetworkAliases[ctr.ID()] = ctr.config.NetworkAliases return nil @@ -480,18 +437,12 @@ func (s *InMemoryState) RemoveContainer(ctr *Container) error { } // Remove our network aliases - ctrAliases, ok := s.ctrNetworkAliases[ctr.ID()] - if ok { - for network, aliases := range ctrAliases { - netAliases, ok := s.networkAliases[network] - if ok { - for _, alias := range aliases { - delete(netAliases, alias) - } - } - } + if _, ok := s.ctrNetworkAliases[ctr.ID()]; ok { delete(s.ctrNetworkAliases, ctr.ID()) } + if _, ok := s.ctrNetworks[ctr.ID()]; ok { + delete(s.ctrNetworks, ctr.ID()) + } return nil } @@ -569,6 +520,26 @@ func (s *InMemoryState) AllContainers() ([]*Container, error) { return ctrs, nil } +// Get all networks this container is present in. +func (s *InMemoryState) GetNetworks(ctr *Container) ([]string, error) { + if !ctr.valid { + return nil, define.ErrCtrRemoved + } + + ctr, ok := s.containers[ctr.ID()] + if !ok { + ctr.valid = false + return nil, define.ErrNoSuchCtr + } + + ctrNetworks, ok := s.ctrNetworks[ctr.ID()] + if !ok { + return nil, define.ErrNoSuchNetwork + } + + return ctrNetworks, nil +} + // GetNetworkAliases returns network aliases for the given container in the // given network. func (s *InMemoryState) GetNetworkAliases(ctr *Container, network string) ([]string, error) { @@ -582,6 +553,7 @@ func (s *InMemoryState) GetNetworkAliases(ctr *Container, network string) ([]str ctr, ok := s.containers[ctr.ID()] if !ok { + ctr.valid = false return nil, define.ErrNoSuchCtr } @@ -615,6 +587,7 @@ func (s *InMemoryState) GetAllNetworkAliases(ctr *Container) (map[string][]strin ctr, ok := s.containers[ctr.ID()] if !ok { + ctr.valid = false return nil, define.ErrNoSuchCtr } @@ -626,9 +599,8 @@ func (s *InMemoryState) GetAllNetworkAliases(ctr *Container) (map[string][]strin return ctrAliases, nil } -// SetNetworkAliases sets network aliases for the given container in the given -// network. -func (s *InMemoryState) SetNetworkAliases(ctr *Container, network string, aliases []string) error { +// NetworkConnect connects to the given network +func (s *InMemoryState) NetworkConnect(ctr *Container, network string, aliases []string) error { if !ctr.valid { return define.ErrCtrRemoved } @@ -639,55 +611,37 @@ func (s *InMemoryState) SetNetworkAliases(ctr *Container, network string, aliase ctr, ok := s.containers[ctr.ID()] if !ok { + ctr.valid = false return define.ErrNoSuchCtr } inNet := false - for _, net := range ctr.config.Networks { + ctrNetworks, ok := s.ctrNetworks[ctr.ID()] + if !ok { + return define.ErrNoSuchNetwork + } + for _, net := range ctrNetworks { if net == network { inNet = true } } - if !inNet { - return define.ErrInvalidArg + if inNet { + return define.ErrNoSuchNetwork } + s.ctrNetworks[ctr.ID()] = append(ctrNetworks, network) ctrAliases, ok := s.ctrNetworkAliases[ctr.ID()] if !ok { ctrAliases = make(map[string][]string) s.ctrNetworkAliases[ctr.ID()] = ctrAliases } - netAliases, ok := ctrAliases[network] - if !ok { - netAliases = []string{} - ctrAliases[network] = netAliases - } - - allAliases, ok := s.networkAliases[network] - if !ok { - allAliases = make(map[string]string) - s.networkAliases[network] = allAliases - } - - for _, alias := range netAliases { - delete(allAliases, alias) - } - - for _, newAlias := range aliases { - if _, ok := allAliases[newAlias]; ok { - return define.ErrAliasExists - } - allAliases[newAlias] = ctr.ID() - } - ctrAliases[network] = aliases return nil } -// RemoveNetworkAliases removes network aliases from the given container in the -// given network. -func (s *InMemoryState) RemoveNetworkAliases(ctr *Container, network string) error { +// Disconnect from the given network and remove all aliases in it. +func (s *InMemoryState) NetworkDisconnect(ctr *Container, network string) error { if !ctr.valid { return define.ErrCtrRemoved } @@ -698,73 +652,36 @@ func (s *InMemoryState) RemoveNetworkAliases(ctr *Container, network string) err ctr, ok := s.containers[ctr.ID()] if !ok { + ctr.valid = false return define.ErrNoSuchCtr } + ctrNetworks, ok := s.ctrNetworks[ctr.ID()] + if !ok { + return define.ErrNoSuchNetwork + } inNet := false - for _, net := range ctr.config.Networks { + remainingNets := make([]string, 0, len(ctrNetworks)) + for _, net := range ctrNetworks { if net == network { inNet = true + break + } else { + remainingNets = append(remainingNets, net) } } if !inNet { - return define.ErrInvalidArg + return define.ErrNoSuchNetwork } + s.ctrNetworks[ctr.ID()] = remainingNets ctrAliases, ok := s.ctrNetworkAliases[ctr.ID()] if !ok { ctrAliases = make(map[string][]string) s.ctrNetworkAliases[ctr.ID()] = ctrAliases } - netAliases, ok := ctrAliases[network] - if !ok { - netAliases = []string{} - ctrAliases[network] = netAliases - } - - allAliases, ok := s.networkAliases[network] - if !ok { - allAliases = make(map[string]string) - s.networkAliases[network] = allAliases - } - - for _, alias := range netAliases { - delete(allAliases, alias) - } - - return nil -} - -// GetAllAliasesForNetwork gets all the aliases for a single network. -func (s *InMemoryState) GetAllAliasesForNetwork(network string) (map[string]string, error) { - if network == "" { - return nil, errors.Wrapf(define.ErrInvalidArg, "network names must not be empty") - } - - allAliases, ok := s.networkAliases[network] - if !ok { - // Can't tell if the network exists. - // Assume it does. - return map[string]string{}, nil - } - - return allAliases, nil -} - -// RemoveAllAliasesForNetwork removes all the aliases for a given network. -func (s *InMemoryState) RemoveAllAliasesForNetwork(network string) error { - if network == "" { - return errors.Wrapf(define.ErrInvalidArg, "network names must not be empty") - } - - if _, ok := s.networkAliases[network]; ok { - delete(s.networkAliases, network) - } - - for _, ctrAliases := range s.ctrNetworkAliases { - if _, ok := ctrAliases[network]; ok { - delete(ctrAliases, network) - } + if _, ok := ctrAliases[network]; ok { + delete(ctrAliases, network) } return nil @@ -1422,7 +1339,7 @@ func (s *InMemoryState) AddContainerToPod(pod *Pod, ctr *Container) error { } // Check network aliases - for network, aliases := range ctr.config.NetworkAliases { + for network := range ctr.config.NetworkAliases { inNet := false for _, net := range ctr.config.Networks { if net == network { @@ -1433,19 +1350,6 @@ func (s *InMemoryState) AddContainerToPod(pod *Pod, ctr *Container) error { if !inNet { return errors.Wrapf(define.ErrInvalidArg, "container %s has network aliases for network %q but is not joined to network", ctr.ID(), network) } - - allNetAliases, ok := s.networkAliases[network] - if ok { - for _, alias := range aliases { - // Check if alias is a name - if _, err := s.nameIndex.Get(alias); err == nil { - return define.ErrInvalidArg - } - if _, ok := allNetAliases[alias]; ok { - return define.ErrAliasExists - } - } - } } // Retrieve pod containers list @@ -1525,46 +1429,17 @@ func (s *InMemoryState) AddContainerToPod(pod *Pod, ctr *Container) error { s.addCtrToVolDependsMap(ctr.ID(), vol.Name) } - for _, network := range ctr.config.Networks { - allNetAliases, ok := s.networkAliases[network] - if !ok { - continue - } - otherCtrID, ok := allNetAliases[ctr.Name()] - if !ok { - continue - } - delete(allNetAliases, ctr.Name()) - - otherCtrAliases, ok := s.ctrNetworkAliases[otherCtrID] - if !ok { - continue - } - otherCtrNetAliases, ok := otherCtrAliases[network] - if !ok { - continue - } - newAliases := []string{} - for _, alias := range otherCtrNetAliases { - if alias != ctr.Name() { - newAliases = append(newAliases, alias) - } + // Add networks + newNets := make([]string, 0, len(ctr.config.Networks)) + for _, net := range ctr.config.Networks { + if net == "" { + return define.ErrInvalidArg } - otherCtrAliases[network] = newAliases + newNets = append(newNets, net) } + s.ctrNetworks[ctr.ID()] = newNets // Add network aliases - for network, aliases := range ctr.config.NetworkAliases { - allNetAliases, ok := s.networkAliases[network] - if !ok { - allNetAliases = make(map[string]string) - s.networkAliases[network] = allNetAliases - } - - for _, alias := range aliases { - allNetAliases[alias] = ctr.ID() - } - } s.ctrNetworkAliases[ctr.ID()] = ctr.config.NetworkAliases return nil @@ -1648,18 +1523,12 @@ func (s *InMemoryState) RemoveContainerFromPod(pod *Pod, ctr *Container) error { } // Remove our network aliases - ctrAliases, ok := s.ctrNetworkAliases[ctr.ID()] - if ok { - for network, aliases := range ctrAliases { - netAliases, ok := s.networkAliases[network] - if ok { - for _, alias := range aliases { - delete(netAliases, alias) - } - } - } + if _, ok := s.ctrNetworkAliases[ctr.ID()]; ok { delete(s.ctrNetworkAliases, ctr.ID()) } + if _, ok := s.ctrNetworks[ctr.ID()]; ok { + delete(s.ctrNetworks, ctr.ID()) + } return nil } |