diff options
-rw-r--r-- | Makefile | 18 | ||||
-rw-r--r-- | cmd/podman/events.go | 2 | ||||
-rw-r--r-- | cmd/podman/varlink.go | 4 | ||||
-rwxr-xr-x | contrib/cirrus/setup_environment.sh | 2 | ||||
-rwxr-xr-x | hack/systemd_tag.sh | 4 | ||||
-rw-r--r-- | libpod.conf | 12 | ||||
-rw-r--r-- | libpod/events/events.go | 4 | ||||
-rw-r--r-- | libpod/events/events_linux.go | 8 | ||||
-rw-r--r-- | libpod/events/journal_linux.go | 10 | ||||
-rw-r--r-- | libpod/events/journal_unsupported.go | 11 | ||||
-rw-r--r-- | libpod/healthcheck_linux.go | 11 | ||||
-rw-r--r-- | libpod/runtime.go | 2 | ||||
-rw-r--r-- | libpod/runtime_pod_linux.go | 10 | ||||
-rw-r--r-- | test/e2e/checkpoint_test.go | 10 | ||||
-rw-r--r-- | vendor.conf | 2 | ||||
-rw-r--r-- | vendor/github.com/containerd/cgroups/cgroup.go | 45 | ||||
-rw-r--r-- | vendor/github.com/containerd/cgroups/opts.go | 61 | ||||
-rw-r--r-- | vendor/github.com/containerd/cgroups/paths.go | 5 |
18 files changed, 199 insertions, 22 deletions
@@ -18,7 +18,23 @@ SHAREDIR_CONTAINERS ?= ${PREFIX}/share/containers ETCDIR ?= ${DESTDIR}/etc TMPFILESDIR ?= ${PREFIX}/lib/tmpfiles.d SYSTEMDDIR ?= ${PREFIX}/lib/systemd/system -BUILDTAGS ?= seccomp $(shell hack/btrfs_tag.sh) $(shell hack/btrfs_installed_tag.sh) $(shell hack/ostree_tag.sh) $(shell hack/selinux_tag.sh) $(shell hack/apparmor_tag.sh) varlink exclude_graphdriver_devicemapper +BUILDTAGS ?= \ + $(shell hack/apparmor_tag.sh) \ + $(shell hack/btrfs_installed_tag.sh) \ + $(shell hack/btrfs_tag.sh) \ + $(shell hack/ostree_tag.sh) \ + $(shell hack/selinux_tag.sh) \ + $(shell hack/systemd_tag.sh) \ + exclude_graphdriver_devicemapper \ + seccomp \ + varlink + +ifeq (,$(findstring systemd,$(BUILDTAGS))) +$(warning \ + Podman is being compiled without the systemd build tag.\ + Install libsystemd for journald support) +endif + BUILDTAGS_CROSS ?= containers_image_openpgp containers_image_ostree_stub exclude_graphdriver_btrfs exclude_graphdriver_devicemapper exclude_graphdriver_overlay ifneq (,$(findstring varlink,$(BUILDTAGS))) PODMAN_VARLINK_DEPENDENCIES = cmd/podman/varlink/iopodman.go diff --git a/cmd/podman/events.go b/cmd/podman/events.go index 15f5e9571..88c1010e3 100644 --- a/cmd/podman/events.go +++ b/cmd/podman/events.go @@ -13,7 +13,7 @@ var ( _eventsCommand = &cobra.Command{ Use: "events", Args: noSubArgs, - Short: "show podman events", + Short: "Show podman events", Long: eventsDescription, RunE: func(cmd *cobra.Command, args []string) error { eventsCommand.InputArgs = args diff --git a/cmd/podman/varlink.go b/cmd/podman/varlink.go index 215542d2c..698a30d84 100644 --- a/cmd/podman/varlink.go +++ b/cmd/podman/varlink.go @@ -29,7 +29,7 @@ var ( Tools speaking varlink protocol can remotely manage pods, containers and images. ` _varlinkCommand = &cobra.Command{ - Use: "varlink [flags] URI", + Use: "varlink [flags] [URI]", Short: "Run varlink interface", Long: varlinkDescription, RunE: func(cmd *cobra.Command, args []string) error { @@ -68,7 +68,7 @@ func varlinkCmd(c *cliconfig.VarlinkValues) error { args := c.InputArgs if len(args) > 1 { - return errors.Errorf("too many arguments. you may optionally provide 1") + return errors.Errorf("too many arguments. You may optionally provide 1") } if len(args) > 0 { diff --git a/contrib/cirrus/setup_environment.sh b/contrib/cirrus/setup_environment.sh index 30bca9af2..4dbd56ed9 100755 --- a/contrib/cirrus/setup_environment.sh +++ b/contrib/cirrus/setup_environment.sh @@ -56,6 +56,8 @@ then CON_SEL="https://kojipkgs.fedoraproject.org/packages/container-selinux/2.100/1.git3b78187.fc29/noarch/container-selinux-2.100-1.git3b78187.fc29.noarch.rpm" echo ">>>>> OVERRIDING container-selinux WITH $CON_SEL <<<<<" dnf -y install $CON_SEL + echo ">>>>> OVERRIDING criu and selinux-policy with latest package <<<<<" + dnf -y upgrade criu selinux-policy ;& # Continue to the next item fedora-28) echo ">>>>> OVERRIDING source-built runc with latest package <<<<<" diff --git a/hack/systemd_tag.sh b/hack/systemd_tag.sh new file mode 100755 index 000000000..c59cad559 --- /dev/null +++ b/hack/systemd_tag.sh @@ -0,0 +1,4 @@ +#!/usr/bin/env bash +if pkg-config --exists libsystemd; then + echo systemd +fi diff --git a/libpod.conf b/libpod.conf index ca8d0fb36..ce6b95cda 100644 --- a/libpod.conf +++ b/libpod.conf @@ -99,6 +99,10 @@ num_locks = 2048 # Uncomment to change location from this default. #volume_path = "/var/lib/containers/storage/volumes" +# Selects which logging mechanism to use for Podman events. Valid values +# are `journald` or `file`. +# events_logger = "journald" + # Default OCI runtime runtime = "runc" @@ -114,6 +118,8 @@ runc = [ "/usr/lib/cri-o-runc/sbin/runc" ] -# Selects which logging mechanism to use for Podman events. Valid values -# are `journald` or `file`. -events_logger = "journald" +# The [runtimes] table MUST be the last thing in this file. +# (Unless another table is added) +# TOML does not provide a way to end a table other than a further table being +# defined, so every key hereafter will be part of [runtimes] and not the main +# config. diff --git a/libpod/events/events.go b/libpod/events/events.go index 650a47bfb..1ec79bcd7 100644 --- a/libpod/events/events.go +++ b/libpod/events/events.go @@ -10,6 +10,10 @@ import ( "github.com/pkg/errors" ) +// ErrNoJournaldLogging indicates that there is no journald logging +// supported (requires libsystemd) +var ErrNoJournaldLogging = errors.New("No support for journald logging") + // String returns a string representation of EventerType func (et EventerType) String() string { if et == LogFile { diff --git a/libpod/events/events_linux.go b/libpod/events/events_linux.go index da5d7965e..11f309574 100644 --- a/libpod/events/events_linux.go +++ b/libpod/events/events_linux.go @@ -8,12 +8,14 @@ import ( ) // NewEventer creates an eventer based on the eventer type -func NewEventer(options EventerOptions) (Eventer, error) { - var eventer Eventer +func NewEventer(options EventerOptions) (eventer Eventer, err error) { logrus.Debugf("Initializing event backend %s", options.EventerType) switch strings.ToUpper(options.EventerType) { case strings.ToUpper(Journald.String()): - eventer = EventJournalD{options} + eventer, err = newEventJournalD(options) + if err != nil { + return nil, errors.Wrapf(err, "eventer creation") + } case strings.ToUpper(LogFile.String()): eventer = EventLogFile{options} default: diff --git a/libpod/events/journal_linux.go b/libpod/events/journal_linux.go index 8ba5bc2c7..78a630e9a 100644 --- a/libpod/events/journal_linux.go +++ b/libpod/events/journal_linux.go @@ -1,3 +1,5 @@ +// +build systemd + package events import ( @@ -10,11 +12,19 @@ import ( "github.com/sirupsen/logrus" ) +// DefaultEventerType is journald when systemd is available +const DefaultEventerType = Journald + // EventJournalD is the journald implementation of an eventer type EventJournalD struct { options EventerOptions } +// newEventJournalD creates a new journald Eventer +func newEventJournalD(options EventerOptions) (Eventer, error) { + return EventJournalD{options}, nil +} + // Write to journald func (e EventJournalD) Write(ee Event) error { m := make(map[string]string) diff --git a/libpod/events/journal_unsupported.go b/libpod/events/journal_unsupported.go new file mode 100644 index 000000000..004efdab2 --- /dev/null +++ b/libpod/events/journal_unsupported.go @@ -0,0 +1,11 @@ +// +build !systemd + +package events + +// DefaultEventerType is logfile when systemd is not present +const DefaultEventerType = LogFile + +// newEventJournalD always returns an error if libsystemd not found +func newEventJournalD(options EventerOptions) (Eventer, error) { + return nil, ErrNoJournaldLogging +} diff --git a/libpod/healthcheck_linux.go b/libpod/healthcheck_linux.go index 869605ea8..d47a3b7cd 100644 --- a/libpod/healthcheck_linux.go +++ b/libpod/healthcheck_linux.go @@ -4,6 +4,7 @@ import ( "fmt" "os" "os/exec" + "strings" "github.com/coreos/go-systemd/dbus" "github.com/pkg/errors" @@ -61,7 +62,13 @@ func (c *Container) removeTimer() error { return errors.Wrapf(err, "unable to get systemd connection to remove healthchecks") } defer conn.Close() - serviceFile := fmt.Sprintf("%s.timer", c.ID()) - _, err = conn.StopUnit(serviceFile, "fail", nil) + timerFile := fmt.Sprintf("%s.timer", c.ID()) + _, err = conn.StopUnit(timerFile, "fail", nil) + + // We want to ignore errors where the timer unit has already been removed. The error + // return is generic so we have to check against the string in the error + if err != nil && strings.HasSuffix(err.Error(), ".timer not loaded.") { + return nil + } return err } diff --git a/libpod/runtime.go b/libpod/runtime.go index e6b84014e..18e9dfeb3 100644 --- a/libpod/runtime.go +++ b/libpod/runtime.go @@ -304,7 +304,7 @@ func defaultRuntimeConfig() (RuntimeConfig, error) { EnablePortReservation: true, EnableLabeling: true, NumLocks: 2048, - EventsLogger: "journald", + EventsLogger: events.DefaultEventerType.String(), }, nil } diff --git a/libpod/runtime_pod_linux.go b/libpod/runtime_pod_linux.go index 456ad365f..124d0daf8 100644 --- a/libpod/runtime_pod_linux.go +++ b/libpod/runtime_pod_linux.go @@ -308,5 +308,15 @@ func (r *Runtime) removePod(ctx context.Context, p *Pod, removeCtrs, force bool) // Mark pod invalid p.valid = false p.newPodEvent(events.Remove) + + // Deallocate the pod lock + if err := p.lock.Free(); err != nil { + if removalErr == nil { + removalErr = errors.Wrapf(err, "error freeing pod %s lock", p.ID()) + } else { + logrus.Errorf("Error freeing pod %s lock: %v", p.ID(), err) + } + } + return removalErr } diff --git a/test/e2e/checkpoint_test.go b/test/e2e/checkpoint_test.go index 5b549755e..c2f5a592c 100644 --- a/test/e2e/checkpoint_test.go +++ b/test/e2e/checkpoint_test.go @@ -21,6 +21,7 @@ var _ = Describe("Podman checkpoint", func() { ) BeforeEach(func() { + SkipIfRootless() tempdir, err = CreateTempDirInTempDir() if err != nil { os.Exit(1) @@ -41,11 +42,12 @@ var _ = Describe("Podman checkpoint", func() { if !criu.CheckForCriu() { Skip("CRIU is missing or too old.") } - // TODO: Remove the skip when the current CRIU SELinux problem is solved. - // See: https://github.com/containers/libpod/issues/2334 + // Only Fedora 29 and newer has a new enough selinux-policy and + // container-selinux package to support CRIU in correctly + // restoring threaded processes hostInfo := podmanTest.Host - if hostInfo.Distribution == "fedora" { - Skip("Checkpointing containers on Fedora currently broken.") + if hostInfo.Distribution == "fedora" && hostInfo.Version < "29" { + Skip("Checkpoint/Restore with SELinux only works on Fedora >= 29") } }) diff --git a/vendor.conf b/vendor.conf index 2f7e36d85..b71e947dc 100644 --- a/vendor.conf +++ b/vendor.conf @@ -11,7 +11,7 @@ github.com/boltdb/bolt v1.3.1 # TODO: no release, can we find an alternative? github.com/buger/goterm c206103e1f37c0c6c5c039706305ea2aa6e8ad3b github.com/checkpoint-restore/go-criu v3.11 -github.com/containerd/cgroups 39b18af02c4120960f517a3a4c2588fabb61d02c +github.com/containerd/cgroups 4994991857f9b0ae8dc439551e8bebdbb4bf66c1 github.com/containerd/continuity 004b46473808b3e7a4a3049c20e4376c91eb966d github.com/containernetworking/cni v0.7.0-rc2 github.com/containernetworking/plugins v0.7.4 diff --git a/vendor/github.com/containerd/cgroups/cgroup.go b/vendor/github.com/containerd/cgroups/cgroup.go index 03fcb9284..e3ef07651 100644 --- a/vendor/github.com/containerd/cgroups/cgroup.go +++ b/vendor/github.com/containerd/cgroups/cgroup.go @@ -30,24 +30,49 @@ import ( ) // New returns a new control via the cgroup cgroups interface -func New(hierarchy Hierarchy, path Path, resources *specs.LinuxResources) (Cgroup, error) { +func New(hierarchy Hierarchy, path Path, resources *specs.LinuxResources, opts ...InitOpts) (Cgroup, error) { + config := newInitConfig() + for _, o := range opts { + if err := o(config); err != nil { + return nil, err + } + } subsystems, err := hierarchy() if err != nil { return nil, err } + var active []Subsystem for _, s := range subsystems { + // check if subsystem exists if err := initializeSubsystem(s, path, resources); err != nil { + if err == ErrControllerNotActive { + if config.InitCheck != nil { + if skerr := config.InitCheck(s, path, err); skerr != nil { + if skerr != ErrIgnoreSubsystem { + return nil, skerr + } + } + } + continue + } return nil, err } + active = append(active, s) } return &cgroup{ path: path, - subsystems: subsystems, + subsystems: active, }, nil } // Load will load an existing cgroup and allow it to be controlled -func Load(hierarchy Hierarchy, path Path) (Cgroup, error) { +func Load(hierarchy Hierarchy, path Path, opts ...InitOpts) (Cgroup, error) { + config := newInitConfig() + for _, o := range opts { + if err := o(config); err != nil { + return nil, err + } + } var activeSubsystems []Subsystem subsystems, err := hierarchy() if err != nil { @@ -60,6 +85,16 @@ func Load(hierarchy Hierarchy, path Path) (Cgroup, error) { if os.IsNotExist(errors.Cause(err)) { return nil, ErrCgroupDeleted } + if err == ErrControllerNotActive { + if config.InitCheck != nil { + if skerr := config.InitCheck(s, path, err); skerr != nil { + if skerr != ErrIgnoreSubsystem { + return nil, skerr + } + } + } + continue + } return nil, err } if _, err := os.Lstat(s.Path(p)); err != nil { @@ -70,6 +105,10 @@ func Load(hierarchy Hierarchy, path Path) (Cgroup, error) { } activeSubsystems = append(activeSubsystems, s) } + // if we do not have any active systems then the cgroup is deleted + if len(activeSubsystems) == 0 { + return nil, ErrCgroupDeleted + } return &cgroup{ path: path, subsystems: activeSubsystems, diff --git a/vendor/github.com/containerd/cgroups/opts.go b/vendor/github.com/containerd/cgroups/opts.go new file mode 100644 index 000000000..7c5d9fb9c --- /dev/null +++ b/vendor/github.com/containerd/cgroups/opts.go @@ -0,0 +1,61 @@ +/* + Copyright The containerd Authors. + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +*/ + +package cgroups + +import ( + "github.com/pkg/errors" +) + +var ( + // ErrIgnoreSubsystem allows the specific subsystem to be skipped + ErrIgnoreSubsystem = errors.New("skip subsystem") + // ErrDevicesRequired is returned when the devices subsystem is required but + // does not exist or is not active + ErrDevicesRequired = errors.New("devices subsystem is required") +) + +// InitOpts allows configuration for the creation or loading of a cgroup +type InitOpts func(*InitConfig) error + +// InitConfig provides configuration options for the creation +// or loading of a cgroup and its subsystems +type InitConfig struct { + // InitCheck can be used to check initialization errors from the subsystem + InitCheck InitCheck +} + +func newInitConfig() *InitConfig { + return &InitConfig{ + InitCheck: RequireDevices, + } +} + +// InitCheck allows subsystems errors to be checked when initialized or loaded +type InitCheck func(Subsystem, Path, error) error + +// AllowAny allows any subsystem errors to be skipped +func AllowAny(s Subsystem, p Path, err error) error { + return ErrIgnoreSubsystem +} + +// RequireDevices requires the device subsystem but no others +func RequireDevices(s Subsystem, p Path, err error) error { + if s.Name() == Devices { + return ErrDevicesRequired + } + return ErrIgnoreSubsystem +} diff --git a/vendor/github.com/containerd/cgroups/paths.go b/vendor/github.com/containerd/cgroups/paths.go index 455ce857f..f45fd4256 100644 --- a/vendor/github.com/containerd/cgroups/paths.go +++ b/vendor/github.com/containerd/cgroups/paths.go @@ -57,6 +57,9 @@ func PidPath(pid int) Path { return existingPath(paths, "") } +// ErrControllerNotActive is returned when a controller is not supported or enabled +var ErrControllerNotActive = errors.New("controller is not supported") + func existingPath(paths map[string]string, suffix string) Path { // localize the paths based on the root mount dest for nested cgroups for n, p := range paths { @@ -77,7 +80,7 @@ func existingPath(paths map[string]string, suffix string) Path { root, ok := paths[string(name)] if !ok { if root, ok = paths[fmt.Sprintf("name=%s", name)]; !ok { - return "", fmt.Errorf("unable to find %q in controller set", name) + return "", ErrControllerNotActive } } if suffix != "" { |