Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions cmd/image-builder/export_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ var (
DescribeImage = describeImage
ProgressFromCmd = progressFromCmd
BasenameFor = basenameFor
DefaultCacheDir = defaultCacheDir
)

type DescribeImgYAML describeImgYAML
Expand Down
28 changes: 26 additions & 2 deletions cmd/image-builder/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import (
"log"
"os"
"os/signal"
"path/filepath"

"strings"
"syscall"
Expand Down Expand Up @@ -37,6 +38,25 @@ var (
osStderr io.Writer = os.Stderr
)

// defaultCacheDir returns the default cache directory for osbuild
// intermediate build artifacts. When running as root it uses the
// system-wide /var/cache path. When running as a non-root user it
// follows the XDG Base Directory specification and falls back to
// ~/.cache.
func defaultCacheDir() string {
if os.Getuid() == 0 {
return "/var/cache/image-builder/store"
}
if cacheHome := os.Getenv("XDG_CACHE_HOME"); cacheHome != "" {
return filepath.Join(cacheHome, "image-builder", "store")
}
home, err := os.UserHomeDir()
if err != nil {
return "/var/cache/image-builder/store"
}
return filepath.Join(home, ".cache", "image-builder", "store")
}

// basenameFor returns the basename for directory and filenames
// for the given imageType. This can be user overriden via userBasename.
func basenameFor(img *imagefilter.Result, userBasename string) string {
Expand Down Expand Up @@ -440,7 +460,11 @@ func cmdBuild(cmd *cobra.Command, args []string) error {
if err != nil {
return err
}
// XXX: check env here, i.e. if user is root and osbuild is installed
// Fail early if the cache directory is not writable, instead of
// waiting for osbuild to fail after slow manifest generation.
if err := os.MkdirAll(cacheDir, 0755); err != nil {
return fmt.Errorf("cannot create cache directory %q: %w\nHint: use --cache to specify a writable path", cacheDir, err)
}
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is nice.


// Setup osbuild environment if running in a container
if setup.IsContainer() {
Expand Down Expand Up @@ -701,7 +725,7 @@ operating systems like Fedora, CentOS and RHEL with easy customizations support.
buildCmd.Flags().AddFlagSet(manifestCmd.Flags())
buildCmd.Flags().Bool("with-manifest", false, `export osbuild manifest`)
buildCmd.Flags().Bool("with-buildlog", false, `export osbuild buildlog`)
buildCmd.Flags().String("cache", "/var/cache/image-builder/store", `osbuild directory to cache intermediate build artifacts"`)
buildCmd.Flags().String("cache", defaultCacheDir(), `osbuild directory to cache intermediate build artifacts"`)
// XXX: add "--verbose" here, similar to how bib is doing this
// (see https://github.com/osbuild/bootc-image-builder/pull/790/commits/5cec7ffd8a526e2ca1e8ada0ea18f927695dfe43)
buildCmd.Flags().String("progress", "auto", "type of progress bar to use (e.g. verbose,term)")
Expand Down
26 changes: 26 additions & 0 deletions cmd/image-builder/main_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -1115,3 +1115,29 @@ customizations.FIPS = true
})
}
}

func TestDefaultCacheDirAsRoot(t *testing.T) {
if os.Getuid() != 0 {
t.Skip("test requires running as root")
}
assert.Equal(t, "/var/cache/image-builder/store", main.DefaultCacheDir())
}

func TestDefaultCacheDirNonRootXDG(t *testing.T) {
if os.Getuid() == 0 {
t.Skip("test requires running as non-root")
}
t.Setenv("XDG_CACHE_HOME", "/tmp/test-xdg-cache")
assert.Equal(t, "/tmp/test-xdg-cache/image-builder/store", main.DefaultCacheDir())
}

func TestDefaultCacheDirNonRootFallback(t *testing.T) {
if os.Getuid() == 0 {
t.Skip("test requires running as non-root")
}
t.Setenv("XDG_CACHE_HOME", "")
home, err := os.UserHomeDir()
require.NoError(t, err)
expected := filepath.Join(home, ".cache", "image-builder", "store")
assert.Equal(t, expected, main.DefaultCacheDir())
}
Loading