Page MenuHomeDevCentral

roles/paas-docker/docker/files/resolve-containers-from-compose.py

Authored By
dereckson
Apr 11 2022, 17:13
Size
3 KB
Referenced Files
None
Subscribers
None

roles/paas-docker/docker/files/resolve-containers-from-compose.py

#!/usr/bin/env python3
# -------------------------------------------------------------
# Resolve docker-compose containers names
# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
# Project: Nasqueron
# Description: Guess by naive heuristics the containers
# run from a docker-compose YAML configuration.
#
# As Docker doesn't record any link between
# a docker compose or stack information and the
# running containers, the approach consist to
# compare the containers names in a config file,
# with the running containers on the machine.
# License: BSD-2-Clause
# -------------------------------------------------------------
import subprocess
import sys
import yaml
# -------------------------------------------------------------
# Parse docker-compose.yml
# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
def parse_compose_config(config_path):
with open(config_path) as fd:
return yaml.safe_load(fd)
def resolve_container_prefix(service, image):
image_short = image.split("/")[1]
return image_short + "_" + service + "_"
def resolve_containers_prefix(compose_config):
return [
resolve_container_prefix(name, args["image"])
for name, args in compose_config["services"].items()
]
# -------------------------------------------------------------
# Interact with Docker CLI
#
# This avoid to have to deal with version conflicts with docker
# Python libraries.
# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
def get_running_container_names():
# TODO: avoid to invoke shell and spawn only the docker process
process = subprocess.run(
"docker ps | awk 'NR!=1 {print $NF}'", capture_output=True, shell=True
)
if process.returncode != 0:
raise RuntimeError("Can't get containers: " + process.stderr.decode().strip())
return process.stdout.decode().strip().split("\n")
# -------------------------------------------------------------
# Cross config file and running Docker information
# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
def is_container_name_match(config_container, running_container):
# The service web for the image acme/foo is foo_web_1:
# <image name>_<service name>_<number>
n = len(config_container)
return (
running_container.startswith(config_container)
and running_container[n:].isnumeric()
)
def resolve_docker_compose_containers_name(config_path):
config = parse_compose_config(config_path)
config_containers = resolve_containers_prefix(config)
running_containers = get_running_container_names()
return [
running_container
for config_container in config_containers
for running_container in running_containers
if is_container_name_match(config_container, running_container)
]
# -------------------------------------------------------------
# Application entry point
# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
def run(config_path):
containers = resolve_docker_compose_containers_name(config_path)
print(" ".join(containers))
if __name__ == "__main__":
argc = len(sys.argv)
if argc < 2:
print(f"Usage: {sys.argv[0]} <path to docker-compose.yml>", file=sys.stderr)
sys.exit(1)
run(sys.argv[1])

File Metadata

Mime Type
text/plain; charset=utf-8
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
1005136
Default Alt Text
roles/paas-docker/docker/files/resolve-containers-from-compose.py (3 KB)

Event Timeline