summaryrefslogtreecommitdiff
path: root/libpod
diff options
context:
space:
mode:
Diffstat (limited to 'libpod')
-rw-r--r--libpod/container_copy_linux.go25
-rw-r--r--libpod/container_inspect.go23
-rw-r--r--libpod/define/errors.go2
-rw-r--r--libpod/define/info.go31
-rw-r--r--libpod/info.go44
-rw-r--r--libpod/runtime.go90
6 files changed, 162 insertions, 53 deletions
diff --git a/libpod/container_copy_linux.go b/libpod/container_copy_linux.go
index 5c275c641..0ab322829 100644
--- a/libpod/container_copy_linux.go
+++ b/libpod/container_copy_linux.go
@@ -237,21 +237,32 @@ func (c *Container) joinMountAndExec(ctx context.Context, f func() error) error
}
defer mountFD.Close()
- pidFD, err := getFD(PIDNS)
+ inHostPidNS, err := c.inHostPidNS()
if err != nil {
- errChan <- err
+ errChan <- errors.Wrap(err, "checking inHostPidNS")
return
}
- defer pidFD.Close()
- if err := unix.Unshare(unix.CLONE_NEWNS); err != nil {
- errChan <- err
- return
+ var pidFD *os.File
+ if !inHostPidNS {
+ pidFD, err = getFD(PIDNS)
+ if err != nil {
+ errChan <- err
+ return
+ }
+ defer pidFD.Close()
}
- if err := unix.Setns(int(pidFD.Fd()), unix.CLONE_NEWPID); err != nil {
+
+ if err := unix.Unshare(unix.CLONE_NEWNS); err != nil {
errChan <- err
return
}
+ if pidFD != nil {
+ if err := unix.Setns(int(pidFD.Fd()), unix.CLONE_NEWPID); err != nil {
+ errChan <- err
+ return
+ }
+ }
if err := unix.Setns(int(mountFD.Fd()), unix.CLONE_NEWNS); err != nil {
errChan <- err
return
diff --git a/libpod/container_inspect.go b/libpod/container_inspect.go
index 4210bc581..638e0b756 100644
--- a/libpod/container_inspect.go
+++ b/libpod/container_inspect.go
@@ -892,3 +892,26 @@ func (c *Container) generateInspectContainerHostConfig(ctrSpec *spec.Spec, named
return hostConfig, nil
}
+
+// Return true if the container is running in the host's PID NS.
+func (c *Container) inHostPidNS() (bool, error) {
+ if c.config.PIDNsCtr != "" {
+ return false, nil
+ }
+ ctrSpec, err := c.specFromState()
+ if err != nil {
+ return false, err
+ }
+ if ctrSpec.Linux != nil {
+ // Locate the spec's PID namespace.
+ // If there is none, it's pid=host.
+ // If there is one and it has a path, it's "ns:".
+ // If there is no path, it's default - the empty string.
+ for _, ns := range ctrSpec.Linux.Namespaces {
+ if ns.Type == spec.PIDNamespace {
+ return false, nil
+ }
+ }
+ }
+ return true, nil
+}
diff --git a/libpod/define/errors.go b/libpod/define/errors.go
index 81bf5f69c..9fd210eed 100644
--- a/libpod/define/errors.go
+++ b/libpod/define/errors.go
@@ -152,7 +152,7 @@ var (
// ErrOCIRuntimeNotFound indicates the OCI runtime attempted to invoke a command
// that was not found
- ErrOCIRuntimeNotFound = errors.New("OCI not found")
+ ErrOCIRuntimeNotFound = errors.New("OCI runtime attempted to invoke a command that was not found")
// ErrOCIRuntimeUnavailable indicates that the OCI runtime associated to a container
// could not be found in the configuration
diff --git a/libpod/define/info.go b/libpod/define/info.go
index c9d6877c0..de709be74 100644
--- a/libpod/define/info.go
+++ b/libpod/define/info.go
@@ -23,21 +23,22 @@ type SecurityInfo struct {
// HostInfo describes the libpod host
type HostInfo struct {
- Arch string `json:"arch"`
- BuildahVersion string `json:"buildahVersion"`
- CgroupManager string `json:"cgroupManager"`
- CGroupsVersion string `json:"cgroupVersion"`
- Conmon *ConmonInfo `json:"conmon"`
- CPUs int `json:"cpus"`
- Distribution DistributionInfo `json:"distribution"`
- EventLogger string `json:"eventLogger"`
- Hostname string `json:"hostname"`
- IDMappings IDMappings `json:"idMappings,omitempty"`
- Kernel string `json:"kernel"`
- MemFree int64 `json:"memFree"`
- MemTotal int64 `json:"memTotal"`
- OCIRuntime *OCIRuntimeInfo `json:"ociRuntime"`
- OS string `json:"os"`
+ Arch string `json:"arch"`
+ BuildahVersion string `json:"buildahVersion"`
+ CgroupManager string `json:"cgroupManager"`
+ CGroupsVersion string `json:"cgroupVersion"`
+ CgroupControllers []string `json:"cgroupControllers"`
+ Conmon *ConmonInfo `json:"conmon"`
+ CPUs int `json:"cpus"`
+ Distribution DistributionInfo `json:"distribution"`
+ EventLogger string `json:"eventLogger"`
+ Hostname string `json:"hostname"`
+ IDMappings IDMappings `json:"idMappings,omitempty"`
+ Kernel string `json:"kernel"`
+ MemFree int64 `json:"memFree"`
+ MemTotal int64 `json:"memTotal"`
+ OCIRuntime *OCIRuntimeInfo `json:"ociRuntime"`
+ OS string `json:"os"`
// RemoteSocket returns the UNIX domain socket the Podman service is listening on
RemoteSocket *RemoteSocket `json:"remoteSocket,omitempty"`
RuntimeInfo map[string]interface{} `json:"runtimeInfo,omitempty"`
diff --git a/libpod/info.go b/libpod/info.go
index 7a28a4cf7..461e39a48 100644
--- a/libpod/info.go
+++ b/libpod/info.go
@@ -93,20 +93,33 @@ func (r *Runtime) hostInfo() (*define.HostInfo, error) {
return nil, errors.Wrapf(err, "error getting Seccomp profile path")
}
+ // CGroups version
+ unified, err := cgroups.IsCgroup2UnifiedMode()
+ if err != nil {
+ return nil, errors.Wrapf(err, "error reading cgroups mode")
+ }
+
+ // Get Map of all available controllers
+ availableControllers, err := cgroups.GetAvailableControllers(nil, unified)
+ if err != nil {
+ return nil, errors.Wrapf(err, "error getting available cgroup controllers")
+ }
+
info := define.HostInfo{
- Arch: runtime.GOARCH,
- BuildahVersion: buildah.Version,
- CgroupManager: r.config.Engine.CgroupManager,
- Linkmode: linkmode.Linkmode(),
- CPUs: runtime.NumCPU(),
- Distribution: hostDistributionInfo,
- EventLogger: r.eventer.String(),
- Hostname: host,
- IDMappings: define.IDMappings{},
- Kernel: kv,
- MemFree: mi.MemFree,
- MemTotal: mi.MemTotal,
- OS: runtime.GOOS,
+ Arch: runtime.GOARCH,
+ BuildahVersion: buildah.Version,
+ CgroupManager: r.config.Engine.CgroupManager,
+ CgroupControllers: availableControllers,
+ Linkmode: linkmode.Linkmode(),
+ CPUs: runtime.NumCPU(),
+ Distribution: hostDistributionInfo,
+ EventLogger: r.eventer.String(),
+ Hostname: host,
+ IDMappings: define.IDMappings{},
+ Kernel: kv,
+ MemFree: mi.MemFree,
+ MemTotal: mi.MemTotal,
+ OS: runtime.GOOS,
Security: define.SecurityInfo{
AppArmorEnabled: apparmor.IsEnabled(),
DefaultCapabilities: strings.Join(r.config.Containers.DefaultCapabilities, ","),
@@ -120,11 +133,6 @@ func (r *Runtime) hostInfo() (*define.HostInfo, error) {
SwapTotal: mi.SwapTotal,
}
- // CGroups version
- unified, err := cgroups.IsCgroup2UnifiedMode()
- if err != nil {
- return nil, errors.Wrapf(err, "error reading cgroups mode")
- }
cgroupVersion := "v1"
if unified {
cgroupVersion = "v2"
diff --git a/libpod/runtime.go b/libpod/runtime.go
index d0bdeb574..713026a9e 100644
--- a/libpod/runtime.go
+++ b/libpod/runtime.go
@@ -13,6 +13,7 @@ import (
"strings"
"sync"
"syscall"
+ "time"
"github.com/containers/common/libimage"
"github.com/containers/common/pkg/config"
@@ -68,17 +69,18 @@ type Runtime struct {
storageConfig storage.StoreOptions
storageSet storageSet
- state State
- store storage.Store
- storageService *storageService
- imageContext *types.SystemContext
- defaultOCIRuntime OCIRuntime
- ociRuntimes map[string]OCIRuntime
- runtimeFlags []string
- netPlugin ocicni.CNIPlugin
- conmonPath string
- libimageRuntime *libimage.Runtime
- lockManager lock.Manager
+ state State
+ store storage.Store
+ storageService *storageService
+ imageContext *types.SystemContext
+ defaultOCIRuntime OCIRuntime
+ ociRuntimes map[string]OCIRuntime
+ runtimeFlags []string
+ netPlugin ocicni.CNIPlugin
+ conmonPath string
+ libimageRuntime *libimage.Runtime
+ libimageEventsShutdown chan bool
+ lockManager lock.Manager
// doRenumber indicates that the runtime should perform a lock renumber
// during initialization.
@@ -215,6 +217,8 @@ func newRuntimeFromConfig(ctx context.Context, conf *config.Config, options ...R
return nil, err
}
+ runtime.libimageEventsShutdown = make(chan bool)
+
return runtime, nil
}
@@ -680,6 +684,62 @@ func (r *Runtime) GetConfig() (*config.Config, error) {
return config, nil
}
+// libimageEventsMap translates a libimage event type to a libpod event status.
+var libimageEventsMap = map[libimage.EventType]events.Status{
+ libimage.EventTypeImagePull: events.Pull,
+ libimage.EventTypeImagePush: events.Push,
+ libimage.EventTypeImageRemove: events.Remove,
+ libimage.EventTypeImageLoad: events.LoadFromArchive,
+ libimage.EventTypeImageSave: events.Save,
+ libimage.EventTypeImageTag: events.Tag,
+ libimage.EventTypeImageUntag: events.Untag,
+ libimage.EventTypeImageMount: events.Mount,
+ libimage.EventTypeImageUnmount: events.Unmount,
+}
+
+// libimageEvents spawns a goroutine in the background which is listenting for
+// events on the libimage.Runtime. The gourtine will be cleaned up implicitly
+// when the main() exists.
+func (r *Runtime) libimageEvents() {
+ toLibpodEventStatus := func(e *libimage.Event) events.Status {
+ status, found := libimageEventsMap[e.Type]
+ if !found {
+ return "Unknown"
+ }
+ return status
+ }
+
+ go func() {
+ eventChannel := r.libimageRuntime.EventChannel()
+
+ for {
+ // Make sure to read and write all events before
+ // checking if we're about to shutdown.
+ for len(eventChannel) > 0 {
+ libimageEvent := <-eventChannel
+ e := events.Event{
+ ID: libimageEvent.ID,
+ Name: libimageEvent.Name,
+ Status: toLibpodEventStatus(libimageEvent),
+ Time: libimageEvent.Time,
+ Type: events.Image,
+ }
+ if err := r.eventer.Write(e); err != nil {
+ logrus.Errorf("unable to write image event: %q", err)
+ }
+ }
+
+ select {
+ case <-r.libimageEventsShutdown:
+ return
+
+ default:
+ time.Sleep(100 * time.Millisecond)
+ }
+ }
+ }()
+}
+
// DeferredShutdown shuts down the runtime without exposing any
// errors. This is only meant to be used when the runtime is being
// shutdown within a defer statement; else use Shutdown
@@ -719,7 +779,11 @@ func (r *Runtime) Shutdown(force bool) error {
// If no store was requested, it can be nil and there is no need to
// attempt to shut it down
if r.store != nil {
- if _, err := r.store.Shutdown(force); err != nil {
+ // Wait for the events to be written.
+ r.libimageEventsShutdown <- true
+
+ // Note that the libimage runtime shuts down the store.
+ if err := r.libimageRuntime.Shutdown(force); err != nil {
lastError = errors.Wrapf(err, "error shutting down container storage")
}
}
@@ -845,6 +909,8 @@ func (r *Runtime) configureStore() error {
return err
}
r.libimageRuntime = libimageRuntime
+ // Run the libimage events routine.
+ r.libimageEvents()
return nil
}