Windows-Programme für Linux als Debian-Paket packen und ausführbar machen

Ab und zu ist es erforderlich, Programme zu nutzen, für die es keine Linux-Versionen gibt. In diesem Fall ist es möglich, die Windows-Version einer Anwendung mit der Windows-kompatiblen Laufzeitumgebung wine zu nutzen.

Ab und zu ist es erforderlich, Programme zu nutzen, für die es keine Linux-Versionen gibt. In diesem Fall ist es möglich, die Windows-Version einer Anwendung mit der Windows-kompatiblen Laufzeitumgebung wine zu nutzen. wine stellt dabei die für die Ausführung von Windows-Programmen erforderlichen dynamischen Programmbibliotheken (Dynamic Link Libraries) zur Verfügung, sodass eine Windows-Binärdatei auch unter Linux gestartet werden kann. Zudem stellt wine auch eine Windows-Registry zur Verfügung, da diese von manchen Windows-Anwendungen erfordert wird.

Um Windows-Programme möglichst komfortabel auch auf Linux-Systemen nutzen zu können, bietet es sich an, diese in ein Linux-AppImage zu packen. Das AppImage ist ein komprimiertes Dateisystemabbild, das alle für die Ausführung eines Programms erforderlichen Abhängigkeiten enthält, sodass die Anwendung auf jedem Linux-System ohne Installation ausgeführt werden kann. In dem Fall der Windows-Anwendung enthält das AppImage die ausführbare Windows-Datei vom Typ exe sowie die Windows-kompatible und für das Programm passend konfigurierte Laufzeitumgebung wine. Macht man einen Doppelklick auf das AppImage, so wird das Windows-Programm mit wine gestartet und man kann es nutzen.

Da in dem AppImage nicht nur die Anwendung als solches, sondern auch noch die wine-Laufzeitumgebung mit allen Abhängigkeiten enthalten ist, wird ein solches AppImage leider recht groß. So wächst dann zum Beispiel eine Windows-exe von etwa 40 MB auf über 100 MB an.

In einem weiteren Schritt muss man das AppImage dann in ein Debian-Installationspaket packen, damit man es einfach auf einem Linux-System installieren kann und die Programmstarter automatisch im Anwendungsmenü erzeugt werden.

Im Detail geht man wie folgt vor:

  • Man muss dann das AppImage in deb-Paket packen. Dabei kann man wie von mir hier beschrieben vorgehen.

Leider funktioniert diese Vorgehensweise nicht generell für alle Windowsanwendungen. Vor allem funktioniert diese Vorgehensweise nicht für Anwendungen, die Microsoft .NET nutzen. Mir ist es aber vollkommen problemlos gelungen, Qt-basierte Windows-Anwendungen auf diese Weise zu packen.

Fernwartung von Laptops bei Schülerinnen und Schülern zuhause: Verteilung von Shell-Skripten und Konfigurationsdateien mit einem deb-Paket über ein launchpad ppa

In diesem Blog-Eintrag werde ich kurz dokumentieren, wie ich die Skripte und Konfigurationsdateien, die unser „GBG-Linux“ konfigurieren, in ein deb-Paket verpackt und dann mithilfe eines launchpad ppa verteilt habe.

Durch die Corona-Krise wurden bei uns in der Schule knapp über sechzig Ubuntu-Laptops an Schülerinnen und Schüler verliehen, die diese Geräte zuhause benutzten. Diese Tatsache machte es erforderlich, dass ich auch in der Lage sein muss, diese Geräte aus der Ferne zu konfigurieren und zu aktualisieren. Ich habe dieses mit dem folgenden kleinen Update-Skript gelöst:

#!/bin/bash
sudo DEBIAN_FRONTEND=noninteractive apt-get -y update
sudo DEBIAN_FRONTEND=noninteractive apt-get -y -o Dpkg::Options::="--force-confdef" -o Dpkg::Options::="--force-confold" dist-upgrade
sudo apt-get autoremove -y

Damit der Standardbenutzer dieses Skript ausführen kann, muss ihm erlaubt werden, das Skript mit sudo ohne Passworteingabe auszuführen. Dieses kann man mit einer Regel in der sudoers-Datei lösen. Statt die Regel direkt in die sudoers hineinzuschreiben, habe ich die Regel im Ordner /etc/sudoers.d/ abgelegt, damit die sudoers nicht angetastet wird:

gbg ALL = NOPASSWD: /usr/bin/updater.sh

Damit der Benutzer gbg die Aktualisierungen dann auch bequem starten kann, muss man noch einen Programmstarter im Startmenü anlegen, auf den der Nutzer dann nur noch klicken muss:

[Desktop Entry]
Type=Application
Name=Updates installieren
GenericName=Updates installieren
Exec=sudo /usr/bin/updater.sh
Icon=/usr/share/icons/updater.svg
Terminal=true
Categories=System;

Wie man dem Code entnehmen kann, habe ich auch noch ein kleines instruktives Icon erstellt. Auf diese Weise kann der Benutzer nun mit einem einfachen Mauskick auf das Icon im Startmenü Updates installieren, ohne dass er dafür ein Passwort eingeben muss.

Konfigurationsänderungen auf den Geräten

Um in der Lage zu sein, auch Konfigurationsänderungen an den Geräten bei den Schülerinnen und Schülern zuhause durchzuführen, habe ich die Skripte, mit denen ich das „GBG-Linux“ verwalte, in ein deb-Paket gepackt und dieses dann in einem launchpad ppa zur Verfügung gestellt. Dieses ppa wird auf den Laptops zu den Paketquellen hinzugefügt und wenn ich dann den „GBG-Client“ aktualisiere und die Schülerin oder der Schüler zuhause den Update-Knopf drückt, dann aktualisiert sich auch automatisch der „GBG-Client“, sodass etwaige Konfigurationsänderungen wirksam werden.

Verpacken von Shell-Skripten in ein deb-Paket

Als Erstes muss man folgende Pakete auf dem Entwicklungsgerät installieren.

sudo apt install dh-make devscripts

Hat man dieses gemacht, so muss man sich einen Ordner erstellen, in dem man die Skripte entwickelt.

mkdir gbgclient-0.1

Dabei ist wichtig, dass man dem Namen die Versionsnummer beifügt. In diesem Ordner erstellt man nun die Shell-Skripte und Konfigurationsdateien, die man mit dem deb-Paket verteilen möchte.

Für die Erstellung unseres deb-Pakets müssen in der .bashrc zunächst zwei Umgebungsvariablen gesetzt werden:

$ cat >>~/.bashrc <<EOF
DEBEMAIL="person@company.tld"
DEBFULLNAME="Vorname Nachname"
export DEBEMAIL DEBFULLNAME
EOF
$ . ~/.bashrc

Diese Variablen werden beim Erstellen des Pakets übernommen. Jetzt müssen wir in unserem Entwicklungsordner das Grundgerüst für das Debian-Paket erzeugen.

dh_make --indep --createorig

dh_make erzeugt im Entwicklungsordner einen Unterordner debian mit vielen für den Paketbau erforderlichen Dateien. Wir müssen aber zusätzlich eine Datei namens „install“ erstellen, die festlegt, in welche Ordner auf dem Zielsystem unsere Skripte aus unserem Entwicklungsordner kopiert werden sollen.

touch debian/install
vi debian/install

In diese Datei tragen wir nun ein, wo die Dateien bei Installation des Pakets hinkopiert werden sollen. Für den „GBG-Client“ sieht das wie folgt aus:

scripts/gbgclient.sh usr/bin
scripts/delete_connections.sh usr/bin
scripts/nutzerdatenerfassung.sh usr/bin
scripts/delete_connections.py usr/bin
gdm3/PostLogin/Default etc/gdm3/PostLogin
gdm3/PostSession/Default etc/gdm3/PostSession
gdm3/PreSession/Default etc/gdm3/PreSession
updater/updater.sh usr/bin
updater/updater.desktop usr/share/applications
updater/updater.svg usr/share/icons
misc/clear_connections.desktop etc/xdg/autostart
sudoers.d/sudogbgclient etc/sudoers.d/

Ich habe im Entwicklungsordner für meine Skripte verschiedene Unterordner eingerichtet, um eine übersichtlichere Struktur zu haben.

Jetzt muss man noch in der Datei debian/control im Archivordner eine Angabe hinzufügen, damit man das Paket erfolgreich bauen kann: Das Feld „section“ muss noch gesetzt werden. Die Datei debian/control könnte in Zeile 2 zum Beispiel so aussehen:

Section: utils

Außerdem muss man jetzt noch in der Datei debian/changelog nach der Versionsnummer focal hinzufügen, wenn man das Paket für 20.04 baut:

gbgclient (0.1-1) focal; urgency=medium

Damit man das Paket bei launchpad hochladen und dort bauen lassen kann, muss man debuild jetzt mit den folgenden Parametern ausführen:

debuild -us -uc -S -sa

Möchte man das Paket lokal auf dem eigenen Entwicklungssystem bauen, so geht das mit diesem Befehl:

debuild -us -uc

Als Nächstes muss man aus dem Entwicklungsordner heraus wechseln und das Paket, genauer die Datei name-version_source.changes (in meinem Fall z. B. gbgclient_0.1-1_source.changes) signieren.

cd ../
debsign -k schlüssel_id gbgclient_0.1-1_source.changes

Dabei muss „schlüssel_id“ durch die ID des zu verwendenden OpenPGP-Schlüssels ersetzt werden. Damit man das Paket dann auf launchpad hochladen kann, muss der öffentliche Schlüssel dort natürlich auch hochgeladen werden. Im nächsten Schritt kann dann das Paket auf launchpad in das persönliche ppa hochgeladen werden. In meinem Fall sieht der Befehl so aus:

dput ppa:feschoppe/gbgclient gbgclient_0.1-1_source.changes

Nach einiger Zeit bekommt man eine Bestätigung per Mail, dass das Paket akzeptiert wurde. Nach dem Hochladen wird es auf launchpad gebaut und steht dann über das entsprechende ppa zum Download bereit. Wenn man nun an dem Paket weiterarbeitet und zum Beispiel Dateien hinzufügt oder verändert, muss man diese Änderungen mit dem folgenden Befehl in das Paket übernehmen:

dpkg-source --commit --include-removal

Danach muss man im changelog die Versionsnummer erhöhen, damit man das Paket dann als neue Version hochladen kann:

nano debian/changelog

Danach muss man es neu bauen, signieren und hochladen. Führt nun die Schülerin oder der Schüler zuhause ein Update aus, so wird die neue Version des „GBG-Clients“ installiert. Auf diese Weise kann ich nun auch bei entliehenen Laptops Konfigurationsänderungen und Ähnliches durchführen.