Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

add support for pack to extend base images using daemon #1791

Draft
wants to merge 34 commits into
base: main
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from 2 commits
Commits
Show all changes
34 commits
Select commit Hold shift + click to select a range
ca07b65
add helper functions for extend using daemon
itsdarshankumar Jun 2, 2023
abdf62c
add buildImage by daemon
itsdarshankumar Jun 2, 2023
5c460c5
extract layers and extend the export phase
itsdarshankumar Jun 11, 2023
8710e46
implements build image extension by daemon
itsdarshankumar Jun 25, 2023
88c8fbd
adds execution measurement
itsdarshankumar Jun 25, 2023
b8295c5
adds mockDaemon and unit test
itsdarshankumar Aug 6, 2023
98fd87d
add tests for multiple buildextend
itsdarshankumar Aug 16, 2023
4ad4631
adds functionality to fetch args from config
itsdarshankumar Aug 17, 2023
9466204
remove run extend
itsdarshankumar Aug 23, 2023
0e2fce6
remove profiling and add comments
itsdarshankumar Aug 23, 2023
c8ac171
Merge changes from main branch
itsdarshankumar Aug 23, 2023
888d1a8
fix logger for daemon extend
itsdarshankumar Aug 26, 2023
f935dd2
fix tests
itsdarshankumar Aug 26, 2023
38d0278
add tarwriter for single file and include workspace in context
itsdarshankumar Aug 30, 2023
b69ddad
Merge changes from main branch
itsdarshankumar Aug 30, 2023
aa78c43
skip test for windows
itsdarshankumar Aug 30, 2023
57f88a2
remove redundant logs
itsdarshankumar Aug 30, 2023
72c6fde
add tests for helper functions
itsdarshankumar Oct 8, 2023
02858bf
Merge branch 'main' into run-extend
itsdarshankumar Oct 8, 2023
d33f1df
Merge branch 'main' into run-extend
natalieparellano Nov 14, 2023
40ca4f6
Merge branch 'buildpacks:main' into run-extend
itsdarshankumar Dec 15, 2023
3ca6ad1
adds test for file-to-tar and fixes loggers
itsdarshankumar Dec 15, 2023
e401acd
fixes linting of imports
itsdarshankumar Dec 15, 2023
cd7ee2e
Merge branch 'main' into run-extend
natalieparellano Dec 20, 2023
77a2c5c
Merge branch 'main' into run-extend
itsdarshankumar Dec 25, 2023
147699b
adds warnings over UID and GID
itsdarshankumar Dec 26, 2023
1311893
adds note in help and phase to notifiy the nomenclature
itsdarshankumar Dec 26, 2023
3e64a54
remove kaniko caching for build extend
itsdarshankumar Dec 26, 2023
bb255dc
update subsequent changes in UID and GID to config
itsdarshankumar Dec 26, 2023
c560e9f
fix tests
itsdarshankumar Dec 26, 2023
7cf7e08
remove redundant tests
itsdarshankumar Dec 26, 2023
b416335
Merge branch 'main' into run-extend
natalieparellano Jan 22, 2024
3b52e66
Merge branch 'main' into run-extend
itsdarshankumar Feb 11, 2024
abb040c
Merge branch 'main' into run-extend
itsdarshankumar Mar 1, 2024
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 internal/build/docker.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,4 +21,5 @@ type DockerClient interface {
ContainerInspect(ctx context.Context, container string) (types.ContainerJSON, error)
ContainerRemove(ctx context.Context, container string, options types.ContainerRemoveOptions) error
CopyToContainer(ctx context.Context, container, path string, content io.Reader, options types.CopyToContainerOptions) error
ImageBuild(ctx context.Context, buildContext io.Reader, options types.ImageBuildOptions) (types.ImageBuildResponse, error)
}
90 changes: 90 additions & 0 deletions internal/build/helper.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,90 @@
package build
natalieparellano marked this conversation as resolved.
Show resolved Hide resolved

import (
"fmt"
"os"
"path/filepath"
"strings"

"github.com/BurntSushi/toml"
"github.com/buildpacks/lifecycle/buildpack"
"github.com/buildpacks/lifecycle/cmd"

"github.com/buildpacks/pack/pkg/logging"
)

const (
DockerfileKindBuild = "build"
DockerfileKindRun = "run"
)

type Extensions struct {
Extensions []buildpack.GroupElement
}
natalieparellano marked this conversation as resolved.
Show resolved Hide resolved

func (extensions *Extensions) DockerFiles(kind string, path string, logger logging.Logger) ([]buildpack.DockerfileInfo, error) {
var dockerfiles []buildpack.DockerfileInfo
for _, ext := range extensions.Extensions {
dockerfile, err := extensions.ReadDockerFile(path, kind, ext.ID)
if err != nil {
return nil, err
}
if dockerfile != nil {
logger.Debugf("Found %s Dockerfile for extension '%s'", kind, ext.ID)
switch kind {
case DockerfileKindBuild:
// will implement later
case DockerfileKindRun:
buildpack.ValidateRunDockerfile(dockerfile, logger)
default:
return nil, fmt.Errorf("unknown dockerfile kind: %s", kind)
}
dockerfiles = append(dockerfiles, *dockerfile)
}
}
return dockerfiles, nil
}

func (extensions *Extensions) ReadDockerFile(path string, kind string, extID string) (*buildpack.DockerfileInfo, error) {
dockerfilePath := filepath.Join(path, kind, escapeID(extID), "Dockerfile")
if _, err := os.Stat(dockerfilePath); err != nil {
return nil, nil
}
return &buildpack.DockerfileInfo{
ExtensionID: extID,
Kind: kind,
Path: dockerfilePath,
}, nil
}
natalieparellano marked this conversation as resolved.
Show resolved Hide resolved

func (extensions *Extensions) SetExtensions(path string, logger logging.Logger) error {
groupExt, err := readExtensionsGroup(path)
if err != nil {
return fmt.Errorf("reading group: %w", err)
}
for i := range groupExt {
groupExt[i].Extension = true
}
for _, groupEl := range groupExt {
if err = cmd.VerifyBuildpackAPI(groupEl.Kind(), groupEl.String(), groupEl.API, logger); err != nil {
return err
}
}
extensions.Extensions = groupExt
fmt.Println("extensions.Extensions", extensions.Extensions)
itsdarshankumar marked this conversation as resolved.
Show resolved Hide resolved
itsdarshankumar marked this conversation as resolved.
Show resolved Hide resolved
return nil
}
itsdarshankumar marked this conversation as resolved.
Show resolved Hide resolved

func readExtensionsGroup(path string) ([]buildpack.GroupElement, error) {
var group buildpack.Group
_, err := toml.DecodeFile(filepath.Join(path, "group.toml"), &group)
for e := range group.GroupExtensions {
group.GroupExtensions[e].Extension = true
group.GroupExtensions[e].Optional = true
itsdarshankumar marked this conversation as resolved.
Show resolved Hide resolved
}
return group.GroupExtensions, err
}

func escapeID(id string) string {
return strings.ReplaceAll(id, "/", "_")
}
71 changes: 65 additions & 6 deletions internal/build/lifecycle_execution.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,16 +3,20 @@ package build
import (
"context"
"fmt"
"io"

"math/rand"
"os"
"path/filepath"
"strconv"

"github.com/BurntSushi/toml"
natalieparellano marked this conversation as resolved.
Show resolved Hide resolved

natalieparellano marked this conversation as resolved.
Show resolved Hide resolved
"github.com/buildpacks/pack/pkg/cache"

"github.com/BurntSushi/toml"
"github.com/buildpacks/lifecycle/api"
"github.com/buildpacks/lifecycle/auth"
"github.com/docker/docker/api/types"
"github.com/google/go-containerregistry/pkg/authn"
"github.com/google/go-containerregistry/pkg/name"
"github.com/pkg/errors"
Expand All @@ -21,6 +25,7 @@ import (
"github.com/buildpacks/pack/internal/builder"
"github.com/buildpacks/pack/internal/paths"
"github.com/buildpacks/pack/internal/style"
"github.com/buildpacks/pack/pkg/archive"
"github.com/buildpacks/pack/pkg/logging"
)

Expand Down Expand Up @@ -247,12 +252,18 @@ func (l *LifecycleExecution) Run(ctx context.Context, phaseFactoryCreator PhaseF
}

if l.platformAPI.AtLeast("0.12") && l.hasExtensionsForRun() {
group.Go(func() error {
l.logger.Info(style.Step("EXTENDING (RUN)"))
return l.ExtendRun(ctx, buildCache, phaseFactory)
})
if l.opts.Publish {
itsdarshankumar marked this conversation as resolved.
Show resolved Hide resolved
group.Go(func() error {
l.logger.Info(style.Step("EXTENDING (RUN)"))
return l.ExtendRun(ctx, buildCache, phaseFactory)
})
} else {
group.Go(func() error {
l.logger.Info(style.Step("EXTENDING (RUN) BY DAEMON"))
return l.ExtendRunByDaemon(ctx, &currentRunImage)
})
}
}

if err := group.Wait(); err != nil {
return err
}
Expand Down Expand Up @@ -413,6 +424,10 @@ func (l *LifecycleExecution) Detect(ctx context.Context, phaseFactory PhaseFacto
CopyOutToMaybe(filepath.Join(l.mountPaths.layersDir(), "analyzed.toml"), l.tmpDir))),
If(l.hasExtensions(), WithPostContainerRunOperations(
CopyOutToMaybe(filepath.Join(l.mountPaths.layersDir(), "generated", "build"), l.tmpDir))),
If(l.hasExtensions(), WithPostContainerRunOperations(
CopyOutToMaybe(filepath.Join(l.mountPaths.layersDir(), "generated", "run"), l.tmpDir))),
If(l.hasExtensions(), WithPostContainerRunOperations(
CopyOutToMaybe(filepath.Join(l.mountPaths.layersDir(), "group.toml"), l.tmpDir))),
natalieparellano marked this conversation as resolved.
Show resolved Hide resolved
envOp,
)

Expand Down Expand Up @@ -707,6 +722,50 @@ func (l *LifecycleExecution) ExtendRun(ctx context.Context, buildCache Cache, ph
return extend.Run(ctx)
}

func (l *LifecycleExecution) ExtendRunByDaemon(ctx context.Context, currentRunImage *string) error {
defaultFilterFunc := func(file string) bool { return true }
itsdarshankumar marked this conversation as resolved.
Show resolved Hide resolved
var extensions Extensions
l.logger.Debugf("extending run image %s", *currentRunImage)
fmt.Println("tmpDir: ", l.tmpDir)
extensions.SetExtensions(l.tmpDir, l.logger)
dockerfiles, err := extensions.DockerFiles(DockerfileKindRun, l.tmpDir, l.logger)
if err != nil {
return fmt.Errorf("getting %s.Dockerfiles: %w", DockerfileKindRun, err)
}
fmt.Println("Dockerfiles: ", dockerfiles)
fmt.Println("extend: ", dockerfiles[1].Extend)
for _, dockerfile := range dockerfiles {
if dockerfile.Extend {
fmt.Println("dockerfile: ", dockerfile)
fmt.Println("dockerfile.Path dir: ", filepath.Dir(dockerfile.Path))
buildContext := archive.ReadDirAsTar(filepath.Dir(dockerfile.Path), "/", 0, 0, -1, true, false, defaultFilterFunc)
itsdarshankumar marked this conversation as resolved.
Show resolved Hide resolved
fmt.Println("buildContext: ", buildContext)
buildArguments := map[string]*string{}
if dockerfile.WithBase == "" {
buildArguments["base_image"] = currentRunImage
}
buildOptions := types.ImageBuildOptions{
Context: buildContext,
Dockerfile: "Dockerfile",
Tags: []string{"run-image"},
itsdarshankumar marked this conversation as resolved.
Show resolved Hide resolved
Remove: true,
BuildArgs: buildArguments,
itsdarshankumar marked this conversation as resolved.
Show resolved Hide resolved
}
response, err := l.docker.ImageBuild(ctx, buildContext, buildOptions)
if err != nil {
return err
}
defer response.Body.Close()
_, err = io.Copy(os.Stdout, response.Body)
if err != nil {
return err
}
l.logger.Debugf("build response for the extend: %v", response)
}
}
return nil
}

func determineDefaultProcessType(platformAPI *api.Version, providedValue string) string {
shouldSetForceDefault := platformAPI.Compare(api.MustParse("0.4")) >= 0 &&
platformAPI.Compare(api.MustParse("0.6")) < 0
Expand Down
1 change: 1 addition & 0 deletions pkg/client/docker.go
Original file line number Diff line number Diff line change
Expand Up @@ -28,4 +28,5 @@ type DockerClient interface {
ContainerWait(ctx context.Context, container string, condition containertypes.WaitCondition) (<-chan containertypes.WaitResponse, <-chan error)
ContainerAttach(ctx context.Context, container string, options types.ContainerAttachOptions) (types.HijackedResponse, error)
ContainerStart(ctx context.Context, container string, options types.ContainerStartOptions) error
ImageBuild(ctx context.Context, buildContext io.Reader, options types.ImageBuildOptions) (types.ImageBuildResponse, error)
}