зеркало из https://github.com/microsoft/docker.git
Add ability to mount volumes in readonly mode using -volumes-from
This commit is contained in:
Родитель
dcaaecc815
Коммит
f9cb6ae46a
24
container.go
24
container.go
|
@ -199,7 +199,7 @@ func ParseRun(args []string, capabilities *Capabilities) (*Config, *HostConfig,
|
||||||
cmd.Var(flVolumes, "v", "Bind mount a volume (e.g. from the host: -v /host:/container, from docker: -v /container)")
|
cmd.Var(flVolumes, "v", "Bind mount a volume (e.g. from the host: -v /host:/container, from docker: -v /container)")
|
||||||
|
|
||||||
var flVolumesFrom utils.ListOpts
|
var flVolumesFrom utils.ListOpts
|
||||||
cmd.Var(&flVolumesFrom, "volumes-from", "Mount volumes from the specified container")
|
cmd.Var(&flVolumesFrom, "volumes-from", "Mount volumes from the specified container(s)")
|
||||||
|
|
||||||
flEntrypoint := cmd.String("entrypoint", "", "Overwrite the default entrypoint of the image")
|
flEntrypoint := cmd.String("entrypoint", "", "Overwrite the default entrypoint of the image")
|
||||||
|
|
||||||
|
@ -749,9 +749,23 @@ func (container *Container) Start() (err error) {
|
||||||
|
|
||||||
// Apply volumes from another container if requested
|
// Apply volumes from another container if requested
|
||||||
if container.Config.VolumesFrom != "" {
|
if container.Config.VolumesFrom != "" {
|
||||||
volumes := strings.Split(container.Config.VolumesFrom, ",")
|
containerSpecs := strings.Split(container.Config.VolumesFrom, ",")
|
||||||
for _, v := range volumes {
|
for _, containerSpec := range containerSpecs {
|
||||||
c := container.runtime.Get(v)
|
mountRW := true
|
||||||
|
specParts := strings.SplitN(containerSpec, ":", 2)
|
||||||
|
switch len(specParts) {
|
||||||
|
case 0:
|
||||||
|
return fmt.Errorf("Malformed volumes-from specification: %s", container.Config.VolumesFrom)
|
||||||
|
case 2:
|
||||||
|
switch specParts[1] {
|
||||||
|
case "ro":
|
||||||
|
mountRW = false
|
||||||
|
case "rw": // mountRW is already true
|
||||||
|
default:
|
||||||
|
return fmt.Errorf("Malformed volumes-from speficication: %s", containerSpec)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
c := container.runtime.Get(specParts[0])
|
||||||
if c == nil {
|
if c == nil {
|
||||||
return fmt.Errorf("Container %s not found. Impossible to mount its volumes", container.ID)
|
return fmt.Errorf("Container %s not found. Impossible to mount its volumes", container.ID)
|
||||||
}
|
}
|
||||||
|
@ -764,7 +778,7 @@ func (container *Container) Start() (err error) {
|
||||||
}
|
}
|
||||||
container.Volumes[volPath] = id
|
container.Volumes[volPath] = id
|
||||||
if isRW, exists := c.VolumesRW[volPath]; exists {
|
if isRW, exists := c.VolumesRW[volPath]; exists {
|
||||||
container.VolumesRW[volPath] = isRW
|
container.VolumesRW[volPath] = isRW && mountRW
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1338,6 +1338,68 @@ func TestBindMounts(t *testing.T) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Test that -volumes-from supports both read-only mounts
|
||||||
|
func TestFromVolumesInReadonlyMode(t *testing.T) {
|
||||||
|
runtime := mkRuntime(t)
|
||||||
|
defer nuke(runtime)
|
||||||
|
container, _, err := runtime.Create(
|
||||||
|
&Config{
|
||||||
|
Image: GetTestImage(runtime).ID,
|
||||||
|
Cmd: []string{"/bin/echo", "-n", "foobar"},
|
||||||
|
Volumes: map[string]struct{}{"/test": {}},
|
||||||
|
},
|
||||||
|
"",
|
||||||
|
)
|
||||||
|
if err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
defer runtime.Destroy(container)
|
||||||
|
_, err = container.Output()
|
||||||
|
if err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
if !container.VolumesRW["/test"] {
|
||||||
|
t.Fail()
|
||||||
|
}
|
||||||
|
|
||||||
|
container2, _, err := runtime.Create(
|
||||||
|
&Config{
|
||||||
|
Image: GetTestImage(runtime).ID,
|
||||||
|
Cmd: []string{"/bin/echo", "-n", "foobar"},
|
||||||
|
VolumesFrom: container.ID + ":ro",
|
||||||
|
},
|
||||||
|
"",
|
||||||
|
)
|
||||||
|
if err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
defer runtime.Destroy(container2)
|
||||||
|
|
||||||
|
_, err = container2.Output()
|
||||||
|
if err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
if container.Volumes["/test"] != container2.Volumes["/test"] {
|
||||||
|
t.Logf("container volumes do not match: %s | %s ",
|
||||||
|
container.Volumes["/test"],
|
||||||
|
container2.Volumes["/test"])
|
||||||
|
t.Fail()
|
||||||
|
}
|
||||||
|
|
||||||
|
_, exists := container2.VolumesRW["/test"]
|
||||||
|
if !exists {
|
||||||
|
t.Logf("container2 is missing '/test' volume: %s", container2.VolumesRW)
|
||||||
|
t.Fail()
|
||||||
|
}
|
||||||
|
|
||||||
|
if container2.VolumesRW["/test"] != false {
|
||||||
|
t.Log("'/test' volume mounted in read-write mode, expected read-only")
|
||||||
|
t.Fail()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
// Test that VolumesRW values are copied to the new container. Regression test for #1201
|
// Test that VolumesRW values are copied to the new container. Regression test for #1201
|
||||||
func TestVolumesFromReadonlyMount(t *testing.T) {
|
func TestVolumesFromReadonlyMount(t *testing.T) {
|
||||||
runtime := mkRuntime(t)
|
runtime := mkRuntime(t)
|
||||||
|
|
|
@ -576,7 +576,7 @@ network communication.
|
||||||
-u="": Username or UID
|
-u="": Username or UID
|
||||||
-dns=[]: Set custom dns servers for the container
|
-dns=[]: Set custom dns servers for the container
|
||||||
-v=[]: Create a bind mount with: [host-dir]:[container-dir]:[rw|ro]. If "container-dir" is missing, then docker creates a new volume.
|
-v=[]: Create a bind mount with: [host-dir]:[container-dir]:[rw|ro]. If "container-dir" is missing, then docker creates a new volume.
|
||||||
-volumes-from="": Mount all volumes from the given container
|
-volumes-from="": Mount all volumes from the given container(s)
|
||||||
-entrypoint="": Overwrite the default entrypoint set by the image
|
-entrypoint="": Overwrite the default entrypoint set by the image
|
||||||
-w="": Working directory inside the container
|
-w="": Working directory inside the container
|
||||||
-lxc-conf=[]: Add custom lxc options -lxc-conf="lxc.cgroup.cpuset.cpus = 0,1"
|
-lxc-conf=[]: Add custom lxc options -lxc-conf="lxc.cgroup.cpuset.cpus = 0,1"
|
||||||
|
@ -668,6 +668,17 @@ can access the network and environment of the redis container via
|
||||||
environment variables. The ``-name`` flag will assign the name ``console``
|
environment variables. The ``-name`` flag will assign the name ``console``
|
||||||
to the newly created container.
|
to the newly created container.
|
||||||
|
|
||||||
|
.. code-block:: bash
|
||||||
|
|
||||||
|
docker run -volumes-from 777f7dc92da7,ba8c0c54f0f2:ro -i -t ubuntu pwd
|
||||||
|
|
||||||
|
The ``-volumes-from`` flag mounts all the defined volumes from the
|
||||||
|
refrence containers. Containers can be specified by a comma seperated
|
||||||
|
list or by repetitions of the ``-volumes-from`` argument. The container
|
||||||
|
id may be optionally suffixed with ``:ro`` or ``:rw`` to mount the volumes in
|
||||||
|
read-only or read-write mode, respectively. By default, the volumes are mounted
|
||||||
|
in the same mode (rw or ro) as the reference container.
|
||||||
|
|
||||||
.. _cli_search:
|
.. _cli_search:
|
||||||
|
|
||||||
``search``
|
``search``
|
||||||
|
|
Загрузка…
Ссылка в новой задаче