Versagter Alsterlauf

Dieses Jahr war ich außergewöhnlich selten in Hamburg. Letztes Wochenende war tatsächlich das erste, dafür aber nicht das letzte Mal. Über Weihnachten und zum Congress werde ich auch dort sein.

Da eigentlich sogar relativ viel Zeit war, wir waren von Donnerstag bis Sonntag dort, habe ich meine Laufsachen mitgenommen und mich schon auf meine traditionelle Alsterrunde gefreut. Zum einen ist die Runde wirklich schön. Ohne Verkehr und die ganze Zeit am Wasser entlang, mal abgesehen von dem je 2km langen Hin- und Rückweg. Außerdem freue ich mich über jeden Kilometer, den ich nicht auf meinen gewohnten und mittlerweile ziemlich langweiligen, Strecken zurücklegen muss.

Hoffen auf die letzte Chance des Jahres über Weihnachten.

1000km+

Wie in jedem Jahr habe ich auch Anfang dieses Jahres wieder das Ziel 1000-Laufkilometer-Plus ausgerufen. Das Klingt erst einmal nach gar nicht so besonders viel. Doch im vergangenen Jahr habe ich diese wirklich erst auf den letzten Drücker, nämlich am 30.12.2014 geschafft.

Für gewöhnlich laufe ich ca. 10km Runden. D.h. also 100 mal laufen, verteilt auf 52 Wochen. Zweimal pro Woche klingt erst einmal auch nicht so viel. Es kommen aber immer noch Urlaube und Krankheiten hinzu, und ganz schnell wird es knapp.

Dieses Jahr hat wirklich schleppend angefangen. Ich bin einfach nach der Arbeit nicht mehr so gut los gekommen. Winter und Dunkelheit haben ihr übriges getan. Dennoch habe ich bis Ende Juni ganz knapp über 500km geschafft. Der Juni stand ganz im Zeichen unserer 4 wöchigen Radtour in Südschweden. Also kein einziger Laufkilometer. In den August bin ich wegen einer Hochzeit und zurück-sei Besuchen auch erst am 13. gestartet.

Da meine Alleine-Elternzeit angefangen hat, hatte ich völlig berechtigte Hoffnung die 1000km auch in diesem Jahr wieder zu knacken. Und tatsächlich. Das Laufen mit dem Kleinen klappt wirklich hervorragend. Wir sind mit einem alten Chariot Cougar I unterwegs und für den Kleinen scheinen die 1 bis 1 1/2 Stunden sehr ertäglich zu sein. Die meiste Zeit schläft er. Doch selbst wenn er aufwacht, hat er Spaß. So ausgestattet sind wir 3 bis 4 mal die Woche unterwegs und schrubben Kilometer. Das schönste daran. Wir können raus wann immer wir wollen. Trotz kurzer Tage heißt das: Immer im hellen laufen!

Lange Rede kurzer Sinn. Bereits Mitte November habe ich die 1000km erreicht. Alles was jetzt kommt ist Zugabe :-)

Im November auf der Insel Poel

/galleries/insel-poel/IMG_6756.thumbnail.jpg

Am vergangenen verlängerten Wochenende haben wir uns eine kleine Ferienwohnung in Kaltenhof auf der Ostseeinsel Poel gemietet. Gefühlt besteht ganz Kaltenhof nur aus Ferienwohnungen.

Gestartet sind wir am Gesundbrunnen. Von dort aus die ODEG nach Wismar genommen. In Wismar angekommen, haben wir uns mit den Rädern direkt in Richtung Poel gemacht, um noch im hellen dort anzukommen.

/galleries/insel-poel/IMG_6759.thumbnail.jpg

Auf der Fahrt zwischen Wismar und Poel war noch hervorragendes Wetter. Nicht zu kalt, nicht zu warm, und da wir relativ spät unterwegs waren, mit herrlichem Licht.

/galleries/insel-poel/IMG_6763.thumbnail.jpg

In Kaltenhof angekommen, haben wir nur noch die Wohnung bezogen und selbst gepflückte Äpfel aus dem Garten geschenkt bekommen. Freitag war es noch schön und wir haben in zwei längeren Spaziergängen den nördlichen Teil der Insel erkundet.

/galleries/insel-poel/IMG_6770.thumbnail.jpg

Unser erster Weg hat uns natürlich ans Meer gezogen.

/galleries/insel-poel/IMG_6786.thumbnail.jpg

Unsere Runde ging von Kaltenhof über Am Schwarzen Busch und Kirchdorf wieder zurück. Von der Ostsee weg ging es durch Felder und kleine Häuserssammlungen.

/galleries/insel-poel/IMG_6790.thumbnail.jpg

Vorbei an einer kleinen Fahrradwerkstatt.

/galleries/insel-poel/IMG_6792.thumbnail.jpg

Gegen Nachmittag sind wir nach Gollwitz und von dort entlang der Küste wieder zurück.

/galleries/insel-poel/IMG_6797.thumbnail.jpg

Entlang am Leuchtturm Gollwitz

/galleries/insel-poel/IMG_6800.thumbnail.jpg

… durch einen kleinen Waldstreifen direkt an der Küste. Da keine Blätter mehr an den Bäumen hingen konnten wir die ganze Zeit über das Wasser sehen.

/galleries/insel-poel/IMG_6809.thumbnail.jpg

Entlang der Küste gibt es immer wieder Lichtungen mit einer Trimm dich Station. An jeder Lichtung ein anderes Gerät. Dazu die Beschreibung was man überhaupt tun soll und wie das Gerät gedacht ist. Bei dem Ausblick macht das vielleicht sogar Spaß?

/galleries/insel-poel/IMG_6819.thumbnail.jpg

Für den Samstag war das Wetter nur solala gemeldet. Eigentlich für den ganzen Tag Schauer und heftiger Wind… immerhin mit 3 Sonnenstunden. Mit den ersten blauen Löchern im Himmel haben wir uns auf die Fahrräder geschwungen und sind, gegen ordentlichen Wind an, nach Timmendorf gefahren. Dafür sind wir am Strand durch Kit-Surfer entschädigt worden.

In Timmendorf haben wir die erste und einzige offene Lokalität des Wochenendes gefunden. In einem einsamen Cafe gab es mittelmäßigen Kaffee und Kuchen, wenigstens zu günstigen Preisen.

/galleries/insel-poel/IMG_6863.thumbnail.jpg

Der erste Teil des Rückweges ging entlang der Steilküste. Zuerst direkt, dann mussten wir mit den Rädern hinter ein Waldstück. Es wurde einfach zu gefährlich mit Hänger.

Uns hat ein orderntlicher Regen erwischt, der nicht mehr aufhören wollte. Gut, dass wir vernünftige Regenklamotten haben.

/galleries/insel-poel/IMG_6877.thumbnail.jpg

Ein schöner Tag, für einige von uns sehr anstrengend ;)

Der Sonntag bestand nur aus der Fahrt durch den Regen zurück nach Wismar und der Zugfahrt zurück.

Ein wirklich schönes Wochenende. Poel ist auf jeden Fall eine Empfehlung. Vielleicht nicht unbedingt im Sommer, im Frühling und Herbst ist es dort schön ruhig. Eigentlich sollte man viel häufiger solche kleinen Trips unternehmen.

… Alle Fotos

Wir werden alle störben… zumindest xmpp *heul*

Diese Nachricht erreichte mich zumindest gerade via besagtem Protokoll, zusammen mit dem Hinweis auf den Artikel auf Heise FastMail: Google und Facebook graben XMPP das Wasser ab.

Doch was ist eigentlich passiert? Eigentlich nichts weiter. XMPP ist einfach nur wieder in der Nische, in der es auch vor Talk und Facebook Chat war.

XMPP hat einfach nur den Weg in die breite Masse nicht gefunden. Dies wird zum einen technische Gründe haben, als auch auf den Plattformgedanken der großen Player zurück zu führen sein. Facebook und Google haben kein Interesse an einem dezentralen Chat-Netzwerk.

Dazu sehe ich keine XMPP-Killer-App. Usability ist mitunter eine Katastrophe. Es ist nach wie vor schwierig Dateien untereinander auszutauschen! Ganz zu schweigen vom Einrichten neuer Accounts oder Video-Chats. Ja. Die Leute wollen Video-Chats. Und ja, es ist technisch auch mit XMPP Jingle möglich. Doch erklär das mal jemand der eigenen Mutter, wenn Video-Chat nicht funktioniert, weil man lieber Client-XY benutzt, und sie nur ihren Enkel sehen möchte.

Wenn XMPP die beste Erfindung seit geschnitten Brot wäre, würde es wohl kaum so viele Chat-Systeme geben, für die sich ein eigenes Protokoll ausgedacht wurde. Und das nicht nur bei den beiden "Großen". Siehe Telegram, matrix.org, Slack, you name it.

Man mag das alles ganz schlimm finden. Auch dass man gefühlt für jeden Menschen mit dem man kommuniziert eine andere App auf dem Smartphone installiert hat. Doch sterben wird XMPP meiner Ansicht nach nicht. Mir ist es völlig unklar wie viele und welche Chat-Systeme unter der Haube auf XMPP setzen. Es sind sicherlich noch einige. Außerdem steht es jedem frei einen XMPP-Server zu betreiben und somit das dezentrale Netzwerk zu stärken.

Ich persönlich bin weit davon entfernt an etwas festzuhalten nur weil es schon immer da war. Vielleicht funktioniert es eben doch nicht so gut wie viele Messanger es benötigen. Wenn XMPP wirklich zu Grunde geht, dann soll es wohl so sein. Es wurde IMHO versäumt, das Umfeld zu entwickeln, das die Leute brauchen.

Another example for bad testing

Today I discovered this in salt.

Someone tries to test the function iptables.get_saved_rules in salt/tests/unit/modules/iptables_test.py#L149

@patch('salt.modules.iptables._parse_conf', MagicMock(return_value=False))
def test_get_saved_rules(self):
    '''
    Test if it return a data structure of the rules in the conf file
    '''
    self.assertFalse(iptables.get_saved_rules())

But in fact acutally nothing is tested at all. Literally nothing.

So lets have a look at the corresponding code. salt/salt/modules/iptables.py#L471

def get_saved_rules(conf_file=None, family='ipv4'):
    '''
    Return a data structure of the rules in the conf file
    CLI Example:
    .. code-block:: bash
        salt '*' iptables.get_saved_rules
        IPv6:
        salt '*' iptables.get_saved_rules family=ipv6
    '''
    return _parse_conf(conf_file, family)

This function just forwards some parameters to another function _parse_conf. The above test mocks out exactly this call, but does not check anything about the mock. This test does not even cover deleting the only statment in this function! This is caused to self.assertFalse, which is not very strict and accepts None as False.

However, I discovered this code, since ipv6 is not working correctly, due to wrong parameter passing to _parse_conf. Having a look there, shows us the use of keywords-only.

def _parse_conf(conf_file=None, in_mem=False, family='ipv4'):
    '''
    If a file is not passed in, and the correct one for this OS is not
    detected, return False
    '''
    ...

So in case of get_saved_rules, ipv4 is passed as parameter in_mem instead of family. So the code always runs the ipv4-path.

Long story short. If you are mocking. Check if your expected call really happened. This code really tests the call for _parse_conf, with expected parameters:

def test_get_saved_rules(self):
    '''
    Test if it return a data structure of the rules in the conf file
    '''
    mock = MagicMock(return_value=False)
    with patch.object(iptables, '_parse_conf', mock):
        self.assertFalse(iptables.get_saved_rules())
        mock.assert_called_with(conf_file=None, family='ipv4')

Even this is not best practice, since calling stuff on mock objects, also silently irgnores errors. e.g. mock.fajdslksahgalds() would work totally fine, without any info. Most important in such cases. Write your test before the code, so you see the test failing once.

… Yes. I opened pull requests for both issues.

Wie hilft $orchestrationtool bei einer Datenmigration

TL;DR: Vollautomatisierung hilft die Migration immer wieder zu testen

In der letzten Zeit habe ich diverse Workshops zum Thema Orchestration gegeben. Zusammen mit meinem geschätzten Kollegn Jan haben wir Gruppen von 3 bis max. 10 Leuten den umgang mit OpenStack Orchestration (Heat) nahe gebracht. Dabei haben wir uns ausschließlich auf Heat Orchestration Templates (HOT) konzentriert. Unsere Teilnehmer waren in einigen Fällen Admins oder DevOps (sie wurden als solche vorgestellt) und weitaus häufiger Software Engineers/Architects.

So viel erst einmal zur Situation. Heat verwende ich hier nur als Synonym für jedes x-beliebige Tool, mit dem eine verteilte Anwendung aufgesetzt werden kann. Ein weiteres Beispiel, dieses mal für Container, wäre Googles Kubernetes.

Was haben wir den Teilnehmern beigebracht?

Nachdem wir die einzelnen OpenStack-Komponenten gezeigt haben, die sich mittels Heat steuern lassen, sind wir direkt zu Heat selber und HOT gegangen. Als einfaches Szenario hat immer eine Applikation mit mehreren Application-Servern, einem davor sitzenden Loadbalancer und einem Datenbank-Server gedient. Auf primitivste Weise haben wir ein Service-Discovery gebaut, so dass neue Application-Server ins LoadBalancing aufgenommen werden. Das zuletzt verwendete Beispiel findet sich im Github Repo example-projects.

Wir haben gezeigt wie mittels HOT eine Infrastruktur inklusive Netzwerk und Firewall ausgerollt werden kann. Innerhalb der VMs wird (wie auch bei AWS) cloud-init angestoßen. Mittels diesem werden die nötigen Anwendungen installiert, konfiguriert und gestartet. Mit diesen kleinen Automatisierungen ist es auch möglich beliebig viele Application-Server nachträglich einzuzufügen. Natürlich gehört in der Realität etwas mehr dazu VMs komplett zu provisionieren und eine Applikation zu deployen. Aber als Proof-of-Concept ist das immer ganz gut angekommen.

Wir wollen den Teilnehmern mehr mitgeben

Zum einen zeigen wir, wie einfach es sein kann, eine komplett neue Infrastruktur mit allen Komponenten hoch zu ziehen. Viel wichtiger aber ist die sensibilisierung auf Cloud-Best-Practices. Siehe dazu The twelve-factor app, oder mein persönliches Fazit zu docker.

Für ein Projekt ergeben sich durch die vollständige Automatisierung gleich mehrere Vorteile. So können Entwickler und QA die Applikation quasi im Production-Environment testen. Dadurch wird die Automatisierung auch immer und immer wieder getestet. Man hat also immer Übung für den Ernstfall: Alles muss von Grund auf neu aufgebaut werden.

Das starten und provisionieren von neuen Instanzen wird durch die Automatisierung einfacher. Das bedeutet, dass kein dedizierter Personenkreis benötigt wird um die Application-Server hoch zu skalieren. Womit ich auf keinen Fall Admins als überflüssig erachte! Die können sich aber auf wichtige Dinge konzentrieren, statt Arbeit zu erledigen, die man auch einem Äffchen trainieren könnte. Nehmen wir einfach folgendes an. Der einzige Admin, der die Infrastruktur aufsetzen kann, ist vor dem Black Friday krank. Es müssen aber unbedingt noch mehr Application-Server. In unserem Szenario kein Problem. Im Endeffekt kann jeder(tm) einen Heat-Stack mit Application-Servern daneben stellen. Sicherlich gilt hier Faktoren wie die maximale Anzahl an Verbindungen auf dem DBMS zu beachten. Aber das führt hier zu weit.

Wie auch für das Beispiel des Black Fridays, kann ein neues Release der Applikation durch einen zusätzlichen Heat-Stack ausgerollt werden. Dabei werden einfach neue Instanzen mit der neuen Version gestartet und die alten einfach abgeschaltet.

Genau an dieser Stelle kommt häufig die Frage: Wie hilft uns Heat bei einer Datenmigration?

Wie hilft uns Heat bei einer Datenmigration?

(Wobei als Datenmigration auf Nachfrage immer eine Änderung des SQL-Schemas war.)

Also… Heat bzw. jedes andere Orchestrationtool hilft in erster Linie genau gar nicht. Zu erst einmal sollte man wissen, dass ein ALTER TABLE in den meisten DBMS nicht um sonst ist (siehe z.B. Avoiding MySQL ALTER table downtime, Schema changes – what’s new in MySQL 5.6?). Gerade wenn eine Tabelle groß wird, sollte man wirklich einen geeigneten Migrations-Plan haben!

Auf jeden Fall gehört eine Migration nicht in den Code (schon gar nicht in den Startup-Code) eines neuen Releases! Keiner möchte eine Situation haben, in der ein neues Release installiert wird und gleich die laufende Production-Umgebung mit den Abgrund zieht (z.B. durch einen expliziten Lock durch ein ALTER TABLE). Die einfachste Möglichkeit Schema-Änderungen zu verhindern ist wohl IKEA Kloppe. Einfach mal damit bei dem entsprechenden Entwickler vorbeischauen.

Neben den möglichen Problemen bei einem ALTER TABLE, kann die vorherige Version der Applikation (App-1.0) mit dem neuen Schema nichts anfangen und daher in Fehler laufen. Im besten Falle hält man die Schema-Änderungen so klein, dass genau dies nicht passiert. Ein zusätzliches Feld wird einem ORM z.B. noch nicht weh tun. Ein Feld entfernen wird man dagegen erst wirklich wenn es nur noch Applikationen gibt, die ohne dieses Feld auskommen.

In jedem Fall sollte mit versionierten DB-Schemata gearbeitet werden, so dass App-2.0 auch mit dem Schema von App-1.0 arbeiten kann, dafür aber ggf. Features noch nicht freigeschaltet sind.

Bleibt die zu vermeidende Situation: Man benötigt ganz ganz ganhanz dringend ein anderes Schema und bricht dadurch App-1.0. Hier gilt es App-2.0 erst einmal überall auszurollen. Ggf. zuerst einmal mit reduziertem Feature-Set. Natürlich wird App-2.0 ohne Migration der DB an genau der selben Stelle fehlschlagen wie auch App-1.0. Doch lässt sich hier gezielt das neue Schema probieren, die Exception fangen und auf das alte Schema zurückfallen.

Vollautomatisierung hilft

Natürlich stimmt meine Aussage von oben nicht. Orchestration und Vollautomatisierung hilft sehr wohl. Zwar gehört die Logik für dem Umgang mit Migrationen in die Applikation, also in den Kompetenzbereich der Entwickler, doch nicht die Migration selbst. Die Vollautomatisierung hilft einfach und schnell ein komplettes Setup aufzubauen und die Migration immer und immer wieder zu testen, so lange bis das Zero-Downtime-Deployment funktioniert. Ist die Änderung doch zu groß um diese ohne Downtime durchzuführen, kann wenigstens der zu erwartende Zeitraum abgeschätzt werden und entsprechende Maßnahmen treffen.

Monkey patch a puppet provider

I just wanted to monkey patch the puppet package provider for gentoo portage.

But why?

# puppet resource package

Only shows packages installed by puppet, but not packages installed by hand. The apt/dpkg- and yum/rpm-provider list all packages.

It was not enough to place a lib/puppet/provider/package/portage.rb. In all my tests, the original behavior was kept. I only want to replace one function.

But how?

When registering new type or providers, etc, puppet is doing a bunch of magick in the background. So first, I have to figure out the name of the automagically created class.

https://github.com/puppetlabs/puppet/blob/master/lib/puppet/provider/package/portage.rb#L4

Puppet::Type.type(:package).provide :portage, :parent=> Puppet::Provider::Packagedo
  ...
end

Trying this in irb

irb(main):001:0> require 'puppet'

irb(main):002:0> Puppet::Type.type(:package).provide :SOMETEST
=> Puppet::Type::Package::ProviderSometest

Hmm. Is it that simple? In one of our modules, I generated a file lib/puppet/provider/package/portage_zz.rb

require 'puppet'


class Puppet::Type::Package::ProviderPortage
    private
    def self.eix_search_format
      "'<category> <name> [<installedversions:LASTVERSION>] [<bestversion:LASTVERSION>] <homepage> <description>\n'"
    end
end

I called it portage_zz.rb, to be sure it will be loaded after the regular portage.rb.

However, the puppet run with pluginsync shipped this file. And... puppet resource package list all packages :)

https://github.com/puppetlabs/puppet/pull/3765

redis subscribe to key

Redis has a buildin pubsub mechanism, but by default it is not possible to listen on specific keys. Redis 2.8 intruduced Keyspace Notifications , to which you can subscribe.

First of all. This feature is disabled by default, so we need to enable it

$ redis-cli config set notify-keyspace-events KAE

This little python-script listens on keyspace-Events containing stash:silence/*

#!/usr/bin/env python

import redis

r = redis.StrictRedis()

pubsub = r.pubsub()
pubsub.psubscribe('__keyspace@*:stash:silence/*')
for msg in pubsub.listen():
    print(msg)

Results to:

{'pattern': '__keyspace@*:stash:silence/*', 'type': 'pmessage', 'channel': '__keyspace@0__:stash:silence/controller.local/check_instance_snat', 'data': 'expired'}

{'pattern': '__keyspace@*:stash:silence/*', 'type': 'pmessage', 'channel': '__keyspace@0__:stash:silence/compute.local', 'data': 'set'}
{'pattern': '__keyspace@*:stash:silence/*', 'type': 'pmessage', 'channel': '__keyspace@0__:stash:silence/compute.local', 'data': 'expire'}

Why?

We are using sensu for monitoring. If someone press the stash-Button (or creates a stash via the sensu-api) we want to send out an ACK email. The sensu-api only inserts into redis and does not inform anyone about the stash. It would be possible to poll the api peridically, but man... it's 2015.

StackStorm

TL;DR: StackStorm ist ein Automatisierungsframework. Es gibt eine zentrale Stelle an der Events einlaufen und Aktionen veranlasst werden. Es ist relativ einfach eigene Automatisierung darin zu realisieren.
Siehe: http://stackstorm.com/product/
Erstes Fazit:
Sehr "pluggable". Lässt sich mit so gut wie jedem System zusammen stecken. StackStorm hat so viele Anwendungsfälle wie man sich vorstellen kann. Darf nur in einem Vertrauten Netz stehen. Zumindest habe ich keine auth-Möglichkeit gesehen. Fühlt sich aber noch hakelig an.

Zuerst einmal. Worum geht es eigentlich?

Auf der Suche nach eine Orchestrierungslösung bin ich über StackStorm http://stackstorm.com/ gestolpert, die auf den ersten Blick recht vielversprechend aussieht.

Doch einen Schritt zurück. Was meine ich hier mit "Orchestrierung"?
Dinge sollen im besten Fall automatisch auf Computern passieren. Viele Szenarien lassen z.B. sich mittels puppet und mcollective lösen, doch oft stößt man an Grenzen. In solchen Fällen werden häufig Scripte geschrieben, die auf dem kurzen Weg über das Configuation Management ausgerollt werden. Je nach Funktion wird noch ein cronjob ergänzt. Dadurch wächst relativ schnell ein Wildwuchs an Scripten an und man verliert schnell den Überblick wann und wo, was passiert. Im schlimmsten Fall rufen sich Scripte noch gegenseitig über ssh auf.

Oft lassen sich diese Arbeitsanweisungen auf sowas wie "Hier ist X passiert, mache dort Y".

Bsp.: Nach einem git-push wird Jenkins getriggert. Jenkins läuft durch und triggert im Erfolgsfall das Ausrollen auf entsprechenden Nodes.

Technisch ist dies sicherlich lösbar. Hie und da ein Script, vielleicht noch irgendwo ein cronjob, und fertig ist die Laube. Der Nächste wundert sich dann wieder ob der Magie und muss die Kette versuchen zu debuggen. Bei Umzügen brechen dann Ketten, an die niemand mehr gedacht hat.

Ich stelle mir einen zentralen Punkt (bei dem es möglich sein muss, ihn redundant auszulegen) vor, in dem Arbeitsanweisungen definiert werden. Und genau an diesem Punkt bin ich auf StackStorm gestoßen.

StackStorm liefert u.A. sensor, trigger, action und rule. In jede Komponente kann man eigene hinzufügen.

StackStorm selbst besteht aus mehreren Services, die sich je um spezielle Aufgaben kümmern. Die Services kommunizieren über amqp-system wie rabbitmq.

Z.B. führt die action core.remote über ssh (falls gewünscht mit sudo) das übergebene Kommando auf einem entfernten aus. core.http ruft einen entfernten Webhook an. An der Stelle "remote" möchte man vielleicht über eine Queue, statt ssh nachdenken. Die Möglichkeit StackStorm zu erweitern macht das recht einfach.

Sensoren verbinden StackStorm mit externen Systemen und registrieren oft trigger. Webhooks können aber separat als trigger eingerichtet werden.

StackStorm kann Webhooks als trigger zur Verfügung stellen. Angenommen wird jedes beliebige json. Es ist auch möglich cron-Tigger zu definieren.

Rules stecken trigger und action anhand von Kriterien zusammen. Wobei das Kriterium optional ist.
Bsp:
---
    name: "examples.webhook_file"
    description: "Sample rule dumping webhook payload to a file."
    enabled: true

    trigger:
        type: "core.st2.webhook"
        parameters:
            url: "sample"

    criteria:
        trigger.body.name:
            pattern: "st2"
            type: "equals"

    action:
        ref: "core.local" ### passiert auf dem StackStorm-Host
        parameters:
            cmd: "echo \"{{trigger.body}}\" >> /tmp/st2.webhook_sample.out"

Die rule-Engine läuft alle treffenden Regeln durch. So kann man auf ein und den selben trigger verschiedene criteria und actions zusammen stecken.

Zusätzlich lassen sich alle actions auch per command line client aufrufen.

st2 run core.local cmd="uname -a"

Jede Auführung wird von StackStorm in der Datenbank gespeichert und ist über

st2 execution list # (/get)

erreichbar. Und genau hier hatte ich in meinen Tests Probleme.

Mein Setup:

Die Installation habe ich nach http://docs.stackstorm.com/install/sources.html durchgeführt und StackStorm via tools/launchdev.sh gestartet. Meine Installation ist noch eine v0.7

sensu mit einem StackStorm-Handler ausgestattet. Dieser hat falls nötig einen Webhook in StackStorm registriert. Von außen, ohne Auth. ACHTUNG: StackStorm nicht im Netz stehen lassen! Außerdem ruft der Handler den Webhook an und lädt das sensu-JSON dort ab.

Der sensu-Hanlder kommt von StackStorm. Kann aber leider nicht mit stashes umgehen. D.h. selbst wenn es in sensu für einen Check/Host einen stash gibt, ruft der Handler trotzdem den webhook an.

Den trigger habe ich mit einer rule ohne criteria mit der action core.local cmd="echo "{{trigger.client.name}}" >> /tmp/st2.sensu.out" zusammen gesteckt.
Bei jedem sensu-Event wurde also der client.name, bei dem das Problem auftrat in eine Datei geschrieben.
---
    name: "sensu.event.process"
    description: "process incoming sensu events"
    enabled: true

    trigger:
        type: "sensu.event_handler"

    action:
        ref: "core.local"
        parameters:
            cmd: "echo \"{{trigger.client.name}}\" >> /tmp/st2.sensu.out"

Ich habe einfach dafür gesorgt, dass ein sensu-Check (der minütlich geprüft wird) rot anzeigt und somit den Webhook anruft. Als ich nach ca. 2 1/2 Wochen wieder an das Thema ging wollte execution list nicht mehr:

# st2 execution list
MESSAGE: database error: too much data for sort() with no index. add an index or specify a smaller limit

Riecht nach "Datenbank + Entwickler = BOOM".

Mit st2 execution get ID kommt man noch an bekannte Ausführungen.

Hier hätte also auch ein core.remote hosts={{trigger.client.name}} cmd="service XY restart" passieren können.
Denkt man sich später irgendwann aus, dass in einem solchen Fall automatisch ein Ticket aufgemacht werden soll. Kein Problem. "Einfach" eine zusätzliche rule einrichten.

StackStorm hat sich als extrem flexibel erwiesen. Der Phantasie sind kaum Grenzen gesetzt. Es tut weitestegehend das was man erwartet und mit Ausnahme von zu viele executions bin ich in keine großen Probleme gelaufen. Bisher habe ich mich noch nicht im reproduzeirbares Aufsetzen und Pakete gekümmert. StackStorm selber kann debian-Pakete bauen. Es gitb ein puppet-Modul (https://github.com/StackStorm/puppet-st2 ) das Pakete per wget runter lädt und installiert. Hier wäre ein repo sicherlich schöner.

Der Grund warum ich initial mit dem dev-Setup angefangen habe: Es ist einfach besser zu debuggen.

Wie baut man ein Desktopsystem für Anwender?

Das ist eine ernst gemeinte Frage. Unter Anwender verstehe ich jemanden wie meine Schwiegermutter, meinen Opa, oder den Arzthelfer.

Ich will nicht unbedingt sagen dass es einen Renter-Modus geben soll. Mit dem Problem von nicht mehr funktionierender oder verstellter Software wird man quasi ständig konfrontiert. Man denke nur an die Anmeldung beim Arzt, oder beim Amt. Ständig? Nein. Das ist übertrieben. Nur dann wenn der Anwender auch Einstellungen verändern kann. Ich kann mich zumindest nur schwer an einen Supermarktbesuch erinnern, an dem die Kasse gestreikt hat.

Aber zurück zu Desktopsystemen, ganz unabhängig vom Benutzten Betriessystem. Ein Anwender-Anwender benötigt nicht besonders viel. Natürlich wird eine Art von grafischer Oberfläche benötigt. Hier sollte eingesetzt werden, mit dem der konkrete Anwender am besten zurecht kommt und was sich am besten in das Ökosystems des Anwenders eingliedert. Besitzt der Anwender z.B. ein iPhone und ein iPad, finde ich es mehr als überlegenswert zu einem Mac zu greifen.  Benutzt der Anwender noch ein Windows XP kann man quasi alles (auch z.B. Cinnamon, oder Mac OS X) nehmen, da der Sprung eh riesig ist. Hier gilt es nicht die eigenen persönlichen Vorlieben durchzusetzen, sondern die des Anwenders!

Was benötigt der Anwender neben der grafischen Oberfläche?

Browser: Auch hier gilt. Persönliche Vorliebe ade. Wir möchten das für den Anwender am besten passende System zusammen schnüren. Unter Mac OS X wird wohl auf Safari zurückgegriffen, unter Windows auf den Internet Explorer, unter Linux ggf. Firefox. Es ist auch zu berücksichtigen welche Anwendung der Anwender auf seinem alten System verwendet. Läuft dort Firefox auch immer in der neusten Version, sollte dies auf dem neuen System berücksichtigt werden, unabhängig vom Betriebssystem.

Mailprogram: Und das nicht einmal zwingend. Liest der Anwender seine Mails über ein Web-Interface, soll das auf dem neuen System auch so bleiben.

Office-Suite: Eigentlich gilt das selbe wie oben. Am besten das gelernte Programm übernehmen, aber auf keinen Fall in der alten Version.

Foto-Suite, Chat(?): s. o.

Viel mehr fällt mir zum Thema "notwendige" Software auch schon nicht ein. Vielleicht kommt noch ein Dateibrowser hinzu. Hier kann sogar die zu verwendende Software auch gleich das Betriebsystem mit beeinflussen. Dies würde ich aber nur gelten lassen, wenn schon die neuste Version auf dem Altsystem zum Einsatz kommt. Muss man ein Update von 10 Jahren machen, kann man auch gleich auf eine andere Software umsteigen. Im besten Fall ist auf dem Altsystem schon die meiste Software in der neusten Version vorhanden.

Ist die benötigte Software soweit klar umrissen, sucht man das Betriebssystem aus. Am besten mit der betroffenen Person zusammen, obwohl sich das oft wegen akuter Ungeduld auf beiden Seiten als schwierig erweist.

Ist das Betriebssystem ausgewählt und installiert werden benötigte Programme installiert und konfiguriert. Sowohl die eigentliche grafische Oberfläche, als auch die Programme. Jedliche nicht benötigte Software fliegt runter. Es werden Panels, Docks, Icons, etc. erstellt und konfiguriert. Meinetwegen wird noch ein schönes Theme ausgewählt und das Hintergrundbild gesetzt. Es sollte eine Grundeinstellung geben und diese mit der betroffenen Person verfeinert werden.

Ein in der letzten Zeit häufig aufgetauchtes Problem sind Tastaturkürzel. Meiner Meinung nach sollten die Tastaturkürzel so weit es geht entfernt werden. Für diese Art von Anwender ist es nicht nötig ein Kürzel für den Wechsel des Tastatur-Layouts anzubieten. Ganz im Gegenteil. Der Anwender drückt aus Versehen eine Tastenkombination und nachher ist das "ß kaputt". Weg damit!

Die Möglichkeiten einen Drucker einzurichten? Weg. Dies gehört ebenfalls zum initialen Aufsetzen des Systems. Wie leicht ist aus versehen ein Drucker gelöscht. Eigentlich sollte man meiner Meinung nach gleich jedliche Konfigurationsmöglichkeit deaktivieren werden. Dies betrifft nicht nur die eigentliche grafische Oberfläche (oder Destkopmanager,  oder wie man es nennen will) sondern die komplette benutzte Software. Wie oft habe ich mir schon Systeme anschauen müssen, bei denen "nichts gemacht wurde", die Konfiguration aber anders war als voher. Z.B. die Sprache auf Spanisch geändert, oder wie schon erwähnt, einfach das Tastatur-Layout geändert. Auch versehentliche Änderungen von Einstellungen des Browsers sind mir schon untergekommen.

Anwender möchten dass das System heute noch weitgehend so funktioniert wie gestern. Dazu unten mehr.

Ich möchte den Anwender hier nicht entmündigen. Wenn er oder sie mit dem System gut zurecht kommt, spricht nichts dagegen die Einstellungen wieder frei zu schalten. Doch annähernd 90% der Familien-Support-Anfragen die ich so bekomme beziehen sich auf veränderte Konfigurationen. Bzw. beziehen sie sich in Wirklichkeit auf "gestern ging es aber noch und ich habe nichts gemacht!", es lässt sich dann aber auf eine Konfigurationsänderung zurückführen. Beim Ändern des Tastatur-Layouts (mein Lieblingsbeispiel), noch nicht einmal einer bewussten Änderung.

Es ist nicht nur so, dass mich solche Art von Anfragen nerven, die Anwender fühlen sich auch noch Dumm. Frustration also auf beiden Seiten und eine Problemlösung in weiter Ferne.

Noch ein Gedanke zum zu wählenden Betriebssystem. Möchte man Long Term Support haben? Ich bin da etwas zwiegespalten. Persönlich setze ich Software ein, die noch an den Kanten blutet. Das ist aus meiner Sicht auch nicht der Königsweg, vor allem nicht für Anwender. Aber ist es LTS? Ich finde kürzere Release-Zyklen in sofern besser, dass sich in kleineren Abständen kleinere Dinge ändern, statt einer großen Änderung alle 3 Jahre. Man stelle sich nur das Szenario des Umstieges von Win XP mit Office 2003 und Internet Explorer 8 auf etwas neues vor. Wirklich jedes Programm hat sich in den Jahren gründlich geändert. Eigentlich möchte man als Admin ein wartungsfreies System. Aber ganz ehrlich. Das wird es nicht geben. Irgendwann wird neue Hardware nicht unterstützt, oder neue Programme laufen auf antiquierten Systemen nicht mehr. Über die Pflege alter Pakete und das ausmerzen von Sicherheitslöcher möchte ich erst gar nicht anfangen. In der DevOps-Bewegung werden lieber viele kleine iterative Rollouts von Software, gegenüber großen Big Bang Rollouts bevorzugt. Ich denke auch Desktop-Systeme können sich sinnvoll in diese Richtung entwickeln.

Ich finde das Benutzbarkeitsproblem mit/in Android und iOS ebenfalls noch nicht gelöst. Klar kann eine 100 Jahre alte Person sich Fotos auf dem iPad anschauen - und nach kurzem zeigen - vor und zurück fahren. Aber wenn dieser oder diese auch nur die Reihenfolge der Icons verändert hat, ist Holland in Not.

Über dieses Thema haben sich bestimmt schon schlauere Menschen als ich den Kopf zerbrochen. Ich war nur wieder einmal frustriert genug etwas ins Internet zu schreiben.

Kommentare: https://plus.google.com/111200602971512069193/posts/TDsUyxoXgjR