diff options
-rw-r--r-- | libpod/boltdb_state.go | 11 | ||||
-rw-r--r-- | libpod/boltdb_state_internal.go | 19 | ||||
-rw-r--r-- | libpod/errors.go | 4 | ||||
-rw-r--r-- | libpod/in_memory_state.go | 5 | ||||
-rw-r--r-- | libpod/state_test.go | 91 |
5 files changed, 130 insertions, 0 deletions
diff --git a/libpod/boltdb_state.go b/libpod/boltdb_state.go index 45d09348e..648c14267 100644 --- a/libpod/boltdb_state.go +++ b/libpod/boltdb_state.go @@ -964,6 +964,11 @@ func (s *BoltState) AddPod(pod *Pod) error { podID := []byte(pod.ID()) podName := []byte(pod.Name()) + var podNamespace []byte + if pod.config.Namespace != "" { + podNamespace = []byte(pod.config.Namespace) + } + podConfigJSON, err := json.Marshal(pod.config) if err != nil { return errors.Wrapf(err, "error marshalling pod %s config to JSON", pod.ID()) @@ -1031,6 +1036,12 @@ func (s *BoltState) AddPod(pod *Pod) error { return errors.Wrapf(err, "error storing pod %s state JSON in DB", pod.ID()) } + if podNamespace != nil { + if err := newPod.Put(namespaceKey, podNamespace); err != nil { + return errors.Wrapf(err, "error storing pod %s namespace in DB", pod.ID()) + } + } + // Add us to the ID and names buckets if err := idsBkt.Put(podID, podName); err != nil { return errors.Wrapf(err, "error storing pod %s ID in DB", pod.ID()) diff --git a/libpod/boltdb_state_internal.go b/libpod/boltdb_state_internal.go index 69e7bee21..5661c5b7f 100644 --- a/libpod/boltdb_state_internal.go +++ b/libpod/boltdb_state_internal.go @@ -1,6 +1,7 @@ package libpod import ( + "bytes" "encoding/json" "path/filepath" "runtime" @@ -27,6 +28,7 @@ const ( netNSName = "netns" containersName = "containers" podIDName = "pod-id" + namespaceName = "namespace" ) var ( @@ -44,6 +46,7 @@ var ( netNSKey = []byte(netNSName) containersBkt = []byte(containersName) podIDKey = []byte(podIDName) + namespaceKey = []byte(namespaceName) ) // Check if the configuration of the database is compatible with the @@ -262,6 +265,11 @@ func (s *BoltState) addContainer(ctr *Container, pod *Pod) error { ctrID := []byte(ctr.ID()) ctrName := []byte(ctr.Name()) + var ctrNamespace []byte + if ctr.config.Namespace != "" { + ctrNamespace = []byte(ctr.config.Namespace) + } + db, err := s.getDBCon() if err != nil { return err @@ -309,6 +317,12 @@ func (s *BoltState) addContainer(ctr *Container, pod *Pod) error { if podCtrs == nil { return errors.Wrapf(ErrInternal, "pod %s does not have a containers bucket", pod.ID()) } + + podNS := podDB.Get(namespaceKey) + if !bytes.Equal(podNS, ctrNamespace) { + return errors.Wrapf(ErrNSMismatch, "container %s is in namespace %s and pod %s is in namespace %s", + ctr.ID(), ctr.config.Namespace, pod.ID(), pod.config.Namespace) + } } // Check if we already have a container with the given ID and name @@ -344,6 +358,11 @@ func (s *BoltState) addContainer(ctr *Container, pod *Pod) error { if err := newCtrBkt.Put(stateKey, stateJSON); err != nil { return errors.Wrapf(err, "error adding container %s state to DB", ctr.ID()) } + if ctrNamespace != nil { + if err := newCtrBkt.Put(namespaceKey, ctrNamespace); err != nil { + return errors.Wrapf(err, "error adding container %s namespace to DB", ctr.ID()) + } + } if pod != nil { if err := newCtrBkt.Put(podIDKey, []byte(pod.ID())); err != nil { return errors.Wrapf(err, "error adding container %s pod to DB", ctr.ID()) diff --git a/libpod/errors.go b/libpod/errors.go index ddd586e29..75b4928da 100644 --- a/libpod/errors.go +++ b/libpod/errors.go @@ -63,6 +63,10 @@ var ( // was created by a libpod with a different config ErrDBBadConfig = errors.New("database configuration mismatch") + // ErrNSMismatch indicates that the requested pod or container is in a + // different namespace and cannot be accessed or modified. + ErrNSMismatch = errors.New("target is in a different namespace") + // ErrNotImplemented indicates that the requested functionality is not // yet present ErrNotImplemented = errors.New("not yet implemented") diff --git a/libpod/in_memory_state.go b/libpod/in_memory_state.go index 36077b9d1..cf2f43477 100644 --- a/libpod/in_memory_state.go +++ b/libpod/in_memory_state.go @@ -494,6 +494,11 @@ func (s *InMemoryState) AddContainerToPod(pod *Pod, ctr *Container) error { return errors.Wrapf(ErrInvalidArg, "container %s is not in pod %s", ctr.ID(), pod.ID()) } + if ctr.config.Namespace != pod.config.Namespace { + return errors.Wrapf(ErrNSMismatch, "container %s is in namespace %s and pod %s is in namespace %s", + ctr.ID(), ctr.config.Namespace, pod.ID(), pod.config.Namespace) + } + // Retrieve pod containers list podCtrs, ok := s.podContainers[pod.ID()] if !ok { diff --git a/libpod/state_test.go b/libpod/state_test.go index 4d5eb9713..7174bbf2a 100644 --- a/libpod/state_test.go +++ b/libpod/state_test.go @@ -2224,6 +2224,97 @@ func TestAddContainerToPodDependencyOutsidePodFails(t *testing.T) { }) } +func TestAddContainerToPodSameNamespaceSucceeds(t *testing.T) { + runForAllStates(t, func(t *testing.T, state State, lockPath string) { + testPod, err := getTestPod1(lockPath) + assert.NoError(t, err) + testPod.config.Namespace = "test1" + + testCtr, err := getTestCtr2(lockPath) + assert.NoError(t, err) + testCtr.config.Namespace = "test1" + testCtr.config.Pod = testPod.ID() + + err = state.AddPod(testPod) + assert.NoError(t, err) + + err = state.AddContainerToPod(testPod, testCtr) + assert.NoError(t, err) + + allCtrs, err := state.AllContainers() + assert.NoError(t, err) + assert.Equal(t, 1, len(allCtrs)) + testContainersEqual(t, testCtr, allCtrs[0]) + }) +} + +func TestAddContainerToPodDifferentNamespaceFails(t *testing.T) { + runForAllStates(t, func(t *testing.T, state State, lockPath string) { + testPod, err := getTestPod1(lockPath) + assert.NoError(t, err) + testPod.config.Namespace = "test1" + + testCtr, err := getTestCtr2(lockPath) + assert.NoError(t, err) + testCtr.config.Namespace = "test2" + testCtr.config.Pod = testPod.ID() + + err = state.AddPod(testPod) + assert.NoError(t, err) + + err = state.AddContainerToPod(testPod, testCtr) + assert.Error(t, err) + + allCtrs, err := state.AllContainers() + assert.NoError(t, err) + assert.Equal(t, 0, len(allCtrs)) + }) +} + +func TestAddContainerToPodNamespaceOnCtrFails(t *testing.T) { + runForAllStates(t, func(t *testing.T, state State, lockPath string) { + testPod, err := getTestPod1(lockPath) + assert.NoError(t, err) + + testCtr, err := getTestCtr2(lockPath) + assert.NoError(t, err) + testCtr.config.Namespace = "test1" + testCtr.config.Pod = testPod.ID() + + err = state.AddPod(testPod) + assert.NoError(t, err) + + err = state.AddContainerToPod(testPod, testCtr) + assert.Error(t, err) + + allCtrs, err := state.AllContainers() + assert.NoError(t, err) + assert.Equal(t, 0, len(allCtrs)) + }) +} + +func TestAddContainerToPodNamespaceOnPodFails(t *testing.T) { + runForAllStates(t, func(t *testing.T, state State, lockPath string) { + testPod, err := getTestPod1(lockPath) + assert.NoError(t, err) + testPod.config.Namespace = "test1" + + testCtr, err := getTestCtr2(lockPath) + assert.NoError(t, err) + testCtr.config.Pod = testPod.ID() + + err = state.AddPod(testPod) + assert.NoError(t, err) + + err = state.AddContainerToPod(testPod, testCtr) + assert.Error(t, err) + + allCtrs, err := state.AllContainers() + assert.NoError(t, err) + assert.Equal(t, 0, len(allCtrs)) + }) +} + func TestRemoveContainerFromPodBadPodFails(t *testing.T) { runForAllStates(t, func(t *testing.T, state State, lockPath string) { testCtr, err := getTestCtr1(lockPath) |