diff --git a/provider/cocoon/create.go b/provider/cocoon/create.go index 8fce362..d73d5b8 100644 --- a/provider/cocoon/create.go +++ b/provider/cocoon/create.go @@ -2,6 +2,7 @@ package cocoon import ( "context" + "crypto/sha256" "fmt" "path/filepath" "strconv" @@ -540,10 +541,19 @@ func isHTTPURL(ref string) bool { // localSnapshotName omits the default tag for backward compatibility. func localSnapshotName(repo, tag string) string { + name := repo if tag == "" || tag == meta.DefaultSnapshotTag { - return repo + name = repo + } else { + name = repo + ":" + tag } - return repo + ":" + tag + const maxSnapshotNameLength = 63 + if len(name) <= maxSnapshotNameLength { + return name + } + sum := sha256.Sum256([]byte(name)) + suffix := fmt.Sprintf("-%x", sum[:6]) + return name[:maxSnapshotNameLength-len(suffix)] + suffix } func forkSnapshotName(sourceVMName string) string { diff --git a/provider/cocoon/create_test.go b/provider/cocoon/create_test.go index b626b30..762564b 100644 --- a/provider/cocoon/create_test.go +++ b/provider/cocoon/create_test.go @@ -526,6 +526,25 @@ func TestLocalSnapshotName(t *testing.T) { } } +func TestLocalSnapshotNameBoundsLongRegistryRefs(t *testing.T) { + repo := "simular/ubuntu2404-base-snapshot" + tag := "ubuntu2404-20260716-29479663055-1" + + got := localSnapshotName(repo, tag) + if len(got) > 63 { + t.Fatalf("local snapshot name length = %d, want <= 63: %q", len(got), got) + } + if got != localSnapshotName(repo, tag) { + t.Fatal("local snapshot name is not deterministic") + } + if got == localSnapshotName(repo, tag+"-different") { + t.Fatal("different registry refs produced the same local snapshot name") + } + if !strings.HasPrefix(got, "simular/ubuntu2404-base-snapshot:") { + t.Fatalf("local snapshot name lost its recognizable prefix: %q", got) + } +} + func TestAssertSnapshotBackend(t *testing.T) { t.Parallel()