From 6f68f8945d8df09be70600e96ee050b74d7d4d23 Mon Sep 17 00:00:00 2001 From: Akihiro Suda Date: Thu, 30 Sep 2021 17:35:24 +0900 Subject: [PATCH] build: support --cache-from and --cache-to Signed-off-by: Akihiro Suda --- README.md | 4 +++- cmd/nerdctl/build.go | 37 +++++++++++++++++++++++++++++ pkg/composer/serviceparser/build.go | 6 ++++- 3 files changed, 45 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 616887dfe3c..74857b56ebe 100644 --- a/README.md +++ b/README.md @@ -603,8 +603,10 @@ Flags: - :whale: `--secret`: Secret file to expose to the build: id=mysecret,src=/local/secret - :whale: `--ssh`: SSH agent socket or keys to expose to the build (format: `default|[=|[,]]`) - :whale: `-q, --quiet`: Suppress the build output and print image ID on success +- :whale: `--cache-from=CACHE`: External cache sources (eg. user/app:cache, type=local,src=path/to/dir) (compatible with `docker buildx build`) +- :whale: `--cache-to=CACHE`: Cache export destinations (eg. user/app:cache, type=local,dest=path/to/dir) (compatible with `docker buildx build`) -Unimplemented `docker build` flags: `--add-host`, `--cache-from`, `--iidfile`, `--label`, `--network`, `--platform`, `--squash` +Unimplemented `docker build` flags: `--add-host`, `--iidfile`, `--label`, `--network`, `--platform`, `--squash` ### :whale: nerdctl commit Create a new image from a container's changes diff --git a/cmd/nerdctl/build.go b/cmd/nerdctl/build.go index a0afd0a0482..928ede461b3 100644 --- a/cmd/nerdctl/build.go +++ b/cmd/nerdctl/build.go @@ -20,6 +20,7 @@ import ( "io" "os" "os/exec" + "strconv" "strings" "path/filepath" @@ -89,6 +90,14 @@ var buildCommand = &cli.Command{ Aliases: []string{"q"}, Usage: "Suppress the build output and print image ID on success", }, + &cli.StringSliceFlag{ + Name: "cache-from", + Usage: "External cache sources (eg. user/app:cache, type=local,src=path/to/dir)", + }, + &cli.StringSliceFlag{ + Name: "cache-to", + Usage: "Cache export destinations (eg. user/app:cache, type=local,dest=path/to/dir)", + }, }, } @@ -192,6 +201,20 @@ func generateBuildctlArgs(clicontext *cli.Context) (string, []string, bool, erro for _, ba := range strutil.DedupeStrSlice(clicontext.StringSlice("build-arg")) { buildctlArgs = append(buildctlArgs, "--opt=build-arg:"+ba) + + // Support `--build-arg BUILDKIT_INLINE_CACHE=1` for compatibility with `docker buildx build` + // https://github.com/docker/buildx/blob/v0.6.3/docs/reference/buildx_build.md#-export-build-cache-to-an-external-cache-destination---cache-to + if strings.HasPrefix(ba, "BUILDKIT_INLINE_CACHE=") { + bic := strings.TrimPrefix(ba, "BUILDKIT_INLINE_CACHE=") + bicParsed, err := strconv.ParseBool(bic) + if err == nil { + if bicParsed { + buildctlArgs = append(buildctlArgs, "--export-cache=type=inline") + } + } else { + logrus.WithError(err).Warnf("invalid BUILDKIT_INLINE_CACHE: %q", bic) + } + } } if clicontext.Bool("no-cache") { @@ -206,5 +229,19 @@ func generateBuildctlArgs(clicontext *cli.Context) (string, []string, bool, erro buildctlArgs = append(buildctlArgs, "--ssh="+s) } + for _, s := range strutil.DedupeStrSlice(clicontext.StringSlice("cache-from")) { + if !strings.Contains(s, "type=") { + s = "type=registry,ref=" + s + } + buildctlArgs = append(buildctlArgs, "--import-cache="+s) + } + + for _, s := range strutil.DedupeStrSlice(clicontext.StringSlice("cache-to")) { + if !strings.Contains(s, "type=") { + s = "type=registry,ref=" + s + } + buildctlArgs = append(buildctlArgs, "--export-cache="+s) + } + return buildctlBinary, buildctlArgs, needsLoading, nil } diff --git a/pkg/composer/serviceparser/build.go b/pkg/composer/serviceparser/build.go index 87e6dfe7d27..e9cebce216d 100644 --- a/pkg/composer/serviceparser/build.go +++ b/pkg/composer/serviceparser/build.go @@ -29,7 +29,7 @@ import ( func parseBuildConfig(c *types.BuildConfig, project *types.Project, imageName string) (*Build, error) { if unknown := reflectutil.UnknownNonEmptyFields(c, - "Context", "Dockerfile", "Args", "Target", + "Context", "Dockerfile", "Args", "CacheFrom", "Target", ); len(unknown) > 0 { logrus.Warnf("Ignoring: build: %+v", unknown) } @@ -66,6 +66,10 @@ func parseBuildConfig(c *types.BuildConfig, project *types.Project, imageName st } } + for _, s := range c.CacheFrom { + b.BuildArgs = append(b.BuildArgs, "--cache-from="+s) + } + if c.Target != "" { b.BuildArgs = append(b.BuildArgs, "--target="+c.Target) }