Compare commits

..

1 commit

Author SHA1 Message Date
f5cc969f93 chore: add .renovaterc.json 2023-12-22 02:01:31 +00:00
5 changed files with 17 additions and 66 deletions

6
.renovaterc.json Normal file
View file

@ -0,0 +1,6 @@
{
"$schema": "https://docs.renovatebot.com/renovate-schema.json",
"extends": [
"local>infrastructure/renovate-config"
]
}

View file

@ -18,50 +18,6 @@ See `requirements.txt`
2. Adapt `config.yml.example` to your needs and save it as `config.yml` 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 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)
### 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 ## Parameters
See `dc-ops --help` See `dc-ops --help`

View file

@ -1,4 +1,3 @@
self-update: true # optional
loglevdel: "INFO" # optional loglevdel: "INFO" # optional
compose-opts: "--dry-run" compose-opts: "--dry-run"
stacks: stacks:

11
dc-ops
View file

@ -5,8 +5,6 @@
# CC-BY-SA (https://creativecommons.org/licenses/by-sa/4.0/deed.de) # CC-BY-SA (https://creativecommons.org/licenses/by-sa/4.0/deed.de)
# for civil use only # for civil use only
# pylint: disable=missing-module-docstring,invalid-name
import argparse import argparse
import logging as log import logging as log
from pathlib import Path from pathlib import Path
@ -17,12 +15,12 @@ from lib.helper import run_subprocess, update_git_repo, do_selfupdate
# read config file # read config file
configfile = Path(__file__).with_name("config.yml") configfile = Path(__file__).with_name("config.yml")
with configfile.open("r", encoding="utf-8") as f: with configfile.open("r") as f:
cfg = yaml.safe_load(f.read()) cfg = yaml.safe_load(f.read())
# fmt: off # fmt: off
parser = argparse.ArgumentParser() parser = argparse.ArgumentParser()
parser.add_argument("--ignore-git-status", action="store_true", help="continue even if there are no new commits") parser.add_argument("--ignore-git-status", action="store_true", help="continue even if there are no new commits") # noqa
parser.add_argument("--loglevel", help="set loglevel (overrides config file)") parser.add_argument("--loglevel", help="set loglevel (overrides config file)")
args = parser.parse_args() args = parser.parse_args()
# fmt: on # fmt: on
@ -49,7 +47,7 @@ for stack in cfg["stacks"]:
# header # header
stackdir = stack["dir"] stackdir = stack["dir"]
log.info("processing: %s", stackdir) log.info(f"* processing {stackdir}")
# update repo and check for new commits # update repo and check for new commits
if not update_git_repo(stackdir, args.ignore_git_status): if not update_git_repo(stackdir, args.ignore_git_status):
@ -57,7 +55,6 @@ for stack in cfg["stacks"]:
# run pre-command # run pre-command
if "pre" in stack: if "pre" in stack:
log.info("-> executing pre-command")
if not run_subprocess(stack["pre"], stackdir): if not run_subprocess(stack["pre"], stackdir):
continue continue
@ -65,7 +62,6 @@ for stack in cfg["stacks"]:
# (or just for the directory if no compose-file defined) # (or just for the directory if no compose-file defined)
composefiles = stack.get("compose-files", ["docker-compose.yml"]) composefiles = stack.get("compose-files", ["docker-compose.yml"])
for composefile in composefiles: for composefile in composefiles:
log.info("-> bringing up %s", composefile)
if not run_subprocess( if not run_subprocess(
f"docker compose --file {composefile} up --detach {composeopts}", f"docker compose --file {composefile} up --detach {composeopts}",
stackdir, stackdir,
@ -74,6 +70,5 @@ for stack in cfg["stacks"]:
# run post-command # run post-command
if "post" in stack: if "post" in stack:
log.info("-> executing post-command")
if not run_subprocess(stack["post"], stackdir): if not run_subprocess(stack["post"], stackdir):
continue continue

View file

@ -1,5 +1,3 @@
# pylint: disable=missing-module-docstring
import logging as log import logging as log
import subprocess import subprocess
import sys import sys
@ -18,9 +16,9 @@ def do_selfupdate():
log.error(str(e)) log.error(str(e))
return return
if pull_res.old_commit: if pull_res.old_commit:
log.info("SelfUpdate: successfully updated myself - exiting") log.info("selfupdate: successfully updated myself - exiting")
sys.exit(0) 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: def run_subprocess(command: str, workdir: str) -> bool:
@ -34,9 +32,7 @@ def run_subprocess(command: str, workdir: str) -> bool:
bool: False if subprocess fails bool: False if subprocess fails
""" """
try: try:
log.debug( log.debug(subprocess.run(command.split(" "), cwd=workdir, text=True))
subprocess.run(command.split(" "), cwd=workdir, text=True, check=False)
)
except subprocess.CalledProcessError: except subprocess.CalledProcessError:
return False return False
@ -53,12 +49,11 @@ def update_git_repo(repo_path: str, ignore_git_status: bool) -> bool:
Returns: Returns:
bool: False if any step fails bool: False if any step fails
""" """
# create repo instance if it exists # create repo instance if it exists
try: try:
repo = git.Repo(repo_path) repo = git.Repo(repo_path)
except git.exc.NoSuchPathError: except git.exc.NoSuchPathError:
log.error("-> directory not found") log.error("directory not found")
return False return False
if not ignore_git_status: if not ignore_git_status:
@ -66,19 +61,19 @@ def update_git_repo(repo_path: str, ignore_git_status: bool) -> bool:
try: try:
fetch_res = repo.remotes.origin.fetch()[0] fetch_res = repo.remotes.origin.fetch()[0]
except git.exc.GitCommandError as e: except git.exc.GitCommandError as e:
log.error("-> %s ", str(e)) log.error(str(e))
return False return False
# check for new commits # check for new commits
if not fetch_res.old_commit: if not fetch_res.old_commit:
log.info("-> no changes - skipping") log.info("no changes - skipping")
return False return False
# pull remote changes to local branch # pull remote changes to local branch
try: try:
log.info("-> %s", repo.git.pull()) log.info(repo.git.pull())
except git.exc.GitCommandError as e: except git.exc.GitCommandError as e:
log.error("-> %s", str(e)) log.error(str(e))
return False return False
return True return True