This commit is contained in:
arkhan 2025-07-09 17:18:31 -05:00 committed by GitHub
commit 176ed6fdd5
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
1 changed files with 165 additions and 25 deletions

View File

@ -3204,7 +3204,22 @@ async def compose_up(compose: PodmanCompose, args: argparse.Namespace) -> int |
max_service_length = 0
for cnt in compose.containers:
curr_length = len(cnt["_service"])
if cnt["_service"] in excluded:
continue
service_name = cnt["_service"]
container_name = cnt["name"]
if getattr(args, 'names', False):
expected_name = compose.format_name(service_name, str(cnt["num"]))
if container_name == expected_name:
display_name = compose.join_name_parts(service_name, str(cnt["num"]))
else:
display_name = container_name
else:
display_name = container_name
curr_length = len(display_name)
max_service_length = curr_length if curr_length > max_service_length else max_service_length
tasks: set[asyncio.Task] = set()
@ -3226,11 +3241,24 @@ async def compose_up(compose: PodmanCompose, args: argparse.Namespace) -> int |
loop.add_signal_handler(signal.SIGINT, lambda: asyncio.create_task(handle_sigint()))
for i, cnt in enumerate(compose.containers):
# Add colored service prefix to output by piping output through sed
color_idx = i % len(compose.console_colors)
color = compose.console_colors[color_idx]
space_suffix = " " * (max_service_length - len(cnt["_service"]) + 1)
log_formatter = "{}[{}]{}|\x1b[0m".format(color, cnt["_service"], space_suffix)
service_name = cnt["_service"]
container_name = cnt["name"]
if getattr(args, 'names', False):
expected_name = compose.format_name(service_name, str(cnt["num"]))
if container_name == expected_name:
display_name = compose.join_name_parts(service_name, str(cnt["num"]))
else:
display_name = container_name
else:
display_name = container_name
space_suffix = " " * (max_service_length + 1 - len(display_name))
log_formatter = "{}{}{}|\x1b[0m".format(color, display_name, space_suffix)
if cnt["_service"] in excluded:
log.debug("** skipping: %s", cnt["name"])
continue
@ -3585,29 +3613,135 @@ async def compose_logs(compose: PodmanCompose, args: argparse.Namespace) -> None
if not args.services and not args.latest:
args.services = container_names_by_service.keys()
compose.assert_services(args.services)
targets = []
service_by_container = {}
for service in args.services:
targets.extend(container_names_by_service[service])
podman_args = []
if args.follow:
podman_args.append("-f")
if args.latest:
podman_args.append("-l")
if args.names:
podman_args.append("-n")
if args.since:
podman_args.extend(["--since", args.since])
# the default value is to print all logs which is in podman = 0 and not
# needed to be passed
if args.tail and args.tail != "all":
podman_args.extend(["--tail", args.tail])
if args.timestamps:
podman_args.append("-t")
if args.until:
podman_args.extend(["--until", args.until])
for target in targets:
podman_args.append(target)
await compose.podman.run([], "logs", podman_args)
containers = container_names_by_service[service]
targets.extend(containers)
for container in containers:
service_by_container[container] = service
should_use_colors = (
(len(args.services) > 1 or args.names)
and not args.latest
and sys.stdout.isatty()
and not getattr(args, "no_color", False)
)
if should_use_colors:
max_service_length = 0
for target in targets:
cnt = compose.container_by_name[target]
service_name = cnt["_service"]
container_name = cnt["name"]
if getattr(args, 'names', False):
expected_name = compose.format_name(service_name, str(cnt["num"]))
if container_name == expected_name:
display_name = compose.join_name_parts(service_name, str(cnt["num"]))
else:
display_name = container_name
else:
display_name = container_name
curr_length = len(display_name)
max_service_length = (
curr_length if curr_length > max_service_length else max_service_length
)
tasks = []
service_colors: dict[str, str] = {}
for target in targets:
cnt = compose.container_by_name[target]
service_name = cnt["_service"]
container_name = cnt["name"]
if getattr(args, 'names', False):
expected_name = compose.format_name(service_name, str(cnt["num"]))
if container_name == expected_name:
display_name = compose.join_name_parts(service_name, str(cnt["num"]))
else:
display_name = container_name
else:
display_name = container_name
if service_name not in service_colors:
color_idx = len(service_colors) % len(compose.console_colors)
service_colors[service_name] = compose.console_colors[color_idx]
color = service_colors[service_name]
space_suffix = " " * (max_service_length + 1 - len(display_name))
log_formatter = "{}{}{}|\x1b[0m".format(color, display_name, space_suffix)
podman_args = []
if args.follow:
podman_args.append("-f")
if args.names:
podman_args.append("-n")
if args.since:
podman_args.extend(["--since", args.since])
if args.tail and args.tail != "all":
podman_args.extend(["--tail", args.tail])
if args.timestamps:
podman_args.append("-t")
if args.until:
podman_args.extend(["--until", args.until])
podman_args.append(target)
task = asyncio.create_task(
compose.podman.run([], "logs", podman_args, log_formatter=log_formatter),
name=f"logs-{service_name}-{target}",
)
tasks.append(task)
async def handle_sigint() -> None:
log.info("Caught SIGINT or Ctrl+C, stopping log streaming...")
for task in tasks:
if not task.done():
task.cancel()
if sys.platform != 'win32':
loop = asyncio.get_event_loop()
loop.add_signal_handler(signal.SIGINT, lambda: asyncio.create_task(handle_sigint()))
try:
await asyncio.gather(*tasks)
except KeyboardInterrupt:
for task in tasks:
if not task.done():
task.cancel()
await asyncio.gather(*tasks, return_exceptions=True)
except Exception as e:
log.error("Error in logs command: %s", e)
for task in tasks:
if not task.done():
task.cancel()
await asyncio.gather(*tasks, return_exceptions=True)
raise
else:
podman_args = []
if args.follow:
podman_args.append("-f")
if args.latest:
podman_args.append("-l")
if args.names:
podman_args.append("-n")
if args.since:
podman_args.extend(["--since", args.since])
if args.tail and args.tail != "all":
podman_args.extend(["--tail", args.tail])
if args.timestamps:
podman_args.append("-t")
if args.until:
podman_args.extend(["--until", args.until])
for target in targets:
podman_args.append(target)
await compose.podman.run([], "logs", podman_args)
@cmd_run(podman_compose, "config", "displays the compose file")
@ -3866,6 +4000,12 @@ def compose_up_parse(parser: argparse.ArgumentParser) -> None:
help="Return the exit code of the selected service container. "
"Implies --abort-on-container-exit.",
)
parser.add_argument(
"-n",
"--names",
action="store_true",
help="Show short service names instead of full container names in logs",
)
@cmd_parse(podman_compose, "down")