e2e test to check build command

Signed-off-by: Nicolas De Loof <nicolas.deloof@gmail.com>
This commit is contained in:
Nicolas De Loof 2019-09-27 17:04:18 +02:00 коммит произвёл Nicolas De loof
Родитель fd10e25e9a
Коммит e4fd0c8a95
10 изменённых файлов: 124 добавлений и 5 удалений

38
e2e/build_test.go Normal file
Просмотреть файл

@ -0,0 +1,38 @@
package e2e
import (
"encoding/json"
"github.com/deislabs/cnab-go/bundle"
"gotest.tools/assert"
"io/ioutil"
"os"
"path"
"testing"
"gotest.tools/icmd"
)
func TestBuild(t *testing.T) {
cmd, cleanup := dockerCli.createTestCmd()
defer cleanup()
testDir := path.Join("testdata", "build")
tmp, err := ioutil.TempDir("","")
assert.NilError(t, err)
defer os.Remove(tmp)
f := path.Join(tmp, "bundle.json")
cmd.Command = dockerCli.Command("app", "build", path.Join(testDir, "single"), "--output", f)
icmd.RunCmd(cmd).Assert(t, icmd.Success)
data, err := ioutil.ReadFile(f)
assert.NilError(t, err)
var bndl bundle.Bundle
err = json.Unmarshal(data, &bndl)
assert.NilError(t, err)
built := []string { bndl.InvocationImages[0].Digest, bndl.Images["web"].Digest, bndl.Images["worker"].Digest }
for _, ref := range built {
cmd.Command = dockerCli.Command("inspect", ref)
icmd.RunCmd(cmd).Assert(t, icmd.Success)
}
}

Просмотреть файл

@ -75,6 +75,9 @@ func TestRenderFormatters(t *testing.T) {
defer cleanup()
appPath := filepath.Join("testdata", "simple", "simple.dockerapp")
cmd.Command = dockerCli.Command("app", "build", appPath)
icmd.RunCmd(cmd).Assert(t, icmd.Success)
cmd.Command = dockerCli.Command("app", "render", "--formatter", "json", appPath)
result := icmd.RunCmd(cmd).Assert(t, icmd.Success)
golden.Assert(t, result.Stdout(), "expected-json-render.golden")

Просмотреть файл

@ -43,10 +43,11 @@ func runWithDindSwarmAndRegistry(t *testing.T, todo func(dindSwarmAndRegistryInf
// Solution found is: fix the port of the registry to be the same internally and externally
// and run the dind container in the same network namespace: this way 127.0.0.1:<registry-port> both resolves to the registry from the client and from dind
swarm := NewContainer("docker:18.09-dind", 2375, "--insecure-registry", fmt.Sprintf("127.0.0.1:%d", registryPort))
swarm := NewContainer("docker:19.03.2-dind", 2375, "--insecure-registry", fmt.Sprintf("127.0.0.1:%d", registryPort))
swarm.Start(t, "--expose", strconv.FormatInt(int64(registryPort), 10),
"-p", fmt.Sprintf("%d:%d", registryPort, registryPort),
"-p", "2375")
"-p", "2375",
"-e", "DOCKER_TLS_CERTDIR=") // Disable certificate generate on DinD startup
defer swarm.Stop(t)
registry := NewContainer("registry:2", registryPort)
@ -76,6 +77,9 @@ func runWithDindSwarmAndRegistry(t *testing.T, todo func(dindSwarmAndRegistryInf
cmd.Command = dockerCli.Command("load", "-i", tmpDir.Join("cnab-app-base.tar.gz"))
icmd.RunCmd(cmd).Assert(t, icmd.Success)
cmd.Command = dockerCli.Command("pull", "busybox:1.30.1")
icmd.RunCmd(cmd).Assert(t, icmd.Success)
info := dindSwarmAndRegistryInfo{
configuredCmd: cmd,
registryAddress: registry.GetAddress(t),

10
e2e/testdata/build/single.dockerapp/docker-compose.yml поставляемый Normal file
Просмотреть файл

@ -0,0 +1,10 @@
version: "3.6"
services:
web:
build:
context: ./web
worker:
build:
context: ./worker
db:
image: postgres:9.3

6
e2e/testdata/build/single.dockerapp/metadata.yml поставляемый Normal file
Просмотреть файл

@ -0,0 +1,6 @@
version: 1.1.0-beta1
name: simple
description: "new fancy webapp with microservices"
maintainers:
- name: John Developer
email: john.dev@example.com

0
e2e/testdata/build/single.dockerapp/parameters.yml поставляемый Normal file
Просмотреть файл

1
e2e/testdata/build/web/Dockerfile поставляемый Normal file
Просмотреть файл

@ -0,0 +1 @@
FROM scratch

1
e2e/testdata/build/worker/Dockerfile поставляемый Normal file
Просмотреть файл

@ -0,0 +1 @@
FROM scratch

Просмотреть файл

@ -11,6 +11,7 @@ import (
"github.com/moby/buildkit/session/auth/authprovider"
"github.com/opencontainers/go-digest"
"github.com/sirupsen/logrus"
"io/ioutil"
"os"
"path/filepath"
"strings"
@ -35,6 +36,7 @@ type buildOptions struct {
progress string
pull bool
tag string
out string
}
func buildCmd(dockerCli command.Cli) *cobra.Command {
@ -57,7 +59,8 @@ func buildCmd(dockerCli command.Cli) *cobra.Command {
flags.BoolVar(&opts.noCache, "no-cache", false, "Do not use cache when building the image")
flags.StringVar(&opts.progress, "progress", "auto", "Set type of progress output (auto, plain, tty). Use plain to show container output")
flags.BoolVar(&opts.pull, "pull", false, "Always attempt to pull a newer version of the image")
cmd.Flags().StringVarP(&opts.tag, "tag", "t", "", "Name and optionally a tag in the 'name:tag' format")
flags.StringVarP(&opts.out, "output", "o", "", "Dump generated bundle into a file")
flags.StringVarP(&opts.tag, "tag", "t", "", "Name and optionally a tag in the 'name:tag' format")
return cmd
}
@ -76,6 +79,7 @@ func runBuild(dockerCli command.Cli, application string, opt buildOptions) (refe
}
ctx := appcontext.Context()
compose, err := bake.ParseCompose(app.Composes()[0]) // Fixme can have > 1 composes ?
if err != nil {
return nil, err
@ -106,7 +110,7 @@ func runBuild(dockerCli command.Cli, application string, opt buildOptions) (refe
}
if logrus.IsLevelEnabled(logrus.DebugLevel) {
dt, err := json.MarshalIndent(map[string]map[string]bake.Target{"target": targets}, "", " ")
dt, err := json.MarshalIndent(targets, "", " ")
if err != nil {
return nil, err
}
@ -152,6 +156,13 @@ func runBuild(dockerCli command.Cli, application string, opt buildOptions) (refe
}
fmt.Println("Successfully built service images")
if logrus.IsLevelEnabled(logrus.DebugLevel) {
dt, err := json.MarshalIndent(resp, "", " ")
if err != nil {
return nil, err
}
logrus.Debug(string(dt))
}
for service, r := range resp {
digest := r.ExporterResponse["containerimage.digest"]
@ -189,8 +200,23 @@ func runBuild(dockerCli command.Cli, application string, opt buildOptions) (refe
digest := digest.SHA256.FromBytes(b.Bytes())
ref = sha{digest}
}
if opt.out != "" {
b, err := json.MarshalIndent(bundle, "", " ")
if err != nil {
return ref, err
}
if opt.out == "-" {
_, err = os.Stdout.Write(b)
} else {
err = ioutil.WriteFile(opt.out, b, 0644)
}
return ref, err
}
if err := persistInBundleStore(ref, bundle); err != nil {
return nil, err
return ref, err
}
return ref, nil

Просмотреть файл

@ -1,6 +1,8 @@
package commands
import (
"bytes"
"context"
"fmt"
"github.com/deislabs/cnab-go/bundle"
"github.com/docker/app/internal/packager"
@ -10,8 +12,11 @@ import (
"github.com/docker/cli/cli/command"
"github.com/docker/cli/cli/config"
"github.com/docker/distribution/reference"
dockertypes "github.com/docker/docker/api/types"
"github.com/docker/docker/pkg/jsonmessage"
"github.com/pkg/errors"
"github.com/sirupsen/logrus"
"io/ioutil"
)
func makeBundleFromApp(dockerCli command.Cli, app *types.App, refOverride reference.NamedTagged) (*bundle.Bundle, error) {
@ -22,6 +27,31 @@ func makeBundleFromApp(dockerCli command.Cli, app *types.App, refOverride refere
return nil, err
}
buildContext := bytes.NewBuffer(nil)
if err := packager.PackInvocationImageContext(dockerCli, app, buildContext); err != nil {
return nil, err
}
logrus.Debugf("Building invocation image %s", invocationImageName)
buildResp, err := dockerCli.Client().ImageBuild(context.TODO(), buildContext, dockertypes.ImageBuildOptions{
Dockerfile: "Dockerfile",
Tags: []string{invocationImageName},
BuildArgs: map[string]*string{},
})
if err != nil {
return nil, err
}
defer buildResp.Body.Close()
if err := jsonmessage.DisplayJSONMessagesStream(buildResp.Body, ioutil.Discard, 0, false, func(jsonmessage.JSONMessage) {}); err != nil {
// If the invocation image can't be found we will get an error of the form:
// manifest for docker/cnab-app-base:v0.6.0-202-gbaf0b246c7 not found
if err.Error() == fmt.Sprintf("manifest for %s not found", packager.BaseInvocationImage(dockerCli)) {
return nil, fmt.Errorf("unable to resolve Docker App base image: %s", packager.BaseInvocationImage(dockerCli))
}
return nil, err
}
return packager.ToCNAB(app, invocationImageName)
}