diff options
Diffstat (limited to 'pkg')
-rw-r--r-- | pkg/adapter/containers.go | 9 | ||||
-rw-r--r-- | pkg/cgroups/blkio.go | 2 | ||||
-rw-r--r-- | pkg/cgroups/cgroups.go | 52 | ||||
-rw-r--r-- | pkg/cgroups/cpu.go | 17 | ||||
-rw-r--r-- | pkg/cgroups/cpuset.go | 19 | ||||
-rw-r--r-- | pkg/cgroups/memory.go | 2 | ||||
-rw-r--r-- | pkg/cgroups/pids.go | 3 | ||||
-rw-r--r-- | pkg/hooks/0.1.0/hook.go | 2 | ||||
-rw-r--r-- | pkg/hooks/1.0.0/when_test.go | 2 | ||||
-rw-r--r-- | pkg/logs/logs.go | 2 | ||||
-rw-r--r-- | pkg/rootless/rootless_linux.go | 4 | ||||
-rw-r--r-- | pkg/sysinfo/sysinfo_test.go | 2 | ||||
-rw-r--r-- | pkg/systemdgen/systemdgen.go | 28 | ||||
-rw-r--r-- | pkg/systemdgen/systemdgen_test.go | 18 | ||||
-rw-r--r-- | pkg/tracing/tracing.go | 6 | ||||
-rw-r--r-- | pkg/trust/trust.go | 2 |
16 files changed, 129 insertions, 41 deletions
diff --git a/pkg/adapter/containers.go b/pkg/adapter/containers.go index 10720886b..0ea89a72c 100644 --- a/pkg/adapter/containers.go +++ b/pkg/adapter/containers.go @@ -1058,7 +1058,14 @@ func (r *LocalRuntime) GenerateSystemd(c *cliconfig.GenerateSystemdValues) (stri if c.Name { name = ctr.Name() } - return systemdgen.CreateSystemdUnitAsString(name, ctr.ID(), c.RestartPolicy, ctr.Config().StaticDir, timeout) + + config := ctr.Config() + conmonPidFile := config.ConmonPidFile + if conmonPidFile == "" { + return "", errors.Errorf("conmon PID file path is empty, try to recreate the container with --conmon-pidfile flag") + } + + return systemdgen.CreateSystemdUnitAsString(name, ctr.ID(), c.RestartPolicy, conmonPidFile, timeout) } // GetNamespaces returns namespace information about a container for PS diff --git a/pkg/cgroups/blkio.go b/pkg/cgroups/blkio.go index ca9107d97..9c2a811d9 100644 --- a/pkg/cgroups/blkio.go +++ b/pkg/cgroups/blkio.go @@ -30,7 +30,7 @@ func (c *blkioHandler) Apply(ctr *CgroupControl, res *spec.LinuxResources) error // Create the cgroup func (c *blkioHandler) Create(ctr *CgroupControl) (bool, error) { if ctr.cgroup2 { - return false, fmt.Errorf("io create not implemented for cgroup v2") + return false, nil } return ctr.createCgroupDirectory(Blkio) } diff --git a/pkg/cgroups/cgroups.go b/pkg/cgroups/cgroups.go index d6c19212b..1dad45d7f 100644 --- a/pkg/cgroups/cgroups.go +++ b/pkg/cgroups/cgroups.go @@ -149,6 +149,51 @@ func (c *CgroupControl) getCgroupv1Path(name string) string { return filepath.Join(cgroupRoot, name, c.path) } +// createCgroupv2Path creates the cgroupv2 path and enables all the available controllers +func createCgroupv2Path(path string) (Err error) { + content, err := ioutil.ReadFile("/sys/fs/cgroup/cgroup.controllers") + if err != nil { + return errors.Wrapf(err, "read /sys/fs/cgroup/cgroup.controllers") + } + if !filepath.HasPrefix(path, "/sys/fs/cgroup") { + return fmt.Errorf("invalid cgroup path %s", path) + } + + res := "" + for i, c := range strings.Split(strings.TrimSpace(string(content)), " ") { + if i == 0 { + res = fmt.Sprintf("+%s", c) + } else { + res = res + fmt.Sprintf(" +%s", c) + } + } + resByte := []byte(res) + + current := "/sys/fs" + elements := strings.Split(path, "/") + for i, e := range elements[3:] { + current = filepath.Join(current, e) + if i > 0 { + if err := os.Mkdir(current, 0755); err != nil { + if !os.IsExist(err) { + return errors.Wrapf(err, "mkdir %s", path) + } + } else { + // If the directory was created, be sure it is not left around on errors. + defer func() { + if Err != nil { + os.Remove(current) + } + }() + } + } + if err := ioutil.WriteFile(filepath.Join(current, "cgroup.subtree_control"), resByte, 0755); err != nil { + return errors.Wrapf(err, "write %s", filepath.Join(current, "cgroup.subtree_control")) + } + } + return nil +} + // initialize initializes the specified hierarchy func (c *CgroupControl) initialize() (err error) { createdSoFar := map[string]controllerHandler{} @@ -161,6 +206,11 @@ func (c *CgroupControl) initialize() (err error) { } } }() + if c.cgroup2 { + if err := createCgroupv2Path(filepath.Join(cgroupRoot, c.path)); err != nil { + return errors.Wrapf(err, "error creating cgroup path %s", c.path) + } + } for name, handler := range handlers { created, err := handler.Create(c) if err != nil { @@ -341,7 +391,7 @@ func (c *CgroupControl) AddPid(pid int) error { pidString := []byte(fmt.Sprintf("%d\n", pid)) if c.cgroup2 { - p := filepath.Join(cgroupRoot, c.path, "tasks") + p := filepath.Join(cgroupRoot, c.path, "cgroup.procs") if err := ioutil.WriteFile(p, pidString, 0644); err != nil { return errors.Wrapf(err, "write %s", p) } diff --git a/pkg/cgroups/cpu.go b/pkg/cgroups/cpu.go index 8640d490e..1c8610cc4 100644 --- a/pkg/cgroups/cpu.go +++ b/pkg/cgroups/cpu.go @@ -61,7 +61,7 @@ func (c *cpuHandler) Apply(ctr *CgroupControl, res *spec.LinuxResources) error { // Create the cgroup func (c *cpuHandler) Create(ctr *CgroupControl) (bool, error) { if ctr.cgroup2 { - return false, fmt.Errorf("cpu create not implemented for cgroup v2") + return false, nil } return ctr.createCgroupDirectory(CPU) } @@ -98,15 +98,24 @@ func (c *cpuHandler) Stat(ctr *CgroupControl, m *Metrics) error { } else { usage.Total, err = readAcct(ctr, "cpuacct.usage") if err != nil { - return err + if !os.IsNotExist(errors.Cause(err)) { + return err + } + usage.Total = 0 } usage.Kernel, err = readAcct(ctr, "cpuacct.usage_sys") if err != nil { - return err + if !os.IsNotExist(errors.Cause(err)) { + return err + } + usage.Kernel = 0 } usage.PerCPU, err = readAcctList(ctr, "cpuacct.usage_percpu") if err != nil { - return err + if !os.IsNotExist(errors.Cause(err)) { + return err + } + usage.PerCPU = nil } } m.CPU = CPUMetrics{Usage: usage} diff --git a/pkg/cgroups/cpuset.go b/pkg/cgroups/cpuset.go index 9aef493c9..25d2f7f76 100644 --- a/pkg/cgroups/cpuset.go +++ b/pkg/cgroups/cpuset.go @@ -14,19 +14,23 @@ import ( type cpusetHandler struct { } -func cpusetCopyFileFromParent(dir, file string) ([]byte, error) { +func cpusetCopyFileFromParent(dir, file string, cgroupv2 bool) ([]byte, error) { if dir == cgroupRoot { return nil, fmt.Errorf("could not find parent to initialize cpuset %s", file) } path := filepath.Join(dir, file) - data, err := ioutil.ReadFile(path) + parentPath := path + if cgroupv2 { + parentPath = fmt.Sprintf("%s.effective", parentPath) + } + data, err := ioutil.ReadFile(parentPath) if err != nil { return nil, errors.Wrapf(err, "open %s", path) } if len(strings.Trim(string(data), "\n")) != 0 { return data, nil } - data, err = cpusetCopyFileFromParent(filepath.Dir(dir), file) + data, err = cpusetCopyFileFromParent(filepath.Dir(dir), file, cgroupv2) if err != nil { return nil, err } @@ -36,9 +40,9 @@ func cpusetCopyFileFromParent(dir, file string) ([]byte, error) { return data, nil } -func cpusetCopyFromParent(path string) error { +func cpusetCopyFromParent(path string, cgroupv2 bool) error { for _, file := range []string{"cpuset.cpus", "cpuset.mems"} { - if _, err := cpusetCopyFileFromParent(path, file); err != nil { + if _, err := cpusetCopyFileFromParent(path, file, cgroupv2); err != nil { return err } } @@ -60,14 +64,15 @@ func (c *cpusetHandler) Apply(ctr *CgroupControl, res *spec.LinuxResources) erro // Create the cgroup func (c *cpusetHandler) Create(ctr *CgroupControl) (bool, error) { if ctr.cgroup2 { - return false, fmt.Errorf("cpuset create not implemented for cgroup v2") + path := filepath.Join(cgroupRoot, ctr.path) + return true, cpusetCopyFromParent(path, true) } created, err := ctr.createCgroupDirectory(CPUset) if !created || err != nil { return created, err } - return true, cpusetCopyFromParent(ctr.getCgroupv1Path(CPUset)) + return true, cpusetCopyFromParent(ctr.getCgroupv1Path(CPUset), false) } // Destroy the cgroup diff --git a/pkg/cgroups/memory.go b/pkg/cgroups/memory.go index 0505eac40..80e88d17c 100644 --- a/pkg/cgroups/memory.go +++ b/pkg/cgroups/memory.go @@ -26,7 +26,7 @@ func (c *memHandler) Apply(ctr *CgroupControl, res *spec.LinuxResources) error { // Create the cgroup func (c *memHandler) Create(ctr *CgroupControl) (bool, error) { if ctr.cgroup2 { - return false, fmt.Errorf("memory create not implemented for cgroup v2") + return false, nil } return ctr.createCgroupDirectory(Memory) } diff --git a/pkg/cgroups/pids.go b/pkg/cgroups/pids.go index c90dc1c02..ffbde100d 100644 --- a/pkg/cgroups/pids.go +++ b/pkg/cgroups/pids.go @@ -35,9 +35,6 @@ func (c *pidHandler) Apply(ctr *CgroupControl, res *spec.LinuxResources) error { // Create the cgroup func (c *pidHandler) Create(ctr *CgroupControl) (bool, error) { - if ctr.cgroup2 { - return false, fmt.Errorf("pid create not implemented for cgroup v2") - } return ctr.createCgroupDirectory(Pids) } diff --git a/pkg/hooks/0.1.0/hook.go b/pkg/hooks/0.1.0/hook.go index ba68b0f10..88a387647 100644 --- a/pkg/hooks/0.1.0/hook.go +++ b/pkg/hooks/0.1.0/hook.go @@ -6,7 +6,7 @@ import ( "errors" "strings" - hooks "github.com/containers/libpod/pkg/hooks" + "github.com/containers/libpod/pkg/hooks" current "github.com/containers/libpod/pkg/hooks/1.0.0" rspec "github.com/opencontainers/runtime-spec/specs-go" ) diff --git a/pkg/hooks/1.0.0/when_test.go b/pkg/hooks/1.0.0/when_test.go index 7187b297b..a749063ff 100644 --- a/pkg/hooks/1.0.0/when_test.go +++ b/pkg/hooks/1.0.0/when_test.go @@ -30,7 +30,7 @@ func TestAlways(t *testing.T) { for _, always := range []bool{true, false} { for _, or := range []bool{true, false} { for _, process := range []*rspec.Process{processStruct, nil} { - t.Run(fmt.Sprintf("always %t, or %t, has process %t", always, or, (process != nil)), func(t *testing.T) { + t.Run(fmt.Sprintf("always %t, or %t, has process %t", always, or, process != nil), func(t *testing.T) { config.Process = process when := When{Always: &always, Or: or} match, err := when.Match(config, map[string]string{}, false) diff --git a/pkg/logs/logs.go b/pkg/logs/logs.go index 1f0ede6f0..0f684750e 100644 --- a/pkg/logs/logs.go +++ b/pkg/logs/logs.go @@ -135,7 +135,7 @@ func parseCRILog(log []byte, msg *logMessage) error { } // Keep this forward compatible. tags := bytes.Split(log[:idx], tagDelimiter) - partial := (LogTag(tags[0]) == LogTagPartial) + partial := LogTag(tags[0]) == LogTagPartial // Trim the tailing new line if this is a partial line. if partial && len(log) > 0 && log[len(log)-1] == '\n' { log = log[:len(log)-1] diff --git a/pkg/rootless/rootless_linux.go b/pkg/rootless/rootless_linux.go index f3b9a8fd5..8028a359c 100644 --- a/pkg/rootless/rootless_linux.go +++ b/pkg/rootless/rootless_linux.go @@ -215,7 +215,7 @@ func EnableLinger() (string, error) { // If we have a D-BUS connection, attempt to read the LINGER property from it. if conn != nil { - path := dbus.ObjectPath((fmt.Sprintf("/org/freedesktop/login1/user/_%s", uid))) + path := dbus.ObjectPath(fmt.Sprintf("/org/freedesktop/login1/user/_%s", uid)) ret, err := conn.Object("org.freedesktop.login1", path).GetProperty("org.freedesktop.login1.User.Linger") if err == nil && ret.Value().(bool) { lingerEnabled = true @@ -265,7 +265,7 @@ func EnableLinger() (string, error) { // If we have a D-BUS connection, attempt to read the RUNTIME PATH from it. if conn != nil { - path := dbus.ObjectPath((fmt.Sprintf("/org/freedesktop/login1/user/_%s", uid))) + path := dbus.ObjectPath(fmt.Sprintf("/org/freedesktop/login1/user/_%s", uid)) ret, err := conn.Object("org.freedesktop.login1", path).GetProperty("org.freedesktop.login1.User.RuntimePath") if err == nil { return strings.Trim(ret.String(), "\"\n"), nil diff --git a/pkg/sysinfo/sysinfo_test.go b/pkg/sysinfo/sysinfo_test.go index b61fbcf54..895828f26 100644 --- a/pkg/sysinfo/sysinfo_test.go +++ b/pkg/sysinfo/sysinfo_test.go @@ -20,7 +20,7 @@ func TestIsCpusetListAvailable(t *testing.T) { for _, c := range cases { r, err := isCpusetListAvailable(c.provided, c.available) if (c.err && err == nil) && r != c.res { - t.Fatalf("Expected pair: %v, %v for %s, %s. Got %v, %v instead", c.res, c.err, c.provided, c.available, (c.err && err == nil), r) + t.Fatalf("Expected pair: %v, %v for %s, %s. Got %v, %v instead", c.res, c.err, c.provided, c.available, c.err && err == nil, r) } } } diff --git a/pkg/systemdgen/systemdgen.go b/pkg/systemdgen/systemdgen.go index 3d1c31b5d..06c5ebde5 100644 --- a/pkg/systemdgen/systemdgen.go +++ b/pkg/systemdgen/systemdgen.go @@ -2,17 +2,18 @@ package systemdgen import ( "fmt" - "path/filepath" + "os" "github.com/pkg/errors" + "github.com/sirupsen/logrus" ) var template = `[Unit] Description=%s Podman Container [Service] Restart=%s -ExecStart=/usr/bin/podman start %s -ExecStop=/usr/bin/podman stop -t %d %s +ExecStart=%s start %s +ExecStop=%s stop -t %d %s KillMode=none Type=forking PIDFile=%s @@ -33,11 +34,26 @@ func ValidateRestartPolicy(restart string) error { // CreateSystemdUnitAsString takes variables to create a systemd unit file used to control // a libpod container -func CreateSystemdUnitAsString(name, cid, restart, pidPath string, stopTimeout int) (string, error) { +func CreateSystemdUnitAsString(name, cid, restart, pidFile string, stopTimeout int) (string, error) { + podmanExe := getPodmanExecutable() + return createSystemdUnitAsString(podmanExe, name, cid, restart, pidFile, stopTimeout) +} + +func createSystemdUnitAsString(exe, name, cid, restart, pidFile string, stopTimeout int) (string, error) { if err := ValidateRestartPolicy(restart); err != nil { return "", err } - pidFile := filepath.Join(pidPath, fmt.Sprintf("%s.pid", cid)) - unit := fmt.Sprintf(template, name, restart, name, stopTimeout, name, pidFile) + + unit := fmt.Sprintf(template, name, restart, exe, name, exe, stopTimeout, name, pidFile) return unit, nil } + +func getPodmanExecutable() string { + podmanExe, err := os.Executable() + if err != nil { + podmanExe = "/usr/bin/podman" + logrus.Warnf("Could not obtain podman executable location, using default %s", podmanExe) + } + + return podmanExe +} diff --git a/pkg/systemdgen/systemdgen_test.go b/pkg/systemdgen/systemdgen_test.go index f2f49e750..e413b24ce 100644 --- a/pkg/systemdgen/systemdgen_test.go +++ b/pkg/systemdgen/systemdgen_test.go @@ -41,7 +41,7 @@ ExecStart=/usr/bin/podman start 639c53578af4d84b8800b4635fa4e680ee80fd67e0e6a2d4 ExecStop=/usr/bin/podman stop -t 10 639c53578af4d84b8800b4635fa4e680ee80fd67e0e6a2d4eea48d1e3230f401 KillMode=none Type=forking -PIDFile=/var/lib/containers/storage/overlay-containers/639c53578af4d84b8800b4635fa4e680ee80fd67e0e6a2d4eea48d1e3230f401/userdata/639c53578af4d84b8800b4635fa4e680ee80fd67e0e6a2d4eea48d1e3230f401.pid +PIDFile=/var/run/containers/storage/overlay-containers/639c53578af4d84b8800b4635fa4e680ee80fd67e0e6a2d4eea48d1e3230f401/userdata/conmon.pid [Install] WantedBy=multi-user.target` @@ -53,15 +53,16 @@ ExecStart=/usr/bin/podman start foobar ExecStop=/usr/bin/podman stop -t 10 foobar KillMode=none Type=forking -PIDFile=/var/lib/containers/storage/overlay-containers/639c53578af4d84b8800b4635fa4e680ee80fd67e0e6a2d4eea48d1e3230f401/userdata/639c53578af4d84b8800b4635fa4e680ee80fd67e0e6a2d4eea48d1e3230f401.pid +PIDFile=/var/run/containers/storage/overlay-containers/639c53578af4d84b8800b4635fa4e680ee80fd67e0e6a2d4eea48d1e3230f401/userdata/conmon.pid [Install] WantedBy=multi-user.target` type args struct { + exe string name string cid string restart string - pidPath string + pidFile string stopTimeout int } tests := []struct { @@ -73,10 +74,11 @@ WantedBy=multi-user.target` {"good with id", args{ + "/usr/bin/podman", "639c53578af4d84b8800b4635fa4e680ee80fd67e0e6a2d4eea48d1e3230f401", "639c53578af4d84b8800b4635fa4e680ee80fd67e0e6a2d4eea48d1e3230f401", "always", - "/var/lib/containers/storage/overlay-containers/639c53578af4d84b8800b4635fa4e680ee80fd67e0e6a2d4eea48d1e3230f401/userdata/", + "/var/run/containers/storage/overlay-containers/639c53578af4d84b8800b4635fa4e680ee80fd67e0e6a2d4eea48d1e3230f401/userdata/conmon.pid", 10, }, goodID, @@ -84,10 +86,11 @@ WantedBy=multi-user.target` }, {"good with name", args{ + "/usr/bin/podman", "foobar", "639c53578af4d84b8800b4635fa4e680ee80fd67e0e6a2d4eea48d1e3230f401", "always", - "/var/lib/containers/storage/overlay-containers/639c53578af4d84b8800b4635fa4e680ee80fd67e0e6a2d4eea48d1e3230f401/userdata/", + "/var/run/containers/storage/overlay-containers/639c53578af4d84b8800b4635fa4e680ee80fd67e0e6a2d4eea48d1e3230f401/userdata/conmon.pid", 10, }, goodName, @@ -95,10 +98,11 @@ WantedBy=multi-user.target` }, {"bad restart policy", args{ + "/usr/bin/podman", "639c53578af4d84b8800b4635fa4e680ee80fd67e0e6a2d4eea48d1e3230f401", "639c53578af4d84b8800b4635fa4e680ee80fd67e0e6a2d4eea48d1e3230f401", "never", - "/var/lib/containers/storage/overlay-containers/639c53578af4d84b8800b4635fa4e680ee80fd67e0e6a2d4eea48d1e3230f401/userdata/", + "/var/run/containers/storage/overlay-containers/639c53578af4d84b8800b4635fa4e680ee80fd67e0e6a2d4eea48d1e3230f401/userdata/conmon.pid", 10, }, "", @@ -107,7 +111,7 @@ WantedBy=multi-user.target` } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { - got, err := CreateSystemdUnitAsString(tt.args.name, tt.args.cid, tt.args.restart, tt.args.pidPath, tt.args.stopTimeout) + got, err := createSystemdUnitAsString(tt.args.exe, tt.args.name, tt.args.cid, tt.args.restart, tt.args.pidFile, tt.args.stopTimeout) if (err != nil) != tt.wantErr { t.Errorf("CreateSystemdUnitAsString() error = %v, wantErr %v", err, tt.wantErr) return diff --git a/pkg/tracing/tracing.go b/pkg/tracing/tracing.go index cae76dee8..d028ddf8f 100644 --- a/pkg/tracing/tracing.go +++ b/pkg/tracing/tracing.go @@ -4,9 +4,9 @@ import ( "fmt" "io" - opentracing "github.com/opentracing/opentracing-go" - jaeger "github.com/uber/jaeger-client-go" - config "github.com/uber/jaeger-client-go/config" + "github.com/opentracing/opentracing-go" + "github.com/uber/jaeger-client-go" + "github.com/uber/jaeger-client-go/config" ) // Init returns an instance of Jaeger Tracer that samples 100% of traces and logs all spans to stdout. diff --git a/pkg/trust/trust.go b/pkg/trust/trust.go index 9a75474ae..3bfe4bda1 100644 --- a/pkg/trust/trust.go +++ b/pkg/trust/trust.go @@ -14,7 +14,7 @@ import ( "github.com/containers/image/types" "github.com/pkg/errors" "github.com/sirupsen/logrus" - yaml "gopkg.in/yaml.v2" + "gopkg.in/yaml.v2" ) // PolicyContent struct for policy.json file |