mirror of
https://github.com/docker/compose.git
synced 2025-07-25 14:44:29 +02:00
commit
cd47829f3d
@ -1,6 +1,15 @@
|
|||||||
Change log
|
Change log
|
||||||
==========
|
==========
|
||||||
|
|
||||||
|
1.3.1 (2015-06-21)
|
||||||
|
------------------
|
||||||
|
|
||||||
|
The following bugs have been fixed:
|
||||||
|
|
||||||
|
- `docker-compose build` would always attempt to pull the base image before building.
|
||||||
|
- `docker-compose help migrate-to-labels` failed with an error.
|
||||||
|
- If no network mode was specified, Compose would set it to "bridge", rather than allowing the Docker daemon to use its configured default network mode.
|
||||||
|
|
||||||
1.3.0 (2015-06-18)
|
1.3.0 (2015-06-18)
|
||||||
------------------
|
------------------
|
||||||
|
|
||||||
|
@ -1,3 +1,3 @@
|
|||||||
from __future__ import unicode_literals
|
from __future__ import unicode_literals
|
||||||
|
|
||||||
__version__ = '1.3.0'
|
__version__ = '1.3.1'
|
||||||
|
@ -33,12 +33,7 @@ class DocoptCommand(object):
|
|||||||
if command is None:
|
if command is None:
|
||||||
raise SystemExit(getdoc(self))
|
raise SystemExit(getdoc(self))
|
||||||
|
|
||||||
command = command.replace('-', '_')
|
handler = self.get_handler(command)
|
||||||
|
|
||||||
if not hasattr(self, command):
|
|
||||||
raise NoSuchCommand(command, self)
|
|
||||||
|
|
||||||
handler = getattr(self, command)
|
|
||||||
docstring = getdoc(handler)
|
docstring = getdoc(handler)
|
||||||
|
|
||||||
if docstring is None:
|
if docstring is None:
|
||||||
@ -47,6 +42,14 @@ class DocoptCommand(object):
|
|||||||
command_options = docopt_full_help(docstring, options['ARGS'], options_first=True)
|
command_options = docopt_full_help(docstring, options['ARGS'], options_first=True)
|
||||||
return options, handler, command_options
|
return options, handler, command_options
|
||||||
|
|
||||||
|
def get_handler(self, command):
|
||||||
|
command = command.replace('-', '_')
|
||||||
|
|
||||||
|
if not hasattr(self, command):
|
||||||
|
raise NoSuchCommand(command, self)
|
||||||
|
|
||||||
|
return getattr(self, command)
|
||||||
|
|
||||||
|
|
||||||
class NoSuchCommand(Exception):
|
class NoSuchCommand(Exception):
|
||||||
def __init__(self, command, supercommand):
|
def __init__(self, command, supercommand):
|
||||||
|
@ -128,10 +128,8 @@ class TopLevelCommand(Command):
|
|||||||
|
|
||||||
Usage: help COMMAND
|
Usage: help COMMAND
|
||||||
"""
|
"""
|
||||||
command = options['COMMAND']
|
handler = self.get_handler(options['COMMAND'])
|
||||||
if not hasattr(self, command):
|
raise SystemExit(getdoc(handler))
|
||||||
raise NoSuchCommand(command, self)
|
|
||||||
raise SystemExit(getdoc(getattr(self, command)))
|
|
||||||
|
|
||||||
def kill(self, project, options):
|
def kill(self, project, options):
|
||||||
"""
|
"""
|
||||||
@ -485,6 +483,24 @@ class TopLevelCommand(Command):
|
|||||||
"""
|
"""
|
||||||
Recreate containers to add labels
|
Recreate containers to add labels
|
||||||
|
|
||||||
|
If you're coming from Compose 1.2 or earlier, you'll need to remove or
|
||||||
|
migrate your existing containers after upgrading Compose. This is
|
||||||
|
because, as of version 1.3, Compose uses Docker labels to keep track
|
||||||
|
of containers, and so they need to be recreated with labels added.
|
||||||
|
|
||||||
|
If Compose detects containers that were created without labels, it
|
||||||
|
will refuse to run so that you don't end up with two sets of them. If
|
||||||
|
you want to keep using your existing containers (for example, because
|
||||||
|
they have data volumes you want to preserve) you can migrate them with
|
||||||
|
the following command:
|
||||||
|
|
||||||
|
docker-compose migrate-to-labels
|
||||||
|
|
||||||
|
Alternatively, if you're not worried about keeping them, you can
|
||||||
|
remove them - Compose will just create new ones.
|
||||||
|
|
||||||
|
docker rm -f myapp_web_1 myapp_db_1 ...
|
||||||
|
|
||||||
Usage: migrate-to-labels
|
Usage: migrate-to-labels
|
||||||
"""
|
"""
|
||||||
legacy.migrate_project_to_labels(project)
|
legacy.migrate_project_to_labels(project)
|
||||||
|
@ -178,7 +178,7 @@ class Project(object):
|
|||||||
del service_dict['net']
|
del service_dict['net']
|
||||||
|
|
||||||
else:
|
else:
|
||||||
net = 'bridge'
|
net = None
|
||||||
|
|
||||||
return net
|
return net
|
||||||
|
|
||||||
|
@ -473,7 +473,7 @@ class Service(object):
|
|||||||
|
|
||||||
def _get_net(self):
|
def _get_net(self):
|
||||||
if not self.net:
|
if not self.net:
|
||||||
return "bridge"
|
return None
|
||||||
|
|
||||||
if isinstance(self.net, Service):
|
if isinstance(self.net, Service):
|
||||||
containers = self.net.containers()
|
containers = self.net.containers()
|
||||||
@ -628,6 +628,7 @@ class Service(object):
|
|||||||
tag=self.image_name,
|
tag=self.image_name,
|
||||||
stream=True,
|
stream=True,
|
||||||
rm=True,
|
rm=True,
|
||||||
|
pull=False,
|
||||||
nocache=no_cache,
|
nocache=no_cache,
|
||||||
dockerfile=self.options.get('dockerfile', None),
|
dockerfile=self.options.get('dockerfile', None),
|
||||||
)
|
)
|
||||||
|
@ -27,7 +27,7 @@ First, install Docker version 1.6 or greater:
|
|||||||
|
|
||||||
To install Compose, run the following commands:
|
To install Compose, run the following commands:
|
||||||
|
|
||||||
curl -L https://github.com/docker/compose/releases/download/1.3.0/docker-compose-`uname -s`-`uname -m` > /usr/local/bin/docker-compose
|
curl -L https://github.com/docker/compose/releases/download/1.3.1/docker-compose-`uname -s`-`uname -m` > /usr/local/bin/docker-compose
|
||||||
chmod +x /usr/local/bin/docker-compose
|
chmod +x /usr/local/bin/docker-compose
|
||||||
|
|
||||||
> Note: If you get a "Permission denied" error, your `/usr/local/bin` directory probably isn't writable and you'll need to install Compose as the superuser. Run `sudo -i`, then the two commands above, then `exit`.
|
> Note: If you get a "Permission denied" error, your `/usr/local/bin` directory probably isn't writable and you'll need to install Compose as the superuser. Run `sudo -i`, then the two commands above, then `exit`.
|
||||||
|
@ -11,6 +11,7 @@ import mock
|
|||||||
|
|
||||||
from compose.cli import main
|
from compose.cli import main
|
||||||
from compose.cli.main import TopLevelCommand
|
from compose.cli.main import TopLevelCommand
|
||||||
|
from compose.cli.docopt_command import NoSuchCommand
|
||||||
from compose.cli.errors import ComposeFileNotFound
|
from compose.cli.errors import ComposeFileNotFound
|
||||||
from compose.service import Service
|
from compose.service import Service
|
||||||
|
|
||||||
@ -101,6 +102,22 @@ class CLITestCase(unittest.TestCase):
|
|||||||
with self.assertRaises(SystemExit):
|
with self.assertRaises(SystemExit):
|
||||||
command.dispatch(['-h'], None)
|
command.dispatch(['-h'], None)
|
||||||
|
|
||||||
|
def test_command_help(self):
|
||||||
|
with self.assertRaises(SystemExit) as ctx:
|
||||||
|
TopLevelCommand().dispatch(['help', 'up'], None)
|
||||||
|
|
||||||
|
self.assertIn('Usage: up', str(ctx.exception))
|
||||||
|
|
||||||
|
def test_command_help_dashes(self):
|
||||||
|
with self.assertRaises(SystemExit) as ctx:
|
||||||
|
TopLevelCommand().dispatch(['help', 'migrate-to-labels'], None)
|
||||||
|
|
||||||
|
self.assertIn('Usage: migrate-to-labels', str(ctx.exception))
|
||||||
|
|
||||||
|
def test_command_help_nonexistent(self):
|
||||||
|
with self.assertRaises(NoSuchCommand):
|
||||||
|
TopLevelCommand().dispatch(['help', 'nonexistent'], None)
|
||||||
|
|
||||||
def test_setup_logging(self):
|
def test_setup_logging(self):
|
||||||
main.setup_logging()
|
main.setup_logging()
|
||||||
self.assertEqual(logging.getLogger().level, logging.DEBUG)
|
self.assertEqual(logging.getLogger().level, logging.DEBUG)
|
||||||
|
@ -209,6 +209,18 @@ class ProjectTest(unittest.TestCase):
|
|||||||
], None)
|
], None)
|
||||||
self.assertEqual(project.get_service('test')._get_volumes_from(), container_ids)
|
self.assertEqual(project.get_service('test')._get_volumes_from(), container_ids)
|
||||||
|
|
||||||
|
def test_net_unset(self):
|
||||||
|
mock_client = mock.create_autospec(docker.Client)
|
||||||
|
project = Project.from_dicts('test', [
|
||||||
|
{
|
||||||
|
'name': 'test',
|
||||||
|
'image': 'busybox:latest',
|
||||||
|
}
|
||||||
|
], mock_client)
|
||||||
|
service = project.get_service('test')
|
||||||
|
self.assertEqual(service._get_net(), None)
|
||||||
|
self.assertNotIn('NetworkMode', service._get_container_host_config({}))
|
||||||
|
|
||||||
def test_use_net_from_container(self):
|
def test_use_net_from_container(self):
|
||||||
container_id = 'aabbccddee'
|
container_id = 'aabbccddee'
|
||||||
container_dict = dict(Name='aaa', Id=container_id)
|
container_dict = dict(Name='aaa', Id=container_id)
|
||||||
|
@ -303,6 +303,17 @@ class ServiceTest(unittest.TestCase):
|
|||||||
with self.assertRaises(NeedsBuildError):
|
with self.assertRaises(NeedsBuildError):
|
||||||
service.create_container(do_build=False)
|
service.create_container(do_build=False)
|
||||||
|
|
||||||
|
def test_build_does_not_pull(self):
|
||||||
|
self.mock_client.build.return_value = [
|
||||||
|
'{"stream": "Successfully built 12345"}',
|
||||||
|
]
|
||||||
|
|
||||||
|
service = Service('foo', client=self.mock_client, build='.')
|
||||||
|
service.build()
|
||||||
|
|
||||||
|
self.assertEqual(self.mock_client.build.call_count, 1)
|
||||||
|
self.assertFalse(self.mock_client.build.call_args[1]['pull'])
|
||||||
|
|
||||||
|
|
||||||
class ServiceVolumesTest(unittest.TestCase):
|
class ServiceVolumesTest(unittest.TestCase):
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user