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

Commit b621499

Browse files
authored
Merge pull request #753 from zappy-shu/APP-321-inspect-cnab-bundles
Image inspect non-app CNABs
2 parents 9249440 + 8908b28 commit b621499

14 files changed

+402
-67
lines changed

e2e/testdata/app-inspect.golden

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,16 @@
11
{
22
"Metadata": {
3-
"version": "1.1.0-beta1",
4-
"name": "simple",
5-
"description": "new fancy webapp with microservices",
6-
"maintainers": [
3+
"Version": "1.1.0-beta1",
4+
"Name": "simple",
5+
"Description": "new fancy webapp with microservices",
6+
"Maintainers": [
77
{
8-
"name": "John Developer",
9-
"email": "[email protected]"
8+
"Name": "John Developer",
9+
"Email": "[email protected]"
1010
},
1111
{
12-
"name": "Jane Developer",
13-
"email": "[email protected]"
12+
"Name": "Jane Developer",
13+
"Email": "[email protected]"
1414
}
1515
]
1616
},

internal/commands/image/inspect.go

Lines changed: 23 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ import (
1010
"github.com/deislabs/cnab-go/action"
1111
"github.com/docker/app/internal"
1212
"github.com/docker/app/internal/cnab"
13+
"github.com/docker/app/internal/inspect"
1314
appstore "github.com/docker/app/internal/store"
1415
"github.com/docker/cli/cli"
1516
"github.com/docker/cli/cli/command"
@@ -68,28 +69,35 @@ func runInspect(dockerCli command.Cli, appname string, opts inspectOptions) erro
6869
if err != nil {
6970
return err
7071
}
71-
installation, err := appstore.NewInstallation("custom-action", ref.String(), bndl)
72-
if err != nil {
73-
return err
74-
}
75-
driverImpl, errBuf, err := cnab.SetupDriver(installation, dockerCli, opts.InstallerContextOptions, os.Stdout)
76-
if err != nil {
77-
return err
78-
}
79-
a := &action.RunCustom{
80-
Action: internal.ActionInspectName,
81-
Driver: driverImpl,
82-
}
8372

8473
format := "json"
8574
if opts.pretty {
8675
format = "pretty"
8776
}
8877

89-
installation.SetParameter(internal.ParameterInspectFormatName, format)
78+
installation, err := appstore.NewInstallation("custom-action", ref.String(), bndl)
79+
if err != nil {
80+
return err
81+
}
82+
83+
if _, hasAction := installation.Bundle.Actions[internal.ActionInspectName]; hasAction {
84+
driverImpl, errBuf, err := cnab.SetupDriver(installation, dockerCli, opts.InstallerContextOptions, os.Stdout)
85+
if err != nil {
86+
return err
87+
}
88+
a := &action.RunCustom{
89+
Action: internal.ActionInspectName,
90+
Driver: driverImpl,
91+
}
9092

91-
if err := a.Run(&installation.Claim, nil); err != nil {
92-
return fmt.Errorf("inspect failed: %s\n%s", err, errBuf)
93+
installation.SetParameter(internal.ParameterInspectFormatName, format)
94+
if err = a.Run(&installation.Claim, nil); err != nil {
95+
return fmt.Errorf("inspect failed: %s\n%s", err, errBuf)
96+
}
97+
} else {
98+
if err = inspect.ImageInspectCNAB(os.Stdout, bndl.Bundle, format); err != nil {
99+
return fmt.Errorf("inspect failed: %s", err)
100+
}
93101
}
94102
return nil
95103
}

internal/commands/inspect.go

Lines changed: 2 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -105,10 +105,6 @@ func runInspect(dockerCli command.Cli, appName string, inspectOptions inspectOpt
105105
}
106106

107107
func hasAction(bndl *bundle.Bundle, actionName string) bool {
108-
for key := range bndl.Actions {
109-
if key == actionName {
110-
return true
111-
}
112-
}
113-
return false
108+
_, ok := bndl.Actions[actionName]
109+
return ok
114110
}

internal/inspect/inspect.go

Lines changed: 65 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -110,7 +110,54 @@ func ImageInspect(out io.Writer, app *types.App, argParameters map[string]string
110110
}
111111

112112
outputFormat := os.Getenv(internal.DockerInspectFormatEnvVar)
113-
return printImageAppInfo(out, appInfo, outputFormat)
113+
return printImageAppInfo(out, appInfo, outputFormat, true)
114+
}
115+
116+
func ImageInspectCNAB(out io.Writer, bndl *bundle.Bundle, outputFormat string) error {
117+
meta := metadata.AppMetadata{
118+
Description: bndl.Description,
119+
Name: bndl.Name,
120+
Version: bndl.Version,
121+
Maintainers: []metadata.Maintainer{},
122+
}
123+
for _, m := range bndl.Maintainers {
124+
meta.Maintainers = append(meta.Maintainers, metadata.Maintainer{
125+
Name: m.Name,
126+
Email: m.Email,
127+
})
128+
}
129+
130+
paramKeys := []string{}
131+
params := map[string]string{}
132+
for _, v := range bndl.Parameters {
133+
paramKeys = append(paramKeys, v.Definition)
134+
if d, ok := bndl.Definitions[v.Definition]; ok && d.Default != nil {
135+
params[v.Definition] = fmt.Sprint(d.Default)
136+
} else {
137+
params[v.Definition] = ""
138+
}
139+
}
140+
sort.Strings(paramKeys)
141+
142+
services := []Service{}
143+
for k, v := range bndl.Images {
144+
services = append(services, Service{
145+
Name: k,
146+
Image: v.Image,
147+
})
148+
}
149+
sort.SliceStable(services, func(i, j int) bool {
150+
return services[i].Name < services[j].Name
151+
})
152+
153+
appInfo := ImageAppInfo{
154+
Metadata: meta,
155+
parametersKeys: paramKeys,
156+
Parameters: params,
157+
Services: services,
158+
}
159+
160+
return printImageAppInfo(out, appInfo, outputFormat, false)
114161
}
115162

116163
func printAppInfo(out io.Writer, app AppInfo, format string) error {
@@ -124,10 +171,10 @@ func printAppInfo(out io.Writer, app AppInfo, format string) error {
124171
}
125172
}
126173

127-
func printImageAppInfo(out io.Writer, app ImageAppInfo, format string) error {
174+
func printImageAppInfo(out io.Writer, app ImageAppInfo, format string, isApp bool) error {
128175
switch format {
129176
case "pretty":
130-
return printTable(out, app)
177+
return printTable(out, app, isApp)
131178
case "json":
132179
return printJSON(out, app)
133180
default:
@@ -165,16 +212,24 @@ func printAppTable(out io.Writer, info AppInfo) error {
165212
return nil
166213
}
167214

168-
func printTable(out io.Writer, appInfo ImageAppInfo) error {
215+
func printTable(out io.Writer, appInfo ImageAppInfo, isApp bool) error {
169216
// Add Meta data
170217
printYAML(out, appInfo.Metadata)
171218

172219
// Add Service section
173-
printSection(out, len(appInfo.Services), func(w io.Writer) {
174-
for _, service := range appInfo.Services {
175-
fmt.Fprintf(w, "%s\t%d\t%s\t%s\n", service.Name, service.Replicas, service.Ports, service.Image)
176-
}
177-
}, "SERVICE", "REPLICAS", "PORTS", "IMAGE")
220+
if isApp {
221+
printSection(out, len(appInfo.Services), func(w io.Writer) {
222+
for _, service := range appInfo.Services {
223+
fmt.Fprintf(w, "%s\t%d\t%s\t%s\n", service.Name, service.Replicas, service.Ports, service.Image)
224+
}
225+
}, "SERVICE", "REPLICAS", "PORTS", "IMAGE")
226+
} else {
227+
printSection(out, len(appInfo.Services), func(w io.Writer) {
228+
for _, service := range appInfo.Services {
229+
fmt.Fprintf(w, "%s\t%s\n", service.Name, service.Image)
230+
}
231+
}, "SERVICE", "IMAGE")
232+
}
178233

179234
// Add Network section
180235
printSection(out, len(appInfo.Networks), func(w io.Writer) {
@@ -325,7 +380,7 @@ func extractParameters(app *types.App, argParameters map[string]string) ([]strin
325380
for k := range allParameters {
326381
parametersKeys = append(parametersKeys, k)
327382
}
328-
sort.Slice(parametersKeys, func(i, j int) bool { return parametersKeys[i] < parametersKeys[j] })
383+
sort.Strings(parametersKeys)
329384
return parametersKeys, allParameters, nil
330385
}
331386

internal/inspect/inspect_test.go

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ package inspect
22

33
import (
44
"bytes"
5+
"encoding/json"
56
"fmt"
67
"os"
78
"testing"
@@ -132,6 +133,30 @@ text: hello`),
132133
})
133134
}
134135

136+
func TestImageInspectCNABFormatJSON(t *testing.T) {
137+
testImageInspectCNAB(t, "json")
138+
}
139+
140+
func TestImageInspectCNABFormatPretty(t *testing.T) {
141+
testImageInspectCNAB(t, "pretty")
142+
}
143+
144+
func testImageInspectCNAB(t *testing.T, format string) {
145+
s := golden.Get(t, "bundle-json.golden")
146+
var bndl bundle.Bundle
147+
err := json.Unmarshal(s, &bndl)
148+
assert.NilError(t, err)
149+
150+
expected := golden.Get(t, fmt.Sprintf("inspect-bundle-%s.golden", format))
151+
152+
outBuffer := new(bytes.Buffer)
153+
err = ImageInspectCNAB(outBuffer, &bndl, format)
154+
assert.NilError(t, err)
155+
156+
result := outBuffer.String()
157+
assert.Equal(t, string(expected), result)
158+
}
159+
135160
func testImageInspect(t *testing.T, dir *fs.Dir, testcase inspectTestCase, suffix string) {
136161
app, err := types.NewAppFromDefaultFiles(dir.Join(testcase.name))
137162
assert.NilError(t, err)

0 commit comments

Comments
 (0)