Skip to content

Commit 77163bf

Browse files
committed
lib: Add CheckpointOptions struct and parsing for CRI options
Add support for parsing checkpoint options from the Kubernetes CRI CheckpointPodRequest map[string]string options field. The new ParseCheckpointOptions function validates known options and their expected types (bool, int, string). Known options: leave-running, tcp-established, ghost-limit, network-lock Boolean values accept: yes, no, true, false, on, off, 0, 1 Generated with Claude Code (https://claude.ai/code) Signed-off-by: Adrian Reber <areber@redhat.com>
1 parent 06e23e6 commit 77163bf

2 files changed

Lines changed: 402 additions & 0 deletions

File tree

lib/checkpoint_options.go

Lines changed: 108 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,108 @@
1+
// SPDX-License-Identifier: Apache-2.0
2+
3+
package metadata
4+
5+
import (
6+
"fmt"
7+
)
8+
9+
// OptionType represents the type of a checkpoint option value
10+
type OptionType int
11+
12+
const (
13+
OptionTypeBool OptionType = iota
14+
OptionTypeInt
15+
OptionTypeString
16+
)
17+
18+
// CheckpointOption defines a known checkpoint option with its expected type
19+
type CheckpointOption struct {
20+
Type OptionType
21+
}
22+
23+
// CheckpointOptions represents the options from a CheckpointPodRequest
24+
type CheckpointOptions struct {
25+
// LeaveRunning leaves the processes running in the container after checkpointing
26+
LeaveRunning bool `json:"leaveRunning,omitempty"`
27+
// TCPEstablished enables support for established TCP connections in the checkpoint
28+
TCPEstablished bool `json:"tcpEstablished,omitempty"`
29+
// GhostLimit limits max size of deleted file contents inside image
30+
GhostLimit int64 `json:"ghostLimit,omitempty"`
31+
// NetworkLock specifies the network locking/unlocking method
32+
NetworkLock string `json:"networkLock,omitempty"`
33+
}
34+
35+
// knownCheckpointOptions defines all known checkpoint options and their expected types
36+
var knownCheckpointOptions = map[string]CheckpointOption{
37+
"leave-running": {Type: OptionTypeBool},
38+
"tcp-established": {Type: OptionTypeBool},
39+
"ghost-limit": {Type: OptionTypeInt},
40+
"network-lock": {Type: OptionTypeString},
41+
}
42+
43+
// parseBool parses a string value as a boolean, accepting:
44+
// yes, no, true, false, on, off, 0, 1 (case-insensitive)
45+
func parseBool(value string) (bool, error) {
46+
switch value {
47+
case "yes", "Yes", "YES", "true", "True", "TRUE", "on", "On", "ON", "1":
48+
return true, nil
49+
case "no", "No", "NO", "false", "False", "FALSE", "off", "Off", "OFF", "0":
50+
return false, nil
51+
default:
52+
return false, fmt.Errorf("invalid boolean value: %q (accepted: yes, no, true, false, on, off, 0, 1)", value)
53+
}
54+
}
55+
56+
// ParseCheckpointOptions validates and parses checkpoint options from a map[string]string.
57+
// It checks if the options are known and if their values match the expected types.
58+
// Returns a CheckpointOptions struct and any validation errors encountered.
59+
func ParseCheckpointOptions(options map[string]string) (*CheckpointOptions, error) {
60+
result := &CheckpointOptions{}
61+
var errs []string
62+
63+
for key, value := range options {
64+
opt, known := knownCheckpointOptions[key]
65+
if !known {
66+
errs = append(errs, fmt.Sprintf("unknown option: %q", key))
67+
continue
68+
}
69+
70+
switch opt.Type {
71+
case OptionTypeBool:
72+
boolVal, err := parseBool(value)
73+
if err != nil {
74+
errs = append(errs, fmt.Sprintf("option %q: %v", key, err))
75+
continue
76+
}
77+
switch key {
78+
case "leave-running":
79+
result.LeaveRunning = boolVal
80+
case "tcp-established":
81+
result.TCPEstablished = boolVal
82+
}
83+
84+
case OptionTypeInt:
85+
var intVal int64
86+
if _, err := fmt.Sscanf(value, "%d", &intVal); err != nil {
87+
errs = append(errs, fmt.Sprintf("option %q: invalid integer value: %q", key, value))
88+
continue
89+
}
90+
switch key {
91+
case "ghost-limit":
92+
result.GhostLimit = intVal
93+
}
94+
95+
case OptionTypeString:
96+
switch key {
97+
case "network-lock":
98+
result.NetworkLock = value
99+
}
100+
}
101+
}
102+
103+
if len(errs) > 0 {
104+
return result, fmt.Errorf("validation errors: %v", errs)
105+
}
106+
107+
return result, nil
108+
}

0 commit comments

Comments
 (0)