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

Commit bd8b7ac

Browse files
Add an Application Store, which can initialize a common bundle store, a claim store per context and a credential store per context.
* Removed duffle home dependency * Renaming all claim messages with installation Signed-off-by: Silvin Lubecki <[email protected]>
1 parent b8895da commit bd8b7ac

File tree

22 files changed

+515
-257
lines changed

22 files changed

+515
-257
lines changed

Gopkg.lock

Lines changed: 1 addition & 3 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

e2e/cnab_test.go

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,6 @@ func TestCallCustomStatusAction(t *testing.T) {
4141
tmpDir := fs.NewDir(t, t.Name())
4242
defer tmpDir.Remove()
4343
testDir := path.Join("testdata", testCase.cnab)
44-
cmd.Env = append(cmd.Env, "DUFFLE_HOME="+tmpDir.Path())
4544

4645
// We need to explicitly set the SYSTEMROOT on windows
4746
// otherwise we get the error:

e2e/commands_test.go

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -307,7 +307,6 @@ func testDockerAppLifecycle(t *testing.T, useBindMount bool) {
307307
tmpDir := fs.NewDir(t, appName)
308308
defer tmpDir.Remove()
309309

310-
cmd.Env = append(cmd.Env, "DUFFLE_HOME="+tmpDir.Path())
311310
cmd.Env = append(cmd.Env, "DOCKER_TARGET_CONTEXT=swarm-target-context")
312311

313312
// Running a swarm using docker in docker to install the application

e2e/pushpull_test.go

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,6 @@ func runWithDindSwarmAndRegistry(t *testing.T, todo func(dindSwarmAndRegistryInf
3131
tmpDir := fs.NewDir(t, t.Name())
3232
defer tmpDir.Remove()
3333

34-
cmd.Env = append(cmd.Env, "DUFFLE_HOME="+tmpDir.Path())
3534
cmd.Env = append(cmd.Env, "DOCKER_TARGET_CONTEXT=swarm-target-context")
3635

3736
// The dind doesn't have the cnab-app-base image so we save it in order to load it later

internal/commands/cnab.go

Lines changed: 20 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -8,22 +8,22 @@ import (
88
"io"
99
"io/ioutil"
1010
"os"
11-
"path/filepath"
1211
"strings"
1312

1413
"github.com/deislabs/duffle/pkg/action"
1514
"github.com/deislabs/duffle/pkg/bundle"
1615
"github.com/deislabs/duffle/pkg/claim"
1716
"github.com/deislabs/duffle/pkg/credentials"
1817
"github.com/deislabs/duffle/pkg/driver"
19-
"github.com/deislabs/duffle/pkg/duffle/home"
2018
"github.com/deislabs/duffle/pkg/loader"
2119
"github.com/docker/app/internal"
2220
"github.com/docker/app/internal/packager"
23-
bundlestore "github.com/docker/app/internal/store"
21+
appstore "github.com/docker/app/internal/store"
2422
"github.com/docker/cli/cli/command"
23+
"github.com/docker/cli/cli/config"
2524
"github.com/docker/cli/cli/context/docker"
2625
"github.com/docker/cli/cli/context/store"
26+
contextstore "github.com/docker/cli/cli/context/store"
2727
"github.com/docker/distribution/reference"
2828
"github.com/docker/docker/api/types"
2929
"github.com/docker/docker/api/types/container"
@@ -41,13 +41,10 @@ const defaultSocketPath string = "/var/run/docker.sock"
4141

4242
type credentialSetOpt func(b *bundle.Bundle, creds credentials.Set) error
4343

44-
func addNamedCredentialSets(namedCredentialsets []string) credentialSetOpt {
44+
func addNamedCredentialSets(credStore appstore.CredentialStore, namedCredentialsets []string) credentialSetOpt {
4545
return func(_ *bundle.Bundle, creds credentials.Set) error {
4646
for _, file := range namedCredentialsets {
47-
if _, err := os.Stat(file); err != nil {
48-
file = filepath.Join(duffleHome().Credentials(), file+".yaml")
49-
}
50-
c, err := credentials.Load(file)
47+
c, err := credStore.Read(file)
5148
if err != nil {
5249
return err
5350
}
@@ -63,12 +60,12 @@ func addNamedCredentialSets(namedCredentialsets []string) credentialSetOpt {
6360
}
6461
}
6562

66-
func addDockerCredentials(contextName string, contextStore store.Store) credentialSetOpt {
63+
func addDockerCredentials(contextName string, store contextstore.Store) credentialSetOpt {
6764
// docker desktop contexts require some rewriting for being used within a container
68-
contextStore = dockerDesktopAwareStore{Store: contextStore}
65+
store = dockerDesktopAwareStore{Store: store}
6966
return func(_ *bundle.Bundle, creds credentials.Set) error {
7067
if contextName != "" {
71-
data, err := ioutil.ReadAll(store.Export(contextName, contextStore))
68+
data, err := ioutil.ReadAll(contextstore.Export(contextName, store))
7269
if err != nil {
7370
return err
7471
}
@@ -141,10 +138,6 @@ func getTargetContext(optstargetContext, currentContext string) string {
141138
return targetContext
142139
}
143140

144-
func duffleHome() home.Home {
145-
return home.Home(home.DefaultHome())
146-
}
147-
148141
// prepareDriver prepares a driver per the user's request.
149142
func prepareDriver(dockerCli command.Cli, bindMount bindMount, stdout io.Writer) (driver.Driver, *bytes.Buffer, error) {
150143
driverImpl, err := driver.Lookup("docker")
@@ -217,11 +210,11 @@ func extractAndLoadAppBasedBundle(dockerCli command.Cli, name string) (*bundle.B
217210
return makeBundleFromApp(dockerCli, app)
218211
}
219212

220-
func resolveBundle(dockerCli command.Cli, name string, pullRef bool, insecureRegistries []string) (*bundle.Bundle, error) {
213+
func resolveBundle(dockerCli command.Cli, bundleStore appstore.BundleStore, name string, pullRef bool, insecureRegistries []string) (*bundle.Bundle, error) {
221214
// resolution logic:
222215
// - if there is a docker-app package in working directory, or an http:// / https:// prefix, use packager.Extract result
223216
// - the name has a .json or .cnab extension and refers to an existing file or web resource: load the bundle
224-
// - name matches a bundle name:version stored in duffle bundle store: use it
217+
// - name matches a bundle name:version stored in the bundle store: use it
225218
// - pull the bundle from the registry and add it to the bundle store
226219
name, kind := getAppNameKind(name)
227220
switch kind {
@@ -246,7 +239,7 @@ func resolveBundle(dockerCli command.Cli, name string, pullRef bool, insecureReg
246239
if err != nil {
247240
return nil, errors.Wrap(err, name)
248241
}
249-
return bundlestore.LookupOrPullBundle(dockerCli, reference.TagNameOnly(ref), pullRef, insecureRegistries)
242+
return bundleStore.LookupOrPullBundle(reference.TagNameOnly(ref), pullRef, dockerCli.ConfigFile(), insecureRegistries)
250243
}
251244
return nil, fmt.Errorf("could not resolve bundle %q", name)
252245
}
@@ -306,6 +299,14 @@ func isDockerHostLocal(host string) bool {
306299

307300
func prepareCustomAction(actionName string, dockerCli command.Cli, appname string, stdout io.Writer,
308301
registryOpts registryOptions, pullOpts pullOptions, paramsOpts parametersOptions) (*action.RunCustom, *claim.Claim, *bytes.Buffer, error) {
302+
s, err := appstore.NewApplicationStore(config.Dir())
303+
if err != nil {
304+
return nil, nil, nil, err
305+
}
306+
bundleStore, err := s.BundleStore()
307+
if err != nil {
308+
return nil, nil, nil, err
309+
}
309310

310311
c, err := claim.New("custom-action")
311312
if err != nil {
@@ -315,7 +316,7 @@ func prepareCustomAction(actionName string, dockerCli command.Cli, appname strin
315316
if err != nil {
316317
return nil, nil, nil, err
317318
}
318-
bundle, err := resolveBundle(dockerCli, appname, pullOpts.pull, registryOpts.insecureRegistries)
319+
bundle, err := resolveBundle(dockerCli, bundleStore, appname, pullOpts.pull, registryOpts.insecureRegistries)
319320
if err != nil {
320321
return nil, nil, nil, err
321322
}

internal/commands/cnab_test.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -218,7 +218,7 @@ func TestShareRegistryCreds(t *testing.T) {
218218
Credentials: map[string]bundle.Location{internal.CredentialRegistryName: {}},
219219
Images: c.images,
220220
},
221-
addNamedCredentialSets(nil),
221+
addNamedCredentialSets(nil, nil),
222222
addDockerCredentials("", nil),
223223
addRegistryCredentials(c.shareCreds, &registryConfigMock{configFile: &configfile.ConfigFile{
224224
AuthConfigs: c.stored,

internal/commands/install.go

Lines changed: 17 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,6 @@ import (
66
"github.com/deislabs/duffle/pkg/action"
77
"github.com/deislabs/duffle/pkg/claim"
88
"github.com/deislabs/duffle/pkg/credentials"
9-
"github.com/deislabs/duffle/pkg/utils/crud"
109
"github.com/docker/cli/cli"
1110
"github.com/docker/cli/cli/command"
1211
"github.com/spf13/cobra"
@@ -36,7 +35,7 @@ const longDescription = `Install the application on either Swarm or Kubernetes.
3635
Bundle name is optional, and can:
3736
- be empty and resolve to any *.dockerapp in working directory
3837
- be a BUNDLE file path and resolve to any *.dockerapp file or dir, or any CNAB file (signed or unsigned)
39-
- match a bundle name in the local duffle bundle repository
38+
- match a bundle name in the local bundle repository
4039
- refer to a CNAB in a container registry
4140
`
4241

@@ -67,27 +66,31 @@ func installCmd(dockerCli command.Cli) *cobra.Command {
6766
func runInstall(dockerCli command.Cli, appname string, opts installOptions) error {
6867
defer muteDockerCli(dockerCli)()
6968
opts.SetDefaultTargetContext(dockerCli)
69+
7070
bind, err := requiredBindMount(opts.targetContext, opts.orchestrator, dockerCli.ContextStore())
7171
if err != nil {
7272
return err
7373
}
74-
bndl, err := resolveBundle(dockerCli, appname, opts.pull, opts.insecureRegistries)
74+
bundleStore, installationStore, credentialStore, err := prepareStores(opts.targetContext)
75+
if err != nil {
76+
return err
77+
}
78+
79+
bndl, err := resolveBundle(dockerCli, bundleStore, appname, opts.pull, opts.insecureRegistries)
7580
if err != nil {
7681
return err
7782
}
7883
if err := bndl.Validate(); err != nil {
7984
return err
8085
}
81-
h := duffleHome()
82-
claimName := opts.stackName
83-
if claimName == "" {
84-
claimName = bndl.Name
86+
installationName := opts.stackName
87+
if installationName == "" {
88+
installationName = bndl.Name
8589
}
86-
claimStore := claim.NewClaimStore(crud.NewFileSystemStore(h.Claims(), "json"))
87-
if _, err = claimStore.Read(claimName); err == nil {
88-
return fmt.Errorf("installation %q already exists", claimName)
90+
if _, err = installationStore.Read(installationName); err == nil {
91+
return fmt.Errorf("installation %q already exists", installationName)
8992
}
90-
c, err := claim.New(claimName)
93+
c, err := claim.New(installationName)
9194
if err != nil {
9295
return err
9396
}
@@ -106,7 +109,7 @@ func runInstall(dockerCli command.Cli, appname string, opts installOptions) erro
106109
); err != nil {
107110
return err
108111
}
109-
creds, err := prepareCredentialSet(bndl, opts.CredentialSetOpts(dockerCli)...)
112+
creds, err := prepareCredentialSet(bndl, opts.CredentialSetOpts(dockerCli, credentialStore)...)
110113
if err != nil {
111114
return err
112115
}
@@ -118,9 +121,9 @@ func runInstall(dockerCli command.Cli, appname string, opts installOptions) erro
118121
Driver: driverImpl,
119122
}
120123
err = inst.Run(c, creds, dockerCli.Out())
121-
// Even if the installation failed, the claim is persisted with its failure status,
124+
// Even if the installation failed, the installation is persisted with its failure status,
122125
// so any installation needs a clean uninstallation.
123-
err2 := claimStore.Store(*c)
126+
err2 := installationStore.Store(*c)
124127
if err != nil {
125128
return fmt.Errorf("install failed: %s", errBuf)
126129
}

internal/commands/pull.go

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,9 +3,10 @@ package commands
33
import (
44
"fmt"
55

6-
bundlestore "github.com/docker/app/internal/store"
6+
"github.com/docker/app/internal/store"
77
"github.com/docker/cli/cli"
88
"github.com/docker/cli/cli/command"
9+
"github.com/docker/cli/cli/config"
910
"github.com/docker/distribution/reference"
1011
"github.com/pkg/errors"
1112
"github.com/spf13/cobra"
@@ -26,11 +27,20 @@ func pullCmd(dockerCli command.Cli) *cobra.Command {
2627
}
2728

2829
func runPull(dockerCli command.Cli, name string, opts registryOptions) error {
30+
appstore, err := store.NewApplicationStore(config.Dir())
31+
if err != nil {
32+
return err
33+
}
34+
bundleStore, err := appstore.BundleStore()
35+
if err != nil {
36+
return err
37+
}
38+
2939
ref, err := reference.ParseNormalizedNamed(name)
3040
if err != nil {
3141
return errors.Wrap(err, name)
3242
}
33-
bndl, err := bundlestore.LookupOrPullBundle(dockerCli, reference.TagNameOnly(ref), true, opts.insecureRegistries)
43+
bndl, err := bundleStore.LookupOrPullBundle(reference.TagNameOnly(ref), true, dockerCli.ConfigFile(), opts.insecureRegistries)
3444
if err != nil {
3545
return errors.Wrap(err, name)
3646
}

internal/commands/root.go

Lines changed: 25 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,9 @@ package commands
33
import (
44
"io/ioutil"
55

6+
"github.com/docker/app/internal/store"
67
"github.com/docker/cli/cli/command"
8+
"github.com/docker/cli/cli/config"
79
"github.com/spf13/cobra"
810
"github.com/spf13/pflag"
911
)
@@ -55,6 +57,26 @@ func muteDockerCli(dockerCli command.Cli) func() {
5557
}
5658
}
5759

60+
func prepareStores(targetContext string) (store.BundleStore, store.InstallationStore, store.CredentialStore, error) {
61+
appstore, err := store.NewApplicationStore(config.Dir())
62+
if err != nil {
63+
return nil, nil, nil, err
64+
}
65+
installationStore, err := appstore.InstallationStore(targetContext)
66+
if err != nil {
67+
return nil, nil, nil, err
68+
}
69+
bundleStore, err := appstore.BundleStore()
70+
if err != nil {
71+
return nil, nil, nil, err
72+
}
73+
credentialStore, err := appstore.CredentialStore(targetContext)
74+
if err != nil {
75+
return nil, nil, nil, err
76+
}
77+
return bundleStore, installationStore, credentialStore, nil
78+
}
79+
5880
type parametersOptions struct {
5981
parametersFiles []string
6082
overrides []string
@@ -73,17 +95,17 @@ type credentialOptions struct {
7395

7496
func (o *credentialOptions) addFlags(flags *pflag.FlagSet) {
7597
flags.StringVar(&o.targetContext, "target-context", "", "Context on which the application is executed")
76-
flags.StringArrayVarP(&o.credentialsets, "credential-set", "c", []string{}, "Use a duffle credentialset (either a YAML file, or a credential set present in the duffle credential store)")
98+
flags.StringArrayVarP(&o.credentialsets, "credential-set", "c", []string{}, "Use a credentialset (either a YAML file, or a credential set present in the credential store)")
7799
flags.BoolVar(&o.sendRegistryAuth, "with-registry-auth", false, "Sends registry auth")
78100
}
79101

80102
func (o *credentialOptions) SetDefaultTargetContext(dockerCli command.Cli) {
81103
o.targetContext = getTargetContext(o.targetContext, dockerCli.CurrentContext())
82104
}
83105

84-
func (o *credentialOptions) CredentialSetOpts(dockerCli command.Cli) []credentialSetOpt {
106+
func (o *credentialOptions) CredentialSetOpts(dockerCli command.Cli, credentialStore store.CredentialStore) []credentialSetOpt {
85107
return []credentialSetOpt{
86-
addNamedCredentialSets(o.credentialsets),
108+
addNamedCredentialSets(credentialStore, o.credentialsets),
87109
addDockerCredentials(o.targetContext, dockerCli.ContextStore()),
88110
addRegistryCredentials(o.sendRegistryAuth, dockerCli),
89111
}

internal/commands/status.go

Lines changed: 9 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -4,9 +4,7 @@ import (
44
"fmt"
55

66
"github.com/deislabs/duffle/pkg/action"
7-
"github.com/deislabs/duffle/pkg/claim"
87
"github.com/deislabs/duffle/pkg/credentials"
9-
"github.com/deislabs/duffle/pkg/utils/crud"
108
"github.com/docker/app/internal"
119
"github.com/docker/cli/cli"
1210
"github.com/docker/cli/cli/command"
@@ -29,16 +27,19 @@ func statusCmd(dockerCli command.Cli) *cobra.Command {
2927
return cmd
3028
}
3129

32-
func runStatus(dockerCli command.Cli, claimName string, opts credentialOptions) error {
30+
func runStatus(dockerCli command.Cli, installationName string, opts credentialOptions) error {
3331
defer muteDockerCli(dockerCli)()
34-
h := duffleHome()
32+
opts.SetDefaultTargetContext(dockerCli)
3533

36-
claimStore := claim.NewClaimStore(crud.NewFileSystemStore(h.Claims(), "json"))
37-
c, err := claimStore.Read(claimName)
34+
_, installationStore, credentialStore, err := prepareStores(opts.targetContext)
35+
if err != nil {
36+
return err
37+
}
38+
39+
c, err := installationStore.Read(installationName)
3840
if err != nil {
3941
return err
4042
}
41-
opts.SetDefaultTargetContext(dockerCli)
4243
bind, err := requiredClaimBindMount(c, opts.targetContext, dockerCli)
4344
if err != nil {
4445
return err
@@ -52,7 +53,7 @@ func runStatus(dockerCli command.Cli, claimName string, opts credentialOptions)
5253
); err != nil {
5354
return err
5455
}
55-
creds, err := prepareCredentialSet(c.Bundle, opts.CredentialSetOpts(dockerCli)...)
56+
creds, err := prepareCredentialSet(c.Bundle, opts.CredentialSetOpts(dockerCli, credentialStore)...)
5657
if err != nil {
5758
return err
5859
}

0 commit comments

Comments
 (0)