mirror of
https://github.com/docker/compose.git
synced 2025-07-21 12:44:54 +02:00
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 inspect import getdoc
|
||||||
|
|
||||||
from .. import __version__
|
from .. import __version__
|
||||||
|
from ..project import NoSuchService
|
||||||
from .command import Command
|
from .command import Command
|
||||||
from .formatter import Formatter
|
from .formatter import Formatter
|
||||||
from .log_printer import LogPrinter
|
from .log_printer import LogPrinter
|
||||||
@ -37,6 +38,9 @@ def main():
|
|||||||
except UserError, e:
|
except UserError, e:
|
||||||
log.error(e.msg)
|
log.error(e.msg)
|
||||||
exit(1)
|
exit(1)
|
||||||
|
except NoSuchService, e:
|
||||||
|
log.error(e.msg)
|
||||||
|
exit(1)
|
||||||
except NoSuchCommand, e:
|
except NoSuchCommand, e:
|
||||||
log.error("No such command: %s", e.command)
|
log.error("No such command: %s", e.command)
|
||||||
log.error("")
|
log.error("")
|
||||||
@ -121,8 +125,6 @@ class TopLevelCommand(Command):
|
|||||||
-d Detached mode: Run container in the background, print new container name
|
-d Detached mode: Run container in the background, print new container name
|
||||||
"""
|
"""
|
||||||
service = self.project.get_service(options['SERVICE'])
|
service = self.project.get_service(options['SERVICE'])
|
||||||
if service is None:
|
|
||||||
raise UserError("No such service: %s" % options['SERVICE'])
|
|
||||||
container_options = {
|
container_options = {
|
||||||
'command': [options['COMMAND']] + options['ARGS'],
|
'command': [options['COMMAND']] + options['ARGS'],
|
||||||
'tty': not options['-d'],
|
'tty': not options['-d'],
|
||||||
@ -146,17 +148,17 @@ class TopLevelCommand(Command):
|
|||||||
"""
|
"""
|
||||||
Create and start containers
|
Create and start containers
|
||||||
|
|
||||||
Usage: up [options]
|
Usage: up [options] [SERVICE...]
|
||||||
|
|
||||||
Options:
|
Options:
|
||||||
-d Detached mode: Run containers in the background, print new container names
|
-d Detached mode: Run containers in the background, print new container names
|
||||||
"""
|
"""
|
||||||
detached = options['-d']
|
detached = options['-d']
|
||||||
|
|
||||||
unstarted = self.project.create_containers()
|
unstarted = self.project.create_containers(service_names=options['SERVICE'])
|
||||||
|
|
||||||
if not detached:
|
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)
|
print "Attaching to", list_containers(to_attach)
|
||||||
log_printer = LogPrinter(to_attach, attach_params={'logs': True})
|
log_printer = LogPrinter(to_attach, attach_params={'logs': True})
|
||||||
|
|
||||||
@ -176,33 +178,33 @@ class TopLevelCommand(Command):
|
|||||||
"""
|
"""
|
||||||
Start all services
|
Start all services
|
||||||
|
|
||||||
Usage: start
|
Usage: start [SERVICE...]
|
||||||
"""
|
"""
|
||||||
self.project.start()
|
self.project.start(service_names=options['SERVICE'])
|
||||||
|
|
||||||
def stop(self, options):
|
def stop(self, options):
|
||||||
"""
|
"""
|
||||||
Stop all services
|
Stop all services
|
||||||
|
|
||||||
Usage: stop
|
Usage: stop [SERVICE...]
|
||||||
"""
|
"""
|
||||||
self.project.stop()
|
self.project.stop(service_names=options['SERVICE'])
|
||||||
|
|
||||||
def kill(self, options):
|
def kill(self, options):
|
||||||
"""
|
"""
|
||||||
Kill all containers
|
Kill all containers
|
||||||
|
|
||||||
Usage: kill
|
Usage: kill [SERVICE...]
|
||||||
"""
|
"""
|
||||||
self.project.kill()
|
self.project.kill(service_names=options['SERVICE'])
|
||||||
|
|
||||||
def rm(self, options):
|
def rm(self, options):
|
||||||
"""
|
"""
|
||||||
Remove all stopped containers
|
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):
|
def logs(self, options):
|
||||||
"""
|
"""
|
||||||
|
@ -46,17 +46,40 @@ class Project(object):
|
|||||||
return cls.from_dicts(name, dicts, client)
|
return cls.from_dicts(name, dicts, client)
|
||||||
|
|
||||||
def get_service(self, name):
|
def get_service(self, name):
|
||||||
|
"""
|
||||||
|
Retrieve a service by name. Raises NoSuchService
|
||||||
|
if the named service does not exist.
|
||||||
|
"""
|
||||||
for service in self.services:
|
for service in self.services:
|
||||||
if service.name == name:
|
if service.name == name:
|
||||||
return service
|
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,
|
Returns a list of (service, container) tuples,
|
||||||
one for each service with no running containers.
|
one for each service with no running containers.
|
||||||
"""
|
"""
|
||||||
containers = []
|
containers = []
|
||||||
for service in self.services:
|
for service in self.get_services(service_names):
|
||||||
if len(service.containers()) == 0:
|
if len(service.containers()) == 0:
|
||||||
containers.append((service, service.create_container()))
|
containers.append((service, service.create_container()))
|
||||||
return containers
|
return containers
|
||||||
@ -66,27 +89,34 @@ class Project(object):
|
|||||||
container.kill()
|
container.kill()
|
||||||
container.remove()
|
container.remove()
|
||||||
|
|
||||||
def start(self, **options):
|
def start(self, service_names=None, **options):
|
||||||
for service in self.services:
|
for service in self.get_services(service_names):
|
||||||
service.start(**options)
|
service.start(**options)
|
||||||
|
|
||||||
def stop(self, **options):
|
def stop(self, service_names=None, **options):
|
||||||
for service in self.services:
|
for service in self.get_services(service_names):
|
||||||
service.stop(**options)
|
service.stop(**options)
|
||||||
|
|
||||||
def kill(self, **options):
|
def kill(self, service_names=None, **options):
|
||||||
for service in self.services:
|
for service in self.get_services(service_names):
|
||||||
service.kill(**options)
|
service.kill(**options)
|
||||||
|
|
||||||
def remove_stopped(self, **options):
|
def remove_stopped(self, service_names=None, **options):
|
||||||
for service in self.services:
|
for service in self.get_services(service_names):
|
||||||
service.remove_stopped(**options)
|
service.remove_stopped(**options)
|
||||||
|
|
||||||
def containers(self, *args, **kwargs):
|
def containers(self, service_names=None, *args, **kwargs):
|
||||||
l = []
|
l = []
|
||||||
for service in self.services:
|
for service in self.get_services(service_names):
|
||||||
for container in service.containers(*args, **kwargs):
|
for container in service.containers(*args, **kwargs):
|
||||||
l.append(container)
|
l.append(container)
|
||||||
return l
|
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)
|
project = Project('test', [web], self.client)
|
||||||
self.assertEqual(project.get_service('web'), web)
|
self.assertEqual(project.get_service('web'), web)
|
||||||
|
|
||||||
def test_up(self):
|
def test_create_containers(self):
|
||||||
web = self.create_service('web')
|
web = self.create_service('web')
|
||||||
db = self.create_service('db')
|
db = self.create_service('db')
|
||||||
project = Project('test', [web, db], self.client)
|
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()
|
web.create_container()
|
||||||
|
|
||||||
self.assertEqual(len(web.containers()), 0)
|
self.assertEqual(len(web.containers()), 0)
|
||||||
@ -54,7 +73,7 @@ class ProjectTest(DockerClientTestCase):
|
|||||||
self.assertEqual(len(web.containers(stopped=True)), 1)
|
self.assertEqual(len(web.containers(stopped=True)), 1)
|
||||||
self.assertEqual(len(db.containers(stopped=True)), 0)
|
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(len(unstarted), 2)
|
||||||
self.assertEqual(unstarted[0][0], web)
|
self.assertEqual(unstarted[0][0], web)
|
||||||
self.assertEqual(unstarted[1][0], db)
|
self.assertEqual(unstarted[1][0], db)
|
||||||
@ -71,7 +90,7 @@ class ProjectTest(DockerClientTestCase):
|
|||||||
self.assertEqual(len(web.containers(stopped=True)), 1)
|
self.assertEqual(len(web.containers(stopped=True)), 1)
|
||||||
self.assertEqual(len(db.containers(stopped=True)), 0)
|
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')
|
web = self.create_service('web')
|
||||||
db = self.create_service('db')
|
db = self.create_service('db')
|
||||||
project = Project('test', [web, db], self.client)
|
project = Project('test', [web, db], self.client)
|
||||||
@ -81,13 +100,25 @@ class ProjectTest(DockerClientTestCase):
|
|||||||
self.assertEqual(len(web.containers()), 0)
|
self.assertEqual(len(web.containers()), 0)
|
||||||
self.assertEqual(len(db.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()
|
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)
|
project.stop(service_names=['web'], timeout=1)
|
||||||
self.assertEqual(len(db.containers()), 0)
|
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)
|
project.remove_stopped(service_names=['web'])
|
||||||
self.assertEqual(len(db.containers()), 0)
|
self.assertEqual(len(project.containers(stopped=True)), 1)
|
||||||
|
|
||||||
|
project.remove_stopped()
|
||||||
|
self.assertEqual(len(project.containers(stopped=True)), 0)
|
||||||
|
Loading…
x
Reference in New Issue
Block a user