diff options
author | Matthew Heon <matthew.heon@gmail.com> | 2018-07-03 11:12:00 -0400 |
---|---|---|
committer | Matthew Heon <matthew.heon@gmail.com> | 2018-07-24 16:12:31 -0400 |
commit | 2705344634a875c49a4c9028d3a2f7e334b4db1f (patch) | |
tree | 8e5dd9d210053f90b228fe9e7fe69f76321577f6 /libpod | |
parent | e838dcb4bf7dc35b1bcf21edad6a1f6c59d969ab (diff) | |
download | podman-2705344634a875c49a4c9028d3a2f7e334b4db1f.tar.gz podman-2705344634a875c49a4c9028d3a2f7e334b4db1f.tar.bz2 podman-2705344634a875c49a4c9028d3a2f7e334b4db1f.zip |
Untested implementation of namespaced BoltDB access
All BoltDB access and update functions now understand namespaces.
Accessing containers outside of your namespace will produce
errors, except for Lookup and All functions, which will perform
their tasks only on containers within your namespace.
The "" namespace remains a reserved, no-restrictions namespace.
Signed-off-by: Matthew Heon <matthew.heon@gmail.com>
Diffstat (limited to 'libpod')
-rw-r--r-- | libpod/boltdb_state.go | 94 | ||||
-rw-r--r-- | libpod/boltdb_state_internal.go | 11 |
2 files changed, 96 insertions, 9 deletions
diff --git a/libpod/boltdb_state.go b/libpod/boltdb_state.go index 73a906761..470201348 100644 --- a/libpod/boltdb_state.go +++ b/libpod/boltdb_state.go @@ -371,7 +371,7 @@ func (s *BoltState) HasContainer(id string) (bool, error) { if ctrExists != nil { if s.namespaceBytes != nil { nsBytes := ctrBucket.Get(namespaceKey) - if bytes.Equal(nsBytes, nsBytes) { + if bytes.Equal(nsBytes, s.namespaceBytes) { exists = true } } else { @@ -425,7 +425,7 @@ func (s *BoltState) RemoveContainer(ctr *Container) error { defer db.Close() err = db.Update(func(tx *bolt.Tx) error { - return removeContainer(ctr, nil, tx, s.namespace) + return s.removeContainer(ctr, nil, tx) }) return err } @@ -873,6 +873,12 @@ func (s *BoltState) PodHasContainer(pod *Pod, id string) (bool, error) { return false, ErrPodRemoved } + if s.namespace != "" { + if s.namespace != pod.config.Namespace { + return false, errors.Wrapf(ErrNSMismatch, "pod %s is in namespace %q but we are in namespace %q", pod.ID(), pod.config.Namespace, s.namespace) + } + } + ctrID := []byte(id) podID := []byte(pod.ID()) @@ -903,6 +909,11 @@ func (s *BoltState) PodHasContainer(pod *Pod, id string) (bool, error) { return errors.Wrapf(ErrInternal, "pod %s missing containers bucket in DB", pod.ID()) } + // Don't bother with a namespace check on the container - + // We maintain the invariant that container namespaces must + // match the namespace of the pod they join. + // We already checked the pod namespace, so we should be fine. + ctr := podCtrs.Get(ctrID) if ctr != nil { exists = true @@ -927,6 +938,12 @@ func (s *BoltState) PodContainersByID(pod *Pod) ([]string, error) { return nil, ErrPodRemoved } + if s.namespace != "" { + if s.namespace != pod.config.Namespace { + return nil, errors.Wrapf(ErrNSMismatch, "pod %s is in namespace %q but we are in namespace %q", pod.ID(), pod.config.Namespace, s.namespace) + } + } + podID := []byte(pod.ID()) ctrs := []string{} @@ -985,6 +1002,12 @@ func (s *BoltState) PodContainers(pod *Pod) ([]*Container, error) { return nil, ErrPodRemoved } + if s.namespace != "" { + if s.namespace != pod.config.Namespace { + return nil, errors.Wrapf(ErrNSMismatch, "pod %s is in namespace %q but we are in namespace %q", pod.ID(), pod.config.Namespace, s.namespace) + } + } + podID := []byte(pod.ID()) ctrs := []*Container{} @@ -1051,6 +1074,12 @@ func (s *BoltState) AddPod(pod *Pod) error { return ErrPodRemoved } + if s.namespace != "" { + if s.namespace != pod.config.Namespace { + return errors.Wrapf(ErrNSMismatch, "pod %s is in namespace %q but we are in namespace %q", pod.ID(), pod.config.Namespace, s.namespace) + } + } + podID := []byte(pod.ID()) podName := []byte(pod.Name()) @@ -1096,6 +1125,11 @@ func (s *BoltState) AddPod(pod *Pod) error { return err } + nsBkt, err := getNSBucket(tx) + if err != nil { + return err + } + // Check if we already have something with the given ID and name idExist := idsBkt.Get(podID) if idExist != nil { @@ -1130,6 +1164,9 @@ func (s *BoltState) AddPod(pod *Pod) error { if err := newPod.Put(namespaceKey, podNamespace); err != nil { return errors.Wrapf(err, "error storing pod %s namespace in DB", pod.ID()) } + if err := nsBkt.Put(podID, podNamespace); err != nil { + return errors.Wrapf(err, "error storing pod %s namespace in DB", pod.ID()) + } } // Add us to the ID and names buckets @@ -1163,6 +1200,12 @@ func (s *BoltState) RemovePod(pod *Pod) error { return ErrPodRemoved } + if s.namespace != "" { + if s.namespace != pod.config.Namespace { + return errors.Wrapf(ErrNSMismatch, "pod %s is in namespace %q but we are in namespace %q", pod.ID(), pod.config.Namespace, s.namespace) + } + } + podID := []byte(pod.ID()) podName := []byte(pod.Name()) @@ -1193,6 +1236,11 @@ func (s *BoltState) RemovePod(pod *Pod) error { return err } + nsBkt, err := getNSBucket(tx) + if err != nil { + return err + } + // Check if the pod exists podDB := podBkt.Bucket(podID) if podDB == nil { @@ -1221,6 +1269,9 @@ func (s *BoltState) RemovePod(pod *Pod) error { if err := namesBkt.Delete(podName); err != nil { return errors.Wrapf(err, "error removing pod %s name (%s) from DB", pod.ID(), pod.Name()) } + if err := nsBkt.Delete(podID); err != nil { + return errors.Wrapf(err, "error removing pod %s namespace from DB", pod.ID()) + } if err := allPodsBkt.Delete(podID); err != nil { return errors.Wrapf(err, "error removing pod %s ID from all pods bucket in DB", pod.ID()) } @@ -1247,6 +1298,12 @@ func (s *BoltState) RemovePodContainers(pod *Pod) error { return ErrPodRemoved } + if s.namespace != "" { + if s.namespace != pod.config.Namespace { + return errors.Wrapf(ErrNSMismatch, "pod %s is in namespace %q but we are in namespace %q", pod.ID(), pod.config.Namespace, s.namespace) + } + } + podID := []byte(pod.ID()) db, err := s.getDBCon() @@ -1393,6 +1450,15 @@ func (s *BoltState) RemoveContainerFromPod(pod *Pod, ctr *Container) error { return ErrPodRemoved } + if s.namespace != "" { + if s.namespace != pod.config.Namespace { + return errors.Wrapf(ErrNSMismatch, "pod %s is in namespace %q but we are in namespace %q", pod.ID(), pod.config.Namespace, s.namespace) + } + if s.namespace != ctr.config.Namespace { + return errors.Wrapf(ErrNSMismatch, "container %s in in namespace %q but we are in namespace %q", ctr.ID(), ctr.config.Namespace, s.namespace) + } + } + if ctr.config.Pod == "" { return errors.Wrapf(ErrNoSuchPod, "container %s is not part of a pod, use RemoveContainer instead", ctr.ID()) } @@ -1408,7 +1474,7 @@ func (s *BoltState) RemoveContainerFromPod(pod *Pod, ctr *Container) error { defer db.Close() err = db.Update(func(tx *bolt.Tx) error { - return removeContainer(ctr, pod, tx, s.namespace) + return s.removeContainer(ctr, pod, tx) }) return err } @@ -1423,6 +1489,12 @@ func (s *BoltState) UpdatePod(pod *Pod) error { return ErrPodRemoved } + if s.namespace != "" { + if s.namespace != pod.config.Namespace { + return errors.Wrapf(ErrNSMismatch, "pod %s is in namespace %q but we are in namespace %q", pod.ID(), pod.config.Namespace, s.namespace) + } + } + newState := new(podState) db, err := s.getDBCon() @@ -1476,6 +1548,12 @@ func (s *BoltState) SavePod(pod *Pod) error { return ErrPodRemoved } + if s.namespace != "" { + if s.namespace != pod.config.Namespace { + return errors.Wrapf(ErrNSMismatch, "pod %s is in namespace %q but we are in namespace %q", pod.ID(), pod.config.Namespace, s.namespace) + } + } + stateJSON, err := json.Marshal(pod.state) if err != nil { return errors.Wrapf(err, "error marshalling pod %s state to JSON", pod.ID()) @@ -1552,9 +1630,15 @@ func (s *BoltState) AllPods() ([]*Pod, error) { pod.config = new(PodConfig) pod.state = new(podState) - pods = append(pods, pod) + if err := s.getPodFromDB(id, pod, podBucket); err != nil { + if errors.Cause(err) != ErrNSMismatch { + return err + } + } else { + pods = append(pods, pod) + } - return s.getPodFromDB(id, pod, podBucket) + return nil }) return err }) diff --git a/libpod/boltdb_state_internal.go b/libpod/boltdb_state_internal.go index 718c43046..81c9f49f5 100644 --- a/libpod/boltdb_state_internal.go +++ b/libpod/boltdb_state_internal.go @@ -459,7 +459,7 @@ func (s *BoltState) addContainer(ctr *Container, pod *Pod) error { // Remove a container from the DB // If pod is not nil, the container is treated as belonging to a pod, and // will be removed from the pod as well -func removeContainer(ctr *Container, pod *Pod, tx *bolt.Tx, namespace string) error { +func (s *BoltState) removeContainer(ctr *Container, pod *Pod, tx *bolt.Tx) error { ctrID := []byte(ctr.ID()) ctrName := []byte(ctr.Name()) @@ -514,9 +514,12 @@ func removeContainer(ctr *Container, pod *Pod, tx *bolt.Tx, namespace string) er // Compare namespace // We can't remove containers not in our namespace - if namespace != "" { - if namespace != ctr.config.Namespace { - return errors.Wrapf(ErrNSMismatch, "container %s is in namespace %q, does not match our namespace %q", ctr.ID(), ctr.config.Namespace, namespace) + if s.namespace != "" { + if s.namespace != ctr.config.Namespace { + return errors.Wrapf(ErrNSMismatch, "container %s is in namespace %q, does not match our namespace %q", ctr.ID(), ctr.config.Namespace, s.namespace) + } + if pod != nil && s.namespace != pod.config.Namespace { + return errors.Wrapf(ErrNSMismatch, "pod %s is in namespace %q, does not match out namespace %q", pod.ID(), pod.config.Namespace, s.namespace) } } |