Merge pull request #1710 from mnowster/improve-output-for-parallel-executions

Improve output for parallel command
This commit is contained in:
Aanand Prasad 2015-07-20 11:49:37 +01:00
commit 05d8daa8e0

View File

@ -1,8 +1,11 @@
import codecs
import hashlib import hashlib
import json import json
import logging import logging
import os import os
import sys
from docker.errors import APIError
import concurrent.futures import concurrent.futures
from .const import DEFAULT_MAX_WORKERS from .const import DEFAULT_MAX_WORKERS
@ -16,10 +19,18 @@ def parallel_execute(command, containers, doing_msg, done_msg, **options):
Execute a given command upon a list of containers in parallel. Execute a given command upon a list of containers in parallel.
""" """
max_workers = os.environ.get('COMPOSE_MAX_WORKERS', DEFAULT_MAX_WORKERS) max_workers = os.environ.get('COMPOSE_MAX_WORKERS', DEFAULT_MAX_WORKERS)
stream = codecs.getwriter('utf-8')(sys.stdout)
lines = []
errors = {}
for container in containers:
write_out_msg(stream, lines, container.name, doing_msg)
def container_command_execute(container, command, **options): def container_command_execute(container, command, **options):
log.info("{} {}...".format(doing_msg, container.name)) try:
return getattr(container, command)(**options) getattr(container, command)(**options)
except APIError as e:
errors[container.name] = e.explanation
with concurrent.futures.ThreadPoolExecutor(max_workers=max_workers) as executor: with concurrent.futures.ThreadPoolExecutor(max_workers=max_workers) as executor:
future_container = { future_container = {
@ -33,7 +44,34 @@ def parallel_execute(command, containers, doing_msg, done_msg, **options):
for future in concurrent.futures.as_completed(future_container): for future in concurrent.futures.as_completed(future_container):
container = future_container[future] container = future_container[future]
log.info("{} {}".format(done_msg, container.name)) write_out_msg(stream, lines, container.name, done_msg)
if errors:
for container in errors:
stream.write("ERROR: for {} {} \n".format(container, errors[container]))
def write_out_msg(stream, lines, container_name, msg):
"""
Using special ANSI code characters we can write out the msg over the top of
a previous status message, if it exists.
"""
if container_name in lines:
position = lines.index(container_name)
diff = len(lines) - position
# move up
stream.write("%c[%dA" % (27, diff))
# erase
stream.write("%c[2K\r" % 27)
stream.write("{}: {} \n".format(container_name, msg))
# move back down
stream.write("%c[%dB" % (27, diff))
else:
diff = 0
lines.append(container_name)
stream.write("{}: {}... \r\n".format(container_name, msg))
stream.flush()
def json_hash(obj): def json_hash(obj):