mirror of
https://github.com/docker/docs.git
synced 2026-04-01 00:38:52 +07:00
Sometimes, some messages were being executed at the same time, meaning that the status wasn't being overwritten, it was displaying on a separate line for both doing and done messages. Rather than trying to have both sets of statuses being written out concurrently, we write out all of the doing messages first. Then the done messages are written out/updated, as they are completed. Signed-off-by: Mazz Mosley <mazz@houseofmnowster.com>
73 lines
2.0 KiB
Python
73 lines
2.0 KiB
Python
import codecs
|
|
import hashlib
|
|
import json
|
|
import logging
|
|
import os
|
|
import sys
|
|
|
|
import concurrent.futures
|
|
|
|
from .const import DEFAULT_MAX_WORKERS
|
|
|
|
|
|
log = logging.getLogger(__name__)
|
|
|
|
|
|
def parallel_execute(command, containers, doing_msg, done_msg, **options):
|
|
"""
|
|
Execute a given command upon a list of containers in parallel.
|
|
"""
|
|
max_workers = os.environ.get('COMPOSE_MAX_WORKERS', DEFAULT_MAX_WORKERS)
|
|
stream = codecs.getwriter('utf-8')(sys.stdout)
|
|
lines = []
|
|
|
|
for container in containers:
|
|
write_out_msg(stream, lines, container.name, doing_msg)
|
|
|
|
def container_command_execute(container, command, **options):
|
|
return getattr(container, command)(**options)
|
|
|
|
with concurrent.futures.ThreadPoolExecutor(max_workers=max_workers) as executor:
|
|
future_container = {
|
|
executor.submit(
|
|
container_command_execute,
|
|
container,
|
|
command,
|
|
**options
|
|
): container for container in containers
|
|
}
|
|
|
|
for future in concurrent.futures.as_completed(future_container):
|
|
container = future_container[future]
|
|
write_out_msg(stream, lines, container.name, done_msg)
|
|
|
|
|
|
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):
|
|
dump = json.dumps(obj, sort_keys=True, separators=(',', ':'))
|
|
h = hashlib.sha256()
|
|
h.update(dump)
|
|
return h.hexdigest()
|