Browse code

Merge -b and -v options

Guillaume J. Charmes authored on 2013/07/16 09:18:11
Showing 4 changed files
... ...
@@ -1249,10 +1249,22 @@ func (opts PathOpts) String() string {
1249 1249
 }
1250 1250
 
1251 1251
 func (opts PathOpts) Set(val string) error {
1252
-	if !filepath.IsAbs(val) {
1253
-		return fmt.Errorf("%s is not an absolute path", val)
1252
+	var containerPath string
1253
+
1254
+	splited := strings.SplitN(val, ":", 2)
1255
+	if len(splited) == 1 {
1256
+		containerPath = splited[0]
1257
+		val = filepath.Clean(splited[0])
1258
+	} else {
1259
+		containerPath = splited[1]
1260
+		val = fmt.Sprintf("%s:%s", splited[0], filepath.Clean(splited[1]))
1261
+	}
1262
+
1263
+	if !filepath.IsAbs(containerPath) {
1264
+		utils.Debugf("%s is not an absolute path", containerPath)
1265
+		return fmt.Errorf("%s is not an absolute path", containerPath)
1254 1266
 	}
1255
-	opts[filepath.Clean(val)] = struct{}{}
1267
+	opts[val] = struct{}{}
1256 1268
 	return nil
1257 1269
 }
1258 1270
 
... ...
@@ -121,14 +121,11 @@ func ParseRun(args []string, capabilities *Capabilities) (*Config, *HostConfig,
121 121
 	cmd.Var(&flDns, "dns", "Set custom dns servers")
122 122
 
123 123
 	flVolumes := NewPathOpts()
124
-	cmd.Var(flVolumes, "v", "Attach a data volume")
124
+	cmd.Var(flVolumes, "v", "Bind mount a volume (e.g. from the host: -v /host:/container, from docker: -v /container)")
125 125
 
126 126
 	flVolumesFrom := cmd.String("volumes-from", "", "Mount volumes from the specified container")
127 127
 	flEntrypoint := cmd.String("entrypoint", "", "Overwrite the default entrypoint of the image")
128 128
 
129
-	var flBinds ListOpts
130
-	cmd.Var(&flBinds, "b", "Bind mount a volume from the host (e.g. -b /host:/container)")
131
-
132 129
 	if err := cmd.Parse(args); err != nil {
133 130
 		return nil, nil, cmd, err
134 131
 	}
... ...
@@ -146,11 +143,17 @@ func ParseRun(args []string, capabilities *Capabilities) (*Config, *HostConfig,
146 146
 		}
147 147
 	}
148 148
 
149
+	var binds []string
150
+
149 151
 	// add any bind targets to the list of container volumes
150
-	for _, bind := range flBinds {
152
+	for bind := range flVolumes {
151 153
 		arr := strings.Split(bind, ":")
152
-		dstDir := arr[1]
153
-		flVolumes[dstDir] = struct{}{}
154
+		if len(arr) > 1 {
155
+			dstDir := arr[1]
156
+			flVolumes[dstDir] = struct{}{}
157
+			binds = append(binds, bind)
158
+			delete(flVolumes, bind)
159
+		}
154 160
 	}
155 161
 
156 162
 	parsedArgs := cmd.Args()
... ...
@@ -187,7 +190,7 @@ func ParseRun(args []string, capabilities *Capabilities) (*Config, *HostConfig,
187 187
 		Entrypoint:   entrypoint,
188 188
 	}
189 189
 	hostConfig := &HostConfig{
190
-		Binds: flBinds,
190
+		Binds: binds,
191 191
 	}
192 192
 
193 193
 	if capabilities != nil && *flMemory > 0 && !capabilities.SwapLimit {
... ...
@@ -493,6 +496,7 @@ func (container *Container) Attach(stdin io.ReadCloser, stdinCloser io.Closer, s
493 493
 func (container *Container) Start(hostConfig *HostConfig) error {
494 494
 	container.State.Lock()
495 495
 	defer container.State.Unlock()
496
+
496 497
 	if len(hostConfig.Binds) == 0 {
497 498
 		hostConfig, _ = container.ReadHostConfig()
498 499
 	}
... ...
@@ -1231,19 +1231,18 @@ func TestBindMounts(t *testing.T) {
1231 1231
 	writeFile(path.Join(tmpDir, "touch-me"), "", t)
1232 1232
 
1233 1233
 	// Test reading from a read-only bind mount
1234
-	stdout, _ := runContainer(r, []string{"-b", fmt.Sprintf("%s:/tmp:ro", tmpDir), "_", "ls", "/tmp"}, t)
1234
+	stdout, _ := runContainer(r, []string{"-v", fmt.Sprintf("%s:/tmp:ro", tmpDir), "_", "ls", "/tmp"}, t)
1235 1235
 	if !strings.Contains(stdout, "touch-me") {
1236 1236
 		t.Fatal("Container failed to read from bind mount")
1237 1237
 	}
1238 1238
 
1239 1239
 	// test writing to bind mount
1240
-	runContainer(r, []string{"-b", fmt.Sprintf("%s:/tmp:rw", tmpDir), "_", "touch", "/tmp/holla"}, t)
1240
+	runContainer(r, []string{"-v", fmt.Sprintf("%s:/tmp:rw", tmpDir), "_", "touch", "/tmp/holla"}, t)
1241 1241
 	readFile(path.Join(tmpDir, "holla"), t) // Will fail if the file doesn't exist
1242 1242
 
1243 1243
 	// test mounting to an illegal destination directory
1244
-	if _, err := runContainer(r, []string{"-b", fmt.Sprintf("%s:.", tmpDir), "ls", "."}, nil); err == nil {
1244
+	if _, err := runContainer(r, []string{"-v", fmt.Sprintf("%s:.", tmpDir), "ls", "."}, nil); err == nil {
1245 1245
 		t.Fatal("Container bind mounted illegal directory")
1246
-
1247 1246
 	}
1248 1247
 }
1249 1248
 
... ...
@@ -1,13 +1,13 @@
1 1
 package docker
2 2
 
3 3
 import (
4
+	"github.com/dotcloud/docker/utils"
4 5
 	"io"
5 6
 	"io/ioutil"
6 7
 	"os"
7 8
 	"path"
8 9
 	"strings"
9 10
 	"testing"
10
-	"github.com/dotcloud/docker/utils"
11 11
 )
12 12
 
13 13
 // This file contains utility functions for docker's unit test suite.
... ...
@@ -87,17 +87,18 @@ func readFile(src string, t *testing.T) (content string) {
87 87
 // The image name (eg. the XXX in []string{"-i", "-t", "XXX", "bash"}, is dynamically replaced by the current test image.
88 88
 // The caller is responsible for destroying the container.
89 89
 // Call t.Fatal() at the first error.
90
-func mkContainer(r *Runtime, args []string, t *testing.T) (*Container, *HostConfig) {
90
+func mkContainer(r *Runtime, args []string, t *testing.T) (*Container, *HostConfig, error) {
91 91
 	config, hostConfig, _, err := ParseRun(args, nil)
92 92
 	if err != nil {
93
-		t.Fatal(err)
93
+		return nil, nil, err
94 94
 	}
95 95
 	config.Image = GetTestImage(r).ID
96 96
 	c, err := NewBuilder(r).Create(config)
97 97
 	if err != nil {
98 98
 		t.Fatal(err)
99
+		return nil, nil, err
99 100
 	}
100
-	return c, hostConfig
101
+	return c, hostConfig, nil
101 102
 }
102 103
 
103 104
 // Create a test container, start it, wait for it to complete, destroy it,
... ...
@@ -110,7 +111,10 @@ func runContainer(r *Runtime, args []string, t *testing.T) (output string, err e
110 110
 			t.Fatal(err)
111 111
 		}
112 112
 	}()
113
-	container, hostConfig := mkContainer(r, args, t)
113
+	container, hostConfig, err := mkContainer(r, args, t)
114
+	if err != nil {
115
+		return "", err
116
+	}
114 117
 	defer r.Destroy(container)
115 118
 	stdout, err := container.StdoutPipe()
116 119
 	if err != nil {