From ca07b658a00f406cd88c0eeffe8902f9ccff1cb2 Mon Sep 17 00:00:00 2001 From: Darshan Kumar Date: Fri, 2 Jun 2023 11:54:04 +0530 Subject: [PATCH] add helper functions for extend using daemon Signed-off-by: Darshan Kumar --- internal/build/docker.go | 1 + internal/build/helper.go | 90 +++++++++++++++++++++++++++ internal/build/lifecycle_execution.go | 40 ++++++++++-- pkg/client/docker.go | 1 + 4 files changed, 127 insertions(+), 5 deletions(-) create mode 100644 internal/build/helper.go diff --git a/internal/build/docker.go b/internal/build/docker.go index 58a53f343..064795a5e 100644 --- a/internal/build/docker.go +++ b/internal/build/docker.go @@ -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) } diff --git a/internal/build/helper.go b/internal/build/helper.go new file mode 100644 index 000000000..c848060b7 --- /dev/null +++ b/internal/build/helper.go @@ -0,0 +1,90 @@ +package build + +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 +} + +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 +} + +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) + return nil +} + +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 + } + return group.GroupExtensions, err +} + +func escapeID(id string) string { + return strings.ReplaceAll(id, "/", "_") +} diff --git a/internal/build/lifecycle_execution.go b/internal/build/lifecycle_execution.go index 485508aa6..52adecbcc 100644 --- a/internal/build/lifecycle_execution.go +++ b/internal/build/lifecycle_execution.go @@ -7,10 +7,13 @@ import ( "os" "path/filepath" "strconv" + "time" + + "github.com/BurntSushi/toml" "github.com/buildpacks/pack/pkg/cache" - "github.com/BurntSushi/toml" + // "github.com/buildpacks/pack/pkg/archive" "github.com/buildpacks/lifecycle/api" "github.com/buildpacks/lifecycle/auth" "github.com/google/go-containerregistry/pkg/authn" @@ -247,10 +250,17 @@ 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 { + 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) + }) + } } if err := group.Wait(); err != nil { @@ -413,6 +423,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))), envOp, ) @@ -707,6 +721,22 @@ func (l *LifecycleExecution) ExtendRun(ctx context.Context, buildCache Cache, ph return extend.Run(ctx) } +func (l *LifecycleExecution) ExtendRunByDaemon(ctx context.Context) error { + var extensions Extensions + l.logger.Debugf("extending run image %s", l.opts.RunImage) + 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) + time.Sleep(10 * time.Minute) + return nil + // buildContest := archive.ReadDirAsTar(filepath.Join(l.tmpDir,"generated","run"),"/",0,0,-1,true,false) +} + func determineDefaultProcessType(platformAPI *api.Version, providedValue string) string { shouldSetForceDefault := platformAPI.Compare(api.MustParse("0.4")) >= 0 && platformAPI.Compare(api.MustParse("0.6")) < 0 diff --git a/pkg/client/docker.go b/pkg/client/docker.go index 0ae1b4880..a825d6821 100644 --- a/pkg/client/docker.go +++ b/pkg/client/docker.go @@ -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) }