From 3b477220323d4ded7e0c9b42bba6b6ae87a4dc7e Mon Sep 17 00:00:00 2001 From: Tonis Tiigi Date: Mon, 22 Nov 2021 20:21:35 -0800 Subject: [PATCH 1/3] build: add no-cache-filter Signed-off-by: Tonis Tiigi --- build/build.go | 40 +++++++++++---------- commands/build.go | 64 ++++++++++++++++++---------------- docs/reference/buildx_build.md | 1 + 3 files changed, 57 insertions(+), 48 deletions(-) diff --git a/build/build.go b/build/build.go index 2c9c07e0..9dcecb58 100644 --- a/build/build.go +++ b/build/build.go @@ -56,24 +56,25 @@ var ( type Options struct { Inputs Inputs - Allow []entitlements.Entitlement - BuildArgs map[string]string - CacheFrom []client.CacheOptionsEntry - CacheTo []client.CacheOptionsEntry - CgroupParent string - Exports []client.ExportEntry - ExtraHosts []string - ImageIDFile string - Labels map[string]string - NetworkMode string - NoCache bool - Platforms []specs.Platform - Pull bool - Session []session.Attachable - ShmSize opts.MemBytes - Tags []string - Target string - Ulimits *opts.UlimitOpt + Allow []entitlements.Entitlement + BuildArgs map[string]string + CacheFrom []client.CacheOptionsEntry + CacheTo []client.CacheOptionsEntry + CgroupParent string + Exports []client.ExportEntry + ExtraHosts []string + ImageIDFile string + Labels map[string]string + NetworkMode string + NoCache bool + NoCacheFilter []string + Platforms []specs.Platform + Pull bool + Session []session.Attachable + ShmSize opts.MemBytes + Tags []string + Target string + Ulimits *opts.UlimitOpt } type Inputs struct { @@ -527,6 +528,9 @@ func toSolveOpt(ctx context.Context, d driver.Driver, multiDriver bool, opt Opti if opt.Target != "" { so.FrontendAttrs["target"] = opt.Target } + if len(opt.NoCacheFilter) > 0 { + so.FrontendAttrs["no-cache"] = strings.Join(opt.NoCacheFilter, ",") + } if opt.NoCache { so.FrontendAttrs["no-cache"] = "" } diff --git a/commands/build.go b/commands/build.go index 2e66c583..97c18799 100644 --- a/commands/build.go +++ b/commands/build.go @@ -42,25 +42,26 @@ type buildOptions struct { contextPath string dockerfileName string - allow []string - buildArgs []string - cacheFrom []string - cacheTo []string - cgroupParent string - contexts []string - extraHosts []string - imageIDFile string - labels []string - networkMode string - outputs []string - platforms []string - quiet bool - secrets []string - shmSize dockeropts.MemBytes - ssh []string - tags []string - target string - ulimits *dockeropts.UlimitOpt + allow []string + buildArgs []string + cacheFrom []string + cacheTo []string + cgroupParent string + contexts []string + extraHosts []string + imageIDFile string + labels []string + networkMode string + noCacheFilter []string + outputs []string + platforms []string + quiet bool + secrets []string + shmSize dockeropts.MemBytes + ssh []string + tags []string + target string + ulimits *dockeropts.UlimitOpt commonOptions } @@ -116,17 +117,18 @@ func runBuild(dockerCli command.Cli, in buildOptions) (err error) { InStream: os.Stdin, NamedContexts: contexts, }, - BuildArgs: listToMap(in.buildArgs, true), - ExtraHosts: in.extraHosts, - ImageIDFile: in.imageIDFile, - Labels: listToMap(in.labels, false), - NetworkMode: in.networkMode, - NoCache: noCache, - Pull: pull, - ShmSize: in.shmSize, - Tags: in.tags, - Target: in.target, - Ulimits: in.ulimits, + BuildArgs: listToMap(in.buildArgs, true), + ExtraHosts: in.extraHosts, + ImageIDFile: in.imageIDFile, + Labels: listToMap(in.labels, false), + NetworkMode: in.networkMode, + NoCache: noCache, + NoCacheFilter: in.noCacheFilter, + Pull: pull, + ShmSize: in.shmSize, + Tags: in.tags, + Target: in.target, + Ulimits: in.ulimits, } platforms, err := platformutil.Parse(in.platforms) @@ -363,6 +365,8 @@ func buildCmd(dockerCli command.Cli, rootOpts *rootOptions) *cobra.Command { flags.StringVar(&options.networkMode, "network", "default", `Set the networking mode for the "RUN" instructions during build`) + flags.StringArrayVar(&options.noCacheFilter, "no-cache-filter", []string{}, "Do not cache specified stages") + flags.StringArrayVarP(&options.outputs, "output", "o", []string{}, `Output destination (format: "type=local,dest=path")`) flags.StringArrayVar(&options.platforms, "platform", platformsDefault, "Set target platform for build") diff --git a/docs/reference/buildx_build.md b/docs/reference/buildx_build.md index 2d415394..39ac9ac9 100644 --- a/docs/reference/buildx_build.md +++ b/docs/reference/buildx_build.md @@ -30,6 +30,7 @@ Start a build | `--metadata-file string` | Write build result metadata to the file | | `--network string` | Set the networking mode for the `RUN` instructions during build | | `--no-cache` | Do not use cache when building the image | +| `--no-cache-filter stringArray` | Do not cache specified stages | | [`-o`](#output), [`--output stringArray`](#output) | Output destination (format: `type=local,dest=path`) | | [`--platform stringArray`](#platform) | Set target platform for build | | [`--progress string`](#progress) | Set type of progress output (`auto`, `plain`, `tty`). Use plain to show container output | From 32f6358d787572e8ca2607c6a746dd0ade27fe09 Mon Sep 17 00:00:00 2001 From: Tonis Tiigi Date: Mon, 22 Nov 2021 20:56:29 -0800 Subject: [PATCH 2/3] bake: add no-cache-filter Signed-off-by: Tonis Tiigi --- bake/bake.go | 23 +++++++++++++++-------- bake/compose.go | 8 ++++++++ docs/reference/buildx_bake.md | 4 ++-- 3 files changed, 25 insertions(+), 10 deletions(-) diff --git a/bake/bake.go b/bake/bake.go index 242b2984..114cc3a8 100644 --- a/bake/bake.go +++ b/bake/bake.go @@ -524,7 +524,7 @@ type Target struct { Pull *bool `json:"pull,omitempty" hcl:"pull,optional"` NoCache *bool `json:"no-cache,omitempty" hcl:"no-cache,optional"` NetworkMode *string `json:"-" hcl:"-"` - + NoCacheFilter []string `json:"no-cache-filter,omitempty" hcl:"no-cache-filter,optional"` // IMPORTANT: if you add more fields here, do not forget to update newOverrides and README. } @@ -536,6 +536,7 @@ func (t *Target) normalize() { t.CacheFrom = removeDupes(t.CacheFrom) t.CacheTo = removeDupes(t.CacheTo) t.Outputs = removeDupes(t.Outputs) + t.NoCacheFilter = removeDupes(t.NoCacheFilter) for k, v := range t.Contexts { if v == "" { @@ -608,6 +609,9 @@ func (t *Target) Merge(t2 *Target) { if t2.NetworkMode != nil { t.NetworkMode = t2.NetworkMode } + if t2.NoCacheFilter != nil { // merge + t.NoCacheFilter = append(t.NoCacheFilter, t2.NoCacheFilter...) + } t.Inherits = append(t.Inherits, t2.Inherits...) } @@ -666,6 +670,8 @@ func (t *Target) AddOverrides(overrides map[string]Override) error { return errors.Errorf("invalid value %s for boolean key no-cache", value) } t.NoCache = &noCache + case "no-cache-filter": + t.NoCacheFilter = o.ArrValue case "pull": pull, err := strconv.ParseBool(value) if err != nil { @@ -776,13 +782,14 @@ func toBuildOpt(t *Target, inp *Input) (*build.Options, error) { t.Context = &bi.ContextPath bo := &build.Options{ - Inputs: bi, - Tags: t.Tags, - BuildArgs: t.Args, - Labels: t.Labels, - NoCache: noCache, - Pull: pull, - NetworkMode: networkMode, + Inputs: bi, + Tags: t.Tags, + BuildArgs: t.Args, + Labels: t.Labels, + NoCache: noCache, + NoCacheFilter: t.NoCacheFilter, + Pull: pull, + NetworkMode: networkMode, } platforms, err := platformutil.Parse(t.Platforms) diff --git a/bake/compose.go b/bake/compose.go index 07f2f158..aecd88f9 100644 --- a/bake/compose.go +++ b/bake/compose.go @@ -194,6 +194,14 @@ func (t *Target) composeExtTarget(exts map[string]interface{}) error { if res, ok := val.(bool); ok { t.NoCache = &res } + case "no-cache-filter": + if res, k := val.(string); k { + t.NoCacheFilter = append(t.NoCacheFilter, res) + } else { + for _, res := range val.([]interface{}) { + t.NoCacheFilter = append(t.NoCacheFilter, res.(string)) + } + } default: return fmt.Errorf("compose file invalid: unkwown %s field for x-bake", key) } diff --git a/docs/reference/buildx_bake.md b/docs/reference/buildx_bake.md index 01439f45..8b3e7180 100644 --- a/docs/reference/buildx_bake.md +++ b/docs/reference/buildx_bake.md @@ -340,7 +340,7 @@ target "db" { Complete list of valid target fields: `args`, `cache-from`, `cache-to`, `context`, `contexts`, `dockerfile`, `inherits`, `labels`, -`no-cache`, `output`, `platform`, `pull`, `secrets`, `ssh`, `tags`, `target` +`no-cache`, `no-cache-filter`, `output`, `platform`, `pull`, `secrets`, `ssh`, `tags`, `target` ### Global scope attributes @@ -982,7 +982,7 @@ $ docker buildx bake --print Complete list of valid fields for `x-bake`: `tags`, `cache-from`, `cache-to`, `secret`, `ssh`, `platforms`, `output`, -`pull`, `no-cache` +`pull`, `no-cache`, `no-cache-filter` ### Built-in variables From eb8057e8e0dceddbf3c9bf74b2a21b07ed322bfd Mon Sep 17 00:00:00 2001 From: Tonis Tiigi Date: Thu, 20 Jan 2022 09:50:33 -0800 Subject: [PATCH 3/3] forbid setting no-cache and no-cache-filter together Per review request. Signed-off-by: Tonis Tiigi --- commands/build.go | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/commands/build.go b/commands/build.go index 97c18799..2ebca306 100644 --- a/commands/build.go +++ b/commands/build.go @@ -99,6 +99,10 @@ func runBuild(dockerCli command.Cli, in buildOptions) (err error) { pull = *in.pull } + if noCache && len(in.noCacheFilter) > 0 { + return errors.Errorf("--no-cache and --no-cache-filter cannot currently be used together") + } + if in.quiet && in.progress != "auto" && in.progress != "quiet" { return errors.Errorf("progress=%s and quiet cannot be used together", in.progress) } else if in.quiet {