diff options
author | Matthew Heon <matthew.heon@gmail.com> | 2017-12-13 16:58:14 -0500 |
---|---|---|
committer | Atomic Bot <atomic-devel@projectatomic.io> | 2017-12-14 18:18:16 +0000 |
commit | 6d297688644a73c23fce7fbbaa5b402eca4d85d8 (patch) | |
tree | 8219e44ba61f50a913031d85b68fdaa23ee09606 | |
parent | d8f099bb5a38b85bdea2bf6d99e0dbd0457ab666 (diff) | |
download | podman-6d297688644a73c23fce7fbbaa5b402eca4d85d8.tar.gz podman-6d297688644a73c23fce7fbbaa5b402eca4d85d8.tar.bz2 podman-6d297688644a73c23fce7fbbaa5b402eca4d85d8.zip |
Update pods to use file locks
Also includes misc other fixes - adding labels, fixing pod names
Signed-off-by: Matthew Heon <matthew.heon@gmail.com>
Closes: #138
Approved by: rhatdan
-rw-r--r-- | libpod/options.go | 16 | ||||
-rw-r--r-- | libpod/pod.go | 57 | ||||
-rw-r--r-- | libpod/runtime_pod.go | 2 | ||||
-rw-r--r-- | libpod/sql_state_internal.go | 2 |
4 files changed, 61 insertions, 16 deletions
diff --git a/libpod/options.go b/libpod/options.go index 07c25faf9..8a12c61e4 100644 --- a/libpod/options.go +++ b/libpod/options.go @@ -401,3 +401,19 @@ func WithPodName(name string) PodCreateOption { return nil } } + +// WithPodLabels sets the labels of a pod +func WithPodLabels(labels map[string]string) PodCreateOption { + return func(pod *Pod) error { + if pod.valid { + return ErrPodFinalized + } + + pod.labels = make(map[string]string) + for key, value := range labels { + pod.labels[key] = value + } + + return nil + } +} diff --git a/libpod/pod.go b/libpod/pod.go index 48a761d57..b336c2677 100644 --- a/libpod/pod.go +++ b/libpod/pod.go @@ -1,21 +1,25 @@ package libpod import ( - "sync" + "os" + "path/filepath" + "github.com/containers/storage" + "github.com/docker/docker/pkg/namesgenerator" "github.com/docker/docker/pkg/stringid" "github.com/pkg/errors" ) // Pod represents a group of containers that may share namespaces type Pod struct { - id string - name string + id string + name string + labels map[string]string containers map[string]*Container valid bool - lock sync.RWMutex + lock storage.Locker } // ID retrieves the pod's ID @@ -28,14 +32,43 @@ func (p *Pod) Name() string { return p.name } -// Creates a new pod -func newPod() (*Pod, error) { +// Labels returns the pod's labels +func (p *Pod) Labels() map[string]string { + labels := make(map[string]string) + for key, value := range p.labels { + labels[key] = value + } + + return labels +} + +// Creates a new, empty pod +func newPod(lockDir string) (*Pod, error) { pod := new(Pod) pod.id = stringid.GenerateNonCryptoID() - pod.name = pod.id // TODO generate human-readable name here + pod.name = namesgenerator.GetRandomName(0) pod.containers = make(map[string]*Container) + // TODO: containers and pods share a locks folder, but not tables in the + // database + // As the locks are 256-bit pseudorandom integers, collision is unlikely + // But it's something worth looking into + + // Path our lock file will reside at + lockPath := filepath.Join(lockDir, pod.id) + // Ensure there is no conflict - file does not exist + _, err := os.Stat(lockPath) + if err == nil || !os.IsNotExist(err) { + return nil, errors.Wrapf(ErrCtrExists, "lockfile for pod ID %s already exists", pod.id) + } + // Grab a lockfile at the given path + lock, err := storage.GetLockfile(lockPath) + if err != nil { + return nil, errors.Wrapf(err, "error creating lockfile for new pod") + } + pod.lock = lock + return pod, nil } @@ -45,8 +78,6 @@ func newPod() (*Pod, error) { func (p *Pod) addContainer(ctr *Container) error { p.lock.Lock() defer p.lock.Unlock() - ctr.lock.Lock() - defer ctr.lock.Unlock() if !p.valid { return ErrPodRemoved @@ -101,8 +132,8 @@ func (p *Pod) Kill(signal uint) error { // HasContainer checks if a container is present in the pod func (p *Pod) HasContainer(id string) (bool, error) { - p.lock.RLock() - defer p.lock.RUnlock() + p.lock.Lock() + defer p.lock.Unlock() if !p.valid { return false, ErrPodRemoved @@ -115,8 +146,8 @@ func (p *Pod) HasContainer(id string) (bool, error) { // GetContainers retrieves the containers in the pod func (p *Pod) GetContainers() ([]*Container, error) { - p.lock.RLock() - defer p.lock.RUnlock() + p.lock.Lock() + defer p.lock.Unlock() if !p.valid { return nil, ErrPodRemoved diff --git a/libpod/runtime_pod.go b/libpod/runtime_pod.go index 162b353e6..35c7f0642 100644 --- a/libpod/runtime_pod.go +++ b/libpod/runtime_pod.go @@ -24,7 +24,7 @@ func (r *Runtime) NewPod(options ...PodCreateOption) (*Pod, error) { return nil, ErrRuntimeStopped } - pod, err := newPod() + pod, err := newPod(r.lockDir) if err != nil { return nil, errors.Wrapf(err, "error creating pod") } diff --git a/libpod/sql_state_internal.go b/libpod/sql_state_internal.go index 515b5b6ad..12a7dbd10 100644 --- a/libpod/sql_state_internal.go +++ b/libpod/sql_state_internal.go @@ -154,8 +154,6 @@ func prepareDB(db *sql.DB) (err error) { // TODO add Pod ID to CreateStaticContainer as a FOREIGN KEY referencing podStatic(Id) // TODO add ctr shared namespaces information - A separate table, probably? So we can FOREIGN KEY the ID // TODO schema migration might be necessary and should be handled here - // TODO add a table for the runtime, and refuse to load the database if the runtime configuration - // does not match the one in the database // Enable foreign keys in SQLite if _, err := db.Exec("PRAGMA foreign_keys = ON;"); err != nil { |