This repository has been archived by the owner on Jun 13, 2021. It is now read-only.
/
bundle.go
98 lines (87 loc) · 3.1 KB
/
bundle.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
92
93
94
95
96
97
98
package packager
import (
"bytes"
"context"
"fmt"
"io/ioutil"
"github.com/deislabs/cnab-go/bundle"
"github.com/docker/app/internal/store"
"github.com/docker/app/types"
"github.com/docker/app/types/metadata"
"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"
)
func MakeBundleFromApp(dockerCli command.Cli, app *types.App, refOverride reference.NamedTagged) (*bundle.Bundle, error) {
logrus.Debug("Making app bundle")
meta := app.Metadata()
invocationImageName, err := MakeInvocationImageName(meta, refOverride)
if err != nil {
return nil, err
}
buildContext := bytes.NewBuffer(nil)
if err := 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", BaseInvocationImage(dockerCli)) {
return nil, fmt.Errorf("unable to resolve Docker App base image: %s", BaseInvocationImage(dockerCli))
}
return nil, err
}
return ToCNAB(app, invocationImageName)
}
func MakeInvocationImageName(meta metadata.AppMetadata, refOverride reference.NamedTagged) (string, error) {
if refOverride != nil {
return MakeCNABImageName(reference.FamiliarName(refOverride), refOverride.Tag(), "-invoc")
}
return MakeCNABImageName(meta.Name, meta.Version, "-invoc")
}
func MakeCNABImageName(appName, appVersion, suffix string) (string, error) {
name := fmt.Sprintf("%s:%s%s", appName, appVersion, suffix)
if _, err := reference.ParseNormalizedNamed(name); err != nil {
return "", errors.Wrapf(err, "image name %q is invalid, please check name and version fields", name)
}
return name, nil
}
func PersistInBundleStore(ref reference.Reference, bndle *bundle.Bundle) (reference.Reference, error) {
appstore, err := store.NewApplicationStore(config.Dir())
if err != nil {
return nil, err
}
bundleStore, err := appstore.BundleStore()
if err != nil {
return nil, err
}
return bundleStore.Store(ref, bndle)
}
func GetNamedTagged(tag string) (reference.NamedTagged, error) {
if tag == "" {
return nil, nil
}
namedRef, err := reference.ParseNormalizedNamed(tag)
if err != nil {
return nil, err
}
ref, ok := reference.TagNameOnly(namedRef).(reference.NamedTagged)
if !ok {
return nil, fmt.Errorf("tag %q must be name with a tag in the 'name:tag' format", tag)
}
return ref, nil
}