58 lines
1.8 KiB
Python
58 lines
1.8 KiB
Python
import logging
|
|
from pathlib import Path
|
|
|
|
import docker
|
|
from docker.models.containers import Container
|
|
from injectable import injectable
|
|
|
|
from app.model.containers import Tree, Compose, SimpleContainer
|
|
|
|
logger = logging.getLogger(__name__)
|
|
|
|
|
|
@injectable(singleton=True)
|
|
class DockerService:
|
|
def __init__(self):
|
|
self._client = docker.from_env()
|
|
# logger.info(f"Docker client initialized. Plugins: {self._client.plugins()}")
|
|
self._tree = self._init_tree()
|
|
|
|
def _init_tree(self) -> Tree:
|
|
tree = Tree()
|
|
container: Container
|
|
for container in self._client.containers.list():
|
|
labels = container.labels
|
|
working_dir = labels.get("com.docker.compose.project.working_dir")
|
|
if working_dir:
|
|
if tree.composes.get(working_dir) is None:
|
|
tree.composes[working_dir] = Compose(working_dir)
|
|
tree.composes[working_dir].containers.append(SimpleContainer.from_container(container))
|
|
else:
|
|
tree.containers.append(SimpleContainer.from_container(container))
|
|
return tree
|
|
|
|
@property
|
|
def tree(self) -> Tree:
|
|
return self._tree
|
|
|
|
def reload(self, compose_path: Path):
|
|
cmd = ["sudo", "docker", "compose", "-f", str(compose_path), "up", "-d"]
|
|
import subprocess
|
|
try:
|
|
process = subprocess.run(
|
|
cmd,
|
|
capture_output=True,
|
|
text=True,
|
|
check=False
|
|
)
|
|
if process.returncode != 0:
|
|
logger.error(f"Docker compose failed with code {process.returncode}")
|
|
logger.error(f"stderr: {process.stderr}")
|
|
raise Exception(f"Docker compose failed: {process.stderr}")
|
|
|
|
logger.info(f"Docker compose executed successfully")
|
|
logger.debug(f"stdout: {process.stdout}")
|
|
return process.stdout, process.stderr, process.returncode
|
|
except Exception as e:
|
|
logger.error(f"Failed to execute docker compose command: {e}")
|
|
raise e
|