2018-02-05 21:05:59 +00:00
|
|
|
package dockerfile // import "github.com/docker/docker/builder/dockerfile"
|
2017-04-13 22:44:36 +00:00
|
|
|
|
|
|
|
import (
|
2022-10-26 16:13:17 +00:00
|
|
|
"context"
|
|
|
|
|
2017-04-13 22:44:36 +00:00
|
|
|
"github.com/docker/docker/api/types/container"
|
|
|
|
"github.com/docker/docker/builder"
|
2017-07-26 21:42:13 +00:00
|
|
|
"github.com/sirupsen/logrus"
|
2017-04-13 22:44:36 +00:00
|
|
|
)
|
|
|
|
|
|
|
|
// ImageProber exposes an Image cache to the Builder. It supports resetting a
|
|
|
|
// cache.
|
|
|
|
type ImageProber interface {
|
2022-10-26 16:13:17 +00:00
|
|
|
Reset(ctx context.Context) error
|
2017-04-13 22:44:36 +00:00
|
|
|
Probe(parentID string, runConfig *container.Config) (string, error)
|
|
|
|
}
|
|
|
|
|
2022-10-26 16:13:17 +00:00
|
|
|
type resetFunc func(context.Context) (builder.ImageCache, error)
|
|
|
|
|
2017-04-13 22:44:36 +00:00
|
|
|
type imageProber struct {
|
|
|
|
cache builder.ImageCache
|
2022-10-26 16:13:17 +00:00
|
|
|
reset resetFunc
|
2017-04-13 22:44:36 +00:00
|
|
|
cacheBusted bool
|
|
|
|
}
|
|
|
|
|
2022-10-26 16:13:17 +00:00
|
|
|
func newImageProber(ctx context.Context, cacheBuilder builder.ImageCacheBuilder, cacheFrom []string, noCache bool) (ImageProber, error) {
|
2017-04-13 22:44:36 +00:00
|
|
|
if noCache {
|
2022-10-26 16:13:17 +00:00
|
|
|
return &nopProber{}, nil
|
|
|
|
}
|
|
|
|
|
|
|
|
reset := func(ctx context.Context) (builder.ImageCache, error) {
|
|
|
|
return cacheBuilder.MakeImageCache(ctx, cacheFrom)
|
2017-04-13 22:44:36 +00:00
|
|
|
}
|
|
|
|
|
2022-10-26 16:13:17 +00:00
|
|
|
cache, err := reset(ctx)
|
|
|
|
if err != nil {
|
|
|
|
return nil, err
|
2017-04-13 22:44:36 +00:00
|
|
|
}
|
2022-10-26 16:13:17 +00:00
|
|
|
return &imageProber{cache: cache, reset: reset}, nil
|
2017-04-13 22:44:36 +00:00
|
|
|
}
|
|
|
|
|
2022-10-26 16:13:17 +00:00
|
|
|
func (c *imageProber) Reset(ctx context.Context) error {
|
|
|
|
newCache, err := c.reset(ctx)
|
|
|
|
if err != nil {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
c.cache = newCache
|
2017-04-13 22:44:36 +00:00
|
|
|
c.cacheBusted = false
|
2022-10-26 16:13:17 +00:00
|
|
|
return nil
|
2017-04-13 22:44:36 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
// 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{}
|
|
|
|
|
2022-10-26 16:13:17 +00:00
|
|
|
func (c *nopProber) Reset(ctx context.Context) error {
|
|
|
|
return nil
|
|
|
|
}
|
2017-04-13 22:44:36 +00:00
|
|
|
|
|
|
|
func (c *nopProber) Probe(_ string, _ *container.Config) (string, error) {
|
|
|
|
return "", nil
|
|
|
|
}
|