Skip to content
This repository was archived by the owner on Jul 18, 2025. It is now read-only.

Commit 8574b9a

Browse files
Bump docker/cli, moby/moby, grpc, runc and duffle
Signed-off-by: Silvin Lubecki <silvin.lubecki@docker.com>
1 parent 5bf177d commit 8574b9a

621 files changed

Lines changed: 104520 additions & 8969 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

Gopkg.lock

Lines changed: 198 additions & 25 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Gopkg.toml

Lines changed: 8 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -25,17 +25,17 @@ required = ["github.com/wadey/gocovmerge"]
2525
# We need > 0.1.1 as it depends on uppercase Sirupsen/logrus.
2626
[[override]]
2727
name = "github.com/opencontainers/runc"
28-
version = "v1.0.0-rc5"
28+
version = "v1.0.0-rc6"
2929

30-
[[constraint]]
30+
[[override]]
3131
name = "github.com/docker/cli"
32-
branch = "expose-stack-commands-1500"
33-
source = "github.com/silvin-lubecki/cli"
32+
revision = "f95ca8e1ba6c22c9abcdbf65e8dcc39c53958bba"
3433

35-
[[constraint]]
36-
name = "github.com/deis/duffle"
37-
branch = "dockercon-version"
38-
source = "git@github.com:simonferquel/duffle.git"
34+
# Waiting for https://github.com/deislabs/duffle/pull/617 to be merged
35+
[[override]]
36+
name = "github.com/deislabs/duffle"
37+
branch = "master-docker-app"
38+
source = "github.com/silvin-lubecki/duffle"
3939

4040
[[constraint]]
4141
name = "github.com/sirupsen/logrus"
@@ -57,10 +57,6 @@ required = ["github.com/wadey/gocovmerge"]
5757
name = "github.com/docker/go-metrics"
5858
revision = "d466d4f6fd960e01820085bd7e1a24426ee7ef18"
5959

60-
[[override]]
61-
name = "github.com/docker/docker"
62-
revision = "53e55db9d3f0f0910ea95515222c8a35e106f10e"
63-
6460
[[override]]
6561
name = "github.com/docker/distribution"
6662
revision = "83389a148052d74ac602f5f1d62f86ff2f3c4aa5"
@@ -85,10 +81,6 @@ required = ["github.com/wadey/gocovmerge"]
8581
name = "k8s.io/client-go"
8682
revision = "kubernetes-1.11.1"
8783

88-
[[override]]
89-
name = "google.golang.org/grpc"
90-
revision = "v1.3.0"
91-
9284
# This is using a fork waiting for go-yaml/yaml#375 to be merged
9385
# This PR allows to set a max decoded value, thus not being exposed to yaml bombs
9486
[[override]]

cmd/docker-app/bundle.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ import (
77
"fmt"
88
"io/ioutil"
99

10-
"github.com/deis/duffle/pkg/bundle"
10+
"github.com/deislabs/duffle/pkg/bundle"
1111
"github.com/docker/app/internal/packager"
1212
"github.com/docker/app/types"
1313
"github.com/docker/app/types/metadata"

cmd/docker-app/install.go

Lines changed: 342 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,342 @@
1+
package main
2+
3+
import (
4+
"fmt"
5+
"io/ioutil"
6+
"os"
7+
"path/filepath"
8+
"strings"
9+
10+
"github.com/deis/duffle/pkg/action"
11+
"github.com/deis/duffle/pkg/bundle"
12+
"github.com/deis/duffle/pkg/claim"
13+
"github.com/deis/duffle/pkg/credentials"
14+
"github.com/deis/duffle/pkg/driver"
15+
"github.com/deis/duffle/pkg/duffle/home"
16+
"github.com/deis/duffle/pkg/loader"
17+
"github.com/deis/duffle/pkg/utils/crud"
18+
"github.com/docker/app/internal"
19+
"github.com/docker/app/internal/packager"
20+
"github.com/docker/app/types/parameters"
21+
"github.com/docker/cli/cli"
22+
"github.com/docker/cli/cli/command"
23+
"github.com/docker/cli/cli/context/store"
24+
cliopts "github.com/docker/cli/opts"
25+
"github.com/docker/docker/pkg/homedir"
26+
"github.com/pkg/errors"
27+
"github.com/spf13/cobra"
28+
"github.com/spf13/pflag"
29+
)
30+
31+
type installOptions struct {
32+
parametersOptions
33+
orchestrator string
34+
namespace string
35+
kubeNamespace string
36+
stackName string
37+
insecure bool
38+
sendRegistryAuth bool
39+
targetContext string
40+
credentialsets []string
41+
}
42+
43+
type parametersOptions struct {
44+
parametersFiles []string
45+
env []string
46+
}
47+
48+
func (o *parametersOptions) addFlags(flags *pflag.FlagSet) {
49+
flags.StringArrayVarP(&o.parametersFiles, "parameters-files", "f", []string{}, "Override parameters files")
50+
flags.StringArrayVarP(&o.env, "set", "s", []string{}, "Override parameters values")
51+
}
52+
53+
type nameKind uint
54+
55+
const (
56+
_ nameKind = iota
57+
nameKindEmpty
58+
nameKindFile
59+
nameKindDir
60+
nameKindReference
61+
)
62+
63+
const longDescription = `Install the application on either Swarm or Kubernetes.
64+
Bundle name is optional, and can be
65+
- empty: resolve to any *.dockerapp file or directory in working dir
66+
- existing file path: work with any *.dockerapp file or dir, or any CNAB bundle file (signed or unsigned)
67+
- match a bundle name in the local duffle bundle repository
68+
- refers to a CNAB bundle in a container registry
69+
`
70+
71+
// installCmd represents the install command
72+
func installCmd(dockerCli command.Cli) *cobra.Command {
73+
var opts installOptions
74+
75+
cmd := &cobra.Command{
76+
Use: "install [<bundle name>] [options]",
77+
Aliases: []string{"deploy"},
78+
Short: "Install an application",
79+
Long: longDescription,
80+
Args: cli.RequiresMaxArgs(1),
81+
RunE: func(cmd *cobra.Command, args []string) error {
82+
return runInstall(dockerCli, firstOrEmpty(args), opts)
83+
},
84+
}
85+
opts.parametersOptions.addFlags(cmd.Flags())
86+
cmd.Flags().StringVarP(&opts.orchestrator, "orchestrator", "o", "", "Orchestrator to install on (swarm, kubernetes)")
87+
cmd.Flags().StringVar(&opts.namespace, "namespace", "", "Namespace to use (default: namespace in metadata)")
88+
cmd.Flags().StringVar(&opts.kubeNamespace, "kube-namespace", "default", "Kubernetes namespace to install into")
89+
cmd.Flags().StringVar(&opts.stackName, "name", "", "Installation name (defaults to application name)")
90+
cmd.Flags().StringVar(&opts.targetContext, "target-context", "", "Context on which to install the application")
91+
cmd.Flags().BoolVar(&opts.insecure, "insecure", false, "Use insecure registry, without SSL")
92+
cmd.Flags().BoolVar(&opts.sendRegistryAuth, "with-registry-auth", false, "Sends registry auth")
93+
cmd.Flags().StringArrayVarP(&opts.credentialsets, "credential-set", "c", []string{}, "Use a duffle credentialset (either a YAML file, or a credential set present in the duffle credential store)")
94+
95+
return cmd
96+
}
97+
98+
func runInstall(dockerCli command.Cli, appname string, opts installOptions) error {
99+
muteDockerCli(dockerCli)
100+
targetContext := getTargetContext(opts.targetContext)
101+
parameterValues, err := prepareParameters(opts.parametersOptions)
102+
if err != nil {
103+
return err
104+
}
105+
106+
bndl, err := resolveBundle(dockerCli, opts.namespace, appname, opts.insecure)
107+
if err != nil {
108+
return err
109+
}
110+
if opts.sendRegistryAuth {
111+
return errors.New("with-registry-auth is not supported at the moment")
112+
}
113+
if err := bndl.Validate(); err != nil {
114+
return err
115+
}
116+
h := duffleHome()
117+
claimName := opts.stackName
118+
if claimName == "" {
119+
claimName = bndl.Name
120+
}
121+
claimStore := claim.NewClaimStore(crud.NewFileSystemStore(h.Claims(), "json"))
122+
if _, err = claimStore.Read(claimName); err == nil {
123+
return fmt.Errorf("installation %q already exists", claimName)
124+
}
125+
c, err := claim.New(claimName)
126+
if err != nil {
127+
return err
128+
}
129+
if _, ok := bndl.Parameters["docker.orchestrator"]; ok {
130+
parameterValues["docker.orchestrator"] = opts.orchestrator
131+
}
132+
if _, ok := bndl.Parameters["docker.kubernetes-namespace"]; ok {
133+
parameterValues["docker.kubernetes-namespace"] = opts.kubeNamespace
134+
}
135+
136+
driverImpl, err := prepareDriver(dockerCli)
137+
if err != nil {
138+
return err
139+
}
140+
creds, err := prepareCredentialSet(targetContext, dockerCli.ContextStore(), bndl, opts.credentialsets)
141+
if err != nil {
142+
return err
143+
}
144+
if err := credentials.Validate(creds, bndl.Credentials); err != nil {
145+
return err
146+
}
147+
148+
c.Bundle = bndl
149+
convertedParamValues := map[string]interface{}{}
150+
151+
if err := applyParameterValues(parameterValues, bndl.Parameters, convertedParamValues); err != nil {
152+
return err
153+
}
154+
155+
c.Parameters, err = bundle.ValuesOrDefaults(convertedParamValues, bndl)
156+
if err != nil {
157+
return err
158+
}
159+
inst := &action.Install{
160+
Driver: driverImpl,
161+
}
162+
err = inst.Run(c, creds, dockerCli.Out())
163+
err2 := claimStore.Store(*c)
164+
if err != nil {
165+
return fmt.Errorf("install failed: %v", err)
166+
}
167+
return err2
168+
}
169+
170+
func applyParameterValues(parameterValues map[string]string, parameterDefinitions map[string]bundle.ParameterDefinition, finalValues map[string]interface{}) error {
171+
for k, v := range parameterValues {
172+
pd, ok := parameterDefinitions[k]
173+
if !ok {
174+
return fmt.Errorf("parameter %q is not defined in the bundle", k)
175+
}
176+
value, err := pd.ConvertValue(v)
177+
if err != nil {
178+
return errors.Wrapf(err, "invalid value for parameter %q", k)
179+
}
180+
if err := pd.ValidateParameterValue(value); err != nil {
181+
return errors.Wrapf(err, "invalid value for parameter %q", k)
182+
}
183+
finalValues[k] = value
184+
}
185+
return nil
186+
}
187+
188+
func prepareParameters(opts parametersOptions) (map[string]string, error) {
189+
p, err := parameters.LoadFiles(opts.parametersFiles)
190+
if err != nil {
191+
return nil, err
192+
}
193+
d := cliopts.ConvertKVStringsToMap(opts.env)
194+
overrides, err := parameters.FromFlatten(d)
195+
if err != nil {
196+
return nil, err
197+
}
198+
if p, err = parameters.Merge(p, overrides); err != nil {
199+
return nil, err
200+
}
201+
return p.Flatten(), nil
202+
}
203+
204+
func getAppNameKind(name string) (string, nameKind) {
205+
if name == "" {
206+
return name, nameKindEmpty
207+
}
208+
// name can be a bundle.json file, a single dockerapp file, or a dockerapp directory
209+
st, err := os.Stat(name)
210+
if os.IsNotExist(err) {
211+
// try with .dockerapp extension
212+
st, err = os.Stat(name + internal.AppExtension)
213+
if err == nil {
214+
name += internal.AppExtension
215+
}
216+
}
217+
if err != nil {
218+
return name, nameKindReference
219+
}
220+
if st.IsDir() {
221+
return name, nameKindDir
222+
}
223+
return name, nameKindFile
224+
}
225+
226+
func extractAndLoadAppBasedBundle(dockerCli command.Cli, namespace, name string) (*bundle.Bundle, error) {
227+
app, err := packager.Extract(name)
228+
if err != nil {
229+
return nil, err
230+
}
231+
defer app.Cleanup()
232+
return makeBundleFromApp(dockerCli, app, namespace, "")
233+
}
234+
235+
func resolveBundle(dockerCli command.Cli, namespace, name string, insecure bool) (*bundle.Bundle, error) {
236+
// resolution logic:
237+
// - if there is a docker-app package in working directory, or an http:// / https:// prefix, use packager.Extract result
238+
// - the name has a .json or .cnab extension and refers to an existing file or web resource: load the bundle
239+
// - name matches a bundle name:version stored in duffle bundle store: use it
240+
// - pull the bundle from the registry and add it to the bundle store
241+
name, kind := getAppNameKind(name)
242+
switch kind {
243+
case nameKindFile:
244+
if strings.HasSuffix(name, internal.AppExtension) {
245+
return extractAndLoadAppBasedBundle(dockerCli, namespace, name)
246+
}
247+
return loader.NewDetectingLoader().Load(name)
248+
case nameKindDir, nameKindEmpty:
249+
return extractAndLoadAppBasedBundle(dockerCli, namespace, name)
250+
case nameKindReference:
251+
// revert to local duffle bundle store or pull the bundle image
252+
return pullBundle(dockerCli, name, false, insecure)
253+
}
254+
return nil, fmt.Errorf("could not resolve bundle %q", name)
255+
}
256+
257+
func getTargetContext(optstargetContext string) string {
258+
var targetContext string
259+
switch {
260+
case optstargetContext != "":
261+
targetContext = optstargetContext
262+
case os.Getenv("DOCKER_TARGET_CONTEXT") != "":
263+
targetContext = os.Getenv("DOCKER_TARGET_CONTEXT")
264+
}
265+
if targetContext == command.ContextDockerHost {
266+
targetContext = ""
267+
}
268+
return targetContext
269+
}
270+
271+
func stringsKVToStringInterface(src map[string]string) map[string]interface{} {
272+
result := map[string]interface{}{}
273+
for k, v := range src {
274+
result[k] = v
275+
}
276+
return result
277+
}
278+
279+
func prepareCredentialSet(contextName string, contextStore store.Store, b *bundle.Bundle, namedCredentialsets []string) (map[string]string, error) {
280+
creds := map[string]string{}
281+
for _, file := range namedCredentialsets {
282+
if _, err := os.Stat(file); err != nil {
283+
file = filepath.Join(duffleHome().Credentials(), file+".yaml")
284+
}
285+
c, err := credentials.Load(file)
286+
if err != nil {
287+
return nil, err
288+
}
289+
values, err := c.Resolve()
290+
if err != nil {
291+
return nil, err
292+
}
293+
for k, v := range values {
294+
if _, ok := creds[k]; ok {
295+
return nil, fmt.Errorf("ambiguous credential resolution: %q is present in multiple credential sets", k)
296+
}
297+
creds[k] = v
298+
}
299+
}
300+
if contextName != "" {
301+
data, err := ioutil.ReadAll(store.Export(contextName, contextStore))
302+
if err != nil {
303+
return nil, err
304+
}
305+
creds["docker.context"] = string(data)
306+
}
307+
_, requiresDockerContext := b.Credentials["docker.context"]
308+
_, hasDockerContext := creds["docker.context"]
309+
if requiresDockerContext && !hasDockerContext {
310+
return nil, errors.New("no target context specified. use use --target-context= or DOCKER_TARGET_CONTEXT= to define it")
311+
}
312+
return creds, nil
313+
}
314+
315+
func duffleHome() home.Home {
316+
if h := os.Getenv(home.HomeEnvVar); h != "" {
317+
return home.Home(h)
318+
}
319+
return home.Home(filepath.Join(homedir.Get(), ".duffle"))
320+
}
321+
322+
// prepareDriver prepares a driver per the user's request.
323+
func prepareDriver(dockerCli command.Cli) (driver.Driver, error) {
324+
driverImpl, err := driver.Lookup("docker")
325+
if err != nil {
326+
return driverImpl, err
327+
}
328+
if d, ok := driverImpl.(*driver.DockerDriver); ok {
329+
d.SetDockerCli(dockerCli)
330+
}
331+
332+
// Load any driver-specific config out of the environment.
333+
if configurable, ok := driverImpl.(driver.Configurable); ok {
334+
driverCfg := map[string]string{}
335+
for env := range configurable.Config() {
336+
driverCfg[env] = os.Getenv(env)
337+
}
338+
configurable.SetConfig(driverCfg)
339+
}
340+
341+
return driverImpl, err
342+
}

0 commit comments

Comments
 (0)