Archiv der Kategorie: Linux

Jitsi auf dem eigenen Server

Jitsi unter Debian zu installieren ist recht straightforward und hier auch gut erklärt. Ich hatte aber doch ein paar Hänger:

a) Es ist doch eine ganz wilde Kette von Authentisierung und Modulen, am besten, um auch das logging zu verstehen, ist das hier erklärt. Bei mir erkannte ich dann, dass die Java Version, die ich für Minecraft installiert hatte, irgendwie das prosody cert nicht intus hatte, das konnte ich nachdem ich auf den standard JRE umgestellt hatte, als user jicofo mit keytool -importcert -file /var/lib/prosody/auth.jitsi.stevekist.de.crt fixen. Ausserdem hab ich im profile noch JAVA_HOME gesetzt.

b) Da mein Server hinter einer Fritte hängt und ich – wie wir fast alle – DynIP habe, musste ich das hier auch so anpassen, das ist in der Doku etwas strange erklärt.

</p>
cat /etc/jitsi/videobridge/sip-communicator.properties
org.jitsi.videobridge.AUTHORIZED_SOURCE_REGEXP=focus@auth.jitsi.stevekist.de/.*
org.ice4j.ice.harvest.NAT_HARVESTER_LOCAL_ADDRESS=192.168.243.10
org.ice4j.ice.harvest.STUN_MAPPING_HARVESTER_ADDRESSES=stun.l.google.com:19302 ,stun1.l.google.com:19302 ,stun2.l.google.com:19302
<p>

Die Googleeinträge werden benutzt um die eigene IP Adresse rauszubekommen. Ich glaub, das könnte ich auch irgendwie anders machen?

Und last not least musste ich der Fritte erklären, dass sie auf der richtigen IP des Servers port forwarded, siehe hier,

Virtuelle Interfaces und Die Fritzbox

Auf meinem Serverlein laufen schon richtig viele Dienste… die meisten sind einfach Webdienste auf nem nginx, aber dann gibt es auch manchmal was anderes… ha-bridge um homematic über die Alexa zu steuern, minecraft für den Nachwuchs… und jetzt – for reasons – auch Jitsi.

Da ist es dann doch nötig mehrere Interfaces mit mehreren IPs zu haben, an die sich die Services dann binden können. Nun erkennt die Fritte aber zum Portforwarden die Geräte nicht anhand der IPs sondern wohl anhand der Mac-Adresse -> einfach ein virtuelles Interface anlegen reicht nicht, es muss eins sein, das auch noch ne eigene Macadresse hat:

Das steht dann entsprechend in der /etc/network/interfaces:

# The primary network interface
auto eth0 eth0.0
iface eth0 inet static
      address 192.168.243.2
      netmask 255.255.255.0
      gateway 192.168.243.1
      dns-nameservers 192.168.243.1
      up  ip link add link eth0 address 74:d4:35:84:f4:10 eth0.0 type macvlan


iface eth0.0 inet static
      address 192.168.243.10

Eigentlich völlig easy, wenn man es weiss, oder?

Supasimple Picture Frame Raspberry Pi

Der plan ist für eine – ja genau eine bestimmte – Anwendung einen Pi aufzusetzen, der innerhalb eines Ordners Bilder als Slideshow zeigt und beim Anstecken eines USB Sticks mit Bildern diese lokal kopiert und dann diese als neue Slideshow nimmt. Was braucht man:
  • Raspberry Pi mit Raspian und folgenden paketen:
  • feh, nodm, xutils (xset)
Das ganze läuft unter dem User “pictures” also legen wir diesen an, ob mit oder ohne Passwort, alles egal. Auf jeden Fall wird der in nodm (/etc/default/nodm) als startuser eingetragen (das sind nur die geänderten Zeilen):
NODM_ENABLED=true
NODM_USER=picture
Dann bekommt der user picture ein .xession:
xset s off
xset -dpms
xset s noblank
feh --quiet --fullscreen --borderless \\
--hide-pointer --slideshow-delay 30 \\
/home/picture/Pictures
Dass die entsprechenden Directories existieren müssen ist klar, oder? So, jetzt fehlt nur noch ein Script um beim Anstecken eines Dongles, den Inhalt auf die SD Karte zu kopieren: /etc/udev/rules.d/usbstick.rules enthält:
ACTION=="add", KERNEL=="sd[a-z][0-9]", TAG+="systemd", ENV{SYSTEMD_WANTS}="usbstick-handler@%k"
Der usbstick handler ist in /lib/systemd/system/usbstick-handler@.service:
[Unit]
Description=Mount USB sticks
BindsTo=dev-%i.device
After=dev-%i.device

[Service]
Type=oneshot
RemainAfterExit=yes
ExecStart=/usr/local/bin/automount %I
ExecStop=/usr/bin/pumount /dev/%I
Es gibt ein /usr/local/bin/automount:
#!/bin/bash

PART=$1
rm -r /home/picture/Pictures/*
/usr/bin/pmount --umask 000 --noatime -w --sync /dev/${PART} /media/usb
cp -r /media/usb/* /home/picture/Pictures/
/usr/bin/pumount /dev/${PART}
killall -HUP feh
So, was könnte man da nicht noch alles machen: ne Taste anschliessen, eine Script, das das alles steuert auch mit vom USB Stick laden, ein Fallback bildchen… aber mei. S’geht ja schon… “Wie, und das war jetzt supasimple????”

Bilder organisieren

Da ich immer wieder mal von IT-Illiteraten dafür beneidet werde, dass ich alle meine Photos auf dem Handy dabei habe, wollte ich hier mal kurz den Verfahrensweg grob notieren, wie das recht einfach geht:

  1. Bilder auf dem PC organisieren.
  2. Bilder fürs Handy verkleinern und in eine geeignete Ordnerstruktur stellen.
  3. Diese Ordnerstruktur aufs Handy synchronisieren

Im Nachfolgenden nun meine Überlegungen dazu, ich hab auch mal – aber wirklich nur kurz – geschaut, wie das unter Windows gehen könnte. Spassig ist das nicht, aber mei… es geht irgendwie. Bei mir machen das unter Linux ein paar 10 Zeiler in Perl (ok, sind mehr Zeilen)…

Bilder auf dem PC organisieren

Ich habe einen “incoming” Ordner, in dem ich meine Bilder aus der oder den Kameras oder von Freunden reinstecke. Die sind alle unterschiedlich benamt, aber das macht an der Stelle erst mal nix. In diesem Ordner sichte ich auch und lösche schon mal fröhlich.

Danach lasse ich mein Skript digiimport auf den Ordner los. Dieses benennt die Bilder nach YYYYMMDD_HHMMSS aus den EXIF Daten um und speichert sie ein einen Zielordner mit der Struktur YYYY/MM/

Soweit so gut, damit sind die Bilder auf dem PC erst mal organisiert und bis auf den Dateinamen auch unverändert. Den Dateinamen ändere ich, weil ich keine Namen doppelt haben will, was man nach der n.ten Kamera zwangsläufig hat.

Wie geht das nun unter Windows?

Im Prinzip ähnlich, nur statt meines Skriptes nimmt man den AmoK EXIF Sorter. Dieser kann Profile anlegen und die Dateien auch entsprechend umbenennen, verschieben und passende Zielordner anlegen. Also entsprechend ein Profil für den Bildereingang und ein Profil für die Handybilder (wird weiter unten erklärt) und gut ist.

Bilder fürs Handy aufbereiten

Hier sind zwei Sachen nötig:

a) Die Programme auf Android können keine Ordnerstrukturen, bzw. gerade mal eine Ebene. Ich setze hier QuickPic ein, weil es diese eine Ebene wenigstens kann und super schnell ist.

b) Damit das Handy nicht aus allen Nähten platzt müssen die Fotos verkleinert werden: meine 15000 Fotos brauchen verkleinert gerade mal 5,5 GB, das geht auf so ziemlich allen Handies.

Bei mir kommt für diesen Zweck das Script “nexuspics” zum Einsatz, das auch gleich noch den sync auf den Server erledigt, ich mach das alles mit rsync. Unter Windows muss man das mehrstufig machen: zum Kopieren in eine neue Ordnerstruktur mit YYYY_MM Namen kann man von oben den AmoK EXIF Sorter nehmen und auf die fertig sortierten Bilder loslassen. Zum Verkleinern danach bietet sich hier der DownSizer an. Der kann auch in verschiedene Grössen ändern. Leider kann der das nicht im bestehenden Verzeichnis machen, sondern das Ding legt auch ein neues an, aber dieses kann man dann z.B. gleich in seiner Dropbox anlegen und das könnte man z.B. mit FolderSync mit dem Handy syncen.

Alles klar? Wenn nicht einfach nen Kommentar rein 🙂

Ah, und hier noch meine Scripte, wirklich “as is”, für mich gehen die.

GSM Gateway mit Asterisk und FreePBX auf Raspberry Pi

Nachdem ich erst versucht habe, das ganze zu Fuß auf Raspian zu bauen, hab ich nach gefühlten zwei Tagen aufgegeben und http://www.raspberry-asterisk.org genommen. Das hat den Riesenvorteil, dass man auch einen einigermaßen aktuellen Asterisk bekommt, auf dem der chan_dongle trotzdem geht.

Bei der Konfiguration hat vor allem:

Installing a FreePBX with FritzBox as trunk on a Raspberry Pi

geholfen. Es hat trotzdem alles nicht auf Anhieb geklappt. Irgendwann bin ich dann dazu übergegangen, alles, was nach ID und Passwort klang, gleich zu nennen, jetzt gehts 🙂 Ob das jetzt sicherheitstechnisch schlimm ist, kann ich schwer sagen (ok, stimmt nicht :-), ist alles im Intranet, da können mich die Leute auch schädigen, wenn sie einfach das Telefon in die Hand nehmen.

Vorher habe ich den UMTS Stick (Huawei E160) direkt an der Fritte betrieben, aber seit 6.83 ging das plötzlich nicht mehr. Aber da man dort eh die ausgehende Rufnummer nicht unterdrücken kann, ist mir das so eh viel lieber. Der RPi braucht übrigens mit dem Dongle ca. 3 Watt.

Im Prinzip sollte das auch immer noch mit dem UMTS Dongle an der Fritte gehen. Aber AVM gibt leider keine Liste mit unterstützten Sticks heraus und Rufnummernunterdrückung geht mit dieser Methode auch nicht… meine Handynummer soll ja nicht unbedingt bei einem Anruf von zuhause angezeigt werden.

Alexa, mach die Glotze aus

Da sitzt man auf dem Sofa, der Film fängt gleich an und daneben leuchtet der Rechner die Welt voll.

Jetzt könnte man natürlich aufstehen und das Ding einfach locken oder den Bildschirm ausschalten oder was immer, aber warum hat man sich denn dieses kleine Laberdöschen in die Bude gestellt. Also flux ein Script zusammengestohlen:

<br />
#!/usr/bin/python<br />
import sys, os<br />
from flask import Flask, jsonify</p>
<p>app = Flask(__name__)<br />
app.config.update(<br />
# DEBUG=True,<br />
)</p>
<p>command = 'gnome-screensaver-command --lock'</p>
<p>@app.route('/lockscreen', methods=['GET'])<br />
def get_tasks():<br />
 os.system(command)<br />
 return &quot;&quot;</p>
<p>if __name__ == '__main__':<br />
 app.run('0.0.0.0',5000 )<br />

Das Ding jetzt als Startprogramm eintragen.

Die Alexa steuert bei mir zuhause eh schon ziemlich viel dank der genialen HA Bridge. Dieser muss man natürlich noch erklären, dass sie z.B. das Device “Monitor” mit dem GET Befehl: http://meinlaptop.fritz.box/lockscreen ausschalten muss. Fertig.

Irgendwelche Security Bedenken?

Neben dem ganzen Amazon- und Cloud-Rotz und eigentlich recht wenige: ich nehme nicht noch nen weiteren Internet Service wie IFTT rein, sondern der Dot steuert das Dingens über die HA Bridge direkt (weil Amazon da halt ne zwei Klassen Gesellschaft hat). Der Flask Server oben ist glaub ich recht überschaubar… vielleicht fallen mir ja noch ein paar Ideen ein, was man machen könnte: Laptop Lautstärke wäre auch noch schick…

Debian Repository per ssh auf ein chroot

Für eigene Zwecke will man immer mal ein Repository haben, auf das andere nicht zugreifen können, aber das man auch an Bekannte oder Testgruppen oder wen auch immer weitergeben kann. ftp mit Passwort und http mit Passwort sind so ne Sache, ein wenig sicherer könnte das schon sein.

Debian Repositories können auch via ssh eingebunden werden, eine entsprechende Zeile in der sources list sieht dann so aus:

deb ssh://repouser@example.com/packages/ jessie main

Auf dem Server muss man einen entsprechenden Nutzer einrichten und die packages enthalten eben das Debian Repository. Authentisierung erfolg per ssh key, d.h. auf Clientseite wird ein ssh-Key erzeugt, der auf Serverseite im ~/.ssh/authorized_keys des repouser liegt. Soweit so straightforward.

Der Nachteil dieser Variante ist, dass der repouser nun einen ssh login auf dem Server hat, was ihn natürlich auch lesenden Zugriff auf andere Ressourcen gibt, was man eher nicht unbedingt will. Kann sein, dass man dies auch noch besser absichern kann, die beste Absicherung ist auf jeden Fall, diesen Benutzer in ein chroot environment zu sperren.

Dieses fahre ich über die sftp chroot variante des sshd, in der sshd_config steht dazu:

Subsystem sftp internal-sftp

Match Group sftp
ChrootDirectory %h
AllowTcpForwarding no

Nun muss der repouser noch zur Gruppe sftp dazu und jetzt kommt das eigentliche Problem: die chroot Umgebung mit den richtigen Dateien und Rechten auszustatten, d.h. alles dort einzurichten, was nötig ist, um auf Clientseite apt-get … aufzurufen. Und da war das Problem: Was braucht apt-get via ssh auf der Serverseite? Letzendlich hab ich es nur raus bekommen, in dem ich mir die Sourcen von apt-get angeschaut habe. Und da waren vor allem find und dd die Hänger… die drauf und es ging. Wie man herausbekommt, welche libs nötig sind, sagt ldd find und ldd dd und gut ist.

Das ganze ist hier in einem schmutzigen Script, das so unter Ubuntu 14.04 läuft, Achtung: die Libs werden so für andere Distris nicht passen, aber ldd ist dein Freund, der Rest stimmt.

<br />
#!/bin/bash<br />
echo &quot;This script should be started as root on the machine, which hosts the repo&quot;<br />
REPOUSER=&quot;repouser&quot;<br />
REPOHOME=&quot;ssdhome/$REPOUSER&quot;<br />
echo &quot;Generating chroot environment for $REPOUSER in $REPOHOME&quot;&lt;/code&gt;</p>
<p>adduser --disabled-password --ingroup sftp --home /$REPOHOME $REPOUSER<br />
mkdir -p /$REPOHOME<br />
chown root:root /$REPOHOME<br />
cd /$REPOHOME<br />
mkdir -p bin dev etc home lib usr var tmp usr/bin vat/tmplib/x86_64-linux-gnu usr/lib/x86_64-linux-gnu $REPOHOME lib/x86_64-linux-gnu lib64<br />
cp /bin/ls bin/<br />
cp /bin/dash bin/sh<br />
cp /bin/bash bin/<br />
cp /usr/bin/scp usr/bin/<br />
cp /bin/dd bin/<br />
cp /usr/bin/find usr/bin/<br />
cp /usr/bin/whoami usr/bin/<br />
cp /lib/x86_64-linux-gnu/libtinfo.so.5 lib/x86_64-linux-gnu/<br />
cp /lib/x86_64-linux-gnu/libdl.so.2 lib/x86_64-linux-gnu/<br />
cp /lib/x86_64-linux-gnu/libc.so.6 lib/x86_64-linux-gnu/<br />
cp /lib64/ld-linux-x86-64.so.2 lib64/<br />
cp /lib/x86_64-linux-gnu/libselinux.so.1 lib/x86_64-linux-gnu/<br />
cp /lib/x86_64-linux-gnu/libacl.so.1 lib/x86_64-linux-gnu/<br />
cp /lib/x86_64-linux-gnu/libpcre.so.3 lib/x86_64-linux-gnu/<br />
cp /lib/x86_64-linux-gnu/libattr.so.1 lib/x86_64-linux-gnu/<br />
cp /lib/x86_64-linux-gnu/libnss_compat* lib/x86_64-linux-gnu/<br />
cp /lib/x86_64-linux-gnu/libm.so.6 lib/x86_64-linux-gnu/<br />
mknod dev/null c 1 3<br />
mknod dev/zero c 1 5<br />
chmod 666 dev/*<br />
chmod 1777 tmp<br />
grep $REPOUSER /etc/passwd &amp;gt;&amp;gt; etc/passwd<br />
echo &quot;now, cp the repository beginning with the packages dir to ssdhome/$REPOUSER&quot;<br />
echo &quot;do not forget to add the public key to ssdhome/$REPOUSER/.ssh/authorized_keys&quot;<br />
echo &quot;and add a line like: deb ssh://$REPOUSER@example.com/packages/ jessie main&quot;<br />

 

Redmine in Sub-URI und https

Boah, diese ganze gelayerte Webappgrütze bringt einem um, wenn man das nicht regelmässig macht und die ganzen Fehlermeldungen der einzelnen Layer sofort versteht…

Ok, ich habe weder Zeit noch Lust, meine Erkenntnisse von 5 Tage rumprobieren hier komplett aufgeräumt wieder zu geben, aber wenigstens das Ergebnis könnte helfen…

Also neben dem “normalen” redmine aufsetzen hab ich das Dingens via thin und socket gegen einen nginx in einer suburi gebunden. Hier die Konfigurationen, die evtl. helfen könnten…

zuerst mal /etc/thin/redmine.yml:

---
chdir: "/space/redmine/latest"
environment: production
timeout: 30
log: "/var/log/thin/redmine.log"
pid: "/space/redmine/latest/tmp/redmine.pid"
max_conns: 1024
max_persistent_conns: 100
require: []
wait: 30
threadpool_size: 20
socket: "/space/redmine/latest/tmp/thin.sock"
daemonize: true
user: www-data
group: www-data
servers: 1
prefix: "/redmine"

nun die /etc/init.d/thin

#!/bin/bash
DAEMON=/usr/local/rvm/gems/ruby-2.2.3/bin/thin
SCRIPT_NAME=/etc/init.d/thin
CONFIG_PATH=/etc/thin
export GEM_PATH=/usr/local/rvm/gems/ruby-2.2.3:/usr/local/rvm/gems/ruby-2.2.3@global
export RUBY_VERSION=ruby-2.2.3
export MY_RUBY_HOME=/usr/local/rvm/rubies/ruby-2.2.3
export XDG_SESSION_COOKIE=xxxxxx
export IRBRC=/usr/local/rvm/rubies/ruby-2.2.3/.irbrc

# Exit if the package is not installed
[ -x "$DAEMON" ] || exit 0

source /usr/local/rvm/scripts/rvm

case "$1" in
  start)
	$DAEMON start --all $CONFIG_PATH
	;;
  stop)
	$DAEMON stop --all $CONFIG_PATH
	;;
  restart)
	$DAEMON restart --all $CONFIG_PATH
	;;
  *)
	echo "Usage: $SCRIPT_NAME {start|stop|restart}" >&2
	exit 3
	;;
esac

last not least der passende ausschnitt aus der /etc/nginx/sites-enabled/ssl

location ~ ^/redmine(/.*|$) {
        alias   /space/redmine/latest/public$1;
#location /redmine {
            proxy_set_header        Host $host;
            proxy_set_header        X-Real-IP $remote_addr;
            proxy_set_header        X-Forwarded-For $proxy_add_x_forwarded_for;
            proxy_set_header        X-Forwarded-Proto $scheme;
            proxy_redirect          http:// https://;
            proxy_pass              http://unix:/space/redmine/latest/tmp/thin.0.sock;
    }

Wie ich es geschafft habe, das ruby 2.2.3. zu installieren, hab ich vergessen… ich vermute mit dem “bundler install” aus dem redmine verzeichnis…

Über kurz oder lang werde ich wohl eher auf docker und einen reverse proxy umsteigen, damit sollte das in ner SubURI wohl auch gehen. Ob mein Serverlein für solche Sachen aber dann noch genug Speicher hat? Wer weiss…

laptopbackup

Uiuiui, am 31.3. war  Worldbackupday, da bin ich doch schon wieder 2 Tage zu spät mit meinem script…  aber immerhin, endlich bin ich mal soweit.

Was machts? naja, im Prinzip ists nur ein wrapper um einen rsync Einzeiler. Er schaut nach, ob der letzte Backup länger als 604800 (7 Tage) zurückliegt, ob der Rechner im ethernet ist und der server gepingt werden kann.  Wenn das alles zutrifft, wird rsync gestartet und ab gehts.  Ein wenig notifications und mail, wenns nicht klappt. Fertig ist die Laube.

Klar, das script muss per crontab nach Geschmack wiederholt werden. Ich mach das alle 10 minuten, aber das ist Geschmacksache. Hier nun das Script. Macht draus, was ihr wollt 🙂

Achja: der Trick, dass das überhaupt aus dem cron geht, ist, ein ssh-key ohne passwort zu verwenden und den auf der anderen Seite zu den authorized keys zu tun, aber das wisst ihr ja sicher.

<br />
#!/bin/bash<br />
cd /home/foobar<br />
SERVER=192.168.1.2<br />
SCRIPTNAME=`basename $0`<br />
last=0<br />
if [ -f .laptopbackup ]<br />
then<br />
    last=`cat .laptopbackup`<br />
fi<br />
curr=`date '+%s'`</p>
<p>diff=$(($curr-$last))<br />
echo diff: $diff<br />
if [ $diff -gt 604800 ]; then<br />
    IP=$(/sbin/ip route | awk '/default/ { print $3 }')<br />
    IF=$(/sbin/ip route | awk '/default/ { print $5 }')<br />
    if [ $IP=&quot;192.168.1.1&quot; ] &amp;&amp; [ $IF=&quot;eth0&quot; ]; then</p>
<p>	ping -q -c 1 $SERVER<br />
	if [ $? -eq  0 ]<br />
	then<br />
	    /usr/bin/notify-send $SCRIPTNAME &quot;Starting backup to $SERVER&quot; --icon=dialog-information<br />
	    /usr/bin/rsync -e '/usr/bin/ssh -i /home/foobar/.ssh/foobar_home' -av --delete --exclude-from=stevebackup.exclude . foobar@192.168.1.2:laptopbackup/ &gt; .laptopbackup.log<br />
	    if [ $? -eq  0 ]<br />
	    then<br />
		/usr/bin/notify-send $SCRIPTNAME &quot;Backup to $SERVER finished&quot; --icon=dialog-information<br />
		echo &quot;$curr&quot; &amp;&gt; .laptopbackup<br />
	    else<br />
		/usr/bin/notify-send $SCRIPTNAME &quot;Backup to $SERVER failed&quot; --icon=dialog-information<br />
		mail -s &quot;laptopbackup: Error&quot; skrodzki@stevekist.de &lt; .laptopbackup.log<br />
	    fi<br />
	else<br />
	    /usr/bin/notify-send $SCRIPTNAME &quot;Server $SERVER not reachable&quot; --icon=dialog-information<br />
	fi<br />
    fi<br />
fi</p>
<p>

Party machen… aka Playlists erstellen.

So, bevor ich es vergesse, schreib ich hier mal auf, wie man eine Playliste für eine Party unter Linux erstellt und dann quer über seine Systeme verteilt…

Also so ne Standard-Playliste heisst ja foo.m3u und besteht eigentlich nur aus Dateinamen mit ihren Pfaden. Mehr geht auch, siehe z.B. hier.  Playlisten kann wohl auch mehr oder minder jeder Player und weil eben unter Linux auch m3u, weils offen ist, trotzdem hat mir quodlibet am besten gefallen, da man da Songs einfach mit der rechten Maustaste zu jeweiligen Listen hinzufügen kann und mit einem Haken auch sieht, ob der Song schon drin ist. Ausserdem kann quodlibet die playlists auch mit relativem Pfad speichern. So geht sie eigentlich mit jedem Player und auch mit den mit kopierten Stücken, wenn die Pfade bleiben.

Weil man für die Party evtl. ein schwächeres Gerät hat, welches nicht genug Speicher für die komplette Musiksammlung hat. Kann man diese ja anhand der playlisten kopieren. Hierzu kopiere ich die auf meinem Serverlein vom Verzeichnis “music” in ein Verzeichnis “playlistmusic” mittels folgendem Befehl:

sed "s/#.*//g" < party.m3u | sed "/^$/d" | while read line; do cp --parents "${line}" '../playlistmusic/'; done

Für mehrere Playlisten macht man das für jede Playliste hintereinander. Jetzt noch die playlisten auch in das playlistmusic verzeichnis kopieren. Fertig. Dieses Verzeichnis ist nun komplett eigenständig funktionsfähig und die Musikstücke sind in der gleichen Ordnerstruktur wie im Ausgang vorhanden…

So, jetzt noch die Mucke aufs Android Device, z.B. mit rsync backup. Da muss man keine Kabel anschliessen und es ist eigentlich schnell genug und einmal konfiguriert geht es.
Jetzt noch Playlist Backup nehmen, um die m3u dem Android bekannt zu machen, und gut ist. Als Party Player wird wohl Cross DJ eingesetzt werden, mal schauen, ob ich dann korrigieren muss, dass das alles nicht läuft. Aber wenn nicht, kommt die Mucke auf nen alten Laptop und ich nehme Mixxx.