diff options
author | Matthew Heon <matthew.heon@pm.me> | 2020-10-26 17:17:45 -0400 |
---|---|---|
committer | Matthew Heon <matthew.heon@pm.me> | 2020-10-27 14:17:41 -0400 |
commit | 6af7e544636ae66ce237489ce6948123e1b3249d (patch) | |
tree | b95ead53ec2419d750c56ca008ed0965457d6d10 /libpod/in_memory_state.go | |
parent | 51fa8ded9ffb7924288a2728ce92af7f6cc66d34 (diff) | |
download | podman-6af7e544636ae66ce237489ce6948123e1b3249d.tar.gz podman-6af7e544636ae66ce237489ce6948123e1b3249d.tar.bz2 podman-6af7e544636ae66ce237489ce6948123e1b3249d.zip |
Add network aliases for containers to DB
This adds the database backend for network aliases. Aliases are
additional names for a container that are used with the CNI
dnsname plugin - the container will be accessible by these names
in addition to its name. Aliases are allowed to change over time
as the container connects to and disconnects from networks.
Aliases are implemented as another bucket in the database to
register all aliases, plus two buckets for each container (one to
hold connected CNI networks, a second to hold its aliases). The
aliases are only unique per-network, to the global and
per-container aliases buckets have a sub-bucket for each CNI
network that has aliases, and the aliases are stored within that
sub-bucket. Aliases are formatted as alias (key) to container ID
(value) in both cases.
Three DB functions are defined for aliases: retrieving current
aliases for a given network, setting aliases for a given network,
and removing all aliases for a given network.
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 | 261 |
1 files changed, 261 insertions, 0 deletions
diff --git a/libpod/in_memory_state.go b/libpod/in_memory_state.go index 0de25a6ef..66c2a5cbd 100644 --- a/libpod/in_memory_state.go +++ b/libpod/in_memory_state.go @@ -31,6 +31,10 @@ 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 + // 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. nameIndex *registrar.Registrar // Global ID registry - ensures ID uniqueness and performs lookups. @@ -65,6 +69,9 @@ func NewInMemoryState() (State, error) { state.podContainers = make(map[string]map[string]*Container) + state.networkAliases = make(map[string]map[string]string) + state.ctrNetworkAliases = make(map[string]map[string][]string) + state.nameIndex = registrar.NewRegistrar() state.idIndex = truncindex.NewTruncIndex([]string{}) @@ -278,6 +285,29 @@ func (s *InMemoryState) AddContainer(ctr *Container) error { return err } + // Check network aliases + for network, aliases := range ctr.config.NetworkAliases { + inNet := false + for _, net := range ctr.config.Networks { + if net == network { + inNet = true + break + } + } + 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 { + if _, ok := allNetAliases[alias]; ok { + return define.ErrAliasExists + } + } + } + } + // There are potential race conditions with this // But in-memory state is intended purely for testing and not production // use, so this should be fine. @@ -334,6 +364,20 @@ func (s *InMemoryState) AddContainer(ctr *Container) error { s.addCtrToVolDependsMap(ctr.ID(), vol.Name) } + // 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 } @@ -396,6 +440,20 @@ func (s *InMemoryState) RemoveContainer(ctr *Container) error { s.removeCtrFromVolDependsMap(ctr.ID(), vol.Name) } + // 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) + } + } + } + delete(s.ctrNetworkAliases, ctr.ID()) + } + return nil } @@ -472,6 +530,153 @@ func (s *InMemoryState) AllContainers() ([]*Container, error) { return ctrs, nil } +// GetNetworkAliases returns network aliases for the given container in the +// given network. +func (s *InMemoryState) GetNetworkAliases(ctr *Container, network string) ([]string, error) { + if !ctr.valid { + return nil, define.ErrCtrRemoved + } + + if network == "" { + return nil, errors.Wrapf(define.ErrInvalidArg, "network names must not be empty") + } + + ctr, ok := s.containers[ctr.ID()] + if !ok { + return nil, define.ErrNoSuchCtr + } + + inNet := false + for _, net := range ctr.config.Networks { + if net == network { + inNet = true + } + } + if !inNet { + return nil, define.ErrInvalidArg + } + + ctrAliases, ok := s.ctrNetworkAliases[ctr.ID()] + if !ok { + return []string{}, nil + } + netAliases, ok := ctrAliases[network] + if !ok { + return []string{}, nil + } + + return netAliases, nil +} + +// SetNetworkAliases sets network aliases for the given container in the given +// network. +func (s *InMemoryState) SetNetworkAliases(ctr *Container, network string, aliases []string) error { + if !ctr.valid { + return define.ErrCtrRemoved + } + + if network == "" { + return errors.Wrapf(define.ErrInvalidArg, "network names must not be empty") + } + + ctr, ok := s.containers[ctr.ID()] + if !ok { + return define.ErrNoSuchCtr + } + + inNet := false + for _, net := range ctr.config.Networks { + if net == network { + inNet = true + } + } + if !inNet { + return define.ErrInvalidArg + } + + 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 { + if !ctr.valid { + return define.ErrCtrRemoved + } + + if network == "" { + return errors.Wrapf(define.ErrInvalidArg, "network names must not be empty") + } + + ctr, ok := s.containers[ctr.ID()] + if !ok { + return define.ErrNoSuchCtr + } + + inNet := false + for _, net := range ctr.config.Networks { + if net == network { + inNet = true + } + } + if !inNet { + return define.ErrInvalidArg + } + + 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 +} + // GetContainerConfig returns a container config from the database by full ID func (s *InMemoryState) GetContainerConfig(id string) (*ContainerConfig, error) { ctr, err := s.LookupContainer(id) @@ -1116,6 +1321,29 @@ func (s *InMemoryState) AddContainerToPod(pod *Pod, ctr *Container) error { return err } + // Check network aliases + for network, aliases := range ctr.config.NetworkAliases { + inNet := false + for _, net := range ctr.config.Networks { + if net == network { + inNet = true + break + } + } + 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 { + if _, ok := allNetAliases[alias]; ok { + return define.ErrAliasExists + } + } + } + } + // Retrieve pod containers list podCtrs, ok := s.podContainers[pod.ID()] if !ok { @@ -1188,6 +1416,25 @@ func (s *InMemoryState) AddContainerToPod(pod *Pod, ctr *Container) error { s.addCtrToDependsMap(ctr.ID(), depCtr) } + // Add container to volume dependencies + for _, vol := range ctr.config.NamedVolumes { + s.addCtrToVolDependsMap(ctr.ID(), vol.Name) + } + + // 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 } @@ -1268,6 +1515,20 @@ func (s *InMemoryState) RemoveContainerFromPod(pod *Pod, ctr *Container) error { s.removeCtrFromDependsMap(ctr.ID(), depCtr) } + // 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) + } + } + } + delete(s.ctrNetworkAliases, ctr.ID()) + } + return nil } |