Skip to content

Commit

Permalink
Merge pull request #393 from buildpack/feature/349-create-package-w-p…
Browse files Browse the repository at this point in the history
…ackage

Add package support to create-package
  • Loading branch information
ameyer-pivotal authored Dec 4, 2019
2 parents f42fe3c + ff75106 commit 17f1ff5
Show file tree
Hide file tree
Showing 20 changed files with 687 additions and 168 deletions.
84 changes: 76 additions & 8 deletions acceptance/acceptance_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -1068,32 +1068,78 @@ func testAcceptance(t *testing.T, when spec.G, it spec.S, packFixturesDir, packP

h.CopyFile(t, filepath.Join(packFixturesDir, "package.toml"), filepath.Join(tmpDir, "package.toml"))

tgz := h.CreateTGZ(t, filepath.Join(bpDir, "noop-buildpack"), "./", 0755)
err = os.Rename(tgz, filepath.Join(tmpDir, "noop-buildpack.tgz"))
err = os.Rename(
h.CreateTGZ(t, filepath.Join(bpDir, "noop-buildpack"), "./", 0755),
filepath.Join(tmpDir, "noop-buildpack.tgz"),
)
h.AssertNil(t, err)

h.CopyFile(t, filepath.Join(packFixturesDir, "package.toml"), filepath.Join(tmpDir, "package.toml"))
err = os.Rename(
h.CreateTGZ(t, filepath.Join(bpDir, "simple-layers-buildpack"), "./", 0755),
filepath.Join(tmpDir, "simple-layers-buildpack.tgz"),
)
h.AssertNil(t, err)
})

it.After(func() {
h.AssertNil(t, os.RemoveAll(tmpDir))
})

it("creates the package", func() {
createPackageLocally := func(absConfigPath string) string {
packageName := "test/package-" + h.RandString(10)
output, err := h.RunE(subjectPack("create-package", "-p", filepath.Join(tmpDir, "package.toml"), packageName))
output, err := h.RunE(subjectPack("create-package", packageName, "-p", absConfigPath))
h.AssertNil(t, err)
h.AssertContains(t, output, fmt.Sprintf("Successfully created package '%s'", packageName))
return packageName
}

createPackageRemotely := func(absConfigPath string) string {
packageName := registryConfig.RepoName("test/package-" + h.RandString(10))
output, err := h.RunE(subjectPack("create-package", packageName, "-p", absConfigPath, "--publish"))
h.AssertNil(t, err)
h.AssertContains(t, output, fmt.Sprintf("Successfully published package '%s'", packageName))
return packageName
}

_, _, err = dockerCli.ImageInspectWithRaw(context.Background(), packageName)
assertImageExistsLocally := func(name string) {
_, _, err := dockerCli.ImageInspectWithRaw(context.Background(), name)
h.AssertNil(t, err)

}

generateAggregatePackageToml := func(nestedPackageName string) string {
packageTomlData := fillTemplate(t,
filepath.Join(packFixturesDir, "package_aggregate.toml"),
map[string]interface{}{"PackageName": nestedPackageName},
)
packageTomlFile, err := ioutil.TempFile(tmpDir, "package_aggregate-*.toml")
h.AssertNil(t, err)
_, err = io.WriteString(packageTomlFile, packageTomlData)
h.AssertNil(t, err)
h.AssertNil(t, packageTomlFile.Close())

return packageTomlFile.Name()
}

it("creates the package", func() {
t.Log("package w/ only buildpacks")
nestedPackageName := createPackageLocally(filepath.Join(tmpDir, "package.toml"))

t.Log("package w/ buildpacks and packages")
assertImageExistsLocally(nestedPackageName)
aggregatePackageToml := generateAggregatePackageToml(nestedPackageName)

packageName := createPackageLocally(aggregatePackageToml)
assertImageExistsLocally(packageName)
})

when("--publish", func() {
it("publishes image to registry", func() {
packageName := registryConfig.RepoName("test/package-" + h.RandString(10))
nestedPackageName := createPackageRemotely(filepath.Join(tmpDir, "package.toml"))
aggregatePackageToml := generateAggregatePackageToml(nestedPackageName)

output := h.Run(t, subjectPack("create-package", "-p", filepath.Join(tmpDir, "package.toml"), "--publish", packageName))
packageName := registryConfig.RepoName("test/package-" + h.RandString(10))
output := h.Run(t, subjectPack("create-package", packageName, "-p", aggregatePackageToml, "--publish"))
h.AssertContains(t, output, fmt.Sprintf("Successfully published package '%s'", packageName))

_, _, err := dockerCli.ImageInspectWithRaw(context.Background(), packageName)
Expand All @@ -1105,6 +1151,28 @@ func testAcceptance(t *testing.T, when spec.G, it spec.S, packFixturesDir, packP
h.AssertNil(t, err)
})
})

when("--no-pull", func() {
it("should use local image", func() {
nestedPackage := createPackageLocally(filepath.Join(tmpDir, "package.toml"))
aggregatePackageToml := generateAggregatePackageToml(nestedPackage)

packageName := registryConfig.RepoName("test/package-" + h.RandString(10))
h.Run(t, subjectPack("create-package", packageName, "-p", aggregatePackageToml, "--no-pull"))

_, _, err := dockerCli.ImageInspectWithRaw(context.Background(), packageName)
h.AssertNil(t, err)
})

it("should not pull image from registry", func() {
nestedPackage := createPackageRemotely(filepath.Join(tmpDir, "package.toml"))
aggregatePackageToml := generateAggregatePackageToml(nestedPackage)

packageName := registryConfig.RepoName("test/package-" + h.RandString(10))
_, err := h.RunE(subjectPack("create-package", packageName, "-p", aggregatePackageToml, "--no-pull"))
h.AssertError(t, err, fmt.Sprintf("image '%s' does not exist on the daemon", nestedPackage))
})
})
})

when("report", func() {
Expand Down
2 changes: 1 addition & 1 deletion acceptance/testdata/pack_current/package.toml
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
id = "noop.buildpack"
version = "noop.buildpack.version"

[[blobs]]
[[buildpacks]]
uri = "noop-buildpack.tgz"

[[stacks]]
Expand Down
13 changes: 13 additions & 0 deletions acceptance/testdata/pack_current/package_aggregate.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
[default]
id = "noop.buildpack"
version = "noop.buildpack.version"

[[buildpacks]]
uri = "simple-layers-buildpack.tgz"

[[packages]]
ref = "{{ .PackageName }}"

[[stacks]]
id = "pack.test.stack"
mixins = ["netcat"]
4 changes: 2 additions & 2 deletions build.go
Original file line number Diff line number Diff line change
Expand Up @@ -224,8 +224,8 @@ func assembleAvailableMixins(buildMixins, runMixins []string) []string {

func allBuildpacks(builderImage imgutil.Image, additionalBuildpacks []dist.Buildpack) ([]dist.BuildpackDescriptor, error) {
var all []dist.BuildpackDescriptor
var bpLayers builder.BuildpackLayers
if _, err := dist.GetLabel(builderImage, builder.BuildpackLayersLabel, &bpLayers); err != nil {
var bpLayers dist.BuildpackLayers
if _, err := dist.GetLabel(builderImage, dist.BuildpackLayersLabel, &bpLayers); err != nil {
return nil, err
}
for id, bps := range bpLayers {
Expand Down
2 changes: 1 addition & 1 deletion build_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -100,7 +100,7 @@ func testBuild(t *testing.T, when spec.G, it spec.S) {
},
},
},
builder.BuildpackLayers{
dist.BuildpackLayers{
"buildpack.id": {
"buildpack.version": {
Stacks: []dist.Stack{
Expand Down
52 changes: 51 additions & 1 deletion create_buildpackage.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,9 @@ package pack

import (
"context"
"io"

"github.com/buildpack/imgutil"
"github.com/pkg/errors"

"github.com/buildpack/pack/internal/buildpackage"
Expand All @@ -14,12 +16,13 @@ type CreatePackageOptions struct {
Name string
Config buildpackage.Config
Publish bool
NoPull bool
}

func (c *Client) CreatePackage(ctx context.Context, opts CreatePackageOptions) error {
packageBuilder := buildpackage.NewBuilder(c.imageFactory)

for _, bc := range opts.Config.Blobs {
for _, bc := range opts.Config.Buildpacks {
blob, err := c.downloader.Download(ctx, bc.URI)
if err != nil {
return errors.Wrapf(err, "downloading buildpack from %s", style.Symbol(bc.URI))
Expand All @@ -33,6 +36,32 @@ func (c *Client) CreatePackage(ctx context.Context, opts CreatePackageOptions) e
packageBuilder.AddBuildpack(bp)
}

for _, ref := range opts.Config.Packages {
pkgImage, err := c.imageFetcher.Fetch(ctx, ref.Ref, !opts.Publish, !opts.NoPull)
if err != nil {
return errors.Wrapf(err, "fetching image %s", style.Symbol(ref.Ref))
}

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(ref.Ref),
)
}

packageBuilder.AddPackage(&packageImage{
img: pkgImage,
bpLayers: bpLayers,
})
}

packageBuilder.SetDefaultBuildpack(opts.Config.Default)

for _, s := range opts.Config.Stacks {
Expand All @@ -46,3 +75,24 @@ func (c *Client) CreatePackage(ctx context.Context, opts CreatePackageOptions) e

return err
}

type packageImage struct {
img imgutil.Image
bpLayers dist.BuildpackLayers
}

func (i *packageImage) Name() string {
return i.img.Name()
}

func (i *packageImage) BuildpackLayers() dist.BuildpackLayers {
return i.bpLayers
}

func (i *packageImage) GetLayer(diffID string) (io.ReadCloser, error) {
return i.img.GetLayer(diffID)
}

func (i *packageImage) Label(name string) (value string, err error) {
return i.img.Label(name)
}
Loading

0 comments on commit 17f1ff5

Please sign in to comment.