From abb2ac053d224d00599f6c828078b94d81e0f0eb Mon Sep 17 00:00:00 2001 From: Rashad Sirajudeen Date: Mon, 6 May 2024 16:25:24 +0530 Subject: [PATCH 1/4] Added case for docker uri for lifecycle Signed-off-by: Rashad Sirajudeen --- pkg/client/create_builder.go | 78 ++++++++++++++++++++++++++++++++++++ 1 file changed, 78 insertions(+) diff --git a/pkg/client/create_builder.go b/pkg/client/create_builder.go index ee1062bc4..fedf96b92 100644 --- a/pkg/client/create_builder.go +++ b/pkg/client/create_builder.go @@ -1,8 +1,12 @@ package client import ( + "archive/tar" "context" "fmt" + "io" + OS "os" + "path/filepath" "sort" "strings" @@ -212,6 +216,43 @@ func (c *Client) fetchLifecycle(ctx context.Context, config pubbldr.LifecycleCon var uri string var err error switch { + case buildpack.HasDockerLocator(config.URI): + var lifecycleImage imgutil.Image + imageName := buildpack.ParsePackageLocator(config.URI) + c.logger.Debugf("Downloading lifecycle image: %s", style.Symbol(imageName)) + + lifecycleImage, err = c.imageFetcher.Fetch(ctx, imageName, image.FetchOptions{Daemon: false}) + if err != nil { + return nil, err + } + + lifecyclePath := filepath.Join(relativeBaseDir, "lifecycle.tar") + layers, err := lifecycleImage.UnderlyingImage().Layers() + if err != nil { + return nil, err + } + + // Assume the last layer has the lifecycle + lifecycleLayer := layers[len(layers)-1] + + layerReader, err := lifecycleLayer.Uncompressed() + if err != nil { + return nil, err + } + defer layerReader.Close() + + file, err := stripTopDirAndWrite(layerReader, lifecyclePath) + if err != nil { + return nil, err + } + + defer file.Close() + // defer OS.Remove(lifecyclePath) + + uri, err = paths.FilePathToURI(lifecyclePath, "") + if err != nil { + return nil, err + } case config.Version != "": v, err := semver.NewVersion(config.Version) if err != nil { @@ -361,3 +402,40 @@ func uriFromLifecycleVersion(version semver.Version, os string, architecture str return fmt.Sprintf("https://github.com/buildpacks/lifecycle/releases/download/v%s/lifecycle-v%s+linux.%s.tgz", version.String(), version.String(), arch) } + +func stripTopDirAndWrite(layerReader io.ReadCloser, outputPath string) (*OS.File, error) { + file, err := OS.Create(outputPath) + if err != nil { + return nil, err + } + + tarWriter := tar.NewWriter(file) + tarReader := tar.NewReader(layerReader) + tarReader.Next() + + for { + header, err := tarReader.Next() + if err == io.EOF { + break + } + if err != nil { + return nil, err + } + + pathSep := string(OS.PathSeparator) + cnbPrefix := fmt.Sprintf("%scnb%s", pathSep, pathSep) + newHeader := *header + newHeader.Name = strings.TrimPrefix(header.Name, cnbPrefix) + + if err := tarWriter.WriteHeader(&newHeader); err != nil { + return nil, err + } + + if _, err := io.Copy(tarWriter, tarReader); err != nil { + return nil, err + } + } + + return file, nil + +} From d7aa0aa2f90169a5336d26b02929a4d3555d6d5a Mon Sep 17 00:00:00 2001 From: Rashad Sirajudeen Date: Mon, 6 May 2024 16:31:43 +0530 Subject: [PATCH 2/4] linter :) Signed-off-by: Rashad Sirajudeen --- pkg/client/create_builder.go | 1 - 1 file changed, 1 deletion(-) diff --git a/pkg/client/create_builder.go b/pkg/client/create_builder.go index fedf96b92..345889920 100644 --- a/pkg/client/create_builder.go +++ b/pkg/client/create_builder.go @@ -437,5 +437,4 @@ func stripTopDirAndWrite(layerReader io.ReadCloser, outputPath string) (*OS.File } return file, nil - } From 92125a7685a95895e410a3a34ea74b96a1cacf9b Mon Sep 17 00:00:00 2001 From: Rashad Sirajudeen Date: Wed, 8 May 2024 19:13:33 +0530 Subject: [PATCH 3/4] Update pkg/client/create_builder.go Co-authored-by: Juan Bustamante Signed-off-by: Rashad Sirajudeen --- pkg/client/create_builder.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pkg/client/create_builder.go b/pkg/client/create_builder.go index 345889920..396417906 100644 --- a/pkg/client/create_builder.go +++ b/pkg/client/create_builder.go @@ -247,7 +247,7 @@ func (c *Client) fetchLifecycle(ctx context.Context, config pubbldr.LifecycleCon } defer file.Close() - // defer OS.Remove(lifecyclePath) +Remove this comment uri, err = paths.FilePathToURI(lifecyclePath, "") if err != nil { From 1e3c3a300d121026da239c6af4f7660e04326a40 Mon Sep 17 00:00:00 2001 From: Rashad Sirajudeen Date: Fri, 17 May 2024 14:58:14 +0530 Subject: [PATCH 4/4] uriFromLifecycleImage Signed-off-by: Rashad Sirajudeen --- pkg/client/create_builder.go | 75 ++++++++++++++++++++---------------- 1 file changed, 41 insertions(+), 34 deletions(-) diff --git a/pkg/client/create_builder.go b/pkg/client/create_builder.go index 396417906..5adf014a6 100644 --- a/pkg/client/create_builder.go +++ b/pkg/client/create_builder.go @@ -217,41 +217,9 @@ func (c *Client) fetchLifecycle(ctx context.Context, config pubbldr.LifecycleCon var err error switch { case buildpack.HasDockerLocator(config.URI): - var lifecycleImage imgutil.Image - imageName := buildpack.ParsePackageLocator(config.URI) - c.logger.Debugf("Downloading lifecycle image: %s", style.Symbol(imageName)) - - lifecycleImage, err = c.imageFetcher.Fetch(ctx, imageName, image.FetchOptions{Daemon: false}) - if err != nil { - return nil, err - } - - lifecyclePath := filepath.Join(relativeBaseDir, "lifecycle.tar") - layers, err := lifecycleImage.UnderlyingImage().Layers() - if err != nil { - return nil, err - } - - // Assume the last layer has the lifecycle - lifecycleLayer := layers[len(layers)-1] - - layerReader, err := lifecycleLayer.Uncompressed() + uri, err = c.uriFromLifecycleImage(ctx, relativeBaseDir, config) if err != nil { - return nil, err - } - defer layerReader.Close() - - file, err := stripTopDirAndWrite(layerReader, lifecyclePath) - if err != nil { - return nil, err - } - - defer file.Close() -Remove this comment - - uri, err = paths.FilePathToURI(lifecyclePath, "") - if err != nil { - return nil, err + return nil, errors.Wrap(err, "Could not parse uri from lifecycle image") } case config.Version != "": v, err := semver.NewVersion(config.Version) @@ -438,3 +406,42 @@ func stripTopDirAndWrite(layerReader io.ReadCloser, outputPath string) (*OS.File return file, nil } + +func (c *Client) uriFromLifecycleImage(ctx context.Context, basePath string, config pubbldr.LifecycleConfig) (uri string, err error) { + var lifecycleImage imgutil.Image + imageName := buildpack.ParsePackageLocator(config.URI) + c.logger.Debugf("Downloading lifecycle image: %s", style.Symbol(imageName)) + + lifecycleImage, err = c.imageFetcher.Fetch(ctx, imageName, image.FetchOptions{Daemon: false}) + if err != nil { + return "", nil + } + + lifecyclePath := filepath.Join(basePath, "lifecycle.tar") + layers, err := lifecycleImage.UnderlyingImage().Layers() + if err != nil { + return "", err + } + + // Assume the last layer has the lifecycle + lifecycleLayer := layers[len(layers)-1] + + layerReader, err := lifecycleLayer.Uncompressed() + if err != nil { + return "", err + } + defer layerReader.Close() + + file, err := stripTopDirAndWrite(layerReader, lifecyclePath) + if err != nil { + return "", err + } + + defer file.Close() + + uri, err = paths.FilePathToURI(lifecyclePath, "") + if err != nil { + return "", err + } + return uri, err +}