diff options
Diffstat (limited to 'libpod/in_memory_state.go')
-rw-r--r-- | libpod/in_memory_state.go | 262 |
1 files changed, 262 insertions, 0 deletions
diff --git a/libpod/in_memory_state.go b/libpod/in_memory_state.go index 0de25a6ef..6c0cde531 100644 --- a/libpod/in_memory_state.go +++ b/libpod/in_memory_state.go @@ -31,6 +31,9 @@ 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 + 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. nameIndex *registrar.Registrar // Global ID registry - ensures ID uniqueness and performs lookups. @@ -65,6 +68,9 @@ func NewInMemoryState() (State, error) { state.podContainers = make(map[string]map[string]*Container) + state.ctrNetworks = make(map[string][]string) + state.ctrNetworkAliases = make(map[string]map[string][]string) + state.nameIndex = registrar.NewRegistrar() state.idIndex = truncindex.NewTruncIndex([]string{}) @@ -278,6 +284,27 @@ 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 := 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) + } + } + // 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 +361,19 @@ func (s *InMemoryState) AddContainer(ctr *Container) error { s.addCtrToVolDependsMap(ctr.ID(), vol.Name) } + // Add networks + newNets := make([]string, 0, len(ctr.config.Networks)) + for _, net := range ctr.config.Networks { + if net == "" { + return define.ErrInvalidArg + } + newNets = append(newNets, net) + } + s.ctrNetworks[ctr.ID()] = newNets + + // Add network aliases + s.ctrNetworkAliases[ctr.ID()] = ctr.config.NetworkAliases + return nil } @@ -396,6 +436,14 @@ func (s *InMemoryState) RemoveContainer(ctr *Container) error { s.removeCtrFromVolDependsMap(ctr.ID(), vol.Name) } + // Remove our network aliases + 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 } @@ -472,6 +520,173 @@ 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) { + 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 { + ctr.valid = false + 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 { + ctr.valid = false + return nil, define.ErrNoSuchCtr + } + + ctrAliases, ok := s.ctrNetworkAliases[ctr.ID()] + if !ok { + return map[string][]string{}, nil + } + + return ctrAliases, nil +} + +// NetworkConnect connects to the given network +func (s *InMemoryState) NetworkConnect(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 { + ctr.valid = false + return define.ErrNoSuchCtr + } + + inNet := false + ctrNetworks, ok := s.ctrNetworks[ctr.ID()] + if !ok { + return define.ErrNoSuchNetwork + } + for _, net := range ctrNetworks { + if net == network { + inNet = true + } + } + 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 + } + ctrAliases[network] = aliases + + return nil +} + +// 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 + } + + if network == "" { + return errors.Wrapf(define.ErrInvalidArg, "network names must not be empty") + } + + 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 + 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.ErrNoSuchNetwork + } + s.ctrNetworks[ctr.ID()] = remainingNets + + ctrAliases, ok := s.ctrNetworkAliases[ctr.ID()] + if !ok { + ctrAliases = make(map[string][]string) + s.ctrNetworkAliases[ctr.ID()] = ctrAliases + } + 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 +1331,27 @@ 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 := 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) + } + } + // Retrieve pod containers list podCtrs, ok := s.podContainers[pod.ID()] if !ok { @@ -1188,6 +1424,24 @@ 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 networks + newNets := make([]string, 0, len(ctr.config.Networks)) + for _, net := range ctr.config.Networks { + if net == "" { + return define.ErrInvalidArg + } + newNets = append(newNets, net) + } + s.ctrNetworks[ctr.ID()] = newNets + + // Add network aliases + s.ctrNetworkAliases[ctr.ID()] = ctr.config.NetworkAliases + return nil } @@ -1268,6 +1522,14 @@ func (s *InMemoryState) RemoveContainerFromPod(pod *Pod, ctr *Container) error { s.removeCtrFromDependsMap(ctr.ID(), depCtr) } + // Remove our network aliases + 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 } |