Compare commits
13 Commits
a5c27f46ef
...
main
| Author | SHA1 | Date | |
|---|---|---|---|
| b8cf7dc166 | |||
| 2da91aa878 | |||
| 3c353d3608 | |||
| 266e7330be | |||
| e811f4961b | |||
| 40d207cd68 | |||
| 9f32fada4c | |||
| 66dad7b8a9 | |||
| f0612746c0 | |||
| 238d231a93 | |||
| 36d0735896 | |||
| 1daa8ee665 | |||
| bd3f9f38f0 |
@@ -0,0 +1 @@
|
|||||||
|
ARGS="--web.listen-address=\"[fd00:327:327:327::{{ node.metadata.get("clerie-monitoring/id") }}]:9100\""
|
||||||
@@ -0,0 +1,3 @@
|
|||||||
|
[Unit]
|
||||||
|
Requires=wg-quick@wg-monitoring.service
|
||||||
|
After=wg-quick@wg-monitoring.service
|
||||||
@@ -0,0 +1,9 @@
|
|||||||
|
[Interface]
|
||||||
|
PrivateKey = {{ node.metadata.get("clerie-monitoring/private-key") }}
|
||||||
|
Address = fd00:327:327:327::{{ node.metadata.get("clerie-monitoring/id") }}/64
|
||||||
|
|
||||||
|
[Peer]
|
||||||
|
Endpoint = [2001:638:904:ffca::7]:54523
|
||||||
|
PublicKey = eyhJKV41E1F0gZHBNqyzUnj72xg5f3bdDduVtpPN4AY=
|
||||||
|
AllowedIPS = fd00:327:327:327::/64
|
||||||
|
PersistentKeepalive = 25
|
||||||
46
bundles/debian-clerie-monitoring/items.py
Normal file
46
bundles/debian-clerie-monitoring/items.py
Normal file
@@ -0,0 +1,46 @@
|
|||||||
|
files = {
|
||||||
|
f"/etc/wireguard/wg-monitoring.conf": {
|
||||||
|
"source": "wg-monitoring.conf",
|
||||||
|
"content_type": "jinja2",
|
||||||
|
"triggers": [
|
||||||
|
"svc_systemd:wg-quick@wg-monitoring:restart",
|
||||||
|
],
|
||||||
|
"needs": [
|
||||||
|
"pkg_apt:wireguard",
|
||||||
|
],
|
||||||
|
},
|
||||||
|
f"/etc/default/prometheus-node-exporter": {
|
||||||
|
"source": "prometheus-node-exporter",
|
||||||
|
"content_type": "jinja2",
|
||||||
|
"triggers": [
|
||||||
|
"svc_systemd:prometheus-node-exporter:restart",
|
||||||
|
],
|
||||||
|
"needs": [
|
||||||
|
"pkg_apt:prometheus-node-exporter",
|
||||||
|
],
|
||||||
|
},
|
||||||
|
f"/etc/systemd/system/prometheus-node-exporter.d/override.conf": {
|
||||||
|
"source": "prometheus-node-exporter-override.conf",
|
||||||
|
"triggers": [
|
||||||
|
"action:systemd-daemon-reload",
|
||||||
|
],
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
pkg_apt = {
|
||||||
|
"wireguard": {},
|
||||||
|
"prometheus-node-exporter": {},
|
||||||
|
}
|
||||||
|
|
||||||
|
svc_systemd = {
|
||||||
|
"wg-quick@wg-monitoring": {
|
||||||
|
"needs": [
|
||||||
|
"file:/etc/wireguard/wg-monitoring.conf",
|
||||||
|
],
|
||||||
|
},
|
||||||
|
"prometheus-node-exporter": {
|
||||||
|
"needs": [
|
||||||
|
"file:/etc/systemd/system/prometheus-node-exporter.d/override.conf",
|
||||||
|
],
|
||||||
|
},
|
||||||
|
}
|
||||||
1
bundles/debian-user-clerie/files/sudoers-clerie
Normal file
1
bundles/debian-user-clerie/files/sudoers-clerie
Normal file
@@ -0,0 +1 @@
|
|||||||
|
clerie ALL=(ALL) NOPASSWD:ALL
|
||||||
34
bundles/debian-user-clerie/items.py
Normal file
34
bundles/debian-user-clerie/items.py
Normal file
@@ -0,0 +1,34 @@
|
|||||||
|
users = {
|
||||||
|
"clerie": {
|
||||||
|
"groups": [ "sudo" ],
|
||||||
|
"shell": "/bin/bash",
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
directories = {
|
||||||
|
"/home/clerie/.ssh": {
|
||||||
|
"mode": "0700",
|
||||||
|
"owner": "clerie",
|
||||||
|
"group": "clerie",
|
||||||
|
"needs": [
|
||||||
|
"user:clerie",
|
||||||
|
],
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
files = {
|
||||||
|
f'/home/clerie/.ssh/authorized_keys': {
|
||||||
|
"content_type": "download",
|
||||||
|
"source": "https://git.clerie.de/clerie/nixfiles/raw/commit/dd76691f7da3f860b25f770b65e602f90e1a1de8/users/clerie/ssh.pub",
|
||||||
|
"content_hash": "f37b63f98c5d4bd5292a81ce01dd7f6bc5e356fc",
|
||||||
|
"mode": "0700",
|
||||||
|
"owner": "clerie",
|
||||||
|
"group": "clerie",
|
||||||
|
"needs": [
|
||||||
|
"directory:/home/clerie/.ssh",
|
||||||
|
],
|
||||||
|
},
|
||||||
|
f'/etc/sudoers.d/sudoers-clerie': {
|
||||||
|
"source": "sudoers-clerie",
|
||||||
|
},
|
||||||
|
}
|
||||||
7
bundles/systemd/items.py
Normal file
7
bundles/systemd/items.py
Normal file
@@ -0,0 +1,7 @@
|
|||||||
|
actions['systemd-daemon-reload'] = {
|
||||||
|
'command': 'systemctl daemon-reload',
|
||||||
|
'triggered': True,
|
||||||
|
'needed_by': {
|
||||||
|
'svc_systemd:',
|
||||||
|
},
|
||||||
|
}
|
||||||
@@ -0,0 +1,6 @@
|
|||||||
|
#!/usr/bin/env bash
|
||||||
|
|
||||||
|
JOB_NAME="$1"
|
||||||
|
TARGET_NAME="$2"
|
||||||
|
|
||||||
|
echo "clerie_backup_last_successful_run_time{backup_job=\"${JOB_NAME}\", backup_target=\"${TARGET_NAME}\"} $(date +%s)" > "/home/{{ node.username }}/.local/state/prometheus-node-exporter/textfiles/clerie-backup-${JOB_NAME}-${TARGET_NAME}.prom"
|
||||||
@@ -38,6 +38,11 @@ files = uberspaceify.files({
|
|||||||
"action:install_restic",
|
"action:install_restic",
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
|
f'/home/{node.username}/bin/clerie-backup-update-monitoring': {
|
||||||
|
"source": "clerie-backup-update-monitoring.sh",
|
||||||
|
"content_type": "jinja2",
|
||||||
|
"mode": "0700",
|
||||||
|
},
|
||||||
**repo_config_files,
|
**repo_config_files,
|
||||||
})
|
})
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,2 @@
|
|||||||
|
basic_auth_users:
|
||||||
|
monitor: "$2y$05$b4TibqWAj3MDv3g.SCaPZe9r6jV8Vowvn/CBZOdScwgkE7JcIuUfK"
|
||||||
@@ -0,0 +1,9 @@
|
|||||||
|
[program:prometheus-node-exporter]
|
||||||
|
command=prometheus-node-exporter
|
||||||
|
--web.listen-address 0.0.0.0:9100
|
||||||
|
--web.config.file=/home/{{ node.username }}/.config/prometheus-node-exporter/web-config.yml
|
||||||
|
--collector.disable-defaults
|
||||||
|
--collector.textfile
|
||||||
|
--collector.textfile.directory=/home/{{ node.username }}/.local/state/prometheus-node-exporter/textfiles
|
||||||
|
--collector.time
|
||||||
|
startsecs=60
|
||||||
60
bundles/uberspace-clerie-monitoring/items.py
Normal file
60
bundles/uberspace-clerie-monitoring/items.py
Normal file
@@ -0,0 +1,60 @@
|
|||||||
|
uberspaceify = repo.libs.uberspace.Uberspaceify(node)
|
||||||
|
|
||||||
|
directories = uberspaceify.directories({
|
||||||
|
f'/home/{node.username}/.local/state/prometheus-node-exporter/textfiles': {
|
||||||
|
},
|
||||||
|
})
|
||||||
|
|
||||||
|
files = uberspaceify.files({
|
||||||
|
f'/home/{node.username}/.bwdownloads/prometheus-node-exporter.tar.gz': {
|
||||||
|
"content_type": "download",
|
||||||
|
"source": "https://github.com/prometheus/node_exporter/releases/download/v1.9.0/node_exporter-1.9.0.linux-amd64.tar.gz",
|
||||||
|
"content_hash": "847bd800f3cae9c8e613c9d2fb59ffc7bb3eb764",
|
||||||
|
"triggers": [
|
||||||
|
"action:prometheus-node-exporter-install",
|
||||||
|
],
|
||||||
|
},
|
||||||
|
f"/home/{node.username}/etc/services.d/prometheus-node-exporter.ini": {
|
||||||
|
"source": "prometheus-node-exporter.ini",
|
||||||
|
"content_type": "jinja2",
|
||||||
|
"triggers": [
|
||||||
|
"action:supervisord-reread",
|
||||||
|
"svc_uberspace_supervisord:prometheus-node-exporter:update",
|
||||||
|
],
|
||||||
|
},
|
||||||
|
f"/home/{node.username}/.config/prometheus-node-exporter/web-config.yml": {
|
||||||
|
"source": "prometheus-node-exporter-web-config.yml",
|
||||||
|
"triggers": [
|
||||||
|
"svc_uberspace_supervisord:prometheus-node-exporter:restart",
|
||||||
|
],
|
||||||
|
},
|
||||||
|
})
|
||||||
|
|
||||||
|
actions["prometheus-node-exporter-exists"] = {
|
||||||
|
"command": 'true',
|
||||||
|
"unless": f'[[ -f "/home/{node.username}/bin/prometheus-node-exporter" && -x "/home/{node.username}/bin/prometheus-node-exporter" ]]',
|
||||||
|
"triggers": [
|
||||||
|
"action:prometheus-node-exporter-install",
|
||||||
|
],
|
||||||
|
}
|
||||||
|
|
||||||
|
actions["prometheus-node-exporter-install"] = {
|
||||||
|
"command": f'tar -xf /home/{node.username}/.bwdownloads/prometheus-node-exporter.tar.gz node_exporter*/node_exporter --to-stdout > /home/{node.username}/bin/prometheus-node-exporter && chmod +x /home/{node.username}/bin/prometheus-node-exporter',
|
||||||
|
"triggered": True,
|
||||||
|
"needs": [
|
||||||
|
f"file:/home/{node.username}/.bwdownloads/prometheus-node-exporter.tar.gz",
|
||||||
|
],
|
||||||
|
}
|
||||||
|
|
||||||
|
svc_uberspace_supervisord["prometheus-node-exporter"] = {
|
||||||
|
"needs": [
|
||||||
|
f"file:/home/{node.username}/etc/services.d/prometheus-node-exporter.ini",
|
||||||
|
"action:prometheus-node-exporter-exists",
|
||||||
|
],
|
||||||
|
}
|
||||||
|
|
||||||
|
uberspace_web_backend["/.node-exporter"] = {
|
||||||
|
"backend": "http",
|
||||||
|
"port": 9100,
|
||||||
|
"remove_prefix": True,
|
||||||
|
}
|
||||||
@@ -7,5 +7,7 @@ echo "# Use crontab-dir-update to regenerate"
|
|||||||
echo
|
echo
|
||||||
echo "PATH=$HOME/.local/bin:$HOME/bin:/usr/local/bin:/usr/bin:/usr/local/sbin:/usr/sbin"
|
echo "PATH=$HOME/.local/bin:$HOME/bin:/usr/local/bin:/usr/bin:/usr/local/sbin:/usr/sbin"
|
||||||
echo
|
echo
|
||||||
|
echo "MAILTO=\"\""
|
||||||
|
echo
|
||||||
|
|
||||||
find $HOME/.config/cron.d -mindepth 1 -maxdepth 1 -type f | sort | xargs cat
|
find $HOME/.config/cron.d -mindepth 1 -maxdepth 1 -type f | sort | xargs cat
|
||||||
|
|||||||
18
bundles/uberspace-supervisord/items.py
Normal file
18
bundles/uberspace-supervisord/items.py
Normal file
@@ -0,0 +1,18 @@
|
|||||||
|
uberspaceify = repo.libs.uberspace.Uberspaceify(node)
|
||||||
|
|
||||||
|
directories = uberspaceify.directories({
|
||||||
|
f'/home/{node.username}/etc/services.d': {
|
||||||
|
"purge": True,
|
||||||
|
"triggers": [
|
||||||
|
"action:supervisord-reread",
|
||||||
|
],
|
||||||
|
},
|
||||||
|
})
|
||||||
|
|
||||||
|
actions["supervisord-reread"] = {
|
||||||
|
"command": "supervisorctl reread",
|
||||||
|
"triggered": True,
|
||||||
|
"needed_by": [
|
||||||
|
"svc_uberspace_supervisord:",
|
||||||
|
],
|
||||||
|
}
|
||||||
6
bundles/uberspace-wordpress/files/wordpress.ini
Normal file
6
bundles/uberspace-wordpress/files/wordpress.ini
Normal file
@@ -0,0 +1,6 @@
|
|||||||
|
max_execution_time = 180
|
||||||
|
memory_limit = 128M
|
||||||
|
post_max_size = 64M
|
||||||
|
upload_max_filesize = 64M
|
||||||
|
max_input_time = 60
|
||||||
|
max_input_vars = 3000
|
||||||
16
bundles/uberspace-wordpress/items.py
Normal file
16
bundles/uberspace-wordpress/items.py
Normal file
@@ -0,0 +1,16 @@
|
|||||||
|
|
||||||
|
uberspaceify = repo.libs.uberspace.Uberspaceify(node)
|
||||||
|
|
||||||
|
files = uberspaceify.files({
|
||||||
|
f'/home/{node.username}/etc/php.d/wordpress.ini': {
|
||||||
|
"source": "wordpress.ini",
|
||||||
|
"triggers": [
|
||||||
|
"action:uberspace-php-restart",
|
||||||
|
],
|
||||||
|
},
|
||||||
|
})
|
||||||
|
|
||||||
|
actions["uberspace-php-restart"] = {
|
||||||
|
"command": "uberspace tools restart php",
|
||||||
|
"triggered": True,
|
||||||
|
}
|
||||||
80
items/svc_uberspace_supervisord.py
Normal file
80
items/svc_uberspace_supervisord.py
Normal file
@@ -0,0 +1,80 @@
|
|||||||
|
from shlex import quote
|
||||||
|
|
||||||
|
from bundlewrap.exceptions import BundleError
|
||||||
|
from bundlewrap.items import Item
|
||||||
|
|
||||||
|
|
||||||
|
def svc_start(node, svcname):
|
||||||
|
return node.run("supervisorctl start {}".format(quote(svcname)), may_fail=True)
|
||||||
|
|
||||||
|
def svc_running(node, svcname):
|
||||||
|
result = node.run("supervisorctl status {}".format(quote(svcname)), may_fail=True)
|
||||||
|
return result.return_code == 0
|
||||||
|
|
||||||
|
def svc_stop(node, svcname):
|
||||||
|
return node.run("supervisorctl stop {}".format(quote(svcname)), may_fail=True)
|
||||||
|
|
||||||
|
|
||||||
|
class SvcSystemd(Item):
|
||||||
|
"""
|
||||||
|
A service managed by supervisord in uberspace.
|
||||||
|
"""
|
||||||
|
BUNDLE_ATTRIBUTE_NAME = "svc_uberspace_supervisord"
|
||||||
|
ITEM_ATTRIBUTES = {
|
||||||
|
'running': True,
|
||||||
|
}
|
||||||
|
ITEM_TYPE_NAME = "svc_uberspace_supervisord"
|
||||||
|
|
||||||
|
def __repr__(self):
|
||||||
|
return "<SvcUberspaceSupervisord name:{} running:{}>".format(
|
||||||
|
self.name,
|
||||||
|
self.attributes['running'],
|
||||||
|
)
|
||||||
|
|
||||||
|
def cdict(self):
|
||||||
|
cdict = {}
|
||||||
|
for option, value in self.attributes.items():
|
||||||
|
if value is not None:
|
||||||
|
cdict[option] = value
|
||||||
|
return cdict
|
||||||
|
|
||||||
|
def fix(self, status):
|
||||||
|
if 'running' in status.keys_to_fix:
|
||||||
|
if self.attributes['running']:
|
||||||
|
svc_start(self.node, self.name)
|
||||||
|
else:
|
||||||
|
svc_stop(self.node, self.name)
|
||||||
|
|
||||||
|
def get_canned_actions(self):
|
||||||
|
return {
|
||||||
|
'stop': {
|
||||||
|
'command': "supervisorctl stop {}".format(self.name),
|
||||||
|
'needed_by': {self.id},
|
||||||
|
},
|
||||||
|
'restart': {
|
||||||
|
'command': "supervisorctl restart {}".format(self.name),
|
||||||
|
'needs': {self.id},
|
||||||
|
},
|
||||||
|
'update': {
|
||||||
|
'command': "supervisorctl update {}".format(self.name),
|
||||||
|
'needs': {self.id},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
def sdict(self):
|
||||||
|
return {
|
||||||
|
'running': svc_running(self.node, self.name),
|
||||||
|
}
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def validate_attributes(cls, bundle, item_id, attributes):
|
||||||
|
for attribute in ('running'):
|
||||||
|
if attributes.get(attribute, None) not in (True, False, None):
|
||||||
|
raise BundleError(_(
|
||||||
|
"expected boolean or None for '{attribute}' on {item} in bundle '{bundle}'"
|
||||||
|
).format(
|
||||||
|
attribute=attribute,
|
||||||
|
bundle=bundle.name,
|
||||||
|
item=item_id,
|
||||||
|
))
|
||||||
|
|
||||||
138
items/uberspace_web_backend.py
Normal file
138
items/uberspace_web_backend.py
Normal file
@@ -0,0 +1,138 @@
|
|||||||
|
from bundlewrap.exceptions import BundleError
|
||||||
|
from bundlewrap.items import Item
|
||||||
|
|
||||||
|
|
||||||
|
def backend_segments_to_dict(segments):
|
||||||
|
attributes = {}
|
||||||
|
|
||||||
|
name = segments[0].strip()
|
||||||
|
|
||||||
|
attributes["backend"] = segments[1].strip().rstrip(",")
|
||||||
|
|
||||||
|
attributes["port"] = None
|
||||||
|
|
||||||
|
if ":" in attributes["backend"]:
|
||||||
|
backend_segments = attributes["backend"].split(":")
|
||||||
|
attributes["backend"] = backend_segments[0]
|
||||||
|
attributes["port"] = int(backend_segments[1])
|
||||||
|
|
||||||
|
attributes["remove_prefix"] = None
|
||||||
|
|
||||||
|
flag = segments[2]
|
||||||
|
if flag == "--remove-prefix":
|
||||||
|
attributes["remove_prefix"] = True
|
||||||
|
|
||||||
|
return attributes
|
||||||
|
|
||||||
|
def get_backend_config(node, name):
|
||||||
|
result = node.run("uberspace web backend list", may_fail=True)
|
||||||
|
backend_lines = result.stdout_text.splitlines()
|
||||||
|
|
||||||
|
for line in backend_lines:
|
||||||
|
segments = line.split("=>", 1)[0].strip().split(" ")
|
||||||
|
if segments[0] == name:
|
||||||
|
d = backend_segments_to_dict(segments)
|
||||||
|
return d
|
||||||
|
|
||||||
|
def make_display_string(name, attributes):
|
||||||
|
backend_name = attributes.get("backend")
|
||||||
|
if attributes.get("backend") == "http":
|
||||||
|
backend_name += f":{attributes.get('port')}"
|
||||||
|
|
||||||
|
args = [ backend_name ]
|
||||||
|
|
||||||
|
if attributes["remove_prefix"]:
|
||||||
|
args.append("--remove-prefix")
|
||||||
|
|
||||||
|
arg_string = ", ".join(args)
|
||||||
|
|
||||||
|
return f"{name} {arg_string}"
|
||||||
|
|
||||||
|
def make_option_string(name, attributes):
|
||||||
|
out = []
|
||||||
|
|
||||||
|
out.append(name)
|
||||||
|
out.append(f" --{attributes.get('backend')}")
|
||||||
|
|
||||||
|
if attributes.get("backend") == "http":
|
||||||
|
out.append("--port")
|
||||||
|
out.append(str(attributes.get('port')))
|
||||||
|
|
||||||
|
if attributes["remove_prefix"]:
|
||||||
|
out.append("--remove-prefix")
|
||||||
|
|
||||||
|
return " ".join(out)
|
||||||
|
|
||||||
|
class UberspaceWebBackend(Item):
|
||||||
|
"""
|
||||||
|
Manage uberspace web backends
|
||||||
|
"""
|
||||||
|
BUNDLE_ATTRIBUTE_NAME = "uberspace_web_backend"
|
||||||
|
ITEM_ATTRIBUTES = {
|
||||||
|
"backend": "apache",
|
||||||
|
"port": None,
|
||||||
|
"remove_prefix": None,
|
||||||
|
}
|
||||||
|
ITEM_TYPE_NAME = "uberspace_web_backend"
|
||||||
|
|
||||||
|
def __repr__(self):
|
||||||
|
return f"<UberspaceWebBackend {make_display_string(self.name, self.attributes)}>"
|
||||||
|
|
||||||
|
def cdict(self):
|
||||||
|
cdict = {}
|
||||||
|
for option, value in self.attributes.items():
|
||||||
|
if value is not None:
|
||||||
|
cdict[option] = value
|
||||||
|
return cdict
|
||||||
|
|
||||||
|
def fix(self, status):
|
||||||
|
self.node.run(f"uberspace web backend set {make_option_string(self.name, self.attributes)}", may_fail=True)
|
||||||
|
|
||||||
|
def sdict(self):
|
||||||
|
return get_backend_config(self.node, self.name)
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def validate_attributes(cls, bundle, item_id, attributes):
|
||||||
|
|
||||||
|
if attributes.get("backend") == "apache":
|
||||||
|
if attributes.get("port") is not None:
|
||||||
|
raise BundleError(_(
|
||||||
|
"do not set 'port' while using 'apache' for 'backend' on {item} in bundle '{bundle}'"
|
||||||
|
).format(
|
||||||
|
item=item_id,
|
||||||
|
bundle=bundle.name,
|
||||||
|
))
|
||||||
|
|
||||||
|
if attributes.get("remove_prefix") is not None:
|
||||||
|
raise BundleError(_(
|
||||||
|
"do not set 'port' while using 'apache' for 'backend' on {item} in bundle '{bundle}'"
|
||||||
|
).format(
|
||||||
|
item=item_id,
|
||||||
|
bundle=bundle.name,
|
||||||
|
))
|
||||||
|
|
||||||
|
elif attributes.get("backend") == "http":
|
||||||
|
if not isinstance(attributes.get("port"), int):
|
||||||
|
raise BundleError(_(
|
||||||
|
"'port' required and needs to be numeric while using 'http' for 'backend' on {item} in bundle '{bundle}'"
|
||||||
|
).format(
|
||||||
|
item=item_id,
|
||||||
|
bundle=bundle.name,
|
||||||
|
))
|
||||||
|
|
||||||
|
if attributes.get("remove_prefix") not in [True, False, None]:
|
||||||
|
raise BundleError(_(
|
||||||
|
"expected boolean for 'remove_prefix' on {item} in bundle '{bundle}'"
|
||||||
|
).format(
|
||||||
|
item=item_id,
|
||||||
|
bundle=bundle.name,
|
||||||
|
))
|
||||||
|
|
||||||
|
else:
|
||||||
|
raise BundleError(_(
|
||||||
|
"expected 'apache' or 'http' for 'backend' on {item} in bundle '{bundle}'"
|
||||||
|
).format(
|
||||||
|
item=item_id,
|
||||||
|
bundle=bundle.name,
|
||||||
|
))
|
||||||
|
|
||||||
124
nodes.py
124
nodes.py
@@ -1,85 +1,47 @@
|
|||||||
bws = libs.bwsops.BwSops("secrets.json")
|
from bundlewrap.utils import error_context
|
||||||
|
import os
|
||||||
|
from pathlib import Path
|
||||||
|
|
||||||
uberspaceify = libs.uberspace.Uberspaceify()
|
uberspaceify = libs.uberspace.Uberspaceify()
|
||||||
|
|
||||||
nodes = uberspaceify.nodes({
|
# Lookup other nodes from different path
|
||||||
"clerie.uber.space": {
|
bwfiles_base_path = Path(os.environ.get("BWFILES_BASE_PATH", ".")).absolute()
|
||||||
"bundles": (
|
bwfiles_nodes_dir_path = bwfiles_base_path / "nodes"
|
||||||
"uberspace-redirect-clerie",
|
bwfiles_secrets_file_path = bwfiles_base_path / "secrets.json"
|
||||||
"uberspace-clerie-backup",
|
|
||||||
"uberspace-crontab-dir",
|
bws = libs.bwsops.BwSops(bwfiles_secrets_file_path)
|
||||||
),
|
|
||||||
"metadata": {
|
def generate_default_repos(node_name, username):
|
||||||
"clerie-backup": {
|
return {
|
||||||
"repos": {
|
"main-cyan": {
|
||||||
"main-cyan": {
|
"repo_password": bws.get([node_name, "clerie-backup-job-main"]),
|
||||||
"repo_password": bws.get("clerie.uber.space/clerie-backup/main-cyan/repo_password"),
|
"repo_url": f"https://cyan.backup.clerie.de/{node_name}/main",
|
||||||
"repo_url": "https://cyan.backup.clerie.de/clerie.uber.space/main",
|
"auth_username": node_name,
|
||||||
"auth_username": "clerie.uber.space",
|
"auth_password": bws.get([node_name, "clerie-backup-target-cyan"]),
|
||||||
"auth_password": bws.get("clerie.uber.space/clerie-backup/main-cyan/auth_password"),
|
"files": [
|
||||||
"files": [
|
f"/home/{username}",
|
||||||
"/home/clerie",
|
f"/var/www/virtual/{username}",
|
||||||
"/var/www/virtual/clerie",
|
],
|
||||||
],
|
"excludes": [
|
||||||
},
|
"/home/*/.cache",
|
||||||
"main-magenta": {
|
],
|
||||||
"repo_password": bws.get("clerie.uber.space/clerie-backup/main-magenta/repo_password"),
|
|
||||||
"repo_url": "https://magenta.backup.clerie.de/clerie.uber.space/main",
|
|
||||||
"auth_username": "clerie.uber.space",
|
|
||||||
"auth_password": bws.get("clerie.uber.space/clerie-backup/main-magenta/auth_password"),
|
|
||||||
"files": [
|
|
||||||
"/home/clerie",
|
|
||||||
"/var/www/virtual/clerie",
|
|
||||||
],
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
"cron": {
|
|
||||||
"jobs": {
|
|
||||||
"backup_main-cyan": "42 */2 * * * clerie-backup main-cyan backup",
|
|
||||||
"backup_main-cyan_mysql": "52 */2 * * * clerie-backup main-cyan restic backup --stdin-filename mysql-databases.sql --stdin-from-command -- mysqldump --all-databases",
|
|
||||||
"backup_main-magenta": "13 */2 * * * clerie-backup main-magenta backup",
|
|
||||||
"backup_main-magenta_mysql": "23 */2 * * * clerie-backup main-magenta restic backup --stdin-filename mysql-databases.sql --stdin-from-command -- mysqldump --all-databases",
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
},
|
||||||
},
|
"main-magenta": {
|
||||||
"cleriewi.uber.space": {
|
"repo_password": bws.get([node_name, "clerie-backup-job-main"]),
|
||||||
"bundles": (
|
"repo_url": f"https://magenta.backup.clerie.de/{node_name}/main",
|
||||||
"uberspace-redirect-clerie",
|
"auth_username": node_name,
|
||||||
"uberspace-clerie-backup",
|
"auth_password": bws.get([node_name, "clerie-backup-target-magenta"]),
|
||||||
"uberspace-crontab-dir",
|
"files": [
|
||||||
),
|
f"/home/{username}",
|
||||||
"metadata": {
|
f"/var/www/virtual/{username}",
|
||||||
"clerie-backup": {
|
],
|
||||||
"repos": {
|
"excludes": [
|
||||||
"main-cyan": {
|
"/home/*/.cache",
|
||||||
"repo_password": bws.get("cleriewi.uber.space/clerie-backup-job-main"),
|
],
|
||||||
"repo_url": "https://cyan.backup.clerie.de/cleriewi.uber.space/main",
|
|
||||||
"auth_username": "cleriewi.uber.space",
|
|
||||||
"auth_password": bws.get("cleriewi.uber.space/clerie-backup-target-cyan"),
|
|
||||||
"files": [
|
|
||||||
"/home/clerie",
|
|
||||||
"/var/www/virtual/clerie",
|
|
||||||
],
|
|
||||||
},
|
|
||||||
"main-magenta": {
|
|
||||||
"repo_password": bws.get("cleriewi.uber.space/clerie-backup-job-main"),
|
|
||||||
"repo_url": "https://magenta.backup.clerie.de/cleriewi.uber.space/main",
|
|
||||||
"auth_username": "cleriewi.uber.space",
|
|
||||||
"auth_password": bws.get("cleriewi.uber.space/clerie-backup-target-magenta"),
|
|
||||||
"files": [
|
|
||||||
"/home/cleriewi",
|
|
||||||
"/var/www/virtual/cleriewi",
|
|
||||||
],
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
"cron": {
|
|
||||||
"jobs": {
|
|
||||||
"backup_main-cyan": "42 */2 * * * clerie-backup main-cyan backup",
|
|
||||||
"backup_main-magenta": "13 */2 * * * clerie-backup main-magenta backup",
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
},
|
||||||
},
|
}
|
||||||
})
|
|
||||||
|
for node_file in sorted(node_file.absolute() for node_file in bwfiles_nodes_dir_path.iterdir() if node_file.is_file() and node_file.suffix == ".py"):
|
||||||
|
with error_context(filename=str(node_file)):
|
||||||
|
with node_file.open() as f:
|
||||||
|
exec(f.read())
|
||||||
|
|||||||
24
nodes/clerie.uber.space.py
Normal file
24
nodes/clerie.uber.space.py
Normal file
@@ -0,0 +1,24 @@
|
|||||||
|
nodes.update(uberspaceify.nodes({
|
||||||
|
"clerie.uber.space": {
|
||||||
|
"bundles": (
|
||||||
|
"uberspace-redirect-clerie",
|
||||||
|
"uberspace-clerie-backup",
|
||||||
|
"uberspace-clerie-monitoring",
|
||||||
|
"uberspace-crontab-dir",
|
||||||
|
"uberspace-supervisord",
|
||||||
|
),
|
||||||
|
"metadata": {
|
||||||
|
"clerie-backup": {
|
||||||
|
"repos": generate_default_repos("clerie.uber.space", "clerie"),
|
||||||
|
},
|
||||||
|
"cron": {
|
||||||
|
"jobs": {
|
||||||
|
"backup_main-cyan": "42 */2 * * * clerie-backup main-cyan backup && clerie-backup-update-monitoring main cyan",
|
||||||
|
"backup_main-cyan_mysql": "52 */2 * * * clerie-backup main-cyan restic backup --stdin-filename mysql-databases.sql --stdin-from-command -- mysqldump --all-databases && clerie-backup-update-monitoring main_mysql cyan",
|
||||||
|
"backup_main-magenta": "13 */2 * * * clerie-backup main-magenta backup && clerie-backup-update-monitoring main magenta",
|
||||||
|
"backup_main-magenta_mysql": "23 */2 * * * clerie-backup main-magenta restic backup --stdin-filename mysql-databases.sql --stdin-from-command -- mysqldump --all-databases && clerie-backup-update-monitoring main_mysql magenta",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}))
|
||||||
22
nodes/cleriewi.uber.space.py
Normal file
22
nodes/cleriewi.uber.space.py
Normal file
@@ -0,0 +1,22 @@
|
|||||||
|
nodes.update(uberspaceify.nodes({
|
||||||
|
"cleriewi.uber.space": {
|
||||||
|
"bundles": (
|
||||||
|
"uberspace-redirect-clerie",
|
||||||
|
"uberspace-clerie-backup",
|
||||||
|
"uberspace-clerie-monitoring",
|
||||||
|
"uberspace-crontab-dir",
|
||||||
|
"uberspace-supervisord",
|
||||||
|
),
|
||||||
|
"metadata": {
|
||||||
|
"clerie-backup": {
|
||||||
|
"repos": generate_default_repos("cleriewi.uber.space", "cleriewi"),
|
||||||
|
},
|
||||||
|
"cron": {
|
||||||
|
"jobs": {
|
||||||
|
"backup_main-cyan": "42 */2 * * * clerie-backup main-cyan backup && clerie-backup-update-monitoring main cyan",
|
||||||
|
"backup_main-magenta": "13 */2 * * * clerie-backup main-magenta backup && clerie-backup-update-monitoring main magenta",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}))
|
||||||
16
nodes/mercury.net.clerie.de.py
Normal file
16
nodes/mercury.net.clerie.de.py
Normal file
@@ -0,0 +1,16 @@
|
|||||||
|
nodes.update({
|
||||||
|
"mercury.net.clerie.de": {
|
||||||
|
"username": "root",
|
||||||
|
"bundles": (
|
||||||
|
"systemd",
|
||||||
|
"debian-user-clerie",
|
||||||
|
"debian-clerie-monitoring",
|
||||||
|
),
|
||||||
|
"metadata": {
|
||||||
|
"clerie-monitoring": {
|
||||||
|
"id": 401,
|
||||||
|
"private-key": bws.get(["mercury.net.clerie.de", "wg-monitoring"]),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
})
|
||||||
27
secrets.json
27
secrets.json
@@ -1,29 +1,20 @@
|
|||||||
{
|
{
|
||||||
"clerie.uber.space": {
|
"clerie.uber.space": {
|
||||||
"clerie-backup": {
|
"clerie-backup-job-main": "ENC[AES256_GCM,data:cEKZuviDYpzyhbjydOYPWF2wzozQwutSRCWo0bGECoTxV1R+PTrX4C7rc/Xj0oGCgclEfZaNvUGOfm4h7Y9xjA==,iv:RiQ/+yFgYS8Sd/fh+Z2SmKlTCIMGU3HtkfjUBDuE7sk=,tag:KC6qUKW+0gffpf3SVjUhdQ==,type:str]",
|
||||||
"main-cyan": {
|
"clerie-backup-target-cyan": "ENC[AES256_GCM,data:V/Bgfu5Thb3pUDtjk20xUQQXBgnmhv+H9R1bABYX2o3JutLntexO4LGeECZdsTIrKEVX/mwcXpFmhesYjTWQqw==,iv:jrxsku6VDCjhzLbhqa2MdOfvu7p6rKWr4WGYP6GCU6I=,tag:7AFT9WcGDH49c2DSy1ZBcw==,type:str]",
|
||||||
"repo_password": "ENC[AES256_GCM,data:BjyMOOGFdcT6e/zuQKPW88XiKhL26KYKebP0dsevMHmKoxQdIw9R/KS/GIlMlJKsz2wwH6nk5adiLBVD9+7TCA==,iv:1/iT4/QwRuZL3pq2D9nYiqTEpMHtf29r1mAYOzkxQeA=,tag:4LxvLRwfJYd9erPhBKb1Bw==,type:str]",
|
"clerie-backup-target-magenta": "ENC[AES256_GCM,data:6E6JJbbnG20FbGtneNZKUok/DsIplcnTEYvJn2zJcZMha1xk9SZGs8Pf4P6odkEjCFN06FeciuS/vgGa7rOP7A==,iv:tTnmJhnHefIusGNIHcZGqDLNEYkUXR0ITsHrDdJl2oo=,tag:LIl7xoiTOs4i2xzVW+N3wg==,type:str]"
|
||||||
"auth_password": "ENC[AES256_GCM,data:j6QJeJ7SKKoEnpiO+YxvHfcP38KVop0bfAScRk0mWeBr+8S+3sYMGnPcVbhoHcqJsWyeeEDomhm/GniGza2zLA==,iv:bxL7Hh9jVZ4wc4/69qSmRZZHcCxlEpllIu9zKA4tRy0=,tag:W4cNmbJgDZlqshUN39ieLw==,type:str]"
|
|
||||||
},
|
|
||||||
"main-magenta": {
|
|
||||||
"repo_password": "ENC[AES256_GCM,data:nDPphjFK0gY77Vq+QLhWRhUM+IxgPD+rIgYS99HCDLS5YVLiPK56kizXRWlOPpq/uUr9bdhLnQAJ8FOBbhvBKA==,iv:HE/v/cVfIrjEXdb820pGJe2hqpYaXiIqDTBr0qTg7AY=,tag:yFpn+0rI9mzGv7vdxUBKjQ==,type:str]",
|
|
||||||
"auth_password": "ENC[AES256_GCM,data:I3NbXg6Gk4/7z2Ct7L10/mASKxInAFbKN9s9O5Lz6mTfbL35n+cu58H2xP/Nxqu/AJMCcOoXwNHhA/iLGH24RQ==,iv:TwdUR7jnVYK0PnQmMs5P+TrXEtyCxQXbxWPDsmdEPbc=,tag:Sat2Wlb4vYMoH+VRgKjaFQ==,type:str]"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
},
|
||||||
"cleriewi.uber.space": {
|
"cleriewi.uber.space": {
|
||||||
"clerie-backup-job-main": "ENC[AES256_GCM,data:f6Hl80iUbjV3h69vjAyyrrvnnVKxk2DhuewE/kP0+9AX/yihlD5aOosqHnF8kbh/5Snow7/1k8CR2xpfSbiDaA==,iv:zdNhrrNr4pWUf2MpuXaBzbjkQ8xbfcZhI1/GsjXj8oY=,tag:+KpPOBwAG5uvoDtGYGBE0Q==,type:str]",
|
"clerie-backup-job-main": "ENC[AES256_GCM,data:f6Hl80iUbjV3h69vjAyyrrvnnVKxk2DhuewE/kP0+9AX/yihlD5aOosqHnF8kbh/5Snow7/1k8CR2xpfSbiDaA==,iv:zdNhrrNr4pWUf2MpuXaBzbjkQ8xbfcZhI1/GsjXj8oY=,tag:+KpPOBwAG5uvoDtGYGBE0Q==,type:str]",
|
||||||
"clerie-backup-target-cyan": "ENC[AES256_GCM,data:Fi9balI8FtDskI2d3t6Mag66ltAuszbTLIL2UV/5mHpb5t5b6VlJFPHa8Xi2ah7a0cI6Ko212pxFp5kunS01Hg==,iv:sqBFq8kE0FhfQqCHjZYyeJt1ej1UrQBz3gpc6cSq8F8=,tag:Ny7+x1teHPrmgWNYoqU51Q==,type:str]",
|
"clerie-backup-target-cyan": "ENC[AES256_GCM,data:Fi9balI8FtDskI2d3t6Mag66ltAuszbTLIL2UV/5mHpb5t5b6VlJFPHa8Xi2ah7a0cI6Ko212pxFp5kunS01Hg==,iv:sqBFq8kE0FhfQqCHjZYyeJt1ej1UrQBz3gpc6cSq8F8=,tag:Ny7+x1teHPrmgWNYoqU51Q==,type:str]",
|
||||||
"clerie-backup-target-magenta": "ENC[AES256_GCM,data:M8kfwUDV8Sd0Um4ZdE3aOiUOwJmtKgARqob+X9E3BLIGCqnJsmgKiEc5jmnkziGkepeT+IynkXJ76zLoz7WKaw==,iv:ruiXAEw3n+o1cYlSlWkUR4XUAjXegb4dUMaTgDbDaXw=,tag:drYDl0VBWW8OMBBoAmQS7Q==,type:str]"
|
"clerie-backup-target-magenta": "ENC[AES256_GCM,data:M8kfwUDV8Sd0Um4ZdE3aOiUOwJmtKgARqob+X9E3BLIGCqnJsmgKiEc5jmnkziGkepeT+IynkXJ76zLoz7WKaw==,iv:ruiXAEw3n+o1cYlSlWkUR4XUAjXegb4dUMaTgDbDaXw=,tag:drYDl0VBWW8OMBBoAmQS7Q==,type:str]"
|
||||||
},
|
},
|
||||||
|
"mercury.net.clerie.de": {
|
||||||
|
"wg-monitoring": "ENC[AES256_GCM,data:zwWOTYbS4khpzyGvK1AdlhxTZrmu7SiwWudbPzKXuuYARz22tGh874mWuhU=,iv:C0vyHvZXxujtrg/SrEL/Q/+tGW12B/R+9/7Wa3uOaPY=,tag:cXz8EbbWMe58XOBQn0AUqQ==,type:str]"
|
||||||
|
},
|
||||||
"sops": {
|
"sops": {
|
||||||
"kms": null,
|
"lastmodified": "2025-08-27T17:24:34Z",
|
||||||
"gcp_kms": null,
|
"mac": "ENC[AES256_GCM,data:OaRVF+Z+epsWo8nMSymrsHavz+vETIj7zjBqI9rmRPpATbZYnkKHPYB8I9IwXkYTnWxLl81nJCkBpsWULV5DAV2kIU89a1CC2BPzBDT/20zKfD2LORSuD/2yN44ZIYqK0TZjm8dJAqwpdBQYqkdu7pvAxEiq5FuTRE3BT2JQMmA=,iv:/7clc4EIbCNI/YHVV6oqrg3sTlWRyUHDz+HVjzzrB/M=,tag:U7tP30c+l82jhMG2eYy5FQ==,type:str]",
|
||||||
"azure_kv": null,
|
|
||||||
"hc_vault": null,
|
|
||||||
"age": null,
|
|
||||||
"lastmodified": "2025-02-16T18:14:02Z",
|
|
||||||
"mac": "ENC[AES256_GCM,data:bS9Q1sEo0ItLJJYFasJsNshfxeCYR2uFF4FVzoaQ6AHMSz76eC/uPU0njoc+tJK6qOYcPPpTGddo6bhv4A7oXaTm+vmfinetXbsvVGi4jX16LP+CEY/uqgqxfQ7+rHB5qdEyi/8Vb7N3WK2166xq3eqsBc3U+djTK2g1UB0Y2Xk=,iv:PFNuQtQENEI07fv/BA7PLth98+sSPMIWsWweQp3kecI=,tag:dW4UY7m2qiZ5Pj3w0V6REA==,type:str]",
|
|
||||||
"pgp": [
|
"pgp": [
|
||||||
{
|
{
|
||||||
"created_at": "2025-02-15T16:00:02Z",
|
"created_at": "2025-02-15T16:00:02Z",
|
||||||
@@ -32,6 +23,6 @@
|
|||||||
}
|
}
|
||||||
],
|
],
|
||||||
"unencrypted_suffix": "_unencrypted",
|
"unencrypted_suffix": "_unencrypted",
|
||||||
"version": "3.9.2"
|
"version": "3.10.2"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Reference in New Issue
Block a user