From c95dd17ffe4d24f34e5e0c5eb287caa8635c4d3c Mon Sep 17 00:00:00 2001 From: Tonis Tiigi Date: Sun, 30 Aug 2020 18:59:15 -0700 Subject: [PATCH] remotecache: validate out broken links from loops Signed-off-by: Tonis Tiigi --- cache/remotecache/v1/chains.go | 41 ++++++++++++++++++++++++++++++++-- 1 file changed, 39 insertions(+), 2 deletions(-) diff --git a/cache/remotecache/v1/chains.go b/cache/remotecache/v1/chains.go index a9b11c3e..a76cc691 100644 --- a/cache/remotecache/v1/chains.go +++ b/cache/remotecache/v1/chains.go @@ -23,7 +23,7 @@ func (c *CacheChains) Add(dgst digest.Digest) solver.CacheExporterRecord { if strings.HasPrefix(dgst.String(), "random:") { return &nopRecord{} } - it := &item{c: c, dgst: dgst} + it := &item{c: c, dgst: dgst, backlinks: map[*item]struct{}{}} c.items = append(c.items, it) return it } @@ -44,6 +44,17 @@ func (c *CacheChains) normalize() error { byKey: map[digest.Digest]*item{}, } + validated := make([]*item, 0, len(c.items)) + for _, it := range c.items { + it.validate() + } + for _, it := range c.items { + if !it.invalid { + validated = append(validated, it) + } + } + c.items = validated + for _, it := range c.items { _, err := normalizeItem(it, st) if err != nil { @@ -99,7 +110,9 @@ type item struct { result *solver.Remote resultTime time.Time - links []map[link]struct{} + links []map[link]struct{} + backlinks map[*item]struct{} + invalid bool } type link struct { @@ -126,6 +139,30 @@ func (c *item) LinkFrom(rec solver.CacheExporterRecord, index int, selector stri } c.links[index][link{src: src, selector: selector}] = struct{}{} + src.backlinks[c] = struct{}{} +} + +func (c *item) validate() { + for _, m := range c.links { + if len(m) == 0 { + c.invalid = true + for bl := range c.backlinks { + changed := false + for _, m := range bl.links { + for l := range m { + if l.src == c { + delete(m, l) + changed = true + } + } + } + if changed { + bl.validate() + } + } + return + } + } } func (c *item) walkAllResults(fn func(i *item) error, visited map[*item]struct{}) error {