summaryrefslogtreecommitdiff
path: root/libpod
diff options
context:
space:
mode:
Diffstat (limited to 'libpod')
-rw-r--r--libpod/container_internal_linux.go2
-rw-r--r--libpod/events.go10
-rw-r--r--libpod/events/config.go9
-rw-r--r--libpod/events/events.go15
-rw-r--r--libpod/events/events_linux.go5
-rw-r--r--libpod/events/journal_linux.go7
-rw-r--r--libpod/events/logfile.go8
-rw-r--r--libpod/options.go30
-rw-r--r--libpod/runtime.go49
-rw-r--r--libpod/runtime_migrate.go47
-rw-r--r--libpod/runtime_renumber.go3
11 files changed, 167 insertions, 18 deletions
diff --git a/libpod/container_internal_linux.go b/libpod/container_internal_linux.go
index f352b188e..c5e404155 100644
--- a/libpod/container_internal_linux.go
+++ b/libpod/container_internal_linux.go
@@ -420,7 +420,7 @@ func (c *Container) generateSpec(ctx context.Context) (*spec.Spec, error) {
// It also expects to be able to write to /sys/fs/cgroup/systemd and /var/log/journal
func (c *Container) setupSystemd(mounts []spec.Mount, g generate.Generator) error {
options := []string{"rw", "rprivate", "noexec", "nosuid", "nodev"}
- for _, dest := range []string{"/run", "/run/lock"} {
+ for _, dest := range []string{"/run"} {
if MountExists(mounts, dest) {
continue
}
diff --git a/libpod/events.go b/libpod/events.go
index 1b5c3bd99..13bb5bdde 100644
--- a/libpod/events.go
+++ b/libpod/events.go
@@ -50,6 +50,16 @@ func (p *Pod) newPodEvent(status events.Status) {
}
}
+// newSystemEvent creates a new event for libpod as a whole.
+func (r *Runtime) newSystemEvent(status events.Status) {
+ e := events.NewEvent(status)
+ e.Type = events.System
+
+ if err := r.eventer.Write(e); err != nil {
+ logrus.Errorf("unable to write system event: %q", err)
+ }
+}
+
// newVolumeEvent creates a new event for a libpod volume
func (v *Volume) newVolumeEvent(status events.Status) {
e := events.NewEvent(status)
diff --git a/libpod/events/config.go b/libpod/events/config.go
index d3b6d8c50..36387e835 100644
--- a/libpod/events/config.go
+++ b/libpod/events/config.go
@@ -84,6 +84,9 @@ const (
Image Type = "image"
// Pod - event is related to pods
Pod Type = "pod"
+ // System - event is related to Podman whole and not to any specific
+ // container/pod/image/volume
+ System Type = "system"
// Volume - event is related to volumes
Volume Type = "volume"
@@ -123,8 +126,14 @@ const (
Pull Status = "pull"
// Push ...
Push Status = "push"
+ // Refresh indicates that the system refreshed the state after a
+ // reboot.
+ Refresh Status = "refresh"
// Remove ...
Remove Status = "remove"
+ // Renumber indicates that lock numbers were reallocated at user
+ // request.
+ Renumber Status = "renumber"
// Restore ...
Restore Status = "restore"
// Save ...
diff --git a/libpod/events/events.go b/libpod/events/events.go
index e8c61faa0..202c9db4e 100644
--- a/libpod/events/events.go
+++ b/libpod/events/events.go
@@ -49,6 +49,8 @@ func (e *Event) ToHumanReadable() string {
humanFormat = fmt.Sprintf("%s %s %s %s (image=%s, name=%s)", e.Time, e.Type, e.Status, e.ID, e.Image, e.Name)
case Image:
humanFormat = fmt.Sprintf("%s %s %s %s %s", e.Time, e.Type, e.Status, e.ID, e.Name)
+ case System:
+ humanFormat = fmt.Sprintf("%s %s %s", e.Time, e.Type, e.Status)
case Volume:
humanFormat = fmt.Sprintf("%s %s %s %s", e.Time, e.Type, e.Status, e.Name)
}
@@ -85,10 +87,12 @@ func StringToType(name string) (Type, error) {
return Image, nil
case Pod.String():
return Pod, nil
+ case System.String():
+ return System, nil
case Volume.String():
return Volume, nil
}
- return "", errors.Errorf("unknown event type %s", name)
+ return "", errors.Errorf("unknown event type %q", name)
}
// StringToStatus converts a string to an Event Status
@@ -107,7 +111,6 @@ func StringToStatus(name string) (Status, error) {
case Commit.String():
return Commit, nil
case Create.String():
-
return Create, nil
case Exec.String():
return Exec, nil
@@ -135,8 +138,14 @@ func StringToStatus(name string) (Status, error) {
return Pull, nil
case Push.String():
return Push, nil
+ case Refresh.String():
+ return Refresh, nil
case Remove.String():
return Remove, nil
+ case Renumber.String():
+ return Renumber, nil
+ case Restore.String():
+ return Restore, nil
case Save.String():
return Save, nil
case Start.String():
@@ -154,7 +163,7 @@ func StringToStatus(name string) (Status, error) {
case Untag.String():
return Untag, nil
}
- return "", errors.Errorf("unknown event status %s", name)
+ return "", errors.Errorf("unknown event status %q", name)
}
func (e EventLogFile) getTail(options ReadOptions) (*tail.Tail, error) {
diff --git a/libpod/events/events_linux.go b/libpod/events/events_linux.go
index d6898145c..da5d7965e 100644
--- a/libpod/events/events_linux.go
+++ b/libpod/events/events_linux.go
@@ -1,13 +1,16 @@
package events
import (
- "github.com/pkg/errors"
"strings"
+
+ "github.com/pkg/errors"
+ "github.com/sirupsen/logrus"
)
// NewEventer creates an eventer based on the eventer type
func NewEventer(options EventerOptions) (Eventer, error) {
var eventer Eventer
+ logrus.Debugf("Initializing event backend %s", options.EventerType)
switch strings.ToUpper(options.EventerType) {
case strings.ToUpper(Journald.String()):
eventer = EventJournalD{options}
diff --git a/libpod/events/journal_linux.go b/libpod/events/journal_linux.go
index e6b54db1d..8ba5bc2c7 100644
--- a/libpod/events/journal_linux.go
+++ b/libpod/events/journal_linux.go
@@ -7,6 +7,7 @@ import (
"github.com/coreos/go-systemd/journal"
"github.com/coreos/go-systemd/sdjournal"
"github.com/pkg/errors"
+ "github.com/sirupsen/logrus"
)
// EventJournalD is the journald implementation of an eventer
@@ -87,7 +88,11 @@ func (e EventJournalD) Read(options ReadOptions) error {
}
newEvent, err := newEventFromJournalEntry(entry)
if err != nil {
- return err
+ // We can't decode this event.
+ // Don't fail hard - that would make events unusable.
+ // Instead, log and continue.
+ logrus.Errorf("Unable to decode event: %v", err)
+ continue
}
include := true
for _, filter := range eventOptions {
diff --git a/libpod/events/logfile.go b/libpod/events/logfile.go
index 3232b86d0..e5efc09bb 100644
--- a/libpod/events/logfile.go
+++ b/libpod/events/logfile.go
@@ -4,6 +4,7 @@ import (
"fmt"
"os"
+ "github.com/containers/storage"
"github.com/pkg/errors"
)
@@ -15,6 +16,13 @@ type EventLogFile struct {
// Writes to the log file
func (e EventLogFile) Write(ee Event) error {
+ // We need to lock events file
+ lock, err := storage.GetLockfile(e.options.LogFilePath + ".lock")
+ if err != nil {
+ return err
+ }
+ lock.Lock()
+ defer lock.Unlock()
f, err := os.OpenFile(e.options.LogFilePath, os.O_APPEND|os.O_CREATE|os.O_WRONLY, 0700)
if err != nil {
return err
diff --git a/libpod/options.go b/libpod/options.go
index 8038f1935..9932d5453 100644
--- a/libpod/options.go
+++ b/libpod/options.go
@@ -1,6 +1,7 @@
package libpod
import (
+ "context"
"net"
"os"
"path/filepath"
@@ -436,6 +437,22 @@ func WithRenumber() RuntimeOption {
}
}
+// WithMigrate instructs libpod to perform a lock migrateing while
+// initializing. This will handle migrations from early versions of libpod with
+// file locks to newer versions with SHM locking, as well as changes in the
+// number of configured locks.
+func WithMigrate() RuntimeOption {
+ return func(rt *Runtime) error {
+ if rt.valid {
+ return ErrRuntimeFinalized
+ }
+
+ rt.doMigrate = true
+
+ return nil
+ }
+}
+
// Container Creation Options
// WithShmDir sets the directory that should be mounted on /dev/shm.
@@ -450,6 +467,19 @@ func WithShmDir(dir string) CtrCreateOption {
}
}
+// WithContext sets the context to use.
+func WithContext(ctx context.Context) RuntimeOption {
+ return func(rt *Runtime) error {
+ if rt.valid {
+ return ErrRuntimeFinalized
+ }
+
+ rt.ctx = ctx
+
+ return nil
+ }
+}
+
// WithSystemd turns on systemd mode in the container
func WithSystemd() CtrCreateOption {
return func(ctr *Container) error {
diff --git a/libpod/runtime.go b/libpod/runtime.go
index d03731284..e85242028 100644
--- a/libpod/runtime.go
+++ b/libpod/runtime.go
@@ -1,8 +1,8 @@
package libpod
import (
+ "context"
"fmt"
- "github.com/containers/libpod/libpod/events"
"io/ioutil"
"os"
"path/filepath"
@@ -12,6 +12,7 @@ import (
"github.com/BurntSushi/toml"
is "github.com/containers/image/storage"
"github.com/containers/image/types"
+ "github.com/containers/libpod/libpod/events"
"github.com/containers/libpod/libpod/image"
"github.com/containers/libpod/libpod/lock"
"github.com/containers/libpod/pkg/firewall"
@@ -100,6 +101,8 @@ type Runtime struct {
// unused.
doRenumber bool
+ doMigrate bool
+
// valid indicates whether the runtime is ready to use.
// valid is set to true when a runtime is returned from GetRuntime(),
// and remains true until the runtime is shut down (rendering its
@@ -109,6 +112,8 @@ type Runtime struct {
// mechanism to read and write even logs
eventer events.Eventer
+
+ ctx context.Context
}
// OCIRuntimePath contains information about an OCI runtime.
@@ -754,6 +759,17 @@ func makeRuntime(runtime *Runtime) (err error) {
if err != nil {
return err
}
+
+ defer func() {
+ if err != nil && store != nil {
+ // Don't forcibly shut down
+ // We could be opening a store in use by another libpod
+ _, err2 := store.Shutdown(false)
+ if err2 != nil {
+ logrus.Errorf("Error removing store for partially-created runtime: %s", err2)
+ }
+ }
+ }()
}
runtime.store = store
@@ -780,17 +796,6 @@ func makeRuntime(runtime *Runtime) (err error) {
runtime.eventer = eventer
ir.Eventer = eventer
- defer func() {
- if err != nil && store != nil {
- // Don't forcibly shut down
- // We could be opening a store in use by another libpod
- _, err2 := store.Shutdown(false)
- if err2 != nil {
- logrus.Errorf("Error removing store for partially-created runtime: %s", err2)
- }
- }
- }()
-
// Set up a storage service for creating container root filesystems from
// images
storageService, err := getStorageService(runtime.store)
@@ -962,6 +967,24 @@ func makeRuntime(runtime *Runtime) (err error) {
// further
runtime.valid = true
+ if runtime.doMigrate {
+ if os.Geteuid() != 0 {
+ aliveLock.Unlock()
+ locked = false
+
+ became, ret, err := rootless.BecomeRootInUserNS()
+ if err != nil {
+ return err
+ }
+ if became {
+ os.Exit(ret)
+ }
+ }
+ if err := runtime.migrate(); err != nil {
+ return err
+ }
+ }
+
return nil
}
@@ -1074,6 +1097,8 @@ func (r *Runtime) refresh(alivePath string) error {
}
defer file.Close()
+ r.newSystemEvent(events.Refresh)
+
return nil
}
diff --git a/libpod/runtime_migrate.go b/libpod/runtime_migrate.go
new file mode 100644
index 000000000..a084df289
--- /dev/null
+++ b/libpod/runtime_migrate.go
@@ -0,0 +1,47 @@
+package libpod
+
+import (
+ "path/filepath"
+
+ "github.com/pkg/errors"
+ "github.com/sirupsen/logrus"
+)
+
+func (r *Runtime) migrate() error {
+ runningContainers, err := r.GetRunningContainers()
+ if err != nil {
+ return err
+ }
+
+ allCtrs, err := r.state.AllContainers()
+ if err != nil {
+ return err
+ }
+
+ logrus.Infof("stopping all containers")
+ for _, ctr := range runningContainers {
+ logrus.Infof("stopping %s", ctr.ID())
+ if err := ctr.Stop(); err != nil {
+ return errors.Wrapf(err, "cannot stop container %s", ctr.ID())
+ }
+ }
+
+ for _, ctr := range allCtrs {
+ oldLocation := filepath.Join(ctr.state.RunDir, "conmon.pid")
+ if ctr.config.ConmonPidFile == oldLocation {
+ logrus.Infof("changing conmon PID file for %s", ctr.ID())
+ ctr.config.ConmonPidFile = filepath.Join(ctr.config.StaticDir, "conmon.pid")
+ if err := r.state.RewriteContainerConfig(ctr, ctr.config); err != nil {
+ return errors.Wrapf(err, "error rewriting config for container %s", ctr.ID())
+ }
+ }
+ }
+
+ for _, ctr := range runningContainers {
+ if err := ctr.Start(r.ctx, true); err != nil {
+ logrus.Errorf("error restarting container %s", ctr.ID())
+ }
+ }
+
+ return nil
+}
diff --git a/libpod/runtime_renumber.go b/libpod/runtime_renumber.go
index 125cf0825..735ffba34 100644
--- a/libpod/runtime_renumber.go
+++ b/libpod/runtime_renumber.go
@@ -1,6 +1,7 @@
package libpod
import (
+ "github.com/containers/libpod/libpod/events"
"github.com/pkg/errors"
)
@@ -53,5 +54,7 @@ func (r *Runtime) renumberLocks() error {
}
}
+ r.newSystemEvent(events.Renumber)
+
return nil
}