package dockerfile // import "github.com/docker/docker/builder/dockerfile" import ( "context" "github.com/docker/docker/api/types/container" "github.com/docker/docker/builder" "github.com/sirupsen/logrus" ) // ImageProber exposes an Image cache to the Builder. It supports resetting a // cache. type ImageProber interface { Reset(ctx context.Context) error Probe(parentID string, runConfig *container.Config) (string, error) } type resetFunc func(context.Context) (builder.ImageCache, error) type imageProber struct { cache builder.ImageCache reset resetFunc cacheBusted bool } func newImageProber(ctx context.Context, cacheBuilder builder.ImageCacheBuilder, cacheFrom []string, noCache bool) (ImageProber, error) { if noCache { return &nopProber{}, nil } reset := func(ctx context.Context) (builder.ImageCache, error) { return cacheBuilder.MakeImageCache(ctx, cacheFrom) } cache, err := reset(ctx) if err != nil { return nil, err } return &imageProber{cache: cache, reset: reset}, nil } func (c *imageProber) Reset(ctx context.Context) error { newCache, err := c.reset(ctx) if err != nil { return err } c.cache = newCache c.cacheBusted = false return nil } // Probe checks if cache match can be found for current build instruction. // It returns the cachedID if there is a hit, and the empty string on miss func (c *imageProber) Probe(parentID string, runConfig *container.Config) (string, error) { if c.cacheBusted { return "", nil } cacheID, err := c.cache.GetCache(parentID, runConfig) if err != nil { return "", err } if len(cacheID) == 0 { logrus.Debugf("[BUILDER] Cache miss: %s", runConfig.Cmd) c.cacheBusted = true return "", nil } logrus.Debugf("[BUILDER] Use cached version: %s", runConfig.Cmd) return cacheID, nil } type nopProber struct{} func (c *nopProber) Reset(ctx context.Context) error { return nil } func (c *nopProber) Probe(_ string, _ *container.Config) (string, error) { return "", nil }