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

Commit f9acea2

Browse files
committed
Introduce --installer-context option
Create a new DockerCli used to run installer image within requested context cli.Cli (not DockerCli implementation) doesn't offer any way to switch contexts once intialized. Signed-off-by: Nicolas De Loof <[email protected]>
1 parent 0fe1aaf commit f9acea2

File tree

7 files changed

+97
-41
lines changed

7 files changed

+97
-41
lines changed

internal/cnab/driver.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -25,13 +25,13 @@ type BindMount struct {
2525

2626
const defaultSocketPath string = "/var/run/docker.sock"
2727

28-
func RequiredClaimBindMount(c claim.Claim, targetContextName string, dockerCli command.Cli) (BindMount, error) {
28+
func RequiredClaimBindMount(c claim.Claim, dockerCli command.Cli) (BindMount, error) {
2929
var specifiedOrchestrator string
3030
if rawOrchestrator, ok := c.Parameters[internal.ParameterOrchestratorName]; ok {
3131
specifiedOrchestrator = rawOrchestrator.(string)
3232
}
3333

34-
return RequiredBindMount(targetContextName, specifiedOrchestrator, dockerCli.ContextStore())
34+
return RequiredBindMount(dockerCli.CurrentContext(), specifiedOrchestrator, dockerCli.ContextStore())
3535
}
3636

3737
// RequiredBindMount Returns the path required to bind mount when running

internal/commands/image/render.go

Lines changed: 9 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@ import (
2222

2323
type renderOptions struct {
2424
cliopts.ParametersOptions
25+
installerContextOptions
2526
formatDriver string
2627
renderOutput string
2728
}
@@ -58,7 +59,7 @@ func runRender(dockerCli command.Cli, appname string, opts renderOptions) error
5859
w = f
5960
}
6061

61-
action, installation, errBuf, err := prepareCustomAction(internal.ActionRenderName, dockerCli, appname, w, opts.ParametersOptions)
62+
action, installation, errBuf, err := prepareCustomAction(internal.ActionRenderName, dockerCli, appname, w, opts)
6263
if err != nil {
6364
return err
6465
}
@@ -70,8 +71,7 @@ func runRender(dockerCli command.Cli, appname string, opts renderOptions) error
7071
return nil
7172
}
7273

73-
func prepareCustomAction(actionName string, dockerCli command.Cli, appname string, stdout io.Writer,
74-
paramsOpts cliopts.ParametersOptions) (*action.RunCustom, *appstore.Installation, *bytes.Buffer, error) {
74+
func prepareCustomAction(actionName string, dockerCli command.Cli, appname string, stdout io.Writer, opts renderOptions) (*action.RunCustom, *appstore.Installation, *bytes.Buffer, error) {
7575
s, err := appstore.NewApplicationStore(config.Dir())
7676
if err != nil {
7777
return nil, nil, nil, err
@@ -91,13 +91,16 @@ func prepareCustomAction(actionName string, dockerCli command.Cli, appname strin
9191
installation.Bundle = bundle
9292

9393
if err := bdl.MergeBundleParameters(installation,
94-
bdl.WithFileParameters(paramsOpts.ParametersFiles),
95-
bdl.WithCommandLineParameters(paramsOpts.Overrides),
94+
bdl.WithFileParameters(opts.ParametersFiles),
95+
bdl.WithCommandLineParameters(opts.Overrides),
9696
); err != nil {
9797
return nil, nil, nil, err
9898
}
9999

100-
driverImpl, errBuf := cnab.PrepareDriver(dockerCli, cnab.BindMount{}, stdout)
100+
driverImpl, errBuf, err := setupDriver(installation, dockerCli, opts.installerContextOptions)
101+
if err != nil {
102+
return nil, nil, nil, err
103+
}
101104
a := &action.RunCustom{
102105
Action: actionName,
103106
Driver: driverImpl,

internal/commands/list.go

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,6 @@ import (
1717
)
1818

1919
type listOptions struct {
20-
targetContextOptions
2120
}
2221

2322
var (
@@ -56,8 +55,7 @@ func listCmd(dockerCli command.Cli) *cobra.Command {
5655
}
5756

5857
func runList(dockerCli command.Cli, opts listOptions) error {
59-
opts.SetDefaultTargetContext(dockerCli)
60-
installations, err := getInstallations(opts.targetContext, config.Dir())
58+
installations, err := getInstallations(dockerCli.CurrentContext(), config.Dir())
6159
if err != nil {
6260
return err
6361
}

internal/commands/remove.go

Lines changed: 4 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -6,14 +6,14 @@ import (
66

77
"github.com/deislabs/cnab-go/action"
88
"github.com/deislabs/cnab-go/credentials"
9-
"github.com/docker/app/internal/cnab"
109
"github.com/docker/cli/cli"
1110
"github.com/docker/cli/cli/command"
1211
"github.com/spf13/cobra"
1312
)
1413

1514
type removeOptions struct {
1615
credentialOptions
16+
installerContextOptions
1717
force bool
1818
}
1919

@@ -38,9 +38,8 @@ func removeCmd(dockerCli command.Cli) *cobra.Command {
3838

3939
func runRemove(dockerCli command.Cli, installationName string, opts removeOptions) (mainErr error) {
4040
defer muteDockerCli(dockerCli)()
41-
opts.SetDefaultTargetContext(dockerCli)
4241

43-
_, installationStore, credentialStore, err := prepareStores(opts.targetContext)
42+
_, installationStore, credentialStore, err := prepareStores(dockerCli.CurrentContext())
4443
if err != nil {
4544
return err
4645
}
@@ -61,11 +60,10 @@ func runRemove(dockerCli command.Cli, installationName string, opts removeOption
6160
fmt.Fprintf(os.Stderr, "deletion forced for running App %q\n", installationName)
6261
}()
6362
}
64-
bind, err := cnab.RequiredClaimBindMount(installation.Claim, opts.targetContext, dockerCli)
63+
driverImpl, errBuf, err := setupDriver(installation, dockerCli, opts.installerContextOptions)
6564
if err != nil {
6665
return err
6766
}
68-
driverImpl, errBuf := cnab.PrepareDriver(dockerCli, bind, nil)
6967
creds, err := prepareCredentialSet(installation.Bundle, opts.CredentialSetOpts(dockerCli, credentialStore)...)
7068
if err != nil {
7169
return err
@@ -85,6 +83,6 @@ func runRemove(dockerCli command.Cli, installationName string, opts removeOption
8583
if err := installationStore.Delete(installationName); err != nil {
8684
return fmt.Errorf("Failed to delete running App %q from the installation store: %s", installationName, err)
8785
}
88-
fmt.Fprintf(os.Stdout, "App %q uninstalled on context %q\n", installationName, opts.targetContext)
86+
fmt.Fprintf(dockerCli.Out(), "App %q uninstalled on context %q\n", installationName, dockerCli.CurrentContext())
8987
return nil
9088
}

internal/commands/root.go

Lines changed: 68 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,18 +1,24 @@
11
package commands
22

33
import (
4+
"bytes"
45
"fmt"
56
"io/ioutil"
67
"os"
78

89
"github.com/deislabs/cnab-go/claim"
10+
"github.com/deislabs/cnab-go/driver"
911
"github.com/docker/app/internal"
12+
"github.com/docker/app/internal/cnab"
1013
"github.com/docker/app/internal/commands/build"
1114
"github.com/docker/app/internal/commands/image"
1215
"github.com/docker/app/internal/store"
1316
appstore "github.com/docker/app/internal/store"
1417
"github.com/docker/cli/cli/command"
1518
"github.com/docker/cli/cli/config"
19+
"github.com/docker/cli/cli/flags"
20+
"github.com/pkg/errors"
21+
"github.com/sirupsen/logrus"
1622
"github.com/spf13/cobra"
1723
"github.com/spf13/pflag"
1824
)
@@ -110,21 +116,76 @@ func prepareBundleStore() (store.BundleStore, error) {
110116
return bundleStore, nil
111117
}
112118

113-
type targetContextOptions struct {
114-
targetContext string
119+
func setupDriver(installation *store.Installation, dockerCli command.Cli, opts installerContextOptions) (driver.Driver, *bytes.Buffer, error) {
120+
dockerCli, err := opts.setInstallerContext(dockerCli)
121+
if err != nil {
122+
return nil, nil, err
123+
}
124+
bind, err := cnab.RequiredClaimBindMount(installation.Claim, dockerCli)
125+
if err != nil {
126+
return nil, nil, err
127+
}
128+
driverImpl, errBuf := cnab.PrepareDriver(dockerCli, bind, nil)
129+
return driverImpl, errBuf, nil
115130
}
116131

117-
func (o *targetContextOptions) SetDefaultTargetContext(dockerCli command.Cli) {
118-
o.targetContext = getTargetContext(o.targetContext, dockerCli.CurrentContext())
132+
type parametersOptions struct {
133+
parametersFiles []string
134+
overrides []string
135+
}
136+
137+
func (o *parametersOptions) addFlags(flags *pflag.FlagSet) {
138+
flags.StringArrayVar(&o.parametersFiles, "parameters-file", []string{}, "Override parameters file")
139+
flags.StringArrayVarP(&o.overrides, "set", "s", []string{}, "Override parameter value")
140+
}
141+
142+
type installerContextOptions struct {
143+
installerContext string
144+
}
145+
146+
func (o *installerContextOptions) addFlag(flags *pflag.FlagSet) {
147+
flags.StringVar(&o.installerContext, "installer-context", "", "Context on which the installer image is ran (default: <current-context>)")
148+
}
149+
150+
func (o *installerContextOptions) setInstallerContext(dockerCli command.Cli) (command.Cli, error) {
151+
o.installerContext = getTargetContext(o.installerContext, dockerCli.CurrentContext())
152+
if o.installerContext != dockerCli.CurrentContext() {
153+
if _, err := dockerCli.ContextStore().GetMetadata(o.installerContext); err != nil {
154+
return nil, errors.Wrapf(err, "Unknown docker context %s", o.installerContext)
155+
}
156+
fmt.Fprintf(dockerCli.Out(), "Using context %q to run installer image", o.installerContext)
157+
cli, err := command.NewDockerCli()
158+
if err != nil {
159+
return nil, err
160+
}
161+
opts := flags.ClientOptions{
162+
Common: &flags.CommonOptions{
163+
Context: o.installerContext,
164+
LogLevel: logrus.GetLevel().String(),
165+
},
166+
ConfigDir: config.Dir(),
167+
}
168+
if err = cli.Apply(
169+
command.WithInputStream(dockerCli.In()),
170+
command.WithOutputStream(dockerCli.Out()),
171+
command.WithErrorStream(dockerCli.Err())); err != nil {
172+
return nil, err
173+
}
174+
if err = cli.Initialize(&opts); err != nil {
175+
return nil, err
176+
}
177+
return cli, nil
178+
}
179+
return dockerCli, nil
119180
}
120181

121182
func getTargetContext(optstargetContext, currentContext string) string {
122183
var targetContext string
123184
switch {
124185
case optstargetContext != "":
125186
targetContext = optstargetContext
126-
case os.Getenv("DOCKER_TARGET_CONTEXT") != "":
127-
targetContext = os.Getenv("DOCKER_TARGET_CONTEXT")
187+
case os.Getenv("INSTALLER_TARGET_CONTEXT") != "":
188+
targetContext = os.Getenv("INSTALLER_TARGET_CONTEXT")
128189
}
129190
if targetContext == "" {
130191
targetContext = currentContext
@@ -133,7 +194,6 @@ func getTargetContext(optstargetContext, currentContext string) string {
133194
}
134195

135196
type credentialOptions struct {
136-
targetContextOptions
137197
credentialsets []string
138198
credentials []string
139199
sendRegistryAuth bool
@@ -149,7 +209,7 @@ func (o *credentialOptions) CredentialSetOpts(dockerCli command.Cli, credentialS
149209
return []credentialSetOpt{
150210
addNamedCredentialSets(credentialStore, o.credentialsets),
151211
addCredentials(o.credentials),
152-
addDockerCredentials(o.targetContext, dockerCli.ContextStore()),
212+
addDockerCredentials(dockerCli.CurrentContext(), dockerCli.ContextStore()),
153213
addRegistryCredentials(o.sendRegistryAuth, dockerCli),
154214
}
155215
}

internal/commands/run.go

Lines changed: 9 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@ import (
2323
type runOptions struct {
2424
cliopts.ParametersOptions
2525
credentialOptions
26+
installerContextOptions
2627
orchestrator string
2728
kubeNamespace string
2829
stackName string
@@ -92,14 +93,8 @@ func runDockerApp(dockerCli command.Cli, appname string, opts runOptions) error
9293
return runBundle(dockerCli, bndl, opts, ref.String())
9394
}
9495

95-
func runBundle(dockerCli command.Cli, bndl *bundle.Bundle, opts runOptions, ref string) error {
96-
opts.SetDefaultTargetContext(dockerCli)
97-
98-
bind, err := cnab.RequiredBindMount(opts.targetContext, opts.orchestrator, dockerCli.ContextStore())
99-
if err != nil {
100-
return err
101-
}
102-
_, installationStore, credentialStore, err := prepareStores(opts.targetContext)
96+
func runBundle(dockerCli command.Cli, bndl *bundle.Bundle, opts runOptions, ref string) (err error) {
97+
_, installationStore, credentialStore, err := prepareStores(dockerCli.CurrentContext())
10398
if err != nil {
10499
return err
105100
}
@@ -114,7 +109,7 @@ func runBundle(dockerCli command.Cli, bndl *bundle.Bundle, opts runOptions, ref
114109
if installation, err := installationStore.Read(installationName); err == nil {
115110
// A failed installation can be overridden, but with a warning
116111
if isInstallationFailed(installation) {
117-
fmt.Fprintf(os.Stderr, "WARNING: installing over previously failed installation %q\n", installationName)
112+
fmt.Fprintf(dockerCli.Err(), "WARNING: installing over previously failed installation %q\n", installationName)
118113
} else {
119114
// Return an error in case of successful installation, or even failed upgrade, which means
120115
// their was already a successful installation.
@@ -128,7 +123,10 @@ func runBundle(dockerCli command.Cli, bndl *bundle.Bundle, opts runOptions, ref
128123
return err
129124
}
130125

131-
driverImpl, errBuf := cnab.PrepareDriver(dockerCli, bind, nil)
126+
driverImpl, errBuf, err := setupDriver(installation, dockerCli, opts.installerContextOptions)
127+
if err != nil {
128+
return err
129+
}
132130
installation.Bundle = bndl
133131

134132
if err := bdl.MergeBundleParameters(installation,
@@ -165,6 +163,6 @@ func runBundle(dockerCli command.Cli, bndl *bundle.Bundle, opts runOptions, ref
165163
return err2
166164
}
167165

168-
fmt.Fprintf(os.Stdout, "App %q running on context %q\n", installationName, opts.targetContext)
166+
fmt.Fprintf(dockerCli.Out(), "App %q running on context %q\n", installationName, dockerCli.CurrentContext())
169167
return nil
170168
}

internal/commands/update.go

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ import (
1616
type updateOptions struct {
1717
cliopts.ParametersOptions
1818
credentialOptions
19+
installerContextOptions
1920
bundleOrDockerApp string
2021
}
2122

@@ -39,9 +40,8 @@ func updateCmd(dockerCli command.Cli) *cobra.Command {
3940

4041
func runUpdate(dockerCli command.Cli, installationName string, opts updateOptions) error {
4142
defer muteDockerCli(dockerCli)()
42-
opts.SetDefaultTargetContext(dockerCli)
4343

44-
bundleStore, installationStore, credentialStore, err := prepareStores(opts.targetContext)
44+
bundleStore, installationStore, credentialStore, err := prepareStores(dockerCli.CurrentContext())
4545
if err != nil {
4646
return err
4747
}
@@ -70,11 +70,10 @@ func runUpdate(dockerCli command.Cli, installationName string, opts updateOption
7070
return err
7171
}
7272

73-
bind, err := cnab.RequiredClaimBindMount(installation.Claim, opts.targetContext, dockerCli)
73+
driverImpl, errBuf, err := setupDriver(installation, dockerCli, opts.installerContextOptions)
7474
if err != nil {
7575
return err
7676
}
77-
driverImpl, errBuf := cnab.PrepareDriver(dockerCli, bind, nil)
7877
creds, err := prepareCredentialSet(installation.Bundle, opts.CredentialSetOpts(dockerCli, credentialStore)...)
7978
if err != nil {
8079
return err
@@ -93,6 +92,6 @@ func runUpdate(dockerCli command.Cli, installationName string, opts updateOption
9392
if err2 != nil {
9493
return err2
9594
}
96-
fmt.Fprintf(os.Stdout, "Running App %q updated on context %q\n", installationName, opts.targetContext)
95+
fmt.Fprintf(dockerCli.Out(), "Running App %q updated on context %q\n", installationName, dockerCli.CurrentContext())
9796
return nil
9897
}

0 commit comments

Comments
 (0)