From cec33f0c84e0ba1539d30a370a4e5f5748930bed Mon Sep 17 00:00:00 2001 From: Avi Deitcher Date: Fri, 23 Sep 2022 13:04:46 +0300 Subject: [PATCH] allow setting cache dir via env var Signed-off-by: Avi Deitcher --- src/cmd/linuxkit/build.go | 11 +++++------ src/cmd/linuxkit/cache_clean.go | 10 ++++++---- src/cmd/linuxkit/cache_export.go | 6 ++++-- src/cmd/linuxkit/cache_ls.go | 6 ++++-- src/cmd/linuxkit/pkg_build.go | 7 +++++-- src/cmd/linuxkit/util.go | 25 +++++++++++++++++++++++++ 6 files changed, 49 insertions(+), 16 deletions(-) diff --git a/src/cmd/linuxkit/build.go b/src/cmd/linuxkit/build.go index 88f3573ba..e98cc5507 100644 --- a/src/cmd/linuxkit/build.go +++ b/src/cmd/linuxkit/build.go @@ -51,9 +51,10 @@ func build(args []string) { buildPull := buildCmd.Bool("pull", false, "Always pull images") buildDocker := buildCmd.Bool("docker", false, "Check for images in docker before linuxkit cache") buildDecompressKernel := buildCmd.Bool("decompress-kernel", false, "Decompress the Linux kernel (default false)") - buildCacheDir := buildCmd.String("cache", defaultLinuxkitCache(), "Directory for caching and finding cached image") buildCmd.Var(&buildFormats, "format", "Formats to create [ "+strings.Join(outputTypes, " ")+" ]") buildArch := buildCmd.String("arch", runtime.GOARCH, "target architecture for which to build") + cacheDir := flagOverEnvVarOverDefaultString{def: defaultLinuxkitCache(), envVar: envVarCacheDir} + buildCmd.Var(&cacheDir, "cache", fmt.Sprintf("Directory for caching and finding cached image, overrides env var %s", envVarCacheDir)) if err := buildCmd.Parse(args); err != nil { log.Fatal("Unable to parse args") @@ -98,8 +99,6 @@ func build(args []string) { } } - cacheDir := *buildCacheDir - if len(buildFormats) == 1 && moby.Streamable(buildFormats[0]) { if *buildOutputFile == "" { *buildOutputFile = filepath.Join(*buildDir, name+"."+buildFormats[0]) @@ -108,7 +107,7 @@ func build(args []string) { *buildDir = "" } } else { - err := moby.ValidateFormats(buildFormats, cacheDir) + err := moby.ValidateFormats(buildFormats, cacheDir.String()) if err != nil { log.Errorf("Error parsing formats: %v", err) buildCmd.Usage() @@ -204,7 +203,7 @@ func build(args []string) { if moby.Streamable(buildFormats[0]) { tp = buildFormats[0] } - err = moby.Build(m, w, moby.BuildOpts{Pull: *buildPull, BuilderType: tp, DecompressKernel: *buildDecompressKernel, CacheDir: cacheDir, DockerCache: *buildDocker, Arch: *buildArch}) + err = moby.Build(m, w, moby.BuildOpts{Pull: *buildPull, BuilderType: tp, DecompressKernel: *buildDecompressKernel, CacheDir: cacheDir.String(), DockerCache: *buildDocker, Arch: *buildArch}) if err != nil { log.Fatalf("%v", err) } @@ -216,7 +215,7 @@ func build(args []string) { } log.Infof("Create outputs:") - err = moby.Formats(filepath.Join(*buildDir, name), image, buildFormats, size, cacheDir) + err = moby.Formats(filepath.Join(*buildDir, name), image, buildFormats, size, cacheDir.String()) if err != nil { log.Fatalf("Error writing outputs: %v", err) } diff --git a/src/cmd/linuxkit/cache_clean.go b/src/cmd/linuxkit/cache_clean.go index 24bcbfccc..5fa02a841 100644 --- a/src/cmd/linuxkit/cache_clean.go +++ b/src/cmd/linuxkit/cache_clean.go @@ -2,6 +2,7 @@ package main import ( "flag" + "fmt" "os" log "github.com/sirupsen/logrus" @@ -10,14 +11,15 @@ import ( func cacheClean(args []string) { flags := flag.NewFlagSet("clean", flag.ExitOnError) - cacheDir := flags.String("cache", defaultLinuxkitCache(), "Directory for caching and finding cached image") + cacheDir := flagOverEnvVarOverDefaultString{def: defaultLinuxkitCache(), envVar: envVarCacheDir} + flags.Var(&cacheDir, "cache", fmt.Sprintf("Directory for caching and finding cached image, overrides env var %s", envVarCacheDir)) if err := flags.Parse(args); err != nil { log.Fatal("Unable to parse args") } - if err := os.RemoveAll(*cacheDir); err != nil { - log.Fatalf("Unable to clean cache %s: %v", *cacheDir, err) + if err := os.RemoveAll(cacheDir.String()); err != nil { + log.Fatalf("Unable to clean cache %s: %v", cacheDir, err) } - log.Infof("Cache cleaned: %s", *cacheDir) + log.Infof("Cache cleaned: %s", cacheDir) } diff --git a/src/cmd/linuxkit/cache_export.go b/src/cmd/linuxkit/cache_export.go index 2b02ab23a..d058f1e8d 100644 --- a/src/cmd/linuxkit/cache_export.go +++ b/src/cmd/linuxkit/cache_export.go @@ -2,6 +2,7 @@ package main import ( "flag" + "fmt" "io" "os" "runtime" @@ -15,7 +16,8 @@ import ( func cacheExport(args []string) { fs := flag.NewFlagSet("export", flag.ExitOnError) - cacheDir := fs.String("cache", defaultLinuxkitCache(), "Directory for caching and finding cached image") + cacheDir := flagOverEnvVarOverDefaultString{def: defaultLinuxkitCache(), envVar: envVarCacheDir} + fs.Var(&cacheDir, "cache", fmt.Sprintf("Directory for caching and finding cached image, overrides env var %s", envVarCacheDir)) arch := fs.String("arch", runtime.GOARCH, "Architecture to resolve an index to an image, if the provided image name is an index") outfile := fs.String("outfile", "", "Path to file to save output, '-' for stdout") format := fs.String("format", "oci", "export format, one of 'oci', 'filesystem'") @@ -33,7 +35,7 @@ func cacheExport(args []string) { name := names[0] fullname := util.ReferenceExpand(name) - p, err := cachepkg.NewProvider(*cacheDir) + p, err := cachepkg.NewProvider(cacheDir.String()) if err != nil { log.Fatalf("unable to read a local cache: %v", err) } diff --git a/src/cmd/linuxkit/cache_ls.go b/src/cmd/linuxkit/cache_ls.go index b288101c5..07d6cb37a 100644 --- a/src/cmd/linuxkit/cache_ls.go +++ b/src/cmd/linuxkit/cache_ls.go @@ -2,6 +2,7 @@ package main import ( "flag" + "fmt" cachepkg "github.com/linuxkit/linuxkit/src/cmd/linuxkit/cache" log "github.com/sirupsen/logrus" @@ -10,14 +11,15 @@ import ( func cacheList(args []string) { flags := flag.NewFlagSet("list", flag.ExitOnError) - cacheDir := flags.String("cache", defaultLinuxkitCache(), "Directory for caching and finding cached image") + cacheDir := flagOverEnvVarOverDefaultString{def: defaultLinuxkitCache(), envVar: envVarCacheDir} + flags.Var(&cacheDir, "cache", fmt.Sprintf("Directory for caching and finding cached image, overrides env var %s", envVarCacheDir)) if err := flags.Parse(args); err != nil { log.Fatal("Unable to parse args") } // list all of the images and content in the cache - p, err := cachepkg.Get(*cacheDir) + p, err := cachepkg.Get(cacheDir.String()) if err != nil { log.Fatalf("unable to read a local cache: %v", err) } diff --git a/src/cmd/linuxkit/pkg_build.go b/src/cmd/linuxkit/pkg_build.go index 6e66adb96..0544f53e0 100644 --- a/src/cmd/linuxkit/pkg_build.go +++ b/src/cmd/linuxkit/pkg_build.go @@ -13,6 +13,7 @@ import ( const ( buildersEnvVar = "LINUXKIT_BUILDERS" + envVarCacheDir = "LINUXKIT_CACHE" // this is the most recent manifest pointed to by moby/buildkit:master as of 2022-07-22, so it includes // our required commit. Once there is a normal semver tag later than this, we should switch to it. defaultBuilderImage = "moby/buildkit@sha256:19c4637f8809f21af01dedf65f7f0d64636165d8191381ec9d5150fccedbae48" @@ -44,7 +45,8 @@ func pkgBuildPush(args []string, withPush bool) { builders := flags.String("builders", "", "Which builders to use for which platforms, e.g. linux/arm64=docker-context-arm64, overrides defaults and environment variables, see https://github.com/linuxkit/linuxkit/blob/master/docs/packages.md#Providing-native-builder-nodes") builderImage := flags.String("builder-image", defaultBuilderImage, "buildkit builder container image to use") builderRestart := flags.Bool("builder-restart", false, "force restarting builder, even if container with correct name and image exists") - buildCacheDir := flags.String("cache", defaultLinuxkitCache(), "Directory for storing built image, incompatible with --docker") + cacheDir := flagOverEnvVarOverDefaultString{def: defaultLinuxkitCache(), envVar: envVarCacheDir} + flags.Var(&cacheDir, "cache", fmt.Sprintf("Directory for caching and finding cached image, overrides env var %s", envVarCacheDir)) // some logic clarification: // pkg build - always builds unless is in cache @@ -84,7 +86,8 @@ func pkgBuildPush(args []string, withPush bool) { if *ignoreCache { opts = append(opts, pkglib.WithBuildIgnoreCache()) } - opts = append(opts, pkglib.WithBuildCacheDir(*buildCacheDir)) + + opts = append(opts, pkglib.WithBuildCacheDir(cacheDir.String())) if withPush { opts = append(opts, pkglib.WithBuildPush()) diff --git a/src/cmd/linuxkit/util.go b/src/cmd/linuxkit/util.go index 70fb047d5..500199de8 100644 --- a/src/cmd/linuxkit/util.go +++ b/src/cmd/linuxkit/util.go @@ -114,6 +114,31 @@ func stringToIntArray(l string, sep string) ([]int, error) { return i, nil } +// handle string with built-in default, overridden by env var, overridden by CLI flag +type flagOverEnvVarOverDefaultString struct { + value string + def string + envVar string +} + +func (f *flagOverEnvVarOverDefaultString) String() string { + val := f.def + if f.envVar != "" { + if e := os.Getenv(f.envVar); e != "" { + val = e + } + } + if f.value != "" { + val = f.value + } + return val +} + +func (f *flagOverEnvVarOverDefaultString) Set(value string) error { + f.value = value + return nil +} + // Convert a multi-line string into an array of strings func splitLines(in string) []string { res := []string{}