mirror of https://github.com/docker/compose.git
up, start, stop, kill and rm all accept a list of services
This commit is contained in:
parent
81093627fe
commit
d3346fa174
|
@ -5,6 +5,7 @@ import re
|
|||
from inspect import getdoc
|
||||
|
||||
from .. import __version__
|
||||
from ..project import NoSuchService
|
||||
from .command import Command
|
||||
from .formatter import Formatter
|
||||
from .log_printer import LogPrinter
|
||||
|
@ -37,6 +38,9 @@ def main():
|
|||
except UserError, e:
|
||||
log.error(e.msg)
|
||||
exit(1)
|
||||
except NoSuchService, e:
|
||||
log.error(e.msg)
|
||||
exit(1)
|
||||
except NoSuchCommand, e:
|
||||
log.error("No such command: %s", e.command)
|
||||
log.error("")
|
||||
|
@ -121,8 +125,6 @@ class TopLevelCommand(Command):
|
|||
-d Detached mode: Run container in the background, print new container name
|
||||
"""
|
||||
service = self.project.get_service(options['SERVICE'])
|
||||
if service is None:
|
||||
raise UserError("No such service: %s" % options['SERVICE'])
|
||||
container_options = {
|
||||
'command': [options['COMMAND']] + options['ARGS'],
|
||||
'tty': not options['-d'],
|
||||
|
@ -146,17 +148,17 @@ class TopLevelCommand(Command):
|
|||
"""
|
||||
Create and start containers
|
||||
|
||||
Usage: up [options]
|
||||
Usage: up [options] [SERVICE...]
|
||||
|
||||
Options:
|
||||
-d Detached mode: Run containers in the background, print new container names
|
||||
"""
|
||||
detached = options['-d']
|
||||
|
||||
unstarted = self.project.create_containers()
|
||||
unstarted = self.project.create_containers(service_names=options['SERVICE'])
|
||||
|
||||
if not detached:
|
||||
to_attach = self.project.containers() + [c for (s, c) in unstarted]
|
||||
to_attach = self.project.containers(service_names=options['SERVICE']) + [c for (s, c) in unstarted]
|
||||
print "Attaching to", list_containers(to_attach)
|
||||
log_printer = LogPrinter(to_attach, attach_params={'logs': True})
|
||||
|
||||
|
@ -176,33 +178,33 @@ class TopLevelCommand(Command):
|
|||
"""
|
||||
Start all services
|
||||
|
||||
Usage: start
|
||||
Usage: start [SERVICE...]
|
||||
"""
|
||||
self.project.start()
|
||||
self.project.start(service_names=options['SERVICE'])
|
||||
|
||||
def stop(self, options):
|
||||
"""
|
||||
Stop all services
|
||||
|
||||
Usage: stop
|
||||
Usage: stop [SERVICE...]
|
||||
"""
|
||||
self.project.stop()
|
||||
self.project.stop(service_names=options['SERVICE'])
|
||||
|
||||
def kill(self, options):
|
||||
"""
|
||||
Kill all containers
|
||||
|
||||
Usage: kill
|
||||
Usage: kill [SERVICE...]
|
||||
"""
|
||||
self.project.kill()
|
||||
self.project.kill(service_names=options['SERVICE'])
|
||||
|
||||
def rm(self, options):
|
||||
"""
|
||||
Remove all stopped containers
|
||||
|
||||
Usage: rm
|
||||
Usage: rm [SERVICE...]
|
||||
"""
|
||||
self.project.remove_stopped()
|
||||
self.project.remove_stopped(service_names=options['SERVICE'])
|
||||
|
||||
def logs(self, options):
|
||||
"""
|
||||
|
|
|
@ -46,17 +46,40 @@ class Project(object):
|
|||
return cls.from_dicts(name, dicts, client)
|
||||
|
||||
def get_service(self, name):
|
||||
"""
|
||||
Retrieve a service by name. Raises NoSuchService
|
||||
if the named service does not exist.
|
||||
"""
|
||||
for service in self.services:
|
||||
if service.name == name:
|
||||
return service
|
||||
|
||||
def create_containers(self):
|
||||
raise NoSuchService(name)
|
||||
|
||||
def get_services(self, service_names=None):
|
||||
"""
|
||||
Returns a list of this project's services filtered
|
||||
by the provided list of names, or all services if
|
||||
service_names is None or [].
|
||||
|
||||
Preserves the original order of self.services.
|
||||
|
||||
Raises NoSuchService if any of the named services
|
||||
do not exist.
|
||||
"""
|
||||
if service_names is None or len(service_names) == 0:
|
||||
return self.services
|
||||
else:
|
||||
unsorted = [self.get_service(name) for name in service_names]
|
||||
return [s for s in self.services if s in unsorted]
|
||||
|
||||
def create_containers(self, service_names=None):
|
||||
"""
|
||||
Returns a list of (service, container) tuples,
|
||||
one for each service with no running containers.
|
||||
"""
|
||||
containers = []
|
||||
for service in self.services:
|
||||
for service in self.get_services(service_names):
|
||||
if len(service.containers()) == 0:
|
||||
containers.append((service, service.create_container()))
|
||||
return containers
|
||||
|
@ -66,27 +89,34 @@ class Project(object):
|
|||
container.kill()
|
||||
container.remove()
|
||||
|
||||
def start(self, **options):
|
||||
for service in self.services:
|
||||
def start(self, service_names=None, **options):
|
||||
for service in self.get_services(service_names):
|
||||
service.start(**options)
|
||||
|
||||
def stop(self, **options):
|
||||
for service in self.services:
|
||||
def stop(self, service_names=None, **options):
|
||||
for service in self.get_services(service_names):
|
||||
service.stop(**options)
|
||||
|
||||
def kill(self, **options):
|
||||
for service in self.services:
|
||||
def kill(self, service_names=None, **options):
|
||||
for service in self.get_services(service_names):
|
||||
service.kill(**options)
|
||||
|
||||
def remove_stopped(self, **options):
|
||||
for service in self.services:
|
||||
def remove_stopped(self, service_names=None, **options):
|
||||
for service in self.get_services(service_names):
|
||||
service.remove_stopped(**options)
|
||||
|
||||
def containers(self, *args, **kwargs):
|
||||
def containers(self, service_names=None, *args, **kwargs):
|
||||
l = []
|
||||
for service in self.services:
|
||||
for service in self.get_services(service_names):
|
||||
for container in service.containers(*args, **kwargs):
|
||||
l.append(container)
|
||||
return l
|
||||
|
||||
|
||||
class NoSuchService(Exception):
|
||||
def __init__(self, name):
|
||||
self.name = name
|
||||
self.msg = "No such service: %s" % self.name
|
||||
|
||||
def __str__(self):
|
||||
return self.msg
|
||||
|
|
|
@ -42,11 +42,30 @@ class ProjectTest(DockerClientTestCase):
|
|||
project = Project('test', [web], self.client)
|
||||
self.assertEqual(project.get_service('web'), web)
|
||||
|
||||
def test_up(self):
|
||||
def test_create_containers(self):
|
||||
web = self.create_service('web')
|
||||
db = self.create_service('db')
|
||||
project = Project('test', [web, db], self.client)
|
||||
|
||||
unstarted = project.create_containers(service_names=['web'])
|
||||
self.assertEqual(len(unstarted), 1)
|
||||
self.assertEqual(unstarted[0][0], web)
|
||||
self.assertEqual(len(web.containers(stopped=True)), 1)
|
||||
self.assertEqual(len(db.containers(stopped=True)), 0)
|
||||
|
||||
unstarted = project.create_containers()
|
||||
self.assertEqual(len(unstarted), 2)
|
||||
self.assertEqual(unstarted[0][0], web)
|
||||
self.assertEqual(unstarted[1][0], db)
|
||||
self.assertEqual(len(web.containers(stopped=True)), 2)
|
||||
self.assertEqual(len(db.containers(stopped=True)), 1)
|
||||
|
||||
def test_up(self):
|
||||
web = self.create_service('web')
|
||||
db = self.create_service('db')
|
||||
other = self.create_service('other')
|
||||
project = Project('test', [web, db, other], self.client)
|
||||
|
||||
web.create_container()
|
||||
|
||||
self.assertEqual(len(web.containers()), 0)
|
||||
|
@ -54,7 +73,7 @@ class ProjectTest(DockerClientTestCase):
|
|||
self.assertEqual(len(web.containers(stopped=True)), 1)
|
||||
self.assertEqual(len(db.containers(stopped=True)), 0)
|
||||
|
||||
unstarted = project.create_containers()
|
||||
unstarted = project.create_containers(service_names=['web', 'db'])
|
||||
self.assertEqual(len(unstarted), 2)
|
||||
self.assertEqual(unstarted[0][0], web)
|
||||
self.assertEqual(unstarted[1][0], db)
|
||||
|
@ -71,7 +90,7 @@ class ProjectTest(DockerClientTestCase):
|
|||
self.assertEqual(len(web.containers(stopped=True)), 1)
|
||||
self.assertEqual(len(db.containers(stopped=True)), 0)
|
||||
|
||||
def test_start_stop(self):
|
||||
def test_start_stop_kill_remove(self):
|
||||
web = self.create_service('web')
|
||||
db = self.create_service('db')
|
||||
project = Project('test', [web, db], self.client)
|
||||
|
@ -81,13 +100,25 @@ class ProjectTest(DockerClientTestCase):
|
|||
self.assertEqual(len(web.containers()), 0)
|
||||
self.assertEqual(len(db.containers()), 0)
|
||||
|
||||
web.create_container()
|
||||
web_container_1 = web.create_container()
|
||||
web_container_2 = web.create_container()
|
||||
db_container = db.create_container()
|
||||
|
||||
project.start(service_names=['web'])
|
||||
self.assertEqual(set(c.name for c in project.containers()), set([web_container_1.name, web_container_2.name]))
|
||||
|
||||
project.start()
|
||||
self.assertEqual(set(c.name for c in project.containers()), set([web_container_1.name, web_container_2.name, db_container.name]))
|
||||
|
||||
self.assertEqual(len(web.containers()), 1)
|
||||
self.assertEqual(len(db.containers()), 0)
|
||||
project.stop(service_names=['web'], timeout=1)
|
||||
self.assertEqual(set(c.name for c in project.containers()), set([db_container.name]))
|
||||
|
||||
project.stop(timeout=1)
|
||||
project.kill(service_names=['db'])
|
||||
self.assertEqual(len(project.containers()), 0)
|
||||
self.assertEqual(len(project.containers(stopped=True)), 3)
|
||||
|
||||
self.assertEqual(len(web.containers()), 0)
|
||||
self.assertEqual(len(db.containers()), 0)
|
||||
project.remove_stopped(service_names=['web'])
|
||||
self.assertEqual(len(project.containers(stopped=True)), 1)
|
||||
|
||||
project.remove_stopped()
|
||||
self.assertEqual(len(project.containers(stopped=True)), 0)
|
||||
|
|
Loading…
Reference in New Issue