Skip to content

Commit

Permalink
Container Image Caching (#505)
Browse files Browse the repository at this point in the history
* added image caching

* fix testing

* feedback updates
  • Loading branch information
dbw7 committed Jul 26, 2024
1 parent 22ad378 commit 837fa6c
Show file tree
Hide file tree
Showing 7 changed files with 51 additions and 15 deletions.
1 change: 1 addition & 0 deletions RELEASE_NOTES.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
* Artifact sources origin and metadata are now extracted from a configuration file (`config/artifacts.yaml`)
* Dropped `-chart` suffix from installed Helm chart names
* Added ability to build aarch64 images on an aarch64 host machine
* Added caching for container images

## API

Expand Down
7 changes: 1 addition & 6 deletions pkg/cache/cache.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,12 +17,7 @@ type Cache struct {
cacheDir string
}

func New(rootDir string) (*Cache, error) {
cacheDir := filepath.Join(rootDir, "cache")
if err := os.MkdirAll(cacheDir, os.ModePerm); err != nil {
return nil, fmt.Errorf("creating a cache directory: %w", err)
}

func New(cacheDir string) (*Cache, error) {
return &Cache{cacheDir: cacheDir}, nil
}

Expand Down
5 changes: 4 additions & 1 deletion pkg/cache/cache_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,10 @@ import (
)

func setup(t *testing.T) (cache *Cache, teardown func()) {
cache, err := New("test-cache")
cacheDir := "test-cache"
assert.NoError(t, os.MkdirAll(cacheDir, os.ModePerm))

cache, err := New(cacheDir)
require.NoError(t, err)

return cache, func() {
Expand Down
30 changes: 23 additions & 7 deletions pkg/combustion/registry.go
Original file line number Diff line number Diff line change
Expand Up @@ -207,6 +207,11 @@ func registryArtefactsPath(ctx *image.Context) string {
}

func populateRegistry(ctx *image.Context, images []string) error {
imageCacheDir := filepath.Join(ctx.CacheDir, "images")
if err := os.MkdirAll(imageCacheDir, os.ModePerm); err != nil {
return fmt.Errorf("creating container image cache dir: %w", err)
}

bar := progressbar.Default(int64(len(images)), "Populating Embedded Artifact Registry...")
zap.S().Infof("Adding the following images to the embedded artifact registry:\n%s", images)

Expand All @@ -227,18 +232,29 @@ func populateRegistry(ctx *image.Context, images []string) error {
arch := ctx.ImageDefinition.Image.Arch.Short()

for _, img := range images {
if err = storeImage(img, arch, logFile); err != nil {
return fmt.Errorf("adding image to registry store: %w", err)
}

convertedImage := strings.ReplaceAll(img, "/", "_")
convertedImageName := fmt.Sprintf("%s-%s", convertedImage, registryTarSuffix)

imageCacheLocation := filepath.Join(imageCacheDir, convertedImageName)
imageTarDest := filepath.Join(registryArtefactsPath(ctx), convertedImageName)
if err = generateRegistryTar(imageTarDest, logFile); err != nil {
return fmt.Errorf("generating registry store tarball: %w", err)
}

if fileio.FileExists(imageCacheLocation) {
if err = fileio.CopyFile(imageCacheLocation, imageTarDest, fileio.NonExecutablePerms); err != nil {
return fmt.Errorf("copying cached container image: %w", err)
}
} else {
if err = storeImage(img, arch, logFile); err != nil {
return fmt.Errorf("adding image to registry store: %w", err)
}

if err = generateRegistryTar(imageTarDest, logFile); err != nil {
return fmt.Errorf("generating registry store tarball: %w", err)
}

if err = fileio.CopyFile(imageTarDest, imageCacheLocation, fileio.NonExecutablePerms); err != nil {
return fmt.Errorf("copying container image to cache: %w", err)
}
}
if err = bar.Add(1); err != nil {
zap.S().Debugf("Error incrementing the progress bar: %s", err)
}
Expand Down
8 changes: 7 additions & 1 deletion pkg/eib/eib.go
Original file line number Diff line number Diff line change
Expand Up @@ -126,6 +126,12 @@ func appendHelm(ctx *image.Context) {
}

func buildCombustion(ctx *image.Context, rootDir string) (*combustion.Combustion, error) {
cacheDir := filepath.Join(rootDir, "cache")
if err := os.MkdirAll(cacheDir, os.ModePerm); err != nil {
return nil, fmt.Errorf("creating a cache directory: %w", err)
}
ctx.CacheDir = cacheDir

combustionHandler := &combustion.Combustion{
NetworkConfigGenerator: network.ConfigGenerator{},
NetworkConfiguratorInstaller: network.ConfiguratorInstaller{},
Expand Down Expand Up @@ -157,7 +163,7 @@ func buildCombustion(ctx *image.Context, rootDir string) (*combustion.Combustion
}

if ctx.ImageDefinition.Kubernetes.Version != "" {
c, err := cache.New(rootDir)
c, err := cache.New(cacheDir)
if err != nil {
return nil, fmt.Errorf("initialising cache instance: %w", err)
}
Expand Down
13 changes: 13 additions & 0 deletions pkg/fileio/file_io.go
Original file line number Diff line number Diff line change
Expand Up @@ -130,3 +130,16 @@ func createFileWithPerms(dest string, perms os.FileMode) (*os.File, error) {

return file, nil
}

func FileExists(filePath string) bool {
if _, err := os.Stat(filePath); err != nil {
if errors.Is(err, os.ErrNotExist) {
return false
}

zap.S().Warnf("Searching for file at (%s) failed: %s", filePath, err)
return false
}

return true
}
2 changes: 2 additions & 0 deletions pkg/image/context.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,8 @@ type Context struct {
ImageDefinition *Definition
// ArtifactSources contains the information necessary for the deployment of external artifacts.
ArtifactSources *ArtifactSources
// CacheDir contains all of the artifacts that are cached for the build process.
CacheDir string
}

type ArtifactSources struct {
Expand Down

0 comments on commit 837fa6c

Please sign in to comment.