From 60dbdc8ce963c31686d0ee07ed473baeec6a2d98 Mon Sep 17 00:00:00 2001 From: Andrew Meyer Date: Wed, 18 Dec 2019 09:14:16 -0600 Subject: [PATCH] Fix acceptance tests - Update lifecycle to allow use of compatible struct during rebase - Fix inspect-builder order in tests - Cleanup package after tests Signed-off-by: Andrew Meyer --- acceptance/acceptance_test.go | 4 + .../testdata/pack_previous/builder.toml | 10 +- go.mod | 2 +- go.sum | 6 +- rebase.go | 2 +- .../github.com/buildpacks/lifecycle/README.md | 2 +- .../buildpacks/lifecycle/archive/tar.go | 108 +++++++++++ .../buildpacks/lifecycle/builder.go | 9 + .../buildpacks/lifecycle/exporter.go | 180 +++++++++++++++++- vendor/github.com/buildpacks/lifecycle/go.mod | 2 +- vendor/github.com/buildpacks/lifecycle/go.sum | 4 +- .../buildpacks/lifecycle/metadata.go | 16 +- .../buildpacks/lifecycle/rebaser.go | 2 +- .../github.com/buildpacks/lifecycle/utils.go | 9 + vendor/modules.txt | 2 +- 15 files changed, 331 insertions(+), 27 deletions(-) diff --git a/acceptance/acceptance_test.go b/acceptance/acceptance_test.go index 3e716380a5..16db811ac1 100644 --- a/acceptance/acceptance_test.go +++ b/acceptance/acceptance_test.go @@ -1447,6 +1447,10 @@ func createBuilder(t *testing.T, runImageMirror, configDir, packPath, lifecycleP // CREATE PACKAGE packageImageName := createPackage(t, configDir, tmpDir, packPath) + key := taskKey("create-package", runImageMirror, configDir, packPath, lifecyclePath) + suiteManager.RegisterCleanUp("clean-"+key, func() error { + return h.DockerRmi(dockerCli, packageImageName) + }) // RENDER builder.toml cfgData := fillTemplate(t, filepath.Join(configDir, "builder.toml"), map[string]interface{}{ diff --git a/acceptance/testdata/pack_previous/builder.toml b/acceptance/testdata/pack_previous/builder.toml index 1abe1c3b3a..325e02717f 100644 --- a/acceptance/testdata/pack_previous/builder.toml +++ b/acceptance/testdata/pack_previous/builder.toml @@ -1,8 +1,3 @@ -[[buildpacks]] - id = "simple/layers" - version = "simple-layers-version" - uri = "simple-layers-buildpack.tgz" - [[buildpacks]] id = "read/env" version = "read-env-version" @@ -12,6 +7,11 @@ # intentionally missing id/version as they are optional uri = "noop-buildpack.tgz" +[[buildpacks]] + id = "simple/layers" + version = "simple-layers-version" + uri = "simple-layers-buildpack.tgz" + [[order]] [[order.group]] id = "simple/layers" diff --git a/go.mod b/go.mod index eae62782d3..ea14c86033 100644 --- a/go.mod +++ b/go.mod @@ -5,7 +5,7 @@ require ( github.com/Masterminds/semver v1.4.2 github.com/apex/log v1.1.2-0.20190827100214-baa5455d1012 github.com/buildpacks/imgutil v0.0.0-20191212154113-dc184e0d403b - github.com/buildpacks/lifecycle v0.5.1-0.20191212164213-3b2b120be460 + github.com/buildpacks/lifecycle v0.5.1-0.20191217221752-3b74c943b7b3 github.com/dgodd/dockerdial v1.0.1 github.com/docker/docker v1.4.2-0.20190924003213-a8608b5b67c7 github.com/docker/go-connections v0.4.0 diff --git a/go.sum b/go.sum index 872e31e956..4b745f3203 100644 --- a/go.sum +++ b/go.sum @@ -21,8 +21,8 @@ github.com/aws/aws-sdk-go v1.20.6/go.mod h1:KmX6BPdI08NWTb3/sm4ZGu5ShLoqVDhKgpiN github.com/aybabtme/rgbterm v0.0.0-20170906152045-cc83f3b3ce59/go.mod h1:q/89r3U2H7sSsE2t6Kca0lfwTK8JdoNGS/yzM/4iH5I= github.com/buildpacks/imgutil v0.0.0-20191212154113-dc184e0d403b h1:SDsB0hJtURA+5i5vIjLntzRNPEqdoz6q+0MShCWdctw= github.com/buildpacks/imgutil v0.0.0-20191212154113-dc184e0d403b/go.mod h1:E3lXJcNXcRefJQAHW5rqboonet+jtOml4qImbJhYGAo= -github.com/buildpacks/lifecycle v0.5.1-0.20191212164213-3b2b120be460 h1:wwnys/9oBN1XX86SuePWXeOIyh07O4gTFZuD3o+iL/g= -github.com/buildpacks/lifecycle v0.5.1-0.20191212164213-3b2b120be460/go.mod h1:1517xYIXEWiehR7ndWdGCkIlD0KJDLvtVuzZGp7K6Ok= +github.com/buildpacks/lifecycle v0.5.1-0.20191217221752-3b74c943b7b3 h1:15zYyFmNbrtx5MmyVEKVgY2/eearqEqGJXLCjmvUo58= +github.com/buildpacks/lifecycle v0.5.1-0.20191217221752-3b74c943b7b3/go.mod h1:ZIuIs9B6tjAW4dthhltKVyEUlhRfFWWix9eqoInMGX4= github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw= github.com/containerd/containerd v1.3.0 h1:xjvXQWABwS2uiv3TWgQt5Uth60Gu86LTGZXMJkjc7rY= github.com/containerd/containerd v1.3.0/go.mod h1:bC6axHOhabU15QhwfG7w5PipXdVtMXFTttgp+kVtyUA= @@ -148,8 +148,6 @@ github.com/rogpeppe/fastuuid v1.1.0/go.mod h1:jVj6XXZzXRy/MSR5jhDC/2q6DgLz+nrA6L github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4= github.com/russross/blackfriday v1.5.2/go.mod h1:JO/DiYxRf+HjHt06OyowR9PTA263kcR/rfWxYHBV53g= github.com/sclevine/spec v1.0.0/go.mod h1:W4J29eT/Kzv7/b9IWLB055Z+qvVC9vt0Arko24q7p+U= -github.com/sclevine/spec v1.2.0 h1:1Jwdf9jSfDl9NVmt8ndHqbTZ7XCCPbh1jI3hkDBHVYA= -github.com/sclevine/spec v1.2.0/go.mod h1:W4J29eT/Kzv7/b9IWLB055Z+qvVC9vt0Arko24q7p+U= github.com/sclevine/spec v1.4.0 h1:z/Q9idDcay5m5irkZ28M7PtQM4aOISzOpj4bUPkDee8= github.com/sclevine/spec v1.4.0/go.mod h1:LvpgJaFyvQzRvc1kaDs0bulYwzC70PbiYjC4QnFHkOM= github.com/sergi/go-diff v1.0.0/go.mod h1:0CfEIISq7TuYL3j771MWULgwwjU+GofnZX9QAmXWZgo= diff --git a/rebase.go b/rebase.go index 038c44dab5..46dd15828f 100644 --- a/rebase.go +++ b/rebase.go @@ -30,7 +30,7 @@ func (c *Client) Rebase(ctx context.Context, opts RebaseOptions) error { return err } - var md lifecycle.LayersMetadata + var md lifecycle.LayersMetadataCompat if ok, err := dist.GetLabel(appImage, lifecycle.LayerMetadataLabel, &md); err != nil { return err } else if !ok { diff --git a/vendor/github.com/buildpacks/lifecycle/README.md b/vendor/github.com/buildpacks/lifecycle/README.md index 6fb26d9e80..92b8fa8f5f 100644 --- a/vendor/github.com/buildpacks/lifecycle/README.md +++ b/vendor/github.com/buildpacks/lifecycle/README.md @@ -1,6 +1,6 @@ # Lifecycle -[![Build Status](https://travis-ci.org/buildpack/lifecycle.svg?branch=master)](https://travis-ci.org/buildpack/lifecycle) +[![Build Status](https://travis-ci.org/buildpacks/lifecycle.svg?branch=master)](https://travis-ci.org/buildpack/lifecycle) [![GoDoc](https://godoc.org/github.com/buildpacks/lifecycle?status.svg)](https://godoc.org/github.com/buildpacks/lifecycle) A reference implementation of [Buildpack API v3](https://github.com/buildpacks/spec). diff --git a/vendor/github.com/buildpacks/lifecycle/archive/tar.go b/vendor/github.com/buildpacks/lifecycle/archive/tar.go index e8a0b63b34..452a9c7eb1 100644 --- a/vendor/github.com/buildpacks/lifecycle/archive/tar.go +++ b/vendor/github.com/buildpacks/lifecycle/archive/tar.go @@ -11,6 +11,83 @@ import ( "time" ) +func WriteFilesToTar(dest string, uid, gid int, files ...string) (string, map[string]struct{}, error) { + hasher := sha256.New() + f, err := os.Create(dest) + if err != nil { + return "", nil, err + } + defer f.Close() + + w := io.MultiWriter(hasher, f) + tw := tar.NewWriter(w) + + fileSet := map[string]struct{}{} + for _, file := range files { + if AddFileToArchive(tw, file, uid, gid, fileSet) != nil { + return "", nil, err + } + } + _ = tw.Close() + + sha := hex.EncodeToString(hasher.Sum(make([]byte, 0, hasher.Size()))) + return "sha256:" + sha, fileSet, nil +} + +func AddFileToArchive(tw *tar.Writer, srcDir string, uid, gid int, fileSet map[string]struct{}) error { + err := addParentDirsUnique(srcDir, tw, uid, gid, fileSet) + if err != nil { + return err + } + + return filepath.Walk(srcDir, func(file string, fi os.FileInfo, err error) error { + if _, ok := fileSet[file]; ok { + return nil + } + if err != nil { + return err + } + if fi.Mode()&os.ModeSocket != 0 { + return nil + } + var header *tar.Header + var target string + if fi.Mode()&os.ModeSymlink != 0 { + target, err = os.Readlink(file) + if err != nil { + return err + } + } + header, err = tar.FileInfoHeader(fi, target) + if err != nil { + return err + } + header.Name = file + header.ModTime = time.Date(1980, time.January, 1, 0, 0, 1, 0, time.UTC) + header.Uid = uid + header.Gid = gid + header.Uname = "" + header.Gname = "" + + if err := tw.WriteHeader(header); err != nil { + return err + } + if fi.Mode().IsRegular() { + f, err := os.Open(file) + if err != nil { + return err + } + defer f.Close() + if _, err := io.Copy(tw, f); err != nil { + return err + } + } + + fileSet[file] = struct{}{} + return nil + }) +} + func WriteTarFile(sourceDir, dest string, uid, gid int) (string, error) { hasher := sha256.New() f, err := os.Create(dest) @@ -79,6 +156,37 @@ func WriteTarArchive(w io.Writer, srcDir string, uid, gid int) error { }) } +func addParentDirsUnique(tarDir string, tw *tar.Writer, uid, gid int, parentDirs map[string]struct{}) error { + parent := filepath.Dir(tarDir) + if parent == "." || parent == "/" { + return nil + } + + if _, ok := parentDirs[parent]; ok { + return nil + } + + if err := addParentDirsUnique(parent, tw, uid, gid, parentDirs); err != nil { + return err + } + + info, err := os.Stat(parent) + if err != nil { + return err + } + + header, err := tar.FileInfoHeader(info, parent) + if err != nil { + return err + } + header.Name = parent + header.ModTime = time.Date(1980, time.January, 1, 0, 0, 1, 0, time.UTC) + + parentDirs[parent] = struct{}{} + + return tw.WriteHeader(header) +} + func addParentDirs(tarDir string, tw *tar.Writer, uid, gid int) error { parent := filepath.Dir(tarDir) if parent == "." || parent == "/" { diff --git a/vendor/github.com/buildpacks/lifecycle/builder.go b/vendor/github.com/buildpacks/lifecycle/builder.go index 603db9ceed..8c1be5dc58 100644 --- a/vendor/github.com/buildpacks/lifecycle/builder.go +++ b/vendor/github.com/buildpacks/lifecycle/builder.go @@ -36,8 +36,13 @@ type Process struct { Direct bool `toml:"direct" json:"direct"` } +type Slice struct { + Paths []string `tom:"paths"` +} + type LaunchTOML struct { Processes []Process `toml:"processes"` + Slices []Slice `toml:"slices"` } type BOMEntry struct { @@ -71,6 +76,8 @@ func (b *Builder) Build() (*BuildMetadata, error) { procMap := processMap{} plan := b.Plan var bom []BOMEntry + var slices []Slice + for _, bp := range b.Group.Group { bpInfo, err := bp.lookup(b.BuildpacksDir) if err != nil { @@ -124,12 +131,14 @@ func (b *Builder) Build() (*BuildMetadata, error) { return nil, err } procMap.add(launch.Processes) + slices = append(slices, launch.Slices...) } return &BuildMetadata{ Processes: procMap.list(), Buildpacks: b.Group.Group, BOM: bom, + Slices: slices, }, nil } diff --git a/vendor/github.com/buildpacks/lifecycle/exporter.go b/vendor/github.com/buildpacks/lifecycle/exporter.go index 03ae6b2d01..ba140ccc3f 100644 --- a/vendor/github.com/buildpacks/lifecycle/exporter.go +++ b/vendor/github.com/buildpacks/lifecycle/exporter.go @@ -4,7 +4,10 @@ import ( "encoding/json" "fmt" "io" + "os" "path/filepath" + "sort" + "strings" "github.com/BurntSushi/toml" "github.com/buildpacks/imgutil" @@ -38,6 +41,12 @@ type LauncherConfig struct { Metadata LauncherMetadata } +type SliceLayer struct { + ID string + TarPath string + SHA string +} + func (e *Exporter) Export( layersDir, appDir string, @@ -59,21 +68,24 @@ func (e *Exporter) Export( meta.RunImage.Reference = runImageRef meta.Stack = stack - meta.App.SHA, err = e.addOrReuseLayer(workingImage, &layer{path: appDir, identifier: "app"}, origMetadata.App.SHA) - if err != nil { - return errors.Wrap(err, "exporting app layer") + buildMD := &BuildMetadata{} + if _, err := toml.DecodeFile(MetadataFilePath(layersDir), buildMD); err != nil { + return errors.Wrap(err, "read build metadata") } - meta.Config.SHA, err = e.addOrReuseLayer(workingImage, &layer{path: filepath.Join(layersDir, "config"), identifier: "config"}, origMetadata.Config.SHA) + // creating app layers (slices + app dir) + appSlices, err := e.createAppSliceLayers(workingImage, &layer{path: appDir, identifier: "app"}, buildMD.Slices) if err != nil { - return errors.Wrap(err, "exporting config layer") + return errors.Wrap(err, "creating app layers") } + // launcher meta.Launcher.SHA, err = e.addOrReuseLayer(workingImage, &layer{path: launcherConfig.Path, identifier: "launcher"}, origMetadata.Launcher.SHA) if err != nil { return errors.Wrap(err, "exporting launcher layer") } + // layers for _, bp := range e.Buildpacks { bpDir, err := readBuildpackLayersDir(layersDir, bp) if err != nil { @@ -126,6 +138,18 @@ func (e *Exporter) Export( } } + // app + meta.App, err = e.addSliceLayers(workingImage, appSlices, origMetadata.App) + if err != nil { + return errors.Wrap(err, "exporting slice layers") + } + + // config + meta.Config.SHA, err = e.addOrReuseLayer(workingImage, &layer{path: filepath.Join(layersDir, "config"), identifier: "config"}, origMetadata.Config.SHA) + if err != nil { + return errors.Wrap(err, "exporting config layer") + } + data, err := json.Marshal(meta) if err != nil { return errors.Wrap(err, "marshall metadata") @@ -135,10 +159,6 @@ func (e *Exporter) Export( return errors.Wrap(err, "set app image metadata label") } - buildMD := &BuildMetadata{} - if _, err := toml.DecodeFile(MetadataFilePath(layersDir), buildMD); err != nil { - return errors.Wrap(err, "read build metadata") - } buildMD.Launcher = launcherConfig.Metadata buildJSON, err := json.Marshal(buildMD) if err != nil { @@ -261,3 +281,145 @@ func (e *Exporter) addOrReuseCacheLayer(cache Cache, layer identifiableLayer, pr e.Logger.Debugf("Layer '%s' SHA: %s\n", layer.Identifier(), sha) return sha, cache.AddLayerFile(sha, tarPath) } + +func (e *Exporter) createAppSliceLayers(image imgutil.Image, appLayer identifiableLayer, slices []Slice) ([]SliceLayer, error) { + var appSlices []SliceLayer + + for index, slice := range slices { + var allGlobMatches []string + for _, path := range slice.Paths { + globMatches, err := filepath.Glob(e.toAbs(appLayer.Path(), path)) + if err != nil { + return nil, errors.Wrap(err, "bad pattern for glob path") + } + allGlobMatches = append(allGlobMatches, globMatches...) + } + sliceLayerID := fmt.Sprintf("slice-%d", index+1) + sliceLayer, err := e.createSliceLayer(image, sliceLayerID, allGlobMatches) + if err != nil { + return nil, errors.Wrap(err, "creating slice layer") + } + appSlices = append(appSlices, sliceLayer) + } + + // finish-up by creating the actual app dir layer and place it at the end of the app slices + // ------------- + // | slice 1 | + // ------------- + // | slice 2 | + // ------------- + // | slice N | + // ------------- + // | app dir | + // ------------- + tarPath := filepath.Join(e.ArtifactsDir, escapeID(appLayer.Identifier())+".tar") + sha, err := archive.WriteTarFile(appLayer.Path(), tarPath, e.UID, e.GID) + if err != nil { + return nil, errors.Wrapf(err, "exporting layer '%s'", appLayer.Identifier()) + } + + return append(appSlices, SliceLayer{ + ID: appLayer.Identifier(), + SHA: sha, + TarPath: tarPath, + }), nil +} + +func (e *Exporter) createSliceLayer(image imgutil.Image, layerID string, files []string) (SliceLayer, error) { + tarPath := filepath.Join(e.ArtifactsDir, escapeID(layerID)+".tar") + sha, fileSet, err := archive.WriteFilesToTar(tarPath, e.UID, e.GID, files...) + if err != nil { + return SliceLayer{}, errors.Wrapf(err, "exporting slice layer '%s'", layerID) + } + + // for this first iteration, just delete the actual files then revisit + // the directories and delete if empty as a result of previous removal + var dirs []string + for file := range fileSet { + stat, _ := os.Stat(file) + if !stat.IsDir() { + err = os.Remove(file) + if err != nil { + e.Logger.Errorf("failed to delete file %v", err) + } + } else { + dirs = append(dirs, file) + } + } + // sort the dirs by their path depth (deepest -> most shallow) to avoid NOT being able to delete a high level dir + // that nested empty dirs. + sort.SliceStable(dirs, func(i, j int) bool { + return len(strings.Split(dirs[i], string(os.PathSeparator))) > len(strings.Split(dirs[j], string(os.PathSeparator))) + }) + for _, dir := range dirs { + if ok, err := isEmptyDir(dir); ok { + if err != nil { + e.Logger.Errorf("failed to check if directory is empty %v", err) + } + err = os.Remove(dir) + if err != nil { + e.Logger.Errorf("failed to delete directory %v", err) + } + } + } + + return SliceLayer{ + ID: layerID, + SHA: sha, + TarPath: tarPath, + }, nil +} + +func (e *Exporter) addSliceLayers(image imgutil.Image, sliceLayers []SliceLayer, previousAppMD []LayerMetadata) ([]LayerMetadata, error) { + var numberOfReusedLayers int + var appMD []LayerMetadata + + for _, slice := range sliceLayers { + var err error + + found := false + for _, previous := range previousAppMD { + if slice.SHA == previous.SHA { + found = true + break + } + } + if found { + err = image.ReuseLayer(slice.SHA) + numberOfReusedLayers++ + } else { + err = image.AddLayer(slice.TarPath) + } + if err != nil { + return nil, err + } + e.Logger.Debugf("Layer '%s' SHA: %s\n", slice.ID, slice.SHA) + appMD = append(appMD, LayerMetadata{SHA: slice.SHA}) + } + + delta := len(sliceLayers) - numberOfReusedLayers + if numberOfReusedLayers > 0 { + e.Logger.Infof("Reusing %d/%d app layer(s)\n", numberOfReusedLayers, len(sliceLayers)) + } + if delta != 0 { + e.Logger.Infof("Adding %d/%d app layer(s)\n", delta, len(sliceLayers)) + } + + return appMD, nil +} + +func (e *Exporter) toAbs(baseDir, path string) string { + path = filepath.Clean(path) + + // force relative path to be absolute from the base dir + if !filepath.IsAbs(path) { + path = filepath.Join(baseDir, path) + } + // force an absolute path to be absolute from base dir + if len(path) > len(baseDir) && path[:len(baseDir)] != baseDir { + path = filepath.Join(baseDir, path) + e.Logger.Warnf("found absolute path %s outside of %s", path, baseDir) + } + + return path +} diff --git a/vendor/github.com/buildpacks/lifecycle/go.mod b/vendor/github.com/buildpacks/lifecycle/go.mod index 9cb61153a6..74555205c5 100644 --- a/vendor/github.com/buildpacks/lifecycle/go.mod +++ b/vendor/github.com/buildpacks/lifecycle/go.mod @@ -13,7 +13,7 @@ require ( github.com/mattn/go-colorable v0.1.4 // indirect github.com/mattn/go-isatty v0.0.10 // indirect github.com/pkg/errors v0.8.1 - github.com/sclevine/spec v1.2.0 + github.com/sclevine/spec v1.4.0 golang.org/x/net v0.0.0-20190724013045-ca1201d0de80 // indirect golang.org/x/sync v0.0.0-20190423024810-112230192c58 google.golang.org/genproto v0.0.0-20190508193815-b515fa19cec8 // indirect diff --git a/vendor/github.com/buildpacks/lifecycle/go.sum b/vendor/github.com/buildpacks/lifecycle/go.sum index 69b28c0abd..eec52a8a26 100644 --- a/vendor/github.com/buildpacks/lifecycle/go.sum +++ b/vendor/github.com/buildpacks/lifecycle/go.sum @@ -134,8 +134,8 @@ github.com/rogpeppe/fastuuid v1.1.0/go.mod h1:jVj6XXZzXRy/MSR5jhDC/2q6DgLz+nrA6L github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4= github.com/russross/blackfriday v1.5.2/go.mod h1:JO/DiYxRf+HjHt06OyowR9PTA263kcR/rfWxYHBV53g= github.com/sclevine/spec v1.0.0/go.mod h1:W4J29eT/Kzv7/b9IWLB055Z+qvVC9vt0Arko24q7p+U= -github.com/sclevine/spec v1.2.0 h1:1Jwdf9jSfDl9NVmt8ndHqbTZ7XCCPbh1jI3hkDBHVYA= -github.com/sclevine/spec v1.2.0/go.mod h1:W4J29eT/Kzv7/b9IWLB055Z+qvVC9vt0Arko24q7p+U= +github.com/sclevine/spec v1.4.0 h1:z/Q9idDcay5m5irkZ28M7PtQM4aOISzOpj4bUPkDee8= +github.com/sclevine/spec v1.4.0/go.mod h1:LvpgJaFyvQzRvc1kaDs0bulYwzC70PbiYjC4QnFHkOM= github.com/sergi/go-diff v1.0.0/go.mod h1:0CfEIISq7TuYL3j771MWULgwwjU+GofnZX9QAmXWZgo= github.com/sirupsen/logrus v1.4.1 h1:GL2rEmy6nsikmW0r8opw9JIRScdMF5hA8cOYLH7In1k= github.com/sirupsen/logrus v1.4.1/go.mod h1:ni0Sbl8bgC9z8RoU9G6nDWqqs/fq4eDPysMBDgk/93Q= diff --git a/vendor/github.com/buildpacks/lifecycle/metadata.go b/vendor/github.com/buildpacks/lifecycle/metadata.go index 898a382a2e..0f392ff616 100644 --- a/vendor/github.com/buildpacks/lifecycle/metadata.go +++ b/vendor/github.com/buildpacks/lifecycle/metadata.go @@ -18,6 +18,7 @@ type BuildMetadata struct { Buildpacks []Buildpack `toml:"buildpacks" json:"buildpacks"` BOM []BOMEntry `toml:"bom" json:"bom"` Launcher LauncherMetadata `toml:"-" json:"launcher"` + Slices []Slice `toml:"slices" json:"-"` } type LauncherMetadata struct { @@ -51,8 +52,21 @@ func (cm *CacheMetadata) MetadataForBuildpack(id string) BuildpackLayersMetadata return BuildpackLayersMetadata{} } +// NOTE: This struct MUST be kept in sync with `LayersMetadataCompat` type LayersMetadata struct { - App LayerMetadata `json:"app" toml:"app"` + App []LayerMetadata `json:"app" toml:"app"` + Config LayerMetadata `json:"config" toml:"config"` + Launcher LayerMetadata `json:"launcher" toml:"launcher"` + Buildpacks []BuildpackLayersMetadata `json:"buildpacks" toml:"buildpacks"` + RunImage RunImageMetadata `json:"runImage" toml:"run-image"` + Stack StackMetadata `json:"stack" toml:"stack"` +} + +// NOTE: This struct MUST be kept in sync with `LayersMetadata`. +// It exists for situations where the `App` field type cannot be +// guaranteed, yet the original struct data must be maintained. +type LayersMetadataCompat struct { + App interface{} `json:"app" toml:"app"` Config LayerMetadata `json:"config" toml:"config"` Launcher LayerMetadata `json:"launcher" toml:"launcher"` Buildpacks []BuildpackLayersMetadata `json:"buildpacks" toml:"buildpacks"` diff --git a/vendor/github.com/buildpacks/lifecycle/rebaser.go b/vendor/github.com/buildpacks/lifecycle/rebaser.go index 185b991ce0..acbb3a0d64 100644 --- a/vendor/github.com/buildpacks/lifecycle/rebaser.go +++ b/vendor/github.com/buildpacks/lifecycle/rebaser.go @@ -17,7 +17,7 @@ func (r *Rebaser) Rebase( newBaseImage imgutil.Image, additionalNames []string, ) error { - var origMetadata LayersMetadata + var origMetadata LayersMetadataCompat if err := DecodeLabel(workingImage, LayerMetadataLabel, &origMetadata); err != nil { return errors.Wrap(err, "get image metadata") } diff --git a/vendor/github.com/buildpacks/lifecycle/utils.go b/vendor/github.com/buildpacks/lifecycle/utils.go index bc89a52df1..243fcba1ef 100644 --- a/vendor/github.com/buildpacks/lifecycle/utils.go +++ b/vendor/github.com/buildpacks/lifecycle/utils.go @@ -2,6 +2,7 @@ package lifecycle import ( "encoding/json" + "io/ioutil" "os" "path/filepath" "strings" @@ -65,3 +66,11 @@ func DecodeLabel(image imgutil.Image, label string, v interface{}) error { func escapeID(id string) string { return strings.Replace(id, "/", "_", -1) } + +func isEmptyDir(name string) (bool, error) { + entries, err := ioutil.ReadDir(name) + if err != nil { + return false, err + } + return len(entries) == 0, nil +} diff --git a/vendor/modules.txt b/vendor/modules.txt index f642779b76..dfa65f2801 100644 --- a/vendor/modules.txt +++ b/vendor/modules.txt @@ -15,7 +15,7 @@ github.com/buildpacks/imgutil github.com/buildpacks/imgutil/fakes github.com/buildpacks/imgutil/local github.com/buildpacks/imgutil/remote -# github.com/buildpacks/lifecycle v0.5.1-0.20191212164213-3b2b120be460 +# github.com/buildpacks/lifecycle v0.5.1-0.20191217221752-3b74c943b7b3 github.com/buildpacks/lifecycle github.com/buildpacks/lifecycle/archive github.com/buildpacks/lifecycle/auth