diff options
author | Matthew Heon <matthew.heon@gmail.com> | 2018-01-12 12:41:10 -0500 |
---|---|---|
committer | Atomic Bot <atomic-devel@projectatomic.io> | 2018-01-16 14:58:06 +0000 |
commit | 20df2196f2158d8656d1b38580d816567843a5e0 (patch) | |
tree | deaf0b58a6e8753893ed99029a71b21433b0fa25 /libpod/in_memory_state.go | |
parent | d2ec1f76287a55d05ef1378fa31d5474c2bcc0bf (diff) | |
download | podman-20df2196f2158d8656d1b38580d816567843a5e0.tar.gz podman-20df2196f2158d8656d1b38580d816567843a5e0.tar.bz2 podman-20df2196f2158d8656d1b38580d816567843a5e0.zip |
Add ability for states to track container dependencies
Also prevent containers with dependencies from being removed from
in memory states. SQLite already enforced this via FOREIGN KEY
constraints.
Signed-off-by: Matthew Heon <matthew.heon@gmail.com>
Closes: #220
Approved by: rhatdan
Diffstat (limited to 'libpod/in_memory_state.go')
-rw-r--r-- | libpod/in_memory_state.go | 83 |
1 files changed, 83 insertions, 0 deletions
diff --git a/libpod/in_memory_state.go b/libpod/in_memory_state.go index 4e4cbb664..b4e224d77 100644 --- a/libpod/in_memory_state.go +++ b/libpod/in_memory_state.go @@ -1,6 +1,8 @@ package libpod import ( + "strings" + "github.com/docker/docker/pkg/truncindex" "github.com/pkg/errors" "github.com/projectatomic/libpod/pkg/registrar" @@ -10,6 +12,7 @@ import ( type InMemoryState struct { pods map[string]*Pod containers map[string]*Container + ctrDepends map[string][]string podNameIndex *registrar.Registrar podIDIndex *truncindex.TruncIndex ctrNameIndex *registrar.Registrar @@ -137,6 +140,15 @@ func (s *InMemoryState) AddContainer(ctr *Container) error { s.containers[ctr.ID()] = ctr + // Add containers this container depends on + s.addCtrToDependsMap(ctr.ID(), ctr.config.IPCNsCtr) + s.addCtrToDependsMap(ctr.ID(), ctr.config.MountNsCtr) + s.addCtrToDependsMap(ctr.ID(), ctr.config.NetNsCtr) + s.addCtrToDependsMap(ctr.ID(), ctr.config.PIDNsCtr) + s.addCtrToDependsMap(ctr.ID(), ctr.config.UserNsCtr) + s.addCtrToDependsMap(ctr.ID(), ctr.config.UTSNsCtr) + s.addCtrToDependsMap(ctr.ID(), ctr.config.CgroupNsCtr) + return nil } @@ -146,6 +158,13 @@ func (s *InMemoryState) RemoveContainer(ctr *Container) error { // Almost no validity checks are performed, to ensure we can kick // misbehaving containers out of the state + // Ensure we don't remove a container which other containers depend on + deps, ok := s.ctrDepends[ctr.ID()] + if ok && len(deps) != 0 { + depsStr := strings.Join(deps, ", ") + return errors.Wrapf(ErrCtrExists, "the following containers depend on container %s: %s", ctr.ID(), depsStr) + } + if _, ok := s.containers[ctr.ID()]; !ok { return errors.Wrapf(ErrNoSuchCtr, "no container exists in state with ID %s", ctr.ID()) } @@ -156,6 +175,16 @@ func (s *InMemoryState) RemoveContainer(ctr *Container) error { delete(s.containers, ctr.ID()) s.ctrNameIndex.Release(ctr.Name()) + delete(s.ctrDepends, ctr.ID()) + + s.removeCtrFromDependsMap(ctr.ID(), ctr.config.IPCNsCtr) + s.removeCtrFromDependsMap(ctr.ID(), ctr.config.MountNsCtr) + s.removeCtrFromDependsMap(ctr.ID(), ctr.config.NetNsCtr) + s.removeCtrFromDependsMap(ctr.ID(), ctr.config.PIDNsCtr) + s.removeCtrFromDependsMap(ctr.ID(), ctr.config.UserNsCtr) + s.removeCtrFromDependsMap(ctr.ID(), ctr.config.UTSNsCtr) + s.removeCtrFromDependsMap(ctr.ID(), ctr.config.CgroupNsCtr) + return nil } @@ -174,6 +203,20 @@ func (s *InMemoryState) SaveContainer(ctr *Container) error { return nil } +// ContainerInUse checks if the given container is being used by other containers +func (s *InMemoryState) ContainerInUse(ctr *Container) ([]string, error) { + if !ctr.valid { + return nil, ErrCtrRemoved + } + + arr, ok := s.ctrDepends[ctr.ID()] + if !ok { + return []string{}, nil + } + + return arr, nil +} + // AllContainers retrieves all containers from the state func (s *InMemoryState) AllContainers() ([]*Container, error) { ctrs := make([]*Container, 0, len(s.containers)) @@ -298,3 +341,43 @@ func (s *InMemoryState) AllPods() ([]*Pod, error) { return pods, nil } + +// Internal Functions + +// Add a container to the dependency mappings +func (s *InMemoryState) addCtrToDependsMap(ctrID, dependsID string) { + if dependsID != "" { + arr, ok := s.ctrDepends[dependsID] + if !ok { + // Do not have a mapping for that container yet + s.ctrDepends[dependsID] = []string{ctrID} + } else { + // Have a mapping for the container + arr = append(arr, ctrID) + s.ctrDepends[dependsID] = arr + } + } +} + +// Remove a container from dependency mappings +func (s *InMemoryState) removeCtrFromDependsMap(ctrID, dependsID string) { + if dependsID != "" { + arr, ok := s.ctrDepends[dependsID] + if !ok { + // Internal state seems inconsistent + // But the dependency is definitely gone + // So just return + return + } + + newArr := make([]string, len(arr), 0) + + for _, id := range arr { + if id != ctrID { + newArr = append(newArr, id) + } + } + + s.ctrDepends[dependsID] = newArr + } +} |