Skip to content

Commit e029a49

Browse files
authored
Merge pull request #4958 from hashicorp/f-mount-docker-087
Implemented bind mount type; added tests
2 parents b5e6483 + a62a151 commit e029a49

File tree

3 files changed

+403
-25
lines changed

3 files changed

+403
-25
lines changed

client/driver/docker.go

+67-15
Original file line numberDiff line numberDiff line change
@@ -168,9 +168,11 @@ type DockerLoggingOpts struct {
168168
}
169169

170170
type DockerMount struct {
171+
Type string `mapstructure:"type"`
171172
Target string `mapstructure:"target"`
172173
Source string `mapstructure:"source"`
173174
ReadOnly bool `mapstructure:"readonly"`
175+
BindOptions []*DockerBindOptions `mapstructure:"bind_options"`
174176
VolumeOptions []*DockerVolumeOptions `mapstructure:"volume_options"`
175177
}
176178

@@ -180,6 +182,10 @@ type DockerDevice struct {
180182
CgroupPermissions string `mapstructure:"cgroup_permissions"`
181183
}
182184

185+
type DockerBindOptions struct {
186+
Propagation string `mapstructure:"propagation"`
187+
}
188+
183189
type DockerVolumeOptions struct {
184190
NoCopy bool `mapstructure:"no_copy"`
185191
Labels []map[string]string `mapstructure:"labels"`
@@ -390,8 +396,29 @@ func NewDockerDriverConfig(task *structs.Task, env *env.TaskEnv) (*DockerDriverC
390396
dconf.Mounts[i].Target = env.ReplaceEnv(m.Target)
391397
dconf.Mounts[i].Source = env.ReplaceEnv(m.Source)
392398

399+
if m.Type == "" {
400+
// default to `volume` type for backwards compatibility
401+
m.Type = "volume"
402+
}
403+
404+
if m.Type != "bind" && m.Type != "volume" {
405+
return nil, fmt.Errorf(`Docker mount type must be "bind" or "volume"`)
406+
}
407+
408+
if m.Type == "bind" && len(m.VolumeOptions) > 0 {
409+
return nil, fmt.Errorf(`volume_options invalid on "bind" mount type`)
410+
}
411+
412+
if m.Type == "volume" && len(m.BindOptions) > 0 {
413+
return nil, fmt.Errorf(`bind_options invalid on "volume" mount type`)
414+
}
415+
416+
if len(m.BindOptions) > 1 {
417+
return nil, fmt.Errorf("only one bind_options stanza allowed")
418+
}
419+
393420
if len(m.VolumeOptions) > 1 {
394-
return nil, fmt.Errorf("Only one volume_options stanza allowed")
421+
return nil, fmt.Errorf("only one volume_options stanza allowed")
395422
}
396423

397424
if len(m.VolumeOptions) == 1 {
@@ -1342,26 +1369,51 @@ func (d *DockerDriver) createContainerConfig(ctx *ExecContext, task *structs.Tas
13421369
hm := docker.HostMount{
13431370
Target: m.Target,
13441371
Source: m.Source,
1345-
Type: "volume", // Only type supported
1372+
Type: m.Type,
13461373
ReadOnly: m.ReadOnly,
13471374
}
1348-
if len(m.VolumeOptions) == 1 {
1349-
vo := m.VolumeOptions[0]
1350-
hm.VolumeOptions = &docker.VolumeOptions{
1351-
NoCopy: vo.NoCopy,
1352-
}
13531375

1354-
if len(vo.DriverConfig) == 1 {
1355-
dc := vo.DriverConfig[0]
1356-
hm.VolumeOptions.DriverConfig = docker.VolumeDriverConfig{
1357-
Name: dc.Name,
1376+
if hm.Type == "bind" {
1377+
volumesEnabled := d.config.ReadBoolDefault(dockerVolumesConfigOption, dockerVolumesConfigDefault)
1378+
hm.Source = filepath.Clean(hm.Source)
1379+
1380+
if filepath.IsAbs(hm.Source) {
1381+
d.logger.Println("[DEBUG] driver.docker: Job contains an absolute path.")
1382+
if !volumesEnabled {
1383+
// Disallow mounting arbitrary absolute paths
1384+
return c, fmt.Errorf("%s is false; cannot bind mount host paths: %+q", dockerVolumesConfigOption, m.Source)
13581385
}
1359-
if len(dc.Options) == 1 {
1360-
hm.VolumeOptions.DriverConfig.Options = dc.Options[0]
1386+
} else {
1387+
// Expand path relative to alloc dir
1388+
hm.Source = filepath.Join(ctx.TaskDir.Dir, m.Source)
1389+
d.logger.Printf("[DEBUG] driver.docker: Job contains a relative path; expanding to %v", hm.Source)
1390+
}
1391+
1392+
if len(m.BindOptions) == 1 {
1393+
bo := m.BindOptions[0]
1394+
hm.BindOptions = &docker.BindOptions{
1395+
Propagation: bo.Propagation,
13611396
}
13621397
}
1363-
if len(vo.Labels) == 1 {
1364-
hm.VolumeOptions.Labels = vo.Labels[0]
1398+
} else {
1399+
if len(m.VolumeOptions) == 1 {
1400+
vo := m.VolumeOptions[0]
1401+
hm.VolumeOptions = &docker.VolumeOptions{
1402+
NoCopy: vo.NoCopy,
1403+
}
1404+
1405+
if len(vo.DriverConfig) == 1 {
1406+
dc := vo.DriverConfig[0]
1407+
hm.VolumeOptions.DriverConfig = docker.VolumeDriverConfig{
1408+
Name: dc.Name,
1409+
}
1410+
if len(dc.Options) == 1 {
1411+
hm.VolumeOptions.DriverConfig.Options = dc.Options[0]
1412+
}
1413+
}
1414+
if len(vo.Labels) == 1 {
1415+
hm.VolumeOptions.Labels = vo.Labels[0]
1416+
}
13651417
}
13661418
}
13671419
hostConfig.Mounts = append(hostConfig.Mounts, hm)

0 commit comments

Comments
 (0)