Einträge über taskwarrior

Taskwarrior Context, extended

Wie man Taskwarrior auf einem uberspace installiert, hatte ich ja schon geschrieben. Dort erwähnte ich schon, dass ich Taskwarrior nicht nur für die private Aufgabenverwaltung nutze, sondern auch dienstliche Tasks damit verwalte. Nun ist Taskwarrior allerdings so aufgebaut, dass alle Tasks einer Taskwarrior-Instanz in einer gemeinsamen Datensenke landen. In meinem Fall ist das der Taskserver, der auf dem uberspace läuft. Schaue ich nun zu Hause meine Taskliste an, sehe ich auch alle dienstlichen Tasks, im Büro auch alle privaten. Nicht sehr schön.

Um diesem Problem etwas entgegenzusteuern, hat das Taskwarrior-Team Contexts eingeführt. Dabei handelt es sich im Grunde genommen um einen permanenten Filter, der bei jedem Kommando angewendet wird. Ein Beispiel: Ich möchte einen Context mit dem Namen work, der nur Tasks anzeigt, die das Tag +work haben. Das Kommando task context define work +work erstellt ebendieses Context. In der Konfigurationsdatei wird ein solcher Context ganz einfach mit der Zeile context.work=+work hinterlegt. Um diesen Context nun zu nutzen, muss er noch per task context work aktiviert werden. Rufe ich nun task list auf, werden nur noch die Tasks aufgelistet, die mit dem Tag +work versehen sind.

Prinzipiell eine super Sache. Nach einiger Gewöhnungszeit stieß ich allerdings schnell an die Grenze, dass mir dieses Konzept etwas zu unflexibel ist. Wenn ich im Büro sitze und mal eben schnell etwas in meiner privaten Taskliste nachschauen möchte, muss ich den Context von work nach private wechseln, dann mein Kommando ausführen, um dann wieder von private zurück nach work zu wechseln. Das ist gelegentlich in Ordnung, macht man das aber häufiger, wird es schnell nervig.

Auf der Suche nach einer Lösung für dieses Komfortproblem wurde ich auf der Taskwarrior-Mailingliste in eine Richtung geschubst, die ich gar nicht auf dem Schirm hatte. Dirk Deimke schlug vor, diese Context Peeking mit Hilfe eines Shell-Scripts zu lösen. Nun bin ich mit meinen gut drei Jahren Linux-Erfahrung ja noch eher ein Linux-Kindergartenkind, daher bin ich selbst gar nicht auf diese Idee gekommen, aber wie das mit Kindergartenkindern so ist, fangen sie sofort an zu spielen, wenn man ihnen ein neues Spielzeug gibt. So habe ich es auch gemacht.

Das resultierende Shell-Script sieht nun so aus:

# Make task work with contexts like I want it to
task () {
  # get the task binary to avoid recurrence
  tb=`which task`
  # extract the selected context by matching the regex
  # context has to be the first argument and consist only
  # of alphanumeric characters
  context=`echo $1 | egrep -o "(=)[[:alnum:]]*"`
  # check whether there was a = character
  if [ -n "$context" ]
  then
    # remove the = char
    context=`echo $context | cut -c 2-`
    # check whether a context name was given
    if [ -n "$context" ]
    then
      # name given, temporarily set this context
      $tb rc.context:$context "${@:2}"
    else
      # no name given, temporarily set no context
      $tb rc.context:none "${@:2}"
    fi
  else
    # no = char, so just call task with all arguments
    $tb "${@}"
  fi
}

Was macht das Script nun? Zum einen habe ich die Möglichkeit, beim einem Aufruf von Taskwarrior einen bestimmten Context vorzugeben. Dazu nutze ich die Syntax =Context. Will ich also auf der Arbeit kurz in meine private Liste schauen, verwende ich den Aufruf task =private list.

Zusätzlich zur Wahl eines bestimmten Contexts kann ich allerdings auch das Context-Feature temporär ausschalten. Dazu verwende ich =ohne Contextnamen. Der Aufruf task = list zeigt mir somit alle Tasks, unabhängig ihres Contexts, an.

Bisher hat mir dieses simple Script schon viele gute Dienste geleistet. Und außerdem hat es mir wieder einen weiteren Teil der Linux-/Unix-Welt nähergebracht.

Zertifikate für den Taskserver erneuern

Wenn man den Taskserver an Hand der Anleitung auf taskwarrior.org installiert hat, haben die Zertifikate zur Absicherung des Datenverkehrs nur eine Haltbarkeit von einem Jahr. Stolpert man dann irgendwann über Meldungen wie

Handshake failed. Error in the certificate.

Sync failed. Could not connect to the Taskserver.

dann ist bestimmt das Zertifikat abgelaufen und muss somit erneuert werden. Die Haltbarkeit des verwendeten Zertifikats kann man sich mit Hilfe des Tools certtool anzeigen lassen:

Wenn man nun sieht, dass das Zertifikat abgelaufen ist, muss ein neues erstellt werden. Dazu geht man wie bei der Installation des Taskservers vor:

  1. Man wechselt in das Installationsverzeichnis des taskd, in meinem Fall ist das die lokale Kopie des git-Repositories, welche im Verzeichnis ~/taskd.git liegt. cd ~/taskd.git/pki
  2. Dort überprüft man die Informationen in der Datei vars.
  3. Wenn dort noch alles stimmt oder man die Daten an die eigenen Bedürfnisse angepasst hat, erstellt man per ./generate ein neues Serverzertifikat.
  4. Die so erstellen Zertifikate kopiert man via cp ca.*.pem server.*.pem $TASKDDATA in das Verzeichnis, in welchem der Taskserver seine Daten ablegt.
  5. Nun muss noch ein neues Clientzertifikat erstellt werden: ./generate <user-name>
  6. Die beiden zusätzlichen Dateine <user-name>.cert.pem und <user-name>.key.pem müssen nun noch auf allen Sync-Clients in die dortigen $TASKDATA-Verzeichnisse kopiert werden.

Nun sollte die Synchronisierung wieder anstandslos funktionieren.

Weitere Informationen gibt es auf der Taskwarrior-Webseite zum Thema Server und Client.

Taskwarrior auf uberspace

Für die Verwaltung von Todos und anderen Dingen, die nicht in Vergessenheit geraten sollen, nutze ich Taskwarrior. Angefangen habe ich damit auf meinem Laptop, aber schon recht schnell wollte ich auch einen Taskwarrior in der Hosentasche, sprich auf dem Smartphone haben. Und auf der Arbeit leistet er mir auch gute Dienste. Allerdings bietet Taskwarrior keine Cloud-Lösung, um Daten zu synchronisieren. Und selbst wenn es diese Möglichkeit gegeben hätte, stellt sich noch immer die Frage, ob man sie auch hätte nutzen wollen. Nun ist es glücklicherweise so, dass es mit dem Taskserver eine Möglichkeit gibt, die Synchronisierung selbst zu bauen. Im Folgenden will ich daher beschreiben, was nötig ist, um den Taskserver auf einem uberspace zu installieren und was darüber hinaus noch für die Synchronisation der Daten erforderlich ist.

Taskserver installieren

Es gibt eine sehr ausführliche Dokumentation auf der Taskserver-Seite, wie man den Server installiert. Ich gehe daher an dieser Stelle nicht im Detail auf alle Punkte ein, sondern beschreibe nur die für uberspace interessanten Schritte etwas genauer.

Ich installiere den Taskserver aus einem tarball-Archiv, wer möchte, kann sich aber auch gern das git-Repository clonen.

Zunächst laden wir uns also das Archiv mit dem Quelltext, entpacken und bauen es. Das ist relativ einfach, da uberspace alle benötigten Tools bereitstellt und daher nichts zusätzliches installiert werden muss. Einzige Besonderheit und Abweichung von der Taskwarrior-Doku ist, dass wir de Taskserver nicht in /usr/bin installieren wollen. Dieses Verzeichnis ist auf einem shared host tabu, stattdessen gibt es das Verzeichnis ~/bin. Das erzielen wir dadurch, dass wir cmake ein INSTALL_PREFIX übergeben, das auf unser Userhome ~ verweist.

Prinzipiell ist es egal, in welches Verzeichnis der Taskserver installiert wird, letztendlich sollte dieses Verzeichnis lediglich in der Umgebungsvariable PATH eingetragen sein, damit er von überall erreichbar ist.

$ curl -LO http://taskwarrior.org/download/taskd-latest.tar.gz
$ tar -xzf taskd-latest.tar.gz
$ cd taskd-1.1.0
$ cmake -DCMAKE_BUILD_TYPE=release -DCMAKE_INSTALL_PREFIX=~ .
. .
$ make
...
$ make install
...

Nun sollte der Taskserver im eigenen Binary-Verzeichnis ~/bin vorhanden sein.

Taskserver einrichten

Als nächstes muss der Taskserver konfiguriert werden. Damit wird zum einen sichergestellt, dass der Taskserver erreichbar ist, zum anderen, dass nur berechtigte Personen an die Daten des Taskservers kommen. Da es auch hierzu wieder eine sehr gute Dokumentation auf der Webseite des Taskservers gibt, spare ich mir zum einen die Arbeit, es hier noch einmal zu beschreiben, und vermeide damit aber auch das Risiko, dass diese Anleitung einmal veraltet sein sollte, weil sich etwas am Setup des Taskservers geändert hat.

Auch bei diesem Schritt muss man lediglich darauf achten, dass der vorgeschlagene Pfad für die Daten des Taskservers, nämlich /var/taskd, auf einem shared host nicht verfügbar ist. Hier bietet sich auch wieder die lokale Variante ~/var/taskd an.

Taskserver erreichbar machen

Während der Einrichtung des Taskservers wurde ein Port gewählt, über den der Taskserver erreichbar sein soll. Dieser Port ist allerdings nicht unbedingt frei, kann also gegebenenfalls bereits von einem anderen Ubernauten auf euren host benutzt werden. Daher gibt es ein Script, um einen Port anzufordern und diesen auch gleich in der Firewall freizuschalten.

$ uberspace-add-port -p tcp --firewall
🚀  All good! Opened tcp port 65432.

Dieser Port, der bei euch natürlich anders lauten kann, muss nun noch in der Konfigurationsdatei des Taskservers eingetragen werden:

$ taskd config server xxxx.uberspace.de:65432

Nun ist der Taskserver fertig eingerichtet und von außen erreichbar. Er kann nun via taskdctl start gestartet werden.