diff options
Diffstat (limited to 'pkg')
-rw-r--r-- | pkg/api/handlers/compat/containers_stats.go | 23 | ||||
-rw-r--r-- | pkg/api/handlers/utils/containers.go | 1 | ||||
-rw-r--r-- | pkg/criu/criu.go | 43 | ||||
-rw-r--r-- | pkg/criu/criu_linux.go | 44 | ||||
-rw-r--r-- | pkg/criu/criu_unsupported.go | 8 | ||||
-rw-r--r-- | pkg/domain/entities/events.go | 10 | ||||
-rw-r--r-- | pkg/domain/infra/abi/containers.go | 22 | ||||
-rw-r--r-- | pkg/machine/e2e/list_test.go | 23 | ||||
-rw-r--r-- | pkg/signal/signal_common.go | 17 | ||||
-rw-r--r-- | pkg/signal/signal_linux.go | 17 | ||||
-rw-r--r-- | pkg/signal/signal_linux_mipsx.go | 17 | ||||
-rw-r--r-- | pkg/signal/signal_unix.go | 11 | ||||
-rw-r--r-- | pkg/signal/signal_unsupported.go | 11 | ||||
-rw-r--r-- | pkg/specgen/generate/container_create.go | 13 | ||||
-rw-r--r-- | pkg/specgen/generate/oci.go | 23 | ||||
-rw-r--r-- | pkg/specgen/volumes.go | 16 |
16 files changed, 138 insertions, 161 deletions
diff --git a/pkg/api/handlers/compat/containers_stats.go b/pkg/api/handlers/compat/containers_stats.go index d6bc26416..12c5283fc 100644 --- a/pkg/api/handlers/compat/containers_stats.go +++ b/pkg/api/handlers/compat/containers_stats.go @@ -12,6 +12,7 @@ import ( api "github.com/containers/podman/v4/pkg/api/types" docker "github.com/docker/docker/api/types" "github.com/gorilla/schema" + runccgroups "github.com/opencontainers/runc/libcontainer/cgroups" "github.com/pkg/errors" "github.com/sirupsen/logrus" ) @@ -133,7 +134,7 @@ streamLabel: // A label to flatten the scope } cfg := ctnr.Config() - memoryLimit := cgroupStat.Memory.Usage.Limit + memoryLimit := cgroupStat.MemoryStats.Usage.Limit if cfg.Spec.Linux != nil && cfg.Spec.Linux.Resources != nil && cfg.Spec.Linux.Resources.Memory != nil && *cfg.Spec.Linux.Resources.Memory.Limit > 0 { memoryLimit = uint64(*cfg.Spec.Linux.Resources.Memory.Limit) } @@ -144,11 +145,11 @@ streamLabel: // A label to flatten the scope Read: time.Now(), PreRead: preRead, PidsStats: docker.PidsStats{ - Current: cgroupStat.Pids.Current, + Current: cgroupStat.PidsStats.Current, Limit: 0, }, BlkioStats: docker.BlkioStats{ - IoServiceBytesRecursive: toBlkioStatEntry(cgroupStat.Blkio.IoServiceBytesRecursive), + IoServiceBytesRecursive: toBlkioStatEntry(cgroupStat.BlkioStats.IoServiceBytesRecursive), IoServicedRecursive: nil, IoQueuedRecursive: nil, IoServiceTimeRecursive: nil, @@ -159,14 +160,14 @@ streamLabel: // A label to flatten the scope }, CPUStats: CPUStats{ CPUUsage: docker.CPUUsage{ - TotalUsage: cgroupStat.CPU.Usage.Total, - PercpuUsage: cgroupStat.CPU.Usage.PerCPU, - UsageInKernelmode: cgroupStat.CPU.Usage.Kernel, - UsageInUsermode: cgroupStat.CPU.Usage.Total - cgroupStat.CPU.Usage.Kernel, + TotalUsage: cgroupStat.CpuStats.CpuUsage.TotalUsage, + PercpuUsage: cgroupStat.CpuStats.CpuUsage.PercpuUsage, + UsageInKernelmode: cgroupStat.CpuStats.CpuUsage.UsageInKernelmode, + UsageInUsermode: cgroupStat.CpuStats.CpuUsage.TotalUsage - cgroupStat.CpuStats.CpuUsage.UsageInKernelmode, }, CPU: stats.CPU, SystemUsage: systemUsage, - OnlineCPUs: uint32(len(cgroupStat.CPU.Usage.PerCPU)), + OnlineCPUs: uint32(len(cgroupStat.CpuStats.CpuUsage.PercpuUsage)), ThrottlingData: docker.ThrottlingData{ Periods: 0, ThrottledPeriods: 0, @@ -175,8 +176,8 @@ streamLabel: // A label to flatten the scope }, PreCPUStats: preCPUStats, MemoryStats: docker.MemoryStats{ - Usage: cgroupStat.Memory.Usage.Usage, - MaxUsage: cgroupStat.Memory.Usage.Limit, + Usage: cgroupStat.MemoryStats.Usage.Usage, + MaxUsage: cgroupStat.MemoryStats.Usage.Limit, Stats: nil, Failcnt: 0, Limit: memoryLimit, @@ -216,7 +217,7 @@ streamLabel: // A label to flatten the scope } } -func toBlkioStatEntry(entries []cgroups.BlkIOEntry) []docker.BlkioStatEntry { +func toBlkioStatEntry(entries []runccgroups.BlkioStatEntry) []docker.BlkioStatEntry { results := make([]docker.BlkioStatEntry, len(entries)) for i, e := range entries { bits, err := json.Marshal(e) diff --git a/pkg/api/handlers/utils/containers.go b/pkg/api/handlers/utils/containers.go index 8588b49ba..1795f6ce1 100644 --- a/pkg/api/handlers/utils/containers.go +++ b/pkg/api/handlers/utils/containers.go @@ -191,7 +191,6 @@ func waitDockerCondition(ctx context.Context, containerName string, interval tim var notRunningStates = []define.ContainerStatus{ define.ContainerStateCreated, define.ContainerStateRemoving, - define.ContainerStateStopped, define.ContainerStateExited, define.ContainerStateConfigured, } diff --git a/pkg/criu/criu.go b/pkg/criu/criu.go index 6570159d7..0b0bbff5d 100644 --- a/pkg/criu/criu.go +++ b/pkg/criu/criu.go @@ -1,51 +1,8 @@ -//go:build linux -// +build linux - package criu -import ( - "github.com/checkpoint-restore/go-criu/v5" - "github.com/checkpoint-restore/go-criu/v5/rpc" - - "google.golang.org/protobuf/proto" -) - // MinCriuVersion for Podman at least CRIU 3.11 is required const MinCriuVersion = 31100 // PodCriuVersion is the version of CRIU needed for // checkpointing and restoring containers out of and into Pods. const PodCriuVersion = 31600 - -// CheckForCriu uses CRIU's go bindings to check if the CRIU -// binary exists and if it at least the version Podman needs. -func CheckForCriu(version int) bool { - c := criu.MakeCriu() - result, err := c.IsCriuAtLeast(version) - if err != nil { - return false - } - return result -} - -func GetCriuVestion() (int, error) { - c := criu.MakeCriu() - return c.GetCriuVersion() -} - -func MemTrack() bool { - features, err := criu.MakeCriu().FeatureCheck( - &rpc.CriuFeatures{ - MemTrack: proto.Bool(true), - }, - ) - if err != nil { - return false - } - - if features == nil || features.MemTrack == nil { - return false - } - - return *features.MemTrack -} diff --git a/pkg/criu/criu_linux.go b/pkg/criu/criu_linux.go new file mode 100644 index 000000000..c28e23fd7 --- /dev/null +++ b/pkg/criu/criu_linux.go @@ -0,0 +1,44 @@ +//go:build linux +// +build linux + +package criu + +import ( + "github.com/checkpoint-restore/go-criu/v5" + "github.com/checkpoint-restore/go-criu/v5/rpc" + + "google.golang.org/protobuf/proto" +) + +// CheckForCriu uses CRIU's go bindings to check if the CRIU +// binary exists and if it at least the version Podman needs. +func CheckForCriu(version int) bool { + c := criu.MakeCriu() + result, err := c.IsCriuAtLeast(version) + if err != nil { + return false + } + return result +} + +func MemTrack() bool { + features, err := criu.MakeCriu().FeatureCheck( + &rpc.CriuFeatures{ + MemTrack: proto.Bool(true), + }, + ) + if err != nil { + return false + } + + if features == nil || features.MemTrack == nil { + return false + } + + return *features.MemTrack +} + +func GetCriuVersion() (int, error) { + c := criu.MakeCriu() + return c.GetCriuVersion() +} diff --git a/pkg/criu/criu_unsupported.go b/pkg/criu/criu_unsupported.go index 3e3ed9c6c..437482a0e 100644 --- a/pkg/criu/criu_unsupported.go +++ b/pkg/criu/criu_unsupported.go @@ -3,6 +3,14 @@ package criu +func CheckForCriu(version int) bool { + return false +} + func MemTrack() bool { return false } + +func GetCriuVersion() (int, error) { + return MinCriuVersion, nil +} diff --git a/pkg/domain/entities/events.go b/pkg/domain/entities/events.go index d8ba0f1d3..de218b285 100644 --- a/pkg/domain/entities/events.go +++ b/pkg/domain/entities/events.go @@ -14,6 +14,7 @@ type Event struct { // TODO: it would be nice to have full control over the types at some // point and fork such Docker types. dockerEvents.Message + HealthStatus string } // ConvertToLibpodEvent converts an entities event to a libpod one. @@ -44,6 +45,7 @@ func ConvertToLibpodEvent(e Event) *libpodEvents.Event { Status: status, Time: time.Unix(0, e.TimeNano), Type: t, + HealthStatus: e.HealthStatus, Details: libpodEvents.Details{ Attributes: details, }, @@ -59,7 +61,7 @@ func ConvertToEntitiesEvent(e libpodEvents.Event) *Event { attributes["image"] = e.Image attributes["name"] = e.Name attributes["containerExitCode"] = strconv.Itoa(e.ContainerExitCode) - return &Event{dockerEvents.Message{ + message := dockerEvents.Message{ // Compatibility with clients that still look for deprecated API elements Status: e.Status.String(), ID: e.ID, @@ -73,5 +75,9 @@ func ConvertToEntitiesEvent(e libpodEvents.Event) *Event { Scope: "local", Time: e.Time.Unix(), TimeNano: e.Time.UnixNano(), - }} + } + return &Event{ + message, + e.HealthStatus, + } } diff --git a/pkg/domain/infra/abi/containers.go b/pkg/domain/infra/abi/containers.go index 1934533cf..281e448f6 100644 --- a/pkg/domain/infra/abi/containers.go +++ b/pkg/domain/infra/abi/containers.go @@ -16,7 +16,6 @@ import ( "github.com/containers/image/v5/manifest" "github.com/containers/podman/v4/libpod" "github.com/containers/podman/v4/libpod/define" - "github.com/containers/podman/v4/libpod/events" "github.com/containers/podman/v4/libpod/logs" "github.com/containers/podman/v4/pkg/checkpoint" "github.com/containers/podman/v4/pkg/domain/entities" @@ -939,6 +938,7 @@ func (ic *ContainerEngine) ContainerStart(ctx context.Context, namesOrIds []stri } return reports, errors.Wrapf(err, "unable to start container %s", ctr.ID()) } + exitCode = ic.GetContainerExitCode(ctx, ctr) reports = append(reports, &entities.ContainerStartReport{ Id: ctr.ID(), @@ -1099,25 +1099,11 @@ func (ic *ContainerEngine) ContainerRun(ctx context.Context, opts entities.Conta func (ic *ContainerEngine) GetContainerExitCode(ctx context.Context, ctr *libpod.Container) int { exitCode, err := ctr.Wait(ctx) - if err == nil { - return int(exitCode) - } - if errors.Cause(err) != define.ErrNoSuchCtr { - logrus.Errorf("Could not retrieve exit code: %v", err) + if err != nil { + logrus.Errorf("Waiting for container %s: %v", ctr.ID(), err) return define.ExecErrorCodeNotFound } - // Make 4 attempt with 0.25s backoff between each for 1 second total - var event *events.Event - for i := 0; i < 4; i++ { - event, err = ic.Libpod.GetLastContainerEvent(ctx, ctr.ID(), events.Exited) - if err != nil { - time.Sleep(250 * time.Millisecond) - continue - } - return event.ContainerExitCode - } - logrus.Errorf("Could not retrieve exit code from event: %v", err) - return define.ExecErrorCodeNotFound + return int(exitCode) } func (ic *ContainerEngine) ContainerLogs(ctx context.Context, containers []string, options entities.ContainerLogsOptions) error { diff --git a/pkg/machine/e2e/list_test.go b/pkg/machine/e2e/list_test.go index 1c8c6ac81..e2121e7bf 100644 --- a/pkg/machine/e2e/list_test.go +++ b/pkg/machine/e2e/list_test.go @@ -29,7 +29,7 @@ var _ = Describe("podman machine list", func() { firstList, err := mb.setCmd(list).run() Expect(err).NotTo(HaveOccurred()) Expect(firstList).Should(Exit(0)) - Expect(len(firstList.outputToStringSlice())).To(Equal(1)) // just the header + Expect(firstList.outputToStringSlice()).To(HaveLen(1)) // just the header i := new(initMachine) session, err := mb.setCmd(i.withImagePath(mb.imagePath)).run() @@ -39,7 +39,7 @@ var _ = Describe("podman machine list", func() { secondList, err := mb.setCmd(list).run() Expect(err).NotTo(HaveOccurred()) Expect(secondList).To(Exit(0)) - Expect(len(secondList.outputToStringSlice())).To(Equal(2)) // one machine and the header + Expect(secondList.outputToStringSlice()).To(HaveLen(2)) // one machine and the header }) It("list machines with quiet or noheading", func() { @@ -51,12 +51,12 @@ var _ = Describe("podman machine list", func() { firstList, err := mb.setCmd(list.withQuiet()).run() Expect(err).NotTo(HaveOccurred()) Expect(firstList).Should(Exit(0)) - Expect(len(firstList.outputToStringSlice())).To(Equal(0)) // No header with quiet + Expect(firstList.outputToStringSlice()).To(HaveLen(0)) // No header with quiet noheaderSession, err := mb.setCmd(list.withNoHeading()).run() // noheader Expect(err).NotTo(HaveOccurred()) Expect(noheaderSession).Should(Exit(0)) - Expect(len(noheaderSession.outputToStringSlice())).To(Equal(0)) + Expect(noheaderSession.outputToStringSlice()).To(HaveLen(0)) i := new(initMachine) session, err := mb.setName(name1).setCmd(i.withImagePath(mb.imagePath)).run() @@ -70,7 +70,7 @@ var _ = Describe("podman machine list", func() { secondList, err := mb.setCmd(list.withQuiet()).run() Expect(err).NotTo(HaveOccurred()) Expect(secondList).To(Exit(0)) - Expect(len(secondList.outputToStringSlice())).To(Equal(2)) // two machines, no header + Expect(secondList.outputToStringSlice()).To(HaveLen(2)) // two machines, no header listNames := secondList.outputToStringSlice() stripAsterisk(listNames) @@ -116,10 +116,10 @@ var _ = Describe("podman machine list", func() { // go format list := new(listMachine) - listSession, err := mb.setCmd(list.withFormat("{{.Name}}").withNoHeading()).run() + listSession, err := mb.setCmd(list.withFormat("{{.Name}}")).run() Expect(err).NotTo(HaveOccurred()) Expect(listSession).To(Exit(0)) - Expect(len(listSession.outputToStringSlice())).To(Equal(1)) + Expect(listSession.outputToStringSlice()).To(HaveLen(1)) listNames := listSession.outputToStringSlice() stripAsterisk(listNames) @@ -135,6 +135,15 @@ var _ = Describe("podman machine list", func() { var listResponse []*machine.ListReporter err = jsoniter.Unmarshal(listSession.Bytes(), &listResponse) Expect(err).To(BeNil()) + + // table format includes the header + list = new(listMachine) + listSession3, err3 := mb.setCmd(list.withFormat("table {{.Name}}")).run() + Expect(err3).NotTo(HaveOccurred()) + Expect(listSession3).To(Exit(0)) + listNames3 := listSession3.outputToStringSlice() + Expect(listNames3).To(HaveLen(2)) + Expect(listNames3).To(ContainSubstring("NAME")) }) }) diff --git a/pkg/signal/signal_common.go b/pkg/signal/signal_common.go index fe5a76dae..fc1ecc04d 100644 --- a/pkg/signal/signal_common.go +++ b/pkg/signal/signal_common.go @@ -2,6 +2,8 @@ package signal import ( "fmt" + "os" + "os/signal" "strconv" "strings" "syscall" @@ -39,3 +41,18 @@ func ParseSignalNameOrNumber(rawSignal string) (syscall.Signal, error) { } return -1, fmt.Errorf("invalid signal: %s", basename) } + +// CatchAll catches all signals and relays them to the specified channel. +func CatchAll(sigc chan os.Signal) { + handledSigs := make([]os.Signal, 0, len(SignalMap)) + for _, s := range SignalMap { + handledSigs = append(handledSigs, s) + } + signal.Notify(sigc, handledSigs...) +} + +// StopCatch stops catching the signals and closes the specified channel. +func StopCatch(sigc chan os.Signal) { + signal.Stop(sigc) + close(sigc) +} diff --git a/pkg/signal/signal_linux.go b/pkg/signal/signal_linux.go index a114ea019..5103b6033 100644 --- a/pkg/signal/signal_linux.go +++ b/pkg/signal/signal_linux.go @@ -9,8 +9,6 @@ package signal // NOTE: this package has originally been copied from github.com/docker/docker. import ( - "os" - "os/signal" "syscall" "golang.org/x/sys/unix" @@ -91,18 +89,3 @@ var SignalMap = map[string]syscall.Signal{ "RTMAX-1": sigrtmax - 1, "RTMAX": sigrtmax, } - -// CatchAll catches all signals and relays them to the specified channel. -func CatchAll(sigc chan os.Signal) { - handledSigs := make([]os.Signal, 0, len(SignalMap)) - for _, s := range SignalMap { - handledSigs = append(handledSigs, s) - } - signal.Notify(sigc, handledSigs...) -} - -// StopCatch stops catching the signals and closes the specified channel. -func StopCatch(sigc chan os.Signal) { - signal.Stop(sigc) - close(sigc) -} diff --git a/pkg/signal/signal_linux_mipsx.go b/pkg/signal/signal_linux_mipsx.go index 9021a10e7..cdf9ad4c5 100644 --- a/pkg/signal/signal_linux_mipsx.go +++ b/pkg/signal/signal_linux_mipsx.go @@ -10,8 +10,6 @@ package signal // NOTE: this package has originally been copied from github.com/docker/docker. import ( - "os" - "os/signal" "syscall" "golang.org/x/sys/unix" @@ -92,18 +90,3 @@ var SignalMap = map[string]syscall.Signal{ "RTMAX-1": sigrtmax - 1, "RTMAX": sigrtmax, } - -// CatchAll catches all signals and relays them to the specified channel. -func CatchAll(sigc chan os.Signal) { - handledSigs := make([]os.Signal, 0, len(SignalMap)) - for _, s := range SignalMap { - handledSigs = append(handledSigs, s) - } - signal.Notify(sigc, handledSigs...) -} - -// StopCatch stops catching the signals and closes the specified channel. -func StopCatch(sigc chan os.Signal) { - signal.Stop(sigc) - close(sigc) -} diff --git a/pkg/signal/signal_unix.go b/pkg/signal/signal_unix.go index 0f43e21b7..7919e3670 100644 --- a/pkg/signal/signal_unix.go +++ b/pkg/signal/signal_unix.go @@ -5,7 +5,6 @@ package signal import ( - "os" "syscall" ) @@ -88,13 +87,3 @@ var SignalMap = map[string]syscall.Signal{ "RTMAX-1": sigrtmax - 1, "RTMAX": sigrtmax, } - -// CatchAll catches all signals and relays them to the specified channel. -func CatchAll(sigc chan os.Signal) { - panic("Unsupported on non-linux platforms") -} - -// StopCatch stops catching the signals and closes the specified channel. -func StopCatch(sigc chan os.Signal) { - panic("Unsupported on non-linux platforms") -} diff --git a/pkg/signal/signal_unsupported.go b/pkg/signal/signal_unsupported.go index 9d0cee317..19ae93a61 100644 --- a/pkg/signal/signal_unsupported.go +++ b/pkg/signal/signal_unsupported.go @@ -5,7 +5,6 @@ package signal import ( - "os" "syscall" ) @@ -88,13 +87,3 @@ var SignalMap = map[string]syscall.Signal{ "RTMAX-1": sigrtmax - 1, "RTMAX": sigrtmax, } - -// CatchAll catches all signals and relays them to the specified channel. -func CatchAll(sigc chan os.Signal) { - panic("Unsupported on non-linux platforms") -} - -// StopCatch stops catching the signals and closes the specified channel. -func StopCatch(sigc chan os.Signal) { - panic("Unsupported on non-linux platforms") -} diff --git a/pkg/specgen/generate/container_create.go b/pkg/specgen/generate/container_create.go index 0dec943d1..6b2e90b22 100644 --- a/pkg/specgen/generate/container_create.go +++ b/pkg/specgen/generate/container_create.go @@ -180,10 +180,23 @@ func MakeContainer(ctx context.Context, rt *libpod.Runtime, s *specgen.SpecGener if err != nil { return nil, nil, nil, err } + resources := runtimeSpec.Linux.Resources + + // resources get overwrritten similarly to pod inheritance, manually assign here if there is a new value + marshalRes, err := json.Marshal(resources) + if err != nil { + return nil, nil, nil, err + } + err = json.Unmarshal(out, runtimeSpec.Linux) if err != nil { return nil, nil, nil, err } + + err = json.Unmarshal(marshalRes, runtimeSpec.Linux.Resources) + if err != nil { + return nil, nil, nil, err + } } if s.ResourceLimits != nil { switch { diff --git a/pkg/specgen/generate/oci.go b/pkg/specgen/generate/oci.go index 19f55c9d8..1044854f4 100644 --- a/pkg/specgen/generate/oci.go +++ b/pkg/specgen/generate/oci.go @@ -298,8 +298,7 @@ func SpecGenToOCI(ctx context.Context, s *specgen.SpecGenerator, rt *libpod.Runt g.AddAnnotation(key, val) } - switch { - case compatibleOptions.InfraResources == nil && s.ResourceLimits != nil: + if s.ResourceLimits != nil { out, err := json.Marshal(s.ResourceLimits) if err != nil { return nil, err @@ -308,29 +307,9 @@ func SpecGenToOCI(ctx context.Context, s *specgen.SpecGenerator, rt *libpod.Runt if err != nil { return nil, err } - case s.ResourceLimits != nil: // if we have predefined resource limits we need to make sure we keep the infra and container limits - originalResources, err := json.Marshal(s.ResourceLimits) - if err != nil { - return nil, err - } - infraResources, err := json.Marshal(compatibleOptions.InfraResources) - if err != nil { - return nil, err - } - err = json.Unmarshal(infraResources, s.ResourceLimits) // put infra's resource limits in the container - if err != nil { - return nil, err - } - err = json.Unmarshal(originalResources, s.ResourceLimits) // make sure we did not override anything - if err != nil { - return nil, err - } g.Config.Linux.Resources = s.ResourceLimits - default: - g.Config.Linux.Resources = compatibleOptions.InfraResources } // Devices - // set the default rule at the beginning of device configuration if !inUserNS && !s.Privileged { g.AddLinuxResourcesDevice(false, "", nil, nil, "rwm") diff --git a/pkg/specgen/volumes.go b/pkg/specgen/volumes.go index a7a1022b0..f272a5c11 100644 --- a/pkg/specgen/volumes.go +++ b/pkg/specgen/volumes.go @@ -1,6 +1,7 @@ package specgen import ( + "path/filepath" "strings" "github.com/containers/common/pkg/parse" @@ -56,7 +57,6 @@ func GenVolumeMounts(volumeFlag []string) (map[string]spec.Mount, map[string]*Na overlayVolumes := make(map[string]*OverlayVolume) volumeFormatErr := errors.Errorf("incorrect volume format, should be [host-dir:]ctr-dir[:option]") - for _, vol := range volumeFlag { var ( options []string @@ -71,6 +71,20 @@ func GenVolumeMounts(volumeFlag []string) (map[string]spec.Mount, map[string]*Na } src = splitVol[0] + + // Support relative paths beginning with ./ + if strings.HasPrefix(src, "./") { + path, err := filepath.EvalSymlinks(src) + if err != nil { + return nil, nil, nil, err + } + src, err = filepath.Abs(path) + if err != nil { + return nil, nil, nil, err + } + splitVol[0] = src + } + if len(splitVol) == 1 { // This is an anonymous named volume. Only thing given // is destination. |