summaryrefslogtreecommitdiff
path: root/libpod/in_memory_state.go
diff options
context:
space:
mode:
Diffstat (limited to 'libpod/in_memory_state.go')
-rw-r--r--libpod/in_memory_state.go393
1 files changed, 393 insertions, 0 deletions
diff --git a/libpod/in_memory_state.go b/libpod/in_memory_state.go
index 0de25a6ef..ba4c70c6b 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,40 @@ func (s *InMemoryState) AddContainer(ctr *Container) error {
return err
}
+ // Check networks
+ for _, net := range ctr.config.Networks {
+ if net == "" {
+ return errors.Wrapf(define.ErrInvalidArg, "network names cannot be empty")
+ }
+ }
+
+ // 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 {
+ // 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
// But in-memory state is intended purely for testing and not production
// use, so this should be fine.
@@ -334,6 +375,48 @@ 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)
+ }
+ }
+ otherCtrAliases[network] = newAliases
+ }
+
+ // 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 +479,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 +569,207 @@ 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
+}
+
+// GetAllNetworkAliases gets all network aliases for the given container.
+func (s *InMemoryState) GetAllNetworkAliases(ctr *Container) (map[string][]string, error) {
+ if !ctr.valid {
+ return nil, define.ErrCtrRemoved
+ }
+
+ ctr, ok := s.containers[ctr.ID()]
+ if !ok {
+ return nil, define.ErrNoSuchCtr
+ }
+
+ ctrAliases, ok := s.ctrNetworkAliases[ctr.ID()]
+ if !ok {
+ return map[string][]string{}, nil
+ }
+
+ 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 {
+ 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
+}
+
+// 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)
+ }
+ }
+
+ 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 +1414,40 @@ func (s *InMemoryState) AddContainerToPod(pod *Pod, ctr *Container) error {
return err
}
+ // Check networks
+ for _, net := range ctr.config.Networks {
+ if net == "" {
+ return errors.Wrapf(define.ErrInvalidArg, "network names cannot be empty")
+ }
+ }
+
+ // 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 {
+ // 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
podCtrs, ok := s.podContainers[pod.ID()]
if !ok {
@@ -1188,6 +1520,53 @@ 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)
+ }
+
+ 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)
+ }
+ }
+ otherCtrAliases[network] = newAliases
+ }
+
+ // 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 +1647,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
}