From 15940a6c395a449e3150972e474a8f5d1524c679 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Fri, 14 Aug 2026 14:07:04 +0000 Subject: [PATCH] Update module github.com/checkpoint-restore/checkpointctl to v1.6.0 Signed-off-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- common/go.mod | 2 +- common/go.sum | 4 +- .../checkpointctl/lib/annotations.go | 3 + .../checkpointctl/lib/metadata.go | 80 ++++++++++++++++++- .../checkpointctl/lib/metadata_open_linux.go | 53 ++++++++++++ .../checkpointctl/lib/metadata_open_other.go | 13 +++ .../checkpointctl/lib/metadata_open_unix.go | 26 ++++++ vendor/modules.txt | 4 +- 8 files changed, 179 insertions(+), 6 deletions(-) create mode 100644 vendor/github.com/checkpoint-restore/checkpointctl/lib/metadata_open_linux.go create mode 100644 vendor/github.com/checkpoint-restore/checkpointctl/lib/metadata_open_other.go create mode 100644 vendor/github.com/checkpoint-restore/checkpointctl/lib/metadata_open_unix.go diff --git a/common/go.mod b/common/go.mod index 10b2dd23e4..34ddbca699 100644 --- a/common/go.mod +++ b/common/go.mod @@ -5,7 +5,7 @@ module go.podman.io/common go 1.25.7 require ( - github.com/checkpoint-restore/checkpointctl v1.5.0 + github.com/checkpoint-restore/checkpointctl v1.6.0 github.com/checkpoint-restore/go-criu/v8 v8.4.0 github.com/containerd/platforms v1.0.0-rc.4 github.com/containers/ocicrypt v1.3.2 diff --git a/common/go.sum b/common/go.sum index 0feaf1ac7e..632b6003c4 100644 --- a/common/go.sum +++ b/common/go.sum @@ -20,8 +20,8 @@ github.com/blang/semver/v4 v4.0.0 h1:1PFHFE6yCCTv8C1TeyNNarDzntLi7wMI5i/pzqYIsAM github.com/blang/semver/v4 v4.0.0/go.mod h1:IbckMUScFkM3pff0VJDNKRiT6TG/YpiHIM2yvyW5YoQ= github.com/cespare/xxhash/v2 v2.3.0 h1:UL815xU9SqsFlibzuggzjXhog7bL6oX9BbNZnL2UFvs= github.com/cespare/xxhash/v2 v2.3.0/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= -github.com/checkpoint-restore/checkpointctl v1.5.0 h1:Uu+D2cOf/GUyCMk23Y8L69P6YoATTe6pH+Au64O3y28= -github.com/checkpoint-restore/checkpointctl v1.5.0/go.mod h1:y5HRs1ZWQUZGyEuthlTHmTJN9PUMOjlaH6JvVaNq9kE= +github.com/checkpoint-restore/checkpointctl v1.6.0 h1:e+hOhEFiUUYZRCbbfbceQ3lLGQXHt2+qKSAR2l9Mv5M= +github.com/checkpoint-restore/checkpointctl v1.6.0/go.mod h1:LjfSgCtcTMbzwcA7d+vXJ7udJsWC/VRJpKUojTAGeCk= github.com/checkpoint-restore/go-criu/v8 v8.4.0 h1:w6WDxjde4pvXYTIBuj6dsWsaPorKwSWuCk/qSKTO3Jw= github.com/checkpoint-restore/go-criu/v8 v8.4.0/go.mod h1:SK5UexowK0P99gCcJJOavgVVlUWydGUfXSQUf1qDkHU= github.com/chzyer/logex v1.1.10/go.mod h1:+Ywpsq7O8HXn0nuIou7OrIPyXbp3wmkHB+jjWRnGsAI= diff --git a/vendor/github.com/checkpoint-restore/checkpointctl/lib/annotations.go b/vendor/github.com/checkpoint-restore/checkpointctl/lib/annotations.go index 8d0ad98036..2ea7b8e8a9 100644 --- a/vendor/github.com/checkpoint-restore/checkpointctl/lib/annotations.go +++ b/vendor/github.com/checkpoint-restore/checkpointctl/lib/annotations.go @@ -19,6 +19,9 @@ const ( // CheckpointAnnotationNamespace specifies the namespace of the pod associated with the checkpoint. CheckpointAnnotationNamespace = "org.criu.checkpoint.pod.namespace" + // CheckpointAnnotationPodUID specifies the UID of the pod associated with the checkpoint. + CheckpointAnnotationPodUID = "org.criu.checkpoint.pod.uid" + // CheckpointAnnotationRootfsImageName specifies the name of the root filesystem image associated with the checkpoint. CheckpointAnnotationRootfsImageName = "org.criu.checkpoint.rootfsImageName" diff --git a/vendor/github.com/checkpoint-restore/checkpointctl/lib/metadata.go b/vendor/github.com/checkpoint-restore/checkpointctl/lib/metadata.go index 1d68f887f9..d2f0d94d90 100644 --- a/vendor/github.com/checkpoint-restore/checkpointctl/lib/metadata.go +++ b/vendor/github.com/checkpoint-restore/checkpointctl/lib/metadata.go @@ -4,7 +4,9 @@ package metadata import ( "encoding/json" + "errors" "fmt" + "io" "os" "path/filepath" "time" @@ -12,6 +14,8 @@ import ( spec "github.com/opencontainers/runtime-spec/specs-go" ) +var errNotRegularFile = errors.New("not a regular file") + const ( // container archive ConfigDumpFile = "config.dump" @@ -79,6 +83,43 @@ type KubernetesContainerCheckpointMetadata struct { Checkpoints []KubernetesCheckpoint `json:"checkpoints"` } +// CheckpointedPodOptions contains metadata about a checkpointed pod +type CheckpointedPodOptions struct { + // Version is the version of the pod checkpoint format + Version int `json:"version"` + // Containers is a map with the short container name as key and the full name as value + Containers map[string]string `json:"containers"` + // Annotations stores checkpoint-related annotations (keys defined in annotations.go) + Annotations map[string]string `json:"annotations,omitempty"` +} + +// PodmanNetworkSubnet represents a single subnet entry in the Podman network status +type PodmanNetworkSubnet struct { + IPNet string `json:"ipnet"` + Gateway string `json:"gateway"` +} + +// PodmanNetworkInterface represents a network interface in the Podman network status +type PodmanNetworkInterface struct { + Subnets []PodmanNetworkSubnet `json:"subnets"` + MacAddress string `json:"mac_address"` +} + +// PodmanNetworkResult represents the network status for a single CNI/netavark network +type PodmanNetworkResult struct { + Interfaces map[string]PodmanNetworkInterface `json:"interfaces"` +} + +// PodmanNetworkStatus maps network names to their results in the network.status file +type PodmanNetworkStatus map[string]PodmanNetworkResult + +func ReadContainerCheckpointNetworkStatus(checkpointDirectory string) (*PodmanNetworkStatus, string, error) { + var networkStatus PodmanNetworkStatus + networkStatusFile, err := ReadJSONFile(&networkStatus, checkpointDirectory, NetworkStatusFile) + + return &networkStatus, networkStatusFile, err +} + func ReadContainerCheckpointSpecDump(checkpointDirectory string) (*spec.Spec, string, error) { var specDump spec.Spec specDumpFile, err := ReadJSONFile(&specDump, checkpointDirectory, SpecDumpFile) @@ -107,6 +148,13 @@ func ReadContainerCheckpointStatusFile(checkpointDirectory string) (*ContainerdS return &containerdStatus, statusFile, err } +func ReadCheckpointPodOptions(checkpointDirectory string) (*CheckpointedPodOptions, string, error) { + var podOptions CheckpointedPodOptions + podOptionsFile, err := ReadJSONFile(&podOptions, checkpointDirectory, PodOptionsFile) + + return &podOptions, podOptionsFile, err +} + // WriteJSONFile marshalls and writes the given data to a JSON file func WriteJSONFile(v interface{}, dir, file string) (string, error) { fileJSON, err := json.MarshalIndent(v, "", " ") @@ -121,9 +169,18 @@ func WriteJSONFile(v interface{}, dir, file string) (string, error) { return file, nil } +// ReadJSONFile reads JSON from a regular file in dir. On Unix, a symbolic link +// in the final path component is rejected. On Linux, reopening the validated +// file descriptor requires access to a usable procfs instance. func ReadJSONFile(v interface{}, dir, file string) (string, error) { file = filepath.Join(dir, file) - content, err := os.ReadFile(file) + f, err := openRegularFile(file) + if err != nil { + return "", err + } + defer f.Close() + + content, err := io.ReadAll(f) if err != nil { return "", err } @@ -134,6 +191,27 @@ func ReadJSONFile(v interface{}, dir, file string) (string, error) { return file, nil } +// openRegularFile applies platform-specific opening safeguards and verifies +// the opened descriptor before returning it. +func openRegularFile(file string) (*os.File, error) { + f, err := openFile(file) + if err != nil { + return nil, err + } + + info, err := f.Stat() + if err != nil { + _ = f.Close() + return nil, err + } + if !info.Mode().IsRegular() { + _ = f.Close() + return nil, fmt.Errorf("%s is %w", file, errNotRegularFile) + } + + return f, nil +} + func ByteToString(b int64) string { const unit = 1024 if b < unit { diff --git a/vendor/github.com/checkpoint-restore/checkpointctl/lib/metadata_open_linux.go b/vendor/github.com/checkpoint-restore/checkpointctl/lib/metadata_open_linux.go new file mode 100644 index 0000000000..876305bf94 --- /dev/null +++ b/vendor/github.com/checkpoint-restore/checkpointctl/lib/metadata_open_linux.go @@ -0,0 +1,53 @@ +// SPDX-License-Identifier: Apache-2.0 + +//go:build linux + +package metadata + +import ( + "fmt" + "os" + + pathrs "github.com/cyphar/filepath-securejoin/pathrs-lite" + "golang.org/x/sys/unix" +) + +// openFile opens path without activating the inode, verifies that the opened +// inode is a regular file, and then reopens that same inode for reading. +func openFile(path string) (*os.File, error) { + handle, err := os.OpenFile(path, unix.O_PATH|unix.O_NOFOLLOW|unix.O_CLOEXEC, 0) + if err != nil { + return nil, err + } + defer handle.Close() + + handleInfo, err := handle.Stat() + if err != nil { + return nil, fmt.Errorf("stat %s: %w", path, err) + } + if !handleInfo.Mode().IsRegular() { + return nil, fmt.Errorf("%s is %w", path, errNotRegularFile) + } + + return reopenFile(handle, path, handleInfo) +} + +func reopenFile(handle *os.File, path string, handleInfo os.FileInfo) (*os.File, error) { + // Linux openat(2) does not support AT_EMPTY_PATH. Reopen the pinned O_PATH + // descriptor using pathrs, which protects against unsafe procfs mounts. + f, err := pathrs.Reopen(handle, unix.O_RDONLY) + if err != nil { + return nil, fmt.Errorf("reopen %s: %w", path, err) + } + info, err := f.Stat() + if err != nil { + _ = f.Close() + return nil, fmt.Errorf("stat reopened %s: %w", path, err) + } + if !os.SameFile(handleInfo, info) { + _ = f.Close() + return nil, fmt.Errorf("reopened file does not match %s", path) + } + + return f, nil +} diff --git a/vendor/github.com/checkpoint-restore/checkpointctl/lib/metadata_open_other.go b/vendor/github.com/checkpoint-restore/checkpointctl/lib/metadata_open_other.go new file mode 100644 index 0000000000..ae057983fb --- /dev/null +++ b/vendor/github.com/checkpoint-restore/checkpointctl/lib/metadata_open_other.go @@ -0,0 +1,13 @@ +// SPDX-License-Identifier: Apache-2.0 + +//go:build !unix + +package metadata + +import "os" + +func openFile(path string) (*os.File, error) { + // Preserve the platform's ordinary open behavior. openRegularFile validates + // the resulting descriptor before any JSON is read. + return os.Open(path) +} diff --git a/vendor/github.com/checkpoint-restore/checkpointctl/lib/metadata_open_unix.go b/vendor/github.com/checkpoint-restore/checkpointctl/lib/metadata_open_unix.go new file mode 100644 index 0000000000..24d525e1e0 --- /dev/null +++ b/vendor/github.com/checkpoint-restore/checkpointctl/lib/metadata_open_unix.go @@ -0,0 +1,26 @@ +// SPDX-License-Identifier: Apache-2.0 + +//go:build unix && !linux + +package metadata + +import ( + "fmt" + "os" + "syscall" +) + +func openFile(path string) (*os.File, error) { + // Reject stable special files before open. O_NONBLOCK prevents a FIFO + // replacement from blocking between this check and the descriptor check in + // openRegularFile. + info, err := os.Lstat(path) + if err != nil { + return nil, err + } + if !info.Mode().IsRegular() { + return nil, fmt.Errorf("%s is %w", path, errNotRegularFile) + } + + return os.OpenFile(path, os.O_RDONLY|syscall.O_NONBLOCK|syscall.O_NOFOLLOW, 0) +} diff --git a/vendor/modules.txt b/vendor/modules.txt index 64228e688e..194363783a 100644 --- a/vendor/modules.txt +++ b/vendor/modules.txt @@ -58,8 +58,8 @@ github.com/aperturerobotics/protobuf-go-lite # github.com/cespare/xxhash/v2 v2.3.0 ## explicit; go 1.11 github.com/cespare/xxhash/v2 -# github.com/checkpoint-restore/checkpointctl v1.5.0 -## explicit; go 1.24.6 +# github.com/checkpoint-restore/checkpointctl v1.6.0 +## explicit; go 1.25.0 github.com/checkpoint-restore/checkpointctl/lib # github.com/checkpoint-restore/go-criu/v8 v8.4.0 ## explicit; go 1.25.0