xOTA is a platform to host temporary amateur radio activies that have similar mechanics as Islands on the Air (IOTA) or Parks on the Air (POTA). It has been used the first time at 37C3 in Hamburg in December 2023 as Toilets on the Air (TOTA).
This section describes the setup that was used for TOTA at 37C3. We used uberspace.de as a hoster and the instructions are geared towards hosting it on uberspace.
Create an uberspace account and follow the manual to SSH in.
wget https://download.swift.org/swift-5.10.1-release/centos7/swift-5.10.1-RELEASE/swift-5.10.1-RELEASE-centos7.tar.gz
mkdir Swift
cd Swift/
tar xzf ../swift-5.10.1-RELEASE-centos7.tar.gz
ln -s ~/Swift/swift-5.10.1-RELEASE-centos7/usr/bin/swift ~/bin/swift
Create a file at ~/Swift/fixincludes/unistd.h with the following contents:
#define HAS_PROBLEMATIC_UNISTD_H 1
// Below code is from https://github.com/nickhutchinson/libdispatch/blob/e1778632982b32e5156de888e54920d7ac848178/fixincludes/unistd.h
#ifndef DISPATCH_FIXINCLUDES_UNISTD_H_
#define DISPATCH_FIXINCLUDES_UNISTD_H_
/* The use of __block in some unistd.h files causes Clang to report an error.
* We work around the issue by forcibly undefining __block. See
* https://bugzilla.redhat.com/show_bug.cgi?id=1009623 */
#if HAS_PROBLEMATIC_UNISTD_H
#pragma push_macro("__block")
#undef __block
#define __block my__block
#include_next <unistd.h>
#pragma pop_macro("__block")
#else
#include_next <unistd.h>
#endif
#endif // DISPATCH_FIXINCLUDES_UNISTD_H_
Clone xOTA to your host, cd into the path and run:
swift build --configuration release -Xcc -I../Swift/fixincludes/
.build/release/xOTA_App --env configure migrate
Create ~/etc/services.d/tota-prod.ini with entried adjusted for your setup:
To enable Username+Passwort authentification add: USER_PASS_ENABLED=1 to the environment.
For CCC Hub auth add CCCHUB_DOMAIN, CCCHUB_CLIENT_ID, CCCHUB_CLIENT_SECRET, CCCHUB_AUTH_CALLBACK, CCCHUB_ME_API and CCCHUB_SCOPE to the environment.
For DARC auth add DARC_SSO_AUTH_CALLBACK, DARCSSO_CLIENT_ID, DARCSSO_CLIENT_SECRET environment.
To enable Awards (see awards section), add AWARDS_ENABLED=1 to the environment.
For enable add a dev instance indication add DEV=1 to the environment.
[program:tota-prod]
command=/home/tota/xOTA-prod/.build/release/xOTA_App serve --env production -p 8081 -H 0.0.0.0
directory=/home/tota/xOTA-prod/
startsecs=10
environment=CCCHUB_DOMAIN="events.ccc.de/congress/2025/hub/sso/",CCCHUB_CLIENT_ID="<redacted>",CCCHUB_CLIENT_SECRET="<redacted>",CCCHUB_AUTH_CALLBACK="https://38c3.totawatch.de/ccc-hub-auth-complete",CCCHUB_ME_API="https://api.events.ccc.de/congress/2024/me",CCCHUB_SCOPE="38c3_attendee",DARC_SSO_AUTH_CALLBACK="https://38c3.totawatch.de/darc-sso-auth-callback",DARCSSO_CLIENT_ID="<redacted>',DARCSSO_CLIENT_SECRET="<redacted>",AWARDS_ENABLED=1
stdout_logfile=/home/tota/logs/tota-prod/stdout.log
stderr_logfile=/home/tota/logs/tota-prod/stderr.log
Load and launcht the service:
supervisorctl reread
supervisorctl update
supervisorctl start tota-prod
Read the uberspace manual for more instructions.
Read the uberspace manuals on adding domains and configuring web backends to run point to the Swift server port.
The naming theme of programs can be changed in configure.swift.
The Leaf templates are in Resources/Views/ and need to be adjusted for your needs.
There is an admin interface available at /admin to create and update references and reset user passwords.
To make a user admin use .build/release/xOTA_App --env configure admin -c <CALLSIGN>, then user can then access the admin interface.
There is CCC Hub SSO authentification, DARC SSO as well as username + password authentification available as options.
Which authentification options are enabled can be configured in configure.swift.
Authentification is tied to the hub SSO endpoint that was reachable at events.ccc.de/congress/2024/hub/sso/. For future CCC events, the SSO endpoint needs to be adjusted in the environment.
Create an OAuth app in the CCC Hub Backoffice with Client type = Confidential, Authorization grant type = Authorization Code.
At 38c3 DARC SSO was offered for the first time. Set it up using the environment variables mentioned above. Only the admin can change the callback domain, there is no self-service.
Awards can be enabled by adding AWARDS_ENABLED=1 to the environment. The different award checkers create new award models and queue the award render jobs if a user is elegible for awards. The actual rendering happens in a separate script that is expected to be located at awards/award.sh
The template name is the award kind used in Sources/App/Services/AwardChecker.swift.
The thumbnails used in stats and on user profiles expect thumbnails of the awards to be placed in Public/awards/#(award.kind).jpg where #(award.kind) are the different award kinds.
Example rendering script:
#!/bin/sh
set -euo pipefail
if [ "$#" -ne 3 ]; then
echo Usage: $(basename $0) CALLSIGN TEMPLATENAME OUT_FILE
exit 1
fi
WORKING_DIR="$(dirname "$0")"
CALLSIGN="$1"
TEMPLATENAME="$2"
OUT_FILE="$3"
pushd "$WORKING_DIR"
echo "\\renewcommand{\\AwardCallsign}{${CALLSIGN}}" > award-options.tex
echo "\\renewcommand{\\AwardTemplate}{template/${TEMPLATENAME}}" >> award-options.tex
if [[ -n ${AWARD_DATE} ]]; then
echo "\\renewcommand{\\AwardDate}{${AWARD_DATE}}" >> award-options.tex
fi
pdflatex award.tex
popd
mkdir -p "$(dirname "$OUT_FILE")"
cp -f "$WORKING_DIR/award.pdf" "$OUT_FILE"