forked from buildpacks/pack
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathpack.go
91 lines (77 loc) · 2.09 KB
/
pack.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
package pack
import (
"context"
"io"
"github.com/buildpacks/imgutil"
"github.com/pkg/errors"
"github.com/buildpacks/pack/internal/dist"
"github.com/buildpacks/pack/internal/style"
)
type buildpackAdder interface {
AddBuildpack(buildpack dist.Buildpack)
}
func addPackageBuildpacks(ctx context.Context, pkgImageRef string, adder buildpackAdder, fetcher ImageFetcher, publish, noPull bool) error {
pkgImage, err := fetcher.Fetch(ctx, pkgImageRef, !publish, !noPull)
if err != nil {
return errors.Wrapf(err, "fetching image %s", style.Symbol(pkgImageRef))
}
bpLayers := dist.BuildpackLayers{}
ok, err := dist.GetLabel(pkgImage, dist.BuildpackLayersLabel, &bpLayers)
if err != nil {
return err
}
if !ok {
return errors.Errorf(
"label %s not present on package %s",
style.Symbol(dist.BuildpackLayersLabel),
style.Symbol(pkgImageRef),
)
}
bps, err := extractBuildpacks(pkgImage, bpLayers)
if err != nil {
return errors.Wrap(err, "extracting package buildpacks")
}
for _, bp := range bps {
adder.AddBuildpack(bp)
}
return nil
}
type openerBlob struct {
opener func() (io.ReadCloser, error)
}
func (b *openerBlob) Open() (io.ReadCloser, error) {
return b.opener()
}
func extractBuildpacks(pkgImage imgutil.Image, bpLayers dist.BuildpackLayers) ([]dist.Buildpack, error) {
var bps []dist.Buildpack
for bpID, v := range bpLayers {
for bpVersion, bpInfo := range v {
desc := dist.BuildpackDescriptor{
API: bpInfo.API,
Info: dist.BuildpackInfo{
ID: bpID,
Version: bpVersion,
},
Stacks: bpInfo.Stacks,
Order: bpInfo.Order,
}
diffID := bpInfo.LayerDiffID // Allow use in closure
b := &openerBlob{
opener: func() (io.ReadCloser, error) {
rc, err := pkgImage.GetLayer(diffID)
if err != nil {
return nil, errors.Wrapf(err,
"extracting buildpack %s layer (diffID %s) from package %s",
style.Symbol(desc.Info.FullName()),
style.Symbol(diffID),
style.Symbol(pkgImage.Name()),
)
}
return rc, nil
},
}
bps = append(bps, dist.BuildpackFromTarBlob(desc, b))
}
}
return bps, nil
}