mirror of
https://github.com/containers/podman.git
synced 2025-07-17 17:43:23 +08:00
Add pod state
Add a mutable state to pods, and database backend sutable for modifying and updating said state. Signed-off-by: Matthew Heon <matthew.heon@gmail.com> Closes: #784 Approved by: rhatdan
This commit is contained in:
@ -623,6 +623,7 @@ func (s *BoltState) Pod(id string) (*Pod, error) {
|
|||||||
|
|
||||||
pod := new(Pod)
|
pod := new(Pod)
|
||||||
pod.config = new(PodConfig)
|
pod.config = new(PodConfig)
|
||||||
|
pod.state = new(podState)
|
||||||
|
|
||||||
db, err := s.getDBCon()
|
db, err := s.getDBCon()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@ -657,6 +658,7 @@ func (s *BoltState) LookupPod(idOrName string) (*Pod, error) {
|
|||||||
|
|
||||||
pod := new(Pod)
|
pod := new(Pod)
|
||||||
pod.config = new(PodConfig)
|
pod.config = new(PodConfig)
|
||||||
|
pod.state = new(podState)
|
||||||
|
|
||||||
db, err := s.getDBCon()
|
db, err := s.getDBCon()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@ -957,9 +959,14 @@ func (s *BoltState) AddPod(pod *Pod) error {
|
|||||||
podID := []byte(pod.ID())
|
podID := []byte(pod.ID())
|
||||||
podName := []byte(pod.Name())
|
podName := []byte(pod.Name())
|
||||||
|
|
||||||
podJSON, err := json.Marshal(pod.config)
|
podConfigJSON, err := json.Marshal(pod.config)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return errors.Wrapf(err, "error marshalling pod %s JSON", pod.ID())
|
return errors.Wrapf(err, "error marshalling pod %s config to JSON", pod.ID())
|
||||||
|
}
|
||||||
|
|
||||||
|
podStateJSON, err := json.Marshal(pod.state)
|
||||||
|
if err != nil {
|
||||||
|
return errors.Wrapf(err, "error marshalling pod %s state to JSON", pod.ID())
|
||||||
}
|
}
|
||||||
|
|
||||||
db, err := s.getDBCon()
|
db, err := s.getDBCon()
|
||||||
@ -1011,10 +1018,14 @@ func (s *BoltState) AddPod(pod *Pod) error {
|
|||||||
return errors.Wrapf(err, "error creating bucket for pod %s containers", pod.ID())
|
return errors.Wrapf(err, "error creating bucket for pod %s containers", pod.ID())
|
||||||
}
|
}
|
||||||
|
|
||||||
if err := newPod.Put(configKey, podJSON); err != nil {
|
if err := newPod.Put(configKey, podConfigJSON); err != nil {
|
||||||
return errors.Wrapf(err, "error storing pod %s configuration in DB", pod.ID())
|
return errors.Wrapf(err, "error storing pod %s configuration in DB", pod.ID())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if err := newPod.Put(stateKey, podStateJSON); err != nil {
|
||||||
|
return errors.Wrapf(err, "error storing pod %s state JSON in DB", pod.ID())
|
||||||
|
}
|
||||||
|
|
||||||
// Add us to the ID and names buckets
|
// Add us to the ID and names buckets
|
||||||
if err := idsBkt.Put(podID, podName); err != nil {
|
if err := idsBkt.Put(podID, podName); err != nil {
|
||||||
return errors.Wrapf(err, "error storing pod %s ID in DB", pod.ID())
|
return errors.Wrapf(err, "error storing pod %s ID in DB", pod.ID())
|
||||||
@ -1296,6 +1307,108 @@ func (s *BoltState) RemoveContainerFromPod(pod *Pod, ctr *Container) error {
|
|||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// UpdatePod updates a pod's state from the database
|
||||||
|
func (s *BoltState) UpdatePod(pod *Pod) error {
|
||||||
|
if !s.valid {
|
||||||
|
return ErrDBClosed
|
||||||
|
}
|
||||||
|
|
||||||
|
if !pod.valid {
|
||||||
|
return ErrPodRemoved
|
||||||
|
}
|
||||||
|
|
||||||
|
newState := new(podState)
|
||||||
|
|
||||||
|
db, err := s.getDBCon()
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
defer db.Close()
|
||||||
|
|
||||||
|
podID := []byte(pod.ID())
|
||||||
|
|
||||||
|
err = db.View(func(tx *bolt.Tx) error {
|
||||||
|
podBkt, err := getPodBucket(tx)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
podDB := podBkt.Bucket(podID)
|
||||||
|
if podDB == nil {
|
||||||
|
pod.valid = false
|
||||||
|
return errors.Wrapf(ErrNoSuchPod, "no pod with ID %s found in database", pod.ID())
|
||||||
|
}
|
||||||
|
|
||||||
|
// Get the pod state JSON
|
||||||
|
podStateBytes := podDB.Get(stateKey)
|
||||||
|
if podStateBytes == nil {
|
||||||
|
return errors.Wrapf(ErrInternal, "pod %s is missing state key in DB", pod.ID())
|
||||||
|
}
|
||||||
|
|
||||||
|
if err := json.Unmarshal(podStateBytes, newState); err != nil {
|
||||||
|
return errors.Wrapf(err, "error unmarshalling pod %s state JSON", pod.ID())
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
})
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
pod.state = newState
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// SavePod saves a pod's state to the database
|
||||||
|
func (s *BoltState) SavePod(pod *Pod) error {
|
||||||
|
if !s.valid {
|
||||||
|
return ErrDBClosed
|
||||||
|
}
|
||||||
|
|
||||||
|
if !pod.valid {
|
||||||
|
return ErrPodRemoved
|
||||||
|
}
|
||||||
|
|
||||||
|
stateJSON, err := json.Marshal(pod.state)
|
||||||
|
if err != nil {
|
||||||
|
return errors.Wrapf(err, "error marshalling pod %s state to JSON", pod.ID())
|
||||||
|
}
|
||||||
|
|
||||||
|
db, err := s.getDBCon()
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
defer db.Close()
|
||||||
|
|
||||||
|
podID := []byte(pod.ID())
|
||||||
|
|
||||||
|
err = db.Update(func(tx *bolt.Tx) error {
|
||||||
|
podBkt, err := getPodBucket(tx)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
podDB := podBkt.Bucket(podID)
|
||||||
|
if podDB == nil {
|
||||||
|
pod.valid = false
|
||||||
|
return errors.Wrapf(ErrNoSuchPod, "no pod with ID %s found in database", pod.ID())
|
||||||
|
}
|
||||||
|
|
||||||
|
// Set the pod state JSON
|
||||||
|
if err := podDB.Put(stateKey, stateJSON); err != nil {
|
||||||
|
return errors.Wrapf(err, "error updating pod %s state in database", pod.ID())
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
})
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
// AllPods returns all pods present in the state
|
// AllPods returns all pods present in the state
|
||||||
func (s *BoltState) AllPods() ([]*Pod, error) {
|
func (s *BoltState) AllPods() ([]*Pod, error) {
|
||||||
if !s.valid {
|
if !s.valid {
|
||||||
@ -1331,6 +1444,7 @@ func (s *BoltState) AllPods() ([]*Pod, error) {
|
|||||||
|
|
||||||
pod := new(Pod)
|
pod := new(Pod)
|
||||||
pod.config = new(PodConfig)
|
pod.config = new(PodConfig)
|
||||||
|
pod.state = new(podState)
|
||||||
|
|
||||||
pods = append(pods, pod)
|
pods = append(pods, pod)
|
||||||
|
|
||||||
|
@ -256,13 +256,22 @@ func (s *BoltState) getPodFromDB(id []byte, pod *Pod, podBkt *bolt.Bucket) error
|
|||||||
return errors.Wrapf(ErrNoSuchPod, "pod with ID %s not found", string(id))
|
return errors.Wrapf(ErrNoSuchPod, "pod with ID %s not found", string(id))
|
||||||
}
|
}
|
||||||
|
|
||||||
podBytes := podDB.Get(configKey)
|
podConfigBytes := podDB.Get(configKey)
|
||||||
if podBytes == nil {
|
if podConfigBytes == nil {
|
||||||
return errors.Wrapf(ErrInternal, "pod %s is missing configuration key in DB", string(id))
|
return errors.Wrapf(ErrInternal, "pod %s is missing configuration key in DB", string(id))
|
||||||
}
|
}
|
||||||
|
|
||||||
if err := json.Unmarshal(podBytes, pod.config); err != nil {
|
if err := json.Unmarshal(podConfigBytes, pod.config); err != nil {
|
||||||
return errors.Wrapf(err, "error unmarshalling pod %s from DB", string(id))
|
return errors.Wrapf(err, "error unmarshalling pod %s config from DB", string(id))
|
||||||
|
}
|
||||||
|
|
||||||
|
podStateBytes := podDB.Get(stateKey)
|
||||||
|
if podStateBytes == nil {
|
||||||
|
return errors.Wrapf(ErrInternal, "pod %s is missing state key in DB", string(id))
|
||||||
|
}
|
||||||
|
|
||||||
|
if err := json.Unmarshal(podStateBytes, pod.state); err != nil {
|
||||||
|
return errors.Wrapf(err, "error unmarshalling pod %s state from DB", string(id))
|
||||||
}
|
}
|
||||||
|
|
||||||
// Get the lock
|
// Get the lock
|
||||||
|
@ -94,9 +94,13 @@ func getTestContainer(id, name, locksDir string) (*Container, error) {
|
|||||||
func getTestPod(id, name, locksDir string) (*Pod, error) {
|
func getTestPod(id, name, locksDir string) (*Pod, error) {
|
||||||
pod := &Pod{
|
pod := &Pod{
|
||||||
config: &PodConfig{
|
config: &PodConfig{
|
||||||
ID: id,
|
ID: id,
|
||||||
Name: name,
|
Name: name,
|
||||||
Labels: map[string]string{"a": "b", "c": "d"},
|
Labels: map[string]string{"a": "b", "c": "d"},
|
||||||
|
CgroupParent: "/hello/world/cgroup/parent",
|
||||||
|
},
|
||||||
|
state: &podState{
|
||||||
|
CgroupPath: "/path/to/cgroups/hello/",
|
||||||
},
|
},
|
||||||
valid: true,
|
valid: true,
|
||||||
}
|
}
|
||||||
@ -180,3 +184,23 @@ func testContainersEqual(t *testing.T, a, b *Container) {
|
|||||||
|
|
||||||
assert.EqualValues(t, aState, bState)
|
assert.EqualValues(t, aState, bState)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Test if pods are equal
|
||||||
|
func testPodsEqual(t *testing.T, a, b *Pod) {
|
||||||
|
if a == nil && b == nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
assert.NotNil(t, a)
|
||||||
|
assert.NotNil(t, b)
|
||||||
|
|
||||||
|
assert.NotNil(t, a.config)
|
||||||
|
assert.NotNil(t, b.config)
|
||||||
|
assert.NotNil(t, a.state)
|
||||||
|
assert.NotNil(t, b.state)
|
||||||
|
|
||||||
|
assert.Equal(t, a.valid, b.valid)
|
||||||
|
|
||||||
|
assert.EqualValues(t, a.config, b.config)
|
||||||
|
assert.EqualValues(t, a.state, b.state)
|
||||||
|
}
|
||||||
|
@ -604,6 +604,36 @@ func (s *InMemoryState) RemoveContainerFromPod(pod *Pod, ctr *Container) error {
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// UpdatePod updates a pod in the state
|
||||||
|
// This is a no-op as there is no backing store
|
||||||
|
func (s *InMemoryState) UpdatePod(pod *Pod) error {
|
||||||
|
if !pod.valid {
|
||||||
|
return ErrPodRemoved
|
||||||
|
}
|
||||||
|
|
||||||
|
if _, ok := s.pods[pod.ID()]; !ok {
|
||||||
|
pod.valid = false
|
||||||
|
return errors.Wrapf(ErrNoSuchPod, "no pod exists in state with ID %s", pod.ID())
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// SavePod updates a pod in the state
|
||||||
|
// This is a no-op at there is no backing store
|
||||||
|
func (s *InMemoryState) SavePod(pod *Pod) error {
|
||||||
|
if !pod.valid {
|
||||||
|
return ErrPodRemoved
|
||||||
|
}
|
||||||
|
|
||||||
|
if _, ok := s.pods[pod.ID()]; !ok {
|
||||||
|
pod.valid = false
|
||||||
|
return errors.Wrapf(ErrNoSuchPod, "no pod exists in state with ID %s", pod.ID())
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
// AllPods retrieves all pods currently in the state
|
// AllPods retrieves all pods currently in the state
|
||||||
func (s *InMemoryState) AllPods() ([]*Pod, error) {
|
func (s *InMemoryState) AllPods() ([]*Pod, error) {
|
||||||
pods := make([]*Pod, 0, len(s.pods))
|
pods := make([]*Pod, 0, len(s.pods))
|
||||||
|
@ -15,6 +15,7 @@ import (
|
|||||||
// ffjson: skip
|
// ffjson: skip
|
||||||
type Pod struct {
|
type Pod struct {
|
||||||
config *PodConfig
|
config *PodConfig
|
||||||
|
state *podState
|
||||||
|
|
||||||
valid bool
|
valid bool
|
||||||
runtime *Runtime
|
runtime *Runtime
|
||||||
@ -23,9 +24,19 @@ type Pod struct {
|
|||||||
|
|
||||||
// PodConfig represents a pod's static configuration
|
// PodConfig represents a pod's static configuration
|
||||||
type PodConfig struct {
|
type PodConfig struct {
|
||||||
ID string `json:"id"`
|
ID string `json:"id"`
|
||||||
Name string `json:"name"`
|
Name string `json:"name"`
|
||||||
Labels map[string]string `json:""`
|
|
||||||
|
// Labels contains labels applied to the pod
|
||||||
|
Labels map[string]string `json:"labels"`
|
||||||
|
// CgroupParent contains the pod's CGroup parent
|
||||||
|
CgroupParent string `json:"cgroupParent"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// podState represents a pod's state
|
||||||
|
type podState struct {
|
||||||
|
// CgroupPath is the path to the pod's CGroup
|
||||||
|
CgroupPath string
|
||||||
}
|
}
|
||||||
|
|
||||||
// ID retrieves the pod's ID
|
// ID retrieves the pod's ID
|
||||||
@ -48,12 +59,18 @@ func (p *Pod) Labels() map[string]string {
|
|||||||
return labels
|
return labels
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// CgroupParent returns the pod's CGroup parent
|
||||||
|
func (p *Pod) CgroupParent() string {
|
||||||
|
return p.config.CgroupParent
|
||||||
|
}
|
||||||
|
|
||||||
// Creates a new, empty pod
|
// Creates a new, empty pod
|
||||||
func newPod(lockDir string, runtime *Runtime) (*Pod, error) {
|
func newPod(lockDir string, runtime *Runtime) (*Pod, error) {
|
||||||
pod := new(Pod)
|
pod := new(Pod)
|
||||||
pod.config = new(PodConfig)
|
pod.config = new(PodConfig)
|
||||||
pod.config.ID = stringid.GenerateNonCryptoID()
|
pod.config.ID = stringid.GenerateNonCryptoID()
|
||||||
pod.config.Labels = make(map[string]string)
|
pod.config.Labels = make(map[string]string)
|
||||||
|
pod.state = new(podState)
|
||||||
pod.runtime = runtime
|
pod.runtime = runtime
|
||||||
|
|
||||||
// Path our lock file will reside at
|
// Path our lock file will reside at
|
||||||
|
@ -1,6 +1,9 @@
|
|||||||
package libpod
|
package libpod
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"path"
|
||||||
|
"strings"
|
||||||
|
|
||||||
"github.com/pkg/errors"
|
"github.com/pkg/errors"
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -45,6 +48,24 @@ func (r *Runtime) NewPod(options ...PodCreateOption) (*Pod, error) {
|
|||||||
|
|
||||||
pod.valid = true
|
pod.valid = true
|
||||||
|
|
||||||
|
// Check CGroup parent sanity, and set it if it was not set
|
||||||
|
switch r.config.CgroupManager {
|
||||||
|
case CgroupfsCgroupsManager:
|
||||||
|
if pod.config.CgroupParent == "" {
|
||||||
|
pod.config.CgroupParent = CgroupfsDefaultCgroupParent
|
||||||
|
} else if strings.HasSuffix(path.Base(pod.config.CgroupParent), ".slice") {
|
||||||
|
return nil, errors.Wrapf(ErrInvalidArg, "systemd slice received as cgroup parent when using cgroupfs")
|
||||||
|
}
|
||||||
|
case SystemdCgroupsManager:
|
||||||
|
if pod.config.CgroupParent == "" {
|
||||||
|
pod.config.CgroupParent = SystemdDefaultCgroupParent
|
||||||
|
} else if len(pod.config.CgroupParent) < 6 || !strings.HasSuffix(path.Base(pod.config.CgroupParent), ".slice") {
|
||||||
|
return nil, errors.Wrapf(ErrInvalidArg, "did not receive systemd slice as cgroup parent when using systemd to manage cgroups")
|
||||||
|
}
|
||||||
|
default:
|
||||||
|
return nil, errors.Wrapf(ErrInvalidArg, "unsupported CGroup manager: %s - cannot validate cgroup parent", r.config.CgroupManager)
|
||||||
|
}
|
||||||
|
|
||||||
if err := r.state.AddPod(pod); err != nil {
|
if err := r.state.AddPod(pod); err != nil {
|
||||||
return nil, errors.Wrapf(err, "error adding pod to state")
|
return nil, errors.Wrapf(err, "error adding pod to state")
|
||||||
}
|
}
|
||||||
|
@ -66,6 +66,10 @@ type State interface {
|
|||||||
// RemoveContainerFromPod removes a container from an existing pod
|
// RemoveContainerFromPod removes a container from an existing pod
|
||||||
// The container will also be removed from the state
|
// The container will also be removed from the state
|
||||||
RemoveContainerFromPod(pod *Pod, ctr *Container) error
|
RemoveContainerFromPod(pod *Pod, ctr *Container) error
|
||||||
|
// UpdatePod updates a pod's state from the database
|
||||||
|
UpdatePod(pod *Pod) error
|
||||||
|
// SavePod saves a pod's state to the database
|
||||||
|
SavePod(pod *Pod) error
|
||||||
// Retrieves all pods presently in state
|
// Retrieves all pods presently in state
|
||||||
AllPods() ([]*Pod, error)
|
AllPods() ([]*Pod, error)
|
||||||
}
|
}
|
||||||
|
@ -915,8 +915,7 @@ func TestGetPodOnePod(t *testing.T) {
|
|||||||
statePod, err := state.Pod(testPod.ID())
|
statePod, err := state.Pod(testPod.ID())
|
||||||
assert.NoError(t, err)
|
assert.NoError(t, err)
|
||||||
|
|
||||||
assert.EqualValues(t, testPod.config, statePod.config)
|
testPodsEqual(t, testPod, statePod)
|
||||||
assert.Equal(t, testPod.valid, statePod.valid)
|
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -937,8 +936,7 @@ func TestGetOnePodFromTwo(t *testing.T) {
|
|||||||
statePod, err := state.Pod(testPod1.ID())
|
statePod, err := state.Pod(testPod1.ID())
|
||||||
assert.NoError(t, err)
|
assert.NoError(t, err)
|
||||||
|
|
||||||
assert.EqualValues(t, testPod1.config, statePod.config)
|
testPodsEqual(t, testPod1, statePod)
|
||||||
assert.Equal(t, testPod1.valid, statePod.valid)
|
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -999,8 +997,7 @@ func TestLookupPodFullID(t *testing.T) {
|
|||||||
statePod, err := state.LookupPod(testPod.ID())
|
statePod, err := state.LookupPod(testPod.ID())
|
||||||
assert.NoError(t, err)
|
assert.NoError(t, err)
|
||||||
|
|
||||||
assert.EqualValues(t, testPod.config, statePod.config)
|
testPodsEqual(t, testPod, statePod)
|
||||||
assert.Equal(t, testPod.valid, statePod.valid)
|
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1015,8 +1012,7 @@ func TestLookupPodUniquePartialID(t *testing.T) {
|
|||||||
statePod, err := state.LookupPod(testPod.ID()[0:8])
|
statePod, err := state.LookupPod(testPod.ID()[0:8])
|
||||||
assert.NoError(t, err)
|
assert.NoError(t, err)
|
||||||
|
|
||||||
assert.EqualValues(t, testPod.config, statePod.config)
|
testPodsEqual(t, testPod, statePod)
|
||||||
assert.Equal(t, testPod.valid, statePod.valid)
|
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1050,8 +1046,7 @@ func TestLookupPodByName(t *testing.T) {
|
|||||||
statePod, err := state.LookupPod(testPod.Name())
|
statePod, err := state.LookupPod(testPod.Name())
|
||||||
assert.NoError(t, err)
|
assert.NoError(t, err)
|
||||||
|
|
||||||
assert.EqualValues(t, testPod.config, statePod.config)
|
testPodsEqual(t, testPod, statePod)
|
||||||
assert.Equal(t, testPod.valid, statePod.valid)
|
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1157,7 +1152,7 @@ func TestAddPodValidPodSucceeds(t *testing.T) {
|
|||||||
assert.NoError(t, err)
|
assert.NoError(t, err)
|
||||||
assert.Equal(t, 1, len(allPods))
|
assert.Equal(t, 1, len(allPods))
|
||||||
|
|
||||||
assert.EqualValues(t, testPod.config, allPods[0].config)
|
testPodsEqual(t, testPod, allPods[0])
|
||||||
assert.Equal(t, testPod.valid, allPods[0].valid)
|
assert.Equal(t, testPod.valid, allPods[0].valid)
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
@ -1318,8 +1313,7 @@ func TestRemovePodFromPods(t *testing.T) {
|
|||||||
assert.NoError(t, err)
|
assert.NoError(t, err)
|
||||||
assert.Equal(t, 1, len(allPods))
|
assert.Equal(t, 1, len(allPods))
|
||||||
|
|
||||||
assert.EqualValues(t, testPod2.config, allPods[0].config)
|
testPodsEqual(t, testPod2, allPods[0])
|
||||||
assert.Equal(t, testPod2.valid, allPods[0].valid)
|
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1394,8 +1388,7 @@ func TestAllPodsFindsPod(t *testing.T) {
|
|||||||
assert.NoError(t, err)
|
assert.NoError(t, err)
|
||||||
assert.Equal(t, 1, len(allPods))
|
assert.Equal(t, 1, len(allPods))
|
||||||
|
|
||||||
assert.EqualValues(t, testPod.config, allPods[0].config)
|
testPodsEqual(t, testPod, allPods[0])
|
||||||
assert.Equal(t, testPod.valid, allPods[0].valid)
|
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2403,3 +2396,62 @@ func TestRemoveContainerFromPodWithDependencySucceedsAfterDepRemoved(t *testing.
|
|||||||
assert.Equal(t, 0, len(allCtrs))
|
assert.Equal(t, 0, len(allCtrs))
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestUpdatePodInvalidPod(t *testing.T) {
|
||||||
|
runForAllStates(t, func(t *testing.T, state State, lockPath string) {
|
||||||
|
err := state.UpdatePod(&Pod{config: &PodConfig{}})
|
||||||
|
assert.Error(t, err)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestUpdatePodPodNotInStateFails(t *testing.T) {
|
||||||
|
runForAllStates(t, func(t *testing.T, state State, lockPath string) {
|
||||||
|
testPod, err := getTestPod1(lockPath)
|
||||||
|
assert.NoError(t, err)
|
||||||
|
|
||||||
|
err = state.UpdatePod(testPod)
|
||||||
|
assert.Error(t, err)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestSavePodInvalidPod(t *testing.T) {
|
||||||
|
runForAllStates(t, func(t *testing.T, state State, lockPath string) {
|
||||||
|
err := state.SavePod(&Pod{config: &PodConfig{}})
|
||||||
|
assert.Error(t, err)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestSavePodPodNotInStateFails(t *testing.T) {
|
||||||
|
runForAllStates(t, func(t *testing.T, state State, lockPath string) {
|
||||||
|
testPod, err := getTestPod1(lockPath)
|
||||||
|
assert.NoError(t, err)
|
||||||
|
|
||||||
|
err = state.SavePod(testPod)
|
||||||
|
assert.Error(t, err)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestSaveAndUpdatePod(t *testing.T) {
|
||||||
|
runForAllStates(t, func(t *testing.T, state State, lockPath string) {
|
||||||
|
testPod, err := getTestPod1(lockPath)
|
||||||
|
assert.NoError(t, err)
|
||||||
|
|
||||||
|
err = state.AddPod(testPod)
|
||||||
|
assert.NoError(t, err)
|
||||||
|
|
||||||
|
statePod, err := state.Pod(testPod.ID())
|
||||||
|
assert.NoError(t, err)
|
||||||
|
|
||||||
|
testPodsEqual(t, testPod, statePod)
|
||||||
|
|
||||||
|
testPod.state.CgroupPath = "/new/path/for/test"
|
||||||
|
|
||||||
|
err = state.SavePod(testPod)
|
||||||
|
assert.NoError(t, err)
|
||||||
|
|
||||||
|
err = state.UpdatePod(statePod)
|
||||||
|
assert.NoError(t, err)
|
||||||
|
|
||||||
|
testPodsEqual(t, testPod, statePod)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
Reference in New Issue
Block a user