aboutsummaryrefslogtreecommitdiff
path: root/libpod
diff options
context:
space:
mode:
authorMatthew Heon <matthew.heon@gmail.com>2017-12-13 16:58:14 -0500
committerAtomic Bot <atomic-devel@projectatomic.io>2017-12-14 18:18:16 +0000
commit6d297688644a73c23fce7fbbaa5b402eca4d85d8 (patch)
tree8219e44ba61f50a913031d85b68fdaa23ee09606 /libpod
parentd8f099bb5a38b85bdea2bf6d99e0dbd0457ab666 (diff)
downloadpodman-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
Diffstat (limited to 'libpod')
-rw-r--r--libpod/options.go16
-rw-r--r--libpod/pod.go57
-rw-r--r--libpod/runtime_pod.go2
-rw-r--r--libpod/sql_state_internal.go2
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 {