Merge pull request #3066 from shin-/3062-dont-log-noop-volume-create

Don't call create on existing volumes
This commit is contained in:
Daniel Nephin 2016-03-08 15:04:59 -08:00
commit 7de9b08ca5
2 changed files with 61 additions and 19 deletions

View File

@ -3,7 +3,6 @@ from __future__ import unicode_literals
import logging import logging
from docker.errors import APIError
from docker.errors import NotFound from docker.errors import NotFound
from .config import ConfigurationError from .config import ConfigurationError
@ -82,12 +81,13 @@ class ProjectVolumes(object):
def initialize(self): def initialize(self):
try: try:
for volume in self.volumes.values(): for volume in self.volumes.values():
volume_exists = volume.exists()
if volume.external: if volume.external:
log.debug( log.debug(
'Volume {0} declared as external. No new ' 'Volume {0} declared as external. No new '
'volume will be created.'.format(volume.name) 'volume will be created.'.format(volume.name)
) )
if not volume.exists(): if not volume_exists:
raise ConfigurationError( raise ConfigurationError(
'Volume {name} declared as external, but could' 'Volume {name} declared as external, but could'
' not be found. Please create the volume manually' ' not be found. Please create the volume manually'
@ -97,28 +97,32 @@ class ProjectVolumes(object):
) )
) )
continue continue
log.info(
'Creating volume "{0}" with {1} driver'.format( if not volume_exists:
volume.full_name, volume.driver or 'default' log.info(
'Creating volume "{0}" with {1} driver'.format(
volume.full_name, volume.driver or 'default'
)
) )
) volume.create()
volume.create() else:
driver = volume.inspect()['Driver']
if volume.driver is not None and driver != volume.driver:
raise ConfigurationError(
'Configuration for volume {0} specifies driver '
'{1}, but a volume with the same name uses a '
'different driver ({3}). If you wish to use the '
'new configuration, please remove the existing '
'volume "{2}" first:\n'
'$ docker volume rm {2}'.format(
volume.name, volume.driver, volume.full_name,
volume.inspect()['Driver']
)
)
except NotFound: except NotFound:
raise ConfigurationError( raise ConfigurationError(
'Volume %s specifies nonexistent driver %s' % (volume.name, volume.driver) 'Volume %s specifies nonexistent driver %s' % (volume.name, volume.driver)
) )
except APIError as e:
if 'Choose a different volume name' in str(e):
raise ConfigurationError(
'Configuration for volume {0} specifies driver {1}, but '
'a volume with the same name uses a different driver '
'({3}). If you wish to use the new configuration, please '
'remove the existing volume "{2}" first:\n'
'$ docker volume rm {2}'.format(
volume.name, volume.driver, volume.full_name,
volume.inspect()['Driver']
)
)
def namespace_spec(self, volume_spec): def namespace_spec(self, volume_spec):
if not volume_spec.is_named_volume: if not volume_spec.is_named_volume:

View File

@ -839,6 +839,44 @@ class ProjectTest(DockerClientTestCase):
vol_name vol_name
) in str(e.exception) ) in str(e.exception)
@v2_only()
def test_initialize_volumes_updated_blank_driver(self):
vol_name = '{0:x}'.format(random.getrandbits(32))
full_vol_name = 'composetest_{0}'.format(vol_name)
config_data = config.Config(
version=V2_0,
services=[{
'name': 'web',
'image': 'busybox:latest',
'command': 'top'
}],
volumes={vol_name: {'driver': 'local'}},
networks={},
)
project = Project.from_config(
name='composetest',
config_data=config_data, client=self.client
)
project.volumes.initialize()
volume_data = self.client.inspect_volume(full_vol_name)
self.assertEqual(volume_data['Name'], full_vol_name)
self.assertEqual(volume_data['Driver'], 'local')
config_data = config_data._replace(
volumes={vol_name: {}}
)
project = Project.from_config(
name='composetest',
config_data=config_data,
client=self.client
)
project.volumes.initialize()
volume_data = self.client.inspect_volume(full_vol_name)
self.assertEqual(volume_data['Name'], full_vol_name)
self.assertEqual(volume_data['Driver'], 'local')
@v2_only() @v2_only()
def test_initialize_volumes_external_volumes(self): def test_initialize_volumes_external_volumes(self):
# Use composetest_ prefix so it gets garbage-collected in tearDown() # Use composetest_ prefix so it gets garbage-collected in tearDown()