Passing data through segues when called dynamicly

tl;dr: I don’t. I grab the top view controller from the stack of the navigation controller.

From my DetailView, I wanted to push to a new ViewController for adding a comment. The “link” to add a new comment was in an action sheet (UIAlertController), so I had to call the segue from the code. To create the segue in the StoryBoard, I had to connect the NavigationController (not the UITableViewController) with the new ViewController.

This means, that when I call

self.navigationController?.performSegue(withIdentifier: "downtimeSegue", sender: self)

the segue will be perform correctly. BUT. The method

override func prepare(for segue: UIStoryboardSegue, sender: Any?)

will not be called since it is implemented in my DetailViewController, not in the NavigationController.

So I am not able to pass any data in that method.

Solution: I just grabbed the DetailViewController via the NavigationController and so I can access all properties.

override func viewDidLoad() {
    for controller in navigationController!.viewControllers {
        if controller is DetailViewController {
            self.delegate = controller as? DetailViewController
        }
    }
}

Limiting scp uploads via authorized_keys

During an automated compile and deployment process you problaby want to copy the new file(s) to the destination server. Since the process will be running within the deployment environment (gitlab-ci in my case) you cannot supply a password every time. So you use SSH keys to authenticate against the server. I found this to be common practice and it is well documented.

Only much later I found that you can limit the command one key is allowed to run on the server. So you might have a script on the server which pulls a built package from the repo after your build pipeline put it there. You simply add a “command=” flag before the key in authorized_keys:

command="/usr/bin/pull-softare-update" ssh-rsa AAAAB123...

This way, you can run ssh user@server.example.com /usr/bin/pull-softare-update but nothing else. Supplying another command via ssh will still result in “pull-software-update” beeing run on the server.

There are cases, though, where you don’t explicitly run a command on the server but still use ssh. Those are rsync and scp. Both start a process on the other side to manage sending/receiving files so you can use the command= feature here, too.

For receiving files, there is an answer on Serverfault which gives a hint on how this might work.

scp starts a process with the hidden command line parameters -f to provide a file or directory for download and -t to specify a directory to put files into (-f: from / -t: to).

command="scp -t /srv/storage/foo" ssh-rsa AAAAB123...

To further limit the key, you can explicitly disallow other ssh features like port forwarding:

command="scp -t /srv/storage/foo",no-pty,no-port-forwarding,no-agent-forwarding,no-X11-forwarding ssh-rsa AAAAB123...

Fulmar für kleine Projekte

Fulmar basiert auf Rake und bringt einige Erweiterungen mit, um mit wenig Code ein Deployment durchzuführen. Zusätzlich zu den Rake-Tasks liest es eine Konfigurationsdatei ein, die unter anderem definiert, welche Ziele es gibt.

Die Basiskonfiguration von Fulmar liegt in zwei Dateien: “Fulmarfile” liegt im Basisverzeichnis des Projekts. Dazu kommt ein Unterverzeichnis “Fulmar”, das eine oder mehrere .config.yml-Dateien enthält.

Konfiguration

Meine Konfigurationsdatei Fulmar/kayssun.config.yml für dieses Blog sieht wie folgt aus:

environments:
  local:
    blog:
      local_path: .
  live:
    blog:
      remote_path: /srv/www/www.kayssun.de
      local_path: _site
      type: rsync
      hostname: ada

Fulmar unterteilt die Ziele einerseits in Environments, bei größeren Projekten in der Agentur wären das zum Beispiel “vagrant” für die lokale Entwicklung, “staging” für erste Tests, “preview” für eine Kundenvorschau und “live” für das Produktivsystem. Hier habe ich nur die Einvironments “local” und “live”. Darunter können beliebig viele “targets” angelegt werden, hier “blog”. Das wird nötig, wenn zu einem Projekt mehrere Dateien gehören, die an unterschiedliche Stellen auf dem Server kopiert werden müssen (zum Beispiel Konfigurationsdateien für andere Dienste).

Hier in meinem Beispiel setze ich die lokalen und entfernten Pfade, die Art des Syncs und den Hostname des Servers.

Die Targets werden dann im Fulmarfile geladen:

desc 'Prepare site (build blog)'
task setup: 'environment:local:blog' do
  local_shell.run 'jekyll build'
end

namespace :deploy do
  desc 'Deploy blog to live system'
  task live: 'environment:live:blog' do
    file_sync.transfer
  end
end

Der erste Task lädt die lokale Konfiguration. local_shell.run führt den Befehl im local_path der gewählten Konfiguration aus. Das wäre hier “.”, also das Verzeichnis, in dem sich Fulmarfile befindet.

Der zweite Task synchronisiert das Verzeichnis “_site” auf den Server. Über remote_shell.run könnten auf dem Server noch Befehle ausgeführt werden, etwa um Caches zu löschen.

Benutzung

Über fulmar -T kann die Liste der verfügbaren Tasks eingesehen werden. fulmar setup kompiliert in meinem Fall das Blog und stellt es unter “_site” bereit. Mit fulmar deploy:live kann dieses Verzeichnis auf den Server synchronisiert werden.

Ausbau

Fulmar wird erst für größere Projekte interessant. In der Agentur (CORE4 GmbH) nutzen wir für alle Projekt möglichst das gleiche Schema. Das macht es leichter, sich in fremde Projekte einzuarbeiten. fulmar setup ist dabei immer der erste Befehl nach dem Auschecken aus dem Git. Damit werden alle nötigen Abhängigkeiten geholt und das System für die Entwicklung vorbereitet. Fulmar bringt Unterstützung für Git, MySQL/MariaDB, rsync, Versionierung der Deployments. S3 und weitere Features werden folgen.

Animiertes Flurlicht

Regenbogen-Beleuchtung

Das Licht in meinem Flur wird von einem Raspberry Pi mit 2x 5m LED-Streifen und 2 Bewegungsmeldern gesteuert.

Für die Steuerung der LED-Streifen wäre nicht unbedingt ein Raspberry Pi nötig, die Logik ließe sich auch mit einem Arduino abbilden. Allerdings wollte ich meinen Code mit Ruby schreiben und später auch noch weitere Funktionen mit dem Rechner im Flur implementieren.

Vorbereitung

Folgende Komponenten sind nötig:

  1. Raspberry Pi
  2. SD-Karte
  3. ein oder zwei selbstklebende LED-Streifen WS2801
  4. ein oder zwei Bewegungsmelder (z.B. HC-SR501)
  5. >=120W-Netzteil, 5V
  6. einige Kabel

WS2801-LED-Streifen

Aufbau

Die LED-Streifen haben vier Anschlüsse: +5V, Ground, Clock und Data. Die ersten beiden müssen mit dem Netzteil verbunden werden, die anderen mit dem Raspberry Pi. Der Raspberry Pi muss wiederrum an den Ground vom Netzteil angeschlossen werden. Die Bewegungsmelder werden ebenfalls +5V, Ground und jeweils eine Datenleitung benötigen.

Die LED-Streifen habe ich an die Decke geklebt und die Datenleitungen auf der gegenüberliegenden des Raspis verbunden. Die Stromleitungen habe ich jeweils an den spitzen des ‘U’ angeschlossen, damit sie nicht zu lang werden.

Verkabelung der LED-Streifen

Die Bewegungsmelder sind in der Mitte des Flurs und schauen jeweils nach links und rechts, so dass der Raspberry Pi auf die Richtung reagieren kann, aus der man in den Flur geht.

Der Raspberry Pi könnte über das Netzteil mit betrieben werden, indem man den 5V-Pin (und Ground) des Pis mit dem Netzteil verbindet, das würde aber die Sicherung umgehen, soweit ich weiß. Ich habe also ein separates USB-Netzteil genommen, das mit später auch erlaubt, mit einem Relais das große Netzteil abzuschalten, wenn es länger nicht gebraucht wird. Nachts etwa.

Bewegungsmelder

Die Bewegungsmelder sind recht einfach anzuschließen. Sie benötigen 5V vom Netzteil und haben jeweils einen Datenausgang, den man mit dem Rasperry Pi verbinden kann. Wenn sie eine Bewegung feststellen, liegt Spannung am Ausgang an, sonst nicht. Ich habe die Bewegungssensoren an die Decke gehängt. Damit sie in der richtigen Position halten, brauchte ich eine Art Gehäuse, das ich aus Bügelperlen gebaut habe. :)

Bewegunssensoren im Bügelperlengehäuse

Die Bügelperlen habe ich an eine dünne Holzplatte geklebt. Silikon eignet sich hier nicht (für euch erprobt) aber normaler Haushaltskleber tuts eigentlich. Das ganze Ding habe ich dann an die Decke geschraubt.

Bewegungssensoren an der Decke

Verkabelung

Die Bewegungssensoren müssen im Grunde einfach nur an einen der freien GPIO-Pins angebracht werden. Die Bildersuche von Google liefert dieverse Treffer zur Belegung, ein Beispiel für die zur Zeit aktuellen Raspberry-Pi-Modelle wäre ein Artikel auf diyhacking.com. Ich habe die Pins 23 und 24 genommen, diese Werte sind auch im späteren Gem zur Lichtsteuerung voreingetragen.

Die LED-Streifen müssen über die SPI-Schnittstelle des Raspberry Pis angeschlossen werden. Das sind die Pins 19 und 23. 19 ist der Datenausgang, 23 die Clock, die das Timing für das Signal vorgibt.

Pin 6 zum Beispiel ist Ground und muss mit dem Netzteil verbunden werden, damit alle Geräte einen gemeinsamen Nullpunkt haben.

Verkabelung des Raspberry Pi

Software

In den Konfigurationssoftware des Raspberry Pi findet sich in den erweiterten Einstellungen die Option, um die SPI-Schnittstelle zu aktivieren. Nach einem Neustart müsste die Geräte /dev/spidev0.0 und /dev/spidev0.1 zur Verfügung stehen.

Ist die Verkabelung genau wie hier beschrieben, kann der Ruby-Gem ws_light direkt genutzt werden:

gem install ws_light
ws_light

Ich habe bisher noch keine Konfigurationsdatei vorgesehen. Wenn Bedarf besteht, kann ich das aber schnell nachrüsten.

Ansonsten lässt sich der Gems auch selbst anpassen, der Code liegt auf github. Die Konfiguration der GPIO-PINs für die Bewegungsmelder ist in der Datei bin/ws_light.

Tagsüber

Nachts

Rückmeldungen

Diese Zusammenfassung ist womöglich als Anleitung für eine Anfängerin noch etwas zu knapp. Ich würde mich über Rückmeldungen freuen und gebe auch gerne Hilfestellung.

Jekyll

Beginnend mit einem Meta-Post will ich mal schnell mein Setup beschreiben, mit dem ich nun zu bloggen gedenke.

Als Blog-Software nutze ich Jekyll, das aus ein paar Dateien eine statische Seite generiert. Ich nutze das “Cayman Theme” von Jason Lang. Für das hochladen auf meinen Webserver habe ich mir schnell Fulmar eingerichtet und zum tatsächlichen Schreiben der Posts nutze ich Sublime Text auf dem Mac. Die statischen Dateien auf dem Server ersparen mir Sicherheitsupdates und generell mag ich Dinge, die sich in ein Git-Repo einchecken lassen.

Der Server läuft mit nginx auf einem Debian-System und das Zertifikat für SSL/TLS habe ich von Let’s encrypt.

blog built using the cayman-theme by Jason Long. LICENSE