Für den Smart Appliance Enabler gibt es Images für Raspberry Pi und amd64, die jeweils die passende Java-Version beinhalten (deshalb Plaform-spezifische Images).
Bevor der Smart Appliance Enabler als Docker-Container betrieben werden kann, muss Docker installiert sein.
Die Docker-Installation ist denkbar einfach, muss aber in einer Root-Shell erfolgen:
pi@raspberrypi:~ $ sudo bash
root@raspberrypi:/home/pi# curl -sSL https://get.docker.com | sh
# Executing docker install script, commit: 6bf300318ebaab958c4adc341a8c7bb9f3a54a1a
[...]
If you would like to use Docker as a non-root user, you should now consider
adding your user to the "docker" group with something like:
sudo usermod -aG docker your-user
Remember that you will have to log out and back in for this to take effect!
WARNING: Adding a user to the "docker" group will grant the ability to run
containers which can be used to obtain root privileges on the
docker host.
Refer to https://docs.docker.com/engine/security/security/#docker-daemon-attack-surface
for more information.
Nachdem man entsprechend des Vorschlags der Docker-Installation dem User die Rolle docker
gegeben hat, muss man sich aus- und einloggen, bevor man die Docker-Installation überprüfen kan:
$ docker version
Client: Docker Engine - Community
Version: 19.03.13
[...]
Server: Docker Engine - Community
Engine:
Version: 19.03.13
[...]
Eine allgemeine Anleitung für die Installation auf allen offiziell unterstützen Plattformen findet sich unter https://docs.docker.com/get-docker/
Im Image befinden sich der Smart Appliance Enabler im Verzeichnis /opt/sae
.
Die Konfigurationsdateien des Smart Appliance Enabler (Appliances.xml
und Device2EM.xml
) werden im Docker-Volume sae
abgelegt.
Zur Laufzeit wird dieses Volume unter /opt/sae/data
gemounted.
Für die Konfiguration als Container gibt es zwei Möglichkeiten:
- Konfiguration mit
docker-compose
auf Basis einer YAML-Datei (empfohlen!) - Konfiguration mit diversen
docker
-Aufrufen
Der Smart Appliance Enabler implementiert das SEMP-Protokoll von SMA. Dieses Protokoll basiert auf UPnP, welches wiederum IP Multicast benötigt.
Die nachfolgend beschriebenen Konfigurationen verwenden deshalb ein macvlan
-Netz, mit dessen Hilfe der Docker-Container des Smart Appliance Enabler eine eigene MAC- und IP-Adresse erhält. Falls das nicht möglich oder gewünscht ist, muss der Docker-Container des Smart Appliance Enabler mit --net=host
gestartet werden.
docker-compose
ermöglicht eine komfortable Konfiguration des Containers über eine YAML-Datei.
docker-compose
muss zusätzlich zu docker
installiert werden.
Vor der Installation von docker-compose
auf dem Raspberry Pi muss der Python-Package-Manager installiert werden:
pi@raspberrypi:~ $ sudo apt-get -y install python3-pip
Die eigentliche Installation von docker-compose
erfolgt danach mit:
pi@raspberrypi:~ $ sudo pip3 -v install docker-compose
Die Beschreibung der Installation docker-compose
findet sich unter https://docs.docker.com/compose/install .
Für den Smart Appliance Enabler existiert eine vorkonfigurierte YAML-Datei, für die ein Verzeichnis angelegt werden muss, um sie danach herunterzuladen:
pi@raspberrypi:~ $ sudo mkdir -p /etc/docker/compose/smartapplianceenabler
pi@raspberrypi:~ $ sudo wget https://github.com/camueller/SmartApplianceEnabler/raw/master/run/etc/docker/compose/docker-compose.yaml -P /etc/docker/compose/smartapplianceenabler
Hinweise zu den notwendigen Anpassungen finden sich als Kommentare in der Datei selbst.
Das Docker-Volume sae
wird automatisch beim Start erstellt, falls noch nicht vorhanden.
Auch wenn der Smart Appliance Enabler als Docker-Container betrieben wird, bietet es sich an, den Container als Service des Systemd zu verwalten. Dazu dient die Datei /lib/systemd/system/smartapplianceenabler-docker-compose.service
, die nachfolgend heruntergeladen und konfiguriert wird:
$ sudo wget https://github.com/camueller/SmartApplianceEnabler/raw/master/run/lib/systemd/system/smartapplianceenabler-docker-compose.service -P /lib/systemd/system
$ sudo chown root.root /lib/systemd/system/smartapplianceenabler-docker-compose.service
$ sudo chmod 755 /lib/systemd/system/smartapplianceenabler-docker-compose.service
Damit der Smart Appliance Enabler beim Systemstart ebenfalls gestartet wird (via Systemd), muss folgender Befehl ausgeführt werden:
pi@raspberrypi ~ $ sudo systemctl enable smartapplianceenabler-docker-compose.service
Created symlink /etc/systemd/system/multi-user.target.wants/smartapplianceenabler-docker-compose.service → /lib/systemd/system/smartapplianceenabler-docker-compose.service.
Nach diesen Änderungen muss der Systemd dazu gebracht werden, die Service-Konfigurationen neu zu lesen:
pi@raspberrypi ~ $ sudo systemctl daemon-reload
sudo systemctl start smartapplianceenabler-docker-compose
sudo systemctl stop smartapplianceenabler-docker-compose
Wenn der Container mit dem Smart Appliance Enabler läuft, sollte der Status active (running)
sein:
sae@raspi:~ $ sudo systemctl status smartapplianceenabler-docker-compose.service
● smartapplianceenabler-docker-compose.service - Smart Appliance Enabler Container
Loaded: loaded (/lib/systemd/system/smartapplianceenabler-docker-compose.service; enabled; vendor preset: enabled)
Active: active (running) since Sat 2020-12-26 13:04:45 CET; 5 days ago
Main PID: 30810 (docker-compose)
Tasks: 3 (limit: 2063)
CGroup: /system.slice/smartapplianceenabler-docker-compose.service
└─30810 /usr/bin/python3 /usr/local/bin/docker-compose up
Dec 26 13:05:40 raspi docker-compose[30810]: sae | 13:05:40.622 [http-nio-8080-exec-1] INFO o.s.web.servlet.DispatcherServlet - Initializing Servlet 'dispatcherServlet'
Dec 26 13:05:40 raspi docker-compose[30810]: sae | 13:05:40.696 [http-nio-8080-exec-1] INFO o.s.web.servlet.DispatcherServlet - Completed initialization in 73 ms
pi@raspi:/etc/docker/compose/smartapplianceenabler $ sudo systemctl status smartapplianceenabler-docker-compose
● smartapplianceenabler-docker-compose.service - Smart Appliance Enabler Container
Loaded: loaded (/lib/systemd/system/smartapplianceenabler-docker-compose.service; enabled; vendor preset: enabled)
Active: active (running) since Mon 2020-11-30 17:27:44 CET; 6s ago
Main PID: 1501 (docker-compose)
Tasks: 3 (limit: 2063)
CGroup: /system.slice/smartapplianceenabler-docker-compose.service
└─1501 /usr/bin/python3 /usr/local/bin/docker-compose up
Nov 30 17:27:44 raspi systemd[1]: Started Smart Appliance Enabler Container.
Nov 30 17:27:47 raspi docker-compose[1501]: Creating network "macvlan0" with driver "macvlan"
Nov 30 17:27:48 raspi docker-compose[1501]: Creating sae ...
Für alle nachfolgenden Befehle muss man sich im Verzeichnis mit der zum Smart Appliance Enabler gehörenden docker-compose.yaml
-Datei befinden (normalerweise /etc/docker/compose/smartapplianceenabler
)!
pi@raspberrypi:~ $ docker-compose up -d
Creating network "macvlan0" with driver "macvlan"
Creating sae ... done
pi@raspberrypi:~ $ docker-compose down
Stopping sae ... done
Removing sae ... done
Removing network macvlan0
$ docker-compose logs
[...]
sae | 17:06:20.733 [main] INFO o.s.b.w.e.tomcat.TomcatWebServer - Tomcat started on port(s): 8080 (http) with context path ''
sae | 17:06:24.615 [http-nio-8080-exec-1] INFO o.a.c.c.C.[Tomcat].[localhost].[/] - Initializing Spring DispatcherServlet 'dispatcherServlet'
sae | 17:06:24.616 [http-nio-8080-exec-1] INFO o.s.web.servlet.DispatcherServlet - Initializing Servlet 'dispatcherServlet'
sae | 17:06:24.708 [http-nio-8080-exec-1] INFO o.s.web.servlet.DispatcherServlet - Completed initialization in 91 ms[...]
Der Smart Appliance Enabler benötigt ein schreibbares Verzeichnis, in dem er seine Dateien ablegen kann. Dazu wird in Docker das Volume sae erzeugt.
pi@raspberrypi:~ $ docker volume create sae
sae
Danach sollte das neue Volume in der Liste der vorhanden Volumes enthalten sein:
pi@raspberrypi:~ $ docker volume ls
DRIVER VOLUME NAME
local sae
Die nachfolgenden Befehle (ausser docker create network ...
) sind nur bis zum nächsten Reboot aktiv und müssen ggf. in einem Init-Script platziert werden.
Zunächst wird ein macvlan
-Interface mit der Bezeichnung macvlan0
als Link auf das physische Interface (hier eth0) erstellt:
sudo ip link add macvlan0 link eth0 type macvlan mode bridge
Für die IP-Adressen der Docker-Container muss ein Overlay-Netz von IP-Adressen definiert werden, welches den Adressbereich des physischen Interfaces überlagert. Dieser Adressbereich muss vom DHCP-Server ignoriert werden, d.h. er darf diesen Adressen niemandem zusteilen!!
Zur Bestimmung geeignete Netze eignet sich der IP Calculator.
Nachfolgend wird das macvlan
-Interface konfiguriert auf eine IP-Adresse aus dem Adressbereich des Overlay-Netzes.
sudo ifconfig macvlan0 192.168.0.223 netmask 255.255.255.0 up
Abschließend muss ein Routing-Eintrag für das Overlay-Netz hinzugefügt werden:
sudo ip route add 192.168.0.192/27 dev macvlan
Jetzt kann das Docker-Netzwerk macvlan0
erstellt werden. Der Parameter subnet
entspricht dem Netz des physischen Inteerfaces. Beim Parameter gateway
handelt sich es um das Ziel der Default-Route (meist die interne IP-Adresses des Internet-Routers). Als Parameter ip-range
wird das Overlay-Netz angegegeben, wobei im Parameter aux-address
die IP-Adresse des macvlan
-Interfaces angegeben wird, damit sie keinem Docker-Container zugewiesen wird. Beim Parameter parent
wird das physische Interface angegeben.
Damit sieht der Befehl wie folgt aus:
docker network create -d macvlan --subnet=192.168.0.0/24 --gateway=192.168.0.1 --ip-range 192.168.0.192/27 --aux-address 'host=192.168.0.223' -o parent=eth0 -o macvlan_mode=bridge macvlan0
Beim Starten des Smart Appliance Enabler in einem neuen Container mit dem Namen sae muss das in Docker angelegte macvlan
-Netzwerk (Parameter --network
) sowie die dem Docker-Container zuzuweisende IP-Adresse (Parameter --ip
) angegeben werden.
Damit sieht der Befehl wie folgt aus:
pi@raspberrypi:~ $ docker run -v sae:/opt/sae/data --network macvlan0 --ip 192.168.0.211 --publish 8080:8080 --device /dev/mem:/dev/mem --privileged --name=sae avanux/smartapplianceenabler-arm32
Dabei können über die Docker-Variable JAVA_OPTS auch Properties gesetzt werden:
pi@raspberrypi:~ $ docker run -v sae:/opt/sae/data --network macvlan0 --ip 192.168.0.211 --publish 8080:8080 --device /dev/mem:/dev/mem --privileged --name=sae -e JAVA_OPTS="-Dserver.port=9000" avanux/smartapplianceenabler-arm32
pi@raspberrypi:~ $ docker stop sae
sae
Auch wenn der Smart Appliance Enabler als Docker-Container betrieben wird, bietet es sich an, den Container als Service des Systemd zu verwalten. Dazu dient die Datei /lib/systemd/system/smartapplianceenabler-docker.service
, die nachfolgend heruntergeladen und konfiguriert wird:
pi@raspberrypi ~ $ sudo wget https://github.com/camueller/SmartApplianceEnabler/raw/master/run/lib/systemd/system/smartapplianceenabler-docker.service -P /lib/systemd/system
pi@raspberrypi ~ $ sudo chown root.root /lib/systemd/system/smartapplianceenabler-docker.service
pi@raspberrypi ~ $ sudo chmod 755 /lib/systemd/system/smartapplianceenabler-docker.service
Damit der Smart Appliance Enabler beim Systemstart ebenfalls gestartet wird (via Systemd), muss folgender Befehl ausgeführt werden:
pi@raspberrypi ~ $ sudo systemctl enable smartapplianceenabler-docker.service
Created symlink /etc/systemd/system/multi-user.target.wants/smartapplianceenabler.service → /lib/systemd/system/smartapplianceenabler.service.
Nach diesen Änderungen muss der Systemd dazu gebracht werden, die Service-Konfigurationen neu zu lesen:
pi@raspberrypi ~ $ sudo systemctl daemon-reload
sudo systemctl start smartapplianceenabler-docker
sudo systemctl stop smartapplianceenabler-docker
sae@raspberrypi:~/docker $ sudo systemctl status smartapplianceenabler-docker
● smartapplianceenabler-docker.service - Smart Appliance Enabler Container
Loaded: loaded (/lib/systemd/system/smartapplianceenabler-docker.service; enabled; vendor preset: enabled)
Active: active (running) since Wed 2019-12-25 17:18:25 CET; 2min 38s ago
Process: 9566 ExecStartPre=/bin/sleep 1 (code=exited, status=0/SUCCESS)
Main PID: 9567 (docker)
Tasks: 11 (limit: 2200)
Memory: 23.0M
CGroup: /system.slice/smartapplianceenabler-docker.service
└─9567 /usr/bin/docker run -v sae:/opt/sae/data --net=host --device /dev/mem:/dev/mem --privileged --name=sae avanux/smartapplianceenabler-arm32
Dec 25 17:19:13 raspberrypi docker[9567]: 16:19:13.925 [main] INFO o.a.coyote.http11.Http11NioProtocol - Initializing ProtocolHandler ["http-nio-8080"]
Dec 25 17:19:13 raspberrypi docker[9567]: 16:19:13.930 [main] INFO o.a.catalina.core.StandardService - Starting service [Tomcat]
Dec 25 17:19:13 raspberrypi docker[9567]: 16:19:13.933 [main] INFO o.a.catalina.core.StandardEngine - Starting Servlet engine: [Apache Tomcat/9.0.29]
Dec 25 17:19:20 raspberrypi docker[9567]: 16:19:20.991 [main] INFO o.a.c.c.C.[Tomcat].[localhost].[/] - Initializing Spring embedded WebApplicationContext
Dec 25 17:19:20 raspberrypi docker[9567]: 16:19:20.992 [main] INFO o.s.web.context.ContextLoader - Root WebApplicationContext: initialization completed in 20208 ms
Dec 25 17:19:25 raspberrypi docker[9567]: 16:19:25.964 [main] INFO o.a.coyote.http11.Http11NioProtocol - Starting ProtocolHandler ["http-nio-8080"]
Dec 25 17:19:26 raspberrypi docker[9567]: 16:19:26.183 [main] INFO o.s.b.w.e.tomcat.TomcatWebServer - Tomcat started on port(s): 8080 (http) with context path ''
Dec 25 17:19:38 raspberrypi docker[9567]: 16:19:38.878 [http-nio-8080-exec-1] INFO o.a.c.c.C.[Tomcat].[localhost].[/] - Initializing Spring DispatcherServlet 'dispatcherServlet'
Dec 25 17:19:38 raspberrypi docker[9567]: 16:19:38.879 [http-nio-8080-exec-1] INFO o.s.web.servlet.DispatcherServlet - Initializing Servlet 'dispatcherServlet'
Dec 25 17:19:38 raspberrypi docker[9567]: 16:19:38.952 [http-nio-8080-exec-1] INFO o.s.web.servlet.DispatcherServlet - Completed initialization in 69 ms
Falls man einen Befehl im laufenden Container des Smart Appliance Enabler ausführen möchte, kann man mit nachfolgendem Befehl eine entsprechend Shell erzeugen:
pi@raspberrypi:~ $ docker exec -it sae bash
Folgender Befehl zeigt die Ausgaben des Smart Appliance Enabler auf der Konsole an:
pi@raspberrypi:~ $ docker logs sae
Zusätzlich zum Konsole-Log erzeugt der Smart Appliance Enabler für jeden Tag eine Log-Datei im /tmp
-Verzeichnis.
Mit dem nachfolgenden Befehl kann dieses angezeigt werden, wobei das Datum entsprechend angepasst werden muss:
pi@raspberrypi:~ $ docker container exec sae tail -f /tmp/rolling-2019-12-25.log
Um evtuell vorhandene Konfigurationsdateien des Smart Appliance Enabler auf dieses Volume zu kopieren, eignet sich dieser Befehl (die erste Zeile erzeugt einen Dummy-Container mit dem Namen sae, falls noch keiner läuft):
pi@raspberrypi:~ docker run -v sae:/opt/sae/data --name sae busybox true
pi@raspberrypi:~ docker cp Appliances.xml sae:/opt/sae/data/
pi@raspberrypi:~ docker cp Device2EM.xml sae:/opt/sae/data/