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

Commit 9c72172

Browse files
authored
Merge pull request #452 from rumpl/feat-cnab-inspect
Feat cnab inspect
2 parents d5784ea + 6e572fc commit 9c72172

File tree

11 files changed

+80
-128
lines changed

11 files changed

+80
-128
lines changed

Jenkinsfile.baguette

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -148,7 +148,7 @@ pipeline {
148148
dir('e2e'){
149149
unstash "e2e"
150150
}
151-
sh './docker-app-e2e-linux --e2e-path=e2e'
151+
sh './docker-app-e2e-linux -test.v --e2e-path=e2e'
152152
}
153153
}
154154
post {
@@ -180,7 +180,7 @@ pipeline {
180180
dir('e2e'){
181181
unstash "e2e"
182182
}
183-
sh './docker-app-e2e-darwin --e2e-path=e2e'
183+
sh './docker-app-e2e-darwin -test.v --e2e-path=e2e'
184184
}
185185
}
186186
post {
@@ -212,7 +212,7 @@ pipeline {
212212
dir('e2e'){
213213
unstash "e2e"
214214
}
215-
bat 'docker-app-e2e-windows.exe --e2e-path=e2e'
215+
bat 'docker-app-e2e-windows.exe -test.v --e2e-path=e2e'
216216
}
217217
}
218218
post {

cmd/cnab-run/inspect.go

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
package main
2+
3+
import (
4+
"os"
5+
6+
appinspect "github.com/docker/app/internal/inspect"
7+
"github.com/docker/app/internal/packager"
8+
)
9+
10+
func inspect() error {
11+
app, err := packager.Extract("")
12+
// todo: merge additional compose file
13+
if err != nil {
14+
return err
15+
}
16+
defer app.Cleanup()
17+
18+
imageMap, err := getBundleImageMap()
19+
if err != nil {
20+
return err
21+
}
22+
23+
parameters := packager.ExtractCNABParametersValues(packager.ExtractCNABParameterMapping(app.Parameters()), os.Environ())
24+
return appinspect.Inspect(os.Stdout, app, parameters, imageMap)
25+
}

cmd/cnab-run/main.go

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ const (
1313
cnabActionUninstall = cnabAction("uninstall")
1414
cnabActionUpgrade = cnabAction("upgrade")
1515
cnabActionStatus = cnabAction("status")
16+
cnabActionInspect = cnabAction("inspect")
1617
)
1718

1819
type cnabOperation struct {
@@ -68,6 +69,11 @@ func main() {
6869
fmt.Fprintf(os.Stderr, "Status failed: %s", err)
6970
os.Exit(1)
7071
}
72+
case cnabActionInspect:
73+
if err := inspect(); err != nil {
74+
fmt.Fprintf(os.Stderr, "Inspect failed: %s", err)
75+
os.Exit(1)
76+
}
7177
default:
7278
fmt.Fprintf(os.Stderr, "Action %q is not supported", op.action)
7379
os.Exit(1)

cmd/docker-app/inspect.go

Lines changed: 33 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -1,38 +1,55 @@
11
package main
22

33
import (
4-
"github.com/docker/app/internal/inspect"
5-
"github.com/docker/app/internal/packager"
6-
"github.com/docker/app/types"
4+
"github.com/deislabs/duffle/pkg/action"
5+
"github.com/deislabs/duffle/pkg/claim"
76
"github.com/docker/cli/cli"
87
"github.com/docker/cli/cli/command"
9-
cliopts "github.com/docker/cli/opts"
8+
"github.com/pkg/errors"
109
"github.com/spf13/cobra"
1110
)
1211

13-
var (
14-
inspectParametersFile []string
15-
inspectEnv []string
16-
)
17-
1812
func inspectCmd(dockerCli command.Cli) *cobra.Command {
13+
var opts parametersOptions
1914
cmd := &cobra.Command{
2015
Use: "inspect [<app-name>] [-s key=value...] [-f parameters-file...]",
2116
Short: "Shows metadata, parameters and a summary of the compose file for a given application",
2217
Args: cli.RequiresMaxArgs(1),
2318
RunE: func(cmd *cobra.Command, args []string) error {
24-
app, err := packager.Extract(firstOrEmpty(args),
25-
types.WithParametersFiles(inspectParametersFile...),
19+
muteDockerCli(dockerCli)
20+
appname := firstOrEmpty(args)
21+
22+
c, err := claim.New("inspect")
23+
if err != nil {
24+
return err
25+
}
26+
driverImpl, err := prepareDriver(dockerCli)
27+
if err != nil {
28+
return err
29+
}
30+
bundle, err := resolveBundle(dockerCli, "", appname)
31+
if err != nil {
32+
return err
33+
}
34+
c.Bundle = bundle
35+
36+
parameters, err := mergeBundleParameters(c.Bundle,
37+
withFileParameters(opts.parametersFiles),
38+
withCommandLineParameters(opts.overrides),
2639
)
2740
if err != nil {
2841
return err
2942
}
30-
defer app.Cleanup()
31-
argParameters := cliopts.ConvertKVStringsToMap(inspectEnv)
32-
return inspect.Inspect(dockerCli.Out(), app, argParameters, nil)
43+
c.Parameters = parameters
44+
45+
a := &action.RunCustom{
46+
Action: "inspect",
47+
Driver: driverImpl,
48+
}
49+
err = a.Run(c, map[string]string{"docker.context": ""}, dockerCli.Out())
50+
return errors.Wrap(err, "Inspect failed")
3351
},
3452
}
35-
cmd.Flags().StringArrayVarP(&inspectParametersFile, "parameters-files", "f", []string{}, "Override with parameters from files")
36-
cmd.Flags().StringArrayVarP(&inspectEnv, "set", "s", []string{}, "Override parameters values")
53+
opts.addFlags(cmd.Flags())
3754
return cmd
3855
}

cmd/docker-app/merge.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,7 @@ func extraFiles(appname string) ([]string, error) {
4242

4343
//handleInPlace returns the operation target path and if it's in-place
4444
func handleInPlace(app *types.App) (string, bool) {
45-
if app.Source == types.AppSourceURL || app.Source == types.AppSourceImage {
45+
if app.Source == types.AppSourceImage {
4646
return internal.DirNameFromAppName(app.Name), false
4747
}
4848
return app.Path + ".tmp", true

cmd/docker-app/parameters_test.go

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -12,8 +12,7 @@ import (
1212
func TestWithLoadFiles(t *testing.T) {
1313
tmpDir := fs.NewDir(t,
1414
t.Name(),
15-
fs.WithFile("params.yaml", `
16-
param1:
15+
fs.WithFile("params.yaml", `param1:
1716
param2: value1
1817
param3: 3
1918
overridden: bar`))

e2e/commands_test.go

Lines changed: 5 additions & 76 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,6 @@ import (
66
"os"
77
"path/filepath"
88
"regexp"
9-
"runtime"
109
"strings"
1110
"testing"
1211

@@ -20,20 +19,6 @@ import (
2019
"gotest.tools/skip"
2120
)
2221

23-
const (
24-
singleFileApp = `version: 0.1.0
25-
name: helloworld
26-
description: "hello world app"
27-
namespace: "foo"
28-
---
29-
version: '3.5'
30-
services:
31-
hello-world:
32-
image: hello-world
33-
---
34-
# This section contains the default values for your application parameters.`
35-
)
36-
3722
func TestRenderTemplates(t *testing.T) {
3823
skip.If(t, !hasExperimental, "experimental mode needed for this test")
3924
appsPath := filepath.Join("testdata", "templates")
@@ -226,56 +211,6 @@ func TestSplitMerge(t *testing.T) {
226211
icmd.RunCmd(cmd).Assert(t, icmd.Success)
227212
}
228213

229-
func TestURL(t *testing.T) {
230-
url := "https://raw.githubusercontent.com/docker/app/v0.4.1/examples/hello-world/hello-world.dockerapp"
231-
result := icmd.RunCommand(dockerApp, "inspect", url).Assert(t, icmd.Success)
232-
golden.Assert(t, result.Combined(), "helloworld-inspect.golden")
233-
}
234-
235-
func TestWithRegistry(t *testing.T) {
236-
r := startRegistry(t)
237-
defer r.Stop(t)
238-
registry := r.GetAddress(t)
239-
// push to a registry
240-
icmd.RunCommand(dockerApp, "push", "--namespace", registry+"/myuser", "testdata/render/envvariables/my.dockerapp").Assert(t, icmd.Success)
241-
icmd.RunCommand(dockerApp, "push", "--namespace", registry+"/myuser", "-t", "latest", "testdata/render/envvariables/my.dockerapp").Assert(t, icmd.Success)
242-
icmd.RunCommand(dockerApp, "inspect", registry+"/myuser/my.dockerapp:0.1.0").Assert(t, icmd.Success)
243-
icmd.RunCommand(dockerApp, "inspect", registry+"/myuser/my.dockerapp").Assert(t, icmd.Success)
244-
icmd.RunCommand(dockerApp, "inspect", registry+"/myuser/my").Assert(t, icmd.Success)
245-
icmd.RunCommand(dockerApp, "inspect", registry+"/myuser/my:0.1.0").Assert(t, icmd.Success)
246-
// push a single-file app to a registry
247-
dir := fs.NewDir(t, "save-prepare-build", fs.WithFile("my.dockerapp", singleFileApp))
248-
defer dir.Remove()
249-
icmd.RunCommand(dockerApp, "push", "--namespace", registry+"/myuser", dir.Join("my.dockerapp")).Assert(t, icmd.Success)
250-
251-
// push with custom repo name
252-
icmd.RunCommand(dockerApp, "push", "-t", "marshmallows", "--namespace", registry+"/rainbows", "--repo", "unicorns", "testdata/render/envvariables/my.dockerapp").Assert(t, icmd.Success)
253-
icmd.RunCommand(dockerApp, "inspect", registry+"/rainbows/unicorns:marshmallows").Assert(t, icmd.Success)
254-
}
255-
256-
func TestAttachmentsWithRegistry(t *testing.T) {
257-
r := startRegistry(t)
258-
defer r.Stop(t)
259-
registry := r.GetAddress(t)
260-
261-
dir := fs.NewDir(t, "testattachments",
262-
fs.WithDir("attachments.dockerapp", fs.FromDir("testdata/attachments.dockerapp")),
263-
)
264-
defer dir.Remove()
265-
266-
icmd.RunCommand(dockerApp, "push", "--namespace", registry+"/acmecorp", dir.Join("attachments.dockerapp")).Assert(t, icmd.Success)
267-
268-
// inspect will run the core pull code too
269-
result := icmd.RunCommand(dockerApp, "inspect", registry+"/acmecorp/attachments.dockerapp:0.1.0")
270-
271-
result.Assert(t, icmd.Success)
272-
resultOutput := result.Combined()
273-
274-
assert.Assert(t, strings.Contains(resultOutput, "config.cfg"))
275-
assert.Assert(t, strings.Contains(resultOutput, "nesteddir/config2.cfg"))
276-
assert.Assert(t, strings.Contains(resultOutput, "nesteddir/nested2/nested3/config3.cfg"))
277-
}
278-
279214
func TestBundle(t *testing.T) {
280215
tmpDir := fs.NewDir(t, t.Name())
281216
defer tmpDir.Remove()
@@ -312,9 +247,11 @@ func TestBundle(t *testing.T) {
312247

313248
// Copy all the files from the invocation image and check them
314249
cmd.Command = []string{dockerCli, "create", "--name", "invocation", "acmecorp/simple:1.1.0-beta1-invoc"}
315-
icmd.RunCmd(cmd).Assert(t, icmd.Success)
250+
id := strings.TrimSpace(icmd.RunCmd(cmd).Assert(t, icmd.Success).Stdout())
316251
cmd.Command = []string{dockerCli, "cp", "invocation:/cnab/app/simple.dockerapp", tmpDir.Join("simple.dockerapp")}
317252
icmd.RunCmd(cmd).Assert(t, icmd.Success)
253+
cmd.Command = []string{dockerCli, "rm", "--force", id}
254+
icmd.RunCmd(cmd).Assert(t, icmd.Success)
318255

319256
appDir := filepath.Join("testdata", "simple", "simple.dockerapp")
320257
manifest := fs.Expected(
@@ -333,19 +270,11 @@ func TestDockerAppLifecycle(t *testing.T) {
333270
defer tmpDir.Remove()
334271

335272
cmd := icmd.Cmd{
336-
Env: []string{
273+
Env: append(os.Environ(),
337274
fmt.Sprintf("DUFFLE_HOME=%s", tmpDir.Path()),
338275
fmt.Sprintf("DOCKER_CONFIG=%s", tmpDir.Path()),
339276
"DOCKER_TARGET_CONTEXT=swarm-target-context",
340-
},
341-
}
342-
343-
// We need to explicitly set the SYSTEMROOT on windows
344-
// otherwise we get the error:
345-
// "panic: failed to read random bytes: CryptAcquireContext: Provider DLL failed to initialize correctly."
346-
// See: https://github.com/golang/go/issues/25210
347-
if runtime.GOOS == "windows" {
348-
cmd.Env = append(cmd.Env, `SYSTEMROOT=C:\WINDOWS`)
277+
),
349278
}
350279

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

e2e/helper_test.go

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -8,11 +8,12 @@ import (
88
"gotest.tools/assert"
99
)
1010

11-
func startRegistry(t *testing.T) *Container {
12-
c := &Container{image: "registry:2", privatePort: 5000}
13-
c.Start(t)
14-
return c
15-
}
11+
// TODO: uncomment once we pull on `resolveBundle`
12+
// func startRegistry(t *testing.T) *Container {
13+
// c := &Container{image: "registry:2", privatePort: 5000}
14+
// c.Start(t)
15+
// return c
16+
// }
1617

1718
// readFile returns the content of the file at the designated path normalizing
1819
// line endings by removing any \r.

internal/packager/extract.go

Lines changed: 0 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,6 @@ package packager
33
import (
44
"fmt"
55
"io/ioutil"
6-
"net/url"
76
"os"
87
"path/filepath"
98
"strings"
@@ -110,12 +109,6 @@ func Extract(name string, ops ...func(*types.App) error) (*types.App, error) {
110109
appname := internal.DirNameFromAppName(name)
111110
s, err := os.Stat(appname)
112111
if err != nil {
113-
// URL or docker image
114-
u, err := url.Parse(name)
115-
if err == nil && (u.Scheme == "http" || u.Scheme == "https") {
116-
ops = append(ops, types.WithSource(types.AppSourceURL))
117-
return loader.LoadFromURL(name, ops...)
118-
}
119112
// look for a docker image
120113
ops = append(ops, types.WithSource(types.AppSourceImage))
121114
app, err := extractImage(name, ops...)

loader/loader.go

Lines changed: 0 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,6 @@ package loader
33
import (
44
"io"
55
"io/ioutil"
6-
"net/http"
76
"os"
87
"path/filepath"
98
"strings"
@@ -14,21 +13,6 @@ import (
1413
"github.com/pkg/errors"
1514
)
1615

17-
// LoadFromURL loads a docker app from an URL that should return a single-file app.
18-
func LoadFromURL(url string, ops ...func(*types.App) error) (*types.App, error) {
19-
resp, err := http.Get(url)
20-
if err != nil {
21-
return nil, errors.Wrap(err, "failed to download "+url)
22-
}
23-
if resp.Body != nil {
24-
defer resp.Body.Close()
25-
}
26-
if resp.StatusCode != 200 {
27-
return nil, errors.Errorf("failed to download %s: %s", url, resp.Status)
28-
}
29-
return LoadFromSingleFile(url, resp.Body, ops...)
30-
}
31-
3216
// LoadFromSingleFile loads a docker app from a single-file format (as a reader)
3317
func LoadFromSingleFile(path string, r io.Reader, ops ...func(*types.App) error) (*types.App, error) {
3418
data, err := ioutil.ReadAll(r)

0 commit comments

Comments
 (0)