feat: Install 50ohm webserver, download the content and install the final, static website

This commit is contained in:
Lars Weiler
2026-02-07 23:53:28 +01:00
commit 238bb38a6c
20 changed files with 578 additions and 0 deletions
+5
View File
@@ -0,0 +1,5 @@
- name: Include tasks from users.yml
ansible.builtin.include_tasks: users.yml
- name: Include tasks from packages.yml
ansible.builtin.include_tasks: packages.yml
+9
View File
@@ -0,0 +1,9 @@
- name: Install packages
ansible.builtin.package:
name:
- python3-venv
- python3-pip
- acl
- nginx
- uv
state: present
+45
View File
@@ -0,0 +1,45 @@
- name: Ensure 'sudo' group exists
ansible.builtin.group:
name: sudo
state: present
- name: Create users from users.yml
ansible.builtin.user:
name: "{{ item.name }}"
shell: "{{ item.shell | default('/bin/bash') }}"
password: "!"
update_password: on_create
groups:
- sudo
state: present
loop: "{{ users | flatten(levels=1)}}"
- name: Add SSH keys for users
ansible.builtin.authorized_key:
user: "{{ item.name }}"
state: present
key: "{{ item.sshkeys }}"
loop: "{{ users | flatten(levels=1) }}"
- name: Ensure sudo group has passwordless sudo access
ansible.builtin.lineinfile:
path: /etc/sudoers.d/sudo-nopasswd
state: present
create: true
line: "%sudo ALL=(ALL) NOPASSWD: ALL"
validate: '/usr/sbin/visudo -cf %s'
mode: '0440'
- name: Ensure sudoers uses sudoers.d
ansible.builtin.lineinfile:
path: /etc/sudoers
state: present
line: "@includedir /etc/sudoers.d"
validate: '/usr/sbin/visudo -cf %s'
- name: Ensure ex-users are removed
ansible.builtin.user:
name: "{{ item }}"
state: absent
remove: true
loop: "{{ ex_users | flatten(levels=1) }}"
+5
View File
@@ -0,0 +1,5 @@
- name: Run build.py in {{ destination_path }}/50ohm
ansible.builtin.command: uv run python3 ./build.py
args:
chdir: "{{ destination_path }}/50ohm"
become_user: "{{ fiftyohm_user }}"
+5
View File
@@ -0,0 +1,5 @@
- name: Run tasks from prepare.yml
ansible.builtin.include_tasks: prepare.yml
- name: Run tasks from build.yml
ansible.builtin.include_tasks: build.yml
+13
View File
@@ -0,0 +1,13 @@
- name: Run uv venv in {{ destination_path }}/50ohm
ansible.builtin.command: uv venv
args:
chdir: "{{ destination_path }}/50ohm"
creates: "{{ destination_path }}/50ohm/.venv"
become_user: "{{ fiftyohm_user }}"
- name: Install dependencies with uv pip in {{ destination_path }}/50ohm
ansible.builtin.command: uv pip sync requirements.txt
args:
chdir: "{{ destination_path }}/50ohm"
creates: "{{ destination_path }}/50ohm/.venv/lib/python3.*/site-packages/uv"
become_user: "{{ fiftyohm_user }}"
@@ -0,0 +1,66 @@
rewrite ^/vn01/?$ https://www.youtube.com/watch?v=WnOBk1UogjM&t=0s redirect;
rewrite ^/mw/?$ https://www.darc.de/mitgliedschaft/mitglied-werden/ redirect;
rewrite ^/rzp/?$ https://www.bundesnetzagentur.de/DE/Fachthemen/Telekommunikation/Frequenzen/SpezielleAnwendungen/Amateurfunk/DL_Vfg_AFu/Rufzeichenplan_10_24_Auszug_aus_Vfg_15_2025.pdf?__blob=publicationFile&v=3 redirect;
rewrite ^/rzl/?$ https://www.bundesnetzagentur.de/SharedDocs/Downloads/DE/Sachgebiete/Telekommunikation/Unternehmen_Institutionen/Frequenzen/Amateurfunk/Rufzeichenliste/rufzeichenliste_afu.html redirect;
rewrite ^/rza/?$ https://ans.bundesnetzagentur.de/Amateurfunk/Rufzeichen.aspx redirect;
rewrite ^/cll/?$ https://www.darc.de/der-club/referate/ausland/funken-im-ausland/cept-laenderliste/ redirect;
rewrite ^/ra/?$ https://www.darc.de/der-club/referate/ausland/ redirect;
rewrite ^/ww/?$ https://www.bundesnetzagentur.de/DE/Fachthemen/Telekommunikation/Technik/EMF/Standortbescheinigung/_functions/wattwaechter.html redirect;
rewrite ^/a1/?$ https://www.gesetze-im-internet.de/afuv_2005/anlage_1.html redirect;
rewrite ^/rnf/?$ https://www.darc.de/der-club/referate/notfunk/ redirect;
rewrite ^/vde-blitz/?$ https://www.vde.com/resource/blob/2001262/56f5576bbaf617b1e9e5195d1e8411d9/vde-information-blitzschutz-funkanlagen-download-data.pdf redirect;
rewrite ^/bfs/?$ https://www.bfs.de/DE/themen/emf/hff/wirkung/hff-nachgewiesen/hff-nachgewiesen.html redirect;
rewrite ^/hamnet/?$ https://hamnetdb.net/map.cgi redirect;
rewrite ^/sim/?$ https://afup.a36.de/pruefungen/pruefungen2.html redirect;
rewrite ^/dl-de/?$ http://www.govdata.de/dl-de/by-2-0 redirect;
rewrite ^/fs/?$ https://www.bundesnetzagentur.de/SharedDocs/Downloads/DE/Sachgebiete/Telekommunikation/Unternehmen_Institutionen/Frequenzen/Amateurfunk/Fragenkatalog/Pruefungsfragen.pdf?__blob=publicationFile&v=2#page=234 redirect;
rewrite ^/bp/?$ https://www.bundesnetzagentur.de/SharedDocs/Downloads/DE/Sachgebiete/Telekommunikation/Unternehmen_Institutionen/Frequenzen/Amateurfunk/Fragenkatalog/Pruefungsfragen.pdf?__blob=publicationFile&v=2#page=246 redirect;
rewrite ^/hm/?$ https://www.bundesnetzagentur.de/SharedDocs/Downloads/DE/Sachgebiete/Telekommunikation/Unternehmen_Institutionen/Frequenzen/Amateurfunk/AntraegeFormulare/Hilfsmittel_12062024.pdf?__blob=publicationFile&v=3 redirect;
rewrite ^/tr/?$ https://dd3ah.de/wp-content/uploads/2019/01/rechnen.pdf redirect;
rewrite ^/rs/?$ https://www.rohde-schwarz.com/ausbildung redirect;
rewrite ^/ajw/?$ https://ajw.darc.de redirect;
rewrite ^/wl/?$ https://www.wavelog.org redirect;
rewrite ^/wlv/?$ https://www.youtube.com/watch?v=G5mJjrKLJvE redirect;
rewrite ^/log/?$ https://log.darc.de redirect;
rewrite ^/buch/?$ https://darcverlag.de/DARC-Amateurfunklehrgang-Klasse-N redirect;
rewrite ^/fk/?$ https://www.bundesnetzagentur.de/SharedDocs/Downloads/DE/Sachgebiete/Telekommunikation/Unternehmen_Institutionen/Frequenzen/Amateurfunk/Fragenkatalog/Pruefungsfragen.pdf?__blob=publicationFile&v=2 redirect;
rewrite ^/geb/?$ https://www.bundesnetzagentur.de/DE/Beschlusskammern/BK02/BK2_01_Aktuell/Downloads/BK2_3_BMDVTKBGebV_download.pdf?__blob=publicationFile&v=4#page=12 redirect;
rewrite ^/wiki-dds/?$ https://de.wikipedia.org/wiki/Direct_Digital_Synthesis redirect;
rewrite ^/vfg33/?$ https://www.bundesnetzagentur.de/SharedDocs/Downloads/DE/Sachgebiete/Telekommunikation/Unternehmen_Institutionen/Frequenzen/Amateurfunk/AmtsblattverfuegungenAFu/Vfg332007Ver246ffentlicId10701pdf.pdf?__blob=publicationFile&v=4 redirect;
rewrite ^/acw/?$ https://youtu.be/iJ2udTxn3SU?si=VolNcnQxOR1VXpuO redirect;
rewrite ^/assb/?$ https://www.youtube.com/watch?v=NMKZfJSjkbQ redirect;
rewrite ^/itu/?$ https://www.itu.int/en/ITU-R/terrestrial/fmd/Pages/call_sign_series.aspx redirect;
rewrite ^/bemfv/?$ https://www.bundesnetzagentur.de/SharedDocs/Downloads/DE/Sachgebiete/Telekommunikation/Verbraucher/ElektromagnetischeFelder/Anzeige_Afu/Erlaeuterung_der_Bewertungsverfahren_nach_BEMFV.pdf?__blob=publicationFile&v=1 redirect;
rewrite ^/BImSchV/?$ https://www.gesetze-im-internet.de/bimschv_26/ redirect;
rewrite ^/so/?$ https://www.bundesnetzagentur.de/DE/Allgemeines/DieBundesnetzagentur/AufgabenStruktur/Standorte/start.html redirect;
rewrite ^/ov/?$ https://www.darc.de/home/#c153658 redirect;
rewrite ^/k01/?$ https://confluence.darc.de/spaces/AJWCards/pages/183894027/Kochen redirect;
rewrite ^/k02/?$ https://confluence.darc.de/spaces/AJWCards/pages/183894047/Fuchsjagd redirect;
rewrite ^/k03/?$ https://confluence.darc.de/spaces/AJWCards/pages/183894050/Rei�~_nagel+Löten redirect;
rewrite ^/k05/?$ https://confluence.darc.de/spaces/AJWCards/pages/183894055/Filmabend redirect;
rewrite ^/k06/?$ https://confluence.darc.de/spaces/AJWCards/pages/183894059/Technik+und+Natur redirect;
rewrite ^/k07/?$ https://confluence.darc.de/spaces/AJWCards/pages/183894064/Schatzsuche redirect;
rewrite ^/k08/?$ https://confluence.darc.de/spaces/AJWCards/pages/183894068/Astronomie redirect;
rewrite ^/k09/?$ https://confluence.darc.de/spaces/AJWCards/pages/183894071/Experimentieren redirect;
rewrite ^/k10/?$ https://confluence.darc.de/spaces/AJWCards/pages/183894074/Technikmuseum redirect;
rewrite ^/k11/?$ https://confluence.darc.de/spaces/AJWCards/pages/183894077/Klasse+N+Kurs redirect;
rewrite ^/k12/?$ https://confluence.darc.de/spaces/AJWCards/pages/183894085/Ausbildungsfunk redirect;
rewrite ^/t02/?$ https://confluence.darc.de/spaces/AJWCards/pages/183894089/Fieldday redirect;
rewrite ^/t01/?$ https://confluence.darc.de/spaces/AJWCards/pages/183894080/Escape+Room redirect;
rewrite ^/t03/?$ https://confluence.darc.de/spaces/AJWCards/pages/183894092/HAMCAMP redirect;
rewrite ^/t04/?$ https://confluence.darc.de/spaces/AJWCards/pages/183894097/3D+Druck redirect;
rewrite ^/t05/?$ https://confluence.darc.de/spaces/AJWCards/pages/183894100/Klasse+E+Kurs redirect;
rewrite ^/t06/?$ https://confluence.darc.de/spaces/AJWCards/pages/183894103/Programmieren redirect;
rewrite ^/t07/?$ https://confluence.darc.de/spaces/AJWCards/pages/183894106/Contest redirect;
rewrite ^/t08/?$ https://confluence.darc.de/spaces/AJWCards/pages/183894110/Planen redirect;
rewrite ^/t09/?$ https://confluence.darc.de/spaces/AJWCards/pages/183894114/Elektronik+Projekt redirect;
rewrite ^/t10/?$ https://confluence.darc.de/spaces/AJWCards/pages/183894117/Wandern redirect;
rewrite ^/t11/?$ https://confluence.darc.de/spaces/AJWCards/pages/183894120/Hackathon redirect;
rewrite ^/e01/?$ https://confluence.darc.de/spaces/AJWCards/pages/183894125/Klasse+A+Kurs redirect;
rewrite ^/e03/?$ https://confluence.darc.de/spaces/AJWCards/pages/183894128/Vorträge redirect;
rewrite ^/e06/?$ https://confluence.darc.de/spaces/AJWCards/pages/183894131/Raumfahrtprojekt redirect;
rewrite ^/e07/?$ https://confluence.darc.de/spaces/AJWCards/pages/183894134/Wetterballon redirect;
rewrite ^/e09/?$ https://confluence.darc.de/spaces/AJWCards/pages/183894141/SDR+Projekt redirect;
rewrite ^/e10/?$ https://confluence.darc.de/spaces/AJWCards/pages/183894145/DX-Pedition redirect;
rewrite ^/e11/?$ https://confluence.darc.de/spaces/AJWCards/pages/183894148/Notfunk redirect;
rewrite ^/e12/?$ https://confluence.darc.de/spaces/AJWCards/pages/183894151/Workshop redirect;
+43
View File
@@ -0,0 +1,43 @@
- name: Create destination directory {{ destination_path }}
ansible.builtin.file:
dest: "{{ destination_path }}"
state: directory
owner: "{{ fiftyohm_user }}"
group: "{{ fiftyohm_group }}"
mode: '0755'
- name: Checkout 50ohm source from https://github.com/DARC-e-V/50ohm to {{ destination_path }}/
ansible.builtin.git:
repo: https://github.com/DARC-e-V/50ohm.git
dest: "{{ destination_path }}/50ohm"
single_branch: true
version: refactor/migrate-from-directus-to-git
force: true
become_user: "{{ fiftyohm_user }}"
- name: Checkout 50ohm-contents-dl from https://github.com/DARC-e-V/50ohm-contents-dl to {{ destination_path }}
ansible.builtin.git:
repo: https://github.com/DARC-e-V/50ohm-contents-dl.git
dest: "{{ destination_path }}/50ohm-contents-dl"
single_branch: true
version: HEAD
become_user: "{{ fiftyohm_user }}"
- name: Create {{ destination_path }}/50ohm/config/config.json
ansible.builtin.copy:
dest: "{{ destination_path }}/50ohm/config/config.json"
content: >
{
"content_path": "../50ohm-contents-dl"
}
owner: "{{ fiftyohm_user }}"
group: "{{ fiftyohm_group }}"
mode: '0444'
- name: Install url_shortener.conf in /srv/50ohm.de/url_shortener.conf
ansible.builtin.copy:
src: files/url_shortener.conf
dest: /srv/50ohm.de/url_shortener.conf
owner: "{{ fiftyohm_user }}"
group: "{{ fiftyohm_group }}"
mode: '0644'
@@ -0,0 +1,7 @@
#!/usr/bin/env bash
set -euo pipefail
git -C 50ohm pull
git -C 50ohm-contents-dl pull
cd 50ohm
uv run python3 ./build.py
+30
View File
@@ -0,0 +1,30 @@
- name: Install refresh-50ohm.sh in {{ destination_path }}/refresh-50ohm.sh
ansible.builtin.copy:
src: files/refresh-50ohm.sh
dest: "{{ destination_path }}/refresh-50ohm.sh"
owner: "{{ fiftyohm_user }}"
group: "{{ fiftyohm_group }}"
mode: '0755'
- name: Install systemd timer unit for 50ohm refresh in /etc/systemd/system/refresh-50ohm.timer
ansible.builtin.template:
src: templates/timer.j2
dest: /etc/systemd/system/refresh-50ohm.timer
owner: root
group: root
mode: '0644'
- name: Install systemd service unit for 50ohm refresh in /etc/systemd/system/refresh-50ohm.service
ansible.builtin.template:
src: templates/service.j2
dest: /etc/systemd/system/refresh-50ohm.service
owner: root
group: root
mode: '0644'
- name: Enable and start refresh-50ohm.timer
ansible.builtin.systemd:
name: refresh-50ohm.timer
enabled: true
state: started
daemon_reload: true
+11
View File
@@ -0,0 +1,11 @@
[Unit]
Description=Refresh 50ohm.de with a timer
[Service]
Type=oneshot
ExecStart={{ destination_path }}/refresh-50ohm.sh
User={{ fiftyohm_user }}
WorkingDirectory={{ destination_path }}/
[Install]
WantedBy=multi-user.target
+10
View File
@@ -0,0 +1,10 @@
[Unit]
Description=Timer for refreshing 50ohm.de
[Timer]
OnBootSec=5min
OnUnitAciveSec=15min
Unit=refresh-50ohm.service
[Install]
WantedBy=timers.target