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

Commit 5bdaed5

Browse files
Add List command to list all the installations, and their result, made from the host.
Signed-off-by: Silvin Lubecki <[email protected]>
1 parent 7d43c90 commit 5bdaed5

File tree

6 files changed

+109
-1
lines changed

6 files changed

+109
-1
lines changed

README.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -351,6 +351,7 @@ Commands:
351351
init Initialize Docker Application definition
352352
inspect Shows metadata, parameters and a summary of the Compose file for a given application
353353
install Install an application
354+
list List the installations and their last known installation result
354355
merge Merge a directory format Docker Application definition into a single file
355356
pull Pull an application package from a registry
356357
push Push an application package to a registry

e2e/commands_test.go

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -350,6 +350,14 @@ func testDockerAppLifecycle(t *testing.T, useBindMount bool) {
350350
fmt.Sprintf("[[:alnum:]]+ %s_api replicated [0-1]/1 python:3.6", appName),
351351
})
352352

353+
// List the installed applications
354+
cmd.Command = dockerCli.Command("app", "list")
355+
checkContains(t, icmd.RunCmd(cmd).Assert(t, icmd.Success).Combined(),
356+
[]string{
357+
`INSTALLATION\s+LAST ACTION\s+RESULT\s+CREATED\s+MODIFIED`,
358+
fmt.Sprintf(`%s\s+install\s+success\s+[[:alnum:]]+\ssecond.\s+[[:alnum:]]+\ssecond`, appName),
359+
})
360+
353361
// Installing again the same application is forbidden
354362
cmd.Command = dockerCli.Command("app", "install", "testdata/simple/simple.dockerapp", "--name", appName)
355363
icmd.RunCmd(cmd).Assert(t, icmd.Expected{
@@ -420,6 +428,6 @@ func initializeDockerAppEnvironment(t *testing.T, cmd *icmd.Cmd, tmpDir *fs.Dir,
420428
func checkContains(t *testing.T, combined string, expectedLines []string) {
421429
for _, expected := range expectedLines {
422430
exp := regexp.MustCompile(expected)
423-
assert.Assert(t, exp.MatchString(combined), expected, combined)
431+
assert.Assert(t, exp.MatchString(combined), "expected %q != actual %q", expected, combined)
424432
}
425433
}

e2e/testdata/plugin-usage-experimental.golden

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ Commands:
99
init Initialize Docker Application definition
1010
inspect Shows metadata, parameters and a summary of the Compose file for a given application
1111
install Install an application
12+
list List the installations and their last known installation result
1213
merge Merge a directory format Docker Application definition into a single file
1314
pull Pull an application package from a registry
1415
push Push an application package to a registry

e2e/testdata/plugin-usage.golden

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ Commands:
99
init Initialize Docker Application definition
1010
inspect Shows metadata, parameters and a summary of the Compose file for a given application
1111
install Install an application
12+
list List the installations and their last known installation result
1213
merge Merge a directory format Docker Application definition into a single file
1314
pull Pull an application package from a registry
1415
push Push an application package to a registry

internal/commands/list.go

Lines changed: 96 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,96 @@
1+
package commands
2+
3+
import (
4+
"fmt"
5+
"io"
6+
"strings"
7+
"text/tabwriter"
8+
"time"
9+
10+
"github.com/deislabs/duffle/pkg/claim"
11+
12+
"github.com/docker/app/internal/store"
13+
"github.com/docker/cli/cli"
14+
"github.com/docker/cli/cli/command"
15+
"github.com/docker/cli/cli/config"
16+
units "github.com/docker/go-units"
17+
"github.com/spf13/cobra"
18+
)
19+
20+
type listOptions struct {
21+
targetContext string
22+
}
23+
24+
var (
25+
listColumns = []struct {
26+
header string
27+
value func(c *claim.Claim) string
28+
}{
29+
{"INSTALLATION", func(c *claim.Claim) string { return c.Name }},
30+
{"LAST ACTION", func(c *claim.Claim) string { return c.Result.Action }},
31+
{"RESULT", func(c *claim.Claim) string { return c.Result.Status }},
32+
{"CREATED", func(c *claim.Claim) string { return units.HumanDuration(time.Since(c.Created)) }},
33+
{"MODIFIED", func(c *claim.Claim) string { return units.HumanDuration(time.Since(c.Modified)) }}}
34+
)
35+
36+
func listCmd(dockerCli command.Cli) *cobra.Command {
37+
var opts listOptions
38+
39+
cmd := &cobra.Command{
40+
Use: "list [OPTIONS]",
41+
Short: "List the installations and their last known installation result",
42+
Aliases: []string{"ls"},
43+
Args: cli.NoArgs,
44+
RunE: func(cmd *cobra.Command, args []string) error {
45+
return runList(dockerCli, opts)
46+
},
47+
}
48+
cmd.Flags().StringVar(&opts.targetContext, "target-context", "", "List installations on this context")
49+
50+
return cmd
51+
}
52+
53+
func runList(dockerCli command.Cli, opts listOptions) error {
54+
targetContext := getTargetContext(opts.targetContext, dockerCli.CurrentContext())
55+
56+
appstore, err := store.NewApplicationStore(config.Dir())
57+
if err != nil {
58+
return err
59+
}
60+
installationStore, err := appstore.InstallationStore(targetContext)
61+
if err != nil {
62+
return err
63+
}
64+
65+
installations, err := installationStore.List()
66+
if err != nil {
67+
return err
68+
}
69+
w := tabwriter.NewWriter(dockerCli.Out(), 0, 0, 1, ' ', 0)
70+
printHeaders(w)
71+
72+
for _, c := range installations {
73+
installation, err := installationStore.Read(c)
74+
if err != nil {
75+
return err
76+
}
77+
printValues(w, &installation)
78+
}
79+
return w.Flush()
80+
}
81+
82+
func printHeaders(w io.Writer) {
83+
var headers []string
84+
for _, column := range listColumns {
85+
headers = append(headers, column.header)
86+
}
87+
fmt.Fprintln(w, strings.Join(headers, "\t"))
88+
}
89+
90+
func printValues(w io.Writer, installation *claim.Claim) {
91+
var values []string
92+
for _, column := range listColumns {
93+
values = append(values, column.value(installation))
94+
}
95+
fmt.Fprintln(w, strings.Join(values, "\t"))
96+
}

internal/commands/root.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@ func addCommands(cmd *cobra.Command, dockerCli command.Cli) {
2626
installCmd(dockerCli),
2727
upgradeCmd(dockerCli),
2828
uninstallCmd(dockerCli),
29+
listCmd(dockerCli),
2930
statusCmd(dockerCli),
3031
initCmd(dockerCli),
3132
inspectCmd(dockerCli),

0 commit comments

Comments
 (0)