Skip to content

Commit

Permalink
chore(internal/provider): refactor cached_image_resource (#46)
Browse files Browse the repository at this point in the history
Addresses some non-blocking comments from #44:

- Extracts some of the functions in cached_image_resource.go to separate internal packages tfutil and imgutil.
- Some other functions are extracted to helpers.go.
- Extracts non-overridable flags to a package-level variable.
- Pre-allocates some slices where possible.
- Removes some unused code and renames some existing code for readability
  • Loading branch information
johnstcn authored Sep 4, 2024
1 parent 23f2cf5 commit 482a446
Show file tree
Hide file tree
Showing 7 changed files with 472 additions and 420 deletions.
103 changes: 103 additions & 0 deletions internal/imgutil/imgutil.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,103 @@
package imgutil

import (
"archive/tar"
"context"
"fmt"
"io"
"os"
"path/filepath"

"github.com/coder/envbuilder/constants"
"github.com/google/go-containerregistry/pkg/authn"
"github.com/google/go-containerregistry/pkg/name"
v1 "github.com/google/go-containerregistry/pkg/v1"
"github.com/google/go-containerregistry/pkg/v1/remote"
"github.com/hashicorp/terraform-plugin-log/tflog"
)

// GetRemoteImage fetches the image manifest of the image.
func GetRemoteImage(imgRef string) (v1.Image, error) {
ref, err := name.ParseReference(imgRef)
if err != nil {
return nil, fmt.Errorf("parse reference: %w", err)
}

img, err := remote.Image(ref, remote.WithAuthFromKeychain(authn.DefaultKeychain))
if err != nil {
return nil, fmt.Errorf("check remote image: %w", err)
}

return img, nil
}

// ExtractEnvbuilderFromImage reads the image located at imgRef and extracts
// MagicBinaryLocation to destPath.
func ExtractEnvbuilderFromImage(ctx context.Context, imgRef, destPath string) error {
needle := filepath.Clean(constants.MagicBinaryLocation)[1:] // skip leading '/'
img, err := GetRemoteImage(imgRef)
if err != nil {
return fmt.Errorf("check remote image: %w", err)
}

layers, err := img.Layers()
if err != nil {
return fmt.Errorf("get image layers: %w", err)
}

// Check the layers in reverse order. The last layers are more likely to
// include the binary.
for i := len(layers) - 1; i >= 0; i-- {
ul, err := layers[i].Uncompressed()
if err != nil {
return fmt.Errorf("get uncompressed layer: %w", err)
}

tr := tar.NewReader(ul)
for {
th, err := tr.Next()
if err == io.EOF {
break
}

if err != nil {
return fmt.Errorf("read tar header: %w", err)
}

name := filepath.Clean(th.Name)
if th.Typeflag != tar.TypeReg {
tflog.Debug(ctx, "skip non-regular file", map[string]any{"name": name, "layer_idx": i + 1})
continue
}

if name != needle {
tflog.Debug(ctx, "skip file", map[string]any{"name": name, "layer_idx": i + 1})
continue
}

tflog.Debug(ctx, "found file", map[string]any{"name": name, "layer_idx": i + 1})
if err := os.MkdirAll(filepath.Dir(destPath), 0o755); err != nil {
return fmt.Errorf("create parent directories: %w", err)
}
destF, err := os.Create(destPath)
if err != nil {
return fmt.Errorf("create dest file for writing: %w", err)
}
defer destF.Close()
_, err = io.Copy(destF, tr)
if err != nil {
return fmt.Errorf("copy dest file from image: %w", err)
}
if err := destF.Close(); err != nil {
return fmt.Errorf("close dest file: %w", err)
}

if err := os.Chmod(destPath, 0o755); err != nil {
return fmt.Errorf("chmod file: %w", err)
}
return nil
}
}

return fmt.Errorf("extract envbuilder binary from image %q: %w", imgRef, os.ErrNotExist)
}
Loading

0 comments on commit 482a446

Please sign in to comment.