Skip to content

Commit a68ee0d

Browse files
Luke Marsdenaanand
authored andcommitted
Support volume_driver in compose
* Add support for volume_driver parameter in compose yml * Don't expand volume host paths if a volume_driver is specified (i.e., disable compose feature "relative to absolute path transformation" when volume drivers are in use, since volume drivers can use name where host path is normally specified; this is a heuristic) Signed-off-by: Luke Marsden <luke@clusterhq.com>
1 parent ea72760 commit a68ee0d

File tree

4 files changed

+33
-2
lines changed

4 files changed

+33
-2
lines changed

compose/config.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,7 @@
4343
'stdin_open',
4444
'tty',
4545
'user',
46+
'volume_driver',
4647
'volumes',
4748
'volumes_from',
4849
'working_dir',
@@ -251,7 +252,7 @@ def process_container_options(service_dict, working_dir=None):
251252
if 'memswap_limit' in service_dict and 'mem_limit' not in service_dict:
252253
raise ConfigurationError("Invalid 'memswap_limit' configuration for %s service: when defining 'memswap_limit' you must set 'mem_limit' as well" % service_dict['name'])
253254

254-
if 'volumes' in service_dict:
255+
if 'volumes' in service_dict and service_dict.get('volume_driver') is None:
255256
service_dict['volumes'] = resolve_volume_paths(service_dict['volumes'], working_dir=working_dir)
256257

257258
if 'build' in service_dict:

docs/yml.md

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -134,6 +134,12 @@ Mount paths as volumes, optionally specifying a path on the host machine
134134
- cache/:/tmp/cache
135135
- ~/configs:/etc/configs/:ro
136136

137+
You can mount a relative path on the host, which will expand relative to
138+
the directory of the Compose configuration file being used.
139+
140+
> Note: No path expansion will be done if you have also specified a
141+
> `volume_driver`.
142+
137143
### volumes_from
138144

139145
Mount all of the volumes from another service or container.
@@ -333,7 +339,7 @@ Override the default labeling scheme for each container.
333339
- label:user:USER
334340
- label:role:ROLE
335341

336-
### working\_dir, entrypoint, user, hostname, domainname, mac\_address, mem\_limit, memswap\_limit, privileged, restart, stdin\_open, tty, cpu\_shares, cpuset, read\_only
342+
### working\_dir, entrypoint, user, hostname, domainname, mac\_address, mem\_limit, memswap\_limit, privileged, restart, stdin\_open, tty, cpu\_shares, cpuset, read\_only, volume\_driver
337343

338344
Each of these is a single value, analogous to its
339345
[docker run](https://docs.docker.com/reference/run/) counterpart.
@@ -360,6 +366,8 @@ Each of these is a single value, analogous to its
360366
tty: true
361367
read_only: true
362368

369+
volume_driver: mydriver
370+
```
363371
364372
## Compose documentation
365373

tests/integration/service_test.py

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -117,6 +117,12 @@ def test_create_container_with_unspecified_volume(self):
117117
service.start_container(container)
118118
self.assertIn('/var/db', container.get('Volumes'))
119119

120+
def test_create_container_with_volume_driver(self):
121+
service = self.create_service('db', volume_driver='foodriver')
122+
container = service.create_container()
123+
service.start_container(container)
124+
self.assertEqual('foodriver', container.get('Config.VolumeDriver'))
125+
120126
def test_create_container_with_cpu_shares(self):
121127
service = self.create_service('db', cpu_shares=73)
122128
container = service.create_container()

tests/unit/config_test.py

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -72,6 +72,22 @@ def test_volume_binding_with_home(self):
7272
d = make_service_dict('foo', {'volumes': ['~:/container/path']}, working_dir='.')
7373
self.assertEqual(d['volumes'], ['/home/user:/container/path'])
7474

75+
def test_named_volume_with_driver(self):
76+
d = make_service_dict('foo', {
77+
'volumes': ['namedvolume:/data'],
78+
'volume_driver': 'foodriver',
79+
}, working_dir='.')
80+
self.assertEqual(d['volumes'], ['namedvolume:/data'])
81+
82+
@mock.patch.dict(os.environ)
83+
def test_named_volume_with_special_chars(self):
84+
os.environ['NAME'] = 'surprise!'
85+
d = make_service_dict('foo', {
86+
'volumes': ['~/${NAME}:/data'],
87+
'volume_driver': 'foodriver',
88+
}, working_dir='.')
89+
self.assertEqual(d['volumes'], ['~/${NAME}:/data'])
90+
7591

7692
class MergePathMappingTest(object):
7793
def config_name(self):

0 commit comments

Comments
 (0)