From f5cc969f93dd52d436380aa3909fff17dbd399d2 Mon Sep 17 00:00:00 2001 From: Renovate Bot <renovate@smsvc.net> Date: Fri, 22 Dec 2023 02:01:31 +0000 Subject: [PATCH 1/6] chore: add .renovaterc.json --- .renovaterc.json | 6 ++++++ 1 file changed, 6 insertions(+) create mode 100644 .renovaterc.json diff --git a/.renovaterc.json b/.renovaterc.json new file mode 100644 index 0000000..ff27ef5 --- /dev/null +++ b/.renovaterc.json @@ -0,0 +1,6 @@ +{ + "$schema": "https://docs.renovatebot.com/renovate-schema.json", + "extends": [ + "local>infrastructure/renovate-config" + ] +} From 3bf7fc225528d705b9655f5e6c3fa00b251bbc17 Mon Sep 17 00:00:00 2001 From: Sebastian Mark <smark@posteo.net> Date: Fri, 22 Dec 2023 22:22:02 +0100 Subject: [PATCH 2/6] feat: enhance logging - remove `*` from stack log entry - prefix log messages with arrow symbol for better readability --- dc-ops | 5 ++++- lib/helper.py | 15 ++++++++------- 2 files changed, 12 insertions(+), 8 deletions(-) diff --git a/dc-ops b/dc-ops index 965bda1..2651f96 100755 --- a/dc-ops +++ b/dc-ops @@ -47,7 +47,7 @@ for stack in cfg["stacks"]: # header stackdir = stack["dir"] - log.info(f"* processing {stackdir}") + log.info(f"processing: {stackdir}") # update repo and check for new commits if not update_git_repo(stackdir, args.ignore_git_status): @@ -55,6 +55,7 @@ for stack in cfg["stacks"]: # run pre-command if "pre" in stack: + log.info("-> executing pre-command") if not run_subprocess(stack["pre"], stackdir): continue @@ -62,6 +63,7 @@ for stack in cfg["stacks"]: # (or just for the directory if no compose-file defined) composefiles = stack.get("compose-files", ["docker-compose.yml"]) for composefile in composefiles: + log.info(f"-> bringing up {composefile}") if not run_subprocess( f"docker compose --file {composefile} up --detach {composeopts}", stackdir, @@ -70,5 +72,6 @@ for stack in cfg["stacks"]: # run post-command if "post" in stack: + log.info("-> executing post-command") if not run_subprocess(stack["post"], stackdir): continue diff --git a/lib/helper.py b/lib/helper.py index 9eae836..2bb56d5 100644 --- a/lib/helper.py +++ b/lib/helper.py @@ -16,9 +16,9 @@ def do_selfupdate(): log.error(str(e)) return if pull_res.old_commit: - log.info("selfupdate: successfully updated myself - exiting") + log.info("SelfUpdate: successfully updated myself - exiting") sys.exit(0) - log.info("selfupdate: no updates found for myself") + log.info("SelfUpdate: no updates found for myself") def run_subprocess(command: str, workdir: str) -> bool: @@ -49,11 +49,12 @@ def update_git_repo(repo_path: str, ignore_git_status: bool) -> bool: Returns: bool: False if any step fails """ + # create repo instance if it exists try: repo = git.Repo(repo_path) except git.exc.NoSuchPathError: - log.error("directory not found") + log.error("-> directory not found") return False if not ignore_git_status: @@ -61,19 +62,19 @@ def update_git_repo(repo_path: str, ignore_git_status: bool) -> bool: try: fetch_res = repo.remotes.origin.fetch()[0] except git.exc.GitCommandError as e: - log.error(str(e)) + log.error("-> " + str(e)) return False # check for new commits if not fetch_res.old_commit: - log.info("no changes - skipping") + log.info("-> no changes - skipping") return False # pull remote changes to local branch try: - log.info(repo.git.pull()) + log.info("-> " + repo.git.pull()) except git.exc.GitCommandError as e: - log.error(str(e)) + log.error("-> " + str(e)) return False return True From 3d52b214425b636b7cf508fdbb2e47c3a54b67b6 Mon Sep 17 00:00:00 2001 From: Sebastian Mark <smark@posteo.net> Date: Fri, 5 Jan 2024 22:13:36 +0100 Subject: [PATCH 3/6] doc: update README with cronjob instructions MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - add section about recommended crontab usage - provide example of how to set up cron job for dc-ops - remind users to set up logrotate for the log file 🤖 --- README.md | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/README.md b/README.md index 8803808..1c879b2 100644 --- a/README.md +++ b/README.md @@ -18,6 +18,14 @@ See `requirements.txt` 2. Adapt `config.yml.example` to your needs and save it as `config.yml` 3. Run `dc-ops` from the shell or from a cron job +### Cron + +Recommended crontab usage: + +`*/15 * * * * python3 /opt/dc-ops/dc-ops 2>&1 | ts "\%FT\%H:\%M:\%S" >>/var/log/dc-ops.log` + +(do not forget logrotate) + ## Parameters See `dc-ops --help` From 260ab2ba227e2c800f630891b84f70825b7882bc Mon Sep 17 00:00:00 2001 From: Sebastian Mark <smark@posteo.net> Date: Mon, 10 Jun 2024 12:09:05 +0200 Subject: [PATCH 4/6] chore: fix pylint complains --- dc-ops | 10 ++++++---- lib/helper.py | 12 ++++++++---- 2 files changed, 14 insertions(+), 8 deletions(-) diff --git a/dc-ops b/dc-ops index 2651f96..311fe48 100755 --- a/dc-ops +++ b/dc-ops @@ -5,6 +5,8 @@ # CC-BY-SA (https://creativecommons.org/licenses/by-sa/4.0/deed.de) # for civil use only +# pylint: disable=missing-module-docstring,invalid-name + import argparse import logging as log from pathlib import Path @@ -15,12 +17,12 @@ from lib.helper import run_subprocess, update_git_repo, do_selfupdate # read config file configfile = Path(__file__).with_name("config.yml") -with configfile.open("r") as f: +with configfile.open("r", encoding="utf-8") as f: cfg = yaml.safe_load(f.read()) # fmt: off parser = argparse.ArgumentParser() -parser.add_argument("--ignore-git-status", action="store_true", help="continue even if there are no new commits") # noqa +parser.add_argument("--ignore-git-status", action="store_true", help="continue even if there are no new commits") parser.add_argument("--loglevel", help="set loglevel (overrides config file)") args = parser.parse_args() # fmt: on @@ -47,7 +49,7 @@ for stack in cfg["stacks"]: # header stackdir = stack["dir"] - log.info(f"processing: {stackdir}") + log.info("processing: %s", stackdir) # update repo and check for new commits if not update_git_repo(stackdir, args.ignore_git_status): @@ -63,7 +65,7 @@ for stack in cfg["stacks"]: # (or just for the directory if no compose-file defined) composefiles = stack.get("compose-files", ["docker-compose.yml"]) for composefile in composefiles: - log.info(f"-> bringing up {composefile}") + log.info("-> bringing up %s", composefile) if not run_subprocess( f"docker compose --file {composefile} up --detach {composeopts}", stackdir, diff --git a/lib/helper.py b/lib/helper.py index 2bb56d5..1fbe286 100644 --- a/lib/helper.py +++ b/lib/helper.py @@ -1,3 +1,5 @@ +# pylint: disable=missing-module-docstring + import logging as log import subprocess import sys @@ -32,7 +34,9 @@ def run_subprocess(command: str, workdir: str) -> bool: bool: False if subprocess fails """ try: - log.debug(subprocess.run(command.split(" "), cwd=workdir, text=True)) + log.debug( + subprocess.run(command.split(" "), cwd=workdir, text=True, check=False) + ) except subprocess.CalledProcessError: return False @@ -62,7 +66,7 @@ def update_git_repo(repo_path: str, ignore_git_status: bool) -> bool: try: fetch_res = repo.remotes.origin.fetch()[0] except git.exc.GitCommandError as e: - log.error("-> " + str(e)) + log.error("-> %s ", str(e)) return False # check for new commits @@ -72,9 +76,9 @@ def update_git_repo(repo_path: str, ignore_git_status: bool) -> bool: # pull remote changes to local branch try: - log.info("-> " + repo.git.pull()) + log.info("-> %s", repo.git.pull()) except git.exc.GitCommandError as e: - log.error("-> " + str(e)) + log.error("-> %s", str(e)) return False return True From 421e33e874f9ac7c758915b8531be03a94cc162c Mon Sep 17 00:00:00 2001 From: Sebastian Mark <smark@posteo.net> Date: Sun, 1 Sep 2024 19:44:35 +0200 Subject: [PATCH 5/6] feat: update example config file MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - add self-update option 🤖 --- config.yml.example | 1 + 1 file changed, 1 insertion(+) diff --git a/config.yml.example b/config.yml.example index a277ca8..af277e7 100644 --- a/config.yml.example +++ b/config.yml.example @@ -1,3 +1,4 @@ +self-update: true # optional loglevdel: "INFO" # optional compose-opts: "--dry-run" stacks: From a2d4a65466791b597ad75461efe4637587a468a8 Mon Sep 17 00:00:00 2001 From: Sebastian Mark <smark@posteo.net> Date: Sun, 1 Sep 2024 20:16:09 +0200 Subject: [PATCH 6/6] doc: add systemd timer and service example --- README.md | 36 ++++++++++++++++++++++++++++++++++++ 1 file changed, 36 insertions(+) diff --git a/README.md b/README.md index 1c879b2..f64716e 100644 --- a/README.md +++ b/README.md @@ -26,6 +26,42 @@ Recommended crontab usage: (do not forget logrotate) +### Systemd + +Recommended systemd usage: + +```toml +# /etc/systemd/system/dc-ops.service +[Unit] +Description=Run dc-ops once +After=docker.target + +[Service] +Type=simple +WorkingDirectory=/opt/dc-ops/ +ExecStart=python3 dc-ops +``` + +```toml +# /etc/systemd/system/dc-ops.timer +[Unit] +Description=Start dc-ops service periodically + +[Timer] +Persistent=true +OnCalendar=*:0/15 +Unit=dc-ops.service + +[Install] +WantedBy=timers.target +``` + +Enable and start the timer: +``` +systemctl enable dc-ops.timer +systemctl start dc-ops.timer +``` + ## Parameters See `dc-ops --help`