Skip to content

Commit

Permalink
Add --rm flag (and options) to Build
Browse files Browse the repository at this point in the history
This instructs melange to clean up after itself. Currently, this only
applies to the guest container image, but we can expand the scope over
time.

Signed-off-by: Jon Johnson <[email protected]>
  • Loading branch information
jonjohnsonjr committed Feb 6, 2024
1 parent 6e56692 commit b1f4cad
Show file tree
Hide file tree
Showing 7 changed files with 62 additions and 3 deletions.
1 change: 1 addition & 0 deletions docs/md/melange_build.md
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,7 @@ melange build [flags]
--overlay-binsh string use specified file as /bin/sh overlay in build environment
--pipeline-dir string directory used to extend defined built-in pipelines
-r, --repository-append strings path to extra repositories to include in the build environment
--rm clean up intermediate artifacts (e.g. container images)
--runner string which runner to use to enable running commands, default is based on your platform. Options are ["bubblewrap" "docker" "lima" "kubernetes"]
--signing-key string key to use for signing
--source-dir string directory used for included sources
Expand Down
15 changes: 15 additions & 0 deletions pkg/build/build.go
Original file line number Diff line number Diff line change
Expand Up @@ -86,6 +86,7 @@ type Build struct {
containerConfig *container.Config
Debug bool
DebugRunner bool
Remove bool
LogPolicy []string
FailOnLintWarning bool
DefaultCPU string
Expand Down Expand Up @@ -220,6 +221,11 @@ func New(ctx context.Context, opts ...Option) (*Build, error) {
}

func (b *Build) Close() error {
if b.Remove {
if err := b.Runner.OCIImageLoader().RemoveImage(context.TODO(), b.containerConfig.ImgRef); err != nil {
return err
}
}
return b.Runner.Close()
}

Expand Down Expand Up @@ -499,6 +505,15 @@ func WithDebugRunner(debug bool) Option {
}
}

// WithRemove indicates whether the the build will clean up after itself.
// This includes deleting any intermediate artifacts like container images.
func WithRemove(remove bool) Option {
return func(b *Build) error {
b.Remove = remove
return nil
}
}

// WithLogPolicy sets the logging policy to use during builds.
func WithLogPolicy(policy []string) Option {
return func(b *Build) error {
Expand Down
3 changes: 3 additions & 0 deletions pkg/cli/build.go
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,7 @@ func Build() *cobra.Command {
var createBuildLog bool
var debug bool
var debugRunner bool
var remove bool
var runner string
var failOnLintWarning bool
var cpu, memory string
Expand Down Expand Up @@ -107,6 +108,7 @@ func Build() *cobra.Command {
build.WithCreateBuildLog(createBuildLog),
build.WithDebug(debug),
build.WithDebugRunner(debugRunner),
build.WithRemove(remove),
build.WithLogPolicy(logPolicy),
build.WithRunner(runner),
build.WithFailOnLintWarning(failOnLintWarning),
Expand Down Expand Up @@ -160,6 +162,7 @@ func Build() *cobra.Command {
cmd.Flags().BoolVar(&createBuildLog, "create-build-log", false, "creates a package.log file containing a list of packages that were built by the command")
cmd.Flags().BoolVar(&debug, "debug", false, "enables debug logging of build pipelines")
cmd.Flags().BoolVar(&debugRunner, "debug-runner", false, "when enabled, the builder pod will persist after the build succeeds or fails")
cmd.Flags().BoolVar(&remove, "rm", false, "clean up intermediate artifacts (e.g. container images)")
cmd.Flags().BoolVar(&failOnLintWarning, "fail-on-lint-warning", false, "turns linter warnings into failures")
cmd.Flags().StringVar(&cpu, "cpu", "", "default CPU resources to use for builds")
cmd.Flags().StringVar(&memory, "memory", "", "default memory resources to use for builds")
Expand Down
4 changes: 4 additions & 0 deletions pkg/container/bubblewrap_runner.go
Original file line number Diff line number Diff line change
Expand Up @@ -191,3 +191,7 @@ func (b bubblewrapOCILoader) LoadImage(ctx context.Context, layer v1.Layer, arch
}
return guestDir, nil
}

func (b bubblewrapOCILoader) RemoveImage(ctx context.Context, ref string) error {
return os.RemoveAll(ref)
}
33 changes: 30 additions & 3 deletions pkg/container/docker_runner.go
Original file line number Diff line number Diff line change
Expand Up @@ -160,7 +160,9 @@ func (dk *docker) TestUsability(ctx context.Context) bool {

// OCIImageLoader create a loader to load an OCI image into the docker daemon.
func (dk *docker) OCIImageLoader() Loader {
return &dockerLoader{}
return &dockerLoader{
cli: dk.cli,
}
}

// TempDir returns the base for temporary directory. For docker
Expand Down Expand Up @@ -241,9 +243,11 @@ func (dk *docker) WorkspaceTar(ctx context.Context, cfg *Config) (io.ReadCloser,
return nil, nil
}

type dockerLoader struct{}
type dockerLoader struct {
cli *client.Client
}

func (d dockerLoader) LoadImage(ctx context.Context, layer v1.Layer, arch apko_types.Architecture, bc *apko_build.Context) (string, error) {
func (d *dockerLoader) LoadImage(ctx context.Context, layer v1.Layer, arch apko_types.Architecture, bc *apko_build.Context) (string, error) {
ctx, span := otel.Tracer("melange").Start(ctx, "docker.LoadImage")
defer span.End()

Expand All @@ -263,3 +267,26 @@ func (d dockerLoader) LoadImage(ctx context.Context, layer v1.Layer, arch apko_t
}
return ref.String(), nil
}

func (d *dockerLoader) RemoveImage(ctx context.Context, ref string) error {
log := clog.FromContext(ctx)
log.Infof("deleting image %q", ref)
resps, err := d.cli.ImageRemove(ctx, ref, types.ImageRemoveOptions{
Force: true,
PruneChildren: true,
})
if err != nil {
return err
}

for _, resp := range resps {
if resp.Untagged != "" {
log.Infof("untagged %q", resp.Untagged)
}
if resp.Deleted != "" {
log.Infof("deleted %q", resp.Deleted)
}
}

return nil
}
8 changes: 8 additions & 0 deletions pkg/container/kubernetes_runner.go
Original file line number Diff line number Diff line change
Expand Up @@ -680,6 +680,14 @@ func (k *k8sLoader) LoadImage(ctx context.Context, layer ggcrv1.Layer, arch apko
return ref.String(), nil
}

func (k *k8sLoader) RemoveImage(ctx context.Context, str string) error {
ref, err := name.ParseReference(str)
if err != nil {
return err
}
return remote.Delete(ref, remote.WithAuthFromKeychain(authn.DefaultKeychain), remote.WithContext(ctx))
}

type k8sTarFetcher struct {
client kubernetes.Interface
restconfig *rest.Config
Expand Down
1 change: 1 addition & 0 deletions pkg/container/runner.go
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,7 @@ type Runner interface {

type Loader interface {
LoadImage(ctx context.Context, layer v1.Layer, arch apko_types.Architecture, bc *apko_build.Context) (ref string, err error)
RemoveImage(ctx context.Context, ref string) error
}

// GetRunner returns the requested runner implementation.
Expand Down

0 comments on commit b1f4cad

Please sign in to comment.