summaryrefslogtreecommitdiff
path: root/libpod
diff options
context:
space:
mode:
Diffstat (limited to 'libpod')
-rw-r--r--libpod/boltdb_state.go11
-rw-r--r--libpod/boltdb_state_internal.go19
-rw-r--r--libpod/errors.go4
-rw-r--r--libpod/in_memory_state.go5
-rw-r--r--libpod/state_test.go91
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)