centos:ansible:ffmuc-rpb4-ol

Dies ist eine alte Version des Dokuments!


Bau eines Freifunk-Offloaders auf Basis eines Raspberry 4B

Bild: Freifunk München Logo

Bei größeren Installationen, wie z.B. in Flüchtlingsunterkünften, Wohnheimen, oder Veranstaltungen bzw. Veranstaltungsräumen gelangt man mit den gängigen Plasteroutern sehr schnell an deren Leistungsgrenzen. Die zeigt sich vor allem beim Datendurchsatz, da die in den Routern verbauten CPUs an ihre Grenzen kommen, da diese nicht für eine permanente Ver- und Entschlüsselung von großen Datenmengen ausgelegt sind.
In diesem Konfigurationsbeispiel wollen wir möglichst einfach und schnell einen Offloader für Freifunk München auf Basis eines Raspberry 4B befassen. Dabei gehen wir auf unterschiedliche Konfigurations-Optionen ein und wollen dennoch die Einstiegshürden für den ungeübteren Ansible und Linux-User möglichst tief ansetzen.

Als Basis für die Konfiguration setzen wir beim sehr gut dokumentierten Artikel von @awlnx aus dem Freifunk WIKI auf.
Nicht unerwähnt darf auch @lqb bleiben, der mit entscheidenden Tips zum Gelingen des Ansible-Playbooks beigetragen hat!

Inhalt

Das Kapitel hier ist in folgende Abschnitte strukturiert.

Wer also z.B. bereits einen SSH-Schlüssel sein eigen nennt oder Grundlagen zu Ansible bereits kennt und installiert hat, kann natürlich sofort beim Playbook bzw. dessen Ausführung einsteigen und die nachfolgenden Informationen überspringen.

Folgende Abschnitte beschreiben den eigentlichen Bau des Freifunk-Offloaders mit Ansible-Unterstützung und ist somit der ideale Einsprungpunkt für den versierten LINUX-Admin mit entsprechenden Ansible-Kenntnissen.:

Grundlegende Informationen rund um die SSH1) und deren Umgang bei der täglichen Arbeit finden sich im Kapitel Secure Shell hier im WIKI.

Damit wir selbst für spätere Administrationsaufgaben und auch unser Ansible-Admin-Host Verbindungen mit Hilfe der SSH2) zu unserem Offloader aufbauen kann, benötigen wir natürlich entsprechendes Schlüsselmaterial, abhängig vom jeweiligen Zielsystem bzw. den kryptographischen Eigenschaften.

Bei der Erstellung wollen wir statt einesRSA-Keys auf zeitgemäße und sicherere ed25519 Schlüssel verwenden. Ed25519 ist ein Elliptic Curve Signature Schema, welches beste Sicherheit bei vertretbaren Aufwand verspricht, als ECDSA oder DSA dies der Fall ist. Zur Auswahl sicherer kryptografischer Kurven bei der Elliptic-Curve Cryptography findet man auf der Seite hier hilfreiche Erklärungen und eine Gegenüberstellung der möglichen verschiedenen Alternativen. Weitere Infos zu den ED25519-Schlüsseln und der SSH finden sich im entsprechenden Kapitel hier im WIKI.

Wir erstellen uns nun einen ED25519-Schlüssel (-t), mit einer festen Schlüssellänge. Der Parameter (-a) beschreibt dabei die Anzahl der KDF-Schlüsselableitfunktion (siehe manpage von ssh-keygen). Wir verwenden als Beschreibung FFMUC Remote-User (-C) und als Ziel-/Speicherort ~/.ssh/id_ed25519_ffmuc (-f).

  $ ssh-keygen -t ed25519 -a 100 -C 'FFMUC Remote-User' -f ~/.ssh/id_ed25519_ffmuc
Generating public/private ed25519 key pair.
Enter passphrase (empty for no passphrase): 
Enter same passphrase again: 
Your identification has been saved in ~/.ssh/id_ed25519_ffmuc.
Your public key has been saved in ~/.ssh/id_ed25519_ffmuc.pub.
The key fingerprint is:
SHA256:jTZQUDbCqZaV64+Dj4n90+15+A+933K*fx3L4iUCBY3kKMQ FFMUC Remote-User
The key's randomart image is:
+--[ED25519 256]--+
|     o+==.oo     |
|     .E+ +.+.    |
|     ++.. = *    |
|    +..+ + O .   |
|   ...  S + o .  |
|     ... E *   . |
|      .oo o + + .|
|      .... . =E  |
|       .. + ooo  |
+----[SHA256]-----

Bild: Ansible Logo


Grundlegende Informationen zu Ansible und dessen Umgang bei der täglichen Arbeit finden sich im Kapitel Ansible hier im WIKI.

Je nach verwendeter Systemumgebung installieren wir nun das vom Paketmaintainer zur Verfügung gestellte RPM bzw. DEB Paket. Im Falle von RedHat basierenden Systemen wie CentOS oder Fedora benutzen wir das Paketverwaltungswerkzeug YUM/DNF oder im Falle von Debian und Ubuntu das Werkzeug APT.

  • RPM basierende Systeme:
     # dnf install ansible

    bzw.

     # yum install ansible
  • DEB basierende Systeme:
     # apt install ansible

    bzw. als eigeloggter User via sudo mit

     $ sudo apt install ansible

Verzeichnis-Struktur

Für unseren Admininstrationsuser legen wir uns zu erst einmal die passende Orderstruktur im Homeverzeichnis an.

 $ mkdir -p ~/ansible/{inventory,playbooks/templates/Raspbian}

Hieraus ergibt sich folgende Struktur:

ansible/
├── inventory
└── playbooks
    └── templates
        └── Raspbian

:GO:

Ansible-Konfigurationsdatei

Als nächstes kopieren wir uns die Vorlage-Konfiguratinsdatei aus dem Verzeichnis /etc/ansible/ in unser Homeverzeichnis.

 $ cp /etc/ansible/ansible.cfg ~/.ansible.cfg

Unter dem Konfigurationsgruppe [ defaults ] setzen wir den Parameter inventory = ~/ansible/inventory/hosts und interpreter_python = auto_silent. Beim ersten Parameter zeigen wir Ansible, wo die Host-Definitionen zu finden sind. beim Parameter interpreter_python geben wir an, dass keine Ausgabe zu den Angaben des Pfads zum Python-Interpreter auf dem Raspberry ausgegeben werden soll. Der Parameter connect_timeout definiert, wie lange eine persistente Verbindung bestehen darf, bevor diese hart getrennt wird. Weitere Information zu den Konfigurationsparametern finden sie in der Dokumentation der Konfigurationsoptionen zu Ansible.

 $ vim ~/.ansible.cfg

Im Ganzen ergibt sich dann hier die doch überschaubare Konfigurationsdatei zu Ansible.

 $ egrep -v '(^.*#|^$)' ~/.ansible.cfg 
[defaults]
inventory          = ~/ansible/inventory/hosts
interpreter_python = auto_silent
[inventory]
[privilege_escalation]
[paramiko_connection]
[ssh_connection]
[persistent_connection]
connect_timeout = 30
[accelerate]
[selinux]
[colors]
[diff]

:GO:

Host-Definitionsdatei

Ähnlich wie bereits auch schon die Konfigurationsdatei zu Ansible wird auch die Datei zur Hostdefinition sehr überschaubar bleiben. Auch hier kopieren wir uns die Vorlagedatei in unser Homeverzeichnis an Ort und Stelle.

 $ cp /etc/ansible/hosts ~/ansible/inventory/

Dort tragen wir den Namen ein, wie wir unseren Host später im Playbook ansprechen wollen. In diesem Konfigurationsbeispiel nutzen wir hier den Namen raspberry-ansible.

 $ vim ~/ansible/inventory/hosts

Somit ergibt sich auch hier eine sehr üersichtliche Konfigurationsdatei.

 $ egrep -v '(^.*#|^$)' ~/ansible/inventory/hosts
raspberry-ansible

:GO:

SSH Konfigurationsdatei

Damit wir unseren Raspberry auch direkt über den zuvor definierten Namen ansprechen können, definieren wir nun noch in unserer SSH-Konfigurationsdatei ~/.ssh/config des Clients diesen Host.

 $ vim ~/.ssh/config
Host raspberry-ansible
     Hostname 10.0.10.29
     Port 22
     User pi
     IdentitiesOnly=yes
     Protocol 2
     IdentityFile ~/.ssh/id_ed25519_ffmuc

Beim Parameter Hostname geben wir die IP-Adresse an, die unser DHCP-Server dem Raspberry verpasst an; in obigen Konfigurationsbeispiel hat unser Raspberry die IP-Adresse 10.0.10.29. Die Datei mit dem Eingangs erzeugten SSH-Schlüssel geben wir beim Parameter IdentityFile an.

Nun können wir uns „endlich“ daran machen unseren Offloader auf Basis eines Raspberry 4B zu bauen. Hierzu greifen wir auf folgendes Playbook zurück und laden es uns auf unseren Rechner.:

 $ wget \
       https://wiki.mailserver.guru/lib/exe/fetch.php/centos:ansible:ansible-playbook-ffmuc-offloader-auf_basis_raspberry-4b.v2.tar.gz \
       -O ansible-playbook-ffmuc-offloader-auf_basis_raspberry-4b.tar.gz

Anschließend entpacken wir es an Ort und Stelle.

 $ tar -xvf ansible-playbook-ffmuc-offloader-auf_basis_raspberry-4b.tar.gz

Somit ergibt sich folgende Verzeichnis- und Dateistruktur:

ansible
├── inventory
│   └── hosts
└── playbooks
    ├── raspi_offloader_file.yml
    ├── raspi_offloader_menu.yml
    └── templates
        └── Raspbian
            ├── bandwidth.j2
            ├── batman-adv.module.j2
            ├── config.j2
            ├── dkms.j2
            ├── ext-respondd_alias.json.j2
            ├── ext-respondd_config.json.j2
            ├── fastd.j2
            ├── hostapd.j2
            ├── hosts.j2
            ├── interfaces.j2
            ├── interfaces_client_ohne_mesh.j2
            ├── interfaces_mesh_mit_client.j2
            ├── interfaces_mesh_ohne_client.j2
            ├── oled-bandwidth.j2
            ├── rclocal_both.j2
            ├── rclocal_vxlan.j2
            └── rclocal_wifi.j2

Nachfolgend finden wir die Inhalte der einzelnen Dateien die im ansible-playbook enthalten sind:

raspi_offloader_file.yml

raspi_offloader_file.yml
--- ### Ansible Playbook für (statische) Konfiguration eines Offloader auf Basis eines Raspberry PI 4B
- name:         raspi_offloader_file.yml
  hosts:        raspberry-ansible
  become:       yes
  become_user:  root
 
  vars:
    fastd_ports:
      muc_cty:  30002
      muc_nord: 30003
      muc_ost:  30004
      muc_sued: 30005
      muc_west: 30006
      uml_nord: 30007
      uml_ost:  30008
      uml_sued: 30009
      uml_west: 30010
      gauting:  30012
      freising: 30013
      welt:     30011 
    vxlan_ids:
      muc_cty:  10758607
      muc_nord: 15521492
      muc_ost:  2948862
      muc_sued: 8599288
      muc_west: 7318933
      uml_nord: 5705961
      uml_ost:  4892713
      uml_sued: 16544703
      uml_west: 16677749
      gauting:  16175732
      freising: 12937858
      welt:     16306234
    batman_adv_version:   "2019.5" 
    ffmuc_segment:        "welt"
    raspberry_hostname:   "ff_django_rpb4_ansible"
    node_contact_address: "BOfH aka Django : django@nausch.org"
    raspberry_latitude:   "48.158542598"
    raspberry_longitude:  "11.769297123"
    raspberry_wifi:       "ja"
    raspberry_clientvlan: "333"
    raspberry_meshvlan:   "666"
    raspberry_oled:       "ja"
    dtparam:              "i2c_arm=on"
 
  tasks:
    - name: Hostname ändern
      shell: hostnamectl set-hostname {{ raspberry_hostname }}
 
    - name: Anpassung /etc/hosts
      template:
        src: Raspbian/hosts.j2
        dest: /etc/hosts
 
    - name: Beschreibung des User 'pi' anpassen
      user:
        name: pi
        comment: "Raspbian System User"
        state: present
 
    - name: Service rfkill am Raspberry deaktivieren
      shell: rfkill unblock wifi
 
    - name: Update und Upgrade der APT-Pakete
      apt:
        upgrade: dist
        update_cache: yes
 
    - name: Reboot nach update
      reboot:
 
    - name: Download des aktuellen BATMAN Archives 
      get_url:
        url: https://downloads.open-mesh.org/batman/releases/batman-adv-{{ batman_adv_version }}/batman-adv-{{ batman_adv_version }}.tar.gz
        dest: /usr/src/batman-adv-{{ batman_adv_version }}.tar.gz
        mode: '0644'
 
    - name: BATMAN-Archiv entpacken
      unarchive:
        src: /usr/src/batman-adv-{{ batman_adv_version }}.tar.gz
        dest: /usr/src
        remote_src: yes
 
    - name: Installation des Dynamic Kernel Module Support Framework und der Header Files für den Raspberry Pi Linux Kernel
      apt:
        update_cache: yes
        pkg:
          - dkms
          - raspberrypi-kernel-headers
        state: present
 
    - name: Rebuild BATMAN Kernel Header Dateien
      make:
        chdir: /usr/src/linux-headers-{{ ansible_kernel }}
        target: scripts
      ignore_errors: yes
 
    - name: Anlegen der dkms.conf für Dynamic Kernel Module Support
      template:
        src: Raspbian/dkms.j2
        dest: /usr/src/batman-adv-{{ batman_adv_version }}/dkms.conf
 
    - name: Dynamic Kernel Module Support hinzufügen
      #become: yes
      command: dkms add -m batman-adv -v {{ batman_adv_version }}
      register: ret
      failed_when: ret.rc != 0 and ret.rc != 3
      changed_when: ret.rc == 0
 
    - name: Dynamic Kernel Module Support bauen
      #become: yes
      command: dkms build -m batman-adv -v {{ batman_adv_version }}
 
    - name: Dynamic Kernel Module Support installieren
      #become: yes
      command: dkms install -m batman-adv -v {{batman_adv_version }}
 
    - name: Laden des Kernelmodul beim Booten veranlassen
      template:
        src: Raspbian/batman-adv.module.j2
        dest: /etc/modules-load.d/batman-adv.module.conf
 
    - name: Laden des BATMAN Moduls
      #become: yes
      modprobe:
        name: batman_adv
        state: present
 
    - name: Laden des dummy Moduls
      #become: yes
      modprobe:
        name: dummy
        state: present
 
    - name: Installation der  bridge-utils
      apt:
        update_cache: yes
        pkg:
         - batctl
         - bridge-utils
        state: present
 
    - name: Aktivierung von BATMAN_V
      shell: batctl ra BATMAN_V
 
    - name: Konfiguration des Interfaces
      template:
        src: Raspbian/interfaces.j2
        dest: /etc/network/interfaces
 
    - name: Installation von FASTD
      #become: yes
      apt:
        name: fastd
        state: present
 
    - name: Verzeichnis für fastd- Konfigurationsdatei anlegen
      file: 
        path: /etc/fastd/{{ ffmuc_segment }} 
        state: directory
 
    - name: Schlüssel für fastd erstellen
      shell: fastd --generate-key > /root/fastd.key
 
    - name: FASTD Secret Key aus /root/fastd.key in Variable übergeben
      shell: grep Secret /root/fastd.key | awk '{print substr($0,9)}' 
      register: secretkey_var
 
    - name: FASTD Socket ermitteln
      set_fact:
        ffmuc_fast_port: "{{ item.value }}"
      loop: "{{ lookup('dict', fastd_ports) }}"
      when: "ffmuc_segment in item.key"
 
    - name: Erstellen der fastd Konfigurationsdatei
      template:
        src: Raspbian/fastd.j2
        dest: /etc/fastd/{{ ffmuc_segment }}/fastd.conf
 
    - name: Service fastd beim Booten starten
      systemd:
        name: fastd@{{ ffmuc_segment }}
        state: started
        enabled: yes
 
    - name: Installation der Pakete git und python3-netifaces
      apt:
        update_cache: yes
        pkg:
          - git
          - python3-netifaces
        state: present
 
    - name: Repo ext-respondd klonen
      git:
        repo: https://github.com/freifunkMUC/ext-respondd 
        dest: /opt/ext-respondd/
 
    - name: Systemd Startdatei für respondd kopieren
      shell: cp /opt/ext-respondd/ext-respondd.service.example /etc/systemd/system/ext-respondd.service
 
    - name: Erstellen der resondd Konfigurationsdatei alias.json
      template:
        src: Raspbian/ext-respondd_alias.json.j2
        dest: /opt/ext-respondd/alias.json
 
    - name: Erstellen der resondd Konfigurationsdatei config.json
      template:
        src: Raspbian/ext-respondd_config.json.j2
        dest: /opt/ext-respondd/config.json
 
    - name: Service ext-respondd beim Booten starten
      systemd:
        name: ext-respondd
        daemon_reload: yes
        state: started
        enabled: yes
 
    - name: Paket hostapd für WLAN installieren
      apt:
        update_cache: yes
        pkg:
          - hostapd
        state: present
      when: ( raspberry_wifi == "ja" ) 
 
    - name: hostapd konfigurieren
      shell: echo 'DAEMON_OPTS="-d"' >> /etc/default/hostapd
      when: ( raspberry_wifi == "ja" )
 
    - name: hostapd Konfigurationsdatei anlegen  
      template:
        src: Raspbian/hostapd.j2 
        dest: /etc/hostapd/hostapd.conf 
      when: ( raspberry_wifi == "ja" )
 
    - name: wlan0 in Bridge packen
      template:
        src: Raspbian/rclocal_wifi.j2
        dest: /etc/rc.local
      when: ( raspberry_wifi == "ja" )
 
    - name: Service hostapd beim Booten und jetzt starten und das Laden der Unit Datei vom Service hostapd ermöglichen
      systemd:
        name: hostapd
        enabled: yes
        masked: no
        state: started
      when: ( raspberry_wifi == "ja" )
 
    - name: Konfiguration des Client-VLAN ohne Mesh-Netz
      template:
        src: Raspbian/interfaces_client_ohne_mesh.j2
        dest: /etc/network/interfaces 
      when: ( raspberry_clientvlan|length > 0 ) and ( raspberry_meshvlan|length == 0 )
 
    - name: vxlan_id für ausgewähltes Segment ermitteln
      set_fact:
        ffmuc_vxlan_id: "{{ item.value }}"
      loop: "{{ lookup('dict', vxlan_ids) }}"
      when: "ffmuc_segment in item.key"  
 
    - name: Konfiguration des Mesh-VLAN ohne Client-VLAN
      template:
        src: Raspbian/interfaces_mesh_ohne_client.j2
        dest: /etc/network/interfaces
      when: ( raspberry_clientvlan|length == 0 ) and ( raspberry_meshvlan|length > 0 )
 
    - name: Konfiguration von Mesh- und Client-VLAN
      template:
        src: Raspbian/interfaces_mesh_mit_client.j2
        dest: /etc/network/interfaces
      when: ( raspberry_clientvlan|length > 0 ) and ( raspberry_meshvlan|length > 0 )
 
    - name: Konfiguration des bevorzugte Meshingpoint in BATMAN_V ohne Wifi-Nutzung
      template:
        src: Raspbian/rclocal_vxlan.j2
        dest: /etc/rc.local
      when: ( raspberry_meshvlan|length > 0 ) and ( raspberry_wifi != "ja" )
 
    - name: Konfiguration des bevorzugte Meshingpoint in BATMAN_V mit Wifi-Nutzung
      template:
        src: Raspbian/rclocal_both.j2
        dest: /etc/rc.local
      when: ( raspberry_meshvlan|length > 0 ) and ( raspberry_wifi == "ja" )      
 
    - name: Für OLED-Konfiguration i2c-bcm2708 in /etc/modules eintragen
      shell: echo i2c-bcm2708 >> /etc/modules
      when: ( raspberry_oled == "ja" )
 
    - name: Für OLED-Konfiguration i2c-dev in /etc/modules eintragen
      shell: echo i2c-dev >> /etc/modules
      when: ( raspberry_oled == "ja" )
 
    - name: Installation der für das OLED benötigten Pakete
      apt:
        update_cache: yes
        pkg:
          - python3-dev 
          - python3-smbus 
          - i2c-tools 
          - python3-pil 
          - python3-pip 
          - python3-setuptools 
          - python3-rpi.gpio
          - git 
          - fonts-freefont-ttf
        state: present
      when: ( raspberry_oled == "ja" )
 
    - name: Laden des Kernelmodul i2c_arm beim Booten veranlassen
      template:
        src: Raspbian/config.j2
        dest: /boot/config.txt
      when: ( raspberry_oled == "ja" )
 
    - name: Reboot nach Konfigurationsänderung
      reboot:
      when: ( raspberry_oled == "ja" )
 
    - name: Repo Adafruit_Python_SSD1306 klonen
      git:
        repo: https://github.com/adafruit/Adafruit_Python_SSD1306.git
        dest: /usr/local/src/Adafruit_Python_SSD1306
      when: ( raspberry_oled == "ja" )
 
    - name: Für OLED-Konfiguration Adafruit_Python_SSD1306 installieren
      shell: cd /usr/local/src/Adafruit_Python_SSD1306 && python3 setup.py install
      when: ( raspberry_oled == "ja" )
 
    - name: Script zur Anzeige klonen
      git:
        repo: https://github.com/awlx/raspberry-oled-bandwidth
        dest: /usr/local/src/raspberry-oled-bandwidth
      when: ( raspberry_oled == "ja" )
 
    - name: Script zur Bandbreitenauslastung anpassen
      template:
        src: Raspbian/bandwidth.j2
        dest: /usr/local/src/raspberry-oled-bandwidth/bandwidth.py
      when: ( raspberry_oled == "ja" )
 
    - name: Startscript für das OLED anlegen
      template:
        src: Raspbian/oled-bandwidth.j2     
        dest: /etc/systemd/system/oled-bandwidth.service
      when: ( raspberry_oled == "ja" )
 
    - name: Service oled-bandwidth beim Booten starten
      systemd:
        name: oled-bandwidth
        daemon_reload: yes
        state: started
        enabled: yes
      when: ( raspberry_oled == "ja" )
 
    - name: Reboot nach Abschluss der Konfiguration unseres Offloaders
      reboot:
 
 
... #YAML Ende Syntax

raspi_offloader_menu.yml

raspi_offloader_menu.yml
--- ### Ansible Playbook für menügeführte Konfiguration eines Offloader auf Basis eines Raspberry PI 4B
- name:         raspi_offloader_menu.yml
  hosts:        raspberry-ansible
  become:       yes
  become_user:  root
 
  vars:
    fastd_ports:
      muc_cty:  30002
      muc_nord: 30003
      muc_ost:  30004
      muc_sued: 30005
      muc_west: 30006
      uml_nord: 30007
      uml_ost:  30008
      uml_sued: 30009
      uml_west: 30010
      gauting:  30012
      freising: 30013
      welt:     30011 
    vxlan_ids:
      muc_cty:  10758607
      muc_nord: 15521492
      muc_ost:  2948862
      muc_sued: 8599288
      muc_west: 7318933
      uml_nord: 5705961
      uml_ost:  4892713
      uml_sued: 16544703
      uml_west: 16677749
      gauting:  16175732
      freising: 12937858
      welt:     16306234
    dtparam:    "i2c_arm=on"
 
  vars_prompt:
    - name: batman_adv_version
      prompt: "\nWas ist die aktuelle BATMAN Version, die hier\nhttps://downloads.open-mesh.org/batman/releases/ gelistet ist?             "
      private: no
 
    - name: ffmuc_segment
      prompt: "\nIn welchem der Segmente hier soll der Offloader betrieben werden: \n                                                                  muc_cty \n                                                                  muc_nord \n                                                                  muc_ost \n                                                                  muc_sued \n                                                                  muc_west \n                                                                  uml_nord \n                                                                  uml_ost \n                                                                  uml_sued \n                                                                  uml_west \n                                                                  gauting \n                                                                  freising \n                                                                  welt     "
      private: no
 
    - name: raspberry_hostname
      prompt: "\nWie lautet der Hostname des Raspberry Offloaders?                          "
      private: no
 
    - name: node_contact_address
      prompt: "\nWie lautet die Kontakt-Adresse des Node-Betreibers?                        "
      private: no
 
    - name: raspberry_latitude
      prompt: "\nWie lautet der Geographische Breitengrad des Raspberry Offloaders?         "
      private: no
 
    - name: raspberry_longitude
      prompt: "\nWie lautet der Geographische Längengrad des Raspberry Offloaders?          "
      private: no
 
    - name: raspberry_wifi
      prompt: "\nSoll der Raspberry Offloader auch ein WLAN ausstrahlen, 'ja'?              " 
      private: no
 
    - name: raspberry_clientvlan
      prompt: "\nSoll der Raspberry Offloader ein Client-VLAN zur Verfügung stellen?\n                                   Wenn ja, wie lautet die VLAN-ID?        "
      private: no
 
    - name: raspberry_meshvlan
      prompt: "\nSoll der Raspberry Offloader ein Mesh-VLAN zur Verfügung stellen?\n                                   Wenn ja, wie lautet die VLAN-ID?        "
      private: no
 
    - name: raspberry_oled
      prompt: "\nIst ein OLE-Display an dem Raspberry Offloader angeschlossen?              "
      private: no
 
  tasks:
    - name: Hostname ändern
      shell: hostnamectl set-hostname {{ raspberry_hostname }}
 
    - name: Anpassung /etc/hosts
      template:
        src: Raspbian/hosts.j2
        dest: /etc/hosts
 
    - name: Beschreibung des User 'pi' anpassen
      user:
        name: pi
        comment: "Raspbian System User"
        state: present
 
    - name: Service rfkill am Raspberry deaktivieren
      shell: rfkill unblock wifi
 
    - name: Update und Upgrade der APT-Pakete
      apt:
        upgrade: dist
        update_cache: yes
 
    - name: Reboot nach update
      reboot:
 
    - name: Download des aktuellen BATMAN Archives 
      get_url:
        url: https://downloads.open-mesh.org/batman/releases/batman-adv-{{ batman_adv_version }}/batman-adv-{{ batman_adv_version }}.tar.gz
        dest: /usr/src/batman-adv-{{ batman_adv_version }}.tar.gz
        mode: '0644'
 
    - name: BATMAN-Archiv entpacken
      unarchive:
        src: /usr/src/batman-adv-{{ batman_adv_version }}.tar.gz
        dest: /usr/src
        remote_src: yes
 
    - name: Installation des Dynamic Kernel Module Support Framework und der Header Files für den Raspberry Pi Linux Kernel
      apt:
        update_cache: yes
        pkg:
          - dkms
          - raspberrypi-kernel-headers
        state: present
 
    - name: Rebuild BATMAN Kernel Header Dateien
      make:
        chdir: /usr/src/linux-headers-{{ ansible_kernel }}
        target: scripts
      ignore_errors: yes
 
    - name: Anlegen der dkms.conf für Dynamic Kernel Module Support
      template:
        src: Raspbian/dkms.j2
        dest: /usr/src/batman-adv-{{ batman_adv_version }}/dkms.conf
 
    - name: Dynamic Kernel Module Support hinzufügen
      #become: yes
      command: dkms add -m batman-adv -v {{ batman_adv_version }}
      register: ret
      failed_when: ret.rc != 0 and ret.rc != 3
      changed_when: ret.rc == 0
 
    - name: Dynamic Kernel Module Support bauen
      #become: yes
      command: dkms build -m batman-adv -v {{ batman_adv_version }}
 
    - name: Dynamic Kernel Module Support installieren
      #become: yes
      command: dkms install -m batman-adv -v {{batman_adv_version }}
 
    - name: Laden des Kernelmodul beim Booten veranlassen
      template:
        src: Raspbian/batman-adv.module.j2
        dest: /etc/modules-load.d/batman-adv.module.conf
 
    - name: Laden des BATMAN Moduls
      #become: yes
      modprobe:
        name: batman_adv
        state: present
 
    - name: Laden des dummy Moduls
      #become: yes
      modprobe:
        name: dummy
        state: present
 
    - name: Installation der  bridge-utils
      apt:
        update_cache: yes
        pkg:
         - batctl
         - bridge-utils
        state: present
 
    - name: Aktivierung von BATMAN_V
      shell: batctl ra BATMAN_V
 
    - name: Konfiguration des Interfaces
      template:
        src: Raspbian/interfaces.j2
        dest: /etc/network/interfaces
 
    - name: Installation von FASTD
      #become: yes
      apt:
        name: fastd
        state: present
 
    - name: Verzeichnis für fastd- Konfigurationsdatei anlegen
      file: 
        path: /etc/fastd/{{ ffmuc_segment }} 
        state: directory
 
    - name: Schlüssel für fastd erstellen
      shell: fastd --generate-key > /root/fastd.key
 
    - name: FASTD Secret Key aus /root/fastd.key in Variable übergeben
      shell: grep Secret /root/fastd.key | awk '{print substr($0,9)}' 
      register: secretkey_var
 
    - name: FASTD Socket ermitteln
      set_fact:
        ffmuc_fast_port: "{{ item.value }}"
      loop: "{{ lookup('dict', fastd_ports) }}"
      when: "ffmuc_segment in item.key"
 
    - name: Erstellen der fastd Konfigurationsdatei
      template:
        src: Raspbian/fastd.j2
        dest: /etc/fastd/{{ ffmuc_segment }}/fastd.conf
 
    - name: Service fastd beim Booten starten
      systemd:
        name: fastd@{{ ffmuc_segment }}
        state: started
        enabled: yes
 
    - name: Installation der Pakete git und python3-netifaces
      apt:
        update_cache: yes
        pkg:
          - git
          - python3-netifaces
        state: present
 
    - name: Repo ext-respondd klonen
      git:
        repo: https://github.com/freifunkMUC/ext-respondd 
        dest: /opt/ext-respondd/
 
    - name: Systemd Startdatei für respondd kopieren
      shell: cp /opt/ext-respondd/ext-respondd.service.example /etc/systemd/system/ext-respondd.service
 
    - name: Erstellen der resondd Konfigurationsdatei alias.json
      template:
        src: Raspbian/ext-respondd_alias.json.j2
        dest: /opt/ext-respondd/alias.json
 
    - name: Erstellen der resondd Konfigurationsdatei config.json
      template:
        src: Raspbian/ext-respondd_config.json.j2
        dest: /opt/ext-respondd/config.json
 
    - name: Service ext-respondd beim Booten starten
      systemd:
        name: ext-respondd
        daemon_reload: yes
        state: started
        enabled: yes
 
    - name: Paket hostapd für WLAN installieren
      apt:
        update_cache: yes
        pkg:
          - hostapd
        state: present
      when: ( raspberry_wifi == "ja" ) 
 
    - name: hostapd konfigurieren
      shell: echo 'DAEMON_OPTS="-d"' >> /etc/default/hostapd
      when: ( raspberry_wifi == "ja" )
 
    - name: hostapd Konfigurationsdatei anlegen  
      template:
        src: Raspbian/hostapd.j2 
        dest: /etc/hostapd/hostapd.conf 
      when: ( raspberry_wifi == "ja" )
 
    - name: wlan0 in Bridge packen
      template:
        src: Raspbian/rclocal_wifi.j2
        dest: /etc/rc.local
      when: ( raspberry_wifi == "ja" )
 
    - name: Service hostapd beim Booten und jetzt starten und das Laden der Unit Datei vom Service hostapd ermöglichen
      systemd:
        name: hostapd
        enabled: yes
        masked: no
        state: started
      when: ( raspberry_wifi == "ja" )
 
    - name: Konfiguration des Client-VLAN ohne Mesh-Netz
      template:
        src: Raspbian/interfaces_client_ohne_mesh.j2
        dest: /etc/network/interfaces 
      when: ( raspberry_clientvlan|length > 0 ) and ( raspberry_meshvlan|length == 0 )
 
    - name: vxlan_id für ausgewähltes Segment ermitteln
      set_fact:
        ffmuc_vxlan_id: "{{ item.value }}"
      loop: "{{ lookup('dict', vxlan_ids) }}"
      when: "ffmuc_segment in item.key"  
 
    - name: Konfiguration des Mesh-VLAN ohne Client-VLAN
      template:
        src: Raspbian/interfaces_mesh_ohne_client.j2
        dest: /etc/network/interfaces
      when: ( raspberry_clientvlan|length == 0 ) and ( raspberry_meshvlan|length > 0 )
 
    - name: Konfiguration von Mesh- und Client-VLAN
      template:
        src: Raspbian/interfaces_mesh_mit_client.j2
        dest: /etc/network/interfaces
      when: ( raspberry_clientvlan|length > 0 ) and ( raspberry_meshvlan|length > 0 )
 
    - name: Konfiguration des bevorzugte Meshingpoint in BATMAN_V ohne Wifi-Nutzung
      template:
        src: Raspbian/rclocal_vxlan.j2
        dest: /etc/rc.local
      when: ( raspberry_meshvlan|length > 0 ) and ( raspberry_wifi != "ja" )
 
    - name: Konfiguration des bevorzugte Meshingpoint in BATMAN_V mit Wifi-Nutzung
      template:
        src: Raspbian/rclocal_both.j2
        dest: /etc/rc.local
      when: ( raspberry_meshvlan|length > 0 ) and ( raspberry_wifi == "ja" )      
 
    - name: Für OLED-Konfiguration i2c-bcm2708 in /etc/modules eintragen
      shell: echo i2c-bcm2708 >> /etc/modules
      when: ( raspberry_oled == "ja" )
 
    - name: Für OLED-Konfiguration i2c-dev in /etc/modules eintragen
      shell: echo i2c-dev >> /etc/modules
      when: ( raspberry_oled == "ja" )
 
    - name: Installation der für das OLED benötigten Pakete
      apt:
        update_cache: yes
        pkg:
          - python3-dev 
          - python3-smbus 
          - i2c-tools 
          - python3-pil 
          - python3-pip 
          - python3-setuptools 
          - python3-rpi.gpio
          - git 
          - fonts-freefont-ttf
        state: present
      when: ( raspberry_oled == "ja" )
 
    - name: Laden des Kernelmodul i2c_arm beim Booten veranlassen
      template:
        src: Raspbian/config.j2
        dest: /boot/config.txt
      when: ( raspberry_oled == "ja" )
 
    - name: Reboot nach Konfigurationsänderung
      reboot:
      when: ( raspberry_oled == "ja" )
 
    - name: Repo Adafruit_Python_SSD1306 klonen
      git:
        repo: https://github.com/adafruit/Adafruit_Python_SSD1306.git
        dest: /usr/local/src/Adafruit_Python_SSD1306
      when: ( raspberry_oled == "ja" )
 
    - name: Für OLED-Konfiguration Adafruit_Python_SSD1306 installieren
      shell: cd /usr/local/src/Adafruit_Python_SSD1306 && python3 setup.py install
      when: ( raspberry_oled == "ja" )
 
    - name: Script zur Anzeige klonen
      git:
        repo: https://github.com/awlx/raspberry-oled-bandwidth
        dest: /usr/local/src/raspberry-oled-bandwidth
      when: ( raspberry_oled == "ja" )
 
    - name: Script zur Bandbreitenauslastung anpassen
      template:
        src: Raspbian/bandwidth.j2
        dest: /usr/local/src/raspberry-oled-bandwidth/bandwidth.py
      when: ( raspberry_oled == "ja" )
 
    - name: Startscript für das OLED anlegen
      template:
        src: Raspbian/oled-bandwidth.j2     
        dest: /etc/systemd/system/oled-bandwidth.service
      when: ( raspberry_oled == "ja" )
 
    - name: Service oled-bandwidth beim Booten starten
      systemd:
        name: oled-bandwidth
        daemon_reload: yes
        state: started
        enabled: yes
      when: ( raspberry_oled == "ja" )
 
    - name: Reboot nach Abschluss der Konfiguration unseres Offloaders
      reboot:
 
... #YAML Ende Syntax

bandwith.j2

bandwith.j2
#
# Inspired by https://github.com/DarrenBeck/rpi-oled-bandwidth and https://photochirp.com/r-pi/use-raspberry-pi-oled-bandwidth-monitor/
#
# Maintained by awlnx - aw@awlnx.space
#
 
import subprocess
import time
import re
import Adafruit_GPIO.SPI as SPI
import Adafruit_SSD1306
from PIL import Image
from PIL import ImageDraw
from PIL import ImageFont
import math
 
# Adjust to your needs
wifi = 'wlan0'
vpn = 'fastd-{{ ffmuc_segment }}'
batman = 'bat-{{ ffmuc_segment }}'
primary_mac = '{{ ansible_eth0.macaddress }}'
 
# We assume 100mbit/s max bandwidth
maxRateIn = 10000000
maxRateOut = 10000000
PImaxRateIn = 10000000
PImaxRateOut = 10000000
 
### DO NOT EDIT BELOW THIS POINT ###
 
# Raspberry Pi pin configuration:
RST = 24
 
# 128x64 display with hardware I2C:
disp = Adafruit_SSD1306.SSD1306_128_64(rst=RST)
 
# Initialize library.
disp.begin()
 
# Clear display.
disp.clear()
disp.display()
 
# Create blank image for drawing.
# Make sure to create image with mode '1' for 1-bit color.
width = disp.width
height = disp.height
image = Image.new('1', (width, height))
 
# Get drawing object to draw on image.
draw = ImageDraw.Draw(image)
 
font = ImageFont.truetype('/usr/share/fonts/truetype/freefont/FreeSans.ttf', 12)
fontsmall = ImageFont.truetype('/usr/share/fonts/truetype/freefont/FreeSans.ttf', 10)
fontverysmall = ImageFont.truetype('/usr/share/fonts/truetype/freefont/FreeSans.ttf', 8)
fontmedium = ImageFont.truetype('/usr/share/fonts/truetype/freefont/FreeSans.ttf', 12)
 
#Display Image
disp.image(image)
disp.display()
 
#Functions
 
def get_network_bytes(interface):
    for line in open('/proc/net/dev', 'r'):
        if interface in line:
            data = line.split('%s:' % interface)[1].split()
            rx_bytes, tx_bytes = (data[0], data[8])
            return (int(rx_bytes), int(tx_bytes))
 
def drawBar (x, barHeight):
    # parameters are x, y, end x, end y
    # draw.rectangle ((x, height - barHeight, x + 10, height -1), outline=255, fill=255)
    draw.rectangle ((x, 32 - barHeight, x + 8, height - 32), outline=255, fill=255)
 
def drawBarLOW (x, barLOWHeight):
        # parameters are x, y, end x, end y
        draw.rectangle ((x, 32 + barLOWHeight, x + 8, height - 32), outline=255, fill=255)
 
def textRate(rate):
    # rate -> raw bitrate
    # Returns: SI formatted bitrate
    if rate == 0:
        return "0B"
    rate = rate * 8
    size_name = (
        "b/s", "kb/s", "mb/s", "gb/s", "tb/s", "pb/s", "eb/s")
    i = int(math.floor(math.log(rate , 1024)))
    p = math.pow(1024, i)
    s = round(rate / p, 1)
    return "%s %s" % (s, size_name[i])
 
lastInBytes = get_network_bytes(vpn)[0];
lastOutBytes = get_network_bytes(vpn)[1];
lastPIInBytes = get_network_bytes(wifi)[0];
lastPIOutBytes = get_network_bytes(wifi)[1];
lastTime = time.time()
 
#timed array vars
timerTime = time.time()
highestSpeedIn = 0
highestSpeedOut = 0
PIhighestSpeedIn = 0
PIhighestSpeedOut = 0
speedArrayIn = []
speedArrayOut = []
PIspeedArrayIn = []
PIspeedArrayOut = []
inMax = 0
outMax = 0
PIinMax = 0
PIoutMax = 0
 
while (1):
    time.sleep(2)
    draw.rectangle((0, 0, width, height), outline=0, fill=0)
 
    now = time.time()
    elapsed = now - lastTime
    lastTime = now
 
    #calculate rates in and out
    inBytes = get_network_bytes(vpn)[0]
    currInBytes = (inBytes - lastInBytes) / elapsed
    lastInBytes = inBytes
 
    outBytes = get_network_bytes(vpn)[1]
    currOutBytes = (outBytes - lastOutBytes) / elapsed
    lastOutBytes = outBytes
 
    PIinBytes = get_network_bytes(wifi)[0]
    currPIInBytes = (PIinBytes - lastPIInBytes) / elapsed
    lastPIInBytes = PIinBytes
 
    PIoutBytes = get_network_bytes(wifi)[1]
    currPIOutBytes = (PIoutBytes - lastPIOutBytes) / elapsed
    lastPIOutBytes = PIoutBytes
 
 
    #max rate last 24 hours calculations
 
    if currInBytes > highestSpeedIn:
        highestSpeedIn = currInBytes
    if currOutBytes > highestSpeedOut:
        highestSpeedOut = currOutBytes
    if currPIInBytes > PIhighestSpeedIn:
        PIhighestSpeedIn = currPIInBytes
    if currPIOutBytes > PIhighestSpeedOut:
        PIhighestSpeedOut = currPIOutBytes
 
    if now > timerTime + 3600:
        print('-----------------------------------------------------------------  time expired')
        timerTime = now
 
        speedArrayIn.append (highestSpeedIn)
        if len (speedArrayIn) > 23:
            del speedArrayIn[0]
        inMax = max(speedArrayIn)
 
        speedArrayOut.append (highestSpeedOut)
        if len (speedArrayOut) > 23:
            del speedArrayOut[0]
        outMax = max(speedArrayOut)
 
        highestSpeedIn = 0
        highestSpeedOut = 0
 
        PIspeedArrayIn.append (PIhighestSpeedIn)
        if len (PIspeedArrayIn) > 23:
            del PIspeedArrayIn[0]
        PIinMax = max(PIspeedArrayIn)
 
        PIspeedArrayOut.append (PIhighestSpeedOut)
        if len (PIspeedArrayOut) > 23:
            del PIspeedArrayOut[0]
        PIoutMax = max(PIspeedArrayOut)
 
        PIhighestSpeedIn = 0
        PIhighestSpeedOut = 0
 
    #adjust these in each loop in case we find a faster speed
    inMax = max(inMax, highestSpeedIn)
    outMax = max(outMax, highestSpeedOut)
    PIinMax = max(PIinMax, PIhighestSpeedIn)
    PIoutMax = max(PIoutMax, PIhighestSpeedOut)
 
    #draw graph
    inHeight = 0.0
    outHeight = 0.0
    PIinHeight = 0.0
    PIoutHeight = 0.0
 
    if currInBytes > 0:
        inHeight = float(currInBytes / maxRateIn) * 32 
 
    if currOutBytes > 0:
        outHeight = float(currOutBytes / maxRateOut) * 32
 
    if currPIInBytes > 0:
        PIinHeight = float(currPIInBytes / PImaxRateIn) * 32
 
    if currPIOutBytes > 0:
        PIoutHeight = float(currPIOutBytes / PImaxRateOut) * 32
 
    drawBar (0, inHeight)
    drawBar (10, PIinHeight)
    drawBarLOW (0, outHeight)
    drawBarLOW (10, PIoutHeight)
    #write rates
    draw.text((26,38), textRate(currInBytes), font=font, fill=255)
    draw.text((26,50), textRate(currOutBytes), font=font, fill=255)
 
    draw.text((81,38), textRate(currPIInBytes), font=font, fill=255)
    draw.text((81,50), textRate(currPIOutBytes), font=font, fill=255)
 
    # Batman Clients
    clients = subprocess.check_output("batctl -m " + batman + " tl | egrep -v '(MainIF|" + primary_mac + ")' | egrep -o '([0-9A-Fa-f]{2}[:-]){5}([0-9A-Fa-f]{2})' | wc -l", shell=True).split().pop()
    draw.text((0,48), "Clients", font=fontverysmall, fill=255)
    draw.text((10,55), clients.decode("utf-8"), font=fontverysmall, fill=255)
 
    #max rates
    draw.text((36,0), "VPN", font=fontsmall, fill=255)
    draw.text((26,10), textRate(inMax), font=fontsmall, fill=255)
    draw.text((26,20), textRate(outMax), font=fontsmall, fill=255)
 
    draw.text((90,0), "Wifi", font=fontsmall, fill=255)
    draw.text((81,10), textRate(PIinMax), font=fontsmall, fill=255)
    draw.text((81,20), textRate(PIoutMax), font=fontsmall, fill=255)
 
    disp.image(image)
    disp.display()

batman-adv.module.j2

batman-adv.module.j2
#
# Load batman-adv module on system boot
#
batman-adv
dummy

config.j2

config.j2
# 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
# Django : 2019-09-11
# default: # dtparam=i2c_arm=on
dtparam=i2c_arm=on
#dtparam=i2s=on
#dtparam=spi=on
 
# Uncomment this to enable the lirc-rpi module
#dtoverlay=lirc-rpi
 
# Additional overlays and parameters are documented /boot/overlays/README
 
# Enable audio (loads snd_bcm2835)
dtparam=audio=on
 
[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

dkms.j2

dkms.j2
PACKAGE_NAME=batman-adv
PACKAGE_VERSION={{ batman_adv_version }}
 
DEST_MODULE_LOCATION=/extra
BUILT_MODULE_NAME=batman-adv
BUILT_MODULE_LOCATION=net/batman-adv
 
MAKE="'make'"
CLEAN="'make' clean"
 
AUTOINSTALL="yes"
[django@T410 Raspbian]$ 
[django@T410 Raspbian]$ 
[django@T410 Raspbian]$ 
[django@T410 Raspbian]$ 
[django@T410 Raspbian]$ cat dkms.j2 
PACKAGE_NAME=batman-adv
PACKAGE_VERSION={{ batman_adv_version }}
 
DEST_MODULE_LOCATION=/extra
BUILT_MODULE_NAME=batman-adv
BUILT_MODULE_LOCATION=net/batman-adv
 
MAKE="'make'"
CLEAN="'make' clean"
 
AUTOINSTALL="yes"

ext-respondd_alias.json.j2

ext-respondd_alias.json.j2
{
  "nodeinfo": {
    "hostname": "{{ raspberry_hostname }}",
    "hardware": {
      "model": "Raspberry Pi 4B"
    },
    "owner": {
      "contact": "{{ node_contact_address }}"
    },
    "system": {
      "site_code": "ffmuc_{{ ffmuc_segment }}",
      "role": "client"
    },
    "location": {
    "latitude": {{ raspberry_latitude }},
    "longitude": {{ raspberry_longitude }}
    }
  },
  "firstseen": "2019-08-14T12:34:56"
}

ext-respondd_config.json.j2

ext-respondd_config.json.j2
{
  "batman": "bat-{{ ffmuc_segment }}",
  "bridge": "br-{{ ffmuc_segment }}",
  "mesh-vpn": [ "fastd-{{ ffmuc_segment }}" ],
  "wan": "eth0",
  "rate_limit": 30,
  "rate_limit_burst": 10
}

fastd.j2

fastd.j2
#
# welt FASTd configuration
#
 
log to syslog level info;
 
interface "fastd-{{ ffmuc_segment }}";
 
method "salsa2012+umac";
method "null";
 
secret "{{ secretkey_var.stdout }}";
 
mtu 1406;
 
status socket "/var/run/fastd.{{ ffmuc_segment }}.sock";
 
on up "
        batctl ra BATMAN_V
        ip link set $INTERFACE down
        ip link set address $(ip -br l | grep eth0 | egrep -o '([0-9A-Fa-f]{2}[:-]){5}([0-9A-Fa-f]{2})' | head -1) dev $INTERFACE
        ip link set $INTERFACE up
        batctl -m bat-{{ ffmuc_segment }} if add $INTERFACE
 
";
 
on down "
        batctl -m bat-{{ ffmuc_segment }} if del $INTERFACE
";
peer group "ffmuc" {
        peer limit 1;
 
        peer "gw01.in.ffmuc.net" {
                key "e9e222c88de0613d7c2f2ca13b61e9146ca15c344b3d7ec55e0705f9fb730706";
                remote "gw01.ext.ffmuc.net" port {{ ffmuc_fast_port }};
        }
 
        peer "gw02.in.ffmuc.net" {
                key "9520145b940bc89358198918f4fb085b24280c3f9ac68600407395f89e856dcb";
                remote "gw02.ext.ffmuc.net" port {{ ffmuc_fast_port }};
        }
 
        peer "gw07.in.ffmuc.net" {
                key "845702d2d9c45f584f405cedb453d1fd61135273c08553156caf0cfa780c7b9a";
                remote "gw07.ext.ffmuc.net" port {{ ffmuc_fast_port }};
        }
}

hostapd.j2

hostapd.j2
ssid=muenchen.freifunk.net/{{ ffmuc_segment }}
 
country_code=US
 
interface=wlan0
driver=nl80211
 
macaddr_acl=0
 
logger_syslog=0
logger_syslog_level=4
logger_stdout=-1
logger_stdout_level=0
 
hw_mode=a
wmm_enabled=1
 
# N
ieee80211n=1
require_ht=1
ht_capab=[MAX-AMSDU-3839][HT40+][SHORT-GI-20][SHORT-GI-40][DSSS_CCK-40]
 
# AC
ieee80211ac=1
require_vht=1
ieee80211d=0
ieee80211h=0
vht_capab=[MAX-AMSDU-3839][SHORT-GI-80]
vht_oper_chwidth=1
channel=36
vht_oper_centr_freq_seg0_idx=42

hosts.j2

hosts.j2
127.0.0.1	localhost {{ raspberry_hostname }}
::1		localhost ip6-localhost ip6-loopback
ff02::1		ip6-allnodes
ff02::2		ip6-allrouters

interfaces_client_ohne_mesh.j2

interfaces_client_ohne_mesh.j2
# interfaces(5) file used by ifup(8) and ifdown(8)
 
# Please note that this file is written to be used with dhcpcd
# For static IP, consult /etc/dhcpcd.conf and 'man dhcpcd.conf'
 
# Include files from /etc/network/interfaces.d:
# source-directory /etc/network/interfaces.d
 
auto eth0
iface eth0 inet dhcp
 
auto eth0.{{ raspberry_clientvlan }}
iface eth0.{{ raspberry_clientvlan }} inet manual
 
auto br-{{ ffmuc_segment }}
iface br-{{ ffmuc_segment }} inet dhcp
        bridge-ports bat-{{ ffmuc_segment }} eth0.{{ raspberry_clientvlan }}
        pre-up /usr/sbin/batctl ra BATMAN_V
        pre-up /sbin/ip link add dummy-{{ ffmuc_segment }} type dummy
        pre-up /sbin/ip link set address $(ip -br l | grep eth0 | egrep -o '([0-9A-Fa-f]{2}[:-]){5}([0-9A-Fa-f]{2})' | head -1) dev dummy-{{ ffmuc_segment }}
        pre-up /sbin/ip link set dummy-{{ ffmuc_segment }} up
        pre-up /usr/sbin/batctl -m bat-{{ ffmuc_segment }} if add dummy-{{ ffmuc_segment }}
        pre-up /sbin/ip link set bat-{{ ffmuc_segment }} up
        pre-up /usr/sbin/batctl -m bat-{{ ffmuc_segment }} gw_mode client
        pre-up /sbin/ip link set address $(ip -br l | grep eth0 | egrep -o '([0-9A-Fa-f]{2}[:-]){5}([0-9A-Fa-f]{2})' | head -1) dev bat-{{ ffmuc_segment }}
        post-up /sbin/ip link set address $(ip -br l | grep eth0 | egrep -o '([0-9A-Fa-f]{2}[:-]){5}([0-9A-Fa-f]{2})' | head -1) dev br-{{ ffmuc_segment }}

interfaces.j2

interfaces.j2
# interfaces(5) file used by ifup(8) and ifdown(8)
 
# Please note that this file is written to be used with dhcpcd
# For static IP, consult /etc/dhcpcd.conf and 'man dhcpcd.conf'
 
# Include files from /etc/network/interfaces.d:
# source-directory /etc/network/interfaces.d
 
auto eth0
iface eth0 inet dhcp
 
auto br-{{ ffmuc_segment }}
iface br-{{ ffmuc_segment }} inet dhcp
        bridge-ports bat-{{ ffmuc_segment }}
        pre-up /usr/sbin/batctl ra BATMAN_V
        pre-up /sbin/ip link add dummy-{{ ffmuc_segment }} type dummy
        pre-up /sbin/ip link set address $(ip -br l | grep eth0 | egrep -o '([0-9A-Fa-f]{2}[:-]){5}([0-9A-Fa-f]{2})' | head -1) dev dummy-{{ ffmuc_segment }}
        pre-up /sbin/ip link set dummy-{{ ffmuc_segment }} up
        pre-up /usr/sbin/batctl -m bat-{{ ffmuc_segment }} if add dummy-{{ ffmuc_segment }}
        pre-up /sbin/ip link set bat-{{ ffmuc_segment }} up
        pre-up /usr/sbin/batctl -m bat-{{ ffmuc_segment }} gw_mode client
        pre-up /sbin/ip link set address $(ip -br l | grep eth0 | egrep -o '([0-9A-Fa-f]{2}[:-]){5}([0-9A-Fa-f]{2})' | head -1) dev bat-{{ ffmuc_segment }}
        post-up /sbin/ip link set address $(ip -br l | grep eth0 | egrep -o '([0-9A-Fa-f]{2}[:-]){5}([0-9A-Fa-f]{2})' | head -1) dev br-{{ ffmuc_segment }}

interfaces_mesh_mit_client.j2

interfaces_mesh_mit_client.j2
# interfaces(5) file used by ifup(8) and ifdown(8)
 
# Please note that this file is written to be used with dhcpcd
# For static IP, consult /etc/dhcpcd.conf and 'man dhcpcd.conf'
 
# Include files from /etc/network/interfaces.d:
# source-directory /etc/network/interfaces.d
 
auto eth0
iface eth0 inet dhcp
 
auto eth0.{{ raspberry_meshvlan }}
iface eth0.{{ raspberry_meshvlan }} inet manual
        pre-up /sbin/ip link add vxlan-mesh type vxlan id {{ ffmuc_vxlan_id }} group ff02::15c dstport 4789 port 32768 61000 no udpcsum udp6zerocsumtx udp6zerocsumrx dev eth0.{{ raspberry_meshvlan }} || true
        up /sbin/ip link set vxlan-mesh up
        post-up /usr/sbin/batctl ra BATMAN_V
        post-up /usr/sbin/batctl -m bat-{{ ffmuc_segment }} if add vxlan-mesh
        down ip link set vxlan-mesh down
        post-down ip link del vxlan-mesh || true
 
auto eth0.{{ raspberry_clientvlan }}
iface eth0.{{ raspberry_clientvlan }} inet manual
 
auto br-{{ ffmuc_segment }}
iface br-{{ ffmuc_segment }} inet dhcp
        bridge-ports bat-{{ ffmuc_segment }} eth0.{{ raspberry_clientvlan }}
        pre-up /usr/sbin/batctl ra BATMAN_V
        pre-up /sbin/ip link add dummy-{{ ffmuc_segment }} type dummy
        pre-up /sbin/ip link set address $(ip -br l | grep eth0 | egrep -o '([0-9A-Fa-f]{2}[:-]){5}([0-9A-Fa-f]{2})' | head -1) dev dummy-{{ ffmuc_segment }}
        pre-up /sbin/ip link set dummy-{{ ffmuc_segment }} up
        pre-up /usr/sbin/batctl -m bat-{{ ffmuc_segment }} if add dummy-{{ ffmuc_segment }}
        pre-up /sbin/ip link set bat-{{ ffmuc_segment }} up
        pre-up /usr/sbin/batctl -m bat-{{ ffmuc_segment }} gw_mode client
        pre-up /sbin/ip link set address $(ip -br l | grep eth0 | egrep -o '([0-9A-Fa-f]{2}[:-]){5}([0-9A-Fa-f]{2})' | head -1) dev bat-{{ ffmuc_segment }}
        post-up /sbin/ip link set address $(ip -br l | grep eth0 | egrep -o '([0-9A-Fa-f]{2}[:-]){5}([0-9A-Fa-f]{2})' | head -1) dev br-{{ ffmuc_segment }}

interfaces_mesh_ohne_client.j2

interfaces_mesh_ohne_client.j2
# interfaces(5) file used by ifup(8) and ifdown(8)
 
# Please note that this file is written to be used with dhcpcd
# For static IP, consult /etc/dhcpcd.conf and 'man dhcpcd.conf'
 
# Include files from /etc/network/interfaces.d:
# source-directory /etc/network/interfaces.d
 
auto eth0
iface eth0 inet dhcp
 
auto eth0.{{ raspberry_meshvlan }}
iface eth0.{{ raspberry_meshvlan }} inet manual
        pre-up /sbin/ip link add vxlan-mesh type vxlan id {{ ffmuc_vxlan_id }} group ff02::15c dstport 4789 port 32768 61000 no udpcsum udp6zerocsumtx udp6zerocsumrx dev eth0.{{ raspberry_meshvlan }} || true
        up /sbin/ip link set vxlan-mesh up
        post-up /usr/sbin/batctl ra BATMAN_V
        post-up /usr/sbin/batctl -m bat-{{ ffmuc_segment }} if add vxlan-mesh
        down ip link set vxlan-mesh down
        post-down ip link del vxlan-mesh || true
 
auto br-{{ ffmuc_segment }}
iface br-{{ ffmuc_segment }} inet dhcp
        bridge-ports bat-{{ ffmuc_segment }}
        pre-up /usr/sbin/batctl ra BATMAN_V
        pre-up /sbin/ip link add dummy-{{ ffmuc_segment }} type dummy
        pre-up /sbin/ip link set address $(ip -br l | grep eth0 | egrep -o '([0-9A-Fa-f]{2}[:-]){5}([0-9A-Fa-f]{2})' | head -1) dev dummy-{{ ffmuc_segment }}
        pre-up /sbin/ip link set dummy-{{ ffmuc_segment }} up
        pre-up /usr/sbin/batctl -m bat-{{ ffmuc_segment }} if add dummy-{{ ffmuc_segment }}
        pre-up /sbin/ip link set bat-{{ ffmuc_segment }} up
        pre-up /usr/sbin/batctl -m bat-{{ ffmuc_segment }} gw_mode client
        pre-up /sbin/ip link set address $(ip -br l | grep eth0 | egrep -o '([0-9A-Fa-f]{2}[:-]){5}([0-9A-Fa-f]{2})' | head -1) dev bat-{{ ffmuc_segment }}
        post-up /sbin/ip link set address $(ip -br l | grep eth0 | egrep -o '([0-9A-Fa-f]{2}[:-]){5}([0-9A-Fa-f]{2})' | head -1) dev br-{{ ffmuc_segment }}

oled-bandwidth.j2

oled-bandwidth.j2
# Django : 2019-09-11
[Unit]
After=network.target
 
[Service]
ExecStart=/usr/bin/python3 /usr/local/src/raspberry-oled-bandwidth/bandwidth.py
 
[Install]
WantedBy=default.target

rclocal_both.j2

rclocal_both.j2
#!/bin/sh -e
#
# rc.local
#
# This script is executed at the end of each multiuser runlevel.
# Make sure that the script will "exit 0" on success or any other
# value on error.
#
# In order to enable or disable this script just change the execution
# bits.
#
# By default this script does nothing.
 
# Print the IP address
_IP=$(hostname -I) || true
if [ "$_IP" ]; then
  printf "My IP address is %s\n" "$_IP"
fi
sleep 10; /sbin/brctl addif br-{{ ffmuc_segment }} wlan0
echo 1000000 > /sys/devices/virtual/net/vxlan-mesh/batman_adv/throughput_override
exit 0

rclocal_vxlan.j2

rclocal_vxlan.j2
#!/bin/sh -e
#
# rc.local
#
# This script is executed at the end of each multiuser runlevel.
# Make sure that the script will "exit 0" on success or any other
# value on error.
#
# In order to enable or disable this script just change the execution
# bits.
#
# By default this script does nothing.
 
# Print the IP address
_IP=$(hostname -I) || true
if [ "$_IP" ]; then
  printf "My IP address is %s\n" "$_IP"
fi
echo 1000000 > /sys/devices/virtual/net/vxlan-mesh/batman_adv/throughput_override
exit 0

rclocal_wifi.j2

rclocal_both.j2
#!/bin/sh -e
#
# rc.local
#
# This script is executed at the end of each multiuser runlevel.
# Make sure that the script will "exit 0" on success or any other
# value on error.
#
# In order to enable or disable this script just change the execution
# bits.
#
# By default this script does nothing.
 
# Print the IP address
_IP=$(hostname -I) || true
if [ "$_IP" ]; then
  printf "My IP address is %s\n" "$_IP"
fi
sleep 10; /sbin/brctl addif br-{{ ffmuc_segment }} wlan0
echo 1000000 > /sys/devices/virtual/net/vxlan-mesh/batman_adv/throughput_override
exit 0

Nachdem es aktuell5) noch kein fertiges Gluon Image für das Raspberry PI 4B gibt, holen wir uns nun das aktuelle Raspbian auf unseren Rechner. Dies hat mitunter auch noch den Charme, dass wir bei Bedarf alle normalen Anwendungen wie Webserver, Chatserver oder z.B. den Unifi-Controller einfach installieren können.

Eine Anleitung zur manuellen Installation findet man auf der offiziellen Raspbian Seite.

 $ wget https://downloads.raspberrypi.org/raspbian_lite_latest

Bevor wir nun das Archiv entpacken überprüfen wir noch die Integrität der heruntergeladenen Datei. Hierzu berechnen wir erst einmal die SHA256-Prüfsumme der Datei raspbian_lite_latest.

 $ sha256sum raspbian_lite_latest
12ae6e17bf95b6ba83beca61e7394e7411b45eba7e6a520f434b0748ea7370e8  raspbian_lite_latest

Die Zeichenfolge überprüfen wir nun mit den Angaben auf der Seite: https://www.raspberrypi.org/downloads/raspbian/ Bild: Bildschirmhardcopy der Seite www.raspberrypi.org/downloads/raspbian/ (Stand: 16.02.2020)

Da sich beide SHA-Werte nicht unterscheiden können wir das herunter geladene ZIP-Archiv nun entpacken.

 $ unzip raspbian_lite_latest
Archive:  raspbian_lite_latest
  inflating: 2020-02-13-raspbian-buster-lite.img  

:GO:

Nun können wir das Image auf die MicroSD Karte, die wir später in den Raspberry 4B stecken kopieren. Wir werfen also am besten einmal einen Blick in das syslog unseres Arbeitsrechners und erkennen so das Device unserer Speicherkarte.

 # tail -f /var/log/syslog
Feb 16 21:47:29 T410 kernel: usb 1-1.2: new high-speed USB device number 6 using ehci-pci
Feb 16 21:47:29 T410 kernel: usb 1-1.2: New USB device found, idVendor=1908, idProduct=0226, bcdDevice= 1.11
Feb 16 21:47:29 T410 kernel: usb 1-1.2: New USB device strings: Mfr=0, Product=0, SerialNumber=0
Feb 16 21:47:29 T410 kernel: usb-storage 1-1.2:1.0: USB Mass Storage device detected
Feb 16 21:47:29 T410 kernel: scsi host4: usb-storage 1-1.2:1.0
Feb 16 21:47:29 T410 mtp-probe[38884]: checking bus 1, device 6: "/sys/devices/pci0000:00/0000:00:1a.0/usb1/1-1/1-1.2"
Feb 16 21:47:29 T410 mtp-probe[38884]: bus: 1, device: 6 was not an MTP device
Feb 16 21:47:29 T410 mtp-probe[38887]: checking bus 1, device 6: "/sys/devices/pci0000:00/0000:00:1a.0/usb1/1-1/1-1.2"
Feb 16 21:47:29 T410 mtp-probe[38887]: bus: 1, device: 6 was not an MTP device
Feb 16 21:47:30 T410 kernel: scsi 4:0:0:0: Direct-Access     Generic  Mass-Storage     1.11 PQ: 0 ANSI: 2
Feb 16 21:47:30 T410 kernel: sd 4:0:0:0: Attached scsi generic sg2 type 0
Feb 16 21:47:30 T410 kernel: sd 4:0:0:0: [sdb] 62333952 512-byte logical blocks: (31.9 GB/29.7 GiB)
Feb 16 21:47:30 T410 kernel: sd 4:0:0:0: [sdb] Write Protect is off
Feb 16 21:47:30 T410 kernel: sd 4:0:0:0: [sdb] No Caching mode page found
Feb 16 21:47:30 T410 kernel: sd 4:0:0:0: [sdb] Assuming drive cache: write through
Feb 16 21:47:30 T410 kernel: sdb: sdb1 sdb2 < sdb5 >
Feb 16 21:47:30 T410 kernel: sd 4:0:0:0: [sdb] Attached SCSI removable disk
Feb 16 21:47:31 T410 kernel: EXT4-fs (sdb5): recovery complete
Feb 16 21:47:31 T410 kernel: EXT4-fs (sdb5): mounted filesystem with ordered data mode. Opts: (null)
Feb 16 21:47:31 T410 kernel: ext4 filesystem being mounted at /run/media/django/SETTINGS supports timestamps until 2038 (0x7fffffff)
Feb 16 21:47:31 T410 journal[1042]: Mounted /dev/sdb5 at /run/media/django/SETTINGS on behalf of uid 1000

In dem gezeigtem Fall handelt es sich also um die Gerätedatei /dev/sdb. Wir wissen also wie wir nun die zuvor heruntergeladene Debian Buster Image-Datei auf die MicroSD-Karte kopieren müssen. In der Regel hat der „normale Nutzer“ keine Rechte um diese Gerätedatei anzusprechen, wir müssen also als Benutzer root oder mir den Rechten des Benutzers root die Gerätedatei /dev/sdb in diesem Konfigurationsbeispiel ansprechen.

 # dd if=~/2020-02-13-raspbian-buster-lite.img of=/dev/sdb bs=4M status=progress conv=fsync

Da wir später weder Tastatur noch Monitor an unseren Raspberry 4B anstecken wollen, diesen demnach im headless-Mode betreiben wollen und werden, legen wir noch eine Datei /boot/ssh auf der SD-Karte ab. Nach dem erneuten Anstecken der MicroSD-Karte wir der Speicher in der Regel im Verzeichnis /run/media/ gemountet. Zum Anlagen der betreffenden Datei ssh in dem Verzeichnis reicht also folgender Aufruf:

 # touch /run/media/django/boot/ssh

Anschließend können wir nach einem unmounten des Gerätes /dev/sdb die Micro-SD-Karte in den Kartenslot des Raspberry 4B stecken und den Kleinstcomputer mit dem Netzwerk und dem zugehörigen Netzteil verbinden und starten.

:GO:

Der Benutzername lautet piund das Passwort raspberry. Das Passwort dieses Nutzers ändern wir nun als erstes ab, da sonst die Gefahr besteht, dass Fremde sich unseres Offloaders bemächtigen!

Wir ändern also das Default-Passwort gleich mal ab und packen auch unseren SSH-Public-key auf den Raspberry 4B. Da wir die IP-Adresse, die unser Raspberry vom DHCP-Server zugewiesen bekommt in unserer SSH-Client-Konfigurationsdatei bereits hinterlegt haben, können wir nun den RaspBerry 4B direkt über den definierten Namen raspberry-ansible ansprechen.

 $ ssh -l pi raspberry-ansible -o IdentitiesOnly=yes "passwd" && \
       ssh-copy-id -i ~/.ssh/id_ed25519_ffmuc.pub -o IdentitiesOnly=yes pi@raspberry-ansible

Alternativ dazu müssten wir den Raspberry 4B über die IP-Adresse ansprechen, die dieser zugewiesen bekommt. In dem folgenden Beispiel wäre das die IP-Adresse: 10.0.10.29:

 $ ssh -l pi 10.0.10.29 -o IdentitiesOnly=yes "passwd" && \
       ssh-copy-id -i ~/.ssh/id_ed25519_ffmuc.pub -o IdentitiesOnly=yes pi@10.0.10.29

In dem folgenden Konfigurationsbeispiel vergeben wir für den Benutzer pi das Passwort gECzebzn7GYSLvXueECAxeGm7l7. Beim Ändern des bestehenden Passwortes müssen wir einmal das Default-Passwort raspberry eingeben und dann 2x das neue gECzebzn7GYSLvXueECAxeGm7l7. Beim Kopieren des Public-Keys müssen wir dann einmalig das neue geänderte Passwort gECzebzn7GYSLvXueECAxeGm7l7 verwenden.

The authenticity of host 'raspberry-ansible (<no hostip for proxy command>)' can't be established.
ECDSA key fingerprint is SHA256:scR7cgECzebzn7GYSLvXueECAxeGm7l7Rp0fp4DHaUk.
Are you sure you want to continue connecting (yes/no/[fingerprint])? yes
Warning: Permanently added 'raspberry-ansible' (ECDSA) to the list of known hosts.
pi@raspberry-ansible's password: 
Current password: raspberry
New password: gECzebzn7GYSLvXueECAxeGm7l7
Retype new password: gECzebzn7GYSLvXueECAxeGm7l7
passwd: password updated successfully
Changing password for pi.

/usr/bin/ssh-copy-id: INFO: Source of key(s) to be installed: "~/.ssh/id_ed25519_ffmuc.pub"
/usr/bin/ssh-copy-id: INFO: attempting to log in with the new key(s), to filter out any that are already installed
/usr/bin/ssh-copy-id: INFO: 1 key(s) remain to be installed -- if you are prompted now it is to install the new keys
pi@raspberry-ansible's password: 

Number of key(s) added: 1

Now try logging into the machine, with:   "ssh -o 'IdentitiesOnly=yes' 'pi@raspberry-ansible'"
and check to make sure that only the key(s) you wanted were added.
 $ ssh raspberry-ansible 

Linux raspberrypi 4.19.97-v7l+ #1294 SMP Thu Jan 30 13:21:14 GMT 2020 armv7l

The programs included with the Debian GNU/Linux system are free software;
the exact distribution terms for each program are described in the
individual files in /usr/share/doc/*/copyright.

Debian GNU/Linux comes with ABSOLUTELY NO WARRANTY, to the extent
permitted by applicable law.

Wi-Fi is currently blocked by rfkill.
Use raspi-config to set the country before use.

pi@raspberrypi:~ $ 

:GO:

Beim Abarbeiten des ansible-playbook werden zur Konfiguration des Offloaders und dessen Komponenten/Dienste folgende Parameter benötigt:

  • Batman-Relase (Version) der zum Einsatz kommen soll.
  • Segment/Domäne in dem der Offloader betrieben werden soll
  • Angaben zur Freifunk Karte zur Darstellung
    • Hostname des Offloaders
    • Kontakt-Adresse des Node-Betreibers
    • Geographische Breitengrad des Raspberry Offloaders
    • Geographische Längengrad des Raspberry Offloaders
  • Funktionen, die der Raspberry Offloader noch ausführen soll:
    • Soll der Raspberry Offloader ein WLAN ausstrahlen (SSID leitet sich vom Segment-Namen ab)?
    • Soll der Raspberry Offloader ein Client-VLAN zur Verfügung stellen, wenn ja wie lautet die VLAN-ID?
    • Soll der Raspberry Offloader ein Mesh-VLAN zur Verfügung stellen, wenn ja wie lautet die VLAN-ID?
  • Ist an dem Raspberry ein OLE-Display von AZDelivery verbaut/angeschlossen?

Bei der Ausführung sind seit Version v2 6) zwei ansible-playbooks enthalten:

  1. raspi_offloader_menu.yml
    Hier werden die benötigten Parameter bei der Ausführung des ansible-playbooks interaktiv abgefragt. Somit ist eine Änderung/Bearbeitung des Playbooks nicht nötig und der ungeübtere Ansible-Nutzer kann sofort loslegen. Möchte man erneut den gleichen Raspberry neu betanken, weil z.B. die MicroSD-Karte getauscht werden musste, so muss man freilich die Informationen sich gesondert merken und bei einem abermaligen Aufruf erneut eingeben.

  2. raspi_offloader_file.yml
    Hier werden die zur Konfiguration benötigten Parameter nicht beim Aufruf des Playbooks abgefragt, sondern im playbook selbst hinterlegt. Das ist im ersten Schritt für den ungeübten Ansible-Nutzer zwar augenscheinlich aufwändiger, hat aber den Vorteil, dass man die zur Konfiguration benötigten Parameter immer sofort „zur Hand“ hat.
    In den Zeilen 34 bis 43 sind diese Parameter entsprechend zu hinterlegen.
     $ vim raspi_offloader_file.yml +34
     34     batman_adv_version:   "2019.5"
     35     ffmuc_segment:        "welt"
     36     raspberry_hostname:   "ff_django_rpb4_ansible"
     37     node_contact_address: "BOfH aka Django : django@nausch.org"
     38     raspberry_latitude:   "48.158542598"
     39     raspberry_longitude:  "11.769297123"
     40     raspberry_wifi:       "ja"
     41     raspberry_clientvlan: "333"
     42     raspberry_meshvlan:   "666"
     43     raspberry_oled:       "ja"

Bsp. 1 : raspi_offloader_menu.yml

Am besten besorgen wir uns die entsprechenden Daten vorab und halten diese parat, da diese nach dem Start des ansible-playbooks abgefragt werden.

Haben wir die Informationen vorrätig, bleibt uns zum Schluss nur noch der Aufruf des Ansible-Scriptes.

 $ ansible-playbook ~/ansible/playbooks/raspi_offloader_menu.yml


Was ist die aktuelle BATMAN Version, die hier
https://downloads.open-mesh.org/batman/releases/ gelistet ist?             : 2019.5

In welchem der Segmente hier soll der Offloader betrieben werden: 
                                                                  muc_cty 
                                                                  muc_nord 
                                                                  muc_ost 
                                                                  muc_sued 
                                                                  muc_west 
                                                                  uml_nord 
                                                                  uml_ost 
                                                                  uml_sued 
                                                                  uml_west 
                                                                  gauting 
                                                                  freising 
                                                                  welt     : welt

Wie lautet der Hostname des Raspberry Offloaders?                          : raspi-offloader

Wie lautet die Kontakt-Adresse des Node-Betreibers?                        : Django aka BOFH - django@nausch.org

Wie lautet der Geographische Breitengrad des Raspberry Offloaders?         : 48.198105

Wie lautet der Geographische Längengrad des Raspberry Offloaders?          : 11.798415

Soll der Raspberry Offloader auch ein WLAN ausstrahlen, 'ja'?              : ja

Soll der Raspberry Offloader ein Client-VLAN zur Verfügung stellen?
                                   Wenn ja, wie lautet die VLAN-ID?        : 333

Soll der Raspberry Offloader ein Mesh-VLAN zur Verfügung stellen?
                                   Wenn ja, wie lautet die VLAN-ID?        : 666

Ist ein OLE-Display an dem Raspberry Offloader angeschlossen?              : ja

PLAY [raspi_offloader.yml] *************************************************************************************************************

TASK [Gathering Facts] *****************************************************************************************************************
ok: [raspi_offloader_menu]

TASK [Hostname ändern] *****************************************************************************************************************
changed: [raspi_offloader_menu]

TASK [Anpassung /etc/hosts] ************************************************************************************************************
changed: [raspi_offloader_menu]

TASK [Beschreibung des User 'pi' anpassen] *********************************************************************************************
changed: [raspi_offloader_menu]

TASK [Service rfkill am Raspberry deaktivieren] ****************************************************************************************
changed: [raspi_offloader_menu]

TASK [Update und Upgrade der APT-Pakete] ***********************************************************************************************
[WARNING]: Updating cache and auto-installing missing dependency: python-apt
changed: [raspi_offloader_menu]

TASK [Reboot nach update] **************************************************************************************************************
changed: [raspi_offloader_menu]

TASK [Download des aktuellen BATMAN Archives] ******************************************************************************************
changed: [raspi_offloader_menu]

TASK [BATMAN-Archiv entpacken] *********************************************************************************************************
changed: [raspi_offloader_menu]

TASK [Installation des Dynamic Kernel Module Support Framework und der Header Files für den Raspberry Pi Linux Kernel] *****************
changed: [raspi_offloader_menu]

TASK [Rebuild BATMAN Kernel Header Dateien] ********************************************************************************************

fatal: [raspi_offloader_menu]: FAILED! => {"changed": false, "cmd": "/usr/bin/make scripts", "msg": "scripts/sortextable.c:31:10: fatal error: tools/be_byteshift.h: No such file or directory\n #include \n          ^~~~~~~~~~~~~~~~~~~~~~\ncompilation terminated.\nmake[1]: *** [scripts/Makefile.host:90: scripts/sortextable] Error 1\nmake: *** [Makefile:1067: scripts] Error 2", "rc": 2, "stderr": "scripts/sortextable.c:31:10: fatal error: tools/be_byteshift.h: No such file or directory\n #include \n          ^~~~~~~~~~~~~~~~~~~~~~\ncompilation terminated.\nmake[1]: *** [scripts/Makefile.host:90: scripts/sortextable] Error 1\nmake: *** [Makefile:1067: scripts] Error 2\n", "stderr_lines": ["scripts/sortextable.c:31:10: fatal error: tools/be_byteshift.h: No such file or directory", " #include ", "          ^~~~~~~~~~~~~~~~~~~~~~", "compilation terminated.", "make[1]: *** [scripts/Makefile.host:90: scripts/sortextable] Error 1", "make: *** [Makefile:1067: scripts] Error 2"], "stdout": "  CC      scripts/mod/empty.o\n  MKELF   scripts/mod/elfconfig.h\n  HOSTCC  scripts/mod/modpost.o\n  CC      scripts/mod/devicetable-offsets.s\n  HOSTCC  scripts/mod/file2alias.o\n  HOSTCC  scripts/mod/sumversion.o\n  HOSTLD  scripts/mod/modpost\n  HOSTCC  scripts/sortextable\n", "stdout_lines": ["  CC      scripts/mod/empty.o", "  MKELF   scripts/mod/elfconfig.h", "  HOSTCC  scripts/mod/modpost.o", "  CC      scripts/mod/devicetable-offsets.s", "  HOSTCC  scripts/mod/file2alias.o", "  HOSTCC  scripts/mod/sumversion.o", "  HOSTLD  scripts/mod/modpost", "  HOSTCC  scripts/sortextable"]}
...ignoring

TASK [Anlegen der dkms.conf für Dynamic Kernel Module Support] *************************************************************************
changed: [raspi_offloader_menu]

TASK [Dynamic Kernel Module Support hinzufügen] ****************************************************************************************
changed: [raspi_offloader_menu]

TASK [Dynamic Kernel Module Support bauen] *********************************************************************************************
changed: [raspi_offloader_menu]

TASK [Dynamic Kernel Module Support installieren] **************************************************************************************
changed: [raspi_offloader_menu]

TASK [Laden des Kernelmodul beim Booten veranlassen] ***********************************************************************************
changed: [raspi_offloader_menu]

TASK [Laden des BATMAN Moduls] *********************************************************************************************************
changed: [raspi_offloader_menu]

TASK [Laden des dummy Moduls] **********************************************************************************************************
changed: [raspi_offloader_menu]

TASK [Installation der  bridge-utils] **************************************************************************************************
changed: [raspi_offloader_menu]

TASK [Aktivierung von BATMAN_V] ********************************************************************************************************
changed: [raspi_offloader_menu]

TASK [Konfiguration des Interfaces] ****************************************************************************************************
changed: [raspi_offloader_menu]

TASK [Installation von FASTD] **********************************************************************************************************
changed: [raspi_offloader_menu]

TASK [Verzeichnis für fastd- Konfigurationsdatei anlegen] ******************************************************************************
changed: [raspi_offloader_menu]

TASK [Schlüssel für fastd erstellen] ***************************************************************************************************
changed: [raspi_offloader_menu]

TASK [FASTD Secret Key aus /root/fastd.key in Variable übergeben] **********************************************************************
changed: [raspi_offloader_menu]

TASK [FASTD Socket ermitteln] **********************************************************************************************************
skipping: [raspi_offloader_menu] => (item={'key': 'muc_cty', 'value': 30002}) 
skipping: [raspi_offloader_menu] => (item={'key': 'muc_nord', 'value': 30003}) 
skipping: [raspi_offloader_menu] => (item={'key': 'muc_ost', 'value': 30004}) 
skipping: [raspi_offloader_menu] => (item={'key': 'muc_sued', 'value': 30005}) 
skipping: [raspi_offloader_menu] => (item={'key': 'muc_west', 'value': 30006}) 
skipping: [raspi_offloader_menu] => (item={'key': 'uml_nord', 'value': 30007}) 
skipping: [raspi_offloader_menu] => (item={'key': 'uml_ost', 'value': 30008}) 
skipping: [raspi_offloader_menu] => (item={'key': 'uml_sued', 'value': 30009}) 
skipping: [raspi_offloader_menu] => (item={'key': 'uml_west', 'value': 30010}) 
skipping: [raspi_offloader_menu] => (item={'key': 'gauting', 'value': 30012}) 
skipping: [raspi_offloader_menu] => (item={'key': 'freising', 'value': 30013})
ok: [raspi_offloader_menu] => (item={'key': 'welt', 'value': 30011})

TASK [Erstellen der fastd Konfigurationsdatei] *****************************************************************************************
changed: [raspi_offloader_menu]

TASK [Service fastd beim Booten starten] ***********************************************************************************************
changed: [raspi_offloader_menu]

TASK [Installation der Pakete git und python3-netifaces] *******************************************************************************
changed: [raspi_offloader_menu]

TASK [Repo ext-respondd klonen] ********************************************************************************************************
changed: [raspi_offloader_menu]

TASK [Systemd Startdatei für respondd kopieren] ****************************************************************************************
changed: [raspi_offloader_menu]

TASK [Erstellen der resondd Konfigurationsdatei alias.json] ****************************************************************************
changed: [raspi_offloader_menu]

TASK [Erstellen der resondd Konfigurationsdatei config.json] ***************************************************************************
changed: [raspi_offloader_menu]

TASK [Service ext-respondd beim Booten starten] ****************************************************************************************
changed: [raspi_offloader_menu]

TASK [Paket hostapd für WLAN installieren] *********************************************************************************************
changed: [raspi_offloader_menu]

TASK [hostapd konfigurieren] ***********************************************************************************************************
changed: [raspi_offloader_menu]

TASK [hostapd Konfigurationsdatei anlegen] *********************************************************************************************
changed: [raspi_offloader_menu]

TASK [wlan0 in Bridge packen] **********************************************************************************************************
changed: [raspi_offloader_menu]

TASK [Service hostapd beim Booten und jetzt starten und das Laden der Unit Datei vom Service hostapd ermöglichen] **********************
changed: [raspi_offloader_menu]

TASK [Konfiguration des Client-VLAN ohne Mesh-Netz] ************************************************************************************
skipping: [raspi_offloader_menu]

TASK [vxlan_id für ausgewähltes Segment ermitteln] *************************************************************************************
skipping: [raspi_offloader_menu] => (item={'key': 'muc_cty', 'value': 10758607}) 
skipping: [raspi_offloader_menu] => (item={'key': 'muc_nord', 'value': 15521492}) 
skipping: [raspi_offloader_menu] => (item={'key': 'muc_ost', 'value': 2948862}) 
skipping: [raspi_offloader_menu] => (item={'key': 'muc_sued', 'value': 8599288}) 
skipping: [raspi_offloader_menu] => (item={'key': 'muc_west', 'value': 7318933}) 
skipping: [raspi_offloader_menu] => (item={'key': 'uml_nord', 'value': 5705961}) 
skipping: [raspi_offloader_menu] => (item={'key': 'uml_ost', 'value': 4892713}) 
skipping: [raspi_offloader_menu] => (item={'key': 'uml_sued', 'value': 16544703}) 
skipping: [raspi_offloader_menu] => (item={'key': 'uml_west', 'value': 16677749}) 
skipping: [raspi_offloader_menu] => (item={'key': 'gauting', 'value': 16175732}) 
skipping: [raspi_offloader_menu] => (item={'key': 'freising', 'value': 12937858})
ok: [raspi_offloader_menu] => (item={'key': 'welt', 'value': 16306234})

TASK [Konfiguration des Mesh-VLAN ohne Client-VLAN] ************************************************************************************
skipping: [raspi_offloader_menu]

TASK [Konfiguration von Mesh- und Client-VLAN] *****************************************************************************************
changed: [raspi_offloader_menu]

TASK [Konfiguration des bevorzugte Meshingpoint in BATMAN_V ohne Wifi-Nutzung] *********************************************************
skipping: [raspi_offloader_menu]

TASK [Konfiguration des bevorzugte Meshingpoint in BATMAN_V mit Wifi-Nutzung] **********************************************************
changed: [raspi_offloader_menu]

TASK [Für OLED-Konfiguration i2c-bcm2708 in /etc/modules eintragen] ********************************************************************
changed: [raspi_offloader_menu]

TASK [Für OLED-Konfiguration i2c-dev in /etc/modules eintragen] ************************************************************************
changed: [raspi_offloader_menu]

TASK [Installation der für das OLED benötigten Pakete] *********************************************************************************
changed: [raspi_offloader_menu]

TASK [Laden des Kernelmodul i2c_arm beim Booten veranlassen] ***************************************************************************
changed: [raspi_offloader_menu]

TASK [Reboot nach Konfigurationsänderung] **********************************************************************************************
changed: [raspi_offloader_menu]

TASK [Repo Adafruit_Python_SSD1306 klonen] *********************************************************************************************
changed: [raspi_offloader_menu]

TASK [Für OLED-Konfiguration Adafruit_Python_SSD1306 installieren] *********************************************************************
changed: [raspi_offloader_menu]

TASK [Script zur Anzeige klonen] *******************************************************************************************************
changed: [raspi_offloader_menu]

TASK [Script zur Bandbreitenauslastung anpassen] ***************************************************************************************
changed: [raspi_offloader_menu]

TASK [Startscript für das OLED anlegen] ************************************************************************************************
changed: [raspi_offloader_menu]

TASK [Service oled-bandwidth beim Booten starten] **************************************************************************************
changed: [raspi_offloader_menu]

TASK [Reboot nach Abschluss der Konfiguration unseres Offloaders] **********************************************************************
changed: [raspi_offloader_menu]

PLAY RECAP *****************************************************************************************************************************
raspi_offloader_menu          : ok=54   changed=50   unreachable=0    failed=0    skipped=3    rescued=0    ignored=1

Nach dem letzten Reboot, der automatisch ausgeführt wird, finden wir unseren Offloader auf der Freifunkkarte:

Bild: Ausschnitt aus der Freifunk Karte

Bsp. 2 : raspi_offloader_file.yml

Falls noch nicht geschehen, ist es vor dem Aufruf des ansible-Playbooks notwendig, die Konfigurationsparameter in den Zeilen 34 bis 43des Raspberry 4B Offloaders im playbook direkt zu hinterlegen.

 $ vim raspi_offloader_file.yml +34
 34     batman_adv_version:   "2019.5"
 35     ffmuc_segment:        "welt"
 36     raspberry_hostname:   "ff_ansible_demo"
 37     node_contact_address: "BOfH aka Django : django@nausch.org"
 38     raspberry_latitude:   "48.158542598"
 39     raspberry_longitude:  "11.769297123"
 40     raspberry_wifi:       "ja"
 41     raspberry_clientvlan: "333"
 42     raspberry_meshvlan:   "666"
 43     raspberry_oled:       "ja"

Haben wir die Informationen in dem Ansible-Playbook hinterlegt, können wir wie geohnt das Ansible-Scriptes ausführen.

 $ ansible-playbook ~/ansible/playbooks/raspi_offloader_file.yml


PLAY [raspi_offloader.yml] *************************************************************************************************************

TASK [Gathering Facts] *****************************************************************************************************************
ok: [raspi_offloader_file]

TASK [Hostname ändern] *****************************************************************************************************************
changed: [raspi_offloader_file]

TASK [Anpassung /etc/hosts] ************************************************************************************************************
changed: [raspi_offloader_file]

TASK [Beschreibung des User 'pi' anpassen] *********************************************************************************************
changed: [raspi_offloader_file]

TASK [Service rfkill am Raspberry deaktivieren] ****************************************************************************************
changed: [raspi_offloader_file]

TASK [Update und Upgrade der APT-Pakete] ***********************************************************************************************
[WARNING]: Updating cache and auto-installing missing dependency: python-apt
changed: [raspi_offloader_file]

TASK [Reboot nach update] **************************************************************************************************************
changed: [raspi_offloader_file]

TASK [Download des aktuellen BATMAN Archives] ******************************************************************************************
changed: [raspi_offloader_file]

TASK [BATMAN-Archiv entpacken] *********************************************************************************************************
changed: [raspi_offloader_file]

TASK [Installation des Dynamic Kernel Module Support Framework und der Header Files für den Raspberry Pi Linux Kernel] *****************
changed: [raspi_offloader_file]

TASK [Rebuild BATMAN Kernel Header Dateien] ********************************************************************************************

fatal: [raspi_offloader_file]: FAILED! => {"changed": false, "cmd": "/usr/bin/make scripts", "msg": "scripts/sortextable.c:31:10: fatal error: tools/be_byteshift.h: No such file or directory\n #include \n          ^~~~~~~~~~~~~~~~~~~~~~\ncompilation terminated.\nmake[1]: *** [scripts/Makefile.host:90: scripts/sortextable] Error 1\nmake: *** [Makefile:1067: scripts] Error 2", "rc": 2, "stderr": "scripts/sortextable.c:31:10: fatal error: tools/be_byteshift.h: No such file or directory\n #include \n          ^~~~~~~~~~~~~~~~~~~~~~\ncompilation terminated.\nmake[1]: *** [scripts/Makefile.host:90: scripts/sortextable] Error 1\nmake: *** [Makefile:1067: scripts] Error 2\n", "stderr_lines": ["scripts/sortextable.c:31:10: fatal error: tools/be_byteshift.h: No such file or directory", " #include ", "          ^~~~~~~~~~~~~~~~~~~~~~", "compilation terminated.", "make[1]: *** [scripts/Makefile.host:90: scripts/sortextable] Error 1", "make: *** [Makefile:1067: scripts] Error 2"], "stdout": "  CC      scripts/mod/empty.o\n  MKELF   scripts/mod/elfconfig.h\n  HOSTCC  scripts/mod/modpost.o\n  CC      scripts/mod/devicetable-offsets.s\n  HOSTCC  scripts/mod/file2alias.o\n  HOSTCC  scripts/mod/sumversion.o\n  HOSTLD  scripts/mod/modpost\n  HOSTCC  scripts/sortextable\n", "stdout_lines": ["  CC      scripts/mod/empty.o", "  MKELF   scripts/mod/elfconfig.h", "  HOSTCC  scripts/mod/modpost.o", "  CC      scripts/mod/devicetable-offsets.s", "  HOSTCC  scripts/mod/file2alias.o", "  HOSTCC  scripts/mod/sumversion.o", "  HOSTLD  scripts/mod/modpost", "  HOSTCC  scripts/sortextable"]}
...ignoring

TASK [Anlegen der dkms.conf für Dynamic Kernel Module Support] *************************************************************************
changed: [raspi_offloader_file]

TASK [Dynamic Kernel Module Support hinzufügen] ****************************************************************************************
changed: [raspi_offloader_file]

TASK [Dynamic Kernel Module Support bauen] *********************************************************************************************
changed: [raspi_offloader_file]

TASK [Dynamic Kernel Module Support installieren] **************************************************************************************
changed: [raspi_offloader_file]

TASK [Laden des Kernelmodul beim Booten veranlassen] ***********************************************************************************
changed: [raspi_offloader_file]

TASK [Laden des BATMAN Moduls] *********************************************************************************************************
changed: [raspi_offloader_file]

TASK [Laden des dummy Moduls] **********************************************************************************************************
changed: [raspi_offloader_file]

TASK [Installation der  bridge-utils] **************************************************************************************************
changed: [raspi_offloader_file]

TASK [Aktivierung von BATMAN_V] ********************************************************************************************************
changed: [raspi_offloader_file]

TASK [Konfiguration des Interfaces] ****************************************************************************************************
changed: [raspi_offloader_file]

TASK [Installation von FASTD] **********************************************************************************************************
changed: [raspi_offloader_file]

TASK [Verzeichnis für fastd- Konfigurationsdatei anlegen] ******************************************************************************
changed: [raspi_offloader_file]

TASK [Schlüssel für fastd erstellen] ***************************************************************************************************
changed: [raspi_offloader_file]

TASK [FASTD Secret Key aus /root/fastd.key in Variable übergeben] **********************************************************************
changed: [raspi_offloader_file]

TASK [FASTD Socket ermitteln] **********************************************************************************************************
skipping: [raspi_offloader_file] => (item={'key': 'muc_cty', 'value': 30002}) 
skipping: [raspi_offloader_file] => (item={'key': 'muc_nord', 'value': 30003}) 
skipping: [raspi_offloader_file] => (item={'key': 'muc_ost', 'value': 30004}) 
skipping: [raspi_offloader_file] => (item={'key': 'muc_sued', 'value': 30005}) 
skipping: [raspi_offloader_file] => (item={'key': 'muc_west', 'value': 30006}) 
skipping: [raspi_offloader_file] => (item={'key': 'uml_nord', 'value': 30007}) 
skipping: [raspi_offloader_file] => (item={'key': 'uml_ost', 'value': 30008}) 
skipping: [raspi_offloader_file] => (item={'key': 'uml_sued', 'value': 30009}) 
skipping: [raspi_offloader_file] => (item={'key': 'uml_west', 'value': 30010}) 
skipping: [raspi_offloader_file] => (item={'key': 'gauting', 'value': 30012}) 
skipping: [raspi_offloader_file] => (item={'key': 'freising', 'value': 30013})
ok: [raspi_offloader_file] => (item={'key': 'welt', 'value': 30011})

TASK [Erstellen der fastd Konfigurationsdatei] *****************************************************************************************
changed: [raspi_offloader_file]

TASK [Service fastd beim Booten starten] ***********************************************************************************************
changed: [raspi_offloader_file]

TASK [Installation der Pakete git und python3-netifaces] *******************************************************************************
changed: [raspi_offloader_file]

TASK [Repo ext-respondd klonen] ********************************************************************************************************
changed: [raspi_offloader_file]

TASK [Systemd Startdatei für respondd kopieren] ****************************************************************************************
changed: [raspi_offloader_file]

TASK [Erstellen der resondd Konfigurationsdatei alias.json] ****************************************************************************
changed: [raspi_offloader_file]

TASK [Erstellen der resondd Konfigurationsdatei config.json] ***************************************************************************
changed: [raspi_offloader_file]

TASK [Service ext-respondd beim Booten starten] ****************************************************************************************
changed: [raspi_offloader_file]

TASK [Paket hostapd für WLAN installieren] *********************************************************************************************
changed: [raspi_offloader_file]

TASK [hostapd konfigurieren] ***********************************************************************************************************
changed: [raspi_offloader_file]

TASK [hostapd Konfigurationsdatei anlegen] *********************************************************************************************
changed: [raspi_offloader_file]

TASK [wlan0 in Bridge packen] **********************************************************************************************************
changed: [raspi_offloader_file]

TASK [Service hostapd beim Booten und jetzt starten und das Laden der Unit Datei vom Service hostapd ermöglichen] **********************
changed: [raspi_offloader_file]

TASK [Konfiguration des Client-VLAN ohne Mesh-Netz] ************************************************************************************
skipping: [raspi_offloader_file]

TASK [vxlan_id für ausgewähltes Segment ermitteln] *************************************************************************************
skipping: [raspi_offloader_file] => (item={'key': 'muc_cty', 'value': 10758607}) 
skipping: [raspi_offloader_file] => (item={'key': 'muc_nord', 'value': 15521492}) 
skipping: [raspi_offloader_file] => (item={'key': 'muc_ost', 'value': 2948862}) 
skipping: [raspi_offloader_file] => (item={'key': 'muc_sued', 'value': 8599288}) 
skipping: [raspi_offloader_file] => (item={'key': 'muc_west', 'value': 7318933}) 
skipping: [raspi_offloader_file] => (item={'key': 'uml_nord', 'value': 5705961}) 
skipping: [raspi_offloader_file] => (item={'key': 'uml_ost', 'value': 4892713}) 
skipping: [raspi_offloader_file] => (item={'key': 'uml_sued', 'value': 16544703}) 
skipping: [raspi_offloader_file] => (item={'key': 'uml_west', 'value': 16677749}) 
skipping: [raspi_offloader_file] => (item={'key': 'gauting', 'value': 16175732}) 
skipping: [raspi_offloader_file] => (item={'key': 'freising', 'value': 12937858})
ok: [raspi_offloader_file] => (item={'key': 'welt', 'value': 16306234})

TASK [Konfiguration des Mesh-VLAN ohne Client-VLAN] ************************************************************************************
skipping: [raspi_offloader_file]

TASK [Konfiguration von Mesh- und Client-VLAN] *****************************************************************************************
changed: [raspi_offloader_file]

TASK [Konfiguration des bevorzugte Meshingpoint in BATMAN_V ohne Wifi-Nutzung] *********************************************************
skipping: [raspi_offloader_file]

TASK [Konfiguration des bevorzugte Meshingpoint in BATMAN_V mit Wifi-Nutzung] **********************************************************
changed: [raspi_offloader_file]

TASK [Für OLED-Konfiguration i2c-bcm2708 in /etc/modules eintragen] ********************************************************************
changed: [raspi_offloader_file]

TASK [Für OLED-Konfiguration i2c-dev in /etc/modules eintragen] ************************************************************************
changed: [raspi_offloader_file]

TASK [Installation der für das OLED benötigten Pakete] *********************************************************************************
changed: [raspi_offloader_file]

TASK [Laden des Kernelmodul i2c_arm beim Booten veranlassen] ***************************************************************************
changed: [raspi_offloader_file]

TASK [Reboot nach Konfigurationsänderung] **********************************************************************************************
changed: [raspi_offloader_file]

TASK [Repo Adafruit_Python_SSD1306 klonen] *********************************************************************************************
changed: [raspi_offloader_file]

TASK [Für OLED-Konfiguration Adafruit_Python_SSD1306 installieren] *********************************************************************
changed: [raspi_offloader_file]

TASK [Script zur Anzeige klonen] *******************************************************************************************************
changed: [raspi_offloader_file]

TASK [Script zur Bandbreitenauslastung anpassen] ***************************************************************************************
changed: [raspi_offloader_file]

TASK [Startscript für das OLED anlegen] ************************************************************************************************
changed: [raspi_offloader_file]

TASK [Service oled-bandwidth beim Booten starten] **************************************************************************************
changed: [raspi_offloader_file]

TASK [Reboot nach Abschluss der Konfiguration unseres Offloaders] **********************************************************************
changed: [raspi_offloader_file]

PLAY RECAP *****************************************************************************************************************************
raspi_offloader_file          : ok=54   changed=50   unreachable=0    failed=0    skipped=3    rescued=0    ignored=1

Auch hier wird nach Beendigung des Ansible-Laufs der Knoten auf der Freifunkkarte an der gewünschten Stelle auftauchen.

Links


1)
Secure SHell
2)
Secure SHell
3) , 6)
Version v2 vom 09.03.2020
4)
Version v1 vom 14.02.2020
5)
Stand: Februar 2020
Diese Website verwendet Cookies. Durch die Nutzung der Website stimmen Sie dem Speichern von Cookies auf Ihrem Computer zu. Außerdem bestätigen Sie, dass Sie unsere Datenschutzbestimmungen gelesen und verstanden haben. Wenn Sie nicht einverstanden sind, verlassen Sie die Website.Weitere Information
  • centos/ansible/ffmuc-rpb4-ol.1599340128.txt.gz
  • Zuletzt geändert: 05.09.2020 21:08.
  • von django