1
0
Fork 0
mirror of https://github.com/moby/moby.git synced 2022-11-09 12:21:53 -05:00

builder: Fix handling of VOLUME command where multiple volumes are

specified in a space delimited list.

Docker-DCO-1.1-Signed-off-by: Erik Hollensbe <github@hollensbe.org> (github: erikh)
This commit is contained in:
Erik Hollensbe 2014-09-11 06:27:51 -07:00
parent 32b5d145fa
commit a5ca549a18
7 changed files with 47 additions and 13 deletions

View file

@ -310,23 +310,20 @@ func user(b *Builder, args []string, attributes map[string]bool) error {
// VOLUME /foo // VOLUME /foo
// //
// Expose the volume /foo for use. Will also accept the JSON form, but either // Expose the volume /foo for use. Will also accept the JSON array form.
// way requires exactly one argument.
// //
func volume(b *Builder, args []string, attributes map[string]bool) error { func volume(b *Builder, args []string, attributes map[string]bool) error {
if len(args) != 1 { if len(args) == 0 {
return fmt.Errorf("Volume cannot be empty") return fmt.Errorf("Volume cannot be empty")
} }
volume := args
if b.Config.Volumes == nil { if b.Config.Volumes == nil {
b.Config.Volumes = map[string]struct{}{} b.Config.Volumes = map[string]struct{}{}
} }
for _, v := range volume { for _, v := range args {
b.Config.Volumes[v] = struct{}{} b.Config.Volumes[v] = struct{}{}
} }
if err := b.commit("", b.Config.Cmd, fmt.Sprintf("VOLUME %s", args)); err != nil { if err := b.commit("", b.Config.Cmd, fmt.Sprintf("VOLUME %v", args)); err != nil {
return err return err
} }
return nil return nil

View file

@ -135,3 +135,21 @@ func parseMaybeJSON(rest string) (*Node, map[string]bool, error) {
node.Value = rest node.Value = rest
return node, nil, nil return node, nil, nil
} }
// parseMaybeJSONToList determines if the argument appears to be a JSON array. If
// so, passes to parseJSON; if not, attmpts to parse it as a whitespace
// delimited string.
func parseMaybeJSONToList(rest string) (*Node, map[string]bool, error) {
rest = strings.TrimSpace(rest)
node, attrs, err := parseJSON(rest)
if err == nil {
return node, attrs, nil
}
if err == errDockerfileJSONNesting {
return nil, nil, err
}
return parseStringsWhitespaceDelimited(rest)
}

View file

@ -55,7 +55,7 @@ func init() {
"cmd": parseMaybeJSON, "cmd": parseMaybeJSON,
"entrypoint": parseMaybeJSON, "entrypoint": parseMaybeJSON,
"expose": parseStringsWhitespaceDelimited, "expose": parseStringsWhitespaceDelimited,
"volume": parseMaybeJSON, "volume": parseMaybeJSONToList,
"insert": parseIgnore, "insert": parseIgnore,
} }
} }

View file

@ -0,0 +1,3 @@
FROM foo
VOLUME /opt/nagios/var /opt/nagios/etc /opt/nagios/libexec /var/log/apache2 /usr/share/snmp/mibs

View file

@ -0,0 +1,2 @@
(from "foo")
(volume "/opt/nagios/var" "/opt/nagios/etc" "/opt/nagios/libexec" "/var/log/apache2" "/usr/share/snmp/mibs")

View file

@ -445,9 +445,10 @@ optional but default, you could use a `CMD` instruction:
The `VOLUME` instruction will create a mount point with the specified name The `VOLUME` instruction will create a mount point with the specified name
and mark it as holding externally mounted volumes from native host or other and mark it as holding externally mounted volumes from native host or other
containers. The value can be a JSON array, `VOLUME ["/var/log/"]`, or a plain containers. The value can be a JSON array, `VOLUME ["/var/log/"]`, or a plain
string, `VOLUME /var/log`. For more information/examples and mounting string with multiple arguments, such as `VOLUME /var/log` or `VOLUME /var/log
instructions via the Docker client, refer to [*Share Directories via Volumes*]( /var/db`. For more information/examples and mounting instructions via the
/userguide/dockervolumes/#volume-def) documentation. Docker client, refer to [*Share Directories via Volumes*](/userguide/dockervolumes/#volume-def)
documentation.
## USER ## USER

View file

@ -582,13 +582,26 @@ func TestBuildWithVolumes(t *testing.T) {
result map[string]map[string]struct{} result map[string]map[string]struct{}
name = "testbuildvolumes" name = "testbuildvolumes"
emptyMap = make(map[string]struct{}) emptyMap = make(map[string]struct{})
expected = map[string]map[string]struct{}{"/test1": emptyMap, "/test2": emptyMap} expected = map[string]map[string]struct{}{
"/test1": emptyMap,
"/test2": emptyMap,
"/test3": emptyMap,
"/test4": emptyMap,
"/test5": emptyMap,
"/test6": emptyMap,
"[/test7": emptyMap,
"/test8]": emptyMap,
}
) )
defer deleteImages(name) defer deleteImages(name)
_, err := buildImage(name, _, err := buildImage(name,
`FROM scratch `FROM scratch
VOLUME /test1 VOLUME /test1
VOLUME /test2`, VOLUME /test2
VOLUME /test3 /test4
VOLUME ["/test5", "/test6"]
VOLUME [/test7 /test8]
`,
true) true)
if err != nil { if err != nil {
t.Fatal(err) t.Fatal(err)