Firmware

Die Firmware von Freifunk Südholstein basiert auf Gluon, wir verwenden dabei in der Regel keine Community-Packages, dadurch ist unsere Firmware sehr stabil und wir können stets auf dem neusten Stand bleiben.

Das site Repository findet man auf GitHub. Freifunk Südholstein hat drei update Kanäle, die regelmäßig bedient werden.

  • testing

  • rc

  • stable

Eine neue Firmware wird stets zuerst im testing Kanal verbreitet, wir haben nur wenige Knoten, welche den testing oder rc Kanal benutzen. Wir hoffen jedoch, dadurch zumindest grobe Probleme rechtzeitig zu entdecken.

Firmware Releases

Ein neuer Release beginnt in der Regel mit einem neuen Release von Gluon, dabei können Änderungen an der site Konfiguration nötig werden. Gelegentlich gibt es auch neue Features, ob diese per Update ausgerollt werden sollen wird dabei mit einer Folgen-Nutzen abschätzung Abgewegt. Sind die Risiken für Fehlfunktionen zu groß, so wird die Funktion zunächst nicht eingeführt.

Sobald die site config angepasst wurde, wird ein neuer git tag angelegt, die Version setzt sich dabei aus der Gluon-Version sowie einer extra Stelle für Änderungen von FFSH zusammen.

  • Gluon Release = 2020.2.3

  • FFSH Release = 0

  • FFSH+Gluon Release 2020.2.3.0

Durch die extra Stelle kann FFSH beliebig viele Releases auf Basis derselben Gluon-Version erstellen. Nachdem ein Release erfolgreich gebaut wurde, wird der Release signiert und per Webserver an die Knoten verteilt.

Dabei gilt die Reihenfolge testing, rc, stable. Nachdem die Knoten eines Kanals aktuallisiert wurden wird in der Regel etwa eine Woche gewartet bis die Firmware auf den folgenden Kanal ausgerollt wird. Aufgrund der geringen Anzahl an Knoten werden testing und rc gelegentlich parallel ausgerollt.

Firmware Pipeline

Für die Firmware Pipeline benutzt Freifunk Südholstein GitHub Actions, sowie abgewandelte Skripte vom Gluon Projekt.

Im site Repository gibt es ein actions Verzeichnis, dort liegen ein paar scripte.

  • generate-actions.py ist ein leicht abgewandeltes script vom Gluon Projekt, welches den GitHub Workflow generiert.

  • install-dependencies.sh installiert zusätzliche Pakete in dem Cointainer von GitHub.

  • run-build-local.sh kann zum bauen auf der lokalen maschine verwendet werden, je nach Bedaf anpassen, für die Fehlersuche gedacht.

  • run-build.sh ist das eigentliche build Skript, bei einem neuen release wird hier die Version angepasst.

Die vom generate-actions.py generierte build-gluon.yml Datei liegt in .github/workflows, das Skript muss in der Regel nur dann neu ausgeführt werden, wenn ein neuer Gluon Release ein target hinzufügt oder entfernt. Das Script muss angepasst werden, wenn es einen neuen major Release gibt z.B. 2020->2021, dann muss der tags liste ein neuer regex Ausdruck hinzugefügt werden.

Experimentell ist bisher der Workflow im release.yml, das Ziel ist es nach dem erfolgreichen Bauen der Firmware manuell einen Release auf GitHub anzulegen. Der Workflow soll dann über API ein Firmware Release-Archiv zusammenstellen und als Anhang an den Release beifügen.

Das Bauen der Firmware dauert aktuell etwas mehr als eine Stunde, wenn GitHub durchschnittlich ausgelastet ist. Sollte GitHub sich eines Tages dazu entscheiden, die Ressourcen zu verringern, gibt es die Möglichkeit einen self-hosted runner z.b. in der Hetzner Cloud zu installieren.

Lokal Bauen

Die Firmware kann auch lokal gebaut werden, dies ist vor allem nützlich, wenn man einen speziellen release erstellen möchte, oder zur Fehlersuche.

Dafür können natürlich ganz klassisch alle Abhängigkeiten installiert werden, Infos gibt es in der Gluon Dokumentation. Allerdings kann es dabei leicht zu Problemen kommen, alternativ liegt im site Repository ein Dockerfile.

docker build . --tag gluon
docker run --name gluon --mount type=bind,source=$(pwd),target=/gluon gluon

Site Repository

Das site Repository wird auf GitHub gehostet. Für jede neue major Version von Gluon wird ein neuer branch angelegt, der main branch wird dabei wenig benutzt.

Es gibt kein Changelog im Repository, auf freifunk-suedholstein.de sind alle Beiträge zur Firmware getagt und man kann einen schnellen Überblick über die Veränderungen bekommen.

Firmware Selector

Von Freifunk Darmstadt gibt es einen tollen Firmware-Selector, der die Auswahl der richtigen Firmware erleichtert.

https://github.com/freifunk-darmstadt/gluon-firmware-selector

git clone https://github.com/freifunk-darmstadt/gluon-firmware-selector.git firmware-selector

Zur Installation wird dieses Repository geklont und eine config.js Datei angelegt.

/*
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Affero General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU Affero General Public License for more details.
 *
 * You should have received a copy of the GNU Affero General Public License
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */

var config = {
  // list images on console that match no model
  listMissingImages: false,
  // see devices.js for different vendor model maps
  vendormodels: vendormodels,
  // set enabled categories of devices (see devices.js)
  enabled_device_categories: ["recommended","ath10k_lowmem","small_kernel_part","legacy_target","4_32","8_32","16_32"],
  // Display a checkbox that allows to display not recommended devices.
  // This only make sense if enabled_device_categories also contains not
  // recommended devices.
  recommended_toggle: true,
  // Optional link to an info page about no longer recommended devices
  recommended_info_link: 'https://freifunk-suedholstein.de/hardware/',
  // community prefix of the firmware images
  community_prefix: 'gluon-ffsh-',
  // firmware version regex
  version_regex: /-([\d]+\.[\d]+\.[\d]+([+-~][\d]+)?)[.-]/,
  // relative image paths and branch
  directories: {
    //'https://firmware.freifunk-suedholstein.de/dev/factory/': 'dev',
    //'https://firmware.freifunk-suedholstein.de/dev/sysupgrade/': 'dev',

    'https://firmware.freifunk-suedholstein.de/testing/factory/': 'testing',
    'https://firmware.freifunk-suedholstein.de/testing/sysupgrade/': 'testing',

    'https://firmware.freifunk-suedholstein.de/rc/factory/': 'rc',
    'https://firmware.freifunk-suedholstein.de/rc/sysupgrade/': 'rc',

    'https://firmware.freifunk-suedholstein.de/stable/factory/': 'stable',
    'https://firmware.freifunk-suedholstein.de/stable/sysupgrade/': 'stable',
  },
  // page title
  title: 'Firmware für Freifunk Südholstein',
  // branch descriptions shown during selection
  branch_descriptions: {
    // Bleibt super: Klar und für die Mehrheit
    stable: 'Empfohlen für Nutzer, die sich nicht näher mit der Firmware beschäftigen wollen und maximale Stabilität suchen.',
    // Guter Kompromiss: Stabil, aber für Tester, die Feedback geben wollen
    rc: 'Empfohlen für Nutzer, die eine stabile Vorabversion testen und bei Problemen Feedback geben wollen.',
    // Warnung vor möglichen Fehlern: Nur für aktive Entwickler/Tester
    testing: 'Enthält die neuesten Änderungen, aber auch mögliche Fehler. Empfohlen nur für aktive Tester, die Zeit für die Problembehebung haben.'
  },
  // recommended branch will be marked during selection
  recommended_branch: 'stable',
  // experimental branches (show a warning for these branches)
  experimental_branches: ['testing', 'rc'],
  // path to preview pictures directory
  preview_pictures: 'pictures/',
  // link to changelog
  changelog: 'https://freifunk-suedholstein.de/tag/firmware/'
};

Und natürlich muss auch eine passende Nginx Konfiguration angelegt werden.

server {
    listen 80;
    listen [::]:80;

    server_name install.freifunk-suedholstein.de;

    return 301 https://$host$request_uri;
}

server {
    listen 443 ssl http2;
    listen [::]:443 ssl http2;

    server_name install.freifunk-suedholstein.de;
    
    root /var/www/firmware-selector;
    index index.html;
    
    autoindex on;
    access_log off;    

    location = /favicon.ico {
        log_not_found off;
        access_log off;
    }

    location = /robots.txt {
        allow all;
        log_not_found off;
        access_log off;
    }
    
    location / {
        try_files $uri $uri/ =404;
    }

    location ~* \.(js|css|png|jpg|jpeg|gif|ico)$ {
        expires max;
        log_not_found off;
    }

    ssl_certificate /etc/letsencrypt/live/install.freifunk-suedholstein.de/fullchain.pem;
    ssl_certificate_key /etc/letsencrypt/live/install.freifunk-suedholstein.de/privkey.pem;
    ssl_session_timeout 1d;
    ssl_session_cache shared:SSL:50m;
    ssl_session_tickets off;

    ssl_dhparam /etc/nginx/dhparam.pem;

    ssl_protocols TLSv1.2 TLSv1.3;
    ssl_ciphers ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:DHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384;
    ssl_prefer_server_ciphers on;

    add_header Strict-Transport-Security max-age=15768000;

    ssl_stapling on;
    ssl_stapling_verify on;

}