Skip to content

Commit 7a490c0

Browse files
committed
fix(types): allow ':' and '/' in snapshot names for OCI tag-aware refs
The validName regex added in #61 (`^[a-zA-Z0-9][a-zA-Z0-9._-]{0,62}$`) rejects vk-cocoon's tag-aware local-snapshot naming (`repo:tag`, e.g. `simular/ubuntu-hot-testing:v1`), breaking PullSnapshot for any cocoon VM create that goes through vk-cocoon. The cocoon subprocess exits with name validation error before reading stdin; vk-cocoon then writes the blob into a closed pipe and surfaces the symptom as "stream snapshot: ... broken pipe" with no visible upstream hint (its `command()` discards subprocess stderr). Split: keep validName strict for VMConfig (hostname / DNS-1123 / cidata constraints apply) and introduce validSnapshotName that additionally allows ':' and '/' for SnapshotConfig. Snapshot names are local cocoon DB keys and never propagate to hostname / DNS / cidata, so the strict charset isn't load-bearing there. Shell-unsafe chars and leading non-alnum remain rejected.
1 parent e56fa36 commit 7a490c0

3 files changed

Lines changed: 18 additions & 5 deletions

File tree

types/snapshot.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -20,8 +20,8 @@ type SnapshotConfig struct {
2020

2121
// Validate checks SnapshotConfig caller-controlled fields. Empty Name is allowed (name is optional).
2222
func (cfg *SnapshotConfig) Validate() error {
23-
if cfg.Name != "" && !validName.MatchString(cfg.Name) {
24-
return fmt.Errorf("snapshot name %q is invalid: must match %s (max 63 chars)", cfg.Name, validName.String())
23+
if cfg.Name != "" && !validSnapshotName.MatchString(cfg.Name) {
24+
return fmt.Errorf("snapshot name %q is invalid: must match %s (max 63 chars)", cfg.Name, validSnapshotName.String())
2525
}
2626
return nil
2727
}

types/snapshot_test.go

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,11 +14,17 @@ func TestSnapshotConfig_Validate(t *testing.T) {
1414
{"empty allowed", "", false},
1515
{"simple", "my-snap", false},
1616
{"with dot underscore", "my.snap_v1", false},
17+
{"oci repo:tag", "simular/ubuntu-hot-testing:v1", false},
18+
{"oci repo only", "simular/ubuntu-hot-testing", false},
19+
{"colon only", "repo:tag", false},
1720
{"max 63", strings.Repeat("a", 63), false},
1821
{"over 63", strings.Repeat("a", 64), true},
1922
{"leading hyphen", "-bad", true},
23+
{"leading slash", "/bad", true},
24+
{"leading colon", ":bad", true},
2025
{"space", "bad name", true},
21-
{"slash", "bad/name", true},
26+
{"semicolon", "bad;rm", true},
27+
{"backtick", "bad`name", true},
2228
{"control char", "bad\x00name", true},
2329
}
2430
for _, tt := range cases {

types/vm.go

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -15,8 +15,15 @@ const (
1515
)
1616

1717
var (
18-
validName = regexp.MustCompile(`^[a-zA-Z0-9][a-zA-Z0-9._-]{0,62}$`)
19-
validUsername = regexp.MustCompile(`^[a-z_][a-z0-9_-]{0,31}$`)
18+
validName = regexp.MustCompile(`^[a-zA-Z0-9][a-zA-Z0-9._-]{0,62}$`)
19+
// validSnapshotName additionally allows ':' and '/' so callers can use
20+
// OCI tag-aware refs (`repo:tag`, `repo/path:tag`) as the local
21+
// snapshot name — vk-cocoon's PullSnapshot relies on this. Still
22+
// rejects shell-unsafe chars and leading non-alnum; snapshot name
23+
// never reaches hostname / DNS-1123 / cidata so the strict
24+
// VMConfig.Name rules don't apply.
25+
validSnapshotName = regexp.MustCompile(`^[a-zA-Z0-9][a-zA-Z0-9._:/-]{0,62}$`)
26+
validUsername = regexp.MustCompile(`^[a-z_][a-z0-9_-]{0,31}$`)
2027
// shellUnsafe rejects chars that break the chpasswd YAML scalar in cidata.
2128
shellUnsafe = regexp.MustCompile("[`$;|&(){}\\\\<>!'\"\\x00-\\x1f\\x7f]")
2229
)

0 commit comments

Comments
 (0)