65 lines
2.1 KiB
Python
65 lines
2.1 KiB
Python
from os import error
|
|
|
|
from yaml import dump
|
|
|
|
from playbook import models
|
|
from playbook.action_registry import ActionRegistry
|
|
from playbook.models import ContextChecker
|
|
from playbook.logging_models import StepLogModel
|
|
|
|
import sys
|
|
import json
|
|
import docker
|
|
import subprocess
|
|
|
|
|
|
dockeractions = ActionRegistry(name="docker_actions_reg")
|
|
|
|
|
|
@dockeractions.register(name="get_service_container_name", version="")
|
|
@ContextChecker.requires("service_name")
|
|
def get_service_container_name(ctx, name) -> StepLogModel:
|
|
client = docker.from_env()
|
|
|
|
filters: dict[str, object]= {
|
|
"label": [f"com.docker.compose.service={ctx["service_name"]}"]
|
|
}
|
|
containers = client.containers.list(filters=filters, all=True)
|
|
|
|
if not containers:
|
|
return StepLogModel.fail(name, [{
|
|
"status": "failed",
|
|
"output": f"no container found for service {ctx["service_name"]}"}
|
|
])
|
|
|
|
new_data = {"container": containers[0].id}
|
|
return StepLogModel.ok(name, f"found container {containers[0].id}", pipe_ctx=new_data)
|
|
|
|
|
|
@dockeractions.register(name="dump_container_pg_db", version="")
|
|
@ContextChecker.requires("container", "dump_path", "db_user", "database")
|
|
def dump_container_pg_db(ctx, name) -> StepLogModel:
|
|
client = docker.from_env()
|
|
container = client.containers.get(ctx["container"])
|
|
|
|
res = container.exec_run(
|
|
cmd=f"pg_dump -U {ctx["db_user"]} {ctx["database"]}",
|
|
stream=False, # change to True to stream directly to host file (need to check)
|
|
demux=True,
|
|
)
|
|
stdout, stderr = res.output
|
|
|
|
if stderr:
|
|
if not isinstance(stderr, bytes):
|
|
return StepLogModel.fail(name, [{"status": "failed", "output": "stderr is not bytes"}])
|
|
if res.exit_code != 0:
|
|
error_msg = stderr.decode("utf-8") if stderr else "dump failed with no output"
|
|
return StepLogModel.fail(name, [{"status": "failed", "output": error_msg}])
|
|
|
|
if not isinstance(stdout, bytes):
|
|
return StepLogModel.fail(name, [{"status": "failed", "output": "stdout is not bytes"}])
|
|
with open(ctx["dump_path"], "wb") as f:
|
|
f.write(stdout)
|
|
|
|
return StepLogModel.ok(name, "database dump successful")
|