12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697 |
- package imagerefchecker
- import (
- "sync"
- "github.com/docker/docker/image"
- "github.com/docker/docker/layer"
- "github.com/moby/buildkit/cache"
- "github.com/opencontainers/go-digest"
- )
- // LayerGetter abstracts away the snapshotter
- type LayerGetter interface {
- GetLayer(string) (layer.Layer, error)
- }
- // Opt represents the options needed to create a refchecker
- type Opt struct {
- LayerGetter LayerGetter
- ImageStore image.Store
- }
- // New creates new image reference checker that can be used to see if a reference
- // is being used by any of the images in the image store
- func New(opt Opt) cache.ExternalRefCheckerFunc {
- return func() (cache.ExternalRefChecker, error) {
- return &checker{opt: opt, layers: lchain{}, cache: map[string]bool{}}, nil
- }
- }
- type lchain map[layer.DiffID]lchain
- func (c lchain) add(ids []layer.DiffID) {
- if len(ids) == 0 {
- return
- }
- id := ids[0]
- ch, ok := c[id]
- if !ok {
- ch = lchain{}
- c[id] = ch
- }
- ch.add(ids[1:])
- }
- func (c lchain) has(ids []layer.DiffID) bool {
- if len(ids) == 0 {
- return true
- }
- ch, ok := c[ids[0]]
- return ok && ch.has(ids[1:])
- }
- type checker struct {
- opt Opt
- once sync.Once
- layers lchain
- cache map[string]bool
- }
- func (c *checker) Exists(key string, chain []digest.Digest) bool {
- if c.opt.ImageStore == nil {
- return false
- }
- c.once.Do(c.init)
- if b, ok := c.cache[key]; ok {
- return b
- }
- l, err := c.opt.LayerGetter.GetLayer(key)
- if err != nil || l == nil {
- c.cache[key] = false
- return false
- }
- ok := c.layers.has(diffIDs(l))
- c.cache[key] = ok
- return ok
- }
- func (c *checker) init() {
- imgs := c.opt.ImageStore.Map()
- for _, img := range imgs {
- c.layers.add(img.RootFS.DiffIDs)
- }
- }
- func diffIDs(l layer.Layer) []layer.DiffID {
- p := l.Parent()
- if p == nil {
- return []layer.DiffID{l.DiffID()}
- }
- return append(diffIDs(p), l.DiffID())
- }
|