Browse code

Buildfile: for ADD command, determine filename from URL.

This is used if the destination is a directory. This makes the URL
download behavior more closely match file copying.

Fixes #1142.

Caleb Spare authored on 2013/07/08 16:43:22
Showing 2 changed files
... ...
@@ -7,6 +7,7 @@ import (
7 7
 	"github.com/dotcloud/docker/utils"
8 8
 	"io"
9 9
 	"io/ioutil"
10
+	"net/url"
10 11
 	"os"
11 12
 	"path"
12 13
 	"reflect"
... ...
@@ -201,6 +202,24 @@ func (b *buildFile) addRemote(container *Container, orig, dest string) error {
201 201
 	}
202 202
 	defer file.Body.Close()
203 203
 
204
+	// If the destination is a directory, figure out the filename.
205
+	if strings.HasSuffix(dest, "/") {
206
+		u, err := url.Parse(orig)
207
+		if err != nil {
208
+			return err
209
+		}
210
+		path := u.Path
211
+		if strings.HasSuffix(path, "/") {
212
+			path = path[:len(path)-1]
213
+		}
214
+		parts := strings.Split(path, "/")
215
+		filename := parts[len(parts)-1]
216
+		if filename == "" {
217
+			return fmt.Errorf("cannot determine filename from url: %s", u)
218
+		}
219
+		dest = dest + filename
220
+	}
221
+
204 222
 	return container.Inject(file.Body, dest)
205 223
 }
206 224
 
... ...
@@ -208,7 +227,7 @@ func (b *buildFile) addContext(container *Container, orig, dest string) error {
208 208
 	origPath := path.Join(b.context, orig)
209 209
 	destPath := path.Join(container.RootfsPath(), dest)
210 210
 	// Preserve the trailing '/'
211
-	if dest[len(dest)-1] == '/' {
211
+	if strings.HasSuffix(dest, "/") {
212 212
 		destPath = destPath + "/"
213 213
 	}
214 214
 	fi, err := os.Stat(origPath)
... ...
@@ -86,6 +86,22 @@ run [ "$(cat /somewheeeere/over/the/rainbooow/ga)" = "bu" ]
86 86
 
87 87
 	{
88 88
 		`
89
+from {IMAGE}
90
+add http://{SERVERADDR}/x /a/b/c
91
+run [ "$(cat /a/b/c)" = "hello" ]
92
+add http://{SERVERADDR}/x?foo=bar /
93
+run [ "$(cat /x)" = "hello" ]
94
+add http://{SERVERADDR}/x /d/
95
+run [ "$(cat /d/x)" = "hello" ]
96
+add http://{SERVERADDR} /e
97
+run [ "$(cat /e)" = "blah" ]
98
+`,
99
+		nil,
100
+		[][2]string{{"/x", "hello"}, {"/", "blah"}},
101
+	},
102
+
103
+	{
104
+		`
89 105
 from   {IMAGE}
90 106
 env    FOO BAR
91 107
 run    [ "$FOO" = "BAR" ]