Skip to content

Commit

Permalink
Merge pull request #1225 from YousefHaggyHeroku/main
Browse files Browse the repository at this point in the history
Expose functionality to download buildpacks
  • Loading branch information
jromero authored Jul 21, 2021
2 parents 4c340df + 1d9b1b8 commit 66a4f32
Show file tree
Hide file tree
Showing 13 changed files with 669 additions and 500 deletions.
6 changes: 3 additions & 3 deletions build.go
Original file line number Diff line number Diff line change
Expand Up @@ -737,15 +737,15 @@ func (c *Client) processBuildpacks(ctx context.Context, builderImage imgutil.Ima
order = appendBuildpackToOrder(order, mainBP.Descriptor().Info)
case buildpack.PackageLocator:
imageName := buildpack.ParsePackageLocator(bp)
mainBP, depBPs, err := extractPackagedBuildpacks(ctx, imageName, c.imageFetcher, publish, pullPolicy)
mainBP, depBPs, err := extractPackagedBuildpacks(ctx, imageName, c.imageFetcher, image.FetchOptions{Daemon: !publish, PullPolicy: pullPolicy})
if err != nil {
return fetchedBPs, order, errors.Wrapf(err, "creating from buildpackage %s", style.Symbol(bp))
}

fetchedBPs = append(append(fetchedBPs, mainBP), depBPs...)
order = appendBuildpackToOrder(order, mainBP.Descriptor().Info)
case buildpack.RegistryLocator:
registryCache, err := c.getRegistry(c.logger, registry)
registryCache, err := getRegistry(c.logger, registry)
if err != nil {
return fetchedBPs, order, errors.Wrapf(err, "invalid registry '%s'", registry)
}
Expand All @@ -755,7 +755,7 @@ func (c *Client) processBuildpacks(ctx context.Context, builderImage imgutil.Ima
return fetchedBPs, order, errors.Wrapf(err, "locating in registry %s", style.Symbol(bp))
}

mainBP, depBPs, err := extractPackagedBuildpacks(ctx, registryBp.Address, c.imageFetcher, publish, pullPolicy)
mainBP, depBPs, err := extractPackagedBuildpacks(ctx, registryBp.Address, c.imageFetcher, image.FetchOptions{Daemon: !publish, PullPolicy: pullPolicy})
if err != nil {
return fetchedBPs, order, errors.Wrapf(err, "extracting from registry %s", style.Symbol(bp))
}
Expand Down
111 changes: 111 additions & 0 deletions buildpack_downloader.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,111 @@
package pack

import (
"context"
"fmt"

"github.com/pkg/errors"

"github.com/buildpacks/pack/config"
"github.com/buildpacks/pack/internal/buildpack"
"github.com/buildpacks/pack/internal/dist"
"github.com/buildpacks/pack/internal/image"
"github.com/buildpacks/pack/internal/paths"
"github.com/buildpacks/pack/internal/style"
"github.com/buildpacks/pack/logging"
)

type buildpackDownloader struct {
logger logging.Logger
imageFetcher ImageFetcher
downloader Downloader
}

func NewBuildpackDownloader(logger logging.Logger, imageFetcher ImageFetcher, downloader Downloader) *buildpackDownloader { //nolint:golint,gosimple
return &buildpackDownloader{
logger: logger,
imageFetcher: imageFetcher,
downloader: downloader,
}
}

type BuildpackDownloadOptions struct {
// Buildpack registry name. Defines where all registry buildpacks will be pulled from.
RegistryName string

// The base directory to use to resolve relative assets
RelativeBaseDir string

// The OS of the builder image
ImageOS string

// Deprecated, the older alternative to buildpack URI
ImageName string

Daemon bool

PullPolicy config.PullPolicy
}

func (c *buildpackDownloader) Download(ctx context.Context, buildpackURI string, opts BuildpackDownloadOptions) (dist.Buildpack, []dist.Buildpack, error) {
var err error
var locatorType buildpack.LocatorType
if buildpackURI == "" && opts.ImageName != "" {
c.logger.Warn("The 'image' key is deprecated. Use 'uri=\"docker://...\"' instead.")
buildpackURI = opts.ImageName
locatorType = buildpack.PackageLocator
} else {
locatorType, err = buildpack.GetLocatorType(buildpackURI, opts.RelativeBaseDir, []dist.BuildpackInfo{})
if err != nil {
return nil, nil, err
}
}

var mainBP dist.Buildpack
var depBPs []dist.Buildpack
switch locatorType {
case buildpack.PackageLocator:
imageName := buildpack.ParsePackageLocator(buildpackURI)
c.logger.Debugf("Downloading buildpack from image: %s", style.Symbol(imageName))
mainBP, depBPs, err = extractPackagedBuildpacks(ctx, imageName, c.imageFetcher, image.FetchOptions{Daemon: opts.Daemon, PullPolicy: opts.PullPolicy})
if err != nil {
return nil, nil, errors.Wrapf(err, "extracting from registry %s", style.Symbol(buildpackURI))
}
case buildpack.RegistryLocator:
c.logger.Debugf("Downloading buildpack from registry: %s", style.Symbol(buildpackURI))
registryCache, err := getRegistry(c.logger, opts.RegistryName)
if err != nil {
return nil, nil, errors.Wrapf(err, "invalid registry '%s'", opts.RegistryName)
}

registryBp, err := registryCache.LocateBuildpack(buildpackURI)
if err != nil {
return nil, nil, errors.Wrapf(err, "locating in registry %s", style.Symbol(buildpackURI))
}

mainBP, depBPs, err = extractPackagedBuildpacks(ctx, registryBp.Address, c.imageFetcher, image.FetchOptions{Daemon: opts.Daemon, PullPolicy: opts.PullPolicy})
if err != nil {
return nil, nil, errors.Wrapf(err, "extracting from registry %s", style.Symbol(buildpackURI))
}
case buildpack.URILocator:
buildpackURI, err = paths.FilePathToURI(buildpackURI, opts.RelativeBaseDir)
if err != nil {
return nil, nil, errors.Wrapf(err, "making absolute: %s", style.Symbol(buildpackURI))
}

c.logger.Debugf("Downloading buildpack from URI: %s", style.Symbol(buildpackURI))

blob, err := c.downloader.Download(ctx, buildpackURI)
if err != nil {
return nil, nil, errors.Wrapf(err, "downloading buildpack from %s", style.Symbol(buildpackURI))
}

mainBP, depBPs, err = decomposeBuildpack(blob, opts.ImageOS)
if err != nil {
return nil, nil, errors.Wrapf(err, "extracting from %s", style.Symbol(buildpackURI))
}
default:
return nil, nil, fmt.Errorf("error reading %s: invalid locator: %s", buildpackURI, locatorType)
}
return mainBP, depBPs, nil
}
Loading

0 comments on commit 66a4f32

Please sign in to comment.