aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMatthew Heon <matthew.heon@gmail.com>2018-07-03 11:12:00 -0400
committerMatthew Heon <matthew.heon@gmail.com>2018-07-24 16:12:31 -0400
commit2705344634a875c49a4c9028d3a2f7e334b4db1f (patch)
tree8e5dd9d210053f90b228fe9e7fe69f76321577f6
parente838dcb4bf7dc35b1bcf21edad6a1f6c59d969ab (diff)
downloadpodman-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>
-rw-r--r--libpod/boltdb_state.go94
-rw-r--r--libpod/boltdb_state_internal.go11
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)
}
}