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>
This commit is contained in:
parent
e838dcb4bf
commit
2705344634
|
|
@ -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
|
||||
})
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Reference in New Issue