Skip to content

Commit

Permalink
Move rebase into pack client
Browse files Browse the repository at this point in the history
Signed-off-by: Andrew Meyer <ameyer@pivotal.io>
  • Loading branch information
ameyer-pivotal committed Apr 4, 2019
1 parent 84b6c2a commit 0019490
Show file tree
Hide file tree
Showing 27 changed files with 665 additions and 683 deletions.
50 changes: 29 additions & 21 deletions client.go
Original file line number Diff line number Diff line change
@@ -1,38 +1,46 @@
package pack

import (
"github.com/buildpack/lifecycle/image"

"github.com/buildpack/pack/config"
"github.com/buildpack/pack/docker"
"github.com/buildpack/pack/logging"
)

type Client struct {
config *config.Config
logger *logging.Logger
fetcher Fetcher
}

func NewClient(config *config.Config, fetcher Fetcher) *Client {
func NewClient(config *config.Config, logger *logging.Logger, fetcher Fetcher) *Client {
return &Client{
config: config,
logger: logger,
fetcher: fetcher,
}
}

//// TODO : move to build.go
//func (c *Client) Build() {
//
//}
//
//// TODO : move to create_builder.go
//func (c *Client) CreateBuilder() {
//
//}
//

//// TODO : move to run.go
//func (c *Client) Run() {
//
//}

// TODO : move to rebase.go
//func (c *Client) Rebase() {
//
//}
func DefaultClient(config *config.Config, logger *logging.Logger) (*Client, error) {
factory, err := image.NewFactory()
if err != nil {
return nil, err
}

dockerClient, err := docker.New()
if err != nil {
return nil, err
}

fetcher := &ImageFetcher{
Factory: factory,
Docker: dockerClient,
}

return &Client{
config: config,
logger: logger,
fetcher: fetcher,
}, nil
}
File renamed without changes.
13 changes: 9 additions & 4 deletions inspect_builder_test.go → client_inspect_builder_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ package pack_test
import (
"errors"
"fmt"
"io/ioutil"
"testing"

imgtest "github.com/buildpack/lifecycle/testhelpers"
Expand All @@ -11,6 +12,7 @@ import (
"github.com/sclevine/spec"
"github.com/sclevine/spec/report"

"github.com/buildpack/pack/logging"
h "github.com/buildpack/pack/testhelpers"

"github.com/buildpack/pack"
Expand All @@ -35,11 +37,14 @@ func testInspectBuilder(t *testing.T, when spec.G, it spec.S) {
it.Before(func() {
mockController = gomock.NewController(t)
mockFetcher = mocks.NewMockFetcher(mockController)
client = pack.NewClient(&config.Config{
RunImages: []config.RunImage{
{Image: "some/run-image", Mirrors: []string{"some/local-mirror"}},
client = pack.NewClient(
&config.Config{
RunImages: []config.RunImage{
{Image: "some/run-image", Mirrors: []string{"some/local-mirror"}},
},
},
}, mockFetcher)
logging.NewLogger(ioutil.Discard, ioutil.Discard, false, false),
mockFetcher)
builderImage = imgtest.NewFakeImage(t, "some/builder", "", "")
})

Expand Down
128 changes: 128 additions & 0 deletions client_rebase.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,128 @@
package pack

import (
"context"
"encoding/json"

"github.com/buildpack/lifecycle"
"github.com/buildpack/lifecycle/image"
"github.com/pkg/errors"

"github.com/buildpack/pack/config"
"github.com/buildpack/pack/style"
)

type RebaseOptions struct {
RepoName string
Publish bool
SkipPull bool
RunImage string
}

func (c *Client) Rebase(ctx context.Context, opts RebaseOptions) error {
fetchImage := c.imageFetchFn(ctx, opts)

appImage, err := fetchImage(opts.RepoName)
if err != nil {
return err
}

runImageName, err := c.getRunImageName(ctx, opts, appImage)
if err != nil {
return err
}

baseImage, err := fetchImage(runImageName)
if err != nil {
return err
}

label, err := appImage.Label(lifecycle.MetadataLabel)
if err != nil {
return err
}
var metadata lifecycle.AppImageMetadata
if err := json.Unmarshal([]byte(label), &metadata); err != nil {
return err
}
c.logger.Info("Rebasing %s on run image %s", style.Symbol(appImage.Name()), style.Symbol(baseImage.Name()))
if err := appImage.Rebase(metadata.RunImage.TopLayer, baseImage); err != nil {
return err
}

metadata.RunImage.SHA, err = baseImage.Digest()
if err != nil {
return err
}
metadata.RunImage.TopLayer, err = baseImage.TopLayer()
if err != nil {
return err
}
newLabel, err := json.Marshal(metadata)
if err := appImage.SetLabel(lifecycle.MetadataLabel, string(newLabel)); err != nil {
return err
}

sha, err := appImage.Save()
if err != nil {
return err
}
c.logger.Info("New sha: %s", style.Symbol(sha))
return nil
}

func (c *Client) imageFetchFn(ctx context.Context, opts RebaseOptions) func(string) (image.Image, error) {
var newImageFn func(string) (image.Image, error)
if opts.Publish {
newImageFn = c.fetcher.FetchRemoteImage
} else {
newImageFn = func(name string) (image.Image, error) {
if opts.SkipPull {
return c.fetcher.FetchLocalImage(name)

} else {
return c.fetcher.FetchUpdatedLocalImage(ctx, name, c.logger.RawVerboseWriter())
}
}
}
return newImageFn
}

func (c *Client) getRunImageName(ctx context.Context, opts RebaseOptions, appImage image.Image) (string, error) {
var runImageName string
if opts.RunImage != "" {
runImageName = opts.RunImage
} else {
contents, err := appImage.Label(lifecycle.MetadataLabel)
if err != nil {
return "", err
}

var appImageMetadata lifecycle.AppImageMetadata
if err := json.Unmarshal([]byte(contents), &appImageMetadata); err != nil {
return "", err
}

registry, err := config.Registry(opts.RepoName)
if err != nil {
return "", errors.Wrapf(err, "parsing registry from reference '%s'", opts.RepoName)
}

var mirrors []string
if localRunImage := c.config.GetRunImage(appImageMetadata.Stack.RunImage.Image); localRunImage != nil {
mirrors = localRunImage.Mirrors
}
mirrors = append(mirrors, appImageMetadata.Stack.RunImage.Image)
mirrors = append(mirrors, appImageMetadata.Stack.RunImage.Mirrors...)
runImageName, err = config.ImageByRegistry(registry, mirrors)
if err != nil {
return "", errors.Wrapf(err, "find image by registry")
}
}

if runImageName == "" {
return "", errors.New("run image must be specified")
}

return runImageName, nil
}
Loading

0 comments on commit 0019490

Please sign in to comment.