From f6cb85c211fb9a311fac21a82d67807fd3f3b514 Mon Sep 17 00:00:00 2001 From: Clemens Klug Date: Wed, 10 Apr 2019 10:36:58 +0200 Subject: [PATCH] add pre/post exec hooks --- Readme.md | 4 ++++ discover.py | 12 +++++----- sample/http-prio/docker-compose.yml | 10 +++++++++ sample/http/docker-compose.yml | 9 ++++++++ sample/notify_telegram.sh | 7 ++++++ sample.json => sample/sample.json | 0 sample.lst => sample/sample.lst | 0 start.py | 34 +++++++++++++++++++++++------ 8 files changed, 62 insertions(+), 14 deletions(-) create mode 100644 sample/http-prio/docker-compose.yml create mode 100644 sample/http/docker-compose.yml create mode 100755 sample/notify_telegram.sh rename sample.json => sample/sample.json (100%) rename sample.lst => sample/sample.lst (100%) diff --git a/Readme.md b/Readme.md index 8b78304..21303eb 100644 --- a/Readme.md +++ b/Readme.md @@ -15,6 +15,10 @@ Examples: * check status `python3 discover.py -a ps /opt/docker/testing/` * stop services `python3 discover.py -a "down -v /srv/testing/` +### pre/post exec + +e.g. `python3 start.py test.lst -a ps --pre 'echo {path} {step}' --post './sample/notify_telegram.sh {path} {cmd} {returncode} \n {stdout}'` + ## manual config ### json config diff --git a/discover.py b/discover.py index 25b2f86..066ac07 100644 --- a/discover.py +++ b/discover.py @@ -1,11 +1,10 @@ -import argparse -import json import os -import subprocess import logging from collections import namedtuple +from start import base_args, change_service + log = logging.getLogger(__name__) COMPOSE_FILE = "docker-compose.yml" @@ -55,11 +54,10 @@ def find_autostart_services(services): if __name__ == "__main__": logging.basicConfig(format="%(message)s (status %(returncode)s)", level=logging.INFO) - parser = argparse.ArgumentParser(description="Docker-compose Autostart discovery") - parser.add_argument("service_dir", nargs="+") - parser.add_argument("--action", "-a", default="up -d") + parser = base_args("Docker-compose Autostart discovery") + parser.add_argument("service_dir", nargs="+", help="One or more directories containing docker-compose services, only direct subdirectories are scanned") parser.add_argument("--list", "-l", action="store_true", help="list autostart services only, no action") - parser.add_argument("--key", "-k", help="alternative label prefix") + parser.add_argument("--key", "-k", help=f"alternative label prefix, default: '{PREFIX}'") args = parser.parse_args() if args.key: diff --git a/sample/http-prio/docker-compose.yml b/sample/http-prio/docker-compose.yml new file mode 100644 index 0000000..f8da373 --- /dev/null +++ b/sample/http-prio/docker-compose.yml @@ -0,0 +1,10 @@ +version: "3" + +services: + http: + image: httpd:alpine + ports: + - "8080:80" + labels: + - "de.wie-ei.autostart=true" + - "de.wie-ei.autostart.priority=100" diff --git a/sample/http/docker-compose.yml b/sample/http/docker-compose.yml new file mode 100644 index 0000000..80be05a --- /dev/null +++ b/sample/http/docker-compose.yml @@ -0,0 +1,9 @@ +version: "3" + +services: + http: + image: httpd:alpine + ports: + - "8080:80" + labels: + - "de.wie-ei.autostart=true" \ No newline at end of file diff --git a/sample/notify_telegram.sh b/sample/notify_telegram.sh new file mode 100755 index 0000000..bdc4914 --- /dev/null +++ b/sample/notify_telegram.sh @@ -0,0 +1,7 @@ +#!/bin/bash +key="$1" +room="$2" +shift 2 +url="https://api.telegram.org/bot${key}/sendMessage" +json='{"chat_id":'${room}', "text":"'"$@"'"}' +curl "$url" --data "$json" -X POST -H 'Content-Type: application/json' \ No newline at end of file diff --git a/sample.json b/sample/sample.json similarity index 100% rename from sample.json rename to sample/sample.json diff --git a/sample.lst b/sample/sample.lst similarity index 100% rename from sample.lst rename to sample/sample.lst diff --git a/start.py b/start.py index 2772fc8..f6b7094 100644 --- a/start.py +++ b/start.py @@ -8,12 +8,26 @@ import sys log = logging.getLogger(__name__) -def change_service(path, action): +def change_service(path, action, pre_cmd=None, post_cmd=None): cmd = ["docker-compose"] + action.split() if path.endswith("/docker-compose.yml"): path = path[:-len("/docker-compose.yml")] - r = subprocess.run(cmd, cwd=path) + args = { + "args": cmd, + "cwd": path, + } + if post_cmd: + args["capture_output"] = True + args["text"] = True + if pre_cmd: + subprocess.run(pre_cmd.format(path=path, cmd=cmd, step="pre").split()) + r = subprocess.run(**args) log.info(f"processed {path}", extra={"path": path, "cmd": cmd, "returncode": r.returncode}) + if post_cmd: + if r.stdout: print(r.stdout) + if r.stderr: print(r.stderr, file=sys.stderr) + subprocess.run(post_cmd.format(path=path, cmd=cmd, step="post", returncode=r.returncode, stdout=r.stdout, stderr=r.stderr).split()) + print() def load_json(config_file): @@ -36,17 +50,23 @@ def get_loader(config_file): return load_stdin return load_raw -def apply(config_file, action): +def apply(config_file, action, pre=None, post=None): load = get_loader(config_file) for path in load(config_file): - change_service(path, action) + change_service(path, action, pre_cmd=pre, post_cmd=post) +def base_args(desc): + parser = argparse.ArgumentParser(description=desc) + parser.add_argument("--action", "-a", default="up -d", help="docker-compose action to apply, default: up -d") + parser.add_argument("--pre", "-s", help="pre-exec: command to run before each action") + parser.add_argument("--post", "-e", help="post-exec: command to run after each action") + return parser + if __name__ == "__main__": logging.basicConfig(format="%(message)s (status %(returncode)s)", level=logging.INFO) - parser = argparse.ArgumentParser(description="Docker-compose Autostart") + parser = base_args("Docker-compose Autostart") parser.add_argument("config_file", default="-", help="json file, plain text list or - for stdin") - parser.add_argument("--action", "-a", default="up -d", help="docker-compose action to apply, default: up -d") args = parser.parse_args() - apply(args.config_file, args.action) + apply(args.config_file, args.action, pre=args.pre, post=args.post)