Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
13 changes: 12 additions & 1 deletion runsc/container/container_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -4097,7 +4097,7 @@ func TestSpecValidation(t *testing.T) {
name: "AnnotationsFail",
mutate: func(spec, restoreSpec *specs.Spec, _, _ string) {
spec.Annotations = make(map[string]string)
spec.Annotations["dev.gvisor.net-disconnect-ok"] = strconv.FormatBool(true)
spec.Annotations["dev.gvisor.flag.net-disconnect-ok"] = strconv.FormatBool(true)
},
wantErr: "Annotations does not match across checkpoint restore",
},
Expand All @@ -4112,6 +4112,17 @@ func TestSpecValidation(t *testing.T) {
},
wantErr: "",
},
{
name: "DebugLogAnnotationsSuccess",
mutate: func(spec, restoreSpec *specs.Spec, _, _ string) {
restoreSpec.Annotations = make(map[string]string)
restoreSpec.Annotations["dev.gvisor.flag.debug-log"] = "/tmp/sandbox-%ID%/"
restoreSpec.Annotations["dev.gvisor.flag.debug"] = "true"
restoreSpec.Annotations["dev.gvisor.flag.debug-command"] = "boot,gofer,start,create"
restoreSpec.Annotations["dev.gvisor.flag.strace"] = "true"
},
wantErr: "",
},
{
name: "Capabilities",
mutate: func(spec, restoreSpec *specs.Spec, _, _ string) {
Expand Down
57 changes: 47 additions & 10 deletions runsc/specutils/restore.go
Original file line number Diff line number Diff line change
Expand Up @@ -139,21 +139,58 @@ func validateDevices(field, cName string, o, n []specs.LinuxDevice) error {
return nil
}

func extractAnnotationsToValidate(o map[string]string) map[string]string {
// These annotations are allowed to be changed during restore.
var allowedRestoreFlagAnnotations = []string{
annotationFlagPrefix + "debug",
annotationFlagPrefix + "debug-log",
annotationFlagPrefix + "debug-command",
annotationFlagPrefix + "debug-log-format",
annotationFlagPrefix + "strace",
annotationFlagPrefix + "strace-syscalls",
annotationFlagPrefix + "strace-log-size",
annotationFlagPrefix + "log-packets",
}

func shouldValidateAnnotation(key string) bool {
const (
gvisorPrefix = "dev.gvisor."
internalPrefix = "dev.gvisor.internal."
mntPrefix = "dev.gvisor.spec.mount."
containerNameRemapPrefix = "dev.gvisor.container-name-remap."
gvisorPrefix = "dev.gvisor."
internalPrefix = "dev.gvisor.internal."
mntPrefix = "dev.gvisor.spec.mount."
)
// Only validate gVisor annotations.
if !strings.HasPrefix(key, gvisorPrefix) {
return false
}
// Do not validate internal annotations. They might container
// checkpoint/restore specific information which ought to change.
if strings.HasPrefix(key, internalPrefix) {
return false
}
// Do not validate container name remap annotations. These are only set
// during restore.
if strings.HasPrefix(key, annotationContainerNameRemap) {
return false
}
// The source of a mount can change during restore.
if strings.HasPrefix(key, mntPrefix) && strings.HasSuffix(key, ".source") {
return false
}
// Flag annotations controlling debug logging can change. They don't impact
// the restorability of the snapshot.
if strings.HasPrefix(key, annotationFlagPrefix) {
for _, allowed := range allowedRestoreFlagAnnotations {
if key == allowed {
return false
}
}
}
return true
}

func extractAnnotationsToValidate(o map[string]string) map[string]string {
n := make(map[string]string)
for key, val := range o {
if strings.HasPrefix(key, internalPrefix) || strings.HasPrefix(key, containerNameRemapPrefix) || (strings.HasPrefix(key, mntPrefix) && strings.HasSuffix(key, ".source")) {
continue
}

if strings.HasPrefix(key, gvisorPrefix) {
if shouldValidateAnnotation(key) {
n[key] = val
}
}
Expand Down
Loading