diff --git a/.envrc b/.envrc deleted file mode 100644 index 5fd603a..0000000 --- a/.envrc +++ /dev/null @@ -1,3 +0,0 @@ -layout python3 - -source_env_if_exists .envrc.local diff --git a/.gitignore b/.gitignore index 8c736ec..bbb5845 100644 --- a/.gitignore +++ b/.gitignore @@ -1,6 +1,3 @@ .secrets.cfg* __pycache__ *.swp -.direnv -.envrc.local -.bw_debug_history diff --git a/bundles/apt/files/sources.list-debian-trixie b/bundles/apt/files/sources.list-debian-trixie deleted file mode 100644 index 6ac79f3..0000000 --- a/bundles/apt/files/sources.list-debian-trixie +++ /dev/null @@ -1,3 +0,0 @@ -deb http://deb.debian.org/debian/ trixie main non-free contrib non-free-firmware -deb http://security.debian.org/debian-security trixie-security main contrib non-free -deb http://deb.debian.org/debian/ trixie-updates main contrib non-free diff --git a/bundles/apt/items.py b/bundles/apt/items.py index ea988af..0f3f92d 100644 --- a/bundles/apt/items.py +++ b/bundles/apt/items.py @@ -5,7 +5,6 @@ supported_os = { 10: 'buster', 11: 'bullseye', 12: 'bookworm', - 13: 'trixie', 99: 'unstable', }, } diff --git a/bundles/arch-with-gui/files/50-network.conf b/bundles/arch-with-gui/files/50-network.conf new file mode 100644 index 0000000..39c38f2 --- /dev/null +++ b/bundles/arch-with-gui/files/50-network.conf @@ -0,0 +1,5 @@ +context.exec = [ + { path = "pactl" args = "load-module module-native-protocol-tcp" } + { path = "pactl" args = "load-module module-zeroconf-discover" } + { path = "pactl" args = "load-module module-zeroconf-publish" } +] diff --git a/bundles/arch-with-gui/files/autologin.conf b/bundles/arch-with-gui/files/autologin.conf new file mode 100644 index 0000000..9398062 --- /dev/null +++ b/bundles/arch-with-gui/files/autologin.conf @@ -0,0 +1,3 @@ +[Autologin] +User=${user} +Session=i3.desktop diff --git a/bundles/arch-with-gui/items.py b/bundles/arch-with-gui/items.py new file mode 100644 index 0000000..5a35931 --- /dev/null +++ b/bundles/arch-with-gui/items.py @@ -0,0 +1,110 @@ +from os import listdir +from os.path import join + +actions = { + 'fc-cache_flush': { + 'command': 'fc-cache -f', + 'triggered': True, + 'needs': { + 'pkg_pacman:fontconfig', + }, + }, + 'i3pystatus_create_virtualenv': { + 'command': '/usr/bin/python3 -m virtualenv -p python3 /opt/i3pystatus/venv/', + 'unless': 'test -d /opt/i3pystatus/venv/', + 'needs': { + 'directory:/opt/i3pystatus/src', + 'pkg_pacman:python-virtualenv', + }, + }, + 'i3pystatus_install': { + 'command': ' && '.join([ + 'cd /opt/i3pystatus/src', + '/opt/i3pystatus/venv/bin/pip install --upgrade pip colour netifaces basiciw pytz', + '/opt/i3pystatus/venv/bin/pip install --upgrade -e .', + ]), + 'needs': { + 'action:i3pystatus_create_virtualenv', + }, + 'triggered': True, + }, +} + +directories = { + '/etc/sddm.conf.d': { + 'purge': True, + }, + '/opt/i3pystatus/src': {}, + '/usr/share/fonts/bundlewrap': { + 'purge': True, + 'triggers': { + 'action:fc-cache_flush', + }, + }, +} + +svc_systemd = { + 'avahi-daemon': { + 'needs': { + 'pkg_pacman:avahi', + }, + }, + 'sddm': { + 'needs': { + 'pkg_pacman:sddm', + }, + }, +} + +git_deploy = { + '/opt/i3pystatus/src': { + 'repo': 'https://github.com/enkore/i3pystatus.git', + 'rev': 'current', + 'triggers': { + 'action:i3pystatus_install', + }, + }, +} + +files['/etc/pipewire/pipewire-pulse.conf.d/50-network.conf'] = {} + +for filename in listdir(join(repo.path, 'data', 'arch-with-gui', 'files', 'fonts')): + if filename.startswith('.'): + continue + + if filename.endswith('.vault'): + # XXX remove this once we have a new bundlewrap release + # https://github.com/bundlewrap/bundlewrap/commit/2429b153dd1ca6781cf3812e2dec9c2b646a546b + from os import environ + if environ.get('BW_VAULT_DUMMY_MODE', '0') == '1': + continue + + font_name = filename[:-6] + attrs = { + 'content': repo.vault.decrypt_file_as_base64(join('arch-with-gui', 'files', 'fonts', filename)), + 'content_type': 'base64', + } + else: + font_name = filename + attrs = { + 'source': join('fonts', filename), + 'content_type': 'binary', + } + + files[f'/usr/share/fonts/bundlewrap/{font_name}'] = { + 'triggers': { + 'action:fc-cache_flush', + }, + **attrs, + } + +if node.metadata.get('arch-with-gui/autologin_as', None): + files['/etc/sddm.conf.d/autologin.conf'] = { + 'context': { + 'user': node.metadata.get('arch-with-gui/autologin_as'), + }, + 'content_type': 'mako', + 'before': { + 'svc_systemd:sddm', + }, + } diff --git a/bundles/arch-with-gui/metadata.py b/bundles/arch-with-gui/metadata.py new file mode 100644 index 0000000..f1fa8d0 --- /dev/null +++ b/bundles/arch-with-gui/metadata.py @@ -0,0 +1,124 @@ +assert node.os == 'arch' + +defaults = { + 'backups': { + 'paths': { + '/etc/netctl', + }, + }, + 'icinga_options': { + 'exclude_from_monitoring': True, + }, + 'nftables': { + 'input': { + '50-avahi': { + 'udp dport 5353 accept', + 'udp sport 5353 accept', + }, + }, + }, + 'pacman': { + 'packages': { + # fonts + 'fontconfig': {}, + 'ttf-dejavu': { + 'needed_by': { + 'pkg_pacman:sddm', + }, + }, + + # login management + 'sddm': {}, + + # networking + 'avahi': {}, + 'netctl': {}, + 'util-linux': {}, # provides rfkill + 'wpa_supplicant': {}, + 'wpa_actiond': {}, + + # shell and other gui stuff + 'dunst': {}, + 'fish': {}, + 'kitty': {}, + 'libnotify': {}, # provides notify-send + 'light': {}, + 'redshift': {}, + 'rofi': {}, + + # sound + 'calf': {}, + 'easyeffects': {}, + 'lsp-plugins': {}, + 'pavucontrol': {}, + 'pipewire': {}, + 'pipewire-jack': {}, + 'pipewire-pulse': {}, + 'pipewire-zeroconf': {}, + 'qpwgraph': {}, + + # window management + 'i3-wm': {}, + 'i3lock': {}, + 'xss-lock': {}, + + # i3pystatus dependencies + 'iw': {}, + 'wireless_tools': {}, + + # Xorg + 'xf86-input-libinput': {}, + 'xf86-input-wacom': {}, + 'xorg-server': {}, + 'xorg-setxkbmap': {}, + 'xorg-xev': {}, + 'xorg-xinput': {}, + 'xorg-xset': {}, + + # all them apps + 'browserpass': {}, + 'browserpass-firefox': {}, + 'ffmpeg': {}, + 'firefox': {}, + 'gimp': {}, + 'imagemagick': {}, + 'inkscape': {}, + 'kdenlive': {}, + 'maim': {}, + 'mosh': {}, + 'mosquitto': {}, + 'mpv': {}, + 'pass': {}, + 'pass-otp': {}, + 'pdftk': {}, + 'pwgen': {}, + 'qpdfview': {}, + 'samba': {}, + 'shotcut': {}, + 'sipcalc': {}, + 'the_silver_searcher': {}, + 'tlp': {}, + 'virt-manager': {}, + 'xclip': {}, + 'xdotool': {}, # needed for maim window selection + }, + }, +} + +@metadata_reactor.provides( + 'backups/paths', +) +def backup_every_user_home(metadata): + paths = set() + + for user, config in metadata.get('users', {}).items(): + if config.get('delete', False): + continue + + paths.add(config.get('home', f'/home/{user}')) + + return { + 'backups': { + 'paths': paths, + }, + } diff --git a/bundles/avahi-daemon/files/avahi-daemon.conf b/bundles/avahi-daemon/files/avahi-daemon.conf deleted file mode 100644 index 0ad1412..0000000 --- a/bundles/avahi-daemon/files/avahi-daemon.conf +++ /dev/null @@ -1,22 +0,0 @@ -[server] -host-name=${node.name.split('.')[-1]} -use-ipv4=yes -use-ipv6=${'yes' if node.metadata.get('avahi-daemon/use-ipv6') else 'no'} -allow-interfaces=${','.join(sorted(node.metadata.get('interfaces', {}).keys()))} -ratelimit-interval-usec=1000000 -ratelimit-burst=1000 - -[wide-area] -enable-wide-area=yes - -[publish] -disable-publishing=no -disable-user-service-publishing=no -publish-hinfo=yes -publish-workstation=no -publish-aaaa-on-ipv4=no -publish-a-on-ipv6=no - -[reflector] - -[rlimits] diff --git a/bundles/avahi-daemon/items.py b/bundles/avahi-daemon/items.py deleted file mode 100644 index 0a0f1aa..0000000 --- a/bundles/avahi-daemon/items.py +++ /dev/null @@ -1,18 +0,0 @@ -directories['/etc/avahi/services'] = { - 'purge': True, -} - -files['/etc/avahi/avahi-daemon.conf'] = { - 'content_type': 'mako', - 'triggers': { - 'svc_systemd:avahi-daemon:restart', - }, -} - -svc_systemd['avahi-daemon'] = { - 'needs': { - 'file:/etc/avahi/avahi-daemon.conf', - 'pkg_apt:avahi-daemon', - 'pkg_apt:libnss-mdns', - }, -} diff --git a/bundles/avahi-daemon/metadata.py b/bundles/avahi-daemon/metadata.py deleted file mode 100644 index f6c3ef5..0000000 --- a/bundles/avahi-daemon/metadata.py +++ /dev/null @@ -1,11 +0,0 @@ -defaults = { - 'apt': { - 'packages': { - 'avahi-daemon': {}, - 'libnss-mdns': {}, - }, - }, - 'avahi-daemon': { - 'use-ipv6': True, - } -} diff --git a/bundles/backup-server/files/check_backup_for_node b/bundles/backup-server/files/check_backup_for_node index bf57012..b7866f8 100644 --- a/bundles/backup-server/files/check_backup_for_node +++ b/bundles/backup-server/files/check_backup_for_node @@ -2,6 +2,7 @@ from datetime import datetime from json import load +from subprocess import check_output from sys import argv, exit from time import time @@ -17,17 +18,29 @@ try: with open(f'/etc/backup-server/config.json', 'r') as f: server_settings = load(f) - with open(f'/etc/backup-server/backups.json', 'r') as f: - backups = load(f) + # get all existing snapshots for NODE + for line in check_output('LC_ALL=C zfs list -H -t snapshot -o name', shell=True).splitlines(): + line = line.decode('UTF-8') - if NODE not in backups: + if line.startswith('{}/{}@'.format(server_settings['zfs-base'], NODE)): + _, snapname = line.split('@', 1) + + if 'zfs-auto-snap' in snapname: + # migration from auto-snapshots, ignore + continue + + ts, bucket = snapname.split('-', 1) + snaps.add(int(ts)) + + if not snaps: print('No backups found!') exit(2) - delta = NOW - backups[NODE] + last_snap = sorted(snaps)[-1] + delta = NOW - last_snap print('Last backup was on {} UTC'.format( - datetime.fromtimestamp(backups[NODE]).strftime('%Y-%m-%d %H:%M:%S'), + datetime.fromtimestamp(last_snap).strftime('%Y-%m-%d %H:%M:%S'), )) # One day without backups is still okay. There may be fluctuations diff --git a/bundles/backup-server/files/check_backup_for_node-cron b/bundles/backup-server/files/check_backup_for_node-cron deleted file mode 100644 index ff1a368..0000000 --- a/bundles/backup-server/files/check_backup_for_node-cron +++ /dev/null @@ -1,38 +0,0 @@ -#!/usr/bin/env python3 - -from json import load, dump -from subprocess import check_output -from shutil import move -from os import remove -from collections import defaultdict - -with open('/etc/backup-server/config.json', 'r') as f: - server_settings = load(f) - -snapshots = defaultdict(set) - -for line in check_output('LC_ALL=C zfs list -H -t snapshot -o name', shell=True).splitlines(): - line = line.decode('UTF-8') - - if line.startswith('{}/'.format(server_settings['zfs-base'])): - try: - dataset, snapname = line.split('@', 1) - - dataset = dataset.split('/')[-1] - ts, bucket = snapname.split('-', 1) - - snapshots[dataset].add(int(ts)) - except Exception as e: - print(f"Exception while parsing snapshot name {line!r}: {e!r}") - -backups = {} -for dataset, snaps in snapshots.items(): - backups[dataset] = sorted(snaps)[-1] - -with open('/etc/backup-server/backups.tmp.json', 'w') as f: - dump(backups, f) - -move( - '/etc/backup-server/backups.tmp.json', - '/etc/backup-server/backups.json', -) diff --git a/bundles/backup-server/files/rotate-single-backup-client b/bundles/backup-server/files/rotate-single-backup-client index c76c6b5..ee49e26 100644 --- a/bundles/backup-server/files/rotate-single-backup-client +++ b/bundles/backup-server/files/rotate-single-backup-client @@ -33,11 +33,12 @@ for line in check_output('LC_ALL=C zfs list -H -t snapshot -o name', shell=True) if line.startswith('{}/{}@'.format(server_settings['zfs-base'], NODE)): _, snapname = line.split('@', 1) - ts, bucket = snapname.split('-', 1) - if not ts.isdigit(): + if 'zfs-auto-snap' in snapname: + # migration from auto-snapshots, ignore continue + ts, bucket = snapname.split('-', 1) buckets.setdefault(bucket, set()).add(int(ts)) syslog(f'classified {line} as {bucket} from {ts}') diff --git a/bundles/backup-server/items.py b/bundles/backup-server/items.py index e872231..bd4d12f 100644 --- a/bundles/backup-server/items.py +++ b/bundles/backup-server/items.py @@ -18,9 +18,6 @@ files = { '/usr/local/share/icinga/plugins/check_backup_for_node': { 'mode': '0755', }, - '/usr/local/share/icinga/plugins/check_backup_for_node-cron': { - 'mode': '0755', - }, } directories['/etc/backup-server/clients'] = { diff --git a/bundles/backup-server/metadata.py b/bundles/backup-server/metadata.py index 6714288..692717d 100644 --- a/bundles/backup-server/metadata.py +++ b/bundles/backup-server/metadata.py @@ -1,5 +1,3 @@ -from bundlewrap.exceptions import BundleError - defaults = { 'backup-server': { 'my_ssh_port': 22, @@ -10,14 +8,6 @@ defaults = { 'c-*', }, }, - 'systemd-timers': { - 'timers': { - 'check_backup_for_node-cron': { - 'command': '/usr/local/share/icinga/plugins/check_backup_for_node-cron', - 'when': '*-*-* *:00/5:00', # every five minutes - } - }, - }, 'zfs': { # The whole point of doing backups is to keep them for a long # time, which eliminates the need for this check. @@ -79,28 +69,25 @@ def zfs_pool(metadata): return {} crypt_devices = {} + pool_devices = set() unlock_actions = set() - devices = metadata.get('backup-server/encrypted-devices') - - pool_devices = set() - - for device, dconfig in devices.items(): - crypt_devices[dconfig['device']] = { - 'dm-name': f'backup-{device}', - 'passphrase': dconfig['passphrase'], + for number, (device, passphrase) in enumerate(sorted(metadata.get('backup-server/encrypted-devices', {}).items())): + crypt_devices[device] = { + 'dm-name': f'backup{number}', + 'passphrase': passphrase, } - pool_devices.add(f'/dev/mapper/backup-{device}') - unlock_actions.add(f'action:dm-crypt_open_backup-{device}') + pool_devices.add(f'/dev/mapper/backup{number}') + unlock_actions.add(f'action:dm-crypt_open_backup{number}') - pool_config = [{ + pool_opts = { 'devices': pool_devices, - }] + } if len(pool_devices) > 2: - pool_config[0]['type'] = 'raidz' + pool_opts['type'] = 'raidz' elif len(pool_devices) > 1: - pool_config[0]['type'] = 'mirror' + pool_opts['type'] = 'mirror' return { 'backup-server': { @@ -113,8 +100,9 @@ def zfs_pool(metadata): 'pools': { 'backups': { 'when_creating': { - 'config': pool_config, - **metadata.get('backup-server/zpool_create_options', {}), + 'config': [ + pool_opts, + ], }, 'needs': unlock_actions, # That's a bit hacky. We do it this way to auto-import @@ -168,11 +156,11 @@ def monitoring(metadata): continue services[f'BACKUPS FOR NODE {client}'] = { - 'command_on_monitored_host': '/usr/local/share/icinga/plugins/check_backup_for_node {} {}'.format( + 'command_on_monitored_host': 'sudo /usr/local/share/icinga/plugins/check_backup_for_node {} {}'.format( client, config['one_backup_every_hours'], ), - 'vars.sshmon_timeout': 40, + 'vars.sshmon_timeout': 20, } return { diff --git a/bundles/basic/items.py b/bundles/basic/items.py index c2cdd49..e0f9242 100644 --- a/bundles/basic/items.py +++ b/bundles/basic/items.py @@ -24,6 +24,7 @@ files = { 'before': { 'action:', 'pkg_apt:', + 'pkg_pacman:', }, }, } diff --git a/bundles/bird/items.py b/bundles/bird/items.py index 4c4b51c..38a1549 100644 --- a/bundles/bird/items.py +++ b/bundles/bird/items.py @@ -1,5 +1,10 @@ +if node.os == 'arch': + filename = '/etc/bird.conf' +else: + filename = '/etc/bird/bird.conf' + files = { - '/etc/bird/bird.conf': { + filename: { 'content_type': 'mako', 'triggers': { 'svc_systemd:bird:reload', @@ -10,7 +15,7 @@ files = { svc_systemd = { 'bird': { 'needs': { - f'file:/etc/bird/bird.conf', + f'file:{filename}', }, }, } diff --git a/bundles/bird/metadata.py b/bundles/bird/metadata.py index f6096a7..bc6be9a 100644 --- a/bundles/bird/metadata.py +++ b/bundles/bird/metadata.py @@ -13,6 +13,15 @@ defaults = { }, }, }, + 'pacman': { + 'packages': { + 'bird': { + 'needed_by': { + 'svc_systemd:bird', + }, + }, + }, + }, 'sysctl': { 'options': { 'net.ipv4.conf.all.forwarding': '1', diff --git a/bundles/cron/items.py b/bundles/cron/items.py index 577bb59..72e8711 100644 --- a/bundles/cron/items.py +++ b/bundles/cron/items.py @@ -1,3 +1,10 @@ +if node.os == 'arch': + service_name = 'cronie' + package_name = 'pkg_pacman:cronie' +else: + service_name = 'cron' + package_name = 'pkg_apt:cron' + files = { '/etc/crontab': { 'content_type': 'mako', @@ -17,9 +24,9 @@ directories = { } svc_systemd = { - 'cron': { + service_name: { 'needs': { - 'pkg_apt:cron', + package_name, }, }, } diff --git a/bundles/cron/metadata.py b/bundles/cron/metadata.py index 67b2b22..66d612a 100644 --- a/bundles/cron/metadata.py +++ b/bundles/cron/metadata.py @@ -4,4 +4,9 @@ defaults = { 'cron': {}, }, }, + 'pacman': { + 'packages': { + 'cronie': {}, + }, + }, } diff --git a/bundles/docker-engine/files/check_docker_container b/bundles/docker-engine/files/check_docker_container deleted file mode 100644 index ea94173..0000000 --- a/bundles/docker-engine/files/check_docker_container +++ /dev/null @@ -1,45 +0,0 @@ -#!/usr/bin/env python3 - -from json import loads -from subprocess import check_output -from sys import argv - -try: - container_name = argv[1] - - docker_ps = check_output([ - 'docker', - 'container', - 'ls', - '--all', - '--format', - 'json', - '--filter', - f'name={container_name}' - ]) - - docker_json = loads(f"[{','.join([l for l in docker_ps.decode().splitlines() if l])}]") - - containers = [ - container - for container in docker_json - if container['Names'] == container_name - ] - - if not containers: - print(f'CRITICAL: container {container_name} not found!') - exit(2) - - if len(containers) > 1: - print(f'Found more than one container matching {container_name}!') - print(docker_ps) - exit(3) - - if containers[0]['State'] != 'running': - print(f'WARNING: container {container_name} not "running"') - exit(2) - - print(f"OK: {containers[0]['Status']}") -except Exception as e: - print(repr(e)) - exit(2) diff --git a/bundles/docker-engine/files/docker-wrapper b/bundles/docker-engine/files/docker-wrapper deleted file mode 100644 index 2821d29..0000000 --- a/bundles/docker-engine/files/docker-wrapper +++ /dev/null @@ -1,67 +0,0 @@ -#!/bin/bash - -[[ -n "$DEBUG" ]] && set -x - -ACTION="$1" - -set -euo pipefail - -if [[ -z "$ACTION" ]] -then - echo "Usage: $0 start|stop" - exit 1 -fi - -PUID="$(id -u "${user}")" -PGID="$(id -g "${user}")" - -if [ "$ACTION" == "start" ] -then - # just exit if the container is actually running already. - set +e - /usr/local/share/icinga/plugins/check_docker_container "${name}" && exit 0 - set -e - - docker rm "${name}" || true - - docker pull "${image}" - - docker run -d \ - --name "${name}" \ - --env "PUID=$PUID" \ - --env "PGID=$PGID" \ - --env "TZ=${timezone}" \ -% for k, v in sorted(environment.items()): - --env "${k}=${v}" \ -% endfor - --network aaarghhh \ -% for host_port, container_port in sorted(ports.items()): - --publish "127.0.0.1:${host_port}:${container_port}" \ -% endfor -% for host_path, container_path in sorted(volumes.items()): -% if host_path.startswith('/'): - --volume "${host_path}:${container_path}" \ -% else: - --volume "/var/opt/docker-engine/${name}/${host_path}:${container_path}" \ -% endif -% endfor - --restart unless-stopped \ -% if command: - "${image}" \ - "${command}" -% else: - "${image}" -% endif - -elif [ "$ACTION" == "stop" ] -then - docker stop "${name}" - -else - echo "Unknown action $ACTION" - exit 1 -fi - -% if node.has_bundle('nftables'): -systemctl reload nftables -% endif diff --git a/bundles/docker-engine/files/docker-wrapper.service b/bundles/docker-engine/files/docker-wrapper.service deleted file mode 100644 index a908c86..0000000 --- a/bundles/docker-engine/files/docker-wrapper.service +++ /dev/null @@ -1,14 +0,0 @@ -[Unit] -Description=docker-engine app ${name} -After=network.target -Requires=${' '.join(sorted(requires))} - -[Service] -WorkingDirectory=/var/opt/docker-engine/${name}/ -ExecStart=/opt/docker-engine/${name} start -ExecStop=/opt/docker-engine/${name} stop -Type=simple -RemainAfterExit=true - -[Install] -WantedBy=multi-user.target diff --git a/bundles/docker-engine/items.py b/bundles/docker-engine/items.py deleted file mode 100644 index 253daff..0000000 --- a/bundles/docker-engine/items.py +++ /dev/null @@ -1,126 +0,0 @@ -from bundlewrap.metadata import metadata_to_json - -deps = { - 'pkg_apt:docker-ce', - 'pkg_apt:docker-ce-cli', -} - -directories['/opt/docker-engine'] = { - 'purge': True, -} -directories['/var/opt/docker-engine'] = {} - -files['/etc/docker/daemon.json'] = { - 'content': metadata_to_json(node.metadata.get('docker-engine/config')), - 'triggers': { - 'svc_systemd:docker:restart', - }, - # install config before installing packages to ensure the config is - # applied to the first start as well - 'before': deps, -} - -svc_systemd['docker'] = { - 'needs': deps, -} - -files['/usr/local/share/icinga/plugins/check_docker_container'] = { - 'mode': '0755', -} - -actions['docker_create_nondefault_network'] = { - # - # By default, containers inherit the DNS settings as defined in the - # /etc/resolv.conf configuration file. Containers that attach to the - # default bridge network receive a copy of this file. Containers that - # attach to a custom network use Docker's embedded DNS server. The embedded - # DNS server forwards external DNS lookups to the DNS servers configured on - # the host. - 'command': 'docker network create aaarghhh', - 'unless': 'docker network ls | grep -q -F aaarghhh', - 'needs': { - 'svc_systemd:docker', - }, -} - -for app, config in node.metadata.get('docker-engine/containers', {}).items(): - volumes = config.get('volumes', {}) - user = config.get('user', f'docker-{app}') - directories[f'/var/opt/docker-engine/{app}'] = { - 'owner': user, - 'group': user, - } - - files[f'/opt/docker-engine/{app}'] = { - 'source': 'docker-wrapper', - 'content_type': 'mako', - 'context': { - 'command': config.get('command'), - 'environment': config.get('environment', {}), - 'image': config['image'], - 'name': app, - 'ports': config.get('ports', {}), - 'timezone': node.metadata.get('timezone'), - 'user': user, - 'volumes': volumes, - }, - 'mode': '0755', - 'triggers': { - f'svc_systemd:docker-{app}:restart', - }, - } - - users[user] = { - 'groups': { - 'docker', - }, - 'after': { - 'action:docker_create_nondefault_network', - 'svc_systemd:docker', - }, - } - if user == f'docker-{app}': - users[user]['home'] = f'/var/opt/docker-engine/{app}' - - files[f'/usr/local/lib/systemd/system/docker-{app}.service'] = { - 'source': 'docker-wrapper.service', - 'content_type': 'mako', - 'context': { - 'name': app, - 'requires': { - *set(config.get('requires', set())), - 'docker.service', - } - }, - 'triggers': { - 'action:systemd-reload', - f'svc_systemd:docker-{app}:restart', - }, - } - - svc_systemd[f'docker-{app}'] = { - 'needs': { - *deps, - f'directory:/var/opt/docker-engine/{app}', - f'file:/opt/docker-engine/{app}', - f'file:/usr/local/lib/systemd/system/docker-{app}.service', - f'user:{user}', - 'svc_systemd:docker', - *set(config.get('needs', set())), - }, - } - - for volume in volumes: - if not volume.startswith('/'): - volume = f'/var/opt/docker-engine/{app}/{volume}' - - directories[volume] = { - 'owner': user, - 'group': user, - 'needed_by': { - f'svc_systemd:docker-{app}', - }, - # don't do anything if the directory exists, docker images - # mangle owners - 'unless': f'test -d {volume}', - } diff --git a/bundles/docker-engine/metadata.py b/bundles/docker-engine/metadata.py deleted file mode 100644 index 4600233..0000000 --- a/bundles/docker-engine/metadata.py +++ /dev/null @@ -1,92 +0,0 @@ -defaults = { - 'apt': { - 'packages': { - 'docker-ce': {}, - 'docker-ce-cli': {}, - 'docker-compose-plugin': {}, - }, - 'repos': { - 'docker': { - 'items': { - 'deb https://download.docker.com/linux/debian {os_release} stable', - }, - }, - }, - }, - 'nftables': { - 'forward': { - 'docker-engine': [ - 'ct state { related, established } accept', - 'ip saddr 172.16.0.0/12 accept', - ], - }, - 'postrouting': { - 'docker-engine': [ - 'ip saddr 172.16.0.0/12 masquerade', - ], - }, - }, - 'docker-engine': { - 'config': { - 'iptables': False, - 'no-new-privileges': True, - }, - }, - 'zfs': { - 'datasets': { - 'tank/docker-data': {}, - }, - }, -} - - -@metadata_reactor.provides( - 'icinga2_api/docker-engine/services', -) -def monitoring(metadata): - services = { - 'DOCKER PROCESS': { - 'command_on_monitored_host': '/usr/lib/nagios/plugins/check_procs -C dockerd -c 1:', - }, - } - - for app in metadata.get('docker-engine/containers', {}): - services[f'DOCKER CONTAINER {app}'] = { - 'command_on_monitored_host': f'sudo /usr/local/share/icinga/plugins/check_docker_container {app}' - } - - return { - 'icinga2_api': { - 'docker-engine': { - 'services': services, - }, - }, - } - - -@metadata_reactor.provides( - 'backups/paths', - 'zfs/datasets', -) -def zfs(metadata): - datasets = {} - - for app in metadata.get('docker-engine/containers', {}): - datasets[f'tank/docker-data/{app}'] = { - 'mountpoint': f'/var/opt/docker-engine/{app}', - 'needed_by': { - f'directory:/var/opt/docker-engine/{app}', - }, - } - - return { - 'backups': { - 'paths': { - v['mountpoint'] - for v in datasets.values() - }, - }, - 'zfs': { - 'datasets': datasets, - }, - } diff --git a/bundles/docker-goauthentik/metadata.py b/bundles/docker-goauthentik/metadata.py deleted file mode 100644 index 9d742fa..0000000 --- a/bundles/docker-goauthentik/metadata.py +++ /dev/null @@ -1,89 +0,0 @@ -assert node.has_bundle('docker-engine') - -defaults = { - 'docker-engine': { - 'containers': { - 'goauthentik-server': { - 'image': 'ghcr.io/goauthentik/server:latest', - 'command': 'server', - 'environment': { - 'AUTHENTIK_POSTGRESQL__HOST': 'goauthentik-postgresql', - 'AUTHENTIK_POSTGRESQL__NAME': 'goauthentik', - 'AUTHENTIK_POSTGRESQL__PASSWORD': repo.vault.password_for(f'{node.name} postgresql goauthentik'), - 'AUTHENTIK_POSTGRESQL__USER': 'goauthentik', - 'AUTHENTIK_REDIS__HOST': 'goauthentik-redis', - 'AUTHENTIK_SECRET_KEY': repo.vault.password_for(f'{node.name} goauthentik secret key'), - }, - 'volumes': { - 'media': '/media', - 'templates': '/templates', - }, - 'ports': { - '9000': '9000', - '9443': '9443', - }, - 'needs': { - 'svc_systemd:docker-goauthentik-postgresql', - 'svc_systemd:docker-goauthentik-redis', - }, - 'requires': { - 'docker-goauthentik-postgresql.service', - 'docker-goauthentik-redis.service', - }, - }, - 'goauthentik-worker': { - 'image': 'ghcr.io/goauthentik/server:latest', - 'command': 'worker', - 'user': 'docker-goauthentik-server', - 'environment': { - 'AUTHENTIK_POSTGRESQL__HOST': 'goauthentik-postgresql', - 'AUTHENTIK_POSTGRESQL__NAME': 'goauthentik', - 'AUTHENTIK_POSTGRESQL__PASSWORD': repo.vault.password_for(f'{node.name} postgresql goauthentik'), - 'AUTHENTIK_POSTGRESQL__USER': 'goauthentik', - 'AUTHENTIK_REDIS__HOST': 'goauthentik-redis', - 'AUTHENTIK_SECRET_KEY': repo.vault.password_for(f'{node.name} goauthentik secret key'), - }, - 'volumes': { - '/var/opt/docker-engine/goauthentik-server/media': '/media', - '/var/opt/docker-engine/goauthentik-server/certs': '/certs', - '/var/opt/docker-engine/goauthentik-server/templates': '/templates', - }, - 'needs': { - 'svc_systemd:docker-goauthentik-postgresql', - 'svc_systemd:docker-goauthentik-redis', - }, - 'requires': { - 'docker-goauthentik-postgresql.service', - 'docker-goauthentik-redis.service', - }, - }, - 'goauthentik-postgresql': { - 'image': 'docker.io/library/postgres:16-alpine', - 'environment': { - 'POSTGRES_PASSWORD': repo.vault.password_for(f'{node.name} postgresql goauthentik'), - 'POSTGRES_USER': 'goauthentik', - 'POSTGRES_DB': 'goauthentik', - }, - 'volumes': { - 'database': '/var/lib/postgresql/data', - }, - }, - 'goauthentik-redis': { - 'image': 'docker.io/library/redis:alpine', - }, - }, - }, - 'nginx': { - 'vhosts': { - 'goauthentik': { - 'locations': { - '/': { - 'target': 'http://127.0.0.1:9000/', - 'websockets': True, - 'max_body_size': '5000m', - }, - }, - }, - }, - }, -} diff --git a/bundles/docker-immich/files/immich-auto-album-share.py b/bundles/docker-immich/files/immich-auto-album-share.py deleted file mode 100644 index cafd32c..0000000 --- a/bundles/docker-immich/files/immich-auto-album-share.py +++ /dev/null @@ -1,87 +0,0 @@ -#!/usr/bin/env python3 - -import logging -from json import loads -from os import environ -from subprocess import check_output -from sys import exit - -import psycopg2 - -PSQL_HOST = environ['DB_HOSTNAME'] -PSQL_USER = environ['DB_USERNAME'] -PSQL_PASS = environ['DB_PASSWORD'] -PSQL_DB = environ['DB_DATABASE_NAME'] - -logging.basicConfig(level=logging.INFO) - -docker_networks = loads(check_output(['docker', 'network', 'inspect', 'aaarghhh'])) - -container_ip = None -# why the fuck is this a list of networks, even though we have to provide -# a network name to inspect ... -for network in docker_networks: - if network['Name'] != 'aaarghhh': - continue - - for _, container in network['Containers'].items(): - if container['Name'] == PSQL_HOST: - container_ip = container['IPv4Address'].split('/')[0] - -if not container_ip: - logging.error(f'could not find ip address for container {PSQL_HOST=} in json') - logging.debug(f'{docker_networks=}') - exit(0) - -logging.debug(f'{PSQL_HOST=} {container_ip=}') - -conn = psycopg2.connect( - dbname=PSQL_DB, - host=container_ip, - password=PSQL_PASS, - user=PSQL_USER, -) - -with conn: - with conn.cursor() as cur: - cur.execute('SELECT "id","ownerId","albumName" FROM albums;') - albums = { - i[0]: { - 'owner': i[1], - 'name': i[2], - } - for i in cur.fetchall() - } - logging.debug(f'{albums=}') - - with conn.cursor() as cur: - cur.execute('SELECT "id","name" FROM users;') - users = { - i[0]: i[1] - for i in cur.fetchall() - } - logging.debug(f'{users=}') - -for album_id, album in albums.items(): - log = logging.getLogger(album["name"]) - with conn: - with conn.cursor() as cur: - cur.execute('SELECT "usersId" FROM albums_shared_users_users WHERE "albumsId" = %s;', (album_id,)) - album_shares = [i[0] for i in cur.fetchall()] - log.info(f'album is shared with {len(album_shares)} users') - log.debug(f'{album_shares=}') - for user_id, user_name in users.items(): - if user_id == album['owner'] or user_id in album_shares: - continue - - log.info(f'sharing album with user {user_name}') - try: - with conn.cursor() as cur: - cur.execute( - 'INSERT INTO albums_shared_users_users ("albumsId","usersId","role") VALUES (%s, %s, %s);', - (album_id, user_id, 'viewer'), - ) - except Exception: - log.exception('failure while creating share') - -conn.close() diff --git a/bundles/docker-immich/items.py b/bundles/docker-immich/items.py deleted file mode 100644 index 8c9d54e..0000000 --- a/bundles/docker-immich/items.py +++ /dev/null @@ -1,3 +0,0 @@ -files['/usr/local/bin/immich-auto-album-share.py'] = { - 'mode': '0755', -} diff --git a/bundles/docker-immich/metadata.py b/bundles/docker-immich/metadata.py deleted file mode 100644 index 3952922..0000000 --- a/bundles/docker-immich/metadata.py +++ /dev/null @@ -1,92 +0,0 @@ -assert node.has_bundle('docker-engine') - -defaults = { - 'apt': { - 'packages': { - 'python3-psycopg2': {}, - }, - }, - 'docker-engine': { - 'containers': { - 'immich': { - 'image': 'ghcr.io/imagegenius/immich:latest', - 'environment': { - 'DB_DATABASE_NAME': 'immich', - 'DB_HOSTNAME': 'immich-postgresql', - 'DB_PASSWORD': repo.vault.password_for(f'{node.name} postgresql immich'), - 'DB_USERNAME': 'immich', - 'REDIS_HOSTNAME': 'immich-redis', - }, - 'volumes': { - 'config': '/config', - 'libraries': '/libraries', - 'photos': '/photos', - }, - 'ports': { - '8080': '8080', - }, - 'needs': { - 'svc_systemd:docker-immich-postgresql', - 'svc_systemd:docker-immich-redis', - }, - 'requires': { - 'docker-immich-postgresql.service', - 'docker-immich-redis.service', - }, - }, - 'immich-postgresql': { - 'image': 'tensorchord/pgvecto-rs:pg14-v0.2.0', - 'environment': { - 'POSTGRES_PASSWORD': repo.vault.password_for(f'{node.name} postgresql immich'), - 'POSTGRES_USER': 'immich', - 'POSTGRES_DB': 'immich', - }, - 'volumes': { - 'database': '/var/lib/postgresql/data', - }, - }, - 'immich-redis': { - 'image': 'docker.io/redis:6.2-alpine', - }, - }, - }, - 'docker-immich': { - 'enable_auto_album_share': False, - }, - 'nginx': { - 'vhosts': { - 'immich': { - 'locations': { - '/': { - 'target': 'http://127.0.0.1:8080/', - 'websockets': True, - 'max_body_size': '5000m', - }, - }, - }, - }, - }, -} - - -@metadata_reactor.provides( - 'systemd-timers/timers/immich-auto-album-share', -) -def auto_album_share(metadata): - if not metadata.get('docker-immich/enable_auto_album_share'): - return {} - - return { - 'systemd-timers': { - 'timers': { - 'immich-auto-album-share': { - 'command': '/usr/local/bin/immich-auto-album-share.py', - 'environment': metadata.get('docker-engine/containers/immich/environment'), - 'when': 'minutely', - 'requisite': { - 'docker-immich-postgresql.service', - }, - }, - }, - }, - } diff --git a/bundles/dovecot/files/dovecot.conf b/bundles/dovecot/files/dovecot.conf index 73afeaf..804c6a9 100644 --- a/bundles/dovecot/files/dovecot.conf +++ b/bundles/dovecot/files/dovecot.conf @@ -29,8 +29,8 @@ mail_location = maildir:/var/mail/vmail/%d/%n protocols = imap lmtp sieve ssl = required -ssl_cert = = (1, 11, 71): return { 'nodejs': { - 'version': 22, + 'version': 20, }, } else: diff --git a/bundles/forgejo/metadata.py b/bundles/forgejo/metadata.py index 16190e2..714568f 100644 --- a/bundles/forgejo/metadata.py +++ b/bundles/forgejo/metadata.py @@ -100,7 +100,7 @@ def nginx(metadata): }, }, 'website_check_path': '/user/login', - 'website_check_string': 'Sign in', + 'website_check_string': 'Sign In', }, }, }, diff --git a/bundles/homeassistant/files/check_homeassistant_update b/bundles/homeassistant/files/check_homeassistant_update index 853c467..ff2b0d7 100644 --- a/bundles/homeassistant/files/check_homeassistant_update +++ b/bundles/homeassistant/files/check_homeassistant_update @@ -2,42 +2,48 @@ from sys import exit -from packaging.version import parse -from requests import get +import requests +from packaging import version -API_TOKEN = "${token}" -DOMAIN = "${domain}" +bearer = "${bearer}" +domain = "${domain}" +OK = 0 +WARN = 1 +CRITICAL = 2 +UNKNOWN = 3 + +status = 3 +message = "Unknown Update Status" + + +domain = "hass.home.kunbox.net" + +s = requests.Session() +s.headers.update({"Content-Type": "application/json"}) try: - r = get("https://version.home-assistant.io/stable.json") - r.raise_for_status() - stable_version = parse(r.json()["homeassistant"]["generic-x86-64"]) -except Exception as e: - print(f"Could not get stable version information from home-assistant.io: {e!r}") - exit(3) - -try: - r = get( - f"https://{DOMAIN}/api/config", - headers={"Authorization": f"Bearer {API_TOKEN}", "Content-Type": "application/json"}, + stable_version = version.parse( + s.get("https://version.home-assistant.io/stable.json").json()["homeassistant"][ + "generic-x86-64" + ] ) - r.raise_for_status() - running_version = parse(r.json()["version"]) -except Exception as e: - print(f"Could not get running version information from homeassistant: {e!r}") - exit(3) - -try: - if stable_version > running_version: - print( - f"There is a newer version available: {stable_version} (currently installed: {running_version})" - ) - exit(2) + s.headers.update( + {"Authorization": f"Bearer {bearer}", "Content-Type": "application/json"} + ) + running_version = version.parse( + s.get(f"https://{domain}/api/config").json()["version"] + ) + if running_version == stable_version: + status = 0 + message = f"OK - running version {running_version} equals stable version {stable_version}" + elif running_version > stable_version: + status = 1 + message = f"WARNING - stable version {stable_version} is lower than running version {running_version}, check if downgrade is necessary." else: - print( - f"Currently running version {running_version} matches newest release on home-assistant.io" - ) - exit(0) + status = 2 + message = f"CRITICAL - update necessary, running version {running_version} is lower than stable version {stable_version}" except Exception as e: - print(repr(e)) - exit(3) + message = f"{message}: {repr(e)}" + +print(message) +exit(status) diff --git a/bundles/homeassistant/files/homeassistant.service b/bundles/homeassistant/files/homeassistant.service index ed0f2a9..a650f17 100644 --- a/bundles/homeassistant/files/homeassistant.service +++ b/bundles/homeassistant/files/homeassistant.service @@ -5,8 +5,6 @@ After=network-online.target [Service] Type=simple User=homeassistant -Environment="VIRTUAL_ENV=/opt/homeassistant/venv" -Environment="PATH=/opt/homeassistant/venv/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin" WorkingDirectory=/var/opt/homeassistant ExecStart=/opt/homeassistant/venv/bin/hass -c "/var/opt/homeassistant" RestartForceExitStatus=100 diff --git a/bundles/homeassistant/items.py b/bundles/homeassistant/items.py index 92f097b..67042d1 100644 --- a/bundles/homeassistant/items.py +++ b/bundles/homeassistant/items.py @@ -30,7 +30,7 @@ files = { '/usr/local/share/icinga/plugins/check_homeassistant_update': { 'content_type': 'mako', 'context': { - 'token': node.metadata.get('homeassistant/api_secret'), + 'bearer': repo.vault.decrypt(node.metadata.get('homeassistant/api_secret')), 'domain': node.metadata.get('homeassistant/domain'), }, 'mode': '0755', diff --git a/bundles/icinga2/files/icinga2/hosts_template.conf b/bundles/icinga2/files/icinga2/hosts_template.conf index ac56ef2..631fc8a 100644 --- a/bundles/icinga2/files/icinga2/hosts_template.conf +++ b/bundles/icinga2/files/icinga2/hosts_template.conf @@ -23,25 +23,6 @@ object Host "${rnode.name}" { vars.notification.mail = true } -% if rnode.ipmi_hostname: -object Host "${rnode.name} IPMI" { - import "generic-host" - - address = "${rnode.ipmi_hostname}" - - vars.location = "${rnode.metadata.get('location', 'unknown')}" - vars.os = "ipmi" - - vars.pretty_name = "${rnode.metadata.get('icinga_options/pretty_name', rnode.metadata.get('hostname'))} IPMI" - vars.show_on_statuspage = false - - vars.period = "${rnode.metadata.get('icinga_options/period', '24x7')}" - - vars.notification.sms = ${str(rnode.metadata.get('icinga_options/vars.notification.sms', True)).lower()} - vars.notification.mail = true -} -% endif - % for depends_on_host in sorted(rnode.metadata.get('icinga_options/also_affected_by', set())): object Dependency "${rnode.name}_depends_on_${depends_on_host}" { parent_host_name = "${depends_on_host}" diff --git a/bundles/icinga2/files/scripts/icinga_notification_wrapper b/bundles/icinga2/files/scripts/icinga_notification_wrapper index fbecd8e..612882d 100644 --- a/bundles/icinga2/files/scripts/icinga_notification_wrapper +++ b/bundles/icinga2/files/scripts/icinga_notification_wrapper @@ -129,14 +129,11 @@ def notify_per_ntfy(): data=message_text, headers=headers, auth=(CONFIG['ntfy']['user'], CONFIG['ntfy']['password']), - timeout=10, ) r.raise_for_status() except Exception as e: log_to_syslog('Sending a Notification failed: {}'.format(repr(e))) - return False - return True def notify_per_mail(): @@ -202,8 +199,7 @@ if __name__ == '__main__': notify_per_mail() if args.sms: - ntfy_worked = False - if CONFIG['ntfy']['user']: - ntfy_worked = notify_per_ntfy() - if not args.service_name or not ntfy_worked: + if not args.service_name: notify_per_sms() + if CONFIG['ntfy']['user']: + notify_per_ntfy() diff --git a/bundles/icinga2/items.py b/bundles/icinga2/items.py index 6f8de54..804d920 100644 --- a/bundles/icinga2/items.py +++ b/bundles/icinga2/items.py @@ -401,6 +401,22 @@ for rnode in sorted(repo.nodes): DAYS_TO_STRING[day%7]: f'{hour}:{minute}-{hour}:{minute+15}', }, }) + elif ( + rnode.has_bundle('pacman') + and rnode.metadata.get('pacman/unattended-upgrades/is_enabled', False) + ): + day = rnode.metadata.get('pacman/unattended-upgrades/day') + hour = rnode.metadata.get('pacman/unattended-upgrades/hour') + minute = rnode.magic_number%30 + + downtimes.append({ + 'name': 'unattended-upgrades', + 'host': rnode.name, + 'comment': f'Downtime for upgrade-and-reboot of node {rnode.name}', + 'times': { + DAYS_TO_STRING[day%7]: f'{hour}:{minute}-{hour}:{minute+15}', + }, + }) files['/etc/icinga2/conf.d/groups.conf'] = { 'source': 'icinga2/groups.conf', diff --git a/bundles/icinga2/metadata.py b/bundles/icinga2/metadata.py index c25ca41..494ff89 100644 --- a/bundles/icinga2/metadata.py +++ b/bundles/icinga2/metadata.py @@ -17,6 +17,7 @@ defaults = { 'icinga2': {}, 'icinga2-ido-pgsql': {}, 'icingaweb2': {}, + 'icingaweb2-module-monitoring': {}, 'python3-easysnmp': {}, 'python3-flask': {}, 'snmp': {}, @@ -54,6 +55,7 @@ defaults = { 'setup-token': repo.vault.password_for(f'{node.name} icingaweb2 setup-token'), }, 'php': { + 'version': '8.2', 'packages': { 'curl', 'gd', diff --git a/bundles/infobeamer-cms/items.py b/bundles/infobeamer-cms/items.py index aa424a1..2d2f8c0 100644 --- a/bundles/infobeamer-cms/items.py +++ b/bundles/infobeamer-cms/items.py @@ -23,7 +23,7 @@ actions = { git_deploy = { '/opt/infobeamer-cms/src': { 'rev': 'master', - 'repo': 'https://github.com/voc/infobeamer-cms.git', + 'repo': 'https://github.com/sophieschi/36c3-cms.git', 'needs': { 'directory:/opt/infobeamer-cms/src', }, @@ -96,6 +96,14 @@ files = { }, } +pkg_pip = { + 'github-flask': { + 'needed_by': { + 'svc_systemd:infobeamer-cms', + }, + }, +} + svc_systemd = { 'infobeamer-cms': { 'needs': { diff --git a/bundles/infobeamer-cms/metadata.py b/bundles/infobeamer-cms/metadata.py index 4413d5a..9d602e0 100644 --- a/bundles/infobeamer-cms/metadata.py +++ b/bundles/infobeamer-cms/metadata.py @@ -1,13 +1,10 @@ -from datetime import datetime, timedelta, timezone - -assert node.has_bundle('redis') +from datetime import datetime, timedelta defaults = { 'infobeamer-cms': { 'config': { 'MAX_UPLOADS': 5, 'PREFERRED_URL_SCHEME': 'https', - 'REDIS_HOST': '127.0.0.1', 'SESSION_COOKIE_NAME': '__Host-sess', 'STATIC_PATH': '/opt/infobeamer-cms/static', 'URL_KEY': repo.vault.password_for(f'{node.name} infobeamer-cms url key'), @@ -52,7 +49,7 @@ def nginx(metadata): 'infobeamer-cms/config/TIME_MIN', ) def event_times(metadata): - event_start = datetime.strptime(metadata.get('infobeamer-cms/event_start_date'), '%Y-%m-%d').replace(tzinfo=timezone.utc) + event_start = datetime.strptime(metadata.get('infobeamer-cms/event_start_date'), '%Y-%m-%d') event_duration = metadata.get('infobeamer-cms/event_duration_days', 4) event_end = event_start + timedelta(days=event_duration) diff --git a/bundles/infobeamer-monitor/files/monitor.py b/bundles/infobeamer-monitor/files/monitor.py index 7646fa6..6f353e6 100644 --- a/bundles/infobeamer-monitor/files/monitor.py +++ b/bundles/infobeamer-monitor/files/monitor.py @@ -1,10 +1,9 @@ #!/usr/bin/env python3 import logging -from datetime import datetime +from datetime import datetime, timezone from json import dumps from time import sleep -from zoneinfo import ZoneInfo import paho.mqtt.client as mqtt from requests import RequestException, get @@ -25,8 +24,7 @@ logging.basicConfig( ) LOG = logging.getLogger("main") -TZ = ZoneInfo("Europe/Berlin") -DUMP_TIME = "0900" +MLOG = logging.getLogger("mqtt") state = None @@ -40,10 +38,7 @@ def mqtt_out(message, level="INFO", device=None): key = "infobeamer" if device: key += f"/{device['id']}" - if device["description"]: - message = f"[{device['description']}] {message}" - else: - message = f"[{device['serial']}] {message}" + message = f"[{device['description']}] {message}" client.publish( CONFIG["mqtt"]["topic"], @@ -66,14 +61,14 @@ def mqtt_dump_state(device): out.append("Location: {}".format(device["location"])) out.append("Setup: {} ({})".format(device["setup"]["name"], device["setup"]["id"])) out.append("Resolution: {}".format(device["run"].get("resolution", "unknown"))) + if not device["is_synced"]: + out.append("syncing ...") mqtt_out( " - ".join(out), device=device, ) -def is_dump_time(): - return datetime.now(TZ).strftime("%H%M") == DUMP_TIME mqtt_out("Monitor starting up") while True: @@ -86,14 +81,15 @@ while True: r.raise_for_status() ib_state = r.json()["devices"] except RequestException as e: - LOG.exception("Could not get device data from info-beamer") + LOG.exception("Could not get data from info-beamer") mqtt_out( - f"Could not get device data from info-beamer: {e!r}", + f"Could not get data from info-beamer: {e!r}", level="WARN", ) else: new_state = {} - for device in sorted(ib_state, key=lambda x: x["id"]): + online_devices = set() + for device in ib_state: did = str(device["id"]) if did in new_state: @@ -101,8 +97,7 @@ while True: continue new_state[did] = device - # force information output for every online device at 09:00 CE(S)T - must_dump_state = is_dump_time() + must_dump_state = False if state is not None: if did not in state: @@ -145,15 +140,16 @@ while True: if device["is_online"]: if device["maintenance"]: mqtt_out( - "maintenance required: {}".format( - " ".join(sorted(device["maintenance"])) - ), + "maintenance required: {}".format(' '.join( + sorted(device["maintenance"]) + )), level="WARN", device=device, ) if ( - device["location"] != state[did]["location"] + device["is_synced"] != state[did]["is_synced"] + or device["location"] != state[did]["location"] or device["setup"]["id"] != state[did]["setup"]["id"] or device["run"].get("resolution") != state[did]["run"].get("resolution") @@ -165,52 +161,23 @@ while True: else: LOG.info("adding device {} to empty state".format(device["id"])) + if device["is_online"]: + online_devices.add( + "{} ({})".format( + device["id"], + device["description"], + ) + ) + state = new_state - try: - r = get( - "https://info-beamer.com/api/v1/account", - auth=("", CONFIG["api_key"]), - ) - r.raise_for_status() - ib_account = r.json() - except RequestException as e: - LOG.exception("Could not get account data from info-beamer") - mqtt_out( - f"Could not get account data from info-beamer: {e!r}", - level="WARN", - ) - else: - available_credits = ib_account["balance"] - if is_dump_time(): - mqtt_out(f"Available Credits: {available_credits}") - - if available_credits < 50: - mqtt_out( - f"balance has dropped below 50 credits! (available: {available_credits})", - level="ERROR", - ) - elif available_credits < 100: - mqtt_out( - f"balance has dropped below 100 credits! (available: {available_credits})", - level="WARN", - ) - - for quota_name, quota_config in sorted(ib_account["quotas"].items()): - value = quota_config["count"]["value"] - limit = quota_config["count"]["limit"] - if value > limit * 0.9: - mqtt_out( - f"quota {quota_name} is over 90% (limit {limit}, value {value})", - level="ERROR", - ) - elif value > limit * 0.8: - mqtt_out( - f"quota {quota_name} is over 80% (limit {limit}, value {value})", - level="WARN", - ) - - sleep(60) + if ( + datetime.now(timezone.utc).strftime("%H%M") == "1312" + and online_devices + and int(datetime.now(timezone.utc).strftime("%S")) < 30 + ): + mqtt_out("Online Devices: {}".format(", ".join(sorted(online_devices)))) + sleep(30) except KeyboardInterrupt: break diff --git a/bundles/ipmitool/metadata.py b/bundles/ipmitool/metadata.py index e908366..a340a7a 100644 --- a/bundles/ipmitool/metadata.py +++ b/bundles/ipmitool/metadata.py @@ -19,4 +19,9 @@ defaults = { '/usr/bin/ipmitool *', }, }, + 'pacman': { + 'packages': { + 'ipmitool': {}, + }, + }, } diff --git a/bundles/letsencrypt/items.py b/bundles/letsencrypt/items.py index dd0b9c2..585cf8e 100644 --- a/bundles/letsencrypt/items.py +++ b/bundles/letsencrypt/items.py @@ -12,10 +12,6 @@ actions = { 'needs': { 'svc_systemd:nginx', }, - 'after': { - 'svc_systemd:nginx:reload', - 'svc_systemd:nginx:restart', - }, }, } diff --git a/bundles/letsencrypt/metadata.py b/bundles/letsencrypt/metadata.py index ffeb084..09620c4 100644 --- a/bundles/letsencrypt/metadata.py +++ b/bundles/letsencrypt/metadata.py @@ -13,6 +13,15 @@ defaults = { }, }, }, + 'pacman': { + 'packages': { + 'dehydrated': { + 'needed_by': { + 'action:letsencrypt_update_certificates', + }, + }, + }, + }, } diff --git a/bundles/lldp/metadata.py b/bundles/lldp/metadata.py index 2f1875c..7a499dd 100644 --- a/bundles/lldp/metadata.py +++ b/bundles/lldp/metadata.py @@ -10,4 +10,15 @@ defaults = { }, }, }, + 'pacman': { + 'packages': { + 'lldpd': { + 'needed_by': { + 'directory:/etc/lldpd.d', + 'file:/etc/lldpd.conf', + 'svc_systemd:lldpd', + }, + }, + }, + }, } diff --git a/bundles/lm-sensors/metadata.py b/bundles/lm-sensors/metadata.py index 01a6d1a..ffd3900 100644 --- a/bundles/lm-sensors/metadata.py +++ b/bundles/lm-sensors/metadata.py @@ -4,6 +4,11 @@ defaults = { 'lm-sensors': {}, }, }, + 'pacman': { + 'packages': { + 'lm_sensors': {}, + }, + }, 'telegraf': { 'input_plugins': { 'builtin': { diff --git a/bundles/matrix-registration/files/config.yaml b/bundles/matrix-registration/files/config.yaml new file mode 100644 index 0000000..b3ad3a5 --- /dev/null +++ b/bundles/matrix-registration/files/config.yaml @@ -0,0 +1,40 @@ +server_location: 'http://[::1]:20080' +server_name: '${server_name}' +registration_shared_secret: '${reg_secret}' +admin_api_shared_secret: '${admin_secret}' +base_url: '${base_url}' +client_redirect: '${client_redirect}' +client_logo: 'static/images/element-logo.png' # use '{cwd}' for current working directory +#db: 'sqlite:///opt/matrix-registration/data/db.sqlite3' +db: 'postgresql://${database['user']}:${database['password']}@localhost/${database['database']}' +host: 'localhost' +port: 20100 +rate_limit: ["100 per day", "10 per minute"] +allow_cors: false +ip_logging: false +logging: + disable_existing_loggers: false + version: 1 + root: + level: DEBUG + handlers: [console] + formatters: + brief: + format: '%(name)s - %(levelname)s - %(message)s' + handlers: + console: + class: logging.StreamHandler + level: INFO + formatter: brief + stream: ext://sys.stdout +# password requirements +password: + min_length: 8 +# username requirements +username: + validation_regex: [] #list of regexes that the selected username must match. Example: '[a-zA-Z]\.[a-zA-Z]' + invalidation_regex: #list of regexes that the selected username must NOT match. Example: '(admin|support)' + - '^abuse' + - 'admin' + - 'support' + - 'help' diff --git a/bundles/matrix-registration/files/matrix-registration.service b/bundles/matrix-registration/files/matrix-registration.service new file mode 100644 index 0000000..bf6ace9 --- /dev/null +++ b/bundles/matrix-registration/files/matrix-registration.service @@ -0,0 +1,14 @@ +[Unit] +Description=matrix-registration +After=network.target + +[Service] +User=matrix-registration +Group=matrix-registration +WorkingDirectory=/opt/matrix-registration/src +ExecStart=/opt/matrix-registration/venv/bin/matrix-registration --config-path /opt/matrix-registration/config.yaml serve +Restart=always +RestartSec=5 + +[Install] +WantedBy=multi-user.target diff --git a/bundles/matrix-registration/items.py b/bundles/matrix-registration/items.py new file mode 100644 index 0000000..05d8914 --- /dev/null +++ b/bundles/matrix-registration/items.py @@ -0,0 +1,65 @@ +actions['matrix-registration_create_virtualenv'] = { + 'command': '/usr/bin/python3 -m virtualenv -p python3 /opt/matrix-registration/venv/', + 'unless': 'test -d /opt/matrix-registration/venv/', + 'needs': { + # actually /opt/matrix-registration, but we don't create that + 'directory:/opt/matrix-registration/src', + }, +} + +actions['matrix-registration_install'] = { + 'command': ' && '.join([ + 'cd /opt/matrix-registration/src', + '/opt/matrix-registration/venv/bin/pip install psycopg2-binary', + '/opt/matrix-registration/venv/bin/pip install -e .', + ]), + 'needs': { + 'action:matrix-registration_create_virtualenv', + }, + 'triggered': True, +} + +users['matrix-registration'] = { + 'home': '/opt/matrix-registration', +} + +directories['/opt/matrix-registration/src'] = {} + +git_deploy['/opt/matrix-registration/src'] = { + 'repo': 'https://github.com/zeratax/matrix-registration.git', + 'rev': 'master', + 'triggers': { + 'action:matrix-registration_install', + 'svc_systemd:matrix-registration:restart', + }, +} + +files['/opt/matrix-registration/config.yaml'] = { + 'content_type': 'mako', + 'context': { + 'admin_secret': node.metadata.get('matrix-registration/admin_secret'), + 'base_url': node.metadata.get('matrix-registration/base_path', ''), + 'client_redirect': node.metadata.get('matrix-registration/client_redirect'), + 'database': node.metadata.get('matrix-registration/database'), + 'reg_secret': node.metadata.get('matrix-synapse/registration_shared_secret'), + 'server_name': node.metadata.get('matrix-synapse/server_name'), + }, + 'triggers': { + 'svc_systemd:matrix-registration:restart', + }, +} + +files['/usr/local/lib/systemd/system/matrix-registration.service'] = { + 'triggers': { + 'action:systemd-reload', + 'svc_systemd:matrix-registration:restart', + }, +} + +svc_systemd['matrix-registration'] = { + 'needs': { + 'action:matrix-registration_install', + 'file:/opt/matrix-registration/config.yaml', + 'file:/usr/local/lib/systemd/system/matrix-registration.service', + }, +} diff --git a/bundles/matrix-registration/metadata.py b/bundles/matrix-registration/metadata.py new file mode 100644 index 0000000..f5e4e7c --- /dev/null +++ b/bundles/matrix-registration/metadata.py @@ -0,0 +1,25 @@ +defaults = { + 'bash_aliases': { + 'matrix-registration': '/opt/matrix-registration/venv/bin/matrix-registration --config-path /opt/matrix-registration/config.yaml', + }, + 'matrix-registration': { + 'admin_secret': repo.vault.password_for(f'{node.name} matrix-registration admin secret'), + 'database': { + 'user': 'matrix-registration', + 'password': repo.vault.password_for(f'{node.name} postgresql matrix-registration'), + 'database': 'matrix-registration', + }, + }, + 'postgresql': { + 'roles': { + 'matrix-registration': { + 'password': repo.vault.password_for(f'{node.name} postgresql matrix-registration'), + }, + }, + 'databases': { + 'matrix-registration': { + 'owner': 'matrix-registration', + }, + }, + }, +} diff --git a/bundles/matrix-synapse/items.py b/bundles/matrix-synapse/items.py index 527cc5e..47a9758 100644 --- a/bundles/matrix-synapse/items.py +++ b/bundles/matrix-synapse/items.py @@ -57,3 +57,32 @@ svc_systemd = { }, }, } + +if node.metadata.get('matrix-synapse/sliding_sync/version', None): + files['/usr/local/bin/matrix-sliding-sync'] = { + 'content_type': 'download', + 'source': 'https://github.com/matrix-org/sliding-sync/releases/download/{}/syncv3_linux_amd64'.format( + node.metadata.get('matrix-synapse/sliding_sync/version'), + ), + 'content_hash': node.metadata.get('matrix-synapse/sliding_sync/sha1', None), + 'mode': '0755', + 'triggers': { + 'svc_systemd:matrix-sliding-sync:restart', + }, + } + + files['/usr/local/lib/systemd/system/matrix-sliding-sync.service'] = { + 'content_type': 'mako', + 'triggers': { + 'action:systemd-reload', + 'svc_systemd:matrix-sliding-sync:restart', + }, + } + + svc_systemd['matrix-sliding-sync'] = { + 'needs': { + 'file:/usr/local/bin/matrix-sliding-sync', + 'file:/usr/local/lib/systemd/system/matrix-sliding-sync.service', + 'postgres_db:synapse', + }, + } diff --git a/bundles/matrix-synapse/metadata.py b/bundles/matrix-synapse/metadata.py index eac3005..7af43f0 100644 --- a/bundles/matrix-synapse/metadata.py +++ b/bundles/matrix-synapse/metadata.py @@ -88,6 +88,14 @@ def nginx(metadata): if not node.has_bundle('nginx'): raise DoNotRunAgain + wellknown_client_sliding_sync = {} + if metadata.get('matrix-synapse/sliding_sync/version', None): + wellknown_client_sliding_sync = { + 'org.matrix.msc3575.proxy': { + 'url': 'https://{}'.format(metadata.get('matrix-synapse/baseurl')), + }, + } + wellknown = { '/.well-known/matrix/client': { 'content': dumps({ @@ -97,6 +105,7 @@ def nginx(metadata): 'm.identity_server': { 'base_url': metadata.get('matrix-synapse/identity_server', 'https://matrix.org'), }, + **wellknown_client_sliding_sync, **metadata.get('matrix-synapse/additional_client_config', {}), }, sort_keys=True), 'return': 200, @@ -125,6 +134,9 @@ def nginx(metadata): 'target': 'http://[::1]:20080', 'max_body_size': '50M', }, + '/_matrix/client/unstable/org.matrix.msc3575/sync': { + 'target': 'http://127.0.0.1:20070', + }, '/_synapse': { 'target': 'http://[::1]:20080', }, diff --git a/bundles/netbox/items.py b/bundles/netbox/items.py index 9edbf0b..f261641 100644 --- a/bundles/netbox/items.py +++ b/bundles/netbox/items.py @@ -38,8 +38,8 @@ actions['netbox_install'] = { 'triggered': True, 'command': ' && '.join([ 'cd /opt/netbox/src', - '/opt/netbox/venv/bin/pip install --upgrade --upgrade-strategy=eager pip wheel setuptools django-auth-ldap gunicorn', - '/opt/netbox/venv/bin/pip install --upgrade --upgrade-strategy=eager -r requirements.txt', + '/opt/netbox/venv/bin/pip install --upgrade pip wheel setuptools django-auth-ldap gunicorn', + '/opt/netbox/venv/bin/pip install --upgrade -r requirements.txt', ]), 'needs': { 'pkg_apt:build-essential', diff --git a/bundles/nextcloud/metadata.py b/bundles/nextcloud/metadata.py index 73c7264..8081cbe 100644 --- a/bundles/nextcloud/metadata.py +++ b/bundles/nextcloud/metadata.py @@ -45,9 +45,6 @@ defaults = { 'pwd': '/var/www/nextcloud', 'user': 'www-data', 'when': '*:00/5', - 'requisite': { - 'postgresql.service', - }, }, }, }, diff --git a/bundles/nfs-client/items.py b/bundles/nfs-client/items.py index 97cebc4..918d02c 100644 --- a/bundles/nfs-client/items.py +++ b/bundles/nfs-client/items.py @@ -1,3 +1,8 @@ +if node.has_bundle('pacman'): + package = 'pkg_pacman:nfs-utils' +else: + package = 'pkg_apt:nfs-common' + for mount, data in node.metadata.get('nfs-client/mounts',{}).items(): data['mount'] = mount data['mount_options'] = set(data.get('mount_options', set())) @@ -37,7 +42,7 @@ for mount, data in node.metadata.get('nfs-client/mounts',{}).items(): 'file:/etc/systemd/system/{}.automount'.format(unitname), 'directory:{}'.format(data['mountpoint']), 'svc_systemd:systemd-networkd', - 'pkg_apt:nfs-common', + package, }, } else: @@ -53,7 +58,7 @@ for mount, data in node.metadata.get('nfs-client/mounts',{}).items(): 'file:/etc/systemd/system/{}.mount'.format(unitname), 'directory:{}'.format(data['mountpoint']), 'svc_systemd:systemd-networkd', - 'pkg_apt:nfs-common', + package, }, } diff --git a/bundles/nfs-client/metadata.py b/bundles/nfs-client/metadata.py index 93bf66e..c59ee60 100644 --- a/bundles/nfs-client/metadata.py +++ b/bundles/nfs-client/metadata.py @@ -4,6 +4,11 @@ defaults = { 'nfs-common': {}, }, }, + 'pacman': { + 'packages': { + 'nfs-utils': {}, + }, + }, } if node.has_bundle('telegraf'): diff --git a/bundles/nfs-server/files/avahi.service b/bundles/nfs-server/files/avahi.service deleted file mode 100644 index 394cdca..0000000 --- a/bundles/nfs-server/files/avahi.service +++ /dev/null @@ -1,10 +0,0 @@ - - - - NFS ${path} on %h - - _nfs._tcp - 2049 - path=${path} - - diff --git a/bundles/nfs-server/files/exports b/bundles/nfs-server/files/exports index ac9c8f8..ad2ca4c 100644 --- a/bundles/nfs-server/files/exports +++ b/bundles/nfs-server/files/exports @@ -1,4 +1,4 @@ -% for path, shares in sorted(node.metadata.get('nfs-server/shares', {}).items()): +% for path, shares in sorted(node.metadata['nfs-server']['shares'].items()): % for share_target, share_options in sorted(shares.items()): % for ip_list in repo.libs.tools.resolve_identifier(repo, share_target).values(): % for ip in sorted(ip_list): diff --git a/bundles/nfs-server/items.py b/bundles/nfs-server/items.py index ce025cf..dacbc48 100644 --- a/bundles/nfs-server/items.py +++ b/bundles/nfs-server/items.py @@ -1,40 +1,25 @@ -from re import sub - -files['/etc/exports'] = { - 'content_type': 'mako', - 'triggers': { - 'action:nfs_reload_shares', +files = { + '/etc/exports': { + 'content_type': 'mako', + 'triggers': { + 'action:nfs_reload_shares', + }, + }, + '/etc/default/nfs-kernel-server': { + 'source': 'etc-default', + 'triggers': { + 'svc_systemd:nfs-server:restart', + }, }, } -files['/etc/default/nfs-kernel-server'] = { - 'source': 'etc-default', - 'triggers': { - 'svc_systemd:nfs-server:restart', +actions = { + 'nfs_reload_shares': { + 'command': 'exportfs -a', + 'triggered': True, }, } -actions['nfs_reload_shares'] = { - 'command': 'exportfs -a', - 'triggered': True, +svc_systemd = { + 'nfs-server': {}, } - -svc_systemd['nfs-server'] = {} - -if node.has_bundle('avahi-daemon'): - for path, shares in node.metadata.get('nfs-server/shares', {}).items(): - create_avahi_file = False - for share_target, share_options in shares.items(): - if ',insecure,' in f',{share_options},': - create_avahi_file = True - - if create_avahi_file: - share_name_normalized = sub('[^a-z0-9-_]+', '_', path) - - files[f'/etc/avahi/services/nfs{share_name_normalized}.service'] = { - 'source': 'avahi.service', - 'content_type': 'mako', - 'context': { - 'path': path, - }, - } diff --git a/bundles/nfs-server/metadata.py b/bundles/nfs-server/metadata.py index d2f833c..73dc68a 100644 --- a/bundles/nfs-server/metadata.py +++ b/bundles/nfs-server/metadata.py @@ -33,10 +33,7 @@ def firewall(metadata): ips.add(share_target) rules = {} - ports = ('111', '2049', '1110', '4045', '35295') - if metadata.get('nfs-server/version', 3) == 4: - ports = ('111', '2049') - for port in ports: + for port in ('111', '2049', '1110', '4045', '35295'): for proto in ('/tcp', '/udp'): rules[port + proto] = atomic(ips) diff --git a/bundles/nftables/files/nftables.conf b/bundles/nftables/files/nftables.conf index 56fba34..c39e8be 100644 --- a/bundles/nftables/files/nftables.conf +++ b/bundles/nftables/files/nftables.conf @@ -23,8 +23,9 @@ table inet filter { icmp type timestamp-request drop icmp type timestamp-reply drop - meta l4proto {icmp, ipv6-icmp} accept + ip protocol icmp accept + ip6 nexthdr ipv6-icmp accept % for ruleset, rules in sorted(input.items()): # ${ruleset} diff --git a/bundles/nftables/items.py b/bundles/nftables/items.py index fc943d4..9bbe11f 100644 --- a/bundles/nftables/items.py +++ b/bundles/nftables/items.py @@ -1,3 +1,8 @@ +if node.has_bundle('pacman'): + package = 'pkg_pacman:nftables' +else: + package = 'pkg_apt:nftables' + directories = { # used by other bundles '/etc/nftables-rules.d': { @@ -37,7 +42,7 @@ svc_systemd = { 'nftables': { 'needs': { 'file:/etc/nftables.conf', - 'pkg_apt:nftables', + package, }, }, } diff --git a/bundles/nftables/metadata.py b/bundles/nftables/metadata.py index 4fac791..8212d3c 100644 --- a/bundles/nftables/metadata.py +++ b/bundles/nftables/metadata.py @@ -10,9 +10,26 @@ defaults = { 'blocked_v4': repo.libs.firewall.global_ip4_blocklist, 'blocked_v6': repo.libs.firewall.global_ip6_blocklist, }, + 'pacman': { + 'packages': { + 'nftables': {}, +# https://github.com/bundlewrap/bundlewrap/issues/688 +# 'iptables': { +# 'installed': False, +# 'needed_by': { +# 'pkg_pacman:iptables-nft', +# }, +# }, + 'iptables-nft': { + 'needed_by': { + 'pkg_pacman:nftables', + }, + }, + }, + }, } -if not node.has_bundle('vmhost') and not node.has_bundle('docker-engine'): +if not node.has_bundle('vmhost'): # see comment in bundles/vmhost/items.py defaults['apt']['packages']['iptables'] = { 'installed': False, diff --git a/bundles/nginx/files/arch-override.conf b/bundles/nginx/files/arch-override.conf new file mode 100644 index 0000000..5496fe6 --- /dev/null +++ b/bundles/nginx/files/arch-override.conf @@ -0,0 +1,9 @@ +[Service] +ExecStart= +ExecStart=/usr/sbin/nginx -c /etc/nginx/nginx.conf + +ExecReload= +ExecReload=/bin/sh -c "/bin/kill -s HUP $(/bin/cat /var/run/nginx.pid)" + +ExecStop= +ExecStop=/bin/sh -c "/bin/kill -s TERM $(/bin/cat /var/run/nginx.pid)" diff --git a/bundles/nginx/files/nginx.conf b/bundles/nginx/files/nginx.conf index b020d3c..dae0a26 100644 --- a/bundles/nginx/files/nginx.conf +++ b/bundles/nginx/files/nginx.conf @@ -1,4 +1,4 @@ -user www-data; +user ${username}; worker_processes ${worker_processes}; pid /var/run/nginx.pid; @@ -11,7 +11,7 @@ events { http { include /etc/nginx/mime.types; types { - application/javascript mjs; + application/javascript js mjs; } default_type application/octet-stream; charset UTF-8; @@ -26,7 +26,7 @@ http { send_timeout 10; access_log off; - error_log /dev/null; + error_log off; client_body_buffer_size 16K; client_header_buffer_size 4k; diff --git a/bundles/nginx/files/site_template b/bundles/nginx/files/site_template index 96875c8..a967893 100644 --- a/bundles/nginx/files/site_template +++ b/bundles/nginx/files/site_template @@ -149,18 +149,18 @@ server { % if 'target' in options: proxy_pass ${options['target']}; proxy_http_version ${options.get('http_version', '1.1')}; - proxy_set_header Host ${options.get('proxy_pass_host', domain)}; + proxy_set_header Host ${domain}; % if options.get('websockets', False): proxy_set_header Connection "upgrade"; proxy_set_header Upgrade $http_upgrade; % endif proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_set_header X-Forwarded-Proto $scheme; - proxy_set_header X-Forwarded-Host ${options.get('x_forwarded_host', options.get('proxy_pass_host', domain))}; + proxy_set_header X-Forwarded-Host ${options.get('x_forwarded_host', domain)}; % for option, value in options.get('proxy_set_header', {}).items(): proxy_set_header ${option} ${value}; % endfor -% if location != '/' and location != '= /': +% if location != '/': proxy_set_header X-Script-Name ${location}; % endif proxy_buffering off; diff --git a/bundles/nginx/items.py b/bundles/nginx/items.py index 304dcd7..53edc86 100644 --- a/bundles/nginx/items.py +++ b/bundles/nginx/items.py @@ -1,5 +1,12 @@ from datetime import datetime, timedelta +if node.has_bundle('pacman'): + package = 'pkg_pacman:nginx' + username = 'http' +else: + package = 'pkg_apt:nginx' + username = 'www-data' + directories = { '/etc/nginx/sites': { 'purge': True, @@ -17,9 +24,9 @@ directories = { }, }, '/var/log/nginx-timing': { - 'owner': 'www-data', + 'owner': username, 'needs': { - 'pkg_apt:nginx', + package, }, }, '/var/www': {}, @@ -33,6 +40,7 @@ files = { '/etc/nginx/nginx.conf': { 'content_type': 'mako', 'context': { + 'username': username, **node.metadata['nginx'], }, 'triggers': { @@ -61,13 +69,21 @@ files = { '/var/www/error.html': {}, '/var/www/not_found.html': {}, } +if node.has_bundle('pacman'): + files['/etc/systemd/system/nginx.service.d/bundlewrap.conf'] = { + 'source': 'arch-override.conf', + 'triggers': { + 'action:systemd-reload', + 'svc_systemd:nginx:restart', + }, + } svc_systemd = { 'nginx': { 'needs': { 'action:generate-dhparam', 'directory:/var/log/nginx-timing', - 'pkg_apt:nginx', + package, }, }, } @@ -104,7 +120,7 @@ for vhost, config in node.metadata.get('nginx/vhosts', {}).items(): 'context': { 'create_logs': config.get('create_logs', False), 'create_timing_log': config.get('timing_log', True), - 'php_version': node.metadata.get('php/__version', ''), + 'php_version': node.metadata.get('php/version', ''), 'security_txt': security_txt_enabled, 'vhost': vhost, **config, diff --git a/bundles/nginx/metadata.py b/bundles/nginx/metadata.py index 28395ff..2715065 100644 --- a/bundles/nginx/metadata.py +++ b/bundles/nginx/metadata.py @@ -33,6 +33,11 @@ defaults = { 'nginx': { 'worker_connections': 768, }, + 'pacman': { + 'packages': { + 'nginx': {}, + }, + }, } if node.has_bundle('telegraf'): diff --git a/bundles/openssh/items.py b/bundles/openssh/items.py index 0b9fa04..a93b873 100644 --- a/bundles/openssh/items.py +++ b/bundles/openssh/items.py @@ -27,22 +27,29 @@ files = { }, } +if node.has_bundle('pacman'): + package = 'pkg_pacman:openssh' + service = 'sshd' +else: + package = 'pkg_apt:openssh-server' + service = 'ssh' + actions = { 'sshd_check_config': { 'command': 'sshd -T -C user=root -C host=localhost -C addr=localhost', 'triggered': True, 'triggers': { - 'svc_systemd:ssh:restart', + 'svc_systemd:{}:restart'.format(service), }, }, } svc_systemd = { - 'ssh': { + service: { 'needs': { 'file:/etc/systemd/system/ssh.service.d/bundlewrap.conf', 'file:/etc/ssh/sshd_config', - 'pkg_apt:openssh-server', + package, }, }, } diff --git a/bundles/openssh/metadata.py b/bundles/openssh/metadata.py index 4db6d78..630b851 100644 --- a/bundles/openssh/metadata.py +++ b/bundles/openssh/metadata.py @@ -8,6 +8,11 @@ defaults = { 'openssh-sftp-server': {}, }, }, + 'pacman': { + 'packages': { + 'openssh': {}, + }, + }, } @metadata_reactor.provides( diff --git a/bundles/pacman/files/check_unattended_upgrades b/bundles/pacman/files/check_unattended_upgrades new file mode 100644 index 0000000..1cafab5 --- /dev/null +++ b/bundles/pacman/files/check_unattended_upgrades @@ -0,0 +1,38 @@ +#!/bin/bash + +statusfile="/var/tmp/unattended_upgrades.status" +if ! [[ -f "$statusfile" ]] +then + echo "Status file not found" + exit 3 +fi + +mtime=$(stat -c %Y $statusfile) +now=$(date +%s) +if (( $now - $mtime > 60*60*24*8 )) +then + echo "Status file is older than 8 days!" + exit 3 +fi + +exitcode=$(cat $statusfile) +case "$exitcode" in + abort_ssh) + echo "Upgrades skipped due to active SSH login" + exit 1 + ;; + 0) + if [[ -f /var/run/reboot-required ]] + then + echo "OK, but updates require a reboot" + exit 1 + else + echo "OK" + exit 0 + fi + ;; + *) + echo "Last exitcode was $exitcode" + exit 2 + ;; +esac diff --git a/bundles/pacman/files/do-unattended-upgrades b/bundles/pacman/files/do-unattended-upgrades new file mode 100644 index 0000000..a04b5fc --- /dev/null +++ b/bundles/pacman/files/do-unattended-upgrades @@ -0,0 +1,18 @@ +#!/bin/bash + +set -xeuo pipefail + +pacman -Syu --noconfirm --noprogressbar + +% for affected, restarts in sorted(restart_triggers.items()): +up_since=$(systemctl show "${affected}" | sed -n 's/^ActiveEnterTimestamp=//p' || echo 0) +up_since_ts=$(date -d "$up_since" +%s || echo 0) +now=$(date +%s) + +if [ $((now - up_since_ts)) -lt 3600 ] +then +% for restart in sorted(restarts): + systemctl restart "${restart}" || true +% endfor +fi +% endfor diff --git a/bundles/pacman/files/faillock.conf b/bundles/pacman/files/faillock.conf new file mode 100644 index 0000000..19c0ff3 --- /dev/null +++ b/bundles/pacman/files/faillock.conf @@ -0,0 +1,2 @@ +# just disable faillock. +deny = 0 diff --git a/bundles/pacman/files/pacman.conf b/bundles/pacman/files/pacman.conf new file mode 100644 index 0000000..834108e --- /dev/null +++ b/bundles/pacman/files/pacman.conf @@ -0,0 +1,52 @@ +[options] +Architecture = auto +CheckSpace +Color +HoldPkg = ${' '.join(sorted(node.metadata.get('pacman/ask_before_removal')))} +ILoveCandy +IgnorePkg = ${' '.join(sorted(node.metadata.get('pacman/ignore_packages', set())))} +LocalFileSigLevel = Optional +NoExtract=${' '.join(sorted(node.metadata.get('pacman/no_extract', set())))} +ParallelDownloads = ${node.metadata.get('pacman/parallel_downloads')} +SigLevel = Required DatabaseOptional +VerbosePkgLists + +% for line in sorted(node.metadata.get('pacman/additional_config', set())): +${line} +% endfor + +[core] +Server = ${node.metadata.get('pacman/repository')} +Include = /etc/pacman.d/mirrorlist + +[extra] +Server = ${node.metadata.get('pacman/repository')} +Include = /etc/pacman.d/mirrorlist + +[community] +Server = ${node.metadata.get('pacman/repository')} +Include = /etc/pacman.d/mirrorlist +% if node.metadata.get('pacman/enable_multilib', False): + +[multilib] +Server = ${node.metadata.get('pacman/repository')} +Include = /etc/pacman.d/mirrorlist +% endif +% if node.metadata.get('pacman/enable_aurto', True): + +[aurto] +Server = https://aurto.kunbox.net/ +SigLevel = Optional TrustAll +% endif +% if node.has_bundle('zfs'): + +[archzfs] +Server = http://archzfs.com/archzfs/x86_64 + +% if node.metadata.get('pacman/linux-lts', False): +[zfs-linux-lts] +% else: +[zfs-linux] +% endif +Server = http://kernels.archzfs.com/$repo/ +% endif diff --git a/bundles/pacman/files/upgrade-and-reboot b/bundles/pacman/files/upgrade-and-reboot new file mode 100644 index 0000000..41973aa --- /dev/null +++ b/bundles/pacman/files/upgrade-and-reboot @@ -0,0 +1,49 @@ +#!/bin/bash + +# With systemd, we can force logging to the journal. This is better than +# spamming the world with cron mails. You can then view these logs using +# "journalctl -rat upgrade-and-reboot". +if which logger >/dev/null 2>&1 +then + # Dump stdout and stderr to logger, which will then put everything + # into the journal. + exec 1> >(logger -t upgrade-and-reboot -p user.info) + exec 2> >(logger -t upgrade-and-reboot -p user.error) +fi + +. /etc/upgrade-and-reboot.conf + +echo "Starting upgrade-and-reboot for node $nodename ..." + +statusfile="/var/tmp/unattended_upgrades.status" +# Workaround, because /var/tmp is usually 1777 +[[ "$UID" == 0 ]] && chown root:root "$statusfile" + +logins=$(ps h -C sshd -o euser | awk '$1 != "root" && $1 != "sshd" && $1 != "sshmon" && $1 != "nobody"') +if [[ -n "$logins" ]] +then + echo "Will abort now, there are active SSH logins: $logins" + echo "abort_ssh" > "$statusfile" + exit 1 +fi + +softlockdir=/var/lib/bundlewrap/soft-$nodename +mkdir -p "$softlockdir" +printf '{"comment": "UPDATE", "date": %s, "expiry": %s, "id": "UNATTENDED", "items": ["*"], "user": "root@localhost"}\n' \ + $(date +%s) \ + $(date -d 'now + 30 mins' +%s) \ + >"$softlockdir"/UNATTENDED +trap 'rm -f "$softlockdir"/UNATTENDED' EXIT + +do-unattended-upgrades +ret=$? + +echo "$ret" > "$statusfile" +if (( $ret != 0 )) +then + exit 1 +fi + +systemctl reboot + +echo "upgrade-and-reboot for node $nodename is DONE" diff --git a/bundles/pacman/files/upgrade-and-reboot.conf b/bundles/pacman/files/upgrade-and-reboot.conf new file mode 100644 index 0000000..ca71dce --- /dev/null +++ b/bundles/pacman/files/upgrade-and-reboot.conf @@ -0,0 +1,3 @@ +nodename="${node.name}" +reboot_mail_to="${node.metadata.get('apt/unattended-upgrades/reboot_mail_to', '')}" +auto_reboot_enabled="${node.metadata.get('apt/unattended-upgrades/reboot_enabled', True)}" diff --git a/bundles/pacman/items.py b/bundles/pacman/items.py new file mode 100644 index 0000000..9f80ca7 --- /dev/null +++ b/bundles/pacman/items.py @@ -0,0 +1,113 @@ +from bundlewrap.exceptions import BundleError + +if not node.os == 'arch': + raise BundleError(f'{node.name}: bundle:pacman requires arch linux') + +files = { + '/etc/pacman.conf': { + 'content_type': 'mako', + }, + '/etc/upgrade-and-reboot.conf': { + 'content_type': 'mako', + }, + '/etc/security/faillock.conf': {}, + '/usr/local/sbin/upgrade-and-reboot': { + 'mode': '0700', + }, + '/usr/local/sbin/do-unattended-upgrades': { + 'content_type': 'mako', + 'mode': '0700', + 'context': { + 'restart_triggers': node.metadata.get('pacman/restart_triggers', {}), + } + }, + '/usr/local/share/icinga/plugins/check_unattended_upgrades': { + 'mode': '0755', + }, +} + +svc_systemd['paccache.timer'] = { + 'needs': { + 'pkg_pacman:pacman-contrib', + }, +} + +pkg_pacman = { + 'at': {}, + 'autoconf': {}, + 'automake': {}, + 'bind': {}, + 'binutils': {}, + 'bison': {}, + 'bzip2': {}, + 'curl': {}, + 'dialog': {}, + 'diffutils': {}, + 'fakeroot': {}, + 'file': {}, + 'findutils': {}, + 'flex': {}, + 'fwupd': {}, + 'gawk': {}, + 'gcc': {}, + 'gettext': {}, + 'git': {}, + 'gnu-netcat': {}, + 'grep': {}, + 'groff': {}, + 'gzip': {}, + 'htop': {}, + 'jq': {}, + 'ldns': {}, + 'less': {}, + 'libtool': {}, + 'logrotate': {}, + 'lsof': {}, + 'm4': {}, + 'mailutils': {}, + 'make': {}, + 'man-db': {}, + 'man-pages': {}, + 'moreutils': {}, + 'mtr': {}, + 'ncdu': {}, + 'nmap': {}, + 'pacman-contrib': {}, + 'patch': {}, + 'pkgconf': {}, + 'python': {}, + 'python-setuptools': { + 'needed_by': { + 'pkg_pip:', + }, + }, + 'python-pip': { + 'needed_by': { + 'pkg_pip:', + }, + }, + 'python-virtualenv': {}, + 'rsync': {}, + 'run-parts': {}, + 'sed': {}, + 'tar': {}, + 'texinfo': {}, + 'tmux': {}, + 'tree': {}, + 'unzip': {}, + 'vim': {}, + 'wget': {}, + 'which': {}, + 'whois': {}, + 'zip': {}, +} + +if node.metadata.get('pacman/linux-lts', False): + pkg_pacman['linux-lts'] = {} + pkg_pacman['acpi_call-lts'] = {} +else: + pkg_pacman['linux'] = {} + pkg_pacman['acpi_call'] = {} + +for pkg, config in node.metadata.get('pacman/packages', {}).items(): + pkg_pacman[pkg] = config diff --git a/bundles/pacman/metadata.py b/bundles/pacman/metadata.py new file mode 100644 index 0000000..fb69a04 --- /dev/null +++ b/bundles/pacman/metadata.py @@ -0,0 +1,54 @@ +defaults = { + 'pacman': { + 'ask_before_removal': { + 'glibc', + 'pacman', + }, + 'no_extract': { + 'etc/cron.d/0hourly', + # don't install systemd-homed pam module. It produces a lot of spam in + # journal about systemd-homed not being active, so just get rid of it. + # Requires reinstall of systemd package, though + 'usr/lib/security/pam_systemd_home.so', + }, + 'parallel_downloads': 4, + 'repository': 'http://ftp.uni-kl.de/pub/linux/archlinux/$repo/os/$arch', + 'unattended-upgrades': { + 'day': 5, + 'hour': 21, + }, + }, +} + + +@metadata_reactor.provides( + 'cron/jobs/upgrade-and-reboot', + 'icinga2_api/pacman/services', +) +def patchday(metadata): + if not metadata.get('pacman/unattended-upgrades/is_enabled', False): + return {} + + day = metadata.get('pacman/unattended-upgrades/day') + hour = metadata.get('pacman/unattended-upgrades/hour') + + return { + 'cron': { + 'jobs': { + 'upgrade-and-reboot': '{minute} {hour} * * {day} root /usr/local/sbin/upgrade-and-reboot'.format( + minute=node.magic_number % 30, + hour=hour, + day=day, + ), + }, + }, + 'icinga2_api': { + 'pacman': { + 'services': { + 'UNATTENDED UPGRADES': { + 'command_on_monitored_host': '/usr/local/share/icinga/plugins/check_unattended_upgrades', + }, + }, + }, + }, + } diff --git a/bundles/paperless-ng/files/paperless-webserver.service b/bundles/paperless-ng/files/paperless-webserver.service index 7c41aa7..5d7f806 100644 --- a/bundles/paperless-ng/files/paperless-webserver.service +++ b/bundles/paperless-ng/files/paperless-webserver.service @@ -8,11 +8,8 @@ Requires=redis.service User=paperless Group=paperless Environment=PAPERLESS_CONFIGURATION_PATH=/opt/paperless/paperless.conf -Environment=GRANIAN_PORT=22070 -Environment=GRANIAN_WORKERS=4 -Environment=GRANIAN_HOST=::1 WorkingDirectory=/opt/paperless/src/paperless-ngx/src -ExecStart=/opt/paperless/venv/bin/granian --interface asginl --ws "paperless.asgi:application" +ExecStart=/opt/paperless/venv/bin/gunicorn -c /opt/paperless/src/paperless-ngx/gunicorn.conf.py -b 127.0.0.1:22070 paperless.asgi:application Restart=always RestartSec=10 SyslogIdentifier=paperless-webserver diff --git a/bundles/paperless-ng/files/paperless.conf b/bundles/paperless-ng/files/paperless.conf index d943063..0cbd054 100644 --- a/bundles/paperless-ng/files/paperless.conf +++ b/bundles/paperless-ng/files/paperless.conf @@ -12,7 +12,7 @@ PAPERLESS_CONSUMPTION_DIR=/mnt/paperless/consume PAPERLESS_DATA_DIR=/mnt/paperless/data PAPERLESS_MEDIA_ROOT=/mnt/paperless/media PAPERLESS_STATICDIR=/opt/paperless/src/paperless-ngx/static -PAPERLESS_FILENAME_FORMAT={{ created_year }}/{{ created_month }}/{{ correspondent }}/{{ asn }}_{{ title }} +PAPERLESS_FILENAME_FORMAT={created_year}/{created_month}/{correspondent}/{asn}_{title} # Security and hosting diff --git a/bundles/paperless-ng/metadata.py b/bundles/paperless-ng/metadata.py index 8db5342..91a18c6 100644 --- a/bundles/paperless-ng/metadata.py +++ b/bundles/paperless-ng/metadata.py @@ -34,7 +34,7 @@ defaults = { }, }, 'nodejs': { - 'version': 22, + 'version': 18, }, 'postgresql': { 'roles': { @@ -99,7 +99,7 @@ def nginx(metadata): 'domain': metadata.get('paperless/domain'), 'locations': { '/': { - 'target': 'http://[::1]:22070', + 'target': 'http://127.0.0.1:22070', 'websockets': True, 'proxy_set_header': { 'X-Forwarded-Host': '$server_name', diff --git a/bundles/php/items.py b/bundles/php/items.py index c836efa..b115c19 100644 --- a/bundles/php/items.py +++ b/bundles/php/items.py @@ -1,4 +1,4 @@ -version = node.metadata.get('php/__version') +version = node.metadata.get('php/version') directories['/var/lib/php/sessions'] = { 'owner': 'www-data', diff --git a/bundles/php/metadata.py b/bundles/php/metadata.py index edb8399..d14954e 100644 --- a/bundles/php/metadata.py +++ b/bundles/php/metadata.py @@ -1,11 +1,12 @@ -OS_PHP_VERSION = { - 12: '8.2', - 13: '8.4', -} - defaults = { - 'php': { - '__version': OS_PHP_VERSION[node.os_version[0]], + 'apt': { + 'repos': { + 'php': { + 'items': { + 'deb https://packages.sury.org/php/ {os_release} main', + }, + }, + }, }, } @@ -14,7 +15,7 @@ defaults = { 'apt/packages', ) def php_packages_with_features(metadata): - version = metadata.get('php/__version') + version = metadata.get('php/version') packages = { f'php{version}': {}, diff --git a/bundles/postfix/files/arch-override.conf b/bundles/postfix/files/arch-override.conf new file mode 100644 index 0000000..3b3e46d --- /dev/null +++ b/bundles/postfix/files/arch-override.conf @@ -0,0 +1,6 @@ +[Service] +# arch postfix is not set up for chrooting by default +ExecStartPre=-/usr/sbin/mkdir -p /var/spool/postfix/etc +% for file in ['/etc/localtime', '/etc/nsswitch.conf', '/etc/resolv.conf', '/etc/services']: +ExecStartPre=-/usr/sbin/cp -p ${file} /var/spool/postfix${file} +% endfor diff --git a/bundles/postfix/files/blocked_recipients b/bundles/postfix/files/blocked_recipients index 4aff372..736e9d4 100644 --- a/bundles/postfix/files/blocked_recipients +++ b/bundles/postfix/files/blocked_recipients @@ -1,5 +1,3 @@ -devnull@${node.metadata.get('postfix/myhostname')} DISCARD DEV-NULL - % for address in sorted(blocked): ${address} REJECT % endfor diff --git a/bundles/postfix/files/main.cf b/bundles/postfix/files/main.cf index 9d74175..6ffffaf 100644 --- a/bundles/postfix/files/main.cf +++ b/bundles/postfix/files/main.cf @@ -3,7 +3,7 @@ biff = no append_dot_mydomain = no readme_directory = no compatibility_level = 2 -myhostname = ${node.metadata.get('postfix/myhostname')} +myhostname = ${node.metadata.get('postfix/myhostname', node.metadata['hostname'])} myorigin = /etc/mailname mydestination = $myhostname, localhost mynetworks = ${' '.join(sorted(mynetworks))} @@ -25,6 +25,7 @@ inet_interfaces = 127.0.0.1 % endif <%text> +smtp_use_tls = yes smtp_tls_loglevel = 1 smtp_tls_note_starttls_offer = yes smtp_tls_session_cache_database = btree:${data_directory}/smtp_scache @@ -37,8 +38,8 @@ smtp_tls_CAfile = /etc/ssl/certs/ca-certificates.crt % if node.has_bundle('postfixadmin'): -smtpd_tls_cert_file = /var/lib/dehydrated/certs/${node.metadata.get('postfix/myhostname')}/fullchain.pem -smtpd_tls_key_file = /var/lib/dehydrated/certs/${node.metadata.get('postfix/myhostname')}/privkey.pem +smtpd_tls_cert_file = /var/lib/dehydrated/certs/${node.metadata.get('postfix/myhostname', node.metadata['hostname'])}/fullchain.pem +smtpd_tls_key_file = /var/lib/dehydrated/certs/${node.metadata.get('postfix/myhostname', node.metadata['hostname'])}/privkey.pem <%text> smtpd_use_tls=yes smtpd_tls_session_cache_database = btree:${data_directory}/smtpd_scache @@ -47,7 +48,7 @@ smtpd_client_restrictions = permit_mynetworks permit_sasl_authenticated smtpd_helo_required = yes smtpd_helo_restrictions = permit_mynetworks reject_invalid_helo_hostname smtpd_data_restrictions = reject_unauth_pipelining -smtpd_recipient_restrictions = check_recipient_access hash:/etc/postfix/blocked_recipients, permit_mynetworks +smtpd_recipient_restrictions = permit_mynetworks, check_recipient_access hash:/etc/postfix/blocked_recipients smtpd_relay_before_recipient_restrictions = yes # https://ssl-config.mozilla.org/#server=postfix&version=3.7.10&config=intermediate&openssl=3.0.11&guideline=5.7 diff --git a/bundles/postfix/items.py b/bundles/postfix/items.py index aeceed1..d1bf0c2 100644 --- a/bundles/postfix/items.py +++ b/bundles/postfix/items.py @@ -21,12 +21,13 @@ for identifier in node.metadata.get('postfix/mynetworks', set()): netmask = '128' mynetworks.add(f'[{ip6}]/{netmask}') +my_package = 'pkg_pacman:postfix' if node.os == 'arch' else 'pkg_apt:postfix' files = { '/etc/mailname': { - 'content': node.metadata.get('postfix/myhostname'), + 'content': node.metadata.get('postfix/myhostname', node.metadata['hostname']), 'before': { - 'pkg_apt:postfix', + my_package, }, 'triggers': { 'svc_systemd:postfix:restart', @@ -81,7 +82,7 @@ actions = { 'command': 'newaliases', 'triggered': True, 'needs': { - 'pkg_apt:postfix', + my_package, }, 'before': { 'svc_systemd:postfix', @@ -91,7 +92,7 @@ actions = { 'command': 'postmap hash:/etc/postfix/blocked_recipients', 'triggered': True, 'needs': { - 'pkg_apt:postfix', + my_package, }, 'before': { 'svc_systemd:postfix', @@ -104,7 +105,17 @@ svc_systemd = { 'needs': { 'file:/etc/postfix/master.cf', 'file:/etc/postfix/main.cf', - 'pkg_apt:postfix', + my_package, }, }, } + +if node.os == 'arch': + files['/etc/systemd/system/postfix.service.d/bundlewrap.conf'] = { + 'source': 'arch-override.conf', + 'content_type': 'mako', + 'triggers': { + 'action:systemd-reload', + 'svc_systemd:postfix:restart', + }, + } diff --git a/bundles/postfix/metadata.py b/bundles/postfix/metadata.py index f457b9b..4788de6 100644 --- a/bundles/postfix/metadata.py +++ b/bundles/postfix/metadata.py @@ -14,7 +14,7 @@ defaults = { 'postfix': { 'services': { 'POSTFIX PROCESS': { - 'command_on_monitored_host': '/usr/local/share/icinga/plugins/check_systemd_unit postfix' + ('' if node.os_version >= (13,) else '@-'), + 'command_on_monitored_host': '/usr/local/share/icinga/plugins/check_systemd_unit postfix' + ('' if node.os == 'arch' else '@-'), }, 'POSTFIX QUEUE': { 'command_on_monitored_host': 'sudo /usr/local/share/icinga/plugins/check_postfix_queue -w 20 -c 40 -d 50', @@ -22,6 +22,12 @@ defaults = { }, }, }, + 'pacman': { + 'packages': { + 'postfix': {}, + 's-nail': {}, + }, + }, } if node.has_bundle('postfixadmin'): @@ -81,7 +87,7 @@ def letsencrypt(metadata): } result['domains'] = { - metadata.get('postfix/myhostname'): set(), + metadata.get('postfix/myhostname', metadata.get('hostname')): set(), } return { @@ -142,14 +148,3 @@ def icinga2(metadata): }, }, } - - -@metadata_reactor.provides( - 'postfix/myhostname', -) -def myhostname(metadata): - return { - 'postfix': { - 'myhostname': metadata.get('hostname'), - }, - } diff --git a/bundles/postgresql/items.py b/bundles/postgresql/items.py index 0a1b09f..f9cdc46 100644 --- a/bundles/postgresql/items.py +++ b/bundles/postgresql/items.py @@ -57,7 +57,7 @@ files = { }, } -if node.has_bundle('backup-client'): +if node.has_bundle('backup-client') and not node.has_bundle('zfs'): files['/etc/backup-pre-hooks.d/90-postgresql-dump-all'] = { 'source': 'backup-pre-hook', 'content_type': 'mako', @@ -67,6 +67,10 @@ if node.has_bundle('backup-client'): 'mode': '0700', } directories['/var/tmp/postgresdumps'] = {} +else: + files['/var/tmp/postgresdumps'] = { + 'delete': True, + } postgres_roles = { 'root': { diff --git a/bundles/postgresql/metadata.py b/bundles/postgresql/metadata.py index b624bae..e69a117 100644 --- a/bundles/postgresql/metadata.py +++ b/bundles/postgresql/metadata.py @@ -11,7 +11,6 @@ defaults = { 'backups': { 'paths': { '/var/lib/postgresql', - '/var/tmp/postgresdumps', }, }, 'bash_functions': { @@ -75,6 +74,8 @@ if node.has_bundle('zfs'): }, }, } +else: + defaults['backups']['paths'].add('/var/tmp/postgresdumps') @metadata_reactor.provides( diff --git a/bundles/powerdns/items.py b/bundles/powerdns/items.py index b6a5e8f..a0c89d2 100644 --- a/bundles/powerdns/items.py +++ b/bundles/powerdns/items.py @@ -3,8 +3,6 @@ from os import listdir from os.path import isfile, join from subprocess import check_output -from bundlewrap.utils.ui import io - zone_path = join(repo.path, 'data', 'powerdns', 'files', 'bind-zones') nameservers = set() @@ -81,10 +79,9 @@ if node.metadata.get('powerdns/features/bind', False): continue try: - output = check_output(['git', 'log', '-1', '--pretty=%ci']).decode('utf-8').strip() + output = check_output(['git', 'log', '-1', '--pretty=%ci', join(zone_path, zone)]).decode('utf-8').strip() serial = datetime.strptime(output, '%Y-%m-%d %H:%M:%S %z').strftime('%y%m%d%H%M') - except Exception as e: - io.stderr(f"Error while parsing commit time for {zone} serial: {e!r}") + except: serial = datetime.now().strftime('%y%m%d0000') primary_zones.add(zone) diff --git a/bundles/powerdnsadmin/items.py b/bundles/powerdnsadmin/items.py index 8398916..fb1bf0d 100644 --- a/bundles/powerdnsadmin/items.py +++ b/bundles/powerdnsadmin/items.py @@ -71,8 +71,8 @@ actions = { 'chown -R powerdnsadmin:powerdnsadmin /opt/powerdnsadmin/src/powerdnsadmin/static/', ]), 'needs': { + 'action:nodejs_install_yarn', 'action:powerdnsadmin_install_deps', - 'bundle:nodejs', 'pkg_apt:', }, }, diff --git a/bundles/powerdnsadmin/metadata.py b/bundles/powerdnsadmin/metadata.py index c2b2c1e..e6f5014 100644 --- a/bundles/powerdnsadmin/metadata.py +++ b/bundles/powerdnsadmin/metadata.py @@ -14,7 +14,7 @@ defaults = { }, }, 'nodejs': { - 'version': 22, + 'version': 18, }, 'users': { 'powerdnsadmin': { diff --git a/bundles/pppd/files/dyndns b/bundles/pppd/files/dyndns index 633915f..5058b2f 100644 --- a/bundles/pppd/files/dyndns +++ b/bundles/pppd/files/dyndns @@ -7,6 +7,7 @@ from subprocess import check_output from requests import get + UPDATE_URL = '${url}' USERNAME = '${username}' PASSWORD = '${password}' diff --git a/bundles/pppd/files/dyndns_periodic b/bundles/pppd/files/dyndns_periodic index 353ee6d..236c4fc 100644 --- a/bundles/pppd/files/dyndns_periodic +++ b/bundles/pppd/files/dyndns_periodic @@ -5,6 +5,7 @@ from ipaddress import ip_address from json import loads from subprocess import check_output, run + DOMAIN = '${domain}' # <%text> diff --git a/bundles/pretalx/items.py b/bundles/pretalx/items.py index e6b22a4..8a57eae 100644 --- a/bundles/pretalx/items.py +++ b/bundles/pretalx/items.py @@ -1,5 +1,5 @@ assert node.has_bundle('redis'), f'{node.name}: pretalx needs redis' -assert node.has_bundle('nodejs'), f'{node.name}: pretalx needs nodejs for rebuild step' +assert node.has_bundle('nodejs'), f'{node.name}: pretalx needs nodejs for rebuild and regenerate_css step' actions = { 'pretalx_create_virtualenv': { @@ -53,6 +53,17 @@ actions = { }, 'triggered': True, }, + 'pretalx_regenerate-css': { + 'command': 'sudo -u pretalx PRETALX_CONFIG_FILE=/opt/pretalx/pretalx.cfg /opt/pretalx/venv/bin/python -m pretalx regenerate_css', + 'needs': { + 'action:pretalx_migrate', + 'directory:/opt/pretalx/data', + 'directory:/opt/pretalx/static', + 'file:/opt/pretalx/pretalx.cfg', + 'bundle:nodejs', + }, + 'triggered': True, + }, } users = { @@ -79,6 +90,7 @@ git_deploy = { 'action:pretalx_install', 'action:pretalx_migrate', 'action:pretalx_rebuild', + 'action:pretalx_regenerate-css', 'svc_systemd:pretalx-web:restart', 'svc_systemd:pretalx-worker:restart', }, @@ -109,6 +121,7 @@ svc_systemd = { 'action:pretalx_install', 'action:pretalx_migrate', 'action:pretalx_rebuild', + 'action:pretalx_regenerate-css', 'file:/etc/systemd/system/pretalx-web.service', 'file:/opt/pretalx/pretalx.cfg', }, @@ -117,7 +130,6 @@ svc_systemd = { 'needs': { 'action:pretalx_install', 'action:pretalx_migrate', - 'action:pretalx_rebuild', 'file:/etc/systemd/system/pretalx-worker.service', 'file:/opt/pretalx/pretalx.cfg', }, @@ -192,6 +204,7 @@ for plugin_name, plugin_config in node.metadata.get('pretalx/plugins', {}).items 'triggers': { 'action:pretalx_migrate', 'action:pretalx_rebuild', + 'action:pretalx_regenerate-css', 'svc_systemd:pretalx-web:restart', 'svc_systemd:pretalx-worker:restart', }, diff --git a/bundles/pretalx/metadata.py b/bundles/pretalx/metadata.py index 15b61e3..7bbad24 100644 --- a/bundles/pretalx/metadata.py +++ b/bundles/pretalx/metadata.py @@ -27,7 +27,7 @@ defaults = { }, }, 'nodejs': { - 'version': 22, + 'version': 18, }, 'pretalx': { 'database': { diff --git a/bundles/proftpd/items.py b/bundles/proftpd/items.py deleted file mode 100644 index 506fb1b..0000000 --- a/bundles/proftpd/items.py +++ /dev/null @@ -1,13 +0,0 @@ -files['/etc/proftpd/proftpd.conf'] = { - 'source': f'{node.name}.conf', - 'triggers': { - 'svc_systemd:proftpd:restart', - }, -} - -svc_systemd['proftpd'] = { - 'needs': { - 'file:/etc/proftpd/proftpd.conf', - 'pkg_apt:proftpd-core', - }, -} diff --git a/bundles/proftpd/metadata.py b/bundles/proftpd/metadata.py deleted file mode 100644 index ad33bfb..0000000 --- a/bundles/proftpd/metadata.py +++ /dev/null @@ -1,26 +0,0 @@ -from bundlewrap.metadata import atomic - -defaults = { - 'apt': { - 'packages': { - 'proftpd-core': {}, - }, - }, -} - - -@metadata_reactor.provides( - 'firewall/port_rules', -) -def firewall(metadata): - sources = atomic(metadata.get('mosquitto/restrict-to', set())) - - return { - 'firewall': { - 'port_rules': { - '20/tcp': sources, - '21/tcp': sources, - '49152-50192/tcp': sources, - }, - }, - } diff --git a/bundles/radvd/files/radvd.conf b/bundles/radvd/files/radvd.conf index ee40111..c66c08f 100644 --- a/bundles/radvd/files/radvd.conf +++ b/bundles/radvd/files/radvd.conf @@ -10,13 +10,11 @@ interface ${interface} AdvOnLink on; AdvAutonomous on; AdvRouterAddr on; - AdvPreferredLifetime 600; - AdvValidLifetime 900; }; % if config.get('rdnss'): RDNSS ${' '.join(sorted(config['rdnss']))} { - AdvRDNSSLifetime 600; + AdvRDNSSLifetime 900; }; % endif }; diff --git a/bundles/redis/files/redis.conf b/bundles/redis/files/redis.conf index f636ddf..f479be2 100644 --- a/bundles/redis/files/redis.conf +++ b/bundles/redis/files/redis.conf @@ -48,4 +48,3 @@ tcp-keepalive 0 timeout 0 zset-max-ziplist-entries 128 zset-max-ziplist-value 64 -protected-mode no diff --git a/bundles/redis/metadata.py b/bundles/redis/metadata.py index db31a84..cf15c20 100644 --- a/bundles/redis/metadata.py +++ b/bundles/redis/metadata.py @@ -1,5 +1,3 @@ -from bundlewrap.metadata import atomic - defaults = { 'apt': { 'packages': { @@ -50,16 +48,3 @@ if node.has_bundle('telegraf'): }, }, } - - -@metadata_reactor.provides( - 'firewall/port_rules', -) -def firewall(metadata): - return { - 'firewall': { - 'port_rules': { - '6379/tcp': atomic(metadata.get('redis/restrict-to', set())), - }, - }, - } diff --git a/bundles/routeros/metadata.py b/bundles/routeros/metadata.py index e987a4e..ca7979f 100644 --- a/bundles/routeros/metadata.py +++ b/bundles/routeros/metadata.py @@ -2,6 +2,7 @@ import re from json import load from os.path import join + with open(join(repo.path, 'configs', 'netbox', f'{node.name}.json')) as f: netbox = load(f) diff --git a/bundles/rspamd/files/local.d/dmarc.conf b/bundles/rspamd/files/local.d/dmarc.conf index 195361e..fa42ec0 100644 --- a/bundles/rspamd/files/local.d/dmarc.conf +++ b/bundles/rspamd/files/local.d/dmarc.conf @@ -1,7 +1,7 @@ reporting { enabled = true; - email = 'devnull@${node.metadata.get('postfix/myhostname')}'; - domain = '${node.metadata.get('postfix/myhostname')}'; + email = 'dmarc+${node.name.replace('.', '-')}@kunbox.net'; + domain = '${node.metadata.get('hostname')}'; org_name = 'kunbox.net'; smtp = '127.0.0.1'; smtp_port = 25; diff --git a/bundles/rspamd/items.py b/bundles/rspamd/items.py index 2f9aacb..0491d17 100644 --- a/bundles/rspamd/items.py +++ b/bundles/rspamd/items.py @@ -96,7 +96,7 @@ if 'dkim' in node.metadata.get('rspamd', {}): }, } - dkim_key = repo.libs.faults.ensure_fault_or_none(node.metadata.get('rspamd/dkim')) + dkim_key = repo.libs.faults.ensure_fault_or_none(node.metadata['rspamd']['dkim']) actions = { 'rspamd_assure_dkim_key_permissions': { diff --git a/bundles/rsyslogd/metadata.py b/bundles/rsyslogd/metadata.py index 877e93b..aec2591 100644 --- a/bundles/rsyslogd/metadata.py +++ b/bundles/rsyslogd/metadata.py @@ -6,11 +6,6 @@ defaults = { 'rsyslog': {}, }, }, - 'backups': { - 'paths': { - '/var/log/rsyslog', - }, - }, 'icinga2_api': { 'rsyslog': { 'services': { diff --git a/bundles/samba/files/smb.conf b/bundles/samba/files/smb.conf index 7c4ad0b..c9a7859 100644 --- a/bundles/samba/files/smb.conf +++ b/bundles/samba/files/smb.conf @@ -13,13 +13,6 @@ map to guest = bad user load printers = no usershare allow guests = yes allow insecure wide links = yes -min protocol = SMB2 -% if timemachine: -vfs objects = fruit -fruit:aapl = yes -fruit:copyfile = yes -fruit:model = MacSamba -% endif % for name, opts in sorted(node.metadata.get('samba/shares', {}).items()): [${name}] @@ -44,24 +37,3 @@ follow symlinks = yes wide links = yes % endif % endfor -% for name in sorted(timemachine): - -[timemachine-${name}] -comment = Time Machine backup for ${name} -available = yes -browseable = yes -guest ok = no -read only = false -valid users = timemachine-${name} -path = /srv/timemachine/${name} -durable handles = yes -vfs objects = catia fruit streams_xattr - -fruit:delete_empty_adfiles = yes -fruit:metadata = stream -fruit:posix_rename = yes -fruit:time machine = yes -fruit:time machine max size = 2000G -fruit:veto_appledouble = no -fruit:wipe_intentionally_left_blank_rfork = yes -% endfor diff --git a/bundles/samba/files/timemachine.service b/bundles/samba/files/timemachine.service deleted file mode 100644 index d25e6e5..0000000 --- a/bundles/samba/files/timemachine.service +++ /dev/null @@ -1,21 +0,0 @@ - - - - %h - - _smb._tcp - 445 - - - _device-info._tcp - 0 - model=RackMac1,2 - - - _adisk._tcp -% for idx, share_name in enumerate(sorted(shares)): - dk${idx}=adVN=timemachine-${share_name},adVF=0x82 -% endfor - sys=waMa=0,adVF=0x100 - - diff --git a/bundles/samba/items.py b/bundles/samba/items.py index 2f5090e..333a338 100644 --- a/bundles/samba/items.py +++ b/bundles/samba/items.py @@ -11,14 +11,9 @@ svc_systemd = { }, } -timemachine_shares = node.metadata.get('samba/timemachine-shares', set()) - files = { '/etc/samba/smb.conf': { 'content_type': 'mako', - 'context': { - 'timemachine': timemachine_shares, - }, 'triggers': { 'svc_systemd:nmbd:restart', 'svc_systemd:smbd:restart', @@ -62,30 +57,3 @@ for user, uconfig in node.metadata.get('users', {}).items(): last_action = { f'action:smbpasswd_for_user_{user}', } - -if timemachine_shares: - assert node.has_bundle('avahi-daemon'), f'{node.name}: samba needs avahi-daemon to publish time machine shares' - - for share, share_config in node.metadata.get('samba/shares', {}).items(): - assert not share_config.get('guest_ok', True), f'{node.name} samba {share}: cannot have time machine shares and "guest ok" shares on the same machine' - - files['/etc/avahi/services/timemachine.service'] = { - 'content_type': 'mako', - 'context': { - 'shares': timemachine_shares, - }, - } - - for share_name in timemachine_shares: - users[f'timemachine-{share_name}'] = { - 'home': f'/srv/timemachine/{share_name}', - } - - directories[f'/srv/timemachine/{share_name}'] = { - 'owner': f'timemachine-{share_name}', - 'group': f'timemachine-{share_name}', - 'mode': '0700', - 'needs': { - f'zfs_dataset:tank/timemachine/{share_name}', - }, - } diff --git a/bundles/samba/metadata.py b/bundles/samba/metadata.py index c8243af..7b9400c 100644 --- a/bundles/samba/metadata.py +++ b/bundles/samba/metadata.py @@ -24,30 +24,3 @@ def firewall(metadata): }, }, } - - -@metadata_reactor.provides( - 'zfs/datasets', -) -def timemachine_zfs(metadata): - shares = metadata.get('samba/timemachine-shares', set()) - - if not shares: - return {} - - assert node.has_bundle('zfs'), f'{node.name}: time machine backups require zfs' - - datasets = { - 'tank/timemachine': {}, - } - - for share_name in shares: - datasets[f'tank/timemachine/{share_name}'] = { - 'mountpoint': f'/srv/timemachine/{share_name}', - } - - return { - 'zfs': { - 'datasets': datasets, - }, - } diff --git a/bundles/scansnap/files/ocr.sh b/bundles/scansnap/files/ocr.sh new file mode 100644 index 0000000..04e98f9 --- /dev/null +++ b/bundles/scansnap/files/ocr.sh @@ -0,0 +1,21 @@ +#!/bin/bash + +set -euo pipefail + +DATE=$(date +%F_%H-%M-%S) + +cd "$1" + +convert *.tiff no_ocr.pdf +ocrmypdf -l deu no_ocr.pdf has_ocr.pdf + +rm -f *.tiff +rm -f no_ocr.pdf + +chown nobody:nogroup has_ocr.pdf + +mv has_ocr.pdf "/srv/scansnap/${DATE}.pdf" + +cd / + +rm -r "$1" diff --git a/bundles/scansnap/files/scan.sh b/bundles/scansnap/files/scan.sh new file mode 100644 index 0000000..ab5800f --- /dev/null +++ b/bundles/scansnap/files/scan.sh @@ -0,0 +1,9 @@ +#!/bin/bash + +set -euo pipefail + +OUTFILE=$(mktemp -d) + +scanimage --source 'ADF Duplex' --format tiff --mode Color --brightness 23 --resolution 300 --page-width 210 --page-height 297.3 -x 210 -y 297.3 --batch=${OUTFILE}/p%04d.tiff + +/etc/scanbd/scripts/ocr.sh "$OUTFILE" & diff --git a/bundles/scansnap/files/scanbd.conf b/bundles/scansnap/files/scanbd.conf new file mode 100644 index 0000000..f425338 --- /dev/null +++ b/bundles/scansnap/files/scanbd.conf @@ -0,0 +1,52 @@ +global { + debug = true + debug-level = 2 + + user = saned + group = scanner + + saned = "/usr/sbin/saned" + saned_opt = {} + saned_env = { "SANE_CONFIG_DIR=/etc/scanbd" } + + scriptdir = /etc/scanbd/scripts + + timeout = 500 + + pidfile = "/var/run/scanbd.pid" + + environment { + device = "SCANBD_DEVICE" + action = "SCANBD_ACTION" + } + + function function_knob { + filter = "^message.*" + desc = "The value of the function knob / wheel / selector" + env = "SCANBD_FUNCTION" + } + function function_mode { + filter = "^mode.*" + desc = "Color mode" + env = "SCANBD_FUNCTION_MODE" + } + + multiple_actions = false + action scan { + filter = "^scan.*" + numerical-trigger { + from-value = 0 + to-value = 1 + } + desc = "Scan to file" + script = "scan.sh" + } +} + +include(scanner.d/avision.conf) +include(scanner.d/fujitsu.conf) +include(scanner.d/hp.conf) +include(scanner.d/pixma.conf) +include(scanner.d/snapscan.conf) +include(scanner.d/canon.conf) +include(scanner.d/plustek.conf) diff --git a/bundles/scansnap/items.py b/bundles/scansnap/items.py new file mode 100644 index 0000000..23f9305 --- /dev/null +++ b/bundles/scansnap/items.py @@ -0,0 +1,39 @@ +directories = { + '/etc/scanbd/scripts': { + 'purge': True, + }, + '/srv/scansnap': { + 'owner': 'nobody', + 'group': 'nogroup', + }, +} + +files = { + '/etc/scanbd/scanbd.conf': { + 'triggers': { + 'svc_systemd:scanbd:restart', + }, + }, + '/etc/scanbd/scripts/ocr.sh': { + 'mode': '0755', + 'needs': { + 'directory:/srv/scansnap', + }, + }, + '/etc/scanbd/scripts/scan.sh': { + 'mode': '0755', + 'needs': { + 'directory:/srv/scansnap', + 'file:/etc/scanbd/scripts/ocr.sh', + }, + }, +} + +svc_systemd = { + 'scanbd': { + 'needs': { + 'file:/etc/scanbd/scanbd.conf', + 'pkg_apt:scanbd', + }, + }, +} diff --git a/bundles/scansnap/metadata.py b/bundles/scansnap/metadata.py new file mode 100644 index 0000000..b1d5535 --- /dev/null +++ b/bundles/scansnap/metadata.py @@ -0,0 +1,22 @@ +defaults = { + 'apt': { + 'packages': { + 'sane-utils': {}, + 'scanbd': {}, + 'imagemagick': {}, + 'ocrmypdf': {}, + 'tesseract-ocr-deu': {}, + }, + }, + 'backups': { + 'paths': { + '/srv/scansnap', + }, + }, + 'cron': { + 'jobs': { + # Automatically remove files which are older than 14 days + 'scansnap_cleanup': '00 00 * * * root /usr/bin/find /srv/scansnap/ -mindepth 1 -mtime +14 -delete', + }, + }, +} diff --git a/bundles/smartd/metadata.py b/bundles/smartd/metadata.py index 5202068..73789d0 100644 --- a/bundles/smartd/metadata.py +++ b/bundles/smartd/metadata.py @@ -43,6 +43,30 @@ if node.has_bundle('telegraf'): } +@metadata_reactor.provides( + 'smartd/disks', +) +def zfs_disks_to_metadata(metadata): + disks = set() + + for config in metadata.get('zfs/pools', {}).values(): + for option in config['when_creating']['config']: + if option.get('type', '') in {'log', 'cache'}: + continue + + for disk in option['devices']: + if search(r'p([0-9]+)$', disk) or disk.startswith('/dev/mapper/'): + continue + + disks.add(disk) + + return { + 'smartd': { + 'disks': disks, + }, + } + + @metadata_reactor.provides( 'icinga2_api/smartd/services', ) diff --git a/bundles/sshmon/files/check_cpu_stats b/bundles/sshmon/files/check_cpu_stats index f0c3a35..36e5ae3 100644 --- a/bundles/sshmon/files/check_cpu_stats +++ b/bundles/sshmon/files/check_cpu_stats @@ -4,30 +4,27 @@ from re import findall from subprocess import check_output from sys import exit -ITERATIONS = 10 - try: top_output = None - top_output = check_output(rf"top -b -n{ITERATIONS} -d1 | grep -i '^%cpu'", shell=True).decode('UTF-8') + for line in check_output(['top', '-b', '-n1', '-d1']).decode('UTF-8').splitlines(): + if line.lower().strip().startswith('%cpu'): + top_output = line.lower().split(':', 2)[1] + break + + if not top_output: + print('%cpu not found in top output') + exit(3) cpu_usage = {} - for value, identifier in findall(r'([0-9\.\,]{3,5}) ([a-z]{2})', top_output): - if identifier not in cpu_usage: - cpu_usage[identifier] = 0.0 - cpu_usage[identifier] += float(value.replace(',', '.')) - - output = [] - for identifier, value_added in cpu_usage.items(): - value = value_added / ITERATIONS - output.append(f"{value:.2f} {identifier}") - cpu_usage[identifier] = value - - print(f"Average over {ITERATIONS} seconds: " + ", ".join(output)) + for value, identifier in findall('([0-9\.\,]{3,5}) ([a-z]{2})', top_output): + cpu_usage[identifier] = float(value.replace(',', '.')) warn = set() crit = set() + print(top_output) + # steal if cpu_usage['st'] > 10: crit.add('CPU steal is {}% (>10%)'.format(cpu_usage['st'])) diff --git a/bundles/sshmon/files/check_forgejo_for_new_release b/bundles/sshmon/files/check_forgejo_for_new_release index 99dcd30..3db5bcd 100644 --- a/bundles/sshmon/files/check_forgejo_for_new_release +++ b/bundles/sshmon/files/check_forgejo_for_new_release @@ -38,10 +38,10 @@ try: for i in releases: if i["tag_name"].startswith(tag_prefix): - if not (i["prerelease"] or i["draft"]) and ( + if ( newest_release is None or parse(i["tag_name"]) > parse(newest_release["tag_name"]) - ): + ) and not (i["prerelease"] or i["draft"]): newest_release = i assert newest_release is not None, "Could not determine latest release" diff --git a/bundles/sshmon/files/check_github_for_new_release b/bundles/sshmon/files/check_github_for_new_release index ec510de..3a50d94 100644 --- a/bundles/sshmon/files/check_github_for_new_release +++ b/bundles/sshmon/files/check_github_for_new_release @@ -37,10 +37,10 @@ try: for i in releases: if i["tag_name"].startswith(tag_prefix): - if not (i["prerelease"] or i["draft"]) and ( + if ( newest_release is None or parse(i["tag_name"]) > parse(newest_release["tag_name"]) - ): + ) and not (i["prerelease"] or i["draft"]): newest_release = i assert newest_release is not None, "Could not determine latest release" diff --git a/bundles/sshmon/files/check_https_certificate_at_url b/bundles/sshmon/files/check_https_certificate_at_url index ce0f0ba..e9fb507 100644 --- a/bundles/sshmon/files/check_https_certificate_at_url +++ b/bundles/sshmon/files/check_https_certificate_at_url @@ -22,8 +22,7 @@ case "$issuer_hash" in # 462422cf: issuer=C = US, O = Let's Encrypt, CN = E5 # 9aad238c: issuer=C = US, O = Let's Encrypt, CN = E6 # 31dfb39d: issuer=C = US, O = Let's Encrypt, CN = R11 - # aa578057: issuer=C = US, O = Let's Encrypt, CN = R10 - 4f06f81d|8d33f237|462422cf|9aad238c|31dfb39d|aa578057) + 4f06f81d|8d33f237|462422cf|9aad238c|31dfb39d) warn_days=10 crit_days=3 ;; diff --git a/bundles/sshmon/items.py b/bundles/sshmon/items.py index be9a9a4..3250f39 100644 --- a/bundles/sshmon/items.py +++ b/bundles/sshmon/items.py @@ -64,3 +64,12 @@ for check in { files["/usr/local/share/icinga/plugins/check_{}".format(check)] = { 'mode': "0755", } + + +if node.has_bundle('pacman'): + symlinks['/usr/lib/nagios/plugins'] = { + 'target': '/usr/lib/monitoring-plugins', + 'needs': { + 'pkg_pacman:monitoring-plugins', + }, + } diff --git a/bundles/sshmon/metadata.py b/bundles/sshmon/metadata.py index 3026479..8d5bb6b 100644 --- a/bundles/sshmon/metadata.py +++ b/bundles/sshmon/metadata.py @@ -19,8 +19,6 @@ defaults = { 'services': { 'CPU': { 'command_on_monitored_host': '/usr/local/share/icinga/plugins/check_cpu_stats', - # takes samples over 10 seconds - 'vars.sshmon_timeout': 20 }, 'LOAD': { 'command_on_monitored_host': '/usr/lib/nagios/plugins/check_load -r -w 4,2,1 -c 8,4,2', @@ -36,6 +34,14 @@ defaults = { 'sshmon', }, }, + 'pacman': { + 'packages': { + 'gawk': {}, + 'perl-libwww': {}, + 'monitoring-plugins': {}, + 'python-requests': {}, + }, + }, } diff --git a/bundles/sudo/metadata.py b/bundles/sudo/metadata.py index e76edaf..82b007d 100644 --- a/bundles/sudo/metadata.py +++ b/bundles/sudo/metadata.py @@ -4,4 +4,9 @@ defaults = { 'sudo': {}, }, }, + 'pacman': { + 'packages': { + 'sudo': {}, + }, + }, } diff --git a/bundles/systemd-boot/files/entry b/bundles/systemd-boot/files/entry new file mode 100755 index 0000000..00d3d8f --- /dev/null +++ b/bundles/systemd-boot/files/entry @@ -0,0 +1,13 @@ +title ${config['title']} + +% if 'linux' in config: +linux ${config['linux']} +% for line in config['initrd']: +initrd ${line} +% endfor +% if config.get('options', set()): +options ${' '.join(sorted(config['options']))} +% endif +% else: +efi ${config['efi']} +% endif diff --git a/bundles/systemd-boot/files/loader.conf b/bundles/systemd-boot/files/loader.conf new file mode 100755 index 0000000..b30de61 --- /dev/null +++ b/bundles/systemd-boot/files/loader.conf @@ -0,0 +1,5 @@ +auto-entries no +auto-firmware yes +console-mode keep +default ${config['default']} +timeout ${config.get('timeout', 5)} diff --git a/bundles/systemd-boot/files/pacman_hook b/bundles/systemd-boot/files/pacman_hook new file mode 100644 index 0000000..d65c027 --- /dev/null +++ b/bundles/systemd-boot/files/pacman_hook @@ -0,0 +1,9 @@ +[Trigger] +Type = Package +Operation = Upgrade +Target = systemd + +[Action] +Description = Gracefully upgrading systemd-boot... +When = PostTransaction +Exec = /usr/bin/systemctl restart systemd-boot-update.service diff --git a/bundles/systemd-boot/items.py b/bundles/systemd-boot/items.py new file mode 100644 index 0000000..0f26d00 --- /dev/null +++ b/bundles/systemd-boot/items.py @@ -0,0 +1,32 @@ +assert node.os == 'arch' +assert node.metadata.get('systemd-boot/default') in node.metadata.get('systemd-boot/entries') + +files = { + '/etc/pacman.d/hooks/99-systemd-boot-update': { + 'source': 'pacman_hook', + }, + '/boot/loader/loader.conf': { + 'content_type': 'mako', + 'context': { + 'config': node.metadata.get('systemd-boot'), + }, + 'mode': None, + }, +} + +directories = { + '/boot/loader/entries': { + 'purge': True, + }, +} + +for entry, config in node.metadata.get('systemd-boot/entries').items(): + files[f'/boot/loader/entries/{entry}.conf'] = { + 'source': 'entry', + 'content_type': 'mako', + 'context': { + 'entry': entry, + 'config': config, + }, + 'mode': None, + } diff --git a/bundles/systemd-timers/files/template.service b/bundles/systemd-timers/files/template.service index 271b756..09c3080 100644 --- a/bundles/systemd-timers/files/template.service +++ b/bundles/systemd-timers/files/template.service @@ -7,11 +7,8 @@ [Unit] Description=Service for Timer ${timer} After=network.target -% if config.get('requires', set()): -Requires=${' '.join(sorted(config['requires']))} -% endif -% if config.get('requisite', set()): -Requisite=${' '.join(sorted(config['requisite']))} +% if config.get('requires', ''): +Requires=${config['requires']} % endif [Service] diff --git a/bundles/systemd/items.py b/bundles/systemd/items.py index 005696e..c8ecbd9 100644 --- a/bundles/systemd/items.py +++ b/bundles/systemd/items.py @@ -1,4 +1,4 @@ -timezone = node.metadata.get('timezone') +timezone = node.metadata.get('timezone', 'UTC') actions['systemd-reload'] = { 'command': 'systemctl daemon-reload', diff --git a/bundles/systemd/metadata.py b/bundles/systemd/metadata.py index 76f2016..15f9b8a 100644 --- a/bundles/systemd/metadata.py +++ b/bundles/systemd/metadata.py @@ -21,7 +21,6 @@ defaults = { }, }, }, - 'timezone': 'UTC', } if not node.has_bundle('rsyslogd'): diff --git a/bundles/telegraf/metadata.py b/bundles/telegraf/metadata.py index 4af8190..097750e 100644 --- a/bundles/telegraf/metadata.py +++ b/bundles/telegraf/metadata.py @@ -25,4 +25,14 @@ defaults = { }, }, }, + 'pacman': { + 'packages': { + 'telegraf-bin': { + 'needed_by': { + 'svc_systemd:telegraf', + 'user:telegraf', + }, + }, + }, + }, } diff --git a/bundles/travelynx/files/travelynx.conf b/bundles/travelynx/files/travelynx.conf index f73e85f..46883cf 100644 --- a/bundles/travelynx/files/travelynx.conf +++ b/bundles/travelynx/files/travelynx.conf @@ -33,12 +33,6 @@ from => '${mail_from}', }, -% if not enable_registration: - registration => { - disabled => 1, - }, -% endif - ref => { issues => 'https://github.com/derf/travelynx/issues', source => 'https://github.com/derf/travelynx', diff --git a/bundles/travelynx/metadata.py b/bundles/travelynx/metadata.py index 630fd27..b7dadd6 100644 --- a/bundles/travelynx/metadata.py +++ b/bundles/travelynx/metadata.py @@ -10,12 +10,11 @@ defaults = { 'password': repo.vault.password_for('{} postgresql travelynx'.format(node.name)), 'database': 'travelynx', }, - 'additional_cookie_secrets': set(), - 'cookie_secret': repo.vault.password_for('{} travelynx cookie_secret'.format(node.name)), - 'enable_registration': False, - 'mail_from': 'travelynx@{}'.format(node.hostname), - 'spare_workers': 2, 'workers': 4, + 'spare_workers': 2, + 'mail_from': 'travelynx@{}'.format(node.hostname), + 'cookie_secret': repo.vault.password_for('{} travelynx cookie_secret'.format(node.name)), + 'additional_cookie_secrets': set(), }, 'postgresql': { 'roles': { diff --git a/bundles/users/metadata.py b/bundles/users/metadata.py index e6f3498..48a8b72 100644 --- a/bundles/users/metadata.py +++ b/bundles/users/metadata.py @@ -7,6 +7,11 @@ defaults = { 'kitty-terminfo': {}, }, }, + 'pacman': { + 'packages': { + 'kitty-terminfo': {}, + }, + }, 'users': { 'root': { 'home': '/root', diff --git a/bundles/vmhost/items.py b/bundles/vmhost/items.py index 402e8ec..e432a40 100644 --- a/bundles/vmhost/items.py +++ b/bundles/vmhost/items.py @@ -24,3 +24,12 @@ if node.has_bundle('nftables') and node.has_bundle('apt'): 'svc_systemd:nftables:reload', }, } + +if node.has_bundle('pacman'): + svc_systemd['libvirtd'] = { + 'running': None, # triggered via .socket + } + svc_systemd['virtlogd'] = { + 'running': None, # triggered via .socket + 'enabled': None, # triggered via .socket + } diff --git a/bundles/vmhost/metadata.py b/bundles/vmhost/metadata.py index 79f9d8a..3aaa10e 100644 --- a/bundles/vmhost/metadata.py +++ b/bundles/vmhost/metadata.py @@ -21,6 +21,12 @@ defaults = { }, }, }, + 'pacman': { + 'packages': { + 'edk2-ovmf': {}, + 'libvirt': {}, + }, + }, } if node.os == 'debian' and node.os_version[0] < 11: @@ -36,6 +42,9 @@ if node.has_bundle('nftables'): }, } +if node.has_bundle('arch-with-gui'): + defaults['pacman']['packages']['virt-manager'] = {} + @metadata_reactor.provides( 'users', diff --git a/bundles/voc-tracker-worker/files/crs-runner.service b/bundles/voc-tracker-worker/files/crs-runner.service new file mode 100644 index 0000000..1c85a33 --- /dev/null +++ b/bundles/voc-tracker-worker/files/crs-runner.service @@ -0,0 +1,16 @@ +[Unit] +Description=CRS runner for ${script} +After=network.target + +[Service] +User=voc +Group=voc +EnvironmentFile=/etc/default/crs-worker +ExecStart=/opt/crs-scripts/bin/crs_run ${script} +WorkingDirectory=/opt/crs-scripts +Restart=on-failure +RestartSec=10 +SyslogIdentifier=crs-${worker} + +[Install] +WantedBy=crs-worker.target diff --git a/bundles/voc-tracker-worker/files/environment b/bundles/voc-tracker-worker/files/environment new file mode 100644 index 0000000..98f40ea --- /dev/null +++ b/bundles/voc-tracker-worker/files/environment @@ -0,0 +1,6 @@ +CRS_TRACKER=${url} +CRS_TOKEN=${token} +CRS_SECRET=${secret} +% if use_vaapi: +CRS_USE_VAAPI=yes +% endif diff --git a/bundles/voc-tracker-worker/items.py b/bundles/voc-tracker-worker/items.py new file mode 100644 index 0000000..6f28a8b --- /dev/null +++ b/bundles/voc-tracker-worker/items.py @@ -0,0 +1,56 @@ +paths = { # subpaths of /video + 'capture', + 'encoded', + 'fuse', + 'intros', + 'repair', + 'tmp', +} + +directories = { + '/opt/crs-scripts': {}, +} + +for path in paths: + directories[f'/video/{path}'] = { + 'owner': 'voc', + 'group': 'voc', + } + +git_deploy = { + '/opt/crs-scripts': { + 'repo': 'https://github.com/crs-tools/crs-scripts.git', + 'rev': 'master', + }, +} + +files = { + '/etc/default/crs-worker': { + 'content_type': 'mako', + 'source': 'environment', + 'context': node.metadata.get('voc-tracker-worker'), + }, +} + +for worker, script in { + 'recording-scheduler': 'script-A-recording-scheduler.pl', + 'mount4cut': 'script-B-mount4cut.pl', + 'cut-postprocessor': 'script-C-cut-postprocessor.pl', + 'encoding': 'script-D-encoding.pl', + 'postencoding': 'script-E-postencoding-auphonic.pl', + 'postprocessing': 'script-F-postprocessing-upload.pl', +}.items(): + files[f'/etc/systemd/system/crs-{worker}.service'] = { + 'content_type': 'mako', + 'source': 'crs-runner.service', + 'context': { + 'worker': worker, + 'script': script, + }, + 'needs': { + 'file:/etc/default/crs-worker', + }, + 'triggers': { + 'action:systemd-reload', + }, + } diff --git a/bundles/voc-tracker-worker/metadata.py b/bundles/voc-tracker-worker/metadata.py new file mode 100644 index 0000000..3a741a8 --- /dev/null +++ b/bundles/voc-tracker-worker/metadata.py @@ -0,0 +1,52 @@ +defaults = { + 'apt': { + 'packages': { + 'ffmpeg': {}, + 'fuse': {}, + 'fuse-ts': {}, + 'libboolean-perl': {}, + 'libconfig-inifiles-perl': {}, + 'libdatetime-perl': {}, + 'libfile-which-perl': {}, + 'libipc-run3-perl': {}, + 'libjson-perl': {}, + 'libmath-round-perl': {}, + 'libproc-processtable-perl': {}, + 'libwww-curl-perl': {}, + 'libxml-rpc-fast-perl': {}, + 'libxml-simple-perl': {}, + }, + }, + 'voc-tracker-worker': { + 'use_vaapi': False, + }, + 'users': { + 'voc': { + 'home': '/opt/voc', + }, + }, + 'pacman': { + 'packages': { + 'ffmpeg': {}, + 'fuse2': {}, + 'fuse3': {}, + # fuse-ts missing + 'perl-boolean': {}, # from aurto + 'perl-config-inifiles': {}, + 'perl-datetime': {}, + 'perl-file-which': {}, + 'perl-ipc-run3': {}, + 'perl-json': {}, + 'perl-math-round': {}, + 'perl-proc-processtable': {}, + 'perl-www-curl': {}, # from aurto + 'perl-xml-simple': {}, + }, + }, +} + +# Install manually from CPAN: +# IO::Socket::SSL +# LWP::Protocol::https +# Types::Serialiser::Error +# XML::RPC::Fast diff --git a/bundles/wireguard/metadata.py b/bundles/wireguard/metadata.py index 267be6a..c08d5ca 100644 --- a/bundles/wireguard/metadata.py +++ b/bundles/wireguard/metadata.py @@ -283,7 +283,7 @@ def interface_ips(metadata): 'nftables/postrouting/10-wireguard', ) def snat(metadata): - if not node.has_bundle('nftables'): + if not node.has_bundle('nftables') or node.os == 'arch': raise DoNotRunAgain snat_ip = metadata.get('wireguard/snat_ip', None) diff --git a/bundles/zfs/files/zfs-import-scan-override.service b/bundles/zfs/files/zfs-import-scan-override.service index 9004ee2..3853425 100644 --- a/bundles/zfs/files/zfs-import-scan-override.service +++ b/bundles/zfs/files/zfs-import-scan-override.service @@ -3,4 +3,8 @@ ConditionPathExists= [Service] ExecStart= +% if node.os == 'arch': +ExecStart=/usr/bin/zpool import -aN -o cachefile=none +% else: ExecStart=/usr/sbin/zpool import -aN -o cachefile=none +% endif diff --git a/bundles/zfs/items.py b/bundles/zfs/items.py index 530d27f..c63250e 100644 --- a/bundles/zfs/items.py +++ b/bundles/zfs/items.py @@ -67,7 +67,6 @@ svc_systemd = { 'file:/etc/systemd/system/zfs-import-scan.service.d/bundlewrap.conf', }, 'after': { - 'bundle:dm-crypt', # might unlock disks 'pkg_apt:', }, 'before': { @@ -84,7 +83,6 @@ svc_systemd = { }, 'zfs-mount.service': { 'after': { - 'bundle:dm-crypt', # might unlock disks 'pkg_apt:', }, }, diff --git a/bundles/zfs/metadata.py b/bundles/zfs/metadata.py index 3b63e0b..a270d5f 100644 --- a/bundles/zfs/metadata.py +++ b/bundles/zfs/metadata.py @@ -43,6 +43,18 @@ defaults = { }, }, }, + 'pacman': { + 'no_extract': { + 'etc/sudoers.d/zfs', + }, + 'packages': { + 'zfs-utils': { + 'needed_by': { + 'svc_systemd:zfs-zed', + }, + }, + }, + }, 'systemd-timers': { 'timers': { 'zfs-auto-snapshot-daily': { @@ -109,6 +121,27 @@ if node.has_bundle('telegraf'): } +@metadata_reactor.provides( + 'pacman/packages', +) +def packages(metadata): + if node.metadata.get('pacman/linux-lts', False): + pkgname = 'zfs-linux-lts' + else: + pkgname = 'zfs-linux' + return { + 'pacman': { + 'packages': { + pkgname: { + 'needed_by': { + 'zfs_dataset:', + 'zfs_pool:', + }, + }, + }, + }, + } + @metadata_reactor.provides( 'apt/packages', ) @@ -137,7 +170,7 @@ def scrub_timer(metadata): 'systemd-timers': { 'timers': { 'zfs-scrub': { - 'when': metadata.get('zfs/scrub_when', 'Sun 02:00:00 UTC'), + 'when': 'Sun 02:00:00 UTC', 'command': scrubs, }, }, diff --git a/configs/as3320.txt b/configs/as3320.txt index 0ac3052..2a42ee0 100644 --- a/configs/as3320.txt +++ b/configs/as3320.txt @@ -1,8 +1,5 @@ -109.203.176.0/21 109.237.176.0/20 -109.72.116.0/24 116.50.16.0/21 -128.65.164.0/22 129.181.208.0/21 129.181.216.0/22 137.170.112.0/24 @@ -18,11 +15,13 @@ 139.12.4.0/24 141.169.240.0/20 141.77.0.0/16 +141.98.44.0/24 143.99.213.0/24 145.225.16.0/23 +146.247.58.0/24 +147.136.84.0/22 147.161.22.0/24 147.78.17.0/24 -147.79.8.0/21 149.208.250.0/23 149.208.252.0/24 149.208.253.0/24 @@ -31,14 +30,10 @@ 149.237.203.0/24 149.237.250.0/24 149.237.251.0/24 -149.237.254.0/24 149.243.232.0/22 149.249.244.0/22 149.249.244.0/23 149.249.246.0/23 -151.243.168.0/24 -151.243.173.0/24 -153.17.244.8/29 153.17.249.0/24 153.17.250.0/24 153.17.251.0/24 @@ -49,14 +44,9 @@ 153.96.218.0/24 153.96.22.0/24 153.97.32.0/24 -153.97.34.0/24 158.116.231.0/24 -163.5.156.0/24 -163.5.170.0/24 -163.5.186.0/24 -163.5.220.0/24 -163.5.47.0/24 -163.5.66.0/24 +160.211.126.0/24 +163.5.168.0/24 164.133.10.0/24 164.133.11.0/24 164.133.150.0/24 @@ -70,9 +60,11 @@ 168.199.192.0/22 168.199.212.0/22 170.237.92.0/23 +171.25.178.0/24 +176.221.24.0/24 +176.221.25.0/24 176.53.136.0/24 176.53.137.0/24 -176.57.59.0/24 185.100.160.0/22 185.101.244.0/23 185.101.246.0/23 @@ -84,45 +76,46 @@ 185.131.239.0/24 185.133.12.0/22 185.136.115.0/24 +185.149.25.0/24 +185.149.26.0/24 +185.149.27.0/24 185.149.52.0/24 185.157.101.0/24 185.161.176.0/22 +185.162.72.0/23 185.163.76.0/24 185.163.77.0/24 185.163.78.0/24 185.163.79.0/24 +185.172.38.0/24 +185.172.39.0/24 185.180.224.0/24 185.183.212.0/23 185.183.214.0/23 185.188.64.0/24 -185.195.239.0/24 185.198.13.0/24 185.202.32.0/21 +185.203.148.0/22 185.207.46.0/24 -185.21.247.0/24 -185.224.0.0/24 +185.235.71.0/24 185.237.0.0/24 185.237.1.0/24 185.237.2.0/24 +185.240.85.0/24 185.242.224.0/24 185.243.44.0/22 185.243.44.0/24 185.243.45.0/24 185.243.46.0/24 185.243.47.0/24 +185.250.42.0/23 185.28.208.0/22 185.39.12.0/22 185.48.0.0/22 185.57.24.0/24 185.82.160.0/23 -185.97.227.0/24 -188.208.124.0/24 -188.208.125.0/24 -188.209.223.0/24 -188.214.136.0/24 -188.214.137.0/24 -188.214.138.0/24 -188.214.139.0/24 +185.91.204.0/22 +192.109.121.0/24 192.109.122.0/24 192.109.124.0/24 192.109.129.0/24 @@ -163,6 +156,7 @@ 193.100.248.0/22 193.100.252.0/24 193.100.3.0/24 +193.101.12.0/22 193.101.128.0/22 193.101.139.0/24 193.101.162.0/23 @@ -182,6 +176,7 @@ 193.110.102.0/23 193.110.102.0/24 193.110.103.0/24 +193.124.35.0/24 193.138.91.0/24 193.141.143.0/24 193.141.180.0/23 @@ -248,6 +243,7 @@ 193.41.10.0/23 193.47.164.0/24 193.53.93.0/24 +193.56.21.0/24 193.58.253.0/24 193.84.136.0/22 193.96.230.0/24 @@ -257,7 +253,6 @@ 193.98.224.0/24 193.99.96.0/20 194.0.151.0/24 -194.0.232.0/24 194.110.133.0/24 194.113.160.0/22 194.113.20.0/23 @@ -294,20 +289,12 @@ 194.127.242.0/23 194.127.254.0/24 194.145.252.0/24 -194.147.171.0/24 194.15.194.0/24 194.15.60.0/24 194.15.61.0/24 194.15.64.0/21 194.15.72.0/22 194.150.228.0/23 -194.152.128.0/24 -194.152.129.0/24 -194.152.132.0/24 -194.152.141.0/24 -194.152.142.0/24 -194.152.154.0/24 -194.152.155.0/24 194.153.86.0/24 194.156.128.0/22 194.156.148.0/24 @@ -329,6 +316,7 @@ 194.180.64.0/20 194.25.0.0/16 194.25.1.5/32 +194.26.191.0/24 194.31.142.0/24 194.31.208.0/24 194.31.209.0/24 @@ -339,11 +327,6 @@ 194.33.115.0/24 194.33.120.0/24 194.33.121.0/24 -194.33.50.0/24 -194.38.48.0/24 -194.38.49.0/24 -194.38.50.0/24 -194.38.51.0/24 194.39.175.0/24 194.39.189.0/24 194.39.48.0/20 @@ -354,20 +337,26 @@ 194.39.63.0/24 194.39.88.0/21 194.39.97.0/24 +194.45.144.0/21 +194.49.110.0/24 194.49.117.0/24 194.49.118.0/23 194.49.125.0/24 194.49.48.0/24 194.49.54.0/24 +194.49.72.0/24 194.49.73.0/24 194.49.74.0/23 194.49.85.0/24 +194.55.158.0/24 194.55.180.0/24 194.55.183.0/24 194.55.192.0/19 194.55.63.0/24 194.55.64.0/20 194.55.87.0/24 +194.58.40.0/24 +194.58.56.0/23 194.59.143.0/24 194.59.150.0/24 194.59.151.0/24 @@ -393,22 +382,34 @@ 194.76.52.0/24 194.77.41.0/24 194.77.42.0/24 +194.85.248.0/24 +194.85.251.0/24 +194.87.10.0/24 +194.87.17.0/24 +194.87.255.0/24 +194.87.77.0/24 +194.88.112.0/20 194.88.16.0/21 194.88.24.0/23 194.88.26.0/24 194.88.28.0/23 +194.88.96.0/21 194.99.118.0/24 194.99.34.0/24 194.99.76.0/23 194.99.83.0/24 194.99.92.0/22 +195.133.20.0/24 +195.133.64.0/22 195.133.7.0/24 +195.133.76.0/24 195.137.216.0/23 195.138.223.0/24 195.144.15.0/24 195.145.0.0/16 195.149.79.0/24 195.160.248.0/22 +195.178.132.0/22 195.190.2.0/24 195.192.254.0/24 195.200.207.0/24 @@ -435,17 +436,12 @@ 198.40.90.0/24 198.57.10.0/24 2.160.0.0/12 -2.58.100.0/24 2.58.102.0/24 -204.52.120.0/24 -204.52.121.0/24 204.69.32.0/24 205.142.63.0/24 212.184.0.0/15 212.185.0.0/16 -212.68.172.0/22 -212.68.176.0/22 -212.68.180.0/22 +212.87.217.0/24 213.145.90.0/23 213.145.92.0/23 213.173.0.0/19 @@ -454,7 +450,6 @@ 213.209.156.0/24 217.0.0.0/13 217.117.96.0/24 -217.177.33.0/24 217.224.0.0/11 217.24.32.0/20 217.24.33.0/24 @@ -464,26 +459,35 @@ 31.224.0.0/11 31.6.56.0/23 37.143.0.0/22 -37.230.61.0/24 +37.230.56.0/24 +37.230.57.0/24 +37.230.58.0/23 +37.230.60.0/24 +37.230.63.0/24 37.46.11.0/24 37.50.0.0/15 37.80.0.0/12 -45.112.192.0/24 -45.129.165.0/24 +45.128.14.0/23 +45.132.217.0/24 45.132.80.0/22 -45.141.54.0/24 -45.145.16.0/24 +45.140.208.0/24 +45.141.130.0/24 +45.142.236.0/24 +45.145.241.0/24 +45.145.243.0/24 45.147.227.0/24 -45.149.7.0/24 -45.155.77.0/24 45.81.255.0/24 45.83.136.0/22 +45.84.214.0/24 45.93.186.0/23 -46.202.0.0/24 +46.20.216.0/21 46.250.224.0/21 46.250.232.0/21 46.78.0.0/15 46.80.0.0/12 +5.10.208.0/24 +5.10.209.0/24 +5.10.220.0/24 5.133.112.0/24 5.249.188.0/22 5.35.192.0/21 @@ -496,15 +500,17 @@ 62.224.0.0/14 62.56.208.0/21 62.68.73.0/24 -62.72.172.0/24 64.137.119.0/24 64.137.125.0/24 64.137.127.0/24 +77.242.149.0/24 77.47.152.0/22 77.83.136.0/23 77.83.138.0/23 +77.83.32.0/22 77.90.156.0/24 77.90.184.0/24 +79.139.52.0/22 79.192.0.0/10 80.128.0.0/11 80.128.0.0/12 @@ -516,55 +522,38 @@ 80.157.8.0/21 80.187.0.0/16 80.187.160.0/20 -80.244.13.0/24 80.64.240.0/22 80.71.231.0/24 80.71.233.0/24 80.71.235.0/24 80.71.236.0/24 80.71.238.0/24 -80.83.80.0/21 81.201.32.0/20 -81.31.210.0/23 -82.163.104.0/21 +81.30.96.0/20 +82.152.178.0/24 82.163.60.0/22 82.206.32.0/21 82.206.40.0/21 -82.206.48.0/21 82.215.70.0/24 +83.136.208.0/22 +83.147.36.0/22 83.243.48.0/21 84.128.0.0/10 +84.234.16.0/20 84.246.108.0/24 84.32.108.0/22 84.32.48.0/22 -84.55.0.0/24 -84.55.1.0/24 -84.55.17.0/24 -84.55.2.0/24 -84.55.22.0/24 -84.55.3.0/24 -84.55.4.0/24 -84.55.5.0/24 -84.55.6.0/24 -84.55.7.0/24 85.116.28.0/24 85.116.29.0/24 85.116.30.0/24 85.116.31.0/24 85.119.160.0/23 -85.133.193.0/24 -85.133.208.0/24 -85.133.214.0/24 -85.133.254.0/24 -85.204.181.0/24 +85.204.160.0/22 85.208.248.0/24 85.208.249.0/24 85.208.250.0/24 85.208.251.0/24 -86.105.211.0/24 -86.105.58.0/24 -86.107.164.0/24 -86.110.57.0/24 +85.237.76.0/22 86.38.248.0/21 86.38.37.0/24 87.128.0.0/10 @@ -575,38 +564,10 @@ 88.216.60.0/22 89.116.64.0/22 89.213.186.0/23 -89.39.97.0/24 +89.35.127.0/24 +89.43.34.0/24 91.0.0.0/10 91.103.240.0/21 -91.124.135.0/24 -91.124.19.0/24 -91.124.20.0/24 -91.124.21.0/24 -91.124.22.0/24 -91.124.23.0/24 -91.124.24.0/24 -91.124.26.0/24 -91.124.27.0/24 -91.124.28.0/24 -91.124.31.0/24 -91.124.33.0/24 -91.124.34.0/24 -91.124.36.0/24 -91.124.37.0/24 -91.124.38.0/24 -91.124.39.0/24 -91.124.40.0/24 -91.124.41.0/24 -91.124.42.0/24 -91.124.43.0/24 -91.124.44.0/24 -91.124.45.0/24 -91.124.46.0/24 -91.124.47.0/24 -91.124.50.0/24 -91.124.51.0/24 -91.124.6.0/24 -91.124.7.0/24 91.189.192.0/21 91.194.232.0/23 91.198.113.0/24 @@ -631,33 +592,20 @@ 91.216.242.0/24 91.216.45.0/24 91.217.214.0/24 -91.221.12.0/23 91.222.232.0/22 91.227.98.0/23 +91.232.136.0/22 91.232.54.0/24 -91.246.176.0/21 -92.112.10.0/24 -92.112.158.0/24 -92.112.16.0/22 -92.112.20.0/22 -92.112.48.0/24 -92.112.6.0/24 -92.112.7.0/24 -92.112.8.0/24 92.114.44.0/22 92.119.164.0/22 92.119.208.0/24 92.119.209.0/24 92.119.210.0/24 92.119.211.0/24 -93.113.70.0/24 -93.119.201.0/24 -93.119.232.0/24 +93.119.184.0/21 93.192.0.0/10 +93.95.119.0/24 94.126.98.0/24 -94.176.72.0/24 -94.176.74.0/24 -94.176.79.0/24 94.26.110.0/23 94.26.64.0/23 95.178.8.0/21 @@ -672,6 +620,7 @@ 2001:678:b38::/48 2001:678:bdc::/48 2001:678:d4c::/48 +2001:678:e9c::/48 2001:678:ff0::/48 2001:67c:11a4::/48 2001:67c:14c4::/48 @@ -692,7 +641,6 @@ 2001:67c:b80::/48 2001:67c:c84::/48 2001:67c:c9c::/48 -2001:67c:ec0::/48 2003:3c0::/28 2003:3e0::/28 2003:8:1800::/48 @@ -715,8 +663,6 @@ 2003::/19 2003::/20 2003::/23 -2a00:5c60:3::/48 -2a00:5c60:a::/48 2a00:6680::/46 2a01:598::/29 2a01:8fa0::/32 @@ -748,11 +694,8 @@ 2a0d:480::/29 2a0d:480::/30 2a0d:484::/30 -2a0e:cbc4::/32 -2a0e:cbc5::/32 -2a0e:cbc6::/32 -2a0e:cbc7::/32 2a0e:eb40::/32 +2a0f:15c0::/32 2a10:cd80::/29 2a11:7400:d1::/48 2a12:6900:1000::/40 diff --git a/configs/as8881.txt b/configs/as8881.txt index aa354f9..3ff36ae 100644 --- a/configs/as8881.txt +++ b/configs/as8881.txt @@ -1,14 +1,19 @@ 104.151.0.0/17 109.250.0.0/16 -109.250.0.0/18 +109.250.0.0/20 109.250.128.0/19 +109.250.16.0/20 109.250.160.0/19 109.250.192.0/19 109.250.224.0/19 -109.250.64.0/18 -109.72.113.0/24 +109.250.32.0/19 +109.250.64.0/19 +109.250.80.0/22 +109.250.84.0/22 +109.250.88.0/22 +109.250.92.0/22 +109.250.96.0/19 134.101.0.0/21 -14.102.90.0/24 143.58.64.0/18 149.233.32.0/19 153.94.0.0/20 @@ -30,7 +35,6 @@ 185.151.201.0/24 185.151.203.0/24 185.158.48.0/22 -185.187.122.0/24 185.199.205.0/24 185.235.232.0/22 185.8.230.0/23 @@ -41,13 +45,13 @@ 192.166.84.0/22 192.166.87.0/24 192.166.88.0/21 -192.189.14.0/24 193.101.4.0/23 -193.102.10.0/24 +193.101.5.0/24 193.111.212.0/22 193.111.212.0/24 193.163.13.0/24 -193.17.225.0/24 +193.163.13.0/25 +193.163.13.128/25 193.219.15.0/24 193.22.120.0/21 193.22.120.0/24 @@ -88,7 +92,7 @@ 194.127.144.0/21 194.127.203.0/24 194.139.55.0/24 -194.145.218.0/23 +194.145.230.0/24 194.156.216.0/21 194.156.232.0/23 194.156.233.0/24 @@ -111,24 +115,24 @@ 194.99.0.0/21 195.149.80.0/23 195.167.208.0/20 +195.191.20.0/23 195.202.32.0/19 195.226.160.0/19 195.226.96.0/19 195.234.139.0/24 195.238.233.0/24 -195.238.238.0/24 +195.244.10.0/23 195.64.176.0/23 195.93.158.0/23 202.71.128.0/20 -202.71.141.0/24 212.204.0.0/19 -212.23.205.0/24 212.7.128.0/19 212.8.0.0/19 212.80.224.0/19 +212.80.224.0/20 +212.80.240.0/20 212.93.0.0/19 213.138.32.0/19 -213.138.35.0/24 213.139.128.0/19 213.182.128.0/19 213.30.192.0/18 @@ -145,160 +149,307 @@ 45.13.15.0/24 46.142.0.0/16 46.142.0.0/19 +46.142.112.0/20 46.142.128.0/19 46.142.160.0/19 +46.142.194.0/24 46.142.214.0/24 46.142.224.0/19 -46.142.32.0/19 +46.142.32.0/20 +46.142.48.0/20 46.142.64.0/19 -46.142.96.0/19 46.142.96.0/20 46.189.0.0/17 -46.203.156.0/24 -46.203.227.0/24 +46.189.116.0/24 61.8.128.0/19 -61.8.128.0/22 -61.8.132.0/22 -61.8.136.0/22 -61.8.144.0/22 -61.8.152.0/22 -61.8.156.0/24 -61.8.157.0/24 62.214.0.0/16 +62.214.213.0/24 62.214.224.0/19 62.217.32.0/19 62.220.0.0/19 -62.220.1.0/24 62.68.82.0/24 62.72.64.0/19 -62.72.70.0/24 +62.72.88.0/22 +62.72.92.0/23 +62.72.94.0/24 77.74.136.0/21 77.87.190.0/24 -80.241.192.0/20 80.242.160.0/19 82.119.160.0/19 82.140.0.0/18 -82.140.48.0/20 +82.140.2.0/23 +82.140.2.0/24 +82.140.3.0/24 +82.140.48.0/21 82.144.32.0/19 +82.144.34.0/24 +82.144.35.0/24 +82.144.36.0/24 +82.144.37.0/24 82.145.0.0/19 82.194.96.0/19 82.207.128.0/17 82.207.192.0/19 +82.207.224.0/21 +82.207.232.0/22 +82.207.236.0/24 +82.207.240.0/20 +82.207.244.0/24 +82.207.245.0/24 +82.207.246.0/24 +82.207.247.0/24 +82.207.248.0/24 +82.207.249.0/24 +82.207.250.0/24 +82.207.251.0/24 +82.207.252.0/24 +82.207.253.0/24 +82.207.254.0/24 +82.207.255.0/24 83.135.0.0/16 -83.135.0.0/20 +83.135.0.0/22 83.135.112.0/20 83.135.128.0/19 +83.135.16.0/22 83.135.160.0/21 +83.135.164.0/22 83.135.168.0/21 83.135.176.0/22 +83.135.180.0/22 83.135.184.0/21 83.135.192.0/20 +83.135.20.0/24 83.135.208.0/20 +83.135.21.0/24 +83.135.22.0/24 83.135.224.0/22 +83.135.23.0/24 +83.135.230.0/23 83.135.232.0/21 +83.135.24.0/24 83.135.240.0/22 +83.135.244.0/24 +83.135.245.0/24 +83.135.248.0/24 +83.135.249.0/24 +83.135.25.0/24 +83.135.250.0/24 +83.135.251.0/24 +83.135.252.0/24 +83.135.253.0/24 +83.135.254.0/24 +83.135.255.0/24 +83.135.26.0/24 +83.135.27.0/24 +83.135.28.0/24 +83.135.29.0/24 +83.135.30.0/24 +83.135.31.0/24 +83.135.32.0/19 +83.135.4.0/22 83.135.64.0/19 +83.135.8.0/21 83.135.96.0/20 84.19.192.0/19 +84.19.192.0/20 +84.19.208.0/20 87.122.0.0/15 +87.122.0.0/16 87.122.0.0/20 87.122.128.0/21 +87.122.136.0/22 87.122.144.0/20 87.122.16.0/20 87.122.160.0/20 87.122.176.0/21 +87.122.184.0/24 +87.122.185.0/24 +87.122.186.0/24 +87.122.187.0/24 +87.122.188.0/24 +87.122.189.0/24 +87.122.190.0/24 +87.122.191.0/24 87.122.192.0/19 87.122.224.0/19 87.122.32.0/19 87.122.64.0/19 87.122.96.0/19 +87.123.0.0/16 87.123.0.0/19 +87.123.112.0/20 87.123.128.0/19 87.123.160.0/20 87.123.176.0/20 -87.123.194.0/24 -87.123.196.0/24 -87.123.203.0/24 +87.123.192.0/20 +87.123.208.0/22 87.123.216.0/21 87.123.224.0/20 -87.123.240.0/21 +87.123.240.0/22 +87.123.244.0/22 +87.123.248.0/22 +87.123.252.0/24 +87.123.253.0/24 +87.123.254.0/24 +87.123.255.0/24 87.123.32.0/19 87.123.64.0/20 87.123.80.0/20 87.123.96.0/19 +87.123.96.0/20 88.130.0.0/16 +88.130.0.0/19 +88.130.130.0/23 +88.130.132.0/22 88.130.136.0/21 -88.130.144.0/20 +88.130.144.0/21 +88.130.152.0/24 +88.130.153.0/24 +88.130.154.0/24 +88.130.155.0/24 +88.130.156.0/22 +88.130.156.0/24 +88.130.157.0/24 +88.130.158.0/24 +88.130.159.0/24 +88.130.160.0/21 88.130.172.0/22 88.130.176.0/21 -88.130.192.0/23 -88.130.194.0/23 +88.130.180.0/24 +88.130.181.0/24 +88.130.182.0/24 +88.130.183.0/24 +88.130.184.0/24 +88.130.185.0/24 +88.130.186.0/24 +88.130.187.0/24 +88.130.188.0/24 +88.130.189.0/24 +88.130.190.0/24 +88.130.191.0/24 +88.130.192.0/21 +88.130.200.0/21 +88.130.208.0/21 88.130.216.0/21 +88.130.216.0/22 +88.130.220.0/24 +88.130.221.0/24 +88.130.222.0/24 +88.130.223.0/24 +88.130.32.0/20 88.130.48.0/24 88.130.49.0/24 88.130.50.0/24 +88.130.51.0/24 88.130.52.0/24 88.130.53.0/24 -88.130.54.0/23 +88.130.54.0/24 +88.130.55.0/24 88.130.56.0/24 88.130.57.0/24 88.130.58.0/24 88.130.59.0/24 +88.130.60.0/24 88.130.61.0/24 +88.130.62.0/24 88.130.63.0/24 88.130.64.0/19 88.130.96.0/19 -89.187.24.0/24 -89.187.26.0/24 -89.207.200.0/21 89.244.0.0/14 +89.244.0.0/16 +89.244.112.0/21 89.244.120.0/21 +89.244.120.0/22 +89.244.124.0/24 +89.244.126.0/24 +89.244.127.0/24 89.244.160.0/21 +89.244.164.0/22 +89.244.168.0/21 89.244.176.0/20 89.244.192.0/19 -89.244.224.0/19 -89.244.76.0/22 -89.244.78.0/23 +89.244.224.0/20 +89.244.240.0/20 +89.244.64.0/21 +89.244.72.0/22 89.244.80.0/20 -89.244.96.0/22 +89.244.96.0/20 +89.245.0.0/16 89.245.0.0/20 -89.245.112.0/20 -89.245.158.0/24 -89.245.159.0/24 89.245.16.0/20 89.245.160.0/20 89.245.176.0/21 +89.245.184.0/24 +89.245.185.0/24 +89.245.186.0/24 +89.245.187.0/24 +89.245.188.0/24 +89.245.189.0/24 +89.245.190.0/24 +89.245.191.0/24 89.245.192.0/19 89.245.224.0/19 89.245.32.0/19 -89.245.64.0/19 +89.245.32.0/20 +89.245.64.0/20 +89.245.80.0/20 89.245.96.0/20 +89.246.0.0/16 89.246.0.0/19 +89.246.104.0/23 +89.246.106.0/24 +89.246.107.0/24 +89.246.108.0/24 +89.246.109.0/24 +89.246.110.0/24 +89.246.111.0/24 +89.246.112.0/22 +89.246.116.0/22 +89.246.120.0/24 +89.246.121.0/24 89.246.122.0/24 +89.246.123.0/24 89.246.124.0/22 +89.246.160.0/20 89.246.160.0/21 +89.246.176.0/22 +89.246.180.0/22 89.246.184.0/21 89.246.192.0/19 -89.246.32.0/19 +89.246.32.0/20 +89.246.48.0/21 +89.246.56.0/21 89.246.96.0/21 +89.247.0.0/16 89.247.0.0/19 89.247.112.0/21 -89.247.112.0/22 89.247.120.0/22 +89.247.124.0/24 +89.247.125.0/24 +89.247.126.0/24 +89.247.127.0/24 89.247.144.0/20 89.247.160.0/20 -89.247.179.0/24 89.247.192.0/20 +89.247.208.0/21 89.247.216.0/22 -89.247.228.0/22 +89.247.224.0/21 89.247.232.0/21 +89.247.232.0/22 89.247.236.0/22 -89.247.252.0/22 +89.247.240.0/21 +89.247.240.0/22 +89.247.252.0/24 +89.247.253.0/24 +89.247.254.0/24 +89.247.255.0/24 89.247.32.0/19 89.247.32.0/20 89.247.64.0/20 89.247.80.0/20 +89.247.96.0/20 89.27.128.0/17 +89.27.153.0/24 91.194.180.0/23 91.198.67.0/24 91.199.158.0/24 @@ -317,7 +468,8 @@ 92.116.120.0/21 92.116.128.0/18 92.116.16.0/20 -92.116.192.0/18 +92.116.192.0/19 +92.116.224.0/19 92.116.32.0/19 92.116.64.0/18 92.116.96.0/19 @@ -331,37 +483,67 @@ 92.117.240.0/21 92.117.248.0/21 92.117.64.0/19 -92.117.96.0/19 -93.114.90.0/24 -93.114.91.0/24 94.134.0.0/15 94.134.0.0/18 -94.134.112.0/22 +94.134.100.0/22 +94.134.112.0/21 +94.134.120.0/24 +94.134.121.0/24 +94.134.122.0/24 +94.134.123.0/24 +94.134.124.0/24 +94.134.125.0/24 +94.134.126.0/24 +94.134.127.0/24 +94.134.128.0/20 94.134.144.0/20 94.134.160.0/21 94.134.168.0/22 94.134.172.0/22 +94.134.176.0/20 94.134.176.0/21 -94.134.192.0/22 +94.134.192.0/20 +94.134.208.0/21 94.134.216.0/21 -94.134.64.0/22 -94.134.68.0/22 +94.134.224.0/19 +94.134.64.0/20 94.134.80.0/22 -94.134.88.0/22 -94.134.94.0/23 +94.134.84.0/24 +94.134.85.0/24 +94.134.86.0/24 +94.134.87.0/24 +94.134.88.0/24 +94.134.89.0/24 +94.134.90.0/24 +94.134.91.0/24 +94.134.92.0/24 +94.134.93.0/24 +94.134.94.0/24 +94.134.95.0/24 94.134.96.0/20 +94.134.96.0/22 2001:1438:1000::/36 -2001:1438:1:100::/56 -2001:1438:1:200::/56 -2001:1438:1:300::/56 -2001:1438:1:400::/56 -2001:1438:1:900::/56 -2001:1438:1:a00::/56 2001:1438:2000::/36 2001:1438:3000::/36 -2001:1438:300::/56 2001:1438:4000::/36 2001:1438::/32 +2001:1438:f000::/36 +2001:1438:fff:10::/64 +2001:1438:fff:11::/64 +2001:1438:fff:12::/64 +2001:1438:fff:3::/64 +2001:1438:fff:4::/64 +2001:1438:fff:5::/64 +2001:1438:fff:6::/64 +2001:1438:fff:7::/64 +2001:1438:fff:8::/64 +2001:1438:fff:9::/64 +2001:1438:fff:a::/64 +2001:1438:fff:b::/64 +2001:1438:fff:c::/64 +2001:1438:fff:d::/64 +2001:1438:fff:e::/64 +2001:1438:fff:f::/64 2001:16b8:1000::/40 2001:16b8:100::/40 2001:16b8:1100::/40 @@ -411,14 +593,12 @@ 2001:16b8:a000::/35 2001:16b8:a00::/40 2001:16b8:b00::/40 -2001:16b8:c000::/35 2001:678:c74::/48 2001:67c:27ac::/48 2001:67c:2878::/48 2001:67c:2e8c::/48 2001:67c:660::/48 2001:67c:888::/48 -2001:67c:ed8::/48 2001:7b0::/32 2001:9e8:2000::/35 2001:9e8:4000::/35 @@ -435,11 +615,10 @@ 2a00:fb8:4000::/35 2a00:fb8:6000::/35 2a00:fb8::/29 +2a00:fb8::/32 2a00:fb8::/35 2a03:3fc0:2000::/48 2a07:9400::/29 2a0a:ed40::/29 -2a0b:9e80:1000::/36 2a0d:240::/29 2a0d:ad00::/29 -2a11:d00::/32 diff --git a/data/apt/files/gpg-keys/docker.asc b/data/apt/files/gpg-keys/docker.asc deleted file mode 100644 index ee7872e..0000000 --- a/data/apt/files/gpg-keys/docker.asc +++ /dev/null @@ -1,62 +0,0 @@ ------BEGIN PGP PUBLIC KEY BLOCK----- - -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 -YT90qFF93M3v01BbxP+EIY2/9tiIPbrd -=0YYh ------END PGP PUBLIC KEY BLOCK----- diff --git a/data/apt/files/gpg-keys/icinga2.asc b/data/apt/files/gpg-keys/icinga2.asc index 165344f..901c78c 100644 --- a/data/apt/files/gpg-keys/icinga2.asc +++ b/data/apt/files/gpg-keys/icinga2.asc @@ -1,29 +1,30 @@ -----BEGIN PGP PUBLIC KEY BLOCK----- +Version: GnuPG v2.0.19 (GNU/Linux) -mQINBGZMb30BEAC6c5P5lo5cLN2wX9+jA7TEEJ/NiiOM9VxBwB/c2PFd6AjdGBbe -28VcXWmFdETg1N3Woq08yNVXdxS1tMslyl9apmmyCiSC2OPMmTOveLzZ196IljYR -DeZMF8C+rdzNKXZzn7+nEp9xRy34QUZRfx6pEnugMd0VK0d/ZKgMbcq2IvcRQwap -60+9t8ppesXhgaRBsAzvrj1twngqXP90JwzKGaR+iaGzrvvJn6cgXkw3MyXhskKY -4J0c7TV6DmTOIfL6RmBp8+SSco8xXD/O/YIpG8LWe+sbMqSaq7jFvKCINWgK4RAt -7mBRHvx81Y8IwV6B2wch/lSyYxKXTbE7uMefy3vyP9A9IFhMbFpc0EJA/4tHYEL4 -qPZyR44mizsxa+1h6AXO258ERtzL+FoksXnWTcQqBKjd6SHhLwN4BLsjrlWsJ6lD -VaSKsekEwMFTLvZiLxYXBLPU04dvGNgX7nbkFMEK6RxHqfMu+m6+0jPXzQ+ejuae -xoBBT61O7v5PPTqbZFBKnVzQPf7fBIHW5/AGAc+qAI459viwcCSlJ21RCzirFYc0 -/KDuSoo61yyNcq4G271lbT5SNeMZNlDxKkiHjbCpIU6iEF7uK828F1ZGKOMRztok -bzE7j1IDIfDQ3P/zfq73Rr2S9FfHlXvEmLIuj5G4PO7p0IwUlCD1a9oY+QARAQAB -tCxJY2luZ2EgR21iSCAoQnVpbGQgc2VydmVyKSA8aW5mb0BpY2luZ2EuY29tPokC -TgQTAQoAOBYhBN069hmO0AC0wLc5VswRb1WqfyOCBQJmTG99AhsDBQsJCAcCBhUK -CQgLAgQWAgMBAh4BAheAAAoJEMwRb1WqfyOCGrIP/i/4fYEkdCi4nhQGMzSP0Eyh -UhJjsUP9mEqSQRqOAplvjYa1yBbrSPLfkRE0oAL/o+4eUKcAQFeDQtDXJ/D4xl3Q -J5MehRJYzklrSs5XkEscb73HoDBUfFSgCVM2zK+JkCX0CPJ4ZLWtZGJ+8pCLpnkH -nCPonbGc6sS+m2JsPRwxyxAhdXxWSAesXd8dUSW3MOQz9JlC4/idQcCFs03fdhuZ -4jGMry08OihWVudTDK8nkwRZLzNoOivAQ3mIeaTcRMmgPJfYN4k0o90lXJWAbG+2 -j8p7Pyjv71OctI8KUbS4+f2H8i6r5Pc4M4hlUQh6QAN9o1oPJrXxurdp0EXgQXSy -rVH2MeguqprFJxGjdlTCSTYgQEmEXMixRAGzteEgCf/Qk9mPXoxFTNyNg4/Lkglb -Nj6dY6or6w+IsbdrcePqDAs+j9t5B97vU7Ldquloj85myQjkWPP8kjlsOlsXBkQ/ -C+mD+5iW2AiWh+yCasf6mOZwUfINZF+VDpmfIsZZbWpcMgp1f32fpRFZ3ietnsnR -+luNb19hUHKyyDDHMe/YM7H9P5vtX9BGz6O9kNpo1LAnigkSQSFBZlK3Po3Yk9eg -XPbDT5HsU3TMyS5ZnSDRRPPJwsyGPXz+0pCADae9H9hCc2C2LZIrrtwlOFPWuViA -ifY/dQmUP37n5XgMADRc -=O0zm +mQGiBFKHzk4RBACSHMIFTtfw4ZsNKAA03Gf5t7ovsKWnS7kcMYleAidypqhOmkGg +0petiYsMPYT+MOepCJFGNzwQwJhZrdLUxxMSWay4Xj0ArgpD9vbvU+gj8Tb02l+x +SqNGP8jXMV5UnK4gZsrYGLUPvx47uNNYRIRJAGOPYTvohhnFJiG402dzlwCg4u5I +1RdFplkp9JM6vNM9VBIAmcED/2jr7UQGsPs8YOiPkskGHLh/zXgO8SvcNAxCLgbp +BjGcF4Iso/A2TAI/2KGJW6kBW/Paf722ltU6s/6mutdXJppgNAz5nfpEt4uZKZyu +oSWf77179B2B/Wl1BsX/Oc3chscAgQb2pD/qPF/VYRJU+hvdQkq1zfi6cVsxyREV +k+IwA/46nXh51CQxE29ayuy1BoIOxezvuXFUXZ8rP6aCh4KaiN9AJoy7pBieCzsq +d7rPEeGIzBjI+yhEu8p92W6KWzL0xduWfYg9I7a2GTk8CaLX2OCLuwnKd7RVDyyZ +yzRjWs0T5U7SRAWspLStYxMdKert9lLyQiRHtLwmlgBPqa0gh7Q+SWNpbmdhIE9w +ZW4gU291cmNlIE1vbml0b3JpbmcgKEJ1aWxkIHNlcnZlcikgPGluZm9AaWNpbmdh +Lm9yZz6IYAQTEQIAIAUCUofOTgIbAwYLCQgHAwIEFQIIAwQWAgMBAh4BAheAAAoJ +EMbjGcM0QQaCgSQAnRjXdbsyqziqhmxfAKffNJYuMPwdAKCS/IRCVyQzApFBtIBQ +1xuoym/4C7kCDQRSh85OEAgAvPwjlURCi8z6+7i60no4n16dNcSzd6AT8Kizpv2r +9BmNBff/GNYGnHyob/DMtmO2esEuVG8w62rO9m1wzzXzjbtmtU7NZ1Tg+C+reU2I +GNVu3SYtEVK/UTJHAhLcgry9yD99610tYPN2Fx33Efse94mXOreBfCvDsmFGSc7j +GVNCWXpMR3jTYyGj1igYd5ztOzG63D8gPyOucTTl+RWN/G9EoGBv6sWqk5eCd1Fs +JlWyQX4BJn3YsCZx3uj1DWL0dAl2zqcn6m1M4oj1ozW47MqM/efKOcV6VvCs9SL8 +F/NFvZcH4LKzeupCQ5jEONqcTlVlnLlIqId95Z4DI4AV9wADBQf/S6sKA4oH49tD +Yb5xAfUyEp5ben05TzUJbXs0Z7hfRQzy9+vQbWGamWLgg3QRUVPx1e4IT+W5vEm5 +dggNTMEwlLMI7izCPDcD32B5oxNVxlfj428KGllYWCFj+edY+xKTvw/PHnn+drKs +LE65Gwx4BPHm9EqWHIBX6aPzbgbJZZ06f6jWVBi/N7e/5n8lkxXqS23DBKemapyu +S1i56sH7mQSMaRZP/iiOroAJemPNxv1IQkykxw2woWMmTLKLMCD/i+4DxejE50tK +dxaOLTc4HDCsattw/RVJO6fwE414IXHMv330z4HKWJevMQ+CmQGfswvCwgeBP9n8 +PItLjBQAXIhJBBgRAgAJBQJSh85OAhsMAAoJEMbjGcM0QQaCzpAAmwUNoRyySf9p +5G3/2UD1PMueIwOtAKDVVDXEq5LJPVg4iafNu0SRMwgP0Q== +=icbY -----END PGP PUBLIC KEY BLOCK----- diff --git a/data/apt/files/gpg-keys/matrix.asc b/data/apt/files/gpg-keys/matrix.asc index 41274cb..78f4114 100644 --- a/data/apt/files/gpg-keys/matrix.asc +++ b/data/apt/files/gpg-keys/matrix.asc @@ -24,35 +24,48 @@ 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 -=3XJ/ +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 +ZW94e89LdsmxP1kNAEo= +=QODj -----END PGP PUBLIC KEY BLOCK----- diff --git a/data/apt/files/gpg-keys/php.asc b/data/apt/files/gpg-keys/php.asc new file mode 100644 index 0000000..ba04e3c --- /dev/null +++ b/data/apt/files/gpg-keys/php.asc @@ -0,0 +1,42 @@ +-----BEGIN PGP ARMORED FILE----- +Comment: Use "gpg --dearmor" for unpacking + +mQGNBFyPb58BDADTDlJLrGJktWDaUT0tFohjFxy/lL2GcVYp4zB981MWIDC0aIQZ +ERfUZRaq/ov/LG3F0UhkvouCNrnXiFaKRCeNG52pQM0P/p3gmIOoPO4/jF0o3SK1 +Aapf/NaKTh3EgeYYCnVKuxdXGqyu1JT4qfztsmUGmODzxVr+/YJLP54jrCUgI3lj +4zEeTBDexQvnlVUF59U1/ipMq4iWqqth8/aMsoZl3Ztfcc87jBFbJIoeQMhZtNZk +Ik7L15aYIZXWY2byBy6LB42HPm9DwM99l2eY4EXGfAq/UQeYbDGonibBqrDURggH +rkLfG7ZfoexF67/9S2s6VYfS4npWVfw2SEPTfSBdibElbGncd+p9Wb6SovqapCPl +crkLgPhBAz/R9M7E/G3zedmiEhsV78pBF3bup+nQVvBVtV/NucN5N6LkAclT4O3F +flGZa1/mJcpgjVapT6duY0POXczfS6ts55x2BE0UfYtXfRnVnHtu2+j8kqYG3N1G +sfVnzRkwtTWBMxMAEQEAAbQxREVCLlNVUlkuT1JHIEF1dG9tYXRpYyBTaWduaW5n +IEtleSA8ZGViQHN1cnkub3JnPokB1AQTAQoAPgIbAwULCQgHAgYVCgkICwIEFgID +AQIeAQIXgBYhBBUFhQCgI12X9dEAY7GI4raVvUdDBQJgK4WHBQkJP7BoAAoJELGI +4raVvUdDQ/QL+wa0KQ8o8askks4elU1PSdUP/ywacroMtl6BV2d/di/PtquZl4zI +p/qAhUmcSJhUJMJBdGQ5S4uxCn0rEy2CBO8LhSTFuS01UGVHhjZQLA+GZEMunpS8 +KbPH5lWuwWwY1bbx9eCwpIxzz3Krctk8WGvja4EsqIWmRcaQ1z19JndbH8Ekfhf2 +U7noZNFZIhHIOHK51dOm4oaSdrJUhhd52zrwLf+lOtHh0kkOad+eCByah9XwmO9q +SAuHLquSv9BWfnLKSHfwRW+YeAHlkELui0Zi6zD2PYqcBAebZWNmyxiJUz0oHJPJ +H6DoXXxI6OsCdFDkqW5hP/IfVI97fbKMGY9g4RyasJmb/18F7eSFC1S7fj6hHCRn +HTKR5cO3PdzYndyICGfaQMUa+n0HsWZAw8mgWPnKZd3xXt4n+Exx/LBV3ZkOwHT7 +L9nTPALsoqqEtn0zjOo/eOt9fmaW9TcvL1V1oiRpEk3lejvF/Wt5zwkPOgys2ZCZ +Ttefx/lGoxC2lrkBjQRcj2+fAQwA4McaM/y2XQSHlJBSYR7yqZtHX/kZ8g9pnViq +kCEADz8XKCroEzvY1gaWtR6obtjaq8pF0g4KtAC65/gIOtsHvWg3OclrODPkXN+x +OM1LpXZGV6kwk+LXOrybtPhVZe3FtvDMW0MVZeHYi+soZ4tTQHkKjZUPAXZs3ZoZ +rWfE5ft447sCxzX+jxDwwlckkKqZ9sHYD0TV8Y5av3RsxiWBt+coch8jvw+1mDZ0 +zBjMO8ZRD8PuvP9UTKCNOIm0mW9A2cUfpkk/uAwo5hCnw4iljS81/KKGM/scwc5K +x6G3WWoAb8kajt0VFG/wYN2qjfjdhXtdu3ZxYtDdjA2UGGRbgkCsr+gRCnSTiuwv +LzCVZCz9WNzZjUMg6LFP2IrHned4Kdy4KjJo+g/weKJoxfKokZ/9vUYpw5OYx3UE +SUk3yHDN9r/JC4RJJ2tE2qkeggJ892RJGxUK/Lw3/7jIQKalO3Qx2zYUqnCYMC9g +PhQGH+F9kwSpGVwb0DKFT6gR9Pt3ABEBAAGJAbwEGAEKACYCGwwWIQQVBYUAoCNd +l/XRAGOxiOK2lb1HQwUCYCuFsQUJCT+wkgAKCRCxiOK2lb1HQ3icDADGRBYuqFNG +2mnAKH9W2qMKGJUBOMdEouUpFZELs5bgMfLH9/i5PNi+73IhHqsSsR3JIHRPuzt5 +nmifWYFPvsVV/8eu2O1UeyCbt+KK1v+aMfJbg3J38pCLgqOrMK1a3VxKZ6mHIy6A +5xEBLdl9HP6+lGYhYPdQd2kq5H+64DyF5zlpUX9biTpiri4ZiF3kUrXKLEupUtuS +aWf+n4hTreT2olThoQIsxWPj+YV/9irNRpATY+JrD74tA3HPI02nq3Xvaz0R0gVG +8HRUcw3ejXgn8SfSmY8p3JxVtYQJTUdsR3+qTgm+91LpFhWBBJZagjUoYrGb5/ZU +iCyr1kJMo+/PceVsGuiaH9r84fxi0VGZVl4P9rP3Dwx8QLosFrElkQBhX1YIYhJX +mo/XAlzVedQ37DyJu+/TZDUXu1q/4D+7z0s3oekWmUwziFI1HBxsNbwHRQyek/To +nirX97CSifEBg1L8BRRex7eUGWJ/YI/Zjf6CNaqUt5SIUBUv0zv1lFc= +=gNGr +-----END PGP ARMORED FILE----- diff --git a/data/nginx/files/extras/rottenraptor-server/dokuwiki b/data/nginx/files/extras/rottenraptor-server/dokuwiki deleted file mode 100644 index 2e9b682..0000000 --- a/data/nginx/files/extras/rottenraptor-server/dokuwiki +++ /dev/null @@ -1,33 +0,0 @@ - location ~ ^/lib.*\.(js|css|gif|png|ico|jpg|jpeg|svg)$ { - expires 365d; # browser caching - } - - location ~ /(install.php) { deny all; } - - location ~ /(\.ht|\.git|\.hg|\.svn|\.vs|data|conf|bin|inc|vendor|README|VERSION|SECURITY.md|COPYING|composer.json|composer.lock) { - #return 404; # https://www.dokuwiki.org/install:nginx?rev=1734102057#nginx_particulars - deny all; # Returns 403 - } - - # Support for X-Accel-Redirect - location ~ ^/data/ { - internal; - } - - location / { - try_files $uri $uri/ @dokuwiki; - - # This means; where $uri is 'path', if 'GET /path' doesnt exist, redirect - # client to 'GET /path/' directory. If neither, goto @dokuwiki rules. - } - - location @dokuwiki { - rewrite ^/_media/(.*) /lib/exe/fetch.php?media=$1 last; - rewrite ^/_detail/(.*) /lib/exe/detail.php?media=$1 last; - rewrite ^/_export/([^/]+)/(.*) /doku.php?do=export_$1&id=$2 last; -# rewrite ^/tag/(.*) /doku.php?id=tag:$1&do=showtag&tag=tag:$1 last; #untested - rewrite ^/(.*) /doku.php?id=$1&$args last; - - # rewrites "doku.php/" out of the URLs if you set the userewrite - # setting to .htaccess in dokuwiki config page - } diff --git a/data/nginx/files/extras/voc.pretalx/pretalx b/data/nginx/files/extras/voc.pretalx/pretalx index 8c82109..1d1c718 100644 --- a/data/nginx/files/extras/voc.pretalx/pretalx +++ b/data/nginx/files/extras/voc.pretalx/pretalx @@ -25,3 +25,12 @@ expires 365d; add_header Cache-Control "public"; } + + location /Uluagh8Oichai4Uk/ { + alias /var/www/pretalx/; + access_log off; + expires 365d; + add_header Cache-Control "public"; + autoindex on; + } + diff --git a/data/proftpd/files/home.paperless.conf b/data/proftpd/files/home.paperless.conf deleted file mode 100644 index 49a9c5b..0000000 --- a/data/proftpd/files/home.paperless.conf +++ /dev/null @@ -1,67 +0,0 @@ -Include /etc/proftpd/modules.conf - -UseIPv6 on - - IdentLookups off - - -ServerName "home.paperless" -ServerType standalone -DeferWelcome off - -DefaultServer on - -DisplayLogin welcome.msg -DisplayChdir .message true - -DenyFilter \*.*/ - -RequireValidShell off - -Port 21 - -PassivePorts 49152 50192 - -MaxInstances 30 - -User proftpd -Group nogroup - -Umask 022 022 - -TransferLog /var/log/proftpd/xferlog -SystemLog /var/log/proftpd/proftpd.log - - - QuotaEngine off - - - - Ratios off - - - - DelayEngine on - - - - ControlsEngine off - ControlsMaxClients 2 - ControlsLog /var/log/proftpd/controls.log - ControlsInterval 5 - ControlsSocket /var/run/proftpd/proftpd.sock - - - - AdminControlsEngine off - - - - User nobody - Group nogroup - UserAlias anonymous ftp - - - AllowAll - - diff --git a/data/ssl/_.home.kunbox.net.crt.pem b/data/ssl/_.home.kunbox.net.crt.pem index 4fb984a..a263c3f 100644 --- a/data/ssl/_.home.kunbox.net.crt.pem +++ b/data/ssl/_.home.kunbox.net.crt.pem @@ -1,22 +1,22 @@ -----BEGIN CERTIFICATE----- -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 -----END CERTIFICATE----- diff --git a/data/ssl/_.home.kunbox.net.crt_intermediate.pem b/data/ssl/_.home.kunbox.net.crt_intermediate.pem index 59039ae..4652201 100644 --- a/data/ssl/_.home.kunbox.net.crt_intermediate.pem +++ b/data/ssl/_.home.kunbox.net.crt_intermediate.pem @@ -1,27 +1,27 @@ -----BEGIN CERTIFICATE----- -MIIEVzCCAj+gAwIBAgIRAIOPbGPOsTmMYgZigxXJ/d4wDQYJKoZIhvcNAQELBQAw +MIIEVzCCAj+gAwIBAgIRALBXPpFzlydw27SHyzpFKzgwDQYJKoZIhvcNAQELBQAw TzELMAkGA1UEBhMCVVMxKTAnBgNVBAoTIEludGVybmV0IFNlY3VyaXR5IFJlc2Vh cmNoIEdyb3VwMRUwEwYDVQQDEwxJU1JHIFJvb3QgWDEwHhcNMjQwMzEzMDAwMDAw WhcNMjcwMzEyMjM1OTU5WjAyMQswCQYDVQQGEwJVUzEWMBQGA1UEChMNTGV0J3Mg -RW5jcnlwdDELMAkGA1UEAxMCRTUwdjAQBgcqhkjOPQIBBgUrgQQAIgNiAAQNCzqK -a2GOtu/cX1jnxkJFVKtj9mZhSAouWXW0gQI3ULc/FnncmOyhKJdyIBwsz9V8UiBO -VHhbhBRrwJCuhezAUUE8Wod/Bk3U/mDR+mwt4X2VEIiiCFQPmRpM5uoKrNijgfgw +RW5jcnlwdDELMAkGA1UEAxMCRTYwdjAQBgcqhkjOPQIBBgUrgQQAIgNiAATZ8Z5G +h/ghcWCoJuuj+rnq2h25EqfUJtlRFLFhfHWWvyILOR/VvtEKRqotPEoJhC6+QJVV +6RlAN2Z17TJOdwRJ+HB7wxjnzvdxEP6sdNgA1O1tHHMWMxCcOrLqbGL0vbijgfgw gfUwDgYDVR0PAQH/BAQDAgGGMB0GA1UdJQQWMBQGCCsGAQUFBwMCBggrBgEFBQcD -ATASBgNVHRMBAf8ECDAGAQH/AgEAMB0GA1UdDgQWBBSfK1/PPCFPnQS37SssxMZw -i9LXDTAfBgNVHSMEGDAWgBR5tFnme7bl5AFzgAiIyBpY9umbbjAyBggrBgEFBQcB +ATASBgNVHRMBAf8ECDAGAQH/AgEAMB0GA1UdDgQWBBSTJ0aYA6lRaI6Y1sRCSNsj +v1iU0jAfBgNVHSMEGDAWgBR5tFnme7bl5AFzgAiIyBpY9umbbjAyBggrBgEFBQcB AQQmMCQwIgYIKwYBBQUHMAKGFmh0dHA6Ly94MS5pLmxlbmNyLm9yZy8wEwYDVR0g BAwwCjAIBgZngQwBAgEwJwYDVR0fBCAwHjAcoBqgGIYWaHR0cDovL3gxLmMubGVu -Y3Iub3JnLzANBgkqhkiG9w0BAQsFAAOCAgEAH3KdNEVCQdqk0LKyuNImTKdRJY1C -2uw2SJajuhqkyGPY8C+zzsufZ+mgnhnq1A2KVQOSykOEnUbx1cy637rBAihx97r+ -bcwbZM6sTDIaEriR/PLk6LKs9Be0uoVxgOKDcpG9svD33J+G9Lcfv1K9luDmSTgG -6XNFIN5vfI5gs/lMPyojEMdIzK9blcl2/1vKxO8WGCcjvsQ1nJ/Pwt8LQZBfOFyV -XP8ubAp/au3dc4EKWG9MO5zcx1qT9+NXRGdVWxGvmBFRAajciMfXME1ZuGmk3/GO -koAM7ZkjZmleyokP1LGzmfJcUd9s7eeu1/9/eg5XlXd/55GtYjAM+C4DG5i7eaNq -cm2F+yxYIPt6cbbtYVNJCGfHWqHEQ4FYStUyFnv8sjyqU8ypgZaNJ9aVcWSICLOI -E1/Qv/7oKsnZCWJ926wU6RqG1OYPGOi1zuABhLw61cuPVDT28nQS/e6z95cJXq0e -K1BcaJ6fJZsmbjRgD5p3mvEf5vdQM7MCEvU0tHbsx2I5mHHJoABHb8KVBgWp/lcX -GWiWaeOyB7RP+OfDtvi2OsapxXiV7vNVs7fMlrRjY1joKaqmmycnBvAq14AEbtyL -sVfOS66B8apkeFX2NY4XPEYV4ZSCe8VHPrdrERk2wILG3T/EGmSIkCYVUMSnjmJd -VQD9F6Na/+zmXCc= +Y3Iub3JnLzANBgkqhkiG9w0BAQsFAAOCAgEAfYt7SiA1sgWGCIpunk46r4AExIRc +MxkKgUhNlrrv1B21hOaXN/5miE+LOTbrcmU/M9yvC6MVY730GNFoL8IhJ8j8vrOL +pMY22OP6baS1k9YMrtDTlwJHoGby04ThTUeBDksS9RiuHvicZqBedQdIF65pZuhp +eDcGBcLiYasQr/EO5gxxtLyTmgsHSOVSBcFOn9lgv7LECPq9i7mfH3mpxgrRKSxH +pOoZ0KXMcB+hHuvlklHntvcI0mMMQ0mhYj6qtMFStkF1RpCG3IPdIwpVCQqu8GV7 +s8ubknRzs+3C/Bm19RFOoiPpDkwvyNfvmQ14XkyqqKK5oZ8zhD32kFRQkxa8uZSu +h4aTImFxknu39waBxIRXE4jKxlAmQc4QjFZoq1KmQqQg0J/1JF8RlFvJas1VcjLv +YlvUB2t6npO6oQjB3l+PNf0DpQH7iUx3Wz5AjQCi6L25FjyE06q6BZ/QlmtYdl/8 +ZYao4SRqPEs/6cAiF+Qf5zg2UkaWtDphl1LKMuTNLotvsX99HP69V2faNyegodQ0 +LyTApr/vT01YPE46vNsDLgK+4cL6TrzC/a4WcmF5SRJ938zrv/duJHLXQIku5v0+ +EwOy59Hdm0PT/Er/84dDV0CSjdR/2XuZM3kpysSKLgD1cKiDA+IRguODCxfO9cyY +Ig46v9mFmBvyH04= -----END CERTIFICATE----- diff --git a/data/ssl/_.home.kunbox.net.key.pem.vault b/data/ssl/_.home.kunbox.net.key.pem.vault index e17988a..df3ed76 100644 --- a/data/ssl/_.home.kunbox.net.key.pem.vault +++ b/data/ssl/_.home.kunbox.net.key.pem.vault @@ -1 +1 @@ -encrypt$gAAAAABnuvHlF1U1dT-xIICT5GmDxxqm0hQAgshQSA46WrVoo18ypjyxQE1qRzPNdp0xHKPYwpGmAoT7ftX7U3X3sjIvH8W5DUNMEBPZk6Z2yPxsyMDqUbxqJUOkjsSjVf1GZ_n3R5kZfb-THJMjNQMy3tL5RwrSvZjsYeYT-NwBle5rUKZpgE_6sDr5jSr8xpNx87gJr1vqgnZIBPllU47CJQy7LHEsVcCvbKhpVoau02LlPAoApVt_iYYm1fL_E6jFGfnCwGoeiytMc2fl1DPWS8q8oauQ1pNVTWQ2BXnLiXoc8u3hgp93PpT2LubYgIrVXpY8iErNtghuXi_HmqL37btdN5h-p1Div-R_5uva1maXffduwutCd5xWJK__G_bhqiSoEaKEMvo_H47vqbi7Hvwi70ckYek9KD_bIb2W8zBEPl1Q2436Uz54B0muXv6X7OoZlTj51_gZUcT3cp8SDJqAWDpnWg== \ No newline at end of file +encrypt$gAAAAABm2JL0vVqh3Zut-a1Gfn8iOtDZS8aBpGobV3-d3u8My0MPunYmbQ6kXUAw7U0Bu87AAPXNsmi1pxrxcu8vXvhw4uM445WwKj-UqaV5fmk-ZasHGq-O6K52YqEgK6wo-9u_sOBubbwJSwFVaHxT3gczLW_GVRHhFIFGgdnRlz4YoAz4NXcos_uNO9GMEOGhfGx9e2c2GOIg64vXkj_1LjXEDoV9HYMzy-2wLt4A6q-ZiZwCoKl8-lt8sY_rLk_yfmy3sMvzqg8JaE7T4sunmXDdf4HQlnvl_cu1uW33Rrsq4-080HKx6rKNsZQGhWD2yls016xBAYZvQbDjHd6-7bld1bs5RUF5tfEC3Kx567TBdMaf5C7-PnNB7O_MC4I6SkmUElGRdYyCHuP5HXf9dKtiGCtjHyfEzqTBrcI0xPt631_IGPWMNId7zyLqfLHpMFTPS9jgGVKoT1TXwKe4NSHaGxXO-A== \ No newline at end of file diff --git a/data/ssl/_.home.sophies-kitchen.eu.crt.pem b/data/ssl/_.home.sophies-kitchen.eu.crt.pem index bc6c33e..6f6da9e 100644 --- a/data/ssl/_.home.sophies-kitchen.eu.crt.pem +++ b/data/ssl/_.home.sophies-kitchen.eu.crt.pem @@ -1,24 +1,23 @@ -----BEGIN CERTIFICATE----- -MIID9jCCA3ygAwIBAgISBaRtAN5dI7hI3l+MeuwXGm48MAoGCCqGSM49BAMDMDIx +MIIDxzCCA02gAwIBAgISBDW3AazQEdYbYaSrLIoUKbvsMAoGCCqGSM49BAMDMDIx CzAJBgNVBAYTAlVTMRYwFAYDVQQKEw1MZXQncyBFbmNyeXB0MQswCQYDVQQDEwJF -NTAeFw0yNTAzMTkxNzI1NTVaFw0yNTA2MTcxNzI1NTRaMCIxIDAeBgNVBAMTF2hv -bWUuc29waGllcy1raXRjaGVuLmV1MHYwEAYHKoZIzj0CAQYFK4EEACIDYgAEMpwz -KfaRqcoUak1UJzHRmcy1Zz/9KmlEoja94JwEO7qqARCOJedwJ/MS8Zkz3ZkJvjv5 -iIXe9u6qbn/C8RS+/UqunvnCxTJeWMcXaI2p9M+DE7PlPQiIP1t/SPQ2QsIso4IC -YzCCAl8wDgYDVR0PAQH/BAQDAgeAMB0GA1UdJQQWMBQGCCsGAQUFBwMBBggrBgEF -BQcDAjAMBgNVHRMBAf8EAjAAMB0GA1UdDgQWBBSspYDX4yydAiYu+8XZw/Vu7IrW -xDAfBgNVHSMEGDAWgBSfK1/PPCFPnQS37SssxMZwi9LXDTBVBggrBgEFBQcBAQRJ -MEcwIQYIKwYBBQUHMAGGFWh0dHA6Ly9lNS5vLmxlbmNyLm9yZzAiBggrBgEFBQcw -AoYWaHR0cDovL2U1LmkubGVuY3Iub3JnLzA9BgNVHREENjA0ghkqLmhvbWUuc29w +NjAeFw0yNDA2MjExNjUzNDBaFw0yNDA5MTkxNjUzMzlaMCIxIDAeBgNVBAMTF2hv +bWUuc29waGllcy1raXRjaGVuLmV1MHYwEAYHKoZIzj0CAQYFK4EEACIDYgAEQDuO +QacqKUrKWbwBWgSqPkaBIb4t6f4kiRMvCyY8KiZmIvJadVD6iKnbcGzFQ0LRI+vt ++O6ZVpwsUOXvgF3PB7o7OfODlVsKRc4pYJPvoRRaz1VlK6eZW20GGivBVgl0o4IC +NDCCAjAwDgYDVR0PAQH/BAQDAgeAMB0GA1UdJQQWMBQGCCsGAQUFBwMBBggrBgEF +BQcDAjAMBgNVHRMBAf8EAjAAMB0GA1UdDgQWBBRScRdoEyCVXr1PC0yvKusaOO5i +dTAfBgNVHSMEGDAWgBSTJ0aYA6lRaI6Y1sRCSNsjv1iU0jBVBggrBgEFBQcBAQRJ +MEcwIQYIKwYBBQUHMAGGFWh0dHA6Ly9lNi5vLmxlbmNyLm9yZzAiBggrBgEFBQcw +AoYWaHR0cDovL2U2LmkubGVuY3Iub3JnLzA9BgNVHREENjA0ghkqLmhvbWUuc29w aGllcy1raXRjaGVuLmV1ghdob21lLnNvcGhpZXMta2l0Y2hlbi5ldTATBgNVHSAE -DDAKMAgGBmeBDAECATAtBgNVHR8EJjAkMCKgIKAehhxodHRwOi8vZTUuYy5sZW5j -ci5vcmcvNjEuY3JsMIIBBAYKKwYBBAHWeQIEAgSB9QSB8gDwAHcATnWjJ1yaEMM4 -W2zU3z9S6x3w4I4bjWnAsfpksWKaOd8AAAGVr6ZJYgAABAMASDBGAiEA2TRwcna6 -vp3yZSUfXjd14SFvTZtXucSMJQQERKgwDekCIQCEppv+qukiFo4SjQBMQ50ptVXC -LMJZVy4A6VuMCmj3VQB1AOCSs/wMHcjnaDYf3mG5lk0KUngZinLWcsSwTaVtb1QE -AAABla+mSgEAAAQDAEYwRAIgXjJYEE32AFXfqx43ZOQrgP5cGdK5znOGCSxmjcMg -S/UCIBZNBTNVtJWGYKJQgS+bx7EbDDWobar7shNd1/jK0Kt3MAoGCCqGSM49BAMD -A2gAMGUCMQCoQeeM5wcNWCgtjoWPqduuEP/W0M4UrBydd2tVAAE7dbYb2Batj2Gg -qnaDMK2j/+ACMCNtwr4CWsgMAsK8HlDVM0UBvzEFOy2X+hkGzqOe0kfN+abHP0Sf -L0aZkl5gt8NcKg== +DDAKMAgGBmeBDAECATCCAQQGCisGAQQB1nkCBAIEgfUEgfIA8AB1AEiw42vapkc0 +D+VqAvqdMOscUgHLVt0sgdm7v6s52IRzAAABkDvuwaIAAAQDAEYwRAIgP3lyMqvr ++a7XWoRLxzQzhv6umJ/hiQPTWen3qqTao34CIGLq9y9ZPZUuo2smf49h9v9I9B4t +o6ihFaHoOB68q37DAHcA3+FW66oFr7WcD4ZxjajAMk6uVtlup/WlagHRwTu+UlwA +AAGQO+7CZAAABAMASDBGAiEAjl1f87koOUNfTNL4IRO+BBEVeHCxPvYRaztVJoC0 +x6ECIQDblc+Snmea3OSqydLcyi8xgdtMySyQgPElXLtM7H+RUjAKBggqhkjOPQQD +AwNoADBlAjA0FOSmTiYrA9Hd2T5DkI2TMOH2akk8SxXprkei6H37bI8O3br7ke8t +jwHWVtvN4d8CMQDohhdWUQ3G8Fl4ektN34oX6U3NcywBm96U3RVt5JYcfnn8ea68 +Qboj263s/g0Ciqs= -----END CERTIFICATE----- diff --git a/data/ssl/_.home.sophies-kitchen.eu.crt_intermediate.pem b/data/ssl/_.home.sophies-kitchen.eu.crt_intermediate.pem index 59039ae..4652201 100644 --- a/data/ssl/_.home.sophies-kitchen.eu.crt_intermediate.pem +++ b/data/ssl/_.home.sophies-kitchen.eu.crt_intermediate.pem @@ -1,27 +1,27 @@ -----BEGIN CERTIFICATE----- -MIIEVzCCAj+gAwIBAgIRAIOPbGPOsTmMYgZigxXJ/d4wDQYJKoZIhvcNAQELBQAw +MIIEVzCCAj+gAwIBAgIRALBXPpFzlydw27SHyzpFKzgwDQYJKoZIhvcNAQELBQAw TzELMAkGA1UEBhMCVVMxKTAnBgNVBAoTIEludGVybmV0IFNlY3VyaXR5IFJlc2Vh cmNoIEdyb3VwMRUwEwYDVQQDEwxJU1JHIFJvb3QgWDEwHhcNMjQwMzEzMDAwMDAw WhcNMjcwMzEyMjM1OTU5WjAyMQswCQYDVQQGEwJVUzEWMBQGA1UEChMNTGV0J3Mg -RW5jcnlwdDELMAkGA1UEAxMCRTUwdjAQBgcqhkjOPQIBBgUrgQQAIgNiAAQNCzqK -a2GOtu/cX1jnxkJFVKtj9mZhSAouWXW0gQI3ULc/FnncmOyhKJdyIBwsz9V8UiBO -VHhbhBRrwJCuhezAUUE8Wod/Bk3U/mDR+mwt4X2VEIiiCFQPmRpM5uoKrNijgfgw +RW5jcnlwdDELMAkGA1UEAxMCRTYwdjAQBgcqhkjOPQIBBgUrgQQAIgNiAATZ8Z5G +h/ghcWCoJuuj+rnq2h25EqfUJtlRFLFhfHWWvyILOR/VvtEKRqotPEoJhC6+QJVV +6RlAN2Z17TJOdwRJ+HB7wxjnzvdxEP6sdNgA1O1tHHMWMxCcOrLqbGL0vbijgfgw gfUwDgYDVR0PAQH/BAQDAgGGMB0GA1UdJQQWMBQGCCsGAQUFBwMCBggrBgEFBQcD -ATASBgNVHRMBAf8ECDAGAQH/AgEAMB0GA1UdDgQWBBSfK1/PPCFPnQS37SssxMZw -i9LXDTAfBgNVHSMEGDAWgBR5tFnme7bl5AFzgAiIyBpY9umbbjAyBggrBgEFBQcB +ATASBgNVHRMBAf8ECDAGAQH/AgEAMB0GA1UdDgQWBBSTJ0aYA6lRaI6Y1sRCSNsj +v1iU0jAfBgNVHSMEGDAWgBR5tFnme7bl5AFzgAiIyBpY9umbbjAyBggrBgEFBQcB AQQmMCQwIgYIKwYBBQUHMAKGFmh0dHA6Ly94MS5pLmxlbmNyLm9yZy8wEwYDVR0g BAwwCjAIBgZngQwBAgEwJwYDVR0fBCAwHjAcoBqgGIYWaHR0cDovL3gxLmMubGVu -Y3Iub3JnLzANBgkqhkiG9w0BAQsFAAOCAgEAH3KdNEVCQdqk0LKyuNImTKdRJY1C -2uw2SJajuhqkyGPY8C+zzsufZ+mgnhnq1A2KVQOSykOEnUbx1cy637rBAihx97r+ -bcwbZM6sTDIaEriR/PLk6LKs9Be0uoVxgOKDcpG9svD33J+G9Lcfv1K9luDmSTgG -6XNFIN5vfI5gs/lMPyojEMdIzK9blcl2/1vKxO8WGCcjvsQ1nJ/Pwt8LQZBfOFyV -XP8ubAp/au3dc4EKWG9MO5zcx1qT9+NXRGdVWxGvmBFRAajciMfXME1ZuGmk3/GO -koAM7ZkjZmleyokP1LGzmfJcUd9s7eeu1/9/eg5XlXd/55GtYjAM+C4DG5i7eaNq -cm2F+yxYIPt6cbbtYVNJCGfHWqHEQ4FYStUyFnv8sjyqU8ypgZaNJ9aVcWSICLOI -E1/Qv/7oKsnZCWJ926wU6RqG1OYPGOi1zuABhLw61cuPVDT28nQS/e6z95cJXq0e -K1BcaJ6fJZsmbjRgD5p3mvEf5vdQM7MCEvU0tHbsx2I5mHHJoABHb8KVBgWp/lcX -GWiWaeOyB7RP+OfDtvi2OsapxXiV7vNVs7fMlrRjY1joKaqmmycnBvAq14AEbtyL -sVfOS66B8apkeFX2NY4XPEYV4ZSCe8VHPrdrERk2wILG3T/EGmSIkCYVUMSnjmJd -VQD9F6Na/+zmXCc= +Y3Iub3JnLzANBgkqhkiG9w0BAQsFAAOCAgEAfYt7SiA1sgWGCIpunk46r4AExIRc +MxkKgUhNlrrv1B21hOaXN/5miE+LOTbrcmU/M9yvC6MVY730GNFoL8IhJ8j8vrOL +pMY22OP6baS1k9YMrtDTlwJHoGby04ThTUeBDksS9RiuHvicZqBedQdIF65pZuhp +eDcGBcLiYasQr/EO5gxxtLyTmgsHSOVSBcFOn9lgv7LECPq9i7mfH3mpxgrRKSxH +pOoZ0KXMcB+hHuvlklHntvcI0mMMQ0mhYj6qtMFStkF1RpCG3IPdIwpVCQqu8GV7 +s8ubknRzs+3C/Bm19RFOoiPpDkwvyNfvmQ14XkyqqKK5oZ8zhD32kFRQkxa8uZSu +h4aTImFxknu39waBxIRXE4jKxlAmQc4QjFZoq1KmQqQg0J/1JF8RlFvJas1VcjLv +YlvUB2t6npO6oQjB3l+PNf0DpQH7iUx3Wz5AjQCi6L25FjyE06q6BZ/QlmtYdl/8 +ZYao4SRqPEs/6cAiF+Qf5zg2UkaWtDphl1LKMuTNLotvsX99HP69V2faNyegodQ0 +LyTApr/vT01YPE46vNsDLgK+4cL6TrzC/a4WcmF5SRJ938zrv/duJHLXQIku5v0+ +EwOy59Hdm0PT/Er/84dDV0CSjdR/2XuZM3kpysSKLgD1cKiDA+IRguODCxfO9cyY +Ig46v9mFmBvyH04= -----END CERTIFICATE----- diff --git a/data/ssl/_.home.sophies-kitchen.eu.key.pem.vault b/data/ssl/_.home.sophies-kitchen.eu.key.pem.vault index 8f76986..2bc548a 100644 --- a/data/ssl/_.home.sophies-kitchen.eu.key.pem.vault +++ b/data/ssl/_.home.sophies-kitchen.eu.key.pem.vault @@ -1 +1 @@ -encrypt$gAAAAABn2wvcFmCiy7gpvvwJzRVNJSSxLvlld2ob9O2ivyekdR6y1_k90Q1xZhs7-ombGAIyez1D7lvuNhYQrnff5TqRa9wKbIVyqOOj4lc5qS2jJWyMl9BCr7Fu0mdW0_33Ke5nGpc3mAMjwTLCn8aw-I_I0kALuhKvZ_H31Oy0Mdjw9rau8TmeWGmJDiPMyHlg_C6s2Gvj2VKHVuGeSVg01frjlTveK-ZsJNGvKm7njCqvqGJytFeV6iHzWYyzMTk8-z_xtv-PKH82ME_IdGVv8YcgmCrXWzzA35A3YEaac7uKui1RFzqN6K5sYL1hsxU9rAyidNRd1fp0CRlpyJWgcf_ykoe2u3ManhFOdMmJdx_nrt2znNLaiQqcSHWuws7pGeSZtX72rGa5ZEBF5xeTruhRSQyjMUuBZrqi75QKyYnpmNSpgh0fDHqHUVmSQ5vInd8Tai2BWz3oqKhrkqJMIXlKQn35Jw== \ No newline at end of file +encrypt$gAAAAABmdb4pdFakOuqHPRpEu_RjEPVVS9Ef0kuvWKKT3Gr3056e0nhinh_THX1w7CqiZ4CQlvSIH7vlDNUORFWlqDuZJOh8FYPSzjr78aK1MqVGZHxQBK8VVNd0K5m1U3z9_4W_pB7Zr_5fLXDqtIW-t68GQPEfxCwy2h2eBepQ2zJiLupWa7JwuqiXH6QyB4gD5Y-9F30RjH52WtJLrx6XtgClPG0p-6FrHcNHqmMYqgpt11zvLa88lOBUoDGFrrqqFRbY039ay2b1jrQOAhTQLDxnAMsbr5jTSbST1modE-1u_Wis-Km-jcMwkiViZpK-HC6Ce_TNdt1NDarBat6nRhTrpqHXENlroVixHmGl1_-Y6mc75tJ-KHQKRRzwK8V_X62iA3vfSz1Xps8B1FZqxJWA2EdM0JkQecCuC-bnpedEoumYnif3vLhe91NV8SQ5FBlkd3NFT8vBAWCgnqT_jDf5YQW70w== \ No newline at end of file diff --git a/groups.py b/groups.py index b5acfd9..d99ced7 100644 --- a/groups.py +++ b/groups.py @@ -3,6 +3,7 @@ from pathlib import Path from bundlewrap.utils import error_context +groups = {} for group in Path(join(repo_path, "groups")).rglob("*.py"): with error_context(filename=str(group)): with open(group, 'r') as f: diff --git a/groups/locations.py b/groups/locations.py index 43e7674..00bf560 100644 --- a/groups/locations.py +++ b/groups/locations.py @@ -61,9 +61,6 @@ groups['home'] = { } groups['sophie'] = { - 'supergroups': { - 'linux', - }, 'member_patterns': { r"sophie\..*", }, @@ -71,9 +68,6 @@ groups['sophie'] = { 'icinga_options': { 'exclude_from_monitoring': True, }, - 'backup-client': { - 'target': 'htz-hel.backup-sophie', - }, 'users': { 'sophie': {}, }, diff --git a/groups/os.py b/groups/os.py index 34f49b2..a6fca0f 100644 --- a/groups/os.py +++ b/groups/os.py @@ -13,6 +13,7 @@ groups['raspberry'] = { groups['linux'] = { 'subgroups': { + 'arch', 'debian', 'raspberry', }, @@ -34,7 +35,7 @@ groups['linux'] = { }, 'metadata': { 'backup-client': { - 'target': 'backup-kunsi', + 'target': 'htz-hel.backup-kunsi', }, 'firewall': { 'port_rules': { @@ -47,6 +48,13 @@ groups['linux'] = { 'pip_command': 'pip3', } +groups['arch'] = { + 'bundles': { + 'pacman', + }, + 'os': 'arch', +} + groups['debian'] = { 'subgroup_patterns': { '^debian-[a-z]+$', @@ -71,10 +79,6 @@ groups['debian-bookworm'] = { 'os_version': (12,) } -groups['debian-trixie'] = { - 'os_version': (13,) -} - groups['debian-sid'] = { 'os_version': (99,) } diff --git a/hooks/test_zfs_consistency.py b/hooks/test_zfs_consistency.py index d7231e5..132afe3 100644 --- a/hooks/test_zfs_consistency.py +++ b/hooks/test_zfs_consistency.py @@ -25,7 +25,7 @@ def test_node(repo, node, **kwargs): pool_name = name.split('/', 1)[0] - if pool_name not in zfs_pools: + if pool_name not in zfs_pools and node.os != 'arch': raise BundleError('{n} zfs_dataset:{ds} wants zfs_pool:{pool}, which wasn\'t found'.format( n=node.name, ds=name, diff --git a/libs/demagify.py b/libs/demagify.py index 02180f0..5fe492c 100644 --- a/libs/demagify.py +++ b/libs/demagify.py @@ -1,6 +1,5 @@ import bwpass - def demagify(something, vault): if isinstance(something, str): if something.startswith('!bwpass:'): diff --git a/libs/s2s.py b/libs/s2s.py index 8372ec2..136a257 100644 --- a/libs/s2s.py +++ b/libs/s2s.py @@ -5,8 +5,7 @@ AS_NUMBERS = { 'home': 4290000138, 'htz-cloud': 4290000137, 'ionos': 4290000002, - 'revision': 4290000078, - 'rottenraptor': 4290000030, + 'glauca': 4290207960, } WG_AUTOGEN_NODES = [ @@ -18,7 +17,7 @@ WG_AUTOGEN_NODES = [ 'home.router', 'htz-cloud.wireguard', 'icinga2', - None, # daisy + 'daisy', ] WG_AUTOGEN_SETTINGS = { diff --git a/libs/ssh.py b/libs/ssh.py index fe3b9b4..89c643a 100644 --- a/libs/ssh.py +++ b/libs/ssh.py @@ -4,9 +4,9 @@ from hashlib import sha3_224 from cryptography.hazmat.primitives.asymmetric.ed25519 import Ed25519PrivateKey from cryptography.hazmat.primitives.serialization import (Encoding, - NoEncryption, - PrivateFormat, - PublicFormat) + NoEncryption, + PrivateFormat, + PublicFormat) from bundlewrap.utils import Fault diff --git a/libs/tools.py b/libs/tools.py index 4f98677..7a984df 100644 --- a/libs/tools.py +++ b/libs/tools.py @@ -5,7 +5,7 @@ from bundlewrap.utils.text import bold, red from bundlewrap.utils.ui import io -def resolve_identifier(repo, identifier, linklocal=False, only_physical=False, allow_private=True): +def resolve_identifier(repo, identifier, linklocal=False, only_physical=False): """ Try to resolve an identifier (group or node). Return a set of ip addresses valid for this identifier. @@ -62,15 +62,10 @@ def resolve_identifier(repo, identifier, linklocal=False, only_physical=False, a 'ipv6': set(), } - has_public_ips = bool([ip for ip in found_ips if not ip.is_private]) - for ip in found_ips: if ip.is_link_local and not linklocal: continue - if ip.is_private and not allow_private and has_public_ips: - continue - if isinstance(ip, IPv4Address): ip_dict['ipv4'].add(ip) else: diff --git a/nodes.py b/nodes.py index 1798613..f47f004 100644 --- a/nodes.py +++ b/nodes.py @@ -12,8 +12,6 @@ for name, data in nodes.items(): if 'password' in data: data['password'] = vault.decrypt(data['password']) - if 'ipmi' in data: - data['ipmi'].update(libs.demagify.demagify(data['ipmi'], vault)) data['metadata'].update(libs.demagify.demagify(data['metadata'], vault)) for node in Path(join(repo_path, "nodes")).rglob("*.py"): diff --git a/nodes/attributes.py b/nodes/attributes.py index eda23f4..85fa36d 100644 --- a/nodes/attributes.py +++ b/nodes/attributes.py @@ -1,7 +1,6 @@ -from bundlewrap.utils.scm import get_rev -from bundlewrap.utils.text import bold, red from bundlewrap.utils.ui import io - +from bundlewrap.utils.scm import get_rev +from bundlewrap.utils.text import red, bold @node_attribute def needs_apply(node): diff --git a/nodes/backup-kunsi.toml b/nodes/backup-kunsi.toml deleted file mode 100644 index 4a47ae4..0000000 --- a/nodes/backup-kunsi.toml +++ /dev/null @@ -1,38 +0,0 @@ -hostname = "2001:67c:b54:1::f" -bundles = ["backup-server", "dm-crypt", "zfs"] -groups = ["debian-bookworm"] - -[metadata] -nameservers = ["2001:4860:4860::8888"] - -[metadata.apt.packages.qemu-guest-agent] - -[metadata.apt.unattended-upgrades] -# requires manual apply to unlock disks -reboot_enabled = false - -[metadata.interfaces.ens18] -ips = ["2001:67c:b54:1::f/64"] -gateway6 = "2001:67c:b54:1::1" - -[metadata.backups] -# this is the backup server -exclude_from_backups = true - -[metadata.backup-server.zpool_create_options] -ashift = 12 - -[metadata.backup-server.encrypted-devices.WVT0RNKF] -device = "/dev/disk/by-id/scsi-0QEMU_QEMU_HARDDISK_drive-scsi4" -passphrase = "!bwpass:bw/backup-kunsi/ata-ST20000NM007D-3DJ103_WVT0RNKF" - -[metadata.backup-server.encrypted-devices.WVT0V0NQ] -device = "/dev/disk/by-id/scsi-0QEMU_QEMU_HARDDISK_drive-scsi5" -passphrase = "!bwpass:bw/backup-kunsi/ata-ST20000NM007D-3DJ103_WVT0V0NQ" - -[metadata.backup-server.encrypted-devices.WVT0W64H] -device = "/dev/disk/by-id/scsi-0QEMU_QEMU_HARDDISK_drive-scsi6" -passphrase = "!bwpass:bw/backup-kunsi/ata-ST20000NM007D-3DJ103_WVT0W64H" - -[metadata.zfs] -scrub_when = "Wed 08:00 Europe/Berlin" diff --git a/nodes/carlene.toml b/nodes/carlene.toml index d5625d9..16fa613 100644 --- a/nodes/carlene.toml +++ b/nodes/carlene.toml @@ -6,6 +6,7 @@ groups = [ bundles = [ "check-mail-received", "dovecot", + "element-web", "forgejo", "matrix-media-repo", "matrix-stickerpicker", @@ -15,6 +16,7 @@ bundles = [ "miniflux", "netbox", "nextcloud", + "nodejs", "ntfy", "oidentd", "php", @@ -36,9 +38,19 @@ email = "franzi.kunsmann@t-online.de" imap_host = "secureimap.t-online.de" imap_pass = "!bwpass_attr:t-online.de/franzi.kunsmann@t-online.de:imap" +[metadata.element-web] +url = "chat.franzi.business" +version = "v1.11.76" +[metadata.element-web.config] +default_server_config.'m.homeserver'.base_url = "https://matrix.franzi.business" +default_server_config.'m.homeserver'.server_name = "franzi.business" +brand = "franzi.business" +defaultCountryCode = "DE" +jitsi.preferredDomain = "meet.ffmuc.net" + [metadata.forgejo] -version = "11.0.0" -sha1 = "3a12529ab21ca04f2b3e6cf7a6c91af18f00ee5d" +version = "8.0.2" +sha1 = "c842480b99445b70c314e20be144789711fa7deb" domain = "git.franzi.business" enable_git_hooks = true install_ssh_key = true @@ -58,9 +70,9 @@ gateway6 = "2a0a:51c0:0:225::1" [metadata.matrix-media-repo] admins = ["@kunsi:franzi.business"] datastore_id = "3fff5da324ed784c771d638bb6be5917" -sha1 = "453c12cfb9f2c44c509620b63f94f8a9e2d048ef" +sha1 = "3e2bb7089b0898b86000243a82cc58ae998dc9d9" upload_max_mb = 500 -version = "v1.3.8" +version = "v1.3.7" [metadata.matrix-media-repo.homeservers.'franzi.business'] api = "synapse" domain = "http://[::1]:20080/" @@ -78,9 +90,13 @@ user_id = "@dimension:franzi.business" admin_contact = "mailto:hostmaster@kunbox.net" baseurl = "matrix.franzi.business" server_name = "franzi.business" -trusted_key_servers = ["matrix.org", "161.rocks"] +trusted_key_servers = ["matrix.org", "finallycoffee.eu"] additional_client_config.'im.vector.riot.jitsi'.preferredDomain = "meet.ffmuc.net" wellknown_also_on_vhosts = ["franzi.business"] +[metadata.matrix-synapse.sliding_sync] +version = "v0.99.15" +sha1 = "cecb371ff5f1dd528cfc490484a0967dcc28cd82" +secret = "!decrypt:encrypt$gAAAAABl9yJlbEZafJ2mumtg03rW0-440NIgFcgdWGMo3Axrypugwctacy9Cq7MYtCBGjnDyNvVLI5B2QMJ9ssCD46NCsFRN3-X4u9rDtxPhRZV7rls_LQ_Csc_GsffJfvpmHbn_wsljd3I74h4ouWlYhhEQUIKwb3eErSZ_VTZhu_bC4jTa0FY=" [metadata.mautrix-telegram] version = "v0.15.2" @@ -98,8 +114,8 @@ provisioning.shared_secret = "!decrypt:encrypt$gAAAAABfVKflEMAi07C_QGP8cy97hF-4g "'@kunsi:franzi.business'" = "admin" [metadata.mautrix-whatsapp] -version = "v0.12.0" -sha1 = "02094da0a164099d4d35e5edb4b87875ad694833" +version = "v0.10.9" +sha1 = "1619579ec6b9fca84fec085a94842d309d3f730c" permissions."'@kunsi:franzi.business'" = "admin" [metadata.mautrix-whatsapp.homeserver] domain = "franzi.business" @@ -110,7 +126,7 @@ domain = "rss.franzi.business" [metadata.netbox] domain = "netbox.franzi.business" -version = "v4.2.8" +version = "v4.1.0" admins.kunsi = "hostmaster@kunbox.net" [metadata.nextcloud] @@ -120,10 +136,6 @@ domain = "warnochwas.de" contact = "mailto:security@kunsmann.eu" Encryption = "https://franzi.business/gpg_hi-kunsmann.eu.asc" -[metadata.nginx.vhosts.'afra.berlin'.locations.'/'] -redirect = "https://afra-berlin.de" -mode = 302 - [metadata.nginx.vhosts.forgejo] domain_aliases = ["git.kunsmann.eu"] @@ -136,10 +148,8 @@ owner = "skye" [metadata.nginx.vhosts.kunsitracker] domain = "kunsitracker.de" -locations.'/'.target = "https://travelynx.franzi.business/" -locations.'/'.proxy_pass_host = "travelynx.franzi.business" -locations.'= /'.target = "https://travelynx.franzi.business/p/Kunsi" -locations.'= /'.proxy_pass_host = "travelynx.franzi.business" +locations.'/'.redirect = "https://travelynx.franzi.business/p/Kunsi" +locations.'/'.mode = 302 [metadata.nginx.vhosts.mta-sts] domain = "mta-sts.kunbox.net" @@ -172,6 +182,7 @@ ratelimit-exempt-hosts = [ ] [metadata.php] +version = "8.2" packages = [ 'gd', 'imagick', @@ -196,7 +207,7 @@ blocked_recipients = [ [metadata.postfixadmin] domain = "postfixadmin.franzi.business" setup_password = "!decrypt:encrypt$gAAAAABgnNGpAqUs--qBXII9ZPcHtxaELy9e2Dx9O44n4l0O4nMHPoIyaPW5HkvpQ2zWTlh5OfjjOgunRtE_voJuY0Kdtji37ixAnuL9ErOJ0LDY5QfMkNPUgPs5alwz1baqYq6rqJ7NDmB0gHraY46v5eG79R2EyQ==" -version = "3.3.15" +version = "3.3.13" [metadata.postgresql] version = 15 @@ -240,17 +251,12 @@ dkim = "uO4aNejDvVdw8BKne3KJIqAvCQMJ0416" [metadata.smartd] disks = [ - "/dev/disk/by-id/nvme-SAMSUNG_MZVL22T0HBLB-00B00_S677NF0W503350", - "/dev/disk/by-id/nvme-SAMSUNG_MZVL22T0HBLB-00B00_S677NX0W114380", + "/dev/nvme0", + "/dev/nvme1", ] -[metadata.systemd-timers.timers.42c3-topic] -command = "/home/kunsi/42c3-topic.sh" -user = "kunsi" -when = "04:00:00 Europe/Berlin" - [metadata.travelynx] -version = "2.11.24" +version = "2.8.35" mail_from = "travelynx@franzi.business" domain = "travelynx.franzi.business" diff --git a/nodes/daisy.toml b/nodes/daisy.toml new file mode 100644 index 0000000..b300487 --- /dev/null +++ b/nodes/daisy.toml @@ -0,0 +1,23 @@ +hostname = "2a11:f2c0:3:4::120" +bundles = [ + "bird", + "wireguard", +] +groups = [ + "debian-bookworm", +] + +[metadata] +location = "glauca" +nameservers = [ + "2606:4700::1111", + "2606:4700:4700::1001", +] +backups.exclude_from_backups = true +icinga_options.period = "daytime" + +[metadata.interfaces.ens18] +ips = [ + "2a11:f2c0:3:4::120/64", +] +gateway6 = "fe80::220:91ff:fe45:e19e" diff --git a/nodes/fkusei-locutus.py b/nodes/fkusei-locutus.py new file mode 100644 index 0000000..23118bd --- /dev/null +++ b/nodes/fkusei-locutus.py @@ -0,0 +1,190 @@ +nodes['fkusei-locutus'] = { + 'dummy': True, + 'hostname': '10.5.99.29', + 'bundles': { + 'arch-with-gui', + 'bird', + 'lldp', + 'lm-sensors', + 'nfs-client', + 'systemd-boot', + 'telegraf-battery-usage', + 'wireguard', + 'voc-tracker-worker', + 'zfs', + }, + 'groups': { + 'arch', + }, + 'metadata': { + 'arch-with-gui': { + 'autologin_as': 'fkunsmann', + }, + 'bird': { + 'bgp_neighbors': { + 'smedia': { + 'local_as': 4200128002, + 'local_ip': '10.200.128.2', + 'neighbor_as': 64900, + 'neighbor_ip': '10.200.128.1', + }, + }, + }, + 'firewall': { + 'port_rules': { + # obs websocket thingie - just allow all RFC1918 ips here + #'4444': { + # '10.0.0.0/8', + # '172.16.0.0/12', + # '192.168.0.0/16', + #}, + # For the occasional file-share using `python -m http.server` + '8000/tcp': {'*'}, + }, + }, + 'interfaces': { + 'eth*': { + 'dhcp': True, + }, + # there is also wlan0, but that's managed by netctl + }, + 'location': 'home', # not actually true, but needed for static dhcp lease + 'nfs-client': { + 'mounts': { + 'nas-storage': { + 'mountpoint': '/mnt/nas', + 'serverpath': '172.19.138.20:/storage/nas', + 'mount_options': { + 'retry=0', + 'ro', + }, + }, + }, + }, + 'openssh': { + 'restrict-to': { + 'rfc1918', + }, + }, + 'pacman': { + 'packages': { + 'amd-ucode': {}, + 'xf86-video-amdgpu': {}, + + # all that other random stuff one needs + 'apachedirectorystudio': {}, + 'direnv': {}, + 'freerdp': {}, + 'sdl_ttf': {}, # for compiling testcard + 'thermald': {}, + }, + }, + 'sysctl': { + 'options': { + # accept RA even though forwarding is enabled + 'net.ipv4.conf.all.accept_ra': '2', + 'net.ipv4.conf.wlan0.accept_ra': '2', + }, + }, + 'systemd-boot': { + 'default': 'arch', + 'entries': { + 'arch': { + 'title': 'Arch Linux', + 'linux': '/vmlinuz-linux', + 'initrd': [ + '/amd-ucode.img', + '/initramfs-linux.img', + ], + 'options': { + 'net.ifnames=0', + 'rw', + 'zfs=zroot/system/root', + }, + }, + 'arch-fallback': { + 'title': 'Arch Linux (no ucode, fallback initramfs)', + 'linux': '/vmlinuz-linux', + 'initrd': [ + '/initramfs-linux-fallback.img', + ], + 'options': { + 'net.ifnames=0', + 'rw', + 'zfs=zroot/system/root', + }, + }, + }, + }, + 'timezone': 'Europe/Berlin', + 'users': { + 'fkunsmann': { + 'password': vault.decrypt('encrypt$gAAAAABgLmmuQGRUStrQawoPee-758emIYn2u8-8ebrgzNAFSp7ifeFDdXXvs-zL3QogwNYlCtBHboH2xfy1rSj6OF5bbNO-tg=='), + 'shell': '/usr/bin/fish', + }, + }, + 'voc-tracker-worker': { + 'url': 'https://tracker.c3voc.de/rpc', + 'token': vault.decrypt('encrypt$gAAAAABiYqaFl4CqOc8DTQIn49Qq0KgAJSzA19GKPNMbyHIjYg0JkvY0sK43ps8CbJWMRR6hJHVK-nP4vrWLwyoWWqt8N8aASMur4odC2s8pEHQKM0TXg4cRwobQz_lyJgrYa2VYdhcD'), + 'secret': vault.decrypt('encrypt$gAAAAABiYqaYbY-3IbnRk-S25pqxrOGN7ovgPo3kBYz8ZqKDedPRzskKZefpLHxBbCOZKjg1XNT4cKbIs5cPCLdj7HdY4beAhnXl4EHZZdxU1zVC7sJCmz9XOS_Ac0UOgOlUFMiet14U'), + }, + 'wireguard': { + 'privatekey': vault.decrypt('smedia$NotViaThisRepository'), + 'peers': { + 'smedia': { + 'endpoint': 'wireguard.htz-cloud.kunbox.net:1194', + 'their_ip': '10.200.128.1', + 'my_ip': '10.200.128.2/20', + 'my_port': 51820, + 'endpoint': '185.122.180.82:51820', + 'psk': vault.decrypt('smedia$NotViaThisRepository'), + 'pubkey': vault.decrypt('smedia$NotViaThisRepository'), + }, + }, + }, + 'zfs': { + 'pools': { + 'zroot': { + 'when_creating': { + 'config': [], + }, + }, + }, + 'datasets': { + # this is not a complete list, but we can't create that + # structure using bundlewrap anyway, so there's no point + # in adding it here. + 'zroot': { + 'compression': 'lz4', + 'relatime': 'on', + 'xattr': 'sa', + 'primarycache': 'metadata' + # encryption is enabled, too. + }, + 'zroot/system/journal': { + 'mountpoint': '/var/log/journal', + 'acltype': 'posix', + }, + 'zroot/system/root': { + 'canmount': 'noauto', + 'mountpoint': '/', + }, + 'zroot/user/fkunsmann': { + 'mountpoint': '/home/fkunsmann', + }, + }, + 'snapshots': { + 'retain_per_dataset': { + 'zroot/user/fkunsmann': { + # juuuuuuuust to be sure + 'hourly': 100, + }, + }, + 'snapshot_never': { + 'zroot/system/journal', + }, + }, + }, + }, + 'os': 'arch', +} diff --git a/nodes/home.fujitsu-n7100.toml b/nodes/home.fujitsu-n7100.toml deleted file mode 100644 index 07d51c0..0000000 --- a/nodes/home.fujitsu-n7100.toml +++ /dev/null @@ -1,9 +0,0 @@ -dummy = true - -[metadata.interfaces.default] -ips = ["172.19.138.75"] -dhcp = true -mac = "00:01:29:59:a9:8c" - -[metadata.icinga_options] -exclude_from_monitoring = true diff --git a/nodes/home.hass.toml b/nodes/home.hass.toml index afb204f..b29dd0e 100644 --- a/nodes/home.hass.toml +++ b/nodes/home.hass.toml @@ -22,11 +22,17 @@ ram = 2 [metadata.homeassistant] domain = 'hass.home.kunbox.net' -api_secret = '!decrypt:encrypt$gAAAAABm9lNg_mNhyzb4S6WRtVRDmQFBnPpoCwyqMnilRrAFUXc-EDvv-nYXPbSIbjTf7ZReTPtqr8k3WrGPqiuqhJ60LVv4A5DMqT5c6hTVr4WbhP4DPEIPgfd5aq6U9_-H9WDyQYHKjnunLJEYtEREzmhTq3XsYeQ05DyE7hfnQ-zVoBb0CsAK7GdhihRTdvhXv2N9M04_rigyBP-roRcUgCqwyHuWJc0IPAyn3R4Mr43ZqgR2fn6dNV_YUVKn9c0nWxIwRnYy6Ff_Te9NoGVmXxkiNUX-90bBLKFiCzrRAtizxrTiQb2SRipaWbgOlV6wbMy2KNux' +api_secret = 'encrypt$gAAAAABjpyuqXLoilokQW5c0zV8shHcOzN1zkEbS-I6WAAX-xDO_OF33YbjbkpELU2HGBzqiWX40J0hsaEbYJOnCHFk8gJ-Xt0vdqqbQ5vca_TGPNQHZPAS4qZoPTcUhmX_I-0EdT6ukhxejXFYBiYRZikTLjH3lcNM5qnckCm-H9NbRdjLb9hbCDIjbEglHmBl_g08S1_ukvX3dDSCIHIxgXXGsdK_Go1KxPJd8G22FL_MMhCfsTW-6ioIqoHSeSA1NGk3MZHEIM2errckiopKBxoBaROsacO9Uqk1zrrgXOs2NsgiTRtrbV1TNlFVaIX9mZdsUnMGZ' + +[metadata.nginx] +restrict-to = [ + '172.19.136.0/25', + '172.19.138.0/24', +] [metadata.pyenv] -version = 'v2.4.23' -python_versions = ["3.13.1"] +version = 'v2.3.36' +python_versions = ["3.12.2"] [metadata.nginx.vhosts.homeassistant] ssl = '_.home.kunbox.net' diff --git a/nodes/home.mitel-rfp35.toml b/nodes/home.mitel-rfp35.toml new file mode 100644 index 0000000..414658a --- /dev/null +++ b/nodes/home.mitel-rfp35.toml @@ -0,0 +1,4 @@ +dummy = true + +[metadata.interfaces.default] +ips = ["172.19.138.41"] diff --git a/nodes/home.mixer96.toml b/nodes/home.mixer96.toml deleted file mode 100644 index 815205f..0000000 --- a/nodes/home.mixer96.toml +++ /dev/null @@ -1,9 +0,0 @@ -dummy = true - -[metadata.interfaces.default] -ips = ["172.19.138.98"] -dhcp = true -mac = "54:e1:ad:a6:0d:1f" - -[metadata.icinga_options] -exclude_from_monitoring = true diff --git a/nodes/home.r630-ipmi.toml b/nodes/home.r630-ipmi.toml new file mode 100644 index 0000000..f58012b --- /dev/null +++ b/nodes/home.r630-ipmi.toml @@ -0,0 +1,6 @@ +dummy = true + +[metadata.interfaces.eth0] +ips = ["172.19.138.23"] +dhcp = true +mac = "50:9a:4c:ad:f9:c4" diff --git a/nodes/home.r630.toml b/nodes/home.r630.toml index f41bb19..2a18418 100644 --- a/nodes/home.r630.toml +++ b/nodes/home.r630.toml @@ -1,15 +1,8 @@ hostname = "172.19.138.22" groups = ["debian-bookworm"] -bundles = ["docker-engine", "nginx", "redis"] - -ipmi_hostname = "172.19.138.23" -ipmi_username = "root" -ipmi_password = "calvin" -ipmi_interface = "lanplus" [metadata] icinga_options.exclude_from_monitoring = true -backups.exclude_from_backups = true [metadata.interfaces.eno3] ips = [ @@ -18,7 +11,7 @@ ips = [ gateway4 = "172.19.138.1" ipv6_accept_ra = true -[metadata.nftables.forward] +[metadata.nftable.forward] 50-local-forward = [ 'ct state { related, established } accept', 'iifname eno3 accept', diff --git a/nodes/home/downloadhelper.py b/nodes/home/downloadhelper.py index 4bd2f10..4874561 100644 --- a/nodes/home/downloadhelper.py +++ b/nodes/home/downloadhelper.py @@ -42,7 +42,7 @@ nodes['home.downloadhelper'] = { 'mounts': { 'storage': { 'mountpoint': '/mnt/nas', - 'serverpath': '172.19.138.20:/mnt/download', + 'serverpath': '172.19.138.20:/storage/download', 'mount_options': { 'retry=0', 'rw', diff --git a/nodes/home/nas.py b/nodes/home/nas.py index d4a4211..e5a1480 100644 --- a/nodes/home/nas.py +++ b/nodes/home/nas.py @@ -3,8 +3,8 @@ nodes['home.nas'] = { 'hostname': '172.19.138.20', 'bundles': { - 'avahi-daemon', 'backup-client', + 'dm-crypt', 'jellyfin', 'lm-sensors', 'mixcloud-downloader', @@ -12,6 +12,7 @@ nodes['home.nas'] = { 'nfs-server', 'rsyslogd', 'samba', + 'scansnap', 'smartd', 'vmhost', 'zfs', @@ -55,18 +56,16 @@ nodes['home.nas'] = { # systemctl start yate }, }, - 'avahi-daemon': { - 'use-ipv6': False, # because having a dynamic address confuses the network somehow - }, 'backups': { 'paths': { - '/home/kunsi/', - '/storage/nas/', - }, - }, - 'cron': { - 'jobs': { - 'avahi-aruba-fixup': '17,47 * * * * root /usr/bin/systemctl restart avahi-daemon.service', + '/storage/nas/Audiobooks', + '/storage/nas/Bilder', + '/storage/nas/Bilder_Archiv', + '/storage/nas/Books', + '/storage/nas/Installer', + '/storage/nas/Musik', + '/storage/nas/Musikvideos', + '/storage/nas/normen', }, }, 'groups': { @@ -80,9 +79,11 @@ nodes['home.nas'] = { }, '5060/tcp': { # yate SIP 'home.snom-wohnzimmer', + 'home.mitel-rfp35', }, '5061/tcp': { # yate SIPS 'home.snom-wohnzimmer', + 'home.mitel-rfp35', }, # yate RTP uses some random UDP port. We cannot firewall # it, because for incoming calls the other side decides @@ -92,9 +93,15 @@ nodes['home.nas'] = { # to deal with randomly changing IPs here. '*/udp': { 'home.snom-wohnzimmer', + 'home.mitel-rfp35', }, }, }, + 'jellyfin': { + 'restrict-to': { + 'home.lgtv-wohnzimmer', + }, + }, 'mixcloud-downloader': { 'netrc': { 'soundcloud': { @@ -130,26 +137,27 @@ nodes['home.nas'] = { 'restrict-to': { '172.19.136.0/25', '172.19.138.0/24', - 'htz-cloud.molly-connector', }, }, 'nfs-server': { 'shares': { - '/mnt/download': { + '/storage/download': { 'home.downloadhelper': 'rw,all_squash,anonuid=65534,anongid=1012,no_subtree_check', }, '/storage/nas': { - '172.19.138.0/24': 'ro,all_squash,anonuid=65534,anongid=65534,no_subtree_check,insecure', + '172.19.138.0/24': 'ro,all_squash,anonuid=65534,anongid=65534,no_subtree_check', }, '/srv/paperless': { 'home.paperless': 'rw,all_squash,anonuid=65534,anongid=65534,no_subtree_check', }, + '/srv/scansnap': { + '172.19.138.0/24': 'rw,all_squash,anonuid=65534,anongid=65534,no_subtree_check', + }, }, }, 'nginx': { 'vhosts': { 'jellyfin': { - 'create_logs': True, 'domain': 'jellyfin.home.kunbox.net', 'ssl': '_.home.kunbox.net', }, @@ -161,29 +169,23 @@ nodes['home.nas'] = { }, }, 'samba': { + 'shares': { + 'music': { + 'path': '/storage/nas/Musik', + 'force_group': 'nas', + }, + }, 'restrict-to': { '172.19.138.0/24', }, - 'timemachine-shares': { - 'apfelcomputer', - 'verrat', - }, }, 'smartd': { 'disks': { '/dev/nvme0', - # nas/timemachine disks - '/dev/disk/by-id/ata-WDC_WD6003FFBX-68MU3N0_V8GE15GR', - '/dev/disk/by-id/ata-WDC_WD6003FFBX-68MU3N0_V8HJ406R', - '/dev/disk/by-id/ata-WDC_WD6003FFBX-68MU3N0_V8HJBTLR', - '/dev/disk/by-id/ata-WDC_WD6003FFBX-68MU3N0_V8HJGN6R', - '/dev/disk/by-id/ata-WDC_WD6003FFBX-68MU3N0_V8J8ZKRR', - '/dev/disk/by-id/ata-WDC_WD6003FFBX-68MU3N0_V9JS5UYL', - - # ssdpool disks - '/dev/disk/by-id/ata-INTEL_SSDSC2KB960G8_PHYF244001QU960CGN', - '/dev/disk/by-id/ata-INTEL_SSDSC2KB960G8_PHYF244002AS960CGN', + # ZFS cache disks + #'/dev/disk/by-id/ata-TS64GSSD370_B807810503', + #'/dev/disk/by-id/ata-TS64GSSD370_B807810527', }, }, 'systemd-networkd': { @@ -222,11 +224,11 @@ nodes['home.nas'] = { 'enable_x_forwarding_for_admins': True, }, 'users': { - #'inbox': { - # 'ssh_pubkey': { - # #'command="/usr/share/rsync/scripts/rrsync -wo /storage/inbox/",no-agent-forwarding,no-port-forwarding,no-pty,no-user-rc,no-X11-forwarding ', - # }, - #}, + 'inbox': { + 'ssh_pubkey': { + #'command="/usr/share/rsync/scripts/rrsync -wo /storage/inbox/",no-agent-forwarding,no-port-forwarding,no-pty,no-user-rc,no-X11-forwarding ', + }, + }, 'kunsi': { 'groups': { 'nas', @@ -238,21 +240,7 @@ nodes['home.nas'] = { 'zfs_arc_max_gb': 8, }, 'pools': { - 'ssdpool': { - 'when_creating': { - 'config': [ - { - 'type': 'mirror', - 'devices': { - '/dev/disk/by-id/ata-INTEL_SSDSC2KB960G8_PHYF244001QU960CGN', - '/dev/disk/by-id/ata-INTEL_SSDSC2KB960G8_PHYF244002AS960CGN', - }, - }, - ], - 'ashift': 12, - }, - }, - 'tank': { + 'storage': { 'when_creating': { 'config': [ { @@ -266,54 +254,77 @@ nodes['home.nas'] = { '/dev/disk/by-id/ata-WDC_WD6003FFBX-68MU3N0_V8J8ZKRR', }, }, +# { +# 'type': 'log', +# 'devices': { +# '/dev/disk/by-id/ata-TS64GSSD370_B807810503-part1', +# '/dev/disk/by-id/ata-TS64GSSD370_B807810527-part1', +# }, +# }, +# { +# 'type': 'cache', +# 'devices': { +# '/dev/disk/by-id/ata-TS64GSSD370_B807810503-part2', +# '/dev/disk/by-id/ata-TS64GSSD370_B807810527-part2', +# }, +# }, ], 'ashift': 12, }, }, }, 'datasets': { - 'ssdpool': { + 'storage': { 'primarycache': 'metadata', }, - 'ssdpool/yate': { + 'storage/opt-yate': { 'mountpoint': '/opt/yate', }, - 'ssdpool/download': { - 'mountpoint': '/mnt/download', - 'quota': '858993459200', # 800 GB + 'storage/download': { + 'mountpoint': '/storage/download', }, - 'ssdpool/paperless': { - 'mountpoint': '/srv/paperless', + 'storage/inbox': { + 'quota': str(1024*1024*1024*1024), # 1TB + 'mountpoint': '/storage/inbox', }, - 'tank': { - 'primarycache': 'metadata', - }, - 'tank/nas': { + 'storage/nas': { 'acltype': 'off', 'atime': 'off', 'compression': 'off', 'mountpoint': '/storage/nas', }, + 'storage/paperless': { + 'mountpoint': '/srv/paperless', + }, + 'storage/scan': { + 'mountpoint': '/srv/scansnap', + }, }, 'snapshots': { 'retain_per_dataset': { - 'tank/nas': { - # juuuuuuuust to be sure. - 'daily': 14, - 'weekly': 6, - 'monthly': 12, - }, - 'ssdpool/download': { + 'storage/download': { 'hourly': 48, 'daily': 0, 'weekly': 0, 'monthly': 0, }, - 'ssdpool/paperless': { + 'storage/nas': { + # juuuuuuuust to be sure. + 'daily': 14, + 'weekly': 6, + 'monthly': 12, + }, + 'storage/paperless': { 'daily': 14, 'weekly': 6, 'monthly': 24, }, + 'storage/scan': { + 'hourly': 6, + 'daily': 0, + 'weekly': 0, + 'monthly': 0, + }, }, }, }, diff --git a/nodes/home/paperless.py b/nodes/home/paperless.py index f7035a5..b734ad3 100644 --- a/nodes/home/paperless.py +++ b/nodes/home/paperless.py @@ -6,10 +6,9 @@ nodes['home.paperless'] = { 'redis', 'postgresql', 'paperless-ng', - 'proftpd', }, 'groups': { - 'debian-trixie', + 'debian-bookworm', 'webserver', }, 'metadata': { @@ -42,24 +41,18 @@ nodes['home.paperless'] = { 'nginx': { 'vhosts': { 'paperless': { - 'create_logs': True, 'ssl': '_.home.kunbox.net', }, }, }, 'paperless': { 'domain': 'paperless.home.kunbox.net', - 'version': 'v2.15.3', + 'version': 'v2.11.6', 'timezone': 'Europe/Berlin', }, 'postgresql': { 'version': 15, }, - 'proftpd': { - 'restrict-to': { - 'home.fujitsu-n7100', - }, - }, 'vm': { 'cpu': 2, 'ram': 2, diff --git a/nodes/htz-cloud.afra.toml b/nodes/htz-cloud.afra.toml new file mode 100644 index 0000000..1585909 --- /dev/null +++ b/nodes/htz-cloud.afra.toml @@ -0,0 +1,100 @@ +hostname = "91.107.203.234" +bundles = [ + "element-web", + "matrix-media-repo", + "matrix-registration", + "matrix-synapse", + "nodejs", + "postgresql", + "zfs", +] +groups = [ + "debian-bookworm", + "webserver", +] + +[metadata.icinga_options] +pretty_name = "afra.berlin" + +[metadata.interfaces.eth0] +ips = [ + "91.107.203.234/32", + "2a01:4f8:c010:b0e1::1/64", +] +gateway4 = '172.31.1.1' +gateway6 = 'fe80::1' + +[metadata.interfaces.ens10] +ips = [ + "172.19.137.7/32", +] +routes.'172.19.128.0/20'.via = "172.19.137.1" + +[metadata.element-web] +url = "element.afra.berlin" +version = "v1.11.76" + +[metadata.element-web.config] +default_server_config.'m.homeserver'.base_url = "https://matrix.afra.berlin" +default_server_config.'m.homeserver'.server_name = "afra.berlin" +brand = "afra.berlin" +defaultCountryCode = "DE" +jitsi.preferredDomain = "meet.ffmuc.net" + +[metadata.matrix-media-repo] +admins = ['@administress:afra.berlin'] +datastore_id = "e33b50474021fba9977f912414cdd7fe8890ed57" +sha1 = "3e2bb7089b0898b86000243a82cc58ae998dc9d9" +upload_max_mb = 50 +version = "v1.3.7" + +[metadata.matrix-media-repo.homeservers.'afra.berlin'] +domain = "http://[::1]:20080/" +api = "synapse" +signing_key_path = "/etc/matrix-synapse/mmr.signing.key" + +[metadata.matrix-registration] +base_path = "/matrix" +client_redirect = "https://element.afra.berlin" + +[metadata.matrix-synapse] +server_name = "afra.berlin" +baseurl = "matrix.afra.berlin" +admin_contact = 'mailto:hostmaster@kunbox.net' +trusted_key_servers = [ + "matrix.org", + "franzi.business", +] +wellknown_also_on_vhosts = ["redirect"] + +[metadata.nginx.vhosts.redirect] +domain = "afra.berlin" + +[metadata.nginx.vhosts.redirect.locations.'/'] +redirect = "https://afra-berlin.de" +mode = 302 + +#[metadata.nginx.vhosts.redirect.locations.'/.well-known/host-meta'] +#redirect = "https://fedi.afra.berlin/.well-known/host-meta" +#mode = 301 +#[metadata.nginx.vhosts.redirect.locations.'/.well-known/nodeinfo'] +#redirect = "https://fedi.afra.berlin/.well-known/nodeinfo" +#mode = 301 +#[metadata.nginx.vhosts.redirect.locations.'/.well-known/webfinger'] +#redirect = "https://fedi.afra.berlin/.well-known/webfinger" +#mode = 301 + +[metadata.nginx.vhosts.redirect.locations.'/matrix/'] +target = "http://127.0.0.1:20100/" + +[metadata.postgresql] +version = "15" +work_mem = 1024 +cache_size = 2048 + +[[metadata.zfs.pools.tank.when_creating.config]] +devices = ["/dev/disk/by-id/scsi-0HC_Volume_32207877"] + +[metadata.vm] +cpu = 2 +ram = 8 diff --git a/nodes/htz-cloud.aurto.toml b/nodes/htz-cloud.aurto.toml new file mode 100644 index 0000000..16fbf9a --- /dev/null +++ b/nodes/htz-cloud.aurto.toml @@ -0,0 +1,59 @@ +hostname = "2a01:4f9:c010:95fa::2" +bundles = ["backup-client"] +groups = [ + "arch", + "webserver", +] + +[metadata] +description = [ + "When adding packages to aurto, please also add those packages to ~/PACKAGES", + "Wenn Pakete zu aurto hinzugefügt werden, trage sie bitte auch in ~/PACKAGES ein", +] + +[metadata.icinga_options] +period = "daytime" + +[metadata.backups] +paths = [ + "/var/cache/pacman/aurto", +] + +[metadata.interfaces.enp1s0] +ips = ["2a01:4f9:c010:95fa::2/64"] +gateway6 = "fe80::1" + +[metadata.interfaces.enp7s0] +ips = ["172.19.137.4/32"] +gateway4 = "172.19.137.1" + +[metadata.nginx.vhosts.aurto] +domain = "aurto.kunbox.net" +webroot = "/var/cache/pacman/aurto" +extras = true + +[metadata.pacman] +enable_aurto = false +additional_config = [ + "Include = /etc/pacman.d/aurto", +] + +[metadata.pacman.unattended-upgrades] +is_enabled = true + +[metadata.sudo.extra_configs] +50_aurto_passwordless = [ + "%wheel ALL=(ALL) NOPASSWD: /usr/bin/arch-nspawn", + "%wheel ALL=(ALL) NOPASSWD: /usr/bin/pacsync aurto", + "%wheel ALL=(ALL) NOPASSWD:SETENV: /usr/bin/makechrootpkg", +] + +[metadata.users.aurto] +groups = ["wheel"] +ssh_pubkey = [ + "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAICYst1HK+gJYhNxzqJGnz4iB73pa89Xz2yH+8wufOcsA", # kunsi work + "ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAACAQC+ja1z5VRQzaKCCePsUM14qMr9QR94qlWc7Je5Poki9UmC1t/TyxRVzcCBL1ZdIfBGx6QKtfkEbvhgb3nxVt3PvXjoJrc6wwGLmNrVsU6B88y35g7nzupQiPKYJwkNzJ9j6Dmkgj1F5Q+aY2SitDaX6vqICLJ4Al/ZFw2IQxVJfC7JXRJ9jRMG5o9gWoE3gWDYEAmw+HU2mNzyeuaD12qJw9DHUimAlgkOWzll3gh9WclsYnnXGrCCn5fyHFUCJl+XXAIy519z7YTpKih02rsIOw5dnaGClBZD/YQu2ZKVFZiwIVH7aBiqHOmtgRyWTQgjbh/fMpIN0ar2f/iZsWYUjd6et48TOmXZYIPCQ5FivXNvxt9oo1XZfq76UHBwlmypLJIWROMbz375n2M6hr3hECuxuPjKEUXAv05KiC1aJ4xc6pFoVhqwAR99hvHw5U4o7/ko2NVjNpTu6Jr5DT5VaQLIdDDjC/93kUjMpdD/8P72bEn7454+WexU6OE6uvNiHj1fetrptr2UAuzVfnCoaV8pBqY7X95gk+lnSENdpr8ltJYMg8s0Z7Pzz0OxsZtzzDY5VmWfC9TCdJkN5lT8IbnaixsYlWdjQl1lMmZGElmelfU3K7YQLAbZiHmHKe4hTl9ZoCcWdTQ3d4y2t1DBos+N2HZNdtFCyOS8esDdMw==", # kunsi privat +] + +[metadata.users.kunsi] +groups = ["wheel"] diff --git a/nodes/htz-cloud.prometheus.toml b/nodes/htz-cloud.prometheus.toml deleted file mode 100644 index 6532493..0000000 --- a/nodes/htz-cloud.prometheus.toml +++ /dev/null @@ -1,7 +0,0 @@ -hostname = "138.199.210.112" -groups = ["debian-bookworm"] - -[metadata.interfaces.eth0] -ips = ["138.199.210.112/32", "2a01:4f8:1c1e:65e4::1/64"] -gateway4 = "172.31.1.1" -gateway6 = "fe80::1" diff --git a/nodes/htz-cloud/pirmasens.py b/nodes/htz-cloud/pirmasens.py index 908e85e..b4c405d 100644 --- a/nodes/htz-cloud/pirmasens.py +++ b/nodes/htz-cloud/pirmasens.py @@ -52,10 +52,12 @@ nodes['htz-cloud.pirmasens'] = { }, }, 'php': { + 'version': '7.4', 'packages': { 'gd', 'imap', 'intl', + 'json', 'mbstring', 'opcache', 'pgsql', @@ -69,7 +71,7 @@ nodes['htz-cloud.pirmasens'] = { }, 'postfixadmin': { 'domain': 'mail.kunsmann.info', - 'version': '3.3.15', + 'version': '3.3.13', 'setup_password': vault.decrypt('encrypt$gAAAAABgnNGpAqUs--qBXII9ZPcHtxaELy9e2Dx9O44n4l0O4nMHPoIyaPW5HkvpQ2zWTlh5OfjjOgunRtE_voJuY0Kdtji37ixAnuL9ErOJ0LDY5QfMkNPUgPs5alwz1baqYq6rqJ7NDmB0gHraY46v5eG79R2EyQ=='), }, 'postgresql': { diff --git a/nodes/htz-cloud/wireguard.py b/nodes/htz-cloud/wireguard.py index 1139390..42c187d 100644 --- a/nodes/htz-cloud/wireguard.py +++ b/nodes/htz-cloud/wireguard.py @@ -37,8 +37,6 @@ nodes['htz-cloud.wireguard'] = { '172.19.137.0/24', '172.19.136.62/31', '172.19.136.64/31', - '172.19.136.66/31', - '192.168.100.0/24', }, }, 'nftables': { @@ -52,8 +50,6 @@ nodes['htz-cloud.wireguard'] = { '50-wireguard': [ 'udp dport 1194 accept', 'udp dport 51800 accept', - 'udp dport 51804 accept', - 'udp dport 51805 accept', # wg.c3voc.de 'udp dport 51801 ip saddr 185.106.84.42 accept', @@ -84,17 +80,6 @@ nodes['htz-cloud.wireguard'] = { '10.73.0.0/16', }, }, - 'fra-jana': { - 'endpoint': 'gw.as212226.net:40000', - 'my_ip': '192.168.48.11/24', - 'my_port': 51802, - 'their_ip': '192.168.48.1', - 'pubkey': vault.decrypt('encrypt$gAAAAABnCA7M0Jg0cQwIaYCYEYN74MOSQK30rbhxD6tDIi2VEBqPh-UHrt7MdRzI4AUZ-p0MzjIdsps_DdGBkUTwA_UKD15Q_tg_LJNwDb04zvgSqc3hnJ4jeS2ZZEED0T1dVJ7E0YNS'), - 'masquerade': True, - 'routes': { - '192.168.100.0/24', - }, - }, 'kunsi-oneplus7': { 'endpoint': None, 'exclude_from_monitoring': True, @@ -104,35 +89,12 @@ nodes['htz-cloud.wireguard'] = { 'psk': vault.decrypt('encrypt$gAAAAABlbr26kyQ_DNIObVNtG31e1uSZkfDKH9Y1tzq8ZNSAMeuEh30cMJBZQskLLYqt5HUGd-YFwYQB_E7oa-WWbHmDh4vAxJ22Efr85tA0TWsgkc2KvKHqZrNo-GCXhxCqs7SqhW1C'), 'pubkey': vault.decrypt('encrypt$gAAAAABlbr27doNVsPXF7hMpAp93fP-h_jlW10zycZAHy05r4R7rOZrLqf5b-lhdamx_kQxypYtcW-jOCYgcqWNsId7RluEmFo3drFuUYKIa32YU_U0Pe5EjVRFz_tuf9NRPPugmHb22'), }, - #'kunsi-p14s': { - # 'endpoint': None, - # 'exclude_from_monitoring': True, - # 'my_ip': '172.19.136.64', - # 'my_port': 1194, - # 'their_ip': '172.19.136.65', - #}, - 'apfelcomputer': { + 'kunsi-p14s': { 'endpoint': None, 'exclude_from_monitoring': True, 'my_ip': '172.19.136.64', 'my_port': 1194, 'their_ip': '172.19.136.65', - 'psk': vault.decrypt('encrypt$gAAAAABnc7LZSHWmOOQJpbtnpMn9QuWnbiB-6rShwgqbilVd45GzkUwOfEHBw28P_TVm9XJgFiQPOIo12DdxPCzSxKRtcqzji72QCzTlze4ZYWjL-iHm7TydLcKzXOTCO42LKpkMPUgR'), - 'pubkey': vault.decrypt('encrypt$gAAAAABnc7LZpfAeig8yCdcZ-NegshXl-DmkJr0F2OlQR2fqhVnrfKPjgOu-5Cq09KnhdvhomGx_9ZtoFS_3OsVqcFHEasBh27aQN41xZPzEN5-qIPQRnmVoTHpufcU6tC-37Fq-PeAE'), - }, - 'revision-dect-vpn': { - 'endpoint': None, - 'exclude_from_monitoring': True, - 'my_port': 51804, - 'my_ip': '172.19.136.66', - 'their_ip': '172.19.136.67', - }, - 'rottenraptor-vpn': { - 'endpoint': None, - 'exclude_from_monitoring': True, - 'my_port': 51805, - 'my_ip': '172.19.136.68', - 'their_ip': '172.19.136.69', }, }, }, diff --git a/nodes/htz-hel/backup-kunsi.py b/nodes/htz-hel/backup-kunsi.py new file mode 100644 index 0000000..6db104e --- /dev/null +++ b/nodes/htz-hel/backup-kunsi.py @@ -0,0 +1,37 @@ +nodes['htz-hel.backup-kunsi'] = { + 'hostname': '2a01:4f9:6b:2d99::1337', + 'bundles': { + 'backup-server', + 'dm-crypt', + 'zfs', + }, + 'groups': { + 'debian-bullseye', + }, + 'metadata': { + 'apt': { + 'unattended-upgrades': { + # requires manual apply after reboot to unlock dm-crypt + # devices + 'reboot_enabled': False, + }, + }, + 'interfaces': { + 'ens18': { + 'ips': { + '2a01:4f9:6b:2d99::1337/64', + }, + 'gateway6': '2a01:4f9:6b:2d99::2', + }, + }, + 'backups': { + # This is the backup target. + 'exclude_from_backups': True, + }, + 'backup-server': { + 'encrypted-devices': { + '/dev/disk/by-id/scsi-0QEMU_QEMU_HARDDISK_drive-scsi1-part1': bwpass.password('bw/backup-kunsi/encryption-passphrase'), + }, + }, + }, +} diff --git a/nodes/htz-hel/proxmox-backupstorage.toml b/nodes/htz-hel/proxmox-backupstorage.toml new file mode 100644 index 0000000..19d83d3 --- /dev/null +++ b/nodes/htz-hel/proxmox-backupstorage.toml @@ -0,0 +1,19 @@ +hostname = "2a01:4f9:6b:2d99::c0ff:ee" +dummy = true + +# How to install: +# - Get server at Hetzner (no IPv4) +# - Install latest proxmox compatible debian +# - RAID5 +# - 50G for system +# - leave rest unpartitioned +# - install zfs +# - create additional partitions for remaining disk space +# - create raidz on those partitions +# - enable ipv6 forwarding +# - install proxmox via apt + +# VM config: +# - IPv6 only +# - IP from the /64 hetzner gives us +# - Gateway is the host itself, to work around the MAC filter hetzner uses diff --git a/nodes/kunsi-p14s.py b/nodes/kunsi-p14s.py new file mode 100644 index 0000000..5e63351 --- /dev/null +++ b/nodes/kunsi-p14s.py @@ -0,0 +1,252 @@ +nodes['kunsi-p14s'] = { + 'hostname': 'localhost', + 'bundles': { + 'arch-with-gui', + 'backup-client', + 'lldp', + 'lm-sensors', + 'nfs-client', + 'systemd-boot', + 'telegraf-battery-usage', + 'vmhost', + 'wireguard', + 'zfs', + }, + 'groups': { + 'arch', + }, + 'metadata': { + 'arch-with-gui': { + 'autologin_as': 'kunsi', + }, + 'backup-client': { + 'exclude_from_monitoring': False, + # only alert people if we're missing more than a week of backups + 'one_backup_every_hours': 7 * 24, + }, + 'firewall': { + 'port_rules': { + # obs websocket thingie - just allow all RFC1918 ips here + #'4444': { + # '10.0.0.0/8', + # '172.16.0.0/12', + # '192.168.0.0/16', + #}, + # For the occasional file-share using `python -m http.server` + '8000/tcp': {'*'}, + }, + }, + 'interfaces': { + 'br0': { + 'ips': {'10.73.100.112/16'}, + 'gateway4': '10.73.0.254', + 'dhcp': True, + }, + # there is also wlp3s0, but that's managed by netctl + }, + 'nfs-client': { + 'mounts': { + 'nas-scansnap': { + 'mountpoint': '/mnt/scansnap', + 'serverpath': '172.19.138.20:/srv/scansnap', + 'mount_options': { + 'retry=0', + 'rw', + }, + }, + 'nas-storage': { + 'mountpoint': '/mnt/nas', + 'serverpath': '172.19.138.20:/storage/nas', + 'mount_options': { + 'retry=0', + 'ro', + }, + }, + }, + }, + 'nftables': { + 'forward': { + '50-routing': [ + 'ct state { related, established } accept', + 'oifname wlan0 accept', + ], + }, + 'postrouting': { + '50-routing': [ + 'oifname wlan0 masquerade', + ], + }, + }, + 'openssh': { + 'restrict-to': { + 'rfc1918', + }, + }, + 'pacman': { + 'no_extract': { + 'etc/sudoers.d/ctdb', # samba junk + }, + 'packages': { + # for hardware support + 'amd-ucode': {}, + 'mesa': {}, + + # various video drivers + 'libva-mesa-driver': {}, + 'mesa-vdpau': {}, + 'xf86-video-amdgpu': {}, + + # all that other random stuff one needs + 'abcde': {}, + 'apachedirectorystudio': {}, + 'claws-mail': {}, + 'claws-mail-themes': {}, + 'ferdium-bin': {}, + 'gumbo-parser': {}, # for claws litehtml + 'inkstitch': {}, # for RZL embroidery machine + 'obs-studio': {}, + 'perl-musicbrainz-discid': {}, # for abcde + 'perl-webservice-musicbrainz': {}, # for abcde + 'sdl_ttf': {}, # for compiling testcard + 'x32edit': {}, + }, + }, + 'systemd-boot': { + 'default': 'arch', + 'entries': { + 'arch': { + 'title': 'Arch Linux', + 'linux': '/vmlinuz-linux', + 'initrd': [ + '/amd-ucode.img', + '/initramfs-linux.img', + ], + 'options': { + 'net.ifnames=0', + 'rw', + 'zfs=zroot/system/root', + }, + }, + 'arch-fallback': { + 'title': 'Arch Linux (no ucode, fallback initramfs)', + 'linux': '/vmlinuz-linux', + 'initrd': [ + '/initramfs-linux-fallback.img', + ], + 'options': { + 'net.ifnames=0', + 'rw', + 'zfs=zroot/system/root', + }, + }, + }, + }, + 'sysctl': { + 'options': { + 'net.ipv4.conf.all.forwarding': '1', + }, + }, + 'systemd-networkd': { + 'bridges': { + 'br0': { + 'match': { + 'en*', + 'eth*', + }, + }, + }, + }, + 'timezone': 'Europe/Berlin', + 'users': { + 'kunsi': { + 'password': vault.decrypt('encrypt$gAAAAABgLmmuQGRUStrQawoPee-758emIYn2u8-8ebrgzNAFSp7ifeFDdXXvs-zL3QogwNYlCtBHboH2xfy1rSj6OF5bbNO-tg=='), + 'shell': '/usr/bin/fish', + }, + }, + 'wireguard': { + 'peers': { + 'htz-cloud.wireguard': { + 'auto_connection': False, + 'endpoint': 'wireguard.htz-cloud.kunbox.net:1194', + 'my_ip': '172.19.136.65', + 'my_port': 51819, + 'their_ip': '172.19.136.64', + 'routes': { + '10.73.0.0/16', + '172.19.128.0/20', + }, + }, + }, + }, + 'zfs': { + 'pools': { + 'zroot': { + 'when_creating': { + 'config': [{ + 'devices': [ + '/dev/disk/by-id/nvme-UMIS_RPETJ1T24MGE2QDQ_SS0L25218X3RC1BG1182-part2', + ], + }], + 'ashift': 12, + }, + }, + }, + 'datasets': { + # this is not a complete list, but we can't create that + # structure using bundlewrap anyway, so there's no point + # in adding it here. + 'zroot': { + 'compression': 'lz4', + 'relatime': 'on', + 'xattr': 'sa', + 'primarycache': 'metadata' + # encryption is enabled, too. + }, + 'zroot/movies': { + 'mountpoint': '/media/movies', + }, + 'zroot/nextcloud': { + 'mountpoint': '/home/kunsi/nextcloud', + }, + 'zroot/system/journal': { + 'mountpoint': '/var/log/journal', + 'acltype': 'posix', + }, + 'zroot/system/libvirt': { + 'mountpoint': '/var/lib/libvirt', + 'needed_by': { + 'bundle:vmhost', + }, + }, + 'zroot/system/video': { + 'mountpoint': '/video', + 'needed_by': { + 'bundle:voc-tracker-worker', + }, + }, + 'zroot/system/root': { + 'canmount': 'noauto', + 'mountpoint': 'legacy', + }, + 'zroot/user/kunsi': { + 'mountpoint': '/home/kunsi', + }, + }, + 'snapshots': { + 'retain_per_dataset': { + 'zroot/user/kunsi': { + # juuuuuuuust to be sure + 'hourly': 100, + }, + }, + 'snapshot_never': { + 'zroot/movies', + 'zroot/nextcloud', + 'zroot/system/journal', + 'zroot/system/video', + }, + }, + }, + }, + 'os': 'arch', +} diff --git a/nodes/proxmox-backupstorage.toml b/nodes/proxmox-backupstorage.toml deleted file mode 100644 index 7f10946..0000000 --- a/nodes/proxmox-backupstorage.toml +++ /dev/null @@ -1,51 +0,0 @@ -hostname = "192.168.100.31" -dummy = true - -ipmi_hostname = "192.168.100.30" -ipmi_username = "root" -ipmi_password = "!bwpass:192.168.100.30/root" -ipmi_interface = "lanplus" - -[metadata.icinga2_api.smartd.services."SMART STATUS CT480BX500SSD1_2314E6C5C695"] -check_command = "sshmon" -"vars.sshmon_command" = "CT480BX500SSD1_2314E6C5C695" - -[metadata.icinga2_api.smartd.services."SMART STATUS CT480BX500SSD1_2314E6C5C6C8"] -check_command = "sshmon" -"vars.sshmon_command" = "CT480BX500SSD1_2314E6C5C6C8" - -[metadata.icinga2_api.smartd.services."SMART STATUS ST20000NM007D-3DJ103_WVT0RNKF"] -check_command = "sshmon" -"vars.sshmon_command" = "ST20000NM007D-3DJ103_WVT0RNKF" - -[metadata.icinga2_api.smartd.services."SMART STATUS ST20000NM007D-3DJ103_WVT0V0NQ"] -check_command = "sshmon" -"vars.sshmon_command" = "ST20000NM007D-3DJ103_WVT0V0NQ" - -[metadata.icinga2_api.smartd.services."SMART STATUS ST20000NM007D-3DJ103_WVT0W64H"] -check_command = "sshmon" -"vars.sshmon_command" = "ST20000NM007D-3DJ103_WVT0W64H" - -[metadata.icinga2_api.smartd.services."SMART STATUS ST18000NM0092-3CX103_ZVV0686W"] -check_command = "sshmon" -"vars.sshmon_command" = "ST18000NM0092-3CX103_ZVV0686W" - -[metadata.icinga2_api.smartd.services."SMART STATUS ST18000NM0092-3CX103_ZVV06JV7"] -check_command = "sshmon" -"vars.sshmon_command" = "ST18000NM0092-3CX103_ZVV06JV7" - -[metadata.icinga2_api.smartd.services."SMART STATUS ST18000NM0092-3CX103_ZVV06SLR"] -check_command = "sshmon" -"vars.sshmon_command" = "ST18000NM0092-3CX103_ZVV06SLR" - -[metadata.icinga2_api.smartd.services."SMART STATUS ST8000NM0045-1RL112_ZA1EYQWR"] -check_command = "sshmon" -"vars.sshmon_command" = "ST8000NM0045-1RL112_ZA1EYQWR" - -[metadata.icinga2_api.smartd.services."SMART STATUS ST8000NM0045-1RL112_ZA1EYZQF"] -check_command = "sshmon" -"vars.sshmon_command" = "ST8000NM0045-1RL112_ZA1EYZQF" - -[metadata.icinga2_api.smartd.services."SMART STATUS ST8000NM0045-1RL112_ZA1EZ0X5"] -check_command = "sshmon" -"vars.sshmon_command" = "ST8000NM0045-1RL112_ZA1EZ0X5" diff --git a/nodes/revision-dect-vpn.toml b/nodes/revision-dect-vpn.toml deleted file mode 100644 index 1340297..0000000 --- a/nodes/revision-dect-vpn.toml +++ /dev/null @@ -1,27 +0,0 @@ -hostname = "10.1.3.252" -bundles = ["bird", "wireguard"] -groups = ["debian-bookworm"] - -[metadata] -location = "revision" -backups.exclude_from_backups = true -icinga_options.exclude_from_monitoring = true - -[metadata.bird] -static_routes = [ - "10.1.3.0/24", -] - -[metadata.interfaces.ens18] -ips = ["10.1.3.252/24"] -gateway4 = "10.1.3.1" - -[metadata.nftables.postrouting] -"50-router" = [ - "oifname ens18 masquerade", -] - -[metadata.wireguard.peers."htz-cloud.wireguard"] -my_port = 51804 -my_ip = "172.19.136.67" -their_ip = "172.19.136.66" diff --git a/nodes/rottenraptor-server.toml b/nodes/rottenraptor-server.toml deleted file mode 100644 index dadc232..0000000 --- a/nodes/rottenraptor-server.toml +++ /dev/null @@ -1,92 +0,0 @@ -hostname = "91.198.192.207" -groups = [ - "debian-bookworm", - "webserver", -] -bundles = [ - "docker-engine", - "docker-goauthentik", - "docker-immich", - "ipmitool", - "php", - "smartd", - "zfs", -] - -ipmi_hostname = "192.168.100.27" -ipmi_username = "Administrator" -ipmi_password = "!bwpass:bw/rottenraptor-server/ipmi" -ipmi_interface = "lanplus" - -[metadata.docker-immich] -enable_auto_album_share = true - -[metadata.icinga_options] -period = "daytime" - -[metadata.interfaces.eno4] -ips = [ - "91.198.192.207/27", - "2001:67c:b54:1::e/64", -] -gateway4 = "91.198.192.193" -gateway6 = "2001:67c:b54:1::1" - -[metadata.nginx.vhosts.'rotten.city'.locations.'/'] -redirect = "https://www.rottenraptor.com/" -mode = 302 - -[metadata.nginx.vhosts.dokuwiki] -domain = "wiki.rotten.city" -php = true -extras = true -webroot_config.owner = "www-data" - -[metadata.nginx.vhosts.goauthentik] -domain = "sso.rotten.city" - -[metadata.nginx.vhosts.immich] -domain = "immich.rotten.city" - -[metadata.php] -packages = [ - "xml", -] - -[metadata.smartd] -disks = [ - "/dev/disk/by-id/ata-HUH721008ALN600_7SGH125C", - "/dev/disk/by-id/ata-HUH721008ALN600_7SGH726C", - "/dev/disk/by-id/ata-WDC_WDS100T1R0A-68A4W0_21133V800321", - "/dev/disk/by-id/ata-WDC_WDS100T1R0A-68A4W0_21283J446103", - "/dev/disk/by-id/nvme-TOSHIBA-RC100_58UPC29HPW5S", -] - -[metadata.vm] -cpu = 4 -ram = 8 - -[metadata.zfs.pools.tank.when_creating] -ashift = 12 - -[[metadata.zfs.pools.tank.when_creating.config]] -type = "mirror" -devices = [ - "/dev/disk/by-id/ata-HUH721008ALN600_7SGH125C", - "/dev/disk/by-id/ata-HUH721008ALN600_7SGH726C", -] - -[[metadata.zfs.pools.tank.when_creating.config]] -type = "log" -devices = [ - "/dev/disk/by-id/ata-WDC_WDS100T1R0A-68A4W0_21133V800321-part1", - "/dev/disk/by-id/ata-WDC_WDS100T1R0A-68A4W0_21283J446103-part1", -] - -[[metadata.zfs.pools.tank.when_creating.config]] -type = "cache" -devices = [ - "/dev/disk/by-id/ata-WDC_WDS100T1R0A-68A4W0_21133V800321-part2", - "/dev/disk/by-id/ata-WDC_WDS100T1R0A-68A4W0_21283J446103-part2", -] - diff --git a/nodes/rottenraptor-vpn.toml b/nodes/rottenraptor-vpn.toml deleted file mode 100644 index 342ce1c..0000000 --- a/nodes/rottenraptor-vpn.toml +++ /dev/null @@ -1,27 +0,0 @@ -hostname = "172.30.17.53" -bundles = ["bird", "wireguard"] -groups = ["debian-bookworm"] - -[metadata] -location = "rottenraptor" -backups.exclude_from_backups = true -icinga_options.exclude_from_monitoring = true - -[metadata.bird] -static_routes = [ - "172.30.17.0/24", -] - -[metadata.interfaces.ens18] -ips = ["172.30.17.53/24"] -gateway4 = "172.30.17.1" - -[metadata.nftables.postrouting] -"50-router" = [ - "oifname ens18 masquerade", -] - -[metadata.wireguard.peers."htz-cloud.wireguard"] -my_port = 51804 -my_ip = "172.19.136.69" -their_ip = "172.19.136.68" diff --git a/nodes/sophie/backupserver.py b/nodes/sophie/backupserver.py index 42c6292..efabae1 100644 --- a/nodes/sophie/backupserver.py +++ b/nodes/sophie/backupserver.py @@ -37,7 +37,6 @@ nodes['htz-hel.backup-sophie'] = { }, 'backup-server': { 'zfs-base': 'tank/backups', - 'my_hostname': 'backup.sophies-kitchen.eu', }, 'nftables': { 'input': { diff --git a/nodes/sophie/miniserver.py b/nodes/sophie/miniserver.py index b852a35..a6603b9 100644 --- a/nodes/sophie/miniserver.py +++ b/nodes/sophie/miniserver.py @@ -1,260 +1,256 @@ # sophie's miniserver -nodes["htz-cloud.miniserver"] = { - "bundles": { - "element-web", - "hedgedoc", - "matrix-media-repo", - "matrix-synapse", +nodes['htz-cloud.miniserver'] = { + 'bundles': { + 'element-web', + 'hedgedoc', + 'matrix-media-repo', + 'matrix-synapse', "matrix-stickerpicker", - "nodejs", - "ntfy", - "mautrix-telegram", - "postgresql", - "zfs", + 'nodejs', + 'ntfy', + 'mautrix-telegram', + 'postgresql', + 'zfs', }, - "groups": { - "debian-bookworm", - "sophie", - "webserver", + 'groups': { + 'debian-bookworm', + 'sophie', + 'webserver', }, - "metadata": { - "interfaces": { - "eth0": { - "ips": { - "157.90.20.62", - "2a01:4f8:c2c:840f::1/64", + 'metadata': { + 'interfaces': { + 'eth0': { + 'ips': { + '157.90.20.62', + '2a01:4f8:c2c:840f::1/64', }, - "gateway4": "172.31.1.1", - "gateway6": "fe80::1", + 'gateway4': '172.31.1.1', + 'gateway6': 'fe80::1', }, }, - "apt": { - "packages": { - "mosh": {}, - "weechat": {}, - "weechat-core": {}, - "weechat-curses": {}, - "weechat-perl": {}, - "weechat-plugins": {}, - "weechat-python": {}, - "weechat-ruby": {}, + 'apt': { + 'packages': { + 'mosh': {}, + 'weechat': {}, + 'weechat-core': {}, + 'weechat-curses': {}, + 'weechat-perl': {}, + 'weechat-plugins': {}, + 'weechat-python': {}, + 'weechat-ruby': {}, }, - "repos": { - "weechat": { - "items": { - "deb https://weechat.org/debian {os_release} main", + 'repos': { + 'weechat': { + 'items': { + 'deb https://weechat.org/debian {os_release} main', }, }, }, }, - "backup-client": { - "pre-hooks": { - "sophie-weechat": "echo 'core.weechat */layout store' >> /home/sophie/.weechat/weechat_fifo\n" - "echo 'core.weechat */save' >> /home/sophie/.weechat/weechat_fifo\n", + 'backup-client': { + 'pre-hooks': { + 'sophie-weechat': \ + 'echo \'core.weechat */layout store\' >> /home/sophie/.weechat/weechat_fifo\n' \ + 'echo \'core.weechat */save\' >> /home/sophie/.weechat/weechat_fifo\n', + }, + 'target': "htz-hel.backup-sophie", + }, + 'backups': { + 'paths': { + '/home/sophie/.weechat', }, }, - "backups": { - "paths": { - "/home/sophie/.weechat", - }, - }, - "element-web": { - "url": "chat.sophies-kitchen.eu", - "version": "v1.11.96", - "config": { - "default_server_config": { - "m.homeserver": { - "base_url": "https://matrix.sophies-kitchen.eu", - "server_name": "sophies-kitchen.eu", + 'element-web': { + 'url': 'chat.sophies-kitchen.eu', + 'version': 'v1.11.76', + 'config': { + 'default_server_config': { + 'm.homeserver': { + 'base_url': 'https://matrix.sophies-kitchen.eu', + 'server_name': 'sophies-kitchen.eu', }, }, - "brand": "sophies-kitchen.eu", - "showLabsSettings": True, - "default_theme": "dark", - "defaultCountryCode": "DE", - "jitsi": { - "preferredDomain": "meet.ffmuc.net", + 'brand': 'sophies-kitchen.eu', + 'showLabsSettings': True, + 'default_theme': 'dark', + 'defaultCountryCode': 'DE', + 'jitsi': { + 'preferredDomain': 'meet.ffmuc.net', }, - "map_style_url": "https://api.maptiler.com/maps/openstreetmap/style.json?key=fU3vlMsMn4Jb6dnEIFsx", + 'map_style_url': "https://api.maptiler.com/maps/openstreetmap/style.json?key=fU3vlMsMn4Jb6dnEIFsx" }, }, - "hedgedoc": { - "version": "1.10.0", - "config": { - "production": { - "allowAnonymousEdits": True, - "domain": "pad.sophies-kitchen.eu", + 'hedgedoc': { + 'version': '1.9.9', + 'config': { + 'production': { + 'allowAnonymousEdits': True, + 'domain': 'pad.sophies-kitchen.eu', }, }, }, - "letsencrypt": { - "concat_and_deploy": { - "sophie-weechat": { - "match_domain": "i.sophies-kitchen.eu", - "target": "/home/sophie/.weechat/ssl/relay.pem", - "chown": "sophie:sophie", - "chmod": "0440", - "commands": [ - "echo 'core.weechat */relay sslcertkey' >> /home/sophie/.weechat/weechat_fifo" + 'letsencrypt': { + 'concat_and_deploy': { + 'sophie-weechat': { + 'match_domain': 'i.sophies-kitchen.eu', + 'target': '/home/sophie/.weechat/ssl/relay.pem', + 'chown': 'sophie:sophie', + 'chmod': '0440', + 'commands': [ + 'echo \'core.weechat */relay sslcertkey\' >> /home/sophie/.weechat/weechat_fifo' ], }, }, - "domains": { - "i.sophies-kitchen.eu": set(), - "webdump.sophies-kitchen.eu": set(), - "matrix.sophies-kitchen.eu": { - "sophies-kitchen.eu", + 'domains': { + 'i.sophies-kitchen.eu': set(), + 'webdump.sophies-kitchen.eu': set(), + 'matrix.sophies-kitchen.eu': { + 'sophies-kitchen.eu', }, }, }, - "matrix-media-repo": { - "version": "v1.3.7", - "datastore_id": "99c09e24edc4e9be6c4c9486bc147e385bc87044", - "sha1": "3e2bb7089b0898b86000243a82cc58ae998dc9d9", - "homeservers": { - "sophies-kitchen.eu": { - "domain": "http://[::1]:20080/", - "api": "synapse", - "signing_key_path": "/etc/matrix-synapse/mmr.signing.key", + 'matrix-media-repo': { + 'version': 'v1.3.7', + 'datastore_id': '99c09e24edc4e9be6c4c9486bc147e385bc87044', + 'sha1': '3e2bb7089b0898b86000243a82cc58ae998dc9d9', + 'homeservers': { + 'sophies-kitchen.eu': { + 'domain': 'http://[::1]:20080/', + 'api': 'synapse', + 'signing_key_path': "/etc/matrix-synapse/mmr.signing.key" }, }, - "admins": { - "@sophie:sophies-kitchen.eu", + 'admins': { + '@sophie:sophies-kitchen.eu', }, - "upload_max_mb": 500, + 'upload_max_mb': 500, }, - "matrix-stickerpicker": { - # use this bot token for telegram import: encrypt$gAAAAABg4bcQVzBF_iXdDtjRQD-O37GHdbHwWXyhCLPOuJLbv3ezUeXKR203hkCXkjfItSHi4NiTEgQPadDZTRkavaRpvAoaQV1a4srCS_Y-NU4RiOmkrVFJ_Xhw6UZvwjQUQ0QPOx9t - "domain": "matrix-stickers.sophies-kitchen.eu", - "config": { - "access_token": vault.decrypt( - "encrypt$gAAAAABg4btB0KGk068ahGZzR0w_Lm1bj1wUbB2WfNNs2bp3PwM4Ftp6MjQnrF-CejZfrF0NjPJw9Z4MrgileHP0sVw04mvgKSHfTf8gv4kTB6WuCIxHeMWHUDx00LTWL73fSlhCK0o1" - ), - "homeserver": "https://matrix.sophies-kitchen.eu", - "user_id": "@dimension:sophies-kitchen.eu", + 'matrix-stickerpicker': { + # use this bot token for telegram import: encrypt$gAAAAABg4bcQVzBF_iXdDtjRQD-O37GHdbHwWXyhCLPOuJLbv3ezUeXKR203hkCXkjfItSHi4NiTEgQPadDZTRkavaRpvAoaQV1a4srCS_Y-NU4RiOmkrVFJ_Xhw6UZvwjQUQ0QPOx9t + 'domain': "matrix-stickers.sophies-kitchen.eu", + 'config': { + 'access_token': vault.decrypt('encrypt$gAAAAABg4btB0KGk068ahGZzR0w_Lm1bj1wUbB2WfNNs2bp3PwM4Ftp6MjQnrF-CejZfrF0NjPJw9Z4MrgileHP0sVw04mvgKSHfTf8gv4kTB6WuCIxHeMWHUDx00LTWL73fSlhCK0o1'), + 'homeserver': "https://matrix.sophies-kitchen.eu", + 'user_id': "@dimension:sophies-kitchen.eu", }, }, - "matrix-synapse": { - "server_name": "sophies-kitchen.eu", - "baseurl": "matrix.sophies-kitchen.eu", - "admin_contact": "mailto:foobar@sophies-kitchen.eu", - "trusted_key_servers": { - "matrix.org", + 'matrix-synapse': { + 'server_name': 'sophies-kitchen.eu', + 'baseurl': 'matrix.sophies-kitchen.eu', + 'admin_contact': 'mailto:foobar@sophies-kitchen.eu', + 'trusted_key_servers': { + 'matrix.org', }, }, - "mautrix-telegram": { - "version": "v0.15.2", - "homeserver": { - "domain": "sophies-kitchen.eu", - "url": "https://matrix.sophies-kitchen.eu", + 'mautrix-telegram': { + 'version': 'v0.15.2', + 'homeserver': { + 'domain': 'sophies-kitchen.eu', + 'url': 'https://matrix.sophies-kitchen.eu', }, - "provisioning": { - "enabled": False, - "shared_secret": '""', + 'provisioning': { + 'enabled': False, + 'shared_secret': '""', }, - "permissions": { - "sophies-kitchen.eu": "full", - "'@sophie:sophies-kitchen.eu'": "admin", + 'permissions': { + 'sophies-kitchen.eu': 'full', + "'@sophie:sophies-kitchen.eu'": 'admin', }, - "telegram": { - "api_id": vault.decrypt( - "encrypt$gAAAAABgnqdXhCTwtCXJhSaCZsiNfHPtjwlYtV1sUAux7JZdejN3xItU9RJLeNu4gUniv36XbBoxKwVtqqyV3RcAs-PgumcfYQ==" - ), - "api_token": vault.decrypt( - "encrypt$gAAAAABgnqd5IdpYRmW-C4ONBSXQfiJrpTVQX0rP0eKoDnLnVTLg-5olSjcw2gVvEKWLnsGEZIgVcG7yEs-sqYRxeiQLFFpSn-Z4We0mhj0CUeFoD-eXJsp-bAgLv9PJoMv5Gjb8r9i6" - ), - "bot_token": '""', + 'telegram': { + 'api_id': vault.decrypt('encrypt$gAAAAABgnqdXhCTwtCXJhSaCZsiNfHPtjwlYtV1sUAux7JZdejN3xItU9RJLeNu4gUniv36XbBoxKwVtqqyV3RcAs-PgumcfYQ=='), + 'api_token': vault.decrypt('encrypt$gAAAAABgnqd5IdpYRmW-C4ONBSXQfiJrpTVQX0rP0eKoDnLnVTLg-5olSjcw2gVvEKWLnsGEZIgVcG7yEs-sqYRxeiQLFFpSn-Z4We0mhj0CUeFoD-eXJsp-bAgLv9PJoMv5Gjb8r9i6'), + 'bot_token': '""', }, }, - "nameservers": { - "213.133.98.98", - "213.133.99.99", - "213.133.100.100", - "2a01:4f8:0:1::add:1010", - "2a01:4f8:0:1::add:9999", - "2a01:4f8:0:1::add:9898", + 'nameservers': { + '213.133.98.98', + '213.133.99.99', + '213.133.100.100', + '2a01:4f8:0:1::add:1010', + '2a01:4f8:0:1::add:9999', + '2a01:4f8:0:1::add:9898', }, - "nftables": { - "input": { - "50-sophie-weechat": [ - "udp dport { 60000-61000 } accept", - "tcp dport 9001 accept", + 'nftables': { + 'input': { + '50-sophie-weechat': [ + 'udp dport { 60000-61000 } accept', + 'tcp dport 9001 accept', ], }, }, - "nginx": { - "vhosts": { - "sophies-kitchen.eu": { - "webroot": "/var/www/sophies-kitchen.eu/_site/", - "extras": True, + 'nginx': { + 'vhosts': { + 'sophies-kitchen.eu': { + 'webroot': '/var/www/sophies-kitchen.eu/_site/', + 'extras': True, }, - "matrix-synapse": { - "domain": "matrix.sophies-kitchen.eu", + 'matrix-synapse': { + 'domain': 'matrix.sophies-kitchen.eu', }, - "webdump.sophies-kitchen.eu": { - "webroot_config": { - "owner": "sophie", - "group": "sophie", - "mode": "0755", + 'webdump.sophies-kitchen.eu': { + 'webroot_config': { + 'owner': 'sophie', + 'group': 'sophie', + 'mode': '0755', }, - "extras": True, + 'extras': True, }, - "recipes.sophies-kitchen.eu": { - "webroot_config": { - "owner": "sophie", - "group": "sophie", - "mode": "0755", + 'recipes.sophies-kitchen.eu': { + 'webroot_config': { + 'owner': 'sophie', + 'group': 'sophie', + 'mode': '0755', }, }, }, }, - "nodejs": { - "version": 20, + 'nodejs': { + 'version': 20, }, - "ntfy": { - "domain": "ntfy.sophies-kitchen.eu", - "allow_unauthorized_write": True, + 'ntfy': { + 'domain': 'ntfy.sophies-kitchen.eu', + 'allow_unauthorized_write': True, }, - "postgresql": { - "version": "13", + 'postgresql': { + 'version': '11', }, - "sysctl": { - "options": { + 'sysctl': { + 'options': { # XXX find out if this is really needed - "net.ipv4.conf.all.forwarding": "1", - "net.ipv6.conf.all.forwarding": "1", + 'net.ipv4.conf.all.forwarding': '1', + 'net.ipv6.conf.all.forwarding': '1', }, }, - "vm": { - "cpu": 2, - "ram": 4, + 'vm': { + 'cpu': 2, + 'ram': 4, }, - "users": { - "sophie": { - "enable_linger": True, - "ssh_pubkey": [ + 'users': { + 'sophie': { + 'enable_linger': True, + 'ssh_pubkey': [ "ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQDILcYrMQNRVXAm5L+7No1ZumqfCyRc1QZmTY3O7Q8hsE4+fCAvwsWm2aSMfLL3NnIl8Nm1Rixzic5jdYKYNIY3SlX1wvTB+MhGb2eyVSd7c/Y98aCLSlDkQ2sebjpdA1FoJOeGD3qxqDwj0+KckXU2ZaSSQY7CxVsjH65UxCHqVAg+6uLdNbj7j850s1B9NXVXef+sBQ5jUngXxnqQWwNh2Mn8auwumkeEG4SYf96wyFkLvmBitOng/GyLWl9YPnXXHHDnatcVipy7y34qw4CQ4P84anecbA+Bqr9IcxBW6qYmYgRKEnAcmEfjQd+BI1gCLB1BBEmb/qp+mVLd4tOh sophie@carbon" ], }, }, - "zfs": { + 'zfs': { "datasets": { "tank/webdump": { "mountpoint": "/var/www/webdump.sophies-kitchen.eu", - "needed_by": ["directory:/var/www/webdump.sophies-kitchen.eu"], + "needed_by": [ + "directory:/var/www/webdump.sophies-kitchen.eu" + ] } }, - "pools": { - "tank": { - "when_creating": { - "config": [ - { - "devices": { - "/dev/disk/by-id/scsi-0HC_Volume_23952298", - }, - } - ] + 'pools': { + 'tank': { + 'when_creating': { + 'config': [{ + 'devices': { + '/dev/disk/by-id/scsi-0HC_Volume_23952298', + }, + }] }, }, }, diff --git a/nodes/sophie/unbound.py b/nodes/sophie/unbound.py deleted file mode 100644 index e0cb10d..0000000 --- a/nodes/sophie/unbound.py +++ /dev/null @@ -1,32 +0,0 @@ -nodes["sophie.unbound"] = { - "hostname": "172.19.164.4", - "bundles": { - "unbound", - }, - "groups": { - "debian-bookworm", - }, - "metadata": { - "interfaces": { - "enp1s0": { - "ips": { - "172.19.164.4/24", - "fe80::4/64", - }, - "gateway4": "172.19.164.1", - "ipv6_accept_ra": True, - }, - }, - "vm": { - "cpu": 2, - "ram": 2, - }, - "unbound": { - "dns64": False, - "restrict-to": { - "172.19.164.0/24", - "fe80::/64", - }, - }, - }, -} diff --git a/nodes/sophie/vmhost.py b/nodes/sophie/vmhost.py index aca520c..d6e56f3 100644 --- a/nodes/sophie/vmhost.py +++ b/nodes/sophie/vmhost.py @@ -3,7 +3,6 @@ nodes['sophie.vmhost'] = { 'bundles': { 'backup-client', 'lm-sensors', - 'nfs-server', 'mosquitto', 'smartd', 'vmhost', @@ -13,14 +12,6 @@ nodes['sophie.vmhost'] = { 'debian-bookworm', }, 'metadata': { - 'apt': { - 'packages': { - 'irqbalance': {}, - }, - }, - 'groups': { - 'nas': {}, - }, 'interfaces': { 'br1': { 'ips': { @@ -58,28 +49,11 @@ nodes['sophie.vmhost'] = { '172.19.164.0/24', }, }, - 'nfs-server': { - 'version': 4, - 'shares': { - '/srv/nas': { - '172.19.164.0/24': 'ro,all_squash,anonuid=65534,anongid=65534,no_subtree_check', - }, - }, - }, - 'smartd': { - 'disks': { - '/dev/nvme0', - - # nas disks - '/dev/disk/by-id/ata-ST20000NM007D-3DJ103_ZVT7BHBQ', - '/dev/disk/by-id/ata-ST20000NM007D-3DJ103_ZVT7D6JP', - }, - }, 'systemd-networkd': { 'bridges': { 'br0': { 'match': { - 'enp1s0', + 'eno1', }, }, 'br1': { @@ -89,26 +63,6 @@ nodes['sophie.vmhost'] = { }, }, }, - 'systemd-timers': { - 'timers': { - # Ensure every user is able to read and write to the NAS dataset. - 'nas_permissions': { - 'command': [ - 'chown -R :nas /srv/nas/', - r'find /srv/nas/ -type d -exec chmod 0775 {} \;', - r'find /srv/nas/ -type f -exec chmod 0664 {} \;', - ], - 'when': '*-*-* 02:00:00', - }, - }, - }, - 'users': { - 'sophie': { - 'groups': { - 'nas', - }, - }, - }, 'zfs': { 'pools': { 'storage': { @@ -119,26 +73,12 @@ nodes['sophie.vmhost'] = { }, }] } - }, - 'nas': { - 'when_creating': { - 'config': [{ - 'type': 'mirror', - 'devices': { - '/dev/disk/by-id/ata-ST20000NM007D-3DJ103_ZVT7BHBQ', - '/dev/disk/by-id/ata-ST20000NM007D-3DJ103_ZVT7D6JP', - }, - }] - } } }, "datasets": { "storage/libvirt": { "mountpoint": "/var/lib/libvirt", }, - "nas": { - "mountpoint": "/srv/nas", - }, }, }, }, diff --git a/nodes/voc/infobeamer-cms.py b/nodes/voc/infobeamer-cms.py index 55949e2..77c21c4 100644 --- a/nodes/voc/infobeamer-cms.py +++ b/nodes/voc/infobeamer-cms.py @@ -1,12 +1,12 @@ nodes['voc.infobeamer-cms'] = { - 'hostname': 'infobeamer.c3voc.de', + 'hostname': 'infobeamer-cms.c3voc.de', 'bundles': { 'infobeamer-cms', 'infobeamer-monitor', 'redis', }, 'groups': { - 'debian-bookworm', + 'debian-bullseye', 'webserver', }, 'metadata': { @@ -25,15 +25,27 @@ nodes['voc.infobeamer-cms'] = { }, 'infobeamer-cms': { 'domain': 'infobeamer.c3voc.de', - 'event_start_date': '2025-02-28', - 'event_duration_days': 3, + 'event_start_date': '2024-05-29', + 'event_duration_days': 5, 'config': { - 'ADMIN_USERS': [], - 'NO_LIMIT_USERS': [], + 'ADMIN_USERS': [ + 'hexchen', + 'jbeyerstedt', + 'jwacalex', + 'kunsi', + 'sophieschi', + ], + 'GITHUB_CLIENT_ID': vault.decrypt('encrypt$gAAAAABiNwHfIu9PYFfJrF7qirn_9vdvvUlEhJnadoNSS5XlCDbI_aMyj21_ZYQxaCkc6_eVX6Cj1jEHZ7Vs6wM-XyQdW0nUOahtqG4uvnYCiM3GFKHW_wQ='), + 'GITHUB_CLIENT_SECRET': vault.decrypt('encrypt$gAAAAABiNwHtdZC2XQ8IjosL7vsmrxZMwDIM6AD5dUlLo996tJs4qV7KJETHgYYZil2aMzClwhcE6JmxdhARRp7IJQ4rQQibelTNmyYSzj_V4puVpvma7SU0UZkTIG95SdPpoHY--Zba'), 'HOSTED_API_KEY': vault.decrypt('encrypt$gAAAAABhxJPH2sIGMAibU2Us1HoCVlNfF0SQQnVl0eiod48Zu8webL_-xk3wDw3yXw1Hkglj-2usl-D3Yd095yTSq0vZMCv2fh-JWwSPdJewQ45x9Ai4vXVD4CNz5vuJBESKS9xQWXTc'), - 'INTERRUPT_KEY': vault.human_password_for('infobeamer-cms interrupt key 38c3', words=1), + 'INTERRUPT_KEY': vault.human_password_for('infobeamer-cms interrupt key'), + 'MQTT_MESSAGE': '{{"level":"info","component":"infobeamer-cms","msg":"{asset} uploaded by {user}. Check it at {url}"}}', + 'MQTT_PASSWORD': vault.decrypt('encrypt$gAAAAABhxakfhhwWn0vxhoO1FiMEpdCkomWvo0dHIuBrqDKav8WDpI6dXpb0hoXiWRsPV6p5m-8RlbfFbjPhz47AY-nFOOAAW6Yis3-IVD-U-InKJo9dvms='), + 'MQTT_SERVER': 'mqtt.c3voc.de', + 'MQTT_TOPIC': '/voc/alert', + 'MQTT_USERNAME': vault.decrypt('encrypt$gAAAAABhxakKHC_kHmHP2mFHorb4niuNTH4F24w1D6m5JUxl117N7znlZA6fpMmY3_NcmBr2Ihw4hL3FjZr9Fm_1oUZ1ZQdADA=='), 'SETUP_IDS': [ - 258552, + 250294, ], # 'EXTRA_ASSETS': [{ # 'type': "image", @@ -44,48 +56,13 @@ nodes['voc.infobeamer-cms'] = { # 'x2': 110, # 'y2': 1070, # }], - 'NOTIFIER': { - 'MQTT_PASSWORD': vault.decrypt('encrypt$gAAAAABhxakfhhwWn0vxhoO1FiMEpdCkomWvo0dHIuBrqDKav8WDpI6dXpb0hoXiWRsPV6p5m-8RlbfFbjPhz47AY-nFOOAAW6Yis3-IVD-U-InKJo9dvms='), - 'MQTT_HOST': 'mqtt.c3voc.de', - 'MQTT_TOPIC': '/voc/alert', - 'MQTT_USERNAME': vault.decrypt('encrypt$gAAAAABhxakKHC_kHmHP2mFHorb4niuNTH4F24w1D6m5JUxl117N7znlZA6fpMmY3_NcmBr2Ihw4hL3FjZr9Fm_1oUZ1ZQdADA=='), - 'NTFY': [ - vault.decrypt('encrypt$gAAAAABm_RXKqIgRfe24frA_uvUMwJECr0TmL6TWPOmrPlS0CJuuBlpN6vGHrMkm5pjD5c5h1brC-aqQavsTk_AHXwq8bHG1QiZtQwqPxGuD_fEVP4-xOZ3t-RjqG3kPLz6ebqPoqyPl'), - ], - }, - 'FAQ': { - 'SOURCE': 'https://github.com/voc/infobeamer-cms', - 'CONTACT': ''' - Please use the IRC - Channel #infobeamer on irc.hackint.org (also - bridged to matrix) - or #info-beamer on the cccv rocketchat instance. - '''.strip(), - }, - 'DEFAULT_SSO_PROVIDER': 'github', - 'DEFAULT_ADMIN_SSO_PROVIDER': 'c3voc', - 'oauth2_providers': { - 'github': { - 'client_id': vault.decrypt('encrypt$gAAAAABiNwHfIu9PYFfJrF7qirn_9vdvvUlEhJnadoNSS5XlCDbI_aMyj21_ZYQxaCkc6_eVX6Cj1jEHZ7Vs6wM-XyQdW0nUOahtqG4uvnYCiM3GFKHW_wQ='), - 'client_secret': vault.decrypt('encrypt$gAAAAABiNwHtdZC2XQ8IjosL7vsmrxZMwDIM6AD5dUlLo996tJs4qV7KJETHgYYZil2aMzClwhcE6JmxdhARRp7IJQ4rQQibelTNmyYSzj_V4puVpvma7SU0UZkTIG95SdPpoHY--Zba'), - }, - 'c3voc': { - 'client_id': 'uqzN2mYeMq4vxnHL6HNmBC80hsvYcfhzniiczdqV', - 'client_secret': vault.decrypt('encrypt$gAAAAABnaZ0z-hQ3yYf8P1g4gyLLvNHcNkiXVtIq7M11qswbzcVM4upfgtxCWBlCgwLN3v7CxwDFQbJnosEq0hbX4c0TEoOausV4upJD0-5zP_1U18gbMGicpZ0TCzYyEhOqvCye7UmFOWzOmplSX1fz43Pf7peDeaPxHjqmxjw0khyExzWw4JPOd1V7LhnesJmPCfGKXn5YHMDicrdYeqFf0FySN1yA5gfLNo7y-S1QMJ6-n6Jct7uuifF9t2OV-zyOj3cKK13B'), - }, - #'c3hub': { - # 'client_id': '16oHBcVstcOKwt3EuX9E2urpYeVC0Dfo3Gzn2XhS', - # 'client_secret': vault.decrypt('encrypt$gAAAAABnaoRKbORUcceyKu3tda3lgMIFC-e0cG0AeMdDYJ--EnTRxp8QcULOTf2oBtKQUk17hgwfsafTFi4eZq1FrjNgq1h5gm83oJYWLQ6pp8Rsp9kjwgtAXf72jIU-AOQxx02SoFMU8r5pdEFEX4FkU_ksbU6s7xgBW8oxq_WO2CXAppTUX61TeB9me2nSLFdJc5-v6RDpQfDvVAm7yNS_PhMvMgVzfEZrFM-EWF_bl0S_q0ejf88o9zaXHIMJpzMruVZOXD0T'), - #}, - }, }, 'rooms': { - 'Saal 1': 34430, # s1 - 'Saal GLITCH': 37731, # s2 - 'Saal ZIGZAG': 26610, # s3 - 'Sendezentrum': 38641, # s4 - 'Stage YELL': 38642, # s5 - 'Stage HUFF': 35042, # s6 + 'Saal 1': 34430, + 'Saal G': 26598, + 'Saal Z': 26610, + 'Saal E (SoS/Lightning-Talks)': 32814, + 'Saal F (Sendezentrum/DLF)': 9717, }, 'interrupts': { 'Questions': 'questions', diff --git a/nodes/voc/pretalx.py b/nodes/voc/pretalx.py index f37a29c..845aa23 100644 --- a/nodes/voc/pretalx.py +++ b/nodes/voc/pretalx.py @@ -17,7 +17,7 @@ nodes['voc.pretalx'] = { }, 'metadata': { 'backup-client': { - 'target': 'backup-kunsi', + 'target': 'htz-hel.backup-kunsi', }, 'check-mail-received': { 't-online': { @@ -49,15 +49,14 @@ nodes['voc.pretalx'] = { }, }, 'pretalx': { - # 2023.3.1 with some bugfixes - 'version': '05e377398cecdd45d3ca6013040c5857bbe225d6', + 'version': 'v2024.2.1', 'domain': 'pretalx.c3voc.de', 'mail_from': 'pretalx@c3voc.de', 'administrators-from-group-id': 1, 'plugins': { 'broadcast_tools': { 'repo': 'https://github.com/Kunsi/pretalx-plugin-broadcast-tools.git', - 'rev': '2.4.0', + 'rev': 'main', }, 'downstream': { 'repo': 'https://github.com/pretalx/pretalx-downstream.git', @@ -65,7 +64,7 @@ nodes['voc.pretalx'] = { }, 'halfnarp': { 'repo': 'https://github.com/seibert-media/pretalx-halfnarp.git', - 'rev': '1.1.2', + 'rev': '1.1.0', }, 'media.ccc.de': { 'repo': 'https://github.com/pretalx/pretalx-media-ccc-de.git', @@ -82,6 +81,6 @@ nodes['voc.pretalx'] = { }, }, 'os': 'debian', - 'os_version': (12,), + 'os_version': (11,), 'pip_command': 'pip3', } diff --git a/requirements.txt b/requirements.txt index 6b2227f..7e81327 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,4 +1,4 @@ -bundlewrap>=4.22.0 +bundlewrap>=4.16.0 PyNaCl bundlewrap-pass semver diff --git a/scripts/passwords-for b/scripts/passwords-for index d019e74..136ba99 100755 --- a/scripts/passwords-for +++ b/scripts/passwords-for @@ -1,7 +1,5 @@ #!/usr/bin/env python3 - from os import environ -from os.path import abspath, dirname from sys import argv from bundlewrap.exceptions import FaultUnavailable @@ -9,13 +7,13 @@ from bundlewrap.metagen import NodeMetadataProxy from bundlewrap.repo import Repository from bundlewrap.utils import Fault -repo = Repository( - dirname(dirname(abspath(__file__))) -) +path = environ.get('BW_REPO_PATH', '.') +repo = Repository(path) def print_faults(dictionary, keypath=[]): for key, value in sorted(dictionary.items()): key = str(key) + if isinstance(value, Fault): try: resolved_fault = value.value @@ -29,22 +27,12 @@ def print_faults(dictionary, keypath=[]): elif isinstance(value, (dict, NodeMetadataProxy)): print_faults(value, keypath=keypath+[key]) - if len(argv) == 1: print('node name missing') exit(1) node = repo.get_node(argv[1]) -if node.username or node.password: - print_faults({ - 'username': node.username, - 'password': node.password, - }) -#if node.ipmi_username or node.ipmi_password: -# print_faults({ -# 'ipmi_username': node.ipmi_username, -# 'ipmi_password': node.ipmi_password, -# }) print_faults({ + 'password': node.password, 'metadata': node.metadata, }) diff --git a/scripts/update-ssh-client-config b/scripts/update-ssh-client-config index ba5acde..0c2f7fd 100755 --- a/scripts/update-ssh-client-config +++ b/scripts/update-ssh-client-config @@ -12,20 +12,10 @@ BW_TABLE_STYLE=grep bw nodes -a hostname -- "lambda:not node.dummy" | \ while read node addr do - if [[ -n "$BW_SSH_HOOK_EXTRA_LINE" ]] - then - echo "Host $addr" >>"$tmpfile" - echo "$BW_SSH_HOOK_EXTRA_LINE" >>"$tmpfile" - echo "" >>"$tmpfile" - fi echo "Host $node" >>"$tmpfile" echo "HostName $addr" >>"$tmpfile" - if [[ -n "$BW_SSH_HOOK_EXTRA_LINE" ]] - then - echo "$BW_SSH_HOOK_EXTRA_LINE" >>"$tmpfile" - fi echo "" >>"$tmpfile" done - mv "$tmpfile" ~/.ssh/config.d/bwnodes + mv "$tmpfile" ~/.ssh/bwnodes ) & diff --git a/users.json b/users.json index 0dab537..5d5b066 100644 --- a/users.json +++ b/users.json @@ -11,8 +11,7 @@ }, "kunsi": { "ssh_pubkey": [ - "ecdsa-sha2-nistp256 AAAAE2VjZHNhLXNoYTItbmlzdHAyNTYAAAAIbmlzdHAyNTYAAABBBLpRRSFhzPC8xNorYiNDG37JivSSER+oUNjSFwJ+4Gn8QdcM5sjQZsokAEFs5AsAWl1i7d/qceA2JGG4jCwDBx0=", - "ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAACAQC+ja1z5VRQzaKCCePsUM14qMr9QR94qlWc7Je5Poki9UmC1t/TyxRVzcCBL1ZdIfBGx6QKtfkEbvhgb3nxVt3PvXjoJrc6wwGLmNrVsU6B88y35g7nzupQiPKYJwkNzJ9j6Dmkgj1F5Q+aY2SitDaX6vqICLJ4Al/ZFw2IQxVJfC7JXRJ9jRMG5o9gWoE3gWDYEAmw+HU2mNzyeuaD12qJw9DHUimAlgkOWzll3gh9WclsYnnXGrCCn5fyHFUCJl+XXAIy519z7YTpKih02rsIOw5dnaGClBZD/YQu2ZKVFZiwIVH7aBiqHOmtgRyWTQgjbh/fMpIN0ar2f/iZsWYUjd6et48TOmXZYIPCQ5FivXNvxt9oo1XZfq76UHBwlmypLJIWROMbz375n2M6hr3hECuxuPjKEUXAv05KiC1aJ4xc6pFoVhqwAR99hvHw5U4o7/ko2NVjNpTu6Jr5DT5VaQLIdDDjC/93kUjMpdD/8P72bEn7454+WexU6OE6uvNiHj1fetrptr2UAuzVfnCoaV8pBqY7X95gk+lnSENdpr8ltJYMg8s0Z7Pzz0OxsZtzzDY5VmWfC9TCdJkN5lT8IbnaixsYlWdjQl1lMmZGElmelfU3K7YQLAbZiHmHKe4hTl9ZoCcWdTQ3d4y2t1DBos+N2HZNdtFCyOS8esDdMw==" + "ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAACAQC+ja1z5VRQzaKCCePsUM14qMr9QR94qlWc7Je5Poki9UmC1t/TyxRVzcCBL1ZdIfBGx6QKtfkEbvhgb3nxVt3PvXjoJrc6wwGLmNrVsU6B88y35g7nzupQiPKYJwkNzJ9j6Dmkgj1F5Q+aY2SitDaX6vqICLJ4Al/ZFw2IQxVJfC7JXRJ9jRMG5o9gWoE3gWDYEAmw+HU2mNzyeuaD12qJw9DHUimAlgkOWzll3gh9WclsYnnXGrCCn5fyHFUCJl+XXAIy519z7YTpKih02rsIOw5dnaGClBZD/YQu2ZKVFZiwIVH7aBiqHOmtgRyWTQgjbh/fMpIN0ar2f/iZsWYUjd6et48TOmXZYIPCQ5FivXNvxt9oo1XZfq76UHBwlmypLJIWROMbz375n2M6hr3hECuxuPjKEUXAv05KiC1aJ4xc6pFoVhqwAR99hvHw5U4o7/ko2NVjNpTu6Jr5DT5VaQLIdDDjC/93kUjMpdD/8P72bEn7454+WexU6OE6uvNiHj1fetrptr2UAuzVfnCoaV8pBqY7X95gk+lnSENdpr8ltJYMg8s0Z7Pzz0OxsZtzzDY5VmWfC9TCdJkN5lT8IbnaixsYlWdjQl1lMmZGElmelfU3K7YQLAbZiHmHKe4hTl9ZoCcWdTQ3d4y2t1DBos+N2HZNdtFCyOS8esDdMw== cardno:000609506971" ], "email": "encrypt$gAAAAABfuXj1DQ3yUn0rEdN2koT1hzgHwCwNp00a0KkWoT_FTsild1zIBpfIiI07AmgIZ5FpyhKH5bSdCVLKc0p4rQuxLrLWpw==", "phone": "encrypt$gAAAAABfuXkP2GetSvTd9JJFz4V2v5r5NubihFRg2AB91mtvXpUVUiflzy1VHQJ_qbp6Rke5LEXbtlluNkAa3OOAr_c9L6Pstw==", @@ -20,7 +19,7 @@ }, "sophie": { "ssh_pubkey": [ - "ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQDU7XmpX4w+rGQDi+dF6M0q65K2iHVgD1wHBoHREjyqCzmPGZgrnLIv6EN9WWJXjCgRdLEUXgPn7PNJnAgBs3U8G8MsF55yrPNUIsEeg6v+Y6zibEujMrwmeDSk0XAn8iSZcy+4cnqykIMk9Hd5WXW7ZhSHGs4MftWn3Z/q15qPHl/w9OyaKDJAjk8yEsD1sZoAQMhomKliKjJ5a6jNyf7otS3HdbZx4KXABJNuWn/IvmwkcaIU8ljyuPkPkiMn5JWhcUK2kE81Y4a5zJxxusSXSF6Ip7W2Rhv+4gnScTjhTPsG70HlSF/LAB2ytKo0F0N/ZB2hJk+Jq6cAwNBzuST7" + "ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQDU7XmpX4w+rGQDi+dF6M0q65K2iHVgD1wHBoHREjyqCzmPGZgrnLIv6EN9WWJXjCgRdLEUXgPn7PNJnAgBs3U8G8MsF55yrPNUIsEeg6v+Y6zibEujMrwmeDSk0XAn8iSZcy+4cnqykIMk9Hd5WXW7ZhSHGs4MftWn3Z/q15qPHl/w9OyaKDJAjk8yEsD1sZoAQMhomKliKjJ5a6jNyf7otS3HdbZx4KXABJNuWn/IvmwkcaIU8ljyuPkPkiMn5JWhcUK2kE81Y4a5zJxxusSXSF6Ip7W2Rhv+4gnScTjhTPsG70HlSF/LAB2ytKo0F0N/ZB2hJk+Jq6cAwNBzuST7 sophie@ejgwmobile" ] } }