Compare commits
1 commit
main
...
renovate/c
Author | SHA1 | Date | |
---|---|---|---|
f5cc969f93 |
5 changed files with 17 additions and 66 deletions
6
.renovaterc.json
Normal file
6
.renovaterc.json
Normal file
|
@ -0,0 +1,6 @@
|
||||||
|
{
|
||||||
|
"$schema": "https://docs.renovatebot.com/renovate-schema.json",
|
||||||
|
"extends": [
|
||||||
|
"local>infrastructure/renovate-config"
|
||||||
|
]
|
||||||
|
}
|
44
README.md
44
README.md
|
@ -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`
|
||||||
|
|
|
@ -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
11
dc-ops
|
@ -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
|
||||||
|
|
|
@ -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
|
||||||
|
|
Loading…
Reference in a new issue