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

Merge pull request #1496 from xdissent/1351-volumes-from-before-volumes

* Runtime: Apply volumes-from before creating volumes
This commit is contained in:
Guillaume J. Charmes 2013-08-14 15:10:41 -07:00
commit 631c449183
2 changed files with 99 additions and 30 deletions

View file

@ -577,14 +577,38 @@ func (container *Container) Start(hostConfig *HostConfig) error {
binds[path.Clean(dst)] = bindMap
}
// FIXME: evaluate volumes-from before individual volumes, so that the latter can override the former.
// Create the requested volumes volumes
if container.Volumes == nil || len(container.Volumes) == 0 {
container.Volumes = make(map[string]string)
container.VolumesRW = make(map[string]bool)
}
// Apply volumes from another container if requested
if container.Config.VolumesFrom != "" {
c := container.runtime.Get(container.Config.VolumesFrom)
if c == nil {
return fmt.Errorf("Container %s not found. Impossible to mount its volumes", container.ID)
}
for volPath, id := range c.Volumes {
if _, exists := container.Volumes[volPath]; exists {
continue
}
if err := os.MkdirAll(path.Join(container.RootfsPath(), volPath), 0755); err != nil {
return nil
}
container.Volumes[volPath] = id
if isRW, exists := c.VolumesRW[volPath]; exists {
container.VolumesRW[volPath] = isRW
}
}
}
// Create the requested volumes if they don't exist
for volPath := range container.Config.Volumes {
volPath = path.Clean(volPath)
// Skip existing volumes
if _, exists := container.Volumes[volPath]; exists {
continue
}
// If an external bind is defined for this volume, use that as a source
if bindMap, exists := binds[volPath]; exists {
container.Volumes[volPath] = bindMap.SrcPath
@ -609,26 +633,6 @@ func (container *Container) Start(hostConfig *HostConfig) error {
return nil
}
}
}
if container.Config.VolumesFrom != "" {
c := container.runtime.Get(container.Config.VolumesFrom)
if c == nil {
return fmt.Errorf("Container %s not found. Impossible to mount its volumes", container.ID)
}
for volPath, id := range c.Volumes {
if _, exists := container.Volumes[volPath]; exists {
return fmt.Errorf("The requested volume %s overlap one of the volume of the container %s", volPath, c.ID)
}
if err := os.MkdirAll(path.Join(container.RootfsPath(), volPath), 0755); err != nil {
return nil
}
container.Volumes[volPath] = id
if isRW, exists := c.VolumesRW[volPath]; exists {
container.VolumesRW[volPath] = isRW
}
}
}
if err := container.generateLXCConfig(); err != nil {
return err

View file

@ -1283,6 +1283,71 @@ func TestRestartWithVolumes(t *testing.T) {
}
}
// Test for #1351
func TestVolumesFromWithVolumes(t *testing.T) {
runtime := mkRuntime(t)
defer nuke(runtime)
container, err := NewBuilder(runtime).Create(&Config{
Image: GetTestImage(runtime).ID,
Cmd: []string{"sh", "-c", "echo -n bar > /test/foo"},
Volumes: map[string]struct{}{"/test": {}},
},
)
if err != nil {
t.Fatal(err)
}
defer runtime.Destroy(container)
for key := range container.Config.Volumes {
if key != "/test" {
t.Fail()
}
}
_, err = container.Output()
if err != nil {
t.Fatal(err)
}
expected := container.Volumes["/test"]
if expected == "" {
t.Fail()
}
container2, err := NewBuilder(runtime).Create(
&Config{
Image: GetTestImage(runtime).ID,
Cmd: []string{"cat", "/test/foo"},
VolumesFrom: container.ID,
Volumes: map[string]struct{}{"/test": {}},
},
)
if err != nil {
t.Fatal(err)
}
defer runtime.Destroy(container2)
output, err := container2.Output()
if err != nil {
t.Fatal(err)
}
if string(output) != "bar" {
t.Fail()
}
if container.Volumes["/test"] != container2.Volumes["/test"] {
t.Fail()
}
// Ensure it restarts successfully
_, err = container2.Output()
if err != nil {
t.Fatal(err)
}
}
func TestOnlyLoopbackExistsWhenUsingDisableNetworkOption(t *testing.T) {
runtime := mkRuntime(t)
defer nuke(runtime)