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

Commit 5dff95d

Browse files
author
Matthieu Nottale
committed
Extract: Also look for a docker image.
Signed-off-by: Matthieu Nottale <[email protected]>
1 parent 87ce4e5 commit 5dff95d

File tree

4 files changed

+37
-6
lines changed

4 files changed

+37
-6
lines changed

cmd/load.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ var loadCmd = &cobra.Command{
1111
Short: "Load an application from a docker image",
1212
Args: cli.RequiresMaxArgs(1),
1313
RunE: func(cmd *cobra.Command, args []string) error {
14-
return packager.Load(firstOrEmpty(args))
14+
return packager.Load(firstOrEmpty(args), ".")
1515
},
1616
}
1717

packager/extract.go

Lines changed: 29 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -46,9 +46,35 @@ func findApp() (string, error) {
4646
return filepath.Join(cwd, hit), nil
4747
}
4848

49+
// extractImage extracts a docker application in a docker image to a temporary directory
50+
func extractImage(appname string) (string, func(), error) {
51+
var imagename string
52+
if strings.Contains(appname, ":") {
53+
nametag := strings.SplitN(appname, ":", 2)
54+
nametag[0] = utils.DirNameFromAppName(nametag[0])
55+
appname = filepath.Base(nametag[0])
56+
imagename = strings.Join(nametag, ":")
57+
} else {
58+
imagename = utils.DirNameFromAppName(appname)
59+
appname = filepath.Base(imagename)
60+
}
61+
tempDir, err := ioutil.TempDir("", "dockerapp")
62+
if err != nil {
63+
return "", noop, err
64+
}
65+
defer os.RemoveAll(tempDir)
66+
err = Load(imagename, tempDir)
67+
if err != nil {
68+
return "", noop, fmt.Errorf("could not locate application in either filesystem or docker image")
69+
}
70+
// this gave us a compressed app, run through extract again
71+
return Extract(filepath.Join(tempDir, appname))
72+
}
73+
4974
// Extract extracts the app content if argument is an archive, or does nothing if a dir.
5075
// It returns effective app name, and cleanup function
5176
// If appname is empty, it looks into cwd, and all subdirs for a single matching .dockerapp
77+
// If nothing is found, it looks for an image and loads it
5278
func Extract(appname string) (string, func(), error) {
5379
if appname == "" {
5480
var err error
@@ -62,6 +88,7 @@ func Extract(appname string) (string, func(), error) {
6288
return "", nil, errors.Wrap(err, "cannot resolve current working directory")
6389
}
6490
}
91+
originalAppname := appname
6592
// try verbatim first
6693
s, err := os.Stat(appname)
6794
if err != nil {
@@ -70,7 +97,8 @@ func Extract(appname string) (string, func(), error) {
7097
s, err = os.Stat(appname)
7198
}
7299
if err != nil {
73-
return "", noop, err
100+
// look for a docker image
101+
return extractImage(originalAppname)
74102
}
75103
if s.IsDir() {
76104
// directory: already decompressed

packager/registry.go

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -47,7 +47,7 @@ COPY / /
4747
}
4848

4949
// Load loads an app from docker
50-
func Load(repotag string) error {
50+
func Load(repotag string, outputDir string) error {
5151
file := filepath.Join(os.TempDir(), "docker-app-"+fmt.Sprintf("%v%v", rand.Int63(), rand.Int63()))
5252
cmd := exec.Command("docker", "save", "-o", file, repotag)
5353
output, err := cmd.CombinedOutput()
@@ -75,7 +75,7 @@ func Load(repotag string) error {
7575
return errors.Wrap(err, "error reading tar data")
7676
}
7777
repo := strings.Split(repotag, ":")[0]
78-
err = ioutil.WriteFile(appName(repo)+constants.AppExtension, data, 0644)
78+
err = ioutil.WriteFile(filepath.Join(outputDir, utils.DirNameFromAppName(filepath.Base(repo))), data, 0644)
7979
return errors.Wrap(err, "error writing output file")
8080
}
8181
}
@@ -108,5 +108,5 @@ func Pull(repotag string) error {
108108
if err != nil {
109109
return errors.Wrapf(err, "error from docker pull command: %s", string(output))
110110
}
111-
return Load(repotag)
111+
return Load(repotag, ".")
112112
}

utils/names.go

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,10 @@ func AppNameFromDir(dirName string) string {
2020
// DirNameFromAppName takes an application name and returns the
2121
// corresponding directory name
2222
func DirNameFromAppName(appName string) string {
23-
return fmt.Sprintf("%s%s", appName, constants.AppExtension)
23+
if strings.HasSuffix(appName, constants.AppExtension) {
24+
return appName
25+
}
26+
return appName + constants.AppExtension
2427
}
2528

2629
// ValidateAppName takes an app name and returns an error if it doesn't

0 commit comments

Comments
 (0)