diff --git a/metadata/gc.go b/metadata/gc.go index d13047eb1..ab75e36fb 100644 --- a/metadata/gc.go +++ b/metadata/gc.go @@ -17,6 +17,7 @@ package metadata import ( + "bytes" "context" "fmt" "strings" @@ -345,7 +346,10 @@ func sendSnapshotRefs(ns string, bkt *bolt.Bucket, fn func(gc.Node)) error { lc := lbkt.Cursor() for k, v := lc.Seek(labelGCSnapRef); k != nil && strings.HasPrefix(string(k), string(labelGCSnapRef)); k, v = lc.Next() { - snapshotter := string(k[len(labelGCSnapRef):]) + snapshotter := k[len(labelGCSnapRef):] + if i := bytes.IndexByte(snapshotter, '/'); i >= 0 { + snapshotter = snapshotter[:i] + } fn(gcnode(ResourceSnapshot, ns, fmt.Sprintf("%s/%s", snapshotter, v))) } } @@ -361,8 +365,8 @@ func sendContentRefs(ns string, bkt *bolt.Bucket, fn func(gc.Node)) error { labelRef := string(labelGCContentRef) for k, v := lc.Seek(labelGCContentRef); k != nil && strings.HasPrefix(string(k), labelRef); k, v = lc.Next() { if ks := string(k); ks != labelRef { - // Allow reference naming, ignore names - if ks[len(labelRef)] != '.' { + // Allow reference naming separated by . or /, ignore names + if ks[len(labelRef)] != '.' && ks[len(labelRef)] != '/' { continue } } diff --git a/metadata/gc_test.go b/metadata/gc_test.go index 4a1e512f6..3892f9748 100644 --- a/metadata/gc_test.go +++ b/metadata/gc_test.go @@ -44,6 +44,7 @@ func TestGCRoots(t *testing.T) { addImage("ns1", "image2", dgst(2), labelmap(string(labelGCSnapRef)+"overlay", "sn2")), addContainer("ns1", "container1", "overlay", "sn4", nil), addContainer("ns1", "container2", "overlay", "sn5", labelmap(string(labelGCSnapRef)+"overlay", "sn6")), + addContainer("ns1", "container3", "overlay", "sn7", labelmap(string(labelGCSnapRef)+"overlay/anything-1", "sn8", string(labelGCSnapRef)+"overlay/anything-2", "sn9")), addContent("ns1", dgst(1), nil), addContent("ns1", dgst(2), nil), addContent("ns1", dgst(3), nil), @@ -55,6 +56,9 @@ func TestGCRoots(t *testing.T) { addSnapshot("ns1", "overlay", "sn4", "", nil), addSnapshot("ns1", "overlay", "sn5", "", nil), addSnapshot("ns1", "overlay", "sn6", "", nil), + addSnapshot("ns1", "overlay", "sn7", "", nil), + addSnapshot("ns1", "overlay", "sn8", "", nil), + addSnapshot("ns1", "overlay", "sn9", "", nil), addLeaseSnapshot("ns2", "l1", "overlay", "sn5"), addLeaseSnapshot("ns2", "l2", "overlay", "sn6"), addLeaseContent("ns2", "l1", dgst(4)), @@ -72,6 +76,9 @@ func TestGCRoots(t *testing.T) { gcnode(ResourceSnapshot, "ns1", "overlay/sn4"), gcnode(ResourceSnapshot, "ns1", "overlay/sn5"), gcnode(ResourceSnapshot, "ns1", "overlay/sn6"), + gcnode(ResourceSnapshot, "ns1", "overlay/sn7"), + gcnode(ResourceSnapshot, "ns1", "overlay/sn8"), + gcnode(ResourceSnapshot, "ns1", "overlay/sn9"), gcnode(ResourceSnapshot, "ns2", "overlay/sn5"), gcnode(ResourceSnapshot, "ns2", "overlay/sn6"), } @@ -197,12 +204,14 @@ func TestGCRefs(t *testing.T) { addContent("ns1", dgst(4), labelmap(string(labelGCContentRef), dgst(1).String())), addContent("ns1", dgst(5), labelmap(string(labelGCContentRef)+".anything-1", dgst(2).String(), string(labelGCContentRef)+".anything-2", dgst(3).String())), addContent("ns1", dgst(6), labelmap(string(labelGCContentRef)+"bad", dgst(1).String())), + addContent("ns1", dgst(7), labelmap(string(labelGCContentRef)+"/anything-1", dgst(2).String(), string(labelGCContentRef)+"/anything-2", dgst(3).String())), addContent("ns2", dgst(1), nil), addContent("ns2", dgst(2), nil), addSnapshot("ns1", "overlay", "sn1", "", nil), addSnapshot("ns1", "overlay", "sn2", "sn1", nil), addSnapshot("ns1", "overlay", "sn3", "sn2", nil), addSnapshot("ns1", "overlay", "sn4", "", labelmap(string(labelGCSnapRef)+"btrfs", "sn1", string(labelGCSnapRef)+"overlay", "sn1")), + addSnapshot("ns1", "overlay", "sn5", "", labelmap(string(labelGCSnapRef)+"overlay/anything-1", "sn1", string(labelGCSnapRef)+"overlay/anything-2", "sn2")), addSnapshot("ns1", "btrfs", "sn1", "", nil), addSnapshot("ns2", "overlay", "sn1", "", nil), addSnapshot("ns2", "overlay", "sn2", "sn1", nil), @@ -220,6 +229,10 @@ func TestGCRefs(t *testing.T) { gcnode(ResourceContent, "ns1", dgst(3).String()), }, gcnode(ResourceContent, "ns1", dgst(6).String()): nil, + gcnode(ResourceContent, "ns1", dgst(7).String()): { + gcnode(ResourceContent, "ns1", dgst(2).String()), + gcnode(ResourceContent, "ns1", dgst(3).String()), + }, gcnode(ResourceContent, "ns2", dgst(1).String()): nil, gcnode(ResourceContent, "ns2", dgst(2).String()): nil, gcnode(ResourceSnapshot, "ns1", "overlay/sn1"): nil, @@ -233,6 +246,10 @@ func TestGCRefs(t *testing.T) { gcnode(ResourceSnapshot, "ns1", "btrfs/sn1"), gcnode(ResourceSnapshot, "ns1", "overlay/sn1"), }, + gcnode(ResourceSnapshot, "ns1", "overlay/sn5"): { + gcnode(ResourceSnapshot, "ns1", "overlay/sn1"), + gcnode(ResourceSnapshot, "ns1", "overlay/sn2"), + }, gcnode(ResourceSnapshot, "ns1", "btrfs/sn1"): nil, gcnode(ResourceSnapshot, "ns2", "overlay/sn1"): nil, gcnode(ResourceSnapshot, "ns2", "overlay/sn2"): {