Mercurial > code > home > repos > infra
changeset 289:65e28d2e0cd8
move static templates to files/ ; use inventory tags for selecting hosts+features ; other refactors
author | drewp@bigasterisk.com |
---|---|
date | Sun, 21 Apr 2024 17:07:23 -0700 |
parents | 3af02e24eaf9 |
children | 828d3f4da54b |
files | apt.py dns.py files/dnsmasq/dnsmasq-mtail.service files/dnsmasq/metrics.mtail files/dnsmasq/run_mtail.sh files/docker_daemon.json files/fstab/dash files/fstab/dot files/fstab/slash files/net/bang_10.2.network files/net/ditto-netplan.yaml files/net/house_net.service files/net/pipe_10.2.network files/net/pipe_isp.network files/net/prime.network files/net/singlenic.network files/pigpiod.service home.py inventory.py kube.py multikube.py net.py package_lists.py packages.py pipe.py ssh.py sync.py system.py templates/boot_config.txt.j2 templates/dnsmasq/dnsmasq-mtail.service.j2 templates/dnsmasq/metrics.mtail.j2 templates/dnsmasq/run_mtail.sh templates/hosts.j2 templates/net/bang_10.2.network.j2 templates/net/ditto-netplan.yaml.j2 templates/net/house_net.service.j2 templates/net/pipe_10.2.network.j2 templates/net/pipe_isp.network.j2 templates/net/prime.network.j2 templates/net/singlenic.network.j2 templates/pigpiod.service.j2 templates/sources.list.j2 templates/wireguard/wg0.conf.j2 users.py wireguard.py |
diffstat | 45 files changed, 342 insertions(+), 486 deletions(-) [+] |
line wrap: on
line diff
--- a/apt.py Sun Apr 21 17:01:13 2024 -0700 +++ b/apt.py Sun Apr 21 17:07:23 2024 -0700 @@ -9,8 +9,6 @@ TZ = 'America/Los_Angeles' -is_pi = host.get_fact(LinuxDistribution)['name'] in ['Debian', 'Raspbian GNU/Linux'] - def pkg_keys(): files.directory(path='/etc/apt/keyrings/') # for raspi @@ -39,7 +37,7 @@ ('https://nvidia.github.io/libnvidia-container/gpgkey', 'nvidia.gpg'), ] ]) - if is_pi or host.name == 'bang': + if 'pi' in host.groups or host.name == 'bang': # this contaminates the apt-update files.file(path="/etc/apt/trusted.gpg.d/podman.asc", present=False) @@ -98,7 +96,7 @@ files.put(src=io.StringIO("nameserver 10.2.0.3\n"), dest='/etc/resolv.conf') -if is_pi: +if 'pi' in host.groups: correct_dns() pkg_keys() apt_sources()
--- a/dns.py Sun Apr 21 17:01:13 2024 -0700 +++ b/dns.py Sun Apr 21 17:07:23 2024 -0700 @@ -5,9 +5,6 @@ import pyinfra from pyinfra import host from pyinfra.operations import files, systemd, server -from pyinfra.facts.server import Arch, LinuxDistribution - -is_pi = host.get_fact(LinuxDistribution)['name'] in ['Debian', 'Raspbian GNU/Linux'] def dnsmasq_instance(net_name, @@ -41,7 +38,7 @@ def standard_host_dns(): files.template(src='templates/hosts.j2', dest='/etc/hosts') - if is_pi: + if 'pi' in host.groups: files.put(dest='/etc/resolv.conf', src=StringIO(''' # written by pyinfra @@ -91,8 +88,8 @@ listen_address='unused') # only works after wireguard is up elif host.name == 'ditto': rpi_iscsi_volumes() # move out of this file- it's not dns -elif host.name == 'pipe': # move out of this file- it's not dns +if host.name == 'pipe': rpi_net_boot() files.directory(path='/opt/dnsmasq') dnsmasq_instance('10.2', @@ -102,10 +99,10 @@ dhcp_hosts_filename='templates/dnsmasq/dhcp_hosts.j2') out = '/opt/dnsmasq/10.2' # This mtail is for dhcp command counts and errors. Another monitor in lanscape/ reads the leases file. - files.template(src='templates/dnsmasq/metrics.mtail.j2', dest=f'{out}/metrics.mtail') - files.template(src='templates/dnsmasq/run_mtail.sh', dest=f'{out}/run_mtail.sh') + files.put(src='files/dnsmasq/metrics.mtail', dest=f'{out}/metrics.mtail') + files.put(src='files/dnsmasq/run_mtail.sh', dest=f'{out}/run_mtail.sh') - files.template(src='templates/dnsmasq/dnsmasq-mtail.service.j2', dest='/etc/systemd/system/dnsmasq-mtail.service') + files.put(src='files/dnsmasq/dnsmasq-mtail.service', dest='/etc/systemd/system/dnsmasq-mtail.service') systemd.service(service='dnsmasq-mtail', enabled=True, restarted=True, daemon_reload=True) # Serve another dns, no dhcp, and include the dynamic-blocking file written by net_routes.
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/files/dnsmasq/dnsmasq-mtail.service Sun Apr 21 17:07:23 2024 -0700 @@ -0,0 +1,13 @@ +# written by pyinfra + +[Unit] +Description=dnsmasq-mtail for 10.2 network +After=dnsmasq_10.2.service + +[Service] +Type=simple + +ExecStart=zsh /opt/dnsmasq/10.2/run_mtail.sh + +[Install] +WantedBy=multi-user.target
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/files/dnsmasq/metrics.mtail Sun Apr 21 17:07:23 2024 -0700 @@ -0,0 +1,37 @@ +counter dnsmasq_no_addr_errors +/no address available/ { + dnsmasq_no_addr_errors++ +} + +counter dnsmasq_dhcp_requests +/DHCPREQUEST/ { + dnsmasq_dhcp_requests++ +} + +counter dnsmasq_dhcp_acks +/DHCPACK/ { + dnsmasq_dhcp_acks++ +} + +counter dnsmasq_dhcp_discovers +/DHCPDISCOVER/ { + dnsmasq_dhcp_discovers++ +} + +counter dnsmasq_dhcp_offers +/DHCPOFFER/ { + dnsmasq_dhcp_offers++ +} + +gauge dnsmasq_dns_queries_answered_locally +gauge dnsmasq_dns_queries_forwarded by server +gauge dnsmasq_dns_queries_retried_or_failed by server + +/queries forwarded (?P<fwd>\d+), queries answered locally (?P<loc>\d+)/ { + dnsmasq_dns_queries_answered_locally = $loc +} + +/server (?P<svr>\S+)#53: queries sent (?P<sent>\d+), retried or failed (?P<fail>\d+)/ { + dnsmasq_dns_queries_forwarded[$svr] = $sent + dnsmasq_dns_queries_retried_or_failed[$svr] = $fail +} \ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/files/dnsmasq/run_mtail.sh Sun Apr 21 17:07:23 2024 -0700 @@ -0,0 +1,11 @@ +#!/bin/zsh +STATS_PERIOD=2m +while (true) { pkill --signal USR1 --oldest --full /usr/sbin/dnsmasq; sleep ${STATS_PERIOD} } & + +rm -f /tmp/dnsmasq_log_pipe +mkfifo /tmp/dnsmasq_log_pipe + +{ journalctl -fu dnsmasq_10.2.service > /tmp/dnsmasq_log_pipe } & + +mtail -port 9991 -logtostderr -logs /tmp/dnsmasq_log_pipe -progs /opt/dnsmasq/10.2 +#-disable_fsnotify -poll_interval ${STATS_PERIOD} \ No newline at end of file
--- a/files/docker_daemon.json Sun Apr 21 17:01:13 2024 -0700 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,1 +0,0 @@ -{ "experimental":true, "insecure-registries":["bang5:5000", "reg:5000"] }
--- a/files/fstab/dash Sun Apr 21 17:01:13 2024 -0700 +++ b/files/fstab/dash Sun Apr 21 17:07:23 2024 -0700 @@ -4,19 +4,8 @@ /dev/disk/by-uuid/d8d23ff1-7c37-4a7d-9fc4-55fc61f912a0 / ext4 defaults 0 1 /dev/disk/by-uuid/CB55-821E /boot/efi vfat defaults 0 1 - -#UUID=b88f75cd-9022-4af9-a11b-5a5a1fbd3132 /d2 ext4 defaults 0 0 -#UUID=3b6780e0-ec86-43be-8d09-e462dbad762e /d3 ext4 defaults 0 0 -#UUID=73bcd201-5f77-4f68-9fba-47835c3c1692 /d4 ext4 defaults 0 0 - - - UUID=73bcd201-5f77-4f68-9fba-47835c3c1692 /d2 ext4 defaults 0 0 UUID=6cae1c30-3c91-4aa7-9e9f-fcbd7ff706fe /d3 ext4 defaults 0 0 UUID=3b6780e0-ec86-43be-8d09-e462dbad762e /d4 ext4 defaults 0 0 - - -#/swap.img none swap sw 0 0 - -ditto5:/my /my nfs rw,noatime 0 0 +ditto5:/my /my nfs rw,noatime 0 0
--- a/files/fstab/dot Sun Apr 21 17:01:13 2024 -0700 +++ b/files/fstab/dot Sun Apr 21 17:07:23 2024 -0700 @@ -8,5 +8,3 @@ /dev/mapper/ubuntu--vg-ubuntu--lv /d2 ext4 defaults 0 1 /dev/disk/by-uuid/5a6ce8db-cde0-4c26-b6a4-08faef2e01a2 /d3 ext4 defaults 0 1 - -#/dev/disk/by-uuid/a3891b94-5ddd-428d-ab6f-8e39f3d8fbde /d3 ext4 defaults 0 1 \ No newline at end of file
--- a/files/fstab/slash Sun Apr 21 17:01:13 2024 -0700 +++ b/files/fstab/slash Sun Apr 21 17:07:23 2024 -0700 @@ -4,4 +4,4 @@ UUID=df079890-9431-4e17-940c-d9ed8ce4e149 / ext4 errors=remount-ro 0 1 UUID=1CFA-995B /boot/efi vfat umask=0077 0 1 -ditto5:/my /my nfs rw,noatime 0 0 +ditto5:/my /my nfs rw,noatime 0 0
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/files/net/bang_10.2.network Sun Apr 21 17:07:23 2024 -0700 @@ -0,0 +1,10 @@ +# written by pyinfra + +[Match] +MACAddress=60:e3:27:04:4a:85 + +[Network] +DHCP=no +Address=10.2.0.1/16 +DNS=10.2.0.3 +Gateway=10.2.0.3
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/files/net/ditto-netplan.yaml Sun Apr 21 17:07:23 2024 -0700 @@ -0,0 +1,22 @@ +# written by pyinfra +network: + ethernets: + eno1: + addresses: + # name=ditto + - 10.2.0.133/16 + # name=mqtt1 etc + - 10.2.0.11/16 + - 10.2.0.12/16 + - 10.2.0.13/16 + - 10.2.0.14/16 + routes: + - to: default + via: 10.2.0.3 + nameservers: + addresses: [10.2.0.3] + enp5s0: + dhcp4: true + ens3: + dhcp4: true + version: 2
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/files/net/house_net.service Sun Apr 21 17:07:23 2024 -0700 @@ -0,0 +1,14 @@ +# written by pyinfra + +[Unit] +After=network-online.target nss-lookup.target +Wants=network-online.target nss-lookup.target + +[Service] +Type=oneshot +ExecStart=sh -c "sysctl net.ipv4.ip_forward=1 && /usr/sbin/iptables -A POSTROUTING --table nat --out-interface eth0 --jump MASQUERADE" +RemainAfterExit=yes + + +[Install] +WantedBy=multi-user.target
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/files/net/pipe_10.2.network Sun Apr 21 17:07:23 2024 -0700 @@ -0,0 +1,14 @@ +# written by pyinfra + +[Match] +# usb dongle +MACAddress=00:05:1b:33:3e:81 + +[Network] +DHCP=no +Address=10.2.0.3/16 +# vip for the filtered dns server we give clients who are to have sometimes-filtered domains +Address=10.2.0.4/16 +DNS=10.2.0.3 +Domains=bigasterisk.com +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/files/net/pipe_isp.network Sun Apr 21 17:07:23 2024 -0700 @@ -0,0 +1,12 @@ +# written by pyinfra + +[Match] +# onboard eth +MACAddress=00:1e:06:43:20:d0 + +[Network] +DHCP=no +Address=192.168.42.3/24 +Gateway=192.168.42.1 +DNS=10.2.0.1 +Domains=bigasterisk.com \ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/files/net/prime.network Sun Apr 21 17:07:23 2024 -0700 @@ -0,0 +1,14 @@ +# written by pyinfra + +# see systemd.network(5) + +[Match] +MACAddress=04:01:09:7f:89:01 + +[Network] +Address=162.243.138.136/24 +Gateway=162.243.138.1 +DNS=10.5.0.1%wg0 +DNS=8.8.8.8 +DNS=8.8.4.4 +Domains=bigasterisk.com \ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/files/net/singlenic.network Sun Apr 21 17:07:23 2024 -0700 @@ -0,0 +1,10 @@ +# written by pyinfra + +[Match] +Name=* + +[Network] +DHCP=yes +# this sauce may or may not help with k3s +LinkLocalAddressing=yes +IPForward=yes \ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/files/pigpiod.service Sun Apr 21 17:07:23 2024 -0700 @@ -0,0 +1,11 @@ +# written by pyinfra + +[Unit] +Description=Daemon required to control GPIO pins via pigpio + +[Service] +Type=simple +ExecStart=/usr/bin/pigpiod -g -p 8888 + +[Install] +WantedBy=multi-user.target
--- a/home.py Sun Apr 21 17:01:13 2024 -0700 +++ b/home.py Sun Apr 21 17:07:23 2024 -0700 @@ -1,12 +1,7 @@ from pyinfra import host from pyinfra.operations import files, server -if host.name in [ - 'dash', - 'slash', - 'bang', - 'ditto', - ]: +if host.data.get('drewp_home'): # maybe bring sync.py in here too server.shell(commands=['chsh -s /bin/zsh drewp'])
--- a/inventory.py Sun Apr 21 17:01:13 2024 -0700 +++ b/inventory.py Sun Apr 21 17:07:23 2024 -0700 @@ -1,25 +1,28 @@ big = [ - ('bang', { 'wireguard_address': '10.5.0.1', }), - ('dash', { 'wireguard_address': '10.5.0.5', 'ssh_hostname': 'dash', }), - ('slash', { 'wireguard_address': '10.5.0.6', 'ssh_hostname': 'slash', }), - ('dot', { 'wireguard_address': '10.5.0.30', 'ssh_hostname': 'dot', }), - ('ditto', { 'wireguard_address': '10.5.0.7', }), - # ('squib', { }), + ('bang' , { 'drewp_gid': 1000, 'drewp_uid': 501, 'k8s_admin': True , 'syncthing': True, 'wireguard_address': '10.5.0.1' , }), + ('dash' , { 'drewp_gid': 1000, 'drewp_home': True, 'drewp_uid': 501, 'gpu': True , 'k8s_admin': True , 'ssh_hostname': 'dash', 'syncthing': True, 'wireguard_address': '10.5.0.5', }), + ('slash' , { 'drewp_gid': 1000, 'drewp_home': True, 'drewp_uid': 501, 'k8s_admin': True , 'ssh_hostname': 'slash', 'syncthing': True, 'wireguard_address': '10.5.0.6' , }), + ('dot' , { 'drewp_gid': 1000, 'drewp_uid': 501, 'ssh_hostname': 'dot' , 'syncthing': True, 'wireguard_address': '10.5.0.30', }), + ('ditto' , { 'coral': True, 'drewp_gid': 1000, 'drewp_home': True, 'drewp_uid': 501, 'gpu': True , 'k8s_admin': True, 'syncthing': True, 'wireguard_address': '10.5.0.7', }), + ('squib' , { 'drewp_gid': 1000, 'drewp_uid': 501, }), ] small = [ - ('pipe', { 'wireguard_address': '10.5.0.3', 'ssh_hostname': '10.2.0.3', }), + ('pipe' , { 'drewp_gid': 501 , 'drewp_uid': 1001, 'ssh_hostname': '10.2.0.3' , 'wireguard_address': '10.5.0.3' , }), ] pi = [ - # ('garage', { 'wireguard_address': '10.5.0.14', 'ssh_hostname': 'garage', }), - ('ws-printer', { 'wireguard_address': '10.5.0.31', 'ssh_hostname': 'ws-printer', }), - ('gn-music', { 'wireguard_address': '10.5.0.32', 'ssh_hostname': 'gn-music', }), - ('li-drums', { 'wireguard_address': '10.5.0.33', 'ssh_hostname': 'li-drums', }), + ('garage' , { 'drewp_gid': 501 , 'drewp_uid': 1000, 'ssh_hostname': 'garage' , 'wireguard_address': '10.5.0.14' , }), + ('ws-printer', { 'drewp_gid': 501 , 'drewp_uid': 1000, 'ssh_hostname': 'ws-printer5', 'wireguard_address': '10.5.0.31' , }), + ('li-drums' , { 'drewp_gid': 501 , 'drewp_uid': 1000, 'ssh_hostname': 'li-drums5' , 'wireguard_address': '10.5.0.33' , }), + ('gn-music' , { 'drewp_gid': 501 , 'drewp_uid': 1000, 'ssh_hostname': 'gn-music' , 'wireguard_address': '10.5.0.32' , }), ] -remote = [ - ('prime', { 'wireguard_address': '10.5.0.2', 'ssh_hostname': '162.243.138.136','mac': '04:01:09:7f:89:01',}), - ('plus', { 'wireguard_address': '10.5.0.110','ssh_hostname': '10.2.0.35', }), - ('pillow', { 'wireguard_address': '10.5.0.111','ssh_hostname':'10.5.0.111',}), +hosted = [ + ('prime' , { 'drewp_gid': 1000, 'drewp_uid': 501, 'ssh_hostname': '162.243.138.136', 'wireguard_address': '10.5.0.2' , }), ] + +laptop = [ + ('plus' , { 'drewp_gid': 1000, 'drewp_home': True, 'drewp_uid': 501, 'ssh_hostname': '10.2.0.35' , 'syncthing': True, 'wg_roamer': True, 'wireguard_address': '10.5.0.110', }), + ('pillow' , { 'drewp_gid': 1000, 'drewp_uid': 1000 , 'ssh_hostname': '10.5.0.111' , 'syncthing': True, 'wg_roamer': True, 'wireguard_address': '10.5.0.111', }), +]
--- a/kube.py Sun Apr 21 17:01:13 2024 -0700 +++ b/kube.py Sun Apr 21 17:07:23 2024 -0700 @@ -5,8 +5,6 @@ from pyinfra.facts.server import Arch, LinuxDistribution from pyinfra.operations import files, server, systemd -is_pi = host.get_fact(LinuxDistribution)['name'] in ['Debian', 'Raspbian GNU/Linux'] - # https://github.com/GoogleContainerTools/skaffold/releases skaffold_version = 'v2.10.1' @@ -34,21 +32,7 @@ mode='755', cache_time=1000) # one time; writes to $HOME - server.shell("skaffold config set --global insecure-registries reg:5000") - - -def pi_cgroup_setup(): - ''' - fixes this: - - Mar 29 23:47:11 ws-printer k3s[5999]: time="2024-03-29T23:47:11-07:00" level=fatal msg="failed to find memory cgroup (v2)" - ''' - return 'cmdline.txt lives on pipe now, not on the pi host' - old_cmdline = host.get_fact(FindInFile, path='/boot/cmdline.txt', pattern=r'.*')[0] - if 'cgroup' not in old_cmdline: - cmdline = old_cmdline + ' cgroup_enable=cpuset cgroup_memory=1 cgroup_enable=memory' - files.line(path='/boot/cmdline.txt', line='.*', replace=cmdline) - # pi needs reboot now + server.shell(commands="skaffold config set --global insecure-registries reg:5000") def host_prep(): @@ -61,9 +45,6 @@ none, strict, loose = 0, 1, 2 server.sysctl(key='net.ipv4.conf.default.rp_filter', value=loose, persist=True) - if is_pi: - pi_cgroup_setup() - # don't try to get aufs-dkms on rpi-- https://github.com/docker/for-linux/issues/709 def podman_insecure_registry(reg): @@ -100,7 +81,7 @@ dest=f'/etc/systemd/system/{service_name}', role=role, ) - if host.name in ['bang', 'garage']: + if not host.data.get('gpu'): # no supported gpu ''' kubectl label --overwrite node bang nvidia.com/gpu.deploy.gpu-feature-discovery=false @@ -135,7 +116,6 @@ server_ip, server_node, nodes, - admin_from, # https://github.com/k3s-io/k3s/releases # 1.23.6 per https://github.com/cilium/cilium/issues/20331 k3s_version, @@ -151,7 +131,7 @@ # also note that podman dropped the default `docker.io/` prefix on image names (see https://unix.stackexchange.com/a/701785/419418) config_and_run_service(k3s_version, server_node, server_ip) - if host.name in admin_from: + if host.data.get('k8s_admin'): podman_insecure_registry(reg='reg:5000') files.directory(path='/etc/rancher/k3s') install_skaffold()
--- a/multikube.py Sun Apr 21 17:01:13 2024 -0700 +++ b/multikube.py Sun Apr 21 17:07:23 2024 -0700 @@ -47,14 +47,6 @@ #skaffold config set --global insecure-registries bang5:5000 -def pi_cgroup_setup(): - old_cmdline = host.get_fact(FindInFile, path='/boot/cmdline.txt', pattern=r'.*')[0] - if 'cgroup' not in old_cmdline: - cmdline = old_cmdline + ' cgroup_enable=cpuset cgroup_memory=1 cgroup_enable=memory' - files.line(path='/boot/cmdline.txt', line='.*', replace=cmdline) - # pi needs reboot now - - def host_prep(): server.sysctl(key='net.ipv4.ip_forward', value="1", persist=True) server.sysctl(key='net.ipv6.conf.all.forwarding', value="1", persist=True) @@ -66,12 +58,11 @@ #none, strict, loose = 0, 1, 2 #server.sysctl(key='net.ipv4.conf.default.rp_filter', value=loose, persist=True) - if is_pi: - pi_cgroup_setup() def service_name(): return 'k3s.service' if host.name == server_node else 'k3s-node.service' + def config_and_run_service(): role = 'server' if host.name == server_node else 'agent' which_conf = 'config-server.yaml.j2' if host.name == server_node else 'config-agent.yaml.j2'
--- a/net.py Sun Apr 21 17:01:13 2024 -0700 +++ b/net.py Sun Apr 21 17:07:23 2024 -0700 @@ -1,9 +1,5 @@ from pyinfra import host from pyinfra.operations import apt, files, server, systemd -from pyinfra.facts.server import Arch, LinuxDistribution - -is_pi = host.get_fact(LinuxDistribution)['name'] in ['Debian', 'Raspbian GNU/Linux'] -is_wifi = False def cleanup(): @@ -23,7 +19,7 @@ delete=True, ) - # On bang (now pipe): + # On pipe: # Now using a HW router for this firewall. No incoming connections. # test connections from the outside: # http://www.t1shopper.com/tools/port-scanner/ @@ -33,74 +29,50 @@ apt.packages(packages=['ufw'], present=False) -# https://github.com/k3s-io/k3s/issues/1812 unclear, but more importantly, this has to be set -# on pipe in a way that works with the commands in house_net.service (and net_routes) -server.shell(commands=[ - 'update-alternatives --set iptables /usr/sbin/iptables-legacy', - 'update-alternatives --set ip6tables /usr/sbin/ip6tables-legacy', -]) -# needs reboot if this changed +def iptables_version(): + # https://github.com/k3s-io/k3s/issues/1812 unclear, but more importantly, this has to be set + # on pipe in a way that works with the commands in house_net.service (and net_routes) + server.shell(commands=[ + 'update-alternatives --set iptables /usr/sbin/iptables-legacy', + 'update-alternatives --set ip6tables /usr/sbin/ip6tables-legacy', + ]) + # needs reboot if this changed -if host.name in ['prime', 'bang', 'pipe', 'ditto']: - server.sysctl(key='net.ipv6.conf.all.disable_ipv6', value=1, persist=True) - - # if is_wifi_pi: - # files.put(dest="/etc/network/interfaces.d/wlan0", src="files/pi_wlan0_powersave") - # ssh.command(host.name, "iw wlan0 set power_save off") - files.directory('/etc/systemd/network') - if host.name == 'prime': - cleanup() +iptables_version() +server.sysctl(key='net.ipv6.conf.all.disable_ipv6', value=1, persist=True) + +if host.name == 'prime': + cleanup() - files.template( - src="templates/net/prime.network.j2", - dest="/etc/systemd/network/99-prime.network", - mac=host.host_data['mac'], - ) - - elif host.name == 'bang': - cleanup() - - files.template(src="templates/net/bang_10.2.network.j2", dest="/etc/systemd/network/20-10.2.network") - apt.packages(packages=['network-manager'], present=False) + files.template( + src="files/net/prime.network", + dest="/etc/systemd/network/99-prime.network", + ) + systemd.service(service='systemd-networkd.service', enabled=True, running=True, restarted=True) - elif host.name == 'plus': - apt.packages(packages=['network-manager'], present=True) - - elif host.name == 'pipe': - cleanup() +if host.name == 'bang': + cleanup() - files.template(src="templates/net/pipe_10.2.network.j2", dest="/etc/systemd/network/99-10.2.network") - files.template(src="templates/net/pipe_isp.network.j2", dest="/etc/systemd/network/99-isp.network") - server.sysctl(key='net.ipv4.ip_forward', value=1, persist=True) - files.template(src="templates/net/house_net.service.j2", - dest="/etc/systemd/system/house_net.service", - out_interface='eth0') - systemd.service(service='house_net.service', daemon_reload=True, enabled=True, running=True, restarted=True) + files.template(src="files/net/bang_10.2.network", dest="/etc/systemd/network/20-10.2.network") + apt.packages(packages=['network-manager'], present=False) + systemd.service(service='systemd-networkd.service', enabled=True, running=True, restarted=True) + +if host.name == 'pipe': + cleanup() - elif host.name == 'ditto': - files.template( - src="templates/net/ditto-netplan.yaml.j2", - dest="/etc/netplan/00-installer-config.yaml", - create_remote_dir=True, - ) - - else: - cleanup() + files.template(src="files/net/pipe_10.2.network", dest="/etc/systemd/network/99-10.2.network") + files.template(src="files/net/pipe_isp.network", dest="/etc/systemd/network/99-isp.network") + server.sysctl(key='net.ipv4.ip_forward', value=1, persist=True) + files.template(src="files/net/house_net.service", dest="/etc/systemd/system/house_net.service", out_interface='eth0') + systemd.service(service='house_net.service', daemon_reload=True, enabled=True, running=True, restarted=True) + systemd.service(service='systemd-networkd.service', enabled=True, running=True, restarted=True) - if is_wifi: - files.put(src="secrets/wpa_supplicant.conf", dest="/etc/wpa_supplicant/wpa_supplicant.conf") - - files.template( - src="templates/net/singlenic.network.j2", - dest="/etc/systemd/network/20-bigasterisk.network", - create_remote_dir=True, - ) - apt.packages(packages=['network-manager'], present=False) +if host.name == 'ditto': + files.template( + src="files/net/ditto-netplan.yaml", + dest="/etc/netplan/00-installer-config.yaml", + create_remote_dir=True, + ) systemd.service(service='systemd-networkd.service', enabled=True, running=True, restarted=True) - - # delete? - # # TODO this breaks wireguard wg on garage, i think. workaround: - # if host.name == 'garage': - # server.shell('ip -4 address add 10.5.0.14/24 dev wg0')
--- a/package_lists.py Sun Apr 21 17:01:13 2024 -0700 +++ b/package_lists.py Sun Apr 21 17:07:23 2024 -0700 @@ -91,7 +91,7 @@ 'wakeonlan', ] -for_bang_ditto = [ +for_ditto = [ 'dnsmasq', 'nfs-common', 'openntpd',
--- a/packages.py Sun Apr 21 17:01:13 2024 -0700 +++ b/packages.py Sun Apr 21 17:07:23 2024 -0700 @@ -1,12 +1,10 @@ from io import StringIO + from pyinfra import host -from pyinfra.facts.server import LinuxDistribution from pyinfra.operations import apt, files, server, systemd import package_lists -is_pi = host.get_fact(LinuxDistribution)['name'] in ['Debian', 'Raspbian GNU/Linux'] - def kitty(): vers = '0.31.0' # see https://github.com/kovidgoyal/kitty/releases @@ -52,12 +50,12 @@ def proper_locate(): apt.packages(packages='mlocate', present=False) - if not is_pi and host.name not in ['prime', 'pipe']: + if 'pi' not in host.groups and host.name not in ['prime', 'pipe']: apt.packages(packages='plocate') def proper_man(): - if host.name in ['pipe', 'prime'] or is_pi: + if 'small' in host.groups or 'pi' in host.groups: apt.packages(packages=['mandb'], present=False) @@ -65,14 +63,12 @@ systemd.service(service='nginx', enabled=False, running=False) -kw = dict(present=True, latest=True) - -apt.packages(packages=package_lists.setup, **kw) +apt.packages(packages=package_lists.setup, latest=True) def roblox(): - server.shell('flatpak install -y org.freedesktop.Platform/x86_64/23.08') - server.shell('flatpak install -y flathub org.vinegarhq.Vinegar') # (roblox runner) + server.shell(commands='flatpak install -y org.freedesktop.Platform/x86_64/23.08') + server.shell(commands='flatpak install -y flathub org.vinegarhq.Vinegar') # (roblox runner) files.put( src=StringIO( #"#!/bin/sh\nexec flatpak run org.vinegarhq.Vinegar player run 'roblox-player:1'\n" @@ -97,35 +93,28 @@ ]) -if not is_pi: - if host.name != 'pipe': - apt.packages(packages=['reptyr']) - kitty() -else: - apt.packages(packages=package_lists.pi_setup) - proper_locate() proper_man() -apt.packages(packages=package_lists.general, **kw) -apt.packages(packages=package_lists.debug, **kw) - -if host.name in ["bang", 'ditto']: - apt.packages(packages=package_lists.for_bang_ditto, **kw) +apt.packages(packages=package_lists.general, latest=True) +apt.packages(packages=package_lists.debug, latest=True) if host.name == "pipe": - apt.packages(packages=package_lists.for_pipe, **kw) + apt.packages(packages=package_lists.for_pipe, latest=True) + +if host.name != 'pipe': + apt.packages(packages=['reptyr']) if host.name == "prime": - apt.packages(packages=package_lists.for_prime, **kw) + apt.packages(packages=package_lists.for_prime, latest=True) if host.name == 'plus': - apt.packages(packages=package_lists.laptop, **kw) + apt.packages(packages=package_lists.laptop, latest=True) -if host.name in ['dash', 'slash', 'ditto', 'dot']: - apt.packages(packages=package_lists.k8s_node_with_nvidia_gpu(host.name)) # no kw, or apt will remove nvidia-utils-VERS (!) +if host.data.get('gpu'): + apt.packages(packages=package_lists.k8s_node_with_nvidia_gpu(host.name)) -if host.name in ['dash', 'slash', 'ditto']: +if host.data.get('k8s_admin'): podman() is_kube_node = host.name in ['dash', 'slash', 'ditto', 'ws-printer', 'li-drums'] @@ -133,19 +122,20 @@ kube_node() if host.name == 'ditto': + apt.packages(packages=package_lists.for_ditto, latest=True) # should have happened in the previous step, but it gets reverted. apt.packages(packages=['nvidia-utils-535-server']) -if not is_pi: - apt.packages(packages=package_lists.non_pi, **kw) -else: - # move to another file? - files.template(src="templates/pigpiod.service.j2", dest="/etc/systemd/system/pigpiod.service") - systemd.service(service='pigpiod', daemon_reload=True, enabled=True) +if 'pi' not in host.groups: + kitty() + apt.packages(packages=package_lists.non_pi, latest=True) + +if 'pi' in host.groups: + apt.packages(packages=package_lists.pi_setup) desktop_env = host.name in ['dash', 'slash', 'plus', 'dot', 'squib', 'pillow'] if desktop_env: - apt.packages(packages=package_lists.xorg + package_lists.desktop, **kw) + apt.packages(packages=package_lists.xorg + package_lists.desktop, latest=True) roblox() if desktop_env or host.name in ['bang', 'ditto']: pdm()
--- a/pipe.py Sun Apr 21 17:01:13 2024 -0700 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,2 +0,0 @@ -from pyinfra.operations import apt, files, git, server, systemd -
--- a/ssh.py Sun Apr 21 17:01:13 2024 -0700 +++ b/ssh.py Sun Apr 21 17:07:23 2024 -0700 @@ -2,7 +2,6 @@ from pyinfra.facts.server import LinuxDistribution from pyinfra.operations import files, systemd -is_pi = host.get_fact(LinuxDistribution)['name'] in ['Debian', 'Raspbian GNU/Linux'] systemd.service( service='ssh', @@ -12,7 +11,7 @@ files.line(path='/etc/ssh/ssh_config', line="HashKnownHosts", replace="HashKnownHosts no") -if not is_pi: +if 'pi' not in host.groups: files.line(path='/etc/ssh/sshd_config', line="^UseDNS\b", replace="UseDNS no") # MAYBE plus needs this fix: adding ListenAddress 0.0.0.0 to /etc/ssh/sshd_config systemd.service(service='sshd', reloaded=True)
--- a/sync.py Sun Apr 21 17:01:13 2024 -0700 +++ b/sync.py Sun Apr 21 17:07:23 2024 -0700 @@ -41,7 +41,7 @@ # primary instance is in k8s (/my/serv/filesync/syncthing); the rest are run with systemd. # Configs are in ~/.config/syncthing/ on each box -if host.name in ['dash', 'dot', 'slash', 'plus', 'bang', 'ditto', 'pillow']: +if host.data.get('syncthing'): apt.packages(packages=['syncthing'], present=False) user = 'ari' if host.name == 'dot' else 'drewp'
--- a/system.py Sun Apr 21 17:01:13 2024 -0700 +++ b/system.py Sun Apr 21 17:07:23 2024 -0700 @@ -1,10 +1,11 @@ import os +from io import StringIO +from typing import cast +import pyinfra from pyinfra import host -from pyinfra.facts.server import LinuxDistribution from pyinfra.operations import apt, files, server, systemd -is_pi = host.get_fact(LinuxDistribution)['name'] in ['Debian', 'Raspbian GNU/Linux'] TZ = 'America/Los_Angeles' @@ -18,6 +19,7 @@ if os.path.exists(fstab_file): files.put(src=fstab_file, dest='/etc/fstab') + def pi_tmpfs(): for line in [ 'tmpfs /var/log tmpfs defaults,noatime,mode=0755 0 0', @@ -57,6 +59,7 @@ fam='tcp') systemd.service(service=svc, enabled=True, restarted=True) + def minecraft_forward(): port = 25765 for fam in ['tcp', 'udp']: @@ -69,14 +72,41 @@ fam=fam) systemd.service(service=svc, enabled=True, restarted=True) + +def pigpiod(): + files.put(src="files/pigpiod.service", dest="/etc/systemd/system/pigpiod.service") + systemd.service(service='pigpiod', daemon_reload=True, enabled=True) + + +def rpi_iscsi_volumes(): + iscsi_dir = '/d2/rpi-iscsi' + for pi_hostname in cast(list, pyinfra.inventory.get_group(name='pi')): + out = f'{iscsi_dir}/{pi_hostname}.disk' + files.directory(path=iscsi_dir) + server.shell(commands=f'dd if=/dev/zero of={out} count=0 bs=1 seek=10G conv=excl || true') + files.put(dest=f"/etc/tgt/conf.d/{pi_hostname}.conf", + src=StringIO(f""" +<target iqn.2024-03.com.bigasterisk:{pi_hostname}.target> + backing-store {out} + initiator-name iqn.2024-03.com.bigasterisk:{pi_hostname}.initiator +</target> + """)) + # restarting is disruptive to connected pis, and they might need to be + # visited: + #systemd.service(service='tgt.service', running=True, restarted=True) + + server.hostname(hostname=host.name) timezone() fstab() -if not is_pi: +if host.name == 'ditto': + rpi_iscsi_volumes() + +if 'pi' not in host.groups: files.line(path='/etc/update-manager/release-upgrades', line="^Prompt=", replace="Prompt=normal") -if is_pi and host.name != 'pipe': +if 'pi' in host.groups: pi_tmpfs() if host.name in ['bang', 'pipe', 'ditto']: @@ -85,11 +115,16 @@ if host.name in ['bang', 'ditto']: nfs_server() +if host.name in ['prime', 'ditto']: + smaller_journals() + if host.name == 'prime': - smaller_journals() web_forward() minecraft_forward() +if 'pi' in host.groups: + pigpiod() + # for space, consider: # k3s crictl rmi --prune # snap list --all | while read snapname ver rev trk pub notes; do if [[ $notes = *disabled* ]]; then snap remove "$snapname" --revision="$rev"; fi; done
--- a/templates/boot_config.txt.j2 Sun Apr 21 17:01:13 2024 -0700 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,80 +0,0 @@ -# written by pyinfra - -# For more options and information see -# http://rpf.io/configtxt -# Some settings may impact device functionality. See link above for details - -# uncomment if you get no picture on HDMI for a default "safe" mode -#hdmi_safe=1 - -# uncomment this if your display has a black border of unused pixels visible -# and your display can output without overscan -#disable_overscan=1 - -# uncomment the following to adjust overscan. Use positive numbers if console -# goes off screen, and negative if there is too much border -#overscan_left=16 -#overscan_right=16 -#overscan_top=16 -#overscan_bottom=16 - -# uncomment to force a console size. By default it will be display's size minus -# overscan. -#framebuffer_width=1280 -#framebuffer_height=720 - -# uncomment if hdmi display is not detected and composite is being output -#hdmi_force_hotplug=1 - -# uncomment to force a specific HDMI mode (this will force VGA) -#hdmi_group=1 -#hdmi_mode=1 - -# uncomment to force a HDMI mode rather than DVI. This can make audio work in -# DMT (computer monitor) modes -#hdmi_drive=2 - -# uncomment to increase signal to HDMI, if you have interference, blanking, or -# no display -#config_hdmi_boost=4 - -# uncomment for composite PAL -#sdtv_mode=2 - -#uncomment to overclock the arm. 700 MHz is the default. -#arm_freq=800 - -# Uncomment some or all of these to enable the optional hardware interfaces -#dtparam=i2c_arm=on -#dtparam=i2s=on -#dtparam=spi=on - -# Uncomment this to enable infrared communication. -#dtoverlay=gpio-ir,gpio_pin=17 -#dtoverlay=gpio-ir-tx,gpio_pin=18 - -# Additional overlays and parameters are documented /boot/overlays/README - -# Enable audio (loads snd_bcm2835) -dtparam=audio=off - -[pi4] -# Enable DRM VC4 V3D driver on top of the dispmanx display stack -dtoverlay=vc4-fkms-v3d -max_framebuffers=2 - -[all] -#dtoverlay=vc4-fkms-v3d -dtoverlay=w1-gpio,gpiopin=17,pullup=y -gpu_mem=16 - -######################## -# unreviewed - -# for beacon -#enable_uart=1 -#dtoverlay=pi3-miniuart-bt -#core_freq=250 - -# for tiny_screen -#- lineinfile: dest=/boot/config.txt line="dtparam=spi=on" regexp="^dtparam=spi="
--- a/templates/dnsmasq/dnsmasq-mtail.service.j2 Sun Apr 21 17:01:13 2024 -0700 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,13 +0,0 @@ -# written by pyinfra - -[Unit] -Description=dnsmasq-mtail for 10.2 network -After=dnsmasq_10.2.service - -[Service] -Type=simple - -ExecStart=zsh /opt/dnsmasq/10.2/run_mtail.sh - -[Install] -WantedBy=multi-user.target
--- a/templates/dnsmasq/metrics.mtail.j2 Sun Apr 21 17:01:13 2024 -0700 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,37 +0,0 @@ -counter dnsmasq_no_addr_errors -/no address available/ { - dnsmasq_no_addr_errors++ -} - -counter dnsmasq_dhcp_requests -/DHCPREQUEST/ { - dnsmasq_dhcp_requests++ -} - -counter dnsmasq_dhcp_acks -/DHCPACK/ { - dnsmasq_dhcp_acks++ -} - -counter dnsmasq_dhcp_discovers -/DHCPDISCOVER/ { - dnsmasq_dhcp_discovers++ -} - -counter dnsmasq_dhcp_offers -/DHCPOFFER/ { - dnsmasq_dhcp_offers++ -} - -gauge dnsmasq_dns_queries_answered_locally -gauge dnsmasq_dns_queries_forwarded by server -gauge dnsmasq_dns_queries_retried_or_failed by server - -/queries forwarded (?P<fwd>\d+), queries answered locally (?P<loc>\d+)/ { - dnsmasq_dns_queries_answered_locally = $loc -} - -/server (?P<svr>\S+)#53: queries sent (?P<sent>\d+), retried or failed (?P<fail>\d+)/ { - dnsmasq_dns_queries_forwarded[$svr] = $sent - dnsmasq_dns_queries_retried_or_failed[$svr] = $fail -} \ No newline at end of file
--- a/templates/dnsmasq/run_mtail.sh Sun Apr 21 17:01:13 2024 -0700 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,11 +0,0 @@ -#!/bin/zsh -STATS_PERIOD=2m -while (true) { pkill --signal USR1 --oldest --full /usr/sbin/dnsmasq; sleep ${STATS_PERIOD} } & - -rm -f /tmp/dnsmasq_log_pipe -mkfifo /tmp/dnsmasq_log_pipe - -{ journalctl -fu dnsmasq_10.2.service > /tmp/dnsmasq_log_pipe } & - -mtail -port 9991 -logtostderr -logs /tmp/dnsmasq_log_pipe -progs /opt/dnsmasq/10.2 -#-disable_fsnotify -poll_interval ${STATS_PERIOD} \ No newline at end of file
--- a/templates/hosts.j2 Sun Apr 21 17:01:13 2024 -0700 +++ b/templates/hosts.j2 Sun Apr 21 17:07:23 2024 -0700 @@ -11,7 +11,7 @@ ff02::2 ip6-allrouters -{% if host.name in ['prime', 'plus'] %} +{% if 'laptop' in host.groups or 'hosted' in host.groups %} 10.5.0.1 bang bang.bigasterisk.com bang5 bang5.bigasterisk.com 10.5.0.7 ditto ditto.bigasterisk.com ditto5 ditto5.bigasterisk.com 10.5.0.5 dash
--- a/templates/net/bang_10.2.network.j2 Sun Apr 21 17:01:13 2024 -0700 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,10 +0,0 @@ -# written by pyinfra - -[Match] -MACAddress=60:e3:27:04:4a:85 - -[Network] -DHCP=no -Address=10.2.0.1/16 -DNS=10.2.0.3 -Gateway=10.2.0.3
--- a/templates/net/ditto-netplan.yaml.j2 Sun Apr 21 17:01:13 2024 -0700 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,22 +0,0 @@ -# written by pyinfra -network: - ethernets: - eno1: - addresses: - # name=ditto - - 10.2.0.133/16 - # name=mqtt1 etc - - 10.2.0.11/16 - - 10.2.0.12/16 - - 10.2.0.13/16 - - 10.2.0.14/16 - routes: - - to: default - via: 10.2.0.3 - nameservers: - addresses: [10.2.0.3] - enp5s0: - dhcp4: true - ens3: - dhcp4: true - version: 2
--- a/templates/net/house_net.service.j2 Sun Apr 21 17:01:13 2024 -0700 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,14 +0,0 @@ -# written by pyinfra - -[Unit] -After=network-online.target nss-lookup.target -Wants=network-online.target nss-lookup.target - -[Service] -Type=oneshot -ExecStart=sh -c "sysctl net.ipv4.ip_forward=1 && /usr/sbin/iptables -A POSTROUTING --table nat --out-interface eth0 --jump MASQUERADE" -RemainAfterExit=yes - - -[Install] -WantedBy=multi-user.target
--- a/templates/net/pipe_10.2.network.j2 Sun Apr 21 17:01:13 2024 -0700 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,14 +0,0 @@ -# written by pyinfra - -[Match] -# usb dongle -MACAddress=00:05:1b:33:3e:81 - -[Network] -DHCP=no -Address=10.2.0.3/16 -# vip for the filtered dns server we give clients who are to have sometimes-filtered domains -Address=10.2.0.4/16 -DNS=10.2.0.3 -Domains=bigasterisk.com -
--- a/templates/net/pipe_isp.network.j2 Sun Apr 21 17:01:13 2024 -0700 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,12 +0,0 @@ -# written by pyinfra - -[Match] -# onboard eth -MACAddress=00:1e:06:43:20:d0 - -[Network] -DHCP=no -Address=192.168.42.3/24 -Gateway=192.168.42.1 -DNS=10.2.0.1 -Domains=bigasterisk.com \ No newline at end of file
--- a/templates/net/prime.network.j2 Sun Apr 21 17:01:13 2024 -0700 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,14 +0,0 @@ -# written by pyinfra - -# see systemd.network(5) - -[Match] -MACAddress={{ mac }} - -[Network] -Address=162.243.138.136/24 -Gateway=162.243.138.1 -DNS=10.5.0.1%wg0 -DNS=8.8.8.8 -DNS=8.8.4.4 -Domains=bigasterisk.com \ No newline at end of file
--- a/templates/net/singlenic.network.j2 Sun Apr 21 17:01:13 2024 -0700 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,10 +0,0 @@ -# written by pyinfra - -[Match] -Name=* - -[Network] -DHCP=yes -# this sauce may or may not help with k3s -LinkLocalAddressing=yes -IPForward=yes \ No newline at end of file
--- a/templates/pigpiod.service.j2 Sun Apr 21 17:01:13 2024 -0700 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,11 +0,0 @@ -# written by pyinfra - -[Unit] -Description=Daemon required to control GPIO pins via pigpio - -[Service] -Type=simple -ExecStart=/usr/bin/pigpiod -g -p 8888 - -[Install] -WantedBy=multi-user.target
--- a/templates/sources.list.j2 Sun Apr 21 17:01:13 2024 -0700 +++ b/templates/sources.list.j2 Sun Apr 21 17:07:23 2024 -0700 @@ -1,26 +1,22 @@ # written by pyinfra -{% if host.name in ['dash', 'squib', 'slash', 'dot', 'plus', 'ditto', 'pillow'] %} +{% if 'big' in host.groups or 'laptop' in host.groups %} deb [arch=amd64,arm64,armhf signed-by=/etc/apt/keyrings/ms.gpg] http://packages.microsoft.com/repos/code stable main deb [arch=amd64 signed-by=/etc/apt/keyrings/chrome.gpg] http://dl.google.com/linux/chrome/deb/ stable main deb [arch=amd64,i386 signed-by=/usr/share/keyrings/steam.gpg] https://repo.steampowered.com/steam/ stable steam deb [signed-by=/etc/apt/keyrings/unityhub.gpg] https://hub.unity3d.com/linux/repos/deb stable main -{% endif %} - -{% if host.name in ['dash', 'squib', 'plus', 'bang', 'slash', 'dot', 'ditto', 'pillow'] %} deb [signed-by=/etc/apt/keyrings/nodesource.gpg] https://deb.nodesource.com/node_18.x nodistro main {% endif %} -# k8s node with nvidia gpu -{% if host.name in ['dash', 'ditto', 'slash', 'dot'] %} +{% if host.data.get('gpu') %} deb [signed-by=/etc/apt/keyrings/nvidia.gpg] https://nvidia.github.io/libnvidia-container/stable/deb/$(ARCH) / {% endif %} -{% if host.name in ['ditto'] %} +{% if host.data.get('coral') %} deb [signed-by=/etc/apt/keyrings/coral.gpg] https://packages.cloud.google.com/apt coral-edgetpu-stable main {% endif %} -{% if host.name in ['dash', 'squib', 'plus', 'bang', 'slash', 'dot', 'prime', 'ditto', 'pillow'] %} +{% if 'big' in host.groups or 'laptop' in host.groups or 'hosted' in host.groups %} deb http://us.archive.ubuntu.com/ubuntu mantic main restricted deb http://us.archive.ubuntu.com/ubuntu mantic multiverse deb http://us.archive.ubuntu.com/ubuntu mantic universe @@ -33,7 +29,7 @@ deb http://us.archive.ubuntu.com/ubuntu mantic-updates universe {% endif %} -{% if host.name in ['pipe'] %} +{% if host.name == 'pipe' %} # seems stuck on jammy since http://deb.odroid.in/n2/ and https://wiki.odroid.com/odroid-n2/os_images/ubuntu don't have anything newer (2023-12-28) deb [signed-by=/etc/apt/trusted.gpg.d/ubuntu-keyring-2018-archive.gpg] http://archive.canonical.com/ubuntu jammy partner deb [signed-by=/etc/apt/trusted.gpg] http://deb.odroid.in/n2/ jammy main @@ -51,7 +47,7 @@ deb [signed-by=/etc/apt/trusted.gpg] http://ppa.launchpad.net/hardkernel/ppa/ubuntu jammy main {% endif %} -{% if host.name in ['garage', 'ws-printer', 'gn-music', 'li-drums'] %} +{% if 'pi' in host.groups %} deb http://deb.debian.org/debian bookworm main contrib non-free non-free-firmware deb http://deb.debian.org/debian-security/ bookworm-security main contrib non-free non-free-firmware deb http://deb.debian.org/debian bookworm-updates main contrib non-free non-free-firmware
--- a/templates/wireguard/wg0.conf.j2 Sun Apr 21 17:01:13 2024 -0700 +++ b/templates/wireguard/wg0.conf.j2 Sun Apr 21 17:07:23 2024 -0700 @@ -21,14 +21,13 @@ {{ peer_block('gn-music', '10.5.0.32/32') }} {{ peer_block('li-drums', '10.5.0.33/32') }} {% elif host.name == 'prime' %} +# this list is wg_roamer & ditto & phone: {{ peer_block('ditto', '10.5.0.0/24') }} {{ peer_block('drew-note10', '10.5.0.112/32') }} {{ peer_block('plus', '10.5.0.110/32', 'public.bigasterisk.com:1195') }} {{ peer_block('pillow', '10.5.0.111/32', 'public.bigasterisk.com:1195') }} - -{% elif host.name in ['plus','pillow'] %} +{% elif host.data.get('wg_roamer') %} {{ peer_block('prime', '10.5.0.0/24', 'public.bigasterisk.com:1195', 50) }} - {# {{ peer_block('ditto', '10.5.0.0/24', 'ditto:1195', 50) }} #} {% else %} # note that hosts on filtered dns cannot currently look up the name 'ditto' {{ peer_block('ditto', '10.5.0.0/24', '10.2.0.133:1195', 50) }}
--- a/users.py Sun Apr 21 17:01:13 2024 -0700 +++ b/users.py Sun Apr 21 17:07:23 2024 -0700 @@ -2,16 +2,11 @@ from pyinfra.operations import server from pyinfra.facts.server import LinuxDistribution -is_pi = host.get_fact(LinuxDistribution)['name'] in ['Debian', 'Raspbian GNU/Linux'] # raspbian took 1000 for 'pi' group, but drewp is rarely used on pi # setups so hopefully it won't matter much that drew group has a # different id. -drewp_uid, drewp_gid = 501, 1000 -if host.name in ['pillow', ]: - drewp_uid, drewp_gid = 1000, 1000 -if host.name in ['pipe', 'garage', 'ws-printer', 'gn-music', 'li-drums']: - drewp_uid, drewp_gid = 1001, 501 +drewp_uid, drewp_gid = host.data.drewp_uid, host.data.drewp_gid drewp_groups = [ 'lp', 'adm', 'dialout', 'cdrom', 'sudo', 'audio', 'video', 'plugdev', 'games', 'users', 'netdev', 'i2c', 'input', 'spi', 'gpio', 'fuse', @@ -46,8 +41,7 @@ server.user(user='drewp', uid=drewp_uid, group='drewp', groups=drewp_groups) - -if not is_pi: +if 'pi' not in host.groups: server.group(group='adm', gid=4) server.group(group='cdrom', gid=24) server.group(group='dialout', gid=20) @@ -89,12 +83,11 @@ server.group(group='kelsi', gid=1008) server.user(user='kelsi', uid=1008, group='elastic') - if host.name != 'pipe': # https://github.com/Fizzadar/pyinfra/issues/835 - server.group(group='drewnote', gid=1009) - server.user(user='drewnote', uid=1009) + server.group(group='drewnote', gid=1009) + server.user(user='drewnote', uid=1009) - server.group(group='prometheus', gid=1010) - server.user(user='prometheus', uid=1010) + server.group(group='prometheus', gid=1010) + server.user(user='prometheus', uid=1010) # delete when garage is diskless if host.name == 'garage':
--- a/wireguard.py Sun Apr 21 17:01:13 2024 -0700 +++ b/wireguard.py Sun Apr 21 17:07:23 2024 -0700 @@ -14,9 +14,7 @@ def peer_block(hostname, allowed_ips, endpoint=None, keepalive=None): - # if allowed_ips.startswith('10.5'): - # # k3s nets also need to travel over wg - # allowed_ips += ', 10.42.0.0/24, 10.43.0.0/24' + # allowed_ips should be determined mostly from host.data.wireguard_address public_key = wireguard_pubkey.pubkey[hostname] out = f'''\ @@ -33,6 +31,22 @@ return out +def get_priv_key(wireguard_interface) -> str: + priv_key_lines = host.get_fact(FindInFile, path=f'/etc/wireguard/{wireguard_interface}.conf', pattern=r'PrivateKey.*') + if not priv_key_lines: + priv_key = subprocess.check_output(['wg', 'genkey']).strip().decode('ascii') + else: + priv_key = priv_key_lines[0].split(' = ')[1] + return priv_key + + +def compute_pub_key(priv_key: str) -> str: + pub_key = subprocess.check_output(['wg', 'pubkey'], input=priv_key.encode('ascii')).strip().decode('ascii') + # todo: if this was new, it should be added to a file of pubkeys that + # peer_block can refer to. meanwhile, edit the template. + return pub_key + + for wireguard_interface in ['wg0', 'bogasterisk']: if wireguard_interface == 'bogasterisk' and host.name != 'prime': continue @@ -44,15 +58,10 @@ # new pi may fail with 'Unable to access interface: Protocol not supported'. reboot fixes. - priv_key_lines = host.get_fact(FindInFile, path=f'/etc/wireguard/{wireguard_interface}.conf', pattern=r'PrivateKey.*') - if not priv_key_lines: - priv_key = subprocess.check_output(['wg', 'genkey']).strip().decode('ascii') - else: - priv_key = priv_key_lines[0].split(' = ')[1] + priv_key = get_priv_key(wireguard_interface) - pub_key = subprocess.check_output(['wg', 'pubkey'], input=priv_key.encode('ascii')).strip().decode('ascii') - # todo: if this was new, it should be added to a file of pubkeys that - # peer_block can refer to. meanwhile, edit the template. + # unused since I still hand-maintain wireguard_pubkey.py :( + # pub_key = compute_pub_key(priv_key) files.template( src=f'templates/wireguard/{wireguard_interface}.conf.j2', @@ -67,9 +76,4 @@ files.template(src='templates/wireguard/wg.service.j2', dest=f'/etc/systemd/system/{svc}', wireguard_interface=wireguard_interface) - systemd.service(service=svc, enabled=True, restarted=True, daemon_reload=True) - systemd.service(service=svc, daemon_reload=True, restarted=True, enabled=True) - -# if host.name == 'bang': -# systemd.service(service=f'dnsmasq_10.5', enabled=True, restarted=True, daemon_reload=True)