diff --git a/bundles/infobeamer-cms/files/infobeamer-cms-runperiodic.service b/bundles/infobeamer-cms/files/infobeamer-cms-runperiodic.service new file mode 100644 index 0000000..1e7ddba --- /dev/null +++ b/bundles/infobeamer-cms/files/infobeamer-cms-runperiodic.service @@ -0,0 +1,10 @@ +[Unit] +Description=infobeamer-cms sync +After=network.target +Requires=infobeamer-cms.service + +[Service] +User=infobeamer-cms +Group=infobeamer-cms +WorkingDirectory=/opt/infobeamer-cms +ExecStart=curl http://127.0.0.1:8000/sync diff --git a/bundles/infobeamer-cms/files/infobeamer-cms-runperiodic.timer b/bundles/infobeamer-cms/files/infobeamer-cms-runperiodic.timer new file mode 100644 index 0000000..48b52f4 --- /dev/null +++ b/bundles/infobeamer-cms/files/infobeamer-cms-runperiodic.timer @@ -0,0 +1,9 @@ +[Unit] +Description=Run infobeamer-cms sync + +[Timer] +OnCalendar=*:0/5 +Persistent=true + +[Install] +WantedBy=timers.target diff --git a/bundles/infobeamer-cms/files/infobeamer-cms.service b/bundles/infobeamer-cms/files/infobeamer-cms.service new file mode 100644 index 0000000..56423ee --- /dev/null +++ b/bundles/infobeamer-cms/files/infobeamer-cms.service @@ -0,0 +1,18 @@ +[Unit] +Description=infobeamer-cms - upload custom info pages to info-beamer +After=network.target + +[Service] +Type=exec +Environment=SETTINGS=settings.cfg +Restart=always +RestartSec=5s +ExecStart=/usr/bin/gunicorn frontend:app -b 127.0.0.1:${PORT} -w ${WORKERS} -t 120 -k gevent --max-requests=1000 + +# You may have to adjust these settings +User=infobeamer-cms +Group=infobeamer-cms +WorkingDirectory=/opt/infobeamer-cms + +[Install] +WantedBy=multi-user.target diff --git a/bundles/infobeamer-cms/files/settings.cfg b/bundles/infobeamer-cms/files/settings.cfg new file mode 100644 index 0000000..435a2d4 --- /dev/null +++ b/bundles/infobeamer-cms/files/settings.cfg @@ -0,0 +1,47 @@ +<% +from json import dumps +%> +# This github OAuth client will be used for authentication. Create +# one at https://github.com/organizations/ACCOUNT/settings/applications +GITHUB_CLIENT_ID = '${GITHUB_CLIENT_ID}' +GITHUB_CLIENT_SECRET = '${GITHUB_CLIENT_SECRET}' + +SESSION_COOKIE_NAME = '${SESSION_COOKIE_NAME}' + +PREFERRED_URL_SCHEME = '${PREFERRED_URL_SCHEME}' + +# info-beamer API keys. +# This key needs access to setups and assets as well as the +# node-message calls. If you consider the host running this +# code trusted, you might use a key with full account access. +# The keys given out to users are adhoc keys based on this key. +HOSTED_API_KEY = '${HOSTED_API_KEY}' + +# Maximum uploads per github user +MAX_UPLOADS = ${MAX_UPLOADS} + +# Setup IDs using the scheduled player setup. One of the +# playlists must be named 'User Content'. Its pages will be +# autogenerated by the CMS when calling /sync +SETUP_IDS = ${SETUP_IDS} + +# Generate some random string. It's used for signing +# urls send to moderators. +URL_KEY = b'${URL_KEY}' + +# Push notifications for moderation requests user pushover. +# Specify a target key and the app key to use. +PUSHOVER_TARGET = '${PUSHOVER_TARGET}' +PUSHOVER_APP_KEY = '${PUSHOVER_APP_KEY}' + +# Unix timestamp allows for specifying start/end time +# of uploaded content +TIME_MIN = ${TIME_MIN} +TIME_MAX = ${TIME_MAX} + +# change this to invalidate cached static files. +VERSION = ${VERSION} + +# rooms. This is both used for the /last view as well +# as the interruption control on /interrupt. +ROOMS = ${dumps(node.metadata.get('infobeamer-cms/config/ROOMS', {}))} diff --git a/bundles/infobeamer-cms/items.py b/bundles/infobeamer-cms/items.py new file mode 100644 index 0000000..e1f812c --- /dev/null +++ b/bundles/infobeamer-cms/items.py @@ -0,0 +1,86 @@ +actions = { + 'infobeamer-cms_set_directory_permissions': { + 'triggered': True, + 'command': 'chown -R infobeamer-cms:infobeamer-cms /opt/infobeamer-cms/static/' + }, +} + +git_deploy = { + '/opt/infobeamer-cms': { + 'rev': 'master', + 'repo': 'https://github.com/sophieschi/36c3-cms.git', + 'needs': { + 'directory:/opt/infobeamer-cms', + }, + 'triggers': { + 'svc_systemd:infobeamer-cms:restart', + 'action:infobeamer-cms_set_directory_permissions', + }, + }, +} + +directories = { + '/opt/infobeamer-cms': {}, +} + +files = { + '/opt/infobeamer-cms/settings.cfg': { + 'content_type': 'mako', + 'context': node.metadata.get('infobeamer-cms/config'), + 'needs': { + 'git_deploy:/opt/infobeamer-cms', + }, + 'triggers': { + 'svc_systemd:infobeamer-cms:restart', + }, + }, + '/etc/systemd/system/infobeamer-cms.service': { + 'content_type': 'mako', + 'context': node.metadata.get('infobeamer-cms/config'), + 'triggers': { + 'action:systemd-reload', + 'svc_systemd:infobeamer-cms:restart', + }, + }, + '/etc/systemd/system/infobeamer-cms-runperiodic.timer': { + 'triggers': { + 'action:systemd-reload', + 'svc_systemd:infobeamer-cms-runperiodic.timer:restart', + }, + }, + '/etc/systemd/system/infobeamer-cms-runperiodic.service': { + 'triggers': { + 'action:systemd-reload', + }, + }, +} + +pkg_pip = { + 'github-flask': { + 'needed_by': { + 'git_deploy:/opt/infobeamer-cms', + }, + }, +} + +svc_systemd = { + 'infobeamer-cms': { + 'needs': { + 'file:/opt/infobeamer-cms/settings.cfg', + 'file:/etc/systemd/system/infobeamer-cms.service', + 'git_deploy:/opt/infobeamer-cms', + }, + }, + 'infobeamer-cms-runperiodic.timer': { + 'needs': { + 'file:/etc/systemd/system/infobeamer-cms-runperiodic.timer', + 'file:/etc/systemd/system/infobeamer-cms-runperiodic.service', + }, + }, +} + +users = { + 'infobeamer-cms': { + 'home': '/opt/infobeamer-cms', + }, +} diff --git a/bundles/infobeamer-cms/metadata.py b/bundles/infobeamer-cms/metadata.py new file mode 100644 index 0000000..5b74877 --- /dev/null +++ b/bundles/infobeamer-cms/metadata.py @@ -0,0 +1,222 @@ +defaults = { + 'apt': { + 'packages': { + 'gunicorn': {}, + 'python3-gevent': {}, + 'python3-flask': {}, + 'python3-jinja2': {}, + 'python3-redis': {}, + 'python3-oauth2client': {}, + 'python3-virtualenv': {}, + 'python3-requests': {}, + 'python3-iso8601': {}, + }, + }, + 'infobeamer-cms': { + 'config': { + 'GITHUB_CLIENT_ID': repo.vault.decrypt('encrypt$gAAAAABhxJT3JG3Qb1X-gjtBxwOXZmF-GVPjNbDkYo0Eke5Ly4CAKiussQ8Lld-4zoIWnIVBgndfPPGFDV2RlAHgb-_RY5r7jQcAlgsR0RUw4as0jEhiKlQ='), + 'GITHUB_CLIENT_SECRET': repo.vault.decrypt('encrypt$gAAAAABhxJUgYzLIm5Efbn9-sEPpQRRiskHKa7fSqNoUxgonpcn7b9e6S_WbNHH_CLGrkKi7oE3pYUticDaLLLSM0bv74lswwElNvkhUuOM-RSeEuyKEhPP-fX-NXIa_AkRkFPVVBLnw'), + 'SESSION_COOKIE_NAME': '__Host-sess', + 'PREFERRED_URL_SCHEME': 'https', + 'HOSTED_API_KEY': repo.vault.decrypt('encrypt$gAAAAABhxJPH2sIGMAibU2Us1HoCVlNfF0SQQnVl0eiod48Zu8webL_-xk3wDw3yXw1Hkglj-2usl-D3Yd095yTSq0vZMCv2fh-JWwSPdJewQ45x9Ai4vXVD4CNz5vuJBESKS9xQWXTc'), + 'MAX_UPLOADS': 5, + 'SETUP_IDS': '[212947]', + 'URL_KEY': repo.vault.password_for(f'{node.name} infobeamer-cms url key'), + 'PUSHOVER_TARGET': repo.vault.decrypt('encrypt$gAAAAABhxKJJrjd-wBezp1Bl8Lu_8BrMm4jiZvOub_XBnPTXE6mAHCTDCRGqH2-Z---hhuJh50MXroNzzIuA_9uAtwXhtkXkrsR344bcZh-idG6V0tDgzds='), + 'PUSHOVER_APP_KEY': repo.vault.decrypt('encrypt$gAAAAABhxJFqFafr8pZhQPn3HXGx0plLNQpnTDtJhM4PnlWYDBKjMZxUVh0Ol4631ZBTO5Sj8SIq79O2-Lx2eu0cGIZuzPQsZIBFuxv-30d81r6ljmLh8RQ='), + 'TIME_MIN': 1640039559, + 'TIME_MAX': 1640905200, + 'VERSION': 1, + 'ROOMS': [ + { + 'name': 'Chaos-West TV', + 'device_id': 17968, + 'interrupts': [ + { + 'name': 'Signal', + 'data': 'signal', + }, + ], + }, + { + 'name': 'Chaosstudio Hamburg', + 'device_id': 3284, + 'interrupts': [ + { + 'name': 'Signal', + 'data': 'signal', + }, + ], + }, + { + 'name': 'ChaosZone TV', + 'device_id': 3, + 'interrupts': [ + { + 'name': 'Signal', + 'data': 'signal', + }, + ], + }, + { + 'name': 'r3s - Monheim/Rhein', + 'device_id': 22460, + 'interrupts': [ + { + 'name': 'Signal', + 'data': 'signal', + }, + ], + }, + { + 'name': 'franconian.net Livestream', + 'device_id': 246100657, + 'interrupts': [ + { + 'name': 'Signal', + 'data': 'signal', + }, + ], + }, + { + 'name': 'about:future stage', + 'device_id': 246100658, + 'interrupts': [ + { + 'name': 'Signal', + 'data': 'signal', + }, + ], + }, + { + 'name': 'Sendezentrum Bühne', + 'device_id': 246100659, + 'interrupts': [ + { + 'name': 'Signal', + 'data': 'signal', + }, + ], + }, + { + 'name': 'Haecksen Stream', + 'device_id': 246100660, + 'interrupts': [ + { + 'name': 'Signal', + 'data': 'signal', + }, + ], + }, + { + 'name': 'xHain Mainhall', + 'device_id': 246100661, + 'interrupts': [ + { + 'name': 'Signal', + 'data': 'signal', + }, + ], + }, + { + 'name': 'xHain Workshop-Area', + 'device_id': 246100662, + 'interrupts': [ + { + 'name': 'Signal', + 'data': 'signal', + }, + ], + }, + { + 'name': 'c-base', + 'device_id': 246100663, + 'interrupts': [ + { + 'name': 'Signal', + 'data': 'signal', + }, + ], + }, + { + 'name': 'about:future Kitchen', + 'device_id': 246100664, + 'interrupts': [ + { + 'name': 'Signal', + 'data': 'signal', + }, + ], + }, + { + 'name': 'Haecksen Zur schönen Mary', + 'device_id': 246100665, + 'interrupts': [ + { + 'name': 'Signal', + 'data': 'signal', + }, + ], + }, + { + 'name': 'Haecksen Zur magischen Margaret', + 'device_id': 246100666, + 'interrupts': [ + { + 'name': 'Signal', + 'data': 'signal', + }, + ], + }, + { + 'name': 'infobeamer stream', + 'device_id': 15586, + 'interrupts': [ + { + 'name': 'Signal', + 'data': 'signal', + }, + ], + }, + + ], + 'PORT': 8000, + 'WORKERS': 4, + 'unused': 'foobar', + }, + }, +} + +@metadata_reactor.provides( + 'nginx/vhosts', +) +def nginx(metadata): + if not node.has_bundle('nginx'): + raise DoNotRunAgain + + locations = { + '/': { + 'target': 'http://127.0.0.1:8000', + }, + '/sync': { + 'return': 'forbidden', + 'mode': 403, + }, + '/static': { + 'alias': '/opt/infobeamer-cms/static', + }, + } + + vhosts = { + 'infobeamer-cms': { + 'locations': locations, + 'website_check_path': '/', + 'website_check_string': '', + }, + } + + return { + 'nginx': { + 'vhosts': vhosts + }, + } diff --git a/bundles/letsencrypt/metadata.py b/bundles/letsencrypt/metadata.py index d5b6d1d..a36b58c 100644 --- a/bundles/letsencrypt/metadata.py +++ b/bundles/letsencrypt/metadata.py @@ -1,6 +1,11 @@ defaults = { 'apt': { 'packages': { + 'openssl': { + 'needed_by': { + 'action:letsencrypt_update_certificates', + }, + }, 'dehydrated': { 'needed_by': { 'action:letsencrypt_update_certificates', diff --git a/nodes/voc/infobeamer-cms.py b/nodes/voc/infobeamer-cms.py new file mode 100644 index 0000000..7062005 --- /dev/null +++ b/nodes/voc/infobeamer-cms.py @@ -0,0 +1,43 @@ +nodes['voc.infobeamer-cms'] = { + 'hostname': 'infobeamer-cms.c3voc.de', + 'bundles': { + 'infobeamer-cms', + 'redis', + }, + 'groups': { + 'debian-bullseye', + 'webserver', + }, + 'metadata': { + 'apt': { + # Move patchday to somewhere where the possibility of + # clashing with actual events is less likely. + 'unattended_upgrades': { + 'day': 1, + }, + }, + 'backups': { + 'exclude_from_backups': True, + }, + 'interfaces': { + 'ens18': { + 'ips': { + '185.106.84.31/26', + '2001:67c:20a0:e::31/64', + }, + 'gateway4': '185.106.84.1', + 'gateway6': '2001:67c:20a0:e::1', + }, + }, + 'icinga_options': { + 'pretty_name': 'infobeamer-cms.c3voc.de', + }, + 'nginx': { + 'vhosts': { + 'infobeamer-cms': { + 'domain': 'infobeamer-cms.c3voc.de', + }, + }, + }, + }, +}