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

Commit 6475f73

Browse files
authored
Merge pull request #362 from vdemeester/358-fix-image-app-name
Fix the application name when extracting a docker image
2 parents 5ede3cc + e125bac commit 6475f73

2 files changed

Lines changed: 59 additions & 13 deletions

File tree

internal/packager/extract.go

Lines changed: 23 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ import (
1111
"github.com/docker/app/internal"
1212
"github.com/docker/app/loader"
1313
"github.com/docker/app/types"
14+
"github.com/docker/distribution/reference"
1415
"github.com/pkg/errors"
1516
)
1617

@@ -42,20 +43,29 @@ func findApp() (string, error) {
4243
return filepath.Join(cwd, hit), nil
4344
}
4445

46+
func appNameFromRef(ref reference.Named) string {
47+
parts := strings.Split(ref.Name(), "/")
48+
return internal.DirNameFromAppName(parts[len(parts)-1])
49+
}
50+
51+
func imageNameFromRef(ref reference.Named) string {
52+
if tagged, ok := ref.(reference.Tagged); ok {
53+
name := internal.DirNameFromAppName(ref.Name())
54+
newRef, _ := reference.WithName(name)
55+
newtaggedRef, _ := reference.WithTag(newRef, tagged.Tag())
56+
return newtaggedRef.String()
57+
}
58+
return internal.DirNameFromAppName(ref.String())
59+
}
60+
4561
// extractImage extracts a docker application in a docker image to a temporary directory
4662
func extractImage(appname string, ops ...func(*types.App) error) (*types.App, error) {
47-
var imagename string
48-
if strings.Contains(appname, ":") {
49-
nametag := strings.Split(appname, ":")
50-
if len(nametag) == 3 || strings.Contains(nametag[1], "/") {
51-
nametag[1] = internal.DirNameFromAppName(nametag[1])
52-
} else {
53-
nametag[0] = internal.DirNameFromAppName(nametag[0])
54-
}
55-
imagename = strings.Join(nametag, ":")
56-
} else {
57-
imagename = internal.DirNameFromAppName(appname)
63+
ref, err := reference.ParseNormalizedNamed(appname)
64+
if err != nil {
65+
return nil, err
5866
}
67+
imagename := imageNameFromRef(ref)
68+
appname = appNameFromRef(ref)
5969
tempDir, err := ioutil.TempDir("", "dockerapp")
6070
if err != nil {
6171
return nil, errors.Wrap(err, "failed to create temporary directory")
@@ -65,8 +75,8 @@ func extractImage(appname string, ops ...func(*types.App) error) (*types.App, er
6575
os.RemoveAll(tempDir)
6676
return nil, err
6777
}
68-
ops = append(ops, types.WithCleanup(func() { os.RemoveAll(tempDir) }))
69-
return Extract(path, ops...)
78+
ops = append(ops, types.WithName(appname), types.WithCleanup(func() { os.RemoveAll(tempDir) }))
79+
return loader.LoadFromDirectory(path, ops...)
7080
}
7181

7282
// Extract extracts the app content if argument is an archive, or does nothing if a dir.

internal/packager/extract_test.go

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
package packager
2+
3+
import (
4+
"testing"
5+
6+
"github.com/docker/distribution/reference"
7+
"gotest.tools/assert"
8+
is "gotest.tools/assert/cmp"
9+
)
10+
11+
func TestImageAppNameFromRef(t *testing.T) {
12+
refs := []struct {
13+
ref string
14+
appName string
15+
imageName string
16+
}{
17+
{ref: "foo", appName: "foo.dockerapp", imageName: "docker.io/library/foo.dockerapp"},
18+
{ref: "foo.dockerapp", appName: "foo.dockerapp", imageName: "docker.io/library/foo.dockerapp"},
19+
{ref: "foo:0.2.0", appName: "foo.dockerapp", imageName: "docker.io/library/foo.dockerapp:0.2.0"},
20+
{ref: "foo.dockerapp:0.2.0", appName: "foo.dockerapp", imageName: "docker.io/library/foo.dockerapp:0.2.0"},
21+
{ref: "namespace/foo", appName: "foo.dockerapp", imageName: "docker.io/namespace/foo.dockerapp"},
22+
{ref: "namespace/bar.dockerapp", appName: "bar.dockerapp", imageName: "docker.io/namespace/bar.dockerapp"},
23+
{ref: "namespace/bar:0.2.0", appName: "bar.dockerapp", imageName: "docker.io/namespace/bar.dockerapp:0.2.0"},
24+
{ref: "namespace/bar.dockerapp:0.2.0", appName: "bar.dockerapp", imageName: "docker.io/namespace/bar.dockerapp:0.2.0"},
25+
{ref: "gcr.io/namespace/baz", appName: "baz.dockerapp", imageName: "gcr.io/namespace/baz.dockerapp"},
26+
{ref: "gcr.io/namespace/baz.dockerapp", appName: "baz.dockerapp", imageName: "gcr.io/namespace/baz.dockerapp"},
27+
{ref: "gcr.io/namespace/baz:0.2.0", appName: "baz.dockerapp", imageName: "gcr.io/namespace/baz.dockerapp:0.2.0"},
28+
{ref: "gcr.io/namespace/baz.dockerapp:0.2.0", appName: "baz.dockerapp", imageName: "gcr.io/namespace/baz.dockerapp:0.2.0"},
29+
}
30+
for _, r := range refs {
31+
ref, err := reference.ParseNormalizedNamed(r.ref)
32+
assert.NilError(t, err)
33+
assert.Assert(t, is.Equal(imageNameFromRef(ref), r.imageName))
34+
assert.Assert(t, is.Equal(appNameFromRef(ref), r.appName))
35+
}
36+
}

0 commit comments

Comments
 (0)