summaryrefslogtreecommitdiff
path: root/libpod
diff options
context:
space:
mode:
authorOpenShift Merge Robot <openshift-merge-robot@users.noreply.github.com>2020-08-21 12:58:55 +0200
committerGitHub <noreply@github.com>2020-08-21 12:58:55 +0200
commit11372c4c4d75d731f346c6be06e41bfe9600ce81 (patch)
tree79a8f85f2f8ac32613ce86db3601b355595cf852 /libpod
parent84180d99bc808795a1f91747436a42745ddececb (diff)
parent7fc3c25410bd5ee053473ffd5df2209f41840ec0 (diff)
downloadpodman-11372c4c4d75d731f346c6be06e41bfe9600ce81.tar.gz
podman-11372c4c4d75d731f346c6be06e41bfe9600ce81.tar.bz2
podman-11372c4c4d75d731f346c6be06e41bfe9600ce81.zip
Merge pull request #7363 from mheon/lets_try_this_again
Lets try this again: v2.0.5 backports, round 2
Diffstat (limited to 'libpod')
-rw-r--r--libpod/boltdb_state.go55
-rw-r--r--libpod/container.go4
-rw-r--r--libpod/container_internal_linux.go29
-rw-r--r--libpod/events/config.go2
-rw-r--r--libpod/events/events.go2
-rw-r--r--libpod/in_memory_state.go30
-rw-r--r--libpod/options.go13
-rw-r--r--libpod/runtime.go16
-rw-r--r--libpod/runtime_img.go26
-rw-r--r--libpod/state.go6
10 files changed, 176 insertions, 7 deletions
diff --git a/libpod/boltdb_state.go b/libpod/boltdb_state.go
index 38881d3e4..4e2630526 100644
--- a/libpod/boltdb_state.go
+++ b/libpod/boltdb_state.go
@@ -424,6 +424,61 @@ func (s *BoltState) SetNamespace(ns string) error {
return nil
}
+// GetName returns the name associated with a given ID. Since IDs are globally
+// unique, it works for both containers and pods.
+// Returns ErrNoSuchCtr if the ID does not exist.
+func (s *BoltState) GetName(id string) (string, error) {
+ if id == "" {
+ return "", define.ErrEmptyID
+ }
+
+ if !s.valid {
+ return "", define.ErrDBClosed
+ }
+
+ idBytes := []byte(id)
+
+ db, err := s.getDBCon()
+ if err != nil {
+ return "", err
+ }
+ defer s.deferredCloseDBCon(db)
+
+ name := ""
+
+ err = db.View(func(tx *bolt.Tx) error {
+ idBkt, err := getIDBucket(tx)
+ if err != nil {
+ return err
+ }
+
+ nameBytes := idBkt.Get(idBytes)
+ if nameBytes == nil {
+ return define.ErrNoSuchCtr
+ }
+
+ if s.namespaceBytes != nil {
+ nsBkt, err := getNSBucket(tx)
+ if err != nil {
+ return err
+ }
+
+ idNs := nsBkt.Get(idBytes)
+ if !bytes.Equal(idNs, s.namespaceBytes) {
+ return define.ErrNoSuchCtr
+ }
+ }
+
+ name = string(nameBytes)
+ return nil
+ })
+ if err != nil {
+ return "", err
+ }
+
+ return name, nil
+}
+
// Container retrieves a single container from the state by its full ID
func (s *BoltState) Container(id string) (*Container, error) {
if id == "" {
diff --git a/libpod/container.go b/libpod/container.go
index 9ad938a5c..644647bc9 100644
--- a/libpod/container.go
+++ b/libpod/container.go
@@ -261,6 +261,10 @@ type ContainerConfig struct {
Mounts []string `json:"mounts,omitempty"`
// NamedVolumes lists the named volumes to mount into the container.
NamedVolumes []*ContainerNamedVolume `json:"namedVolumes,omitempty"`
+ // CreateWorkingDir indicates that Libpod should create the container's
+ // working directory if it does not exist. Some OCI runtimes do this by
+ // default, but others do not.
+ CreateWorkingDir bool `json:"createWorkingDir,omitempty"`
// Security Config
diff --git a/libpod/container_internal_linux.go b/libpod/container_internal_linux.go
index d72e3ad47..0d9a1c824 100644
--- a/libpod/container_internal_linux.go
+++ b/libpod/container_internal_linux.go
@@ -157,7 +157,32 @@ func (c *Container) prepare() error {
}
// Save changes to container state
- return c.save()
+ if err := c.save(); err != nil {
+ return err
+ }
+
+ // Ensure container entrypoint is created (if required)
+ if c.config.CreateWorkingDir {
+ workdir, err := securejoin.SecureJoin(c.state.Mountpoint, c.WorkingDir())
+ if err != nil {
+ return errors.Wrapf(err, "error creating path to container %s working dir", c.ID())
+ }
+ rootUID := c.RootUID()
+ rootGID := c.RootGID()
+
+ if err := os.MkdirAll(workdir, 0755); err != nil {
+ if os.IsExist(err) {
+ return nil
+ }
+ return errors.Wrapf(err, "error creating container %s working dir", c.ID())
+ }
+
+ if err := os.Chown(workdir, rootUID, rootGID); err != nil {
+ return errors.Wrapf(err, "error chowning container %s working directory to container root", c.ID())
+ }
+ }
+
+ return nil
}
// cleanupNetwork unmounts and cleans up the container's network
@@ -575,7 +600,7 @@ func (c *Container) setupSystemd(mounts []spec.Mount, g generate.Generator) erro
Destination: "/sys/fs/cgroup/systemd",
Type: "bind",
Source: "/sys/fs/cgroup/systemd",
- Options: []string{"bind", "nodev", "noexec", "nosuid"},
+ Options: []string{"bind", "nodev", "noexec", "nosuid", "rprivate"},
}
g.AddMount(systemdMnt)
g.AddLinuxMaskedPaths("/sys/fs/cgroup/systemd/release_agent")
diff --git a/libpod/events/config.go b/libpod/events/config.go
index c34408e63..bb35c03c0 100644
--- a/libpod/events/config.go
+++ b/libpod/events/config.go
@@ -101,6 +101,8 @@ const (
Attach Status = "attach"
// AutoUpdate ...
AutoUpdate Status = "auto-update"
+ // Build ...
+ Build Status = "build"
// Checkpoint ...
Checkpoint Status = "checkpoint"
// Cleanup ...
diff --git a/libpod/events/events.go b/libpod/events/events.go
index 0253b1ee5..722c9595e 100644
--- a/libpod/events/events.go
+++ b/libpod/events/events.go
@@ -127,6 +127,8 @@ func StringToStatus(name string) (Status, error) {
switch name {
case Attach.String():
return Attach, nil
+ case Build.String():
+ return Build, nil
case Checkpoint.String():
return Checkpoint, nil
case Cleanup.String():
diff --git a/libpod/in_memory_state.go b/libpod/in_memory_state.go
index 794212bf0..b0eae0992 100644
--- a/libpod/in_memory_state.go
+++ b/libpod/in_memory_state.go
@@ -106,6 +106,36 @@ func (s *InMemoryState) SetNamespace(ns string) error {
return nil
}
+// GetName retrieves the name associated with a given ID.
+// Works with both Container and Pod IDs.
+func (s *InMemoryState) GetName(id string) (string, error) {
+ if id == "" {
+ return "", define.ErrEmptyID
+ }
+
+ var idIndex *truncindex.TruncIndex
+ if s.namespace != "" {
+ nsIndex, ok := s.namespaceIndexes[s.namespace]
+ if !ok {
+ // We have no containers in the namespace
+ // Return false
+ return "", define.ErrNoSuchCtr
+ }
+ idIndex = nsIndex.idIndex
+ } else {
+ idIndex = s.idIndex
+ }
+
+ fullID, err := idIndex.Get(id)
+ if err != nil {
+ if err == truncindex.ErrNotExist {
+ return "", define.ErrNoSuchCtr
+ }
+ return "", errors.Wrapf(err, "error performing truncindex lookup for ID %s", id)
+ }
+ return fullID, nil
+}
+
// Container retrieves a container from its full ID
func (s *InMemoryState) Container(id string) (*Container, error) {
if id == "" {
diff --git a/libpod/options.go b/libpod/options.go
index 560b406e2..a4e4b99e9 100644
--- a/libpod/options.go
+++ b/libpod/options.go
@@ -1395,6 +1395,19 @@ func WithCreateCommand(cmd []string) CtrCreateOption {
}
}
+// WithCreateWorkingDir tells Podman to create the container's working directory
+// if it does not exist.
+func WithCreateWorkingDir() CtrCreateOption {
+ return func(ctr *Container) error {
+ if ctr.valid {
+ return define.ErrCtrFinalized
+ }
+
+ ctr.config.CreateWorkingDir = true
+ return nil
+ }
+}
+
// Volume Creation Options
// WithVolumeName sets the name of the volume.
diff --git a/libpod/runtime.go b/libpod/runtime.go
index 24370d50e..867644be7 100644
--- a/libpod/runtime.go
+++ b/libpod/runtime.go
@@ -732,6 +732,22 @@ func (r *Runtime) GetStore() storage.Store {
return r.store
}
+// GetName retrieves the name associated with a given full ID.
+// This works for both containers and pods, and does not distinguish between the
+// two.
+// If the given ID does not correspond to any existing Pod or Container,
+// ErrNoSuchCtr is returned.
+func (r *Runtime) GetName(id string) (string, error) {
+ r.lock.RLock()
+ defer r.lock.RUnlock()
+
+ if !r.valid {
+ return "", define.ErrRuntimeStopped
+ }
+
+ return r.state.GetName(id)
+}
+
// DBConfig is a set of Libpod runtime configuration settings that are saved in
// a State when it is first created, and can subsequently be retrieved.
type DBConfig struct {
diff --git a/libpod/runtime_img.go b/libpod/runtime_img.go
index 7c75dbf98..9515aa468 100644
--- a/libpod/runtime_img.go
+++ b/libpod/runtime_img.go
@@ -10,18 +10,18 @@ import (
"os"
"github.com/containers/buildah/imagebuildah"
+ "github.com/containers/image/v5/directory"
+ dockerarchive "github.com/containers/image/v5/docker/archive"
"github.com/containers/image/v5/docker/reference"
+ ociarchive "github.com/containers/image/v5/oci/archive"
"github.com/containers/libpod/v2/libpod/define"
+ "github.com/containers/libpod/v2/libpod/events"
"github.com/containers/libpod/v2/libpod/image"
"github.com/containers/libpod/v2/pkg/util"
"github.com/containers/storage"
+ v1 "github.com/opencontainers/image-spec/specs-go/v1"
"github.com/pkg/errors"
"github.com/sirupsen/logrus"
-
- "github.com/containers/image/v5/directory"
- dockerarchive "github.com/containers/image/v5/docker/archive"
- ociarchive "github.com/containers/image/v5/oci/archive"
- v1 "github.com/opencontainers/image-spec/specs-go/v1"
)
// Runtime API
@@ -140,6 +140,10 @@ func storageContainers(imageID string, store storage.Store) ([]string, error) {
// Removes the containers passed in the array.
func removeStorageContainers(ctrIDs []string, store storage.Store) error {
for _, ctrID := range ctrIDs {
+ if _, err := store.Unmount(ctrID, true); err != nil {
+ return errors.Wrapf(err, "could not unmount container %q to remove it", ctrID)
+ }
+
if err := store.DeleteContainer(ctrID); err != nil {
return errors.Wrapf(err, "could not remove container %q", ctrID)
}
@@ -147,9 +151,21 @@ func removeStorageContainers(ctrIDs []string, store storage.Store) error {
return nil
}
+// newBuildEvent creates a new event based on completion of a built image
+func (r *Runtime) newImageBuildCompleteEvent(idOrName string) {
+ e := events.NewEvent(events.Build)
+ e.Type = events.Image
+ e.Name = idOrName
+ if err := r.eventer.Write(e); err != nil {
+ logrus.Errorf("unable to write build event: %q", err)
+ }
+}
+
// Build adds the runtime to the imagebuildah call
func (r *Runtime) Build(ctx context.Context, options imagebuildah.BuildOptions, dockerfiles ...string) (string, reference.Canonical, error) {
id, ref, err := imagebuildah.BuildDockerfiles(ctx, r.store, options, dockerfiles...)
+ // Write event for build completion
+ r.newImageBuildCompleteEvent(id)
return id, ref, err
}
diff --git a/libpod/state.go b/libpod/state.go
index 6206a2994..44632b02f 100644
--- a/libpod/state.go
+++ b/libpod/state.go
@@ -43,6 +43,12 @@ type State interface {
// containers and pods in all namespaces will be returned.
SetNamespace(ns string) error
+ // Resolve an ID into a Name. Since Podman names and IDs are globally
+ // unique between Pods and Containers, the ID may belong to either a pod
+ // or container. Despite this, we will always return ErrNoSuchCtr if the
+ // ID does not exist.
+ GetName(id string) (string, error)
+
// Return a container from the database from its full ID.
// If the container is not in the set namespace, an error will be
// returned.