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

Expose functionality to download buildpacks #1225

Merged
merged 19 commits into from
Jul 21, 2021
Merged
Show file tree
Hide file tree
Changes from 17 commits
Commits
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
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