knuspermagier.de
Hallo. Ich bins! Philipp!

Print

20151216_0012_IMG_2308.jpg

Normalerweise decke ich meinen täglichen Bedarf an Lesestoff ja mit Artikel auf Hackernews oder Reddit. In letzter Zeit passiert es mir aber immer öfter, dass mich die bunten Cover von diversen Magazinen in der Printerzeugnistheke im Edeka anlachen... bisher konnte ich da immer widerstehen.

Aber warum eigentlich nicht. Warum nicht mal etwas lesen, was nichts mit Technik zu tun hat und liebevoll von jemandem für das Printmedium hergerichtet wurde!

Da ich außer dem Mickey Maus-Heft, der GameStar und der c't bisher eher keinen Kontakt mit der Materie hatte, habe ich natürlich auch gar keine Ahnung, was man kaufen kann und was nicht -- National Geographic klang jetzt aber relativ seriös und ein Traveller bin ich ja auch, perfekt!

Mal sehen, ob ich es irgendwann lesen werde.

(Schrieb ich hier gerade einen Blogpost darüber, dass ich mir ein Magazin kaufte? Wohin sind wir nur gekommen)

Cloud Reader API

Im Zuge meiner “Ich will alles Tracken”-Manie fiel mir gestern ein, dass ja mal jemand die WhisperSync-API reverse engineeren könnte. Dann könnte man sich schön eine Timeline bauen, wann man wieviel gelesen hat!

Kurz gegoogelt und phantomsync gefunden, dass anscheinend eine JSON mit Daten erzeugt, leider benutzt das aber PhantomJS um den Cloud Reader zu crawlen und das finde ich etwas uncool… Die APIs sind ja da, es müsste sie nur mal jemand herausschreiben und gucken, wie man einen Sessiontoken erzeugen kann.

Wenn dann Lesetagebu.ch noch eine API hätte un die gewonnenen Daten einzuspeisen!

Macht das bitte mal jemand? So richtig bringt es ja auch nichts, deswegen bin ich zu faul dazu.

Ein Cockpit für philippwaldhauer.de

Vor ein paar Monaten baute ich philippwaldhauer.de ja neu, damals alles gespeist aus einer Datei, mit einem PHP-Array, in dem die ganzen Texte standen. Das war für den Anfang erstmal ganz okay, ab und zu möchte man sein Portfolio aber auch aktuell halten und dann nervt es natürlich etwas, wenn man immer eine Datei auf dem Server editieren muss.

Da ich aktuell keine 80€ für Kirby ausgeben will, benutzte ich nun Cockpit (was mir Flo schon mehrfach empfohlen hat) um das ganze vernünftig per Browser bedienbar zu machen. Das klappte alles sehr einfach und ist damit sehr zu empfehlen.

Optimizing your iOS workflow with fastlane

Last week I finally had some time to improve the building and distribution workflow for an iOS app we built for a client. The whole development process was a bit messy — we started with Testflight, switched to Hockeyapp when Testflight was shut down and later moved to a self hosted Enterprise distribution, because the client wanted to test the product in-house with more testers.

While the process now is a bit easier with only three different targets (dev, mainly used on my devices, test as Enterprise distribution and, of course, the App Store build) it always was a big hassle to juggle around bundle identifiers and API endpoint URLs.

So I tried to optimize the workflow. At first I tried to be extra smart and built a small Ruby script using the xcodeproj gem to change bundle identifiers and stuff, but I quickly discovered that I’m reinventing the wheel — most of the work can be done via build configurations and schemes directly in Xcode. This blog post finally helped me to understand everything. mindblown.gif

This at least made the error-prone manual editing not necessary anymore, but I still had to compile the app, export it, upload it to the test server via Transmit, tell my coworkers that a new build is available for testing, push everything to git, etc etc.

Fortunately I rediscovered fastlane. With fastlane the work is reduced to typing “fastlane testbuild” and it does everything from compiling the app to sending a slack message with the download link.

My Fastfile looks like this and was pretty easy to create:

platform :ios do
  before_all do
    ENV["SLACK_URL"] = "https://hooks.slack.com/services/..."
  end

  desc "Upload test build"
  lane :testbuild do
    increment_build_number
    bundle_version = `/usr/libexec/PlistBuddy -c Print:CFBundleVersion ../Files/Info.plist`.strip
    version = `/usr/libexec/PlistBuddy -c Print:CFBundleShortVersionString ../Files/Info.plist`.strip
    filename = "Testbuild-" + version + "-" + bundle_version + ".ipa"

    gym(
      scheme: "Testbuild",
      configuration: "Testbuild Release",
      export_method: "enterprise",
      output_directory: "build",
      output_name: filename,
      clean: true
    )
    sh "./upload.sh \"" + filename + ".ipa\""

    slack(
      message: "Testbuild-" + version + "-" + bundle_version + " is now available at XYZ",
      channel: "#alerts",
      success:  true
    )

  end
end

(Sadly I did not find a way to upload to a SFTP server without writing a shell script, but that wasn't a big deal either.)

In addition to the two or three small features I’m using fastlane provides a whole bunch more. Automatic generation of screenshots, uploading them, submitting to the App store, Certificate management, etc. I hope I get to use more of them in the future.

Musikupdate (1)

Werde ich jetzt regelmäßig über Musik posten, die ich in der letzten Zeit gehört habe? Man weiß es nicht. Anfangen kann man ja mal! Hier schonmal die passende Spotify-Playlist:


Anfang Oktober kam, für mich völlig unerwartet, ein neues Album von Samsas Traum raus. Ich bin zwar am 14.11. auf dem Konzert in Hamburg, hatte aber gar nicht auf dem Schirm, dass es dafür auch ein neues Album gibt.

“Poesie: Friedrichs Geschichte” behandelt die Zeit von 1933 — 1945 und ist textlich daher nicht unbedingt das, was ich mir zur Entspannung anhören will. Davon abgesehen, sind die Songs aber eigentlich ganz gut. Eine schwierige Platte, schade.

***

Im krassen Gegensatz dazu hörte ich letzte Woche viel von Joris, den ich über die Discover Weekly von Spotify entdeckte. Das ist einfach nur sanfte und eingängige Popmusik.


Durch einen Tweet vom @HerrBertling wurde auf Caspian aufmerksam. Die machen so… atmosphärische Instrumentalmusik. Ich hörte das glaub ich am Donnerstag den ganzen Tag beim Arbeiten und es war sehr gut.


Damit ihr total von meinem Musikgeschmack verwirrt seid, erwähne ich jetzt noch, dass am Freitag das MTV Unplugged von Revolverheld rauskam.

Ich mag die Stimme von dem Sänger, hörte mir dem Kram bisher einmal an und fand es “gut”, entdeckte jetzt aber noch noch kein Highlight.


Letzte Woche waren wir ja beim Westernhagen-Konzert in der ehemaligen o2 World in Hamburg. Am Tag danach suchte ich ein bisschen bei Youtube und fand eine Reihe von Videos mit Westernhagen und Sido. Eine komische Kombination, kann man sicher aber mal kurz anschauen.

Language Identifiers in iOS 9

Yay. In iOS 9 you may have noticed some language related issues. All my Instagram push notifications are in German instead of English, for example. After a similar problem appeared in an app we developed, I did some googling and found this technical note, which states:

With iOS 9, the results returned by NSLocale.preferredLanguages() can differ from previous releases.

TL;DR: NSLocale.preferredLanguages() now returns en-US instead of en. Update your code if you check for isEqualToString:@"en".

Erste Schritte mit Ansible

Seit Monaten bin ich auf der Suche nach einer Art Server automatisch zu konfigurieren, für die ich mich nicht drei Wochen in ein dickes Regelwerk einarbeiten muss.

Meine Anforderungen waren ja ganz einfach:

  1. Ich will bestimmen welche Pakete und Services auf dem Server sein sollen und welche Konfigurationsdateien wo rumliegen sollen. Diese sollen aus entsprechenden Templates mit Variablen generiert werden.

  2. Ich will nicht zwei Millionen verschachtelte Ordner mit tausend Dateien anlegen nur um nginx auf einem Server zu installieren.

  3. Ich will nicht auf meinem Rechner und auf dem Server zwanzig neue Services installieren müssen, damit alles automagisch zusammenfindet.

  4. Ich will eine Doku, mit der ich mir in 15 Minuten ein einfaches “nginx + PHP + mysql”-Setup-Script zusammenbauen kann, ohne von den Möglichkeiten total überwältigt zu werden.

Vor ein paar Wochen unternahm ich dann, weil ich beruflich mal wieder Server administrieren musste, einen neuen Versuch, etwas zu finden.

Folgende Sachen erfüllten meine Anforderungen leider nicht: Puppet, Chef, SaltStack.

(Das bedeutet nicht, dass sie nicht vielleicht auch dafür geeignet waren, aber ich fand in meiner Kurzrecherche nicht die nötigen Anhaltspunkte)

Zuerst dachte ich, dass auch Ansible den Test nicht bestehen wird, nach kurzem Studium der Dokumentation waren die Bedenken allerdings wie weggeblasen.

Dank des Getting Started-Guides bekam ich einen guten ersten Einblick und war tatsächlich in der Lage schnell und problemlos ein Playbook zu erstellen, mit dem ich die Server einrichten konnte.

Um diesem Post jetzt noch etwas mehr Inhalt als “Ansible ist toll” zu geben, hier ein wirklich kurzes Playbook.

Ziel soll es sein, einen Ubuntu-EC2-Server mit nginx, PHP und MySQL auszustatten.

---
- hosts: all
  gather_facts: false
  remote_user: ubuntu
  sudo: yes
  vars:
    http_port: 80
    api_root: /var/www/ansibletest.com/
  tasks:
  - name: update apt
    apt: update_cache=yes upgrade=full
  - name: install tools
    apt: name={{item}} state=present
    with_items:
      - vim
      - wget
      - curl
      - python-setuptools
      - screen

Jap. Ihr seht richtig. Yaml. Keine Ahnung was das soll, aber diesen einen Minuspunkt kann man wohl verkraften. Anscheinend startet man ein Playbook (so heißen diese Vorschriften bei Ansible) mit drei Minussen.

Dieser erste Block hier sorgt jedenfalls dafür, dass essentielle Dinge wie vim, wget und screen installiert sind. Vorher wird apt geupdated. Außerdem werden ein paar Variablen gesetzt, die später in die Konfigurations-Templates eingefügt werden. Diese können aber z.B. auch in der Host-Konfiguration pro Host, oder pro Gruppe von Hosts angegeben werden.

Sieht alles ziemlich verständlich aus, oder?

  - name: install nginx
     apt: name=nginx state=present
  - name: install php5 and modules
    apt: name={{item}} state=present
    with_items:
      - php5-fpm
      - php5-cli
      - php5-mcrypt
      - php5-curl
      - php5-mysql
      - php5-json
      - php5-readline
  - name: enable php5 modules
    shell: php5enmod mcrypt curl mysql json readline
  - name: install mysql
    apt: name=mysql-server state=present

Auch hier nur ganz einfache Anweisungen, hauptsächlich für apt. Spannender wird’s im letzten Teil, der die Konfigurationen erzeugt.

  - name: delete default config
    file: path=/etc/nginx/sites-available/default state=absent
    notify:
    - restart webserver
  - name: copy nginx config for api
    notify:
    - restart webserver
    template: src=templates/nginx-site.j2 dest=/etc/nginx/sites-available/ansibletest.conf
  - name: activate config
    file: src=/etc/nginx/sites-available/ansibletest.conf dest=/etc/nginx/sites-enabled/ansibletest.conf state=link
    notify:
    - restart webserver
  - name: ensure nginx is running
    service: name=nginx state=started enabled=yes
  - name: ensure php5-fpm is running
    service: name=php5-fpm state=started enabled=yes
handlers:
  - name: restart webserver
    service: name=nginx state=restarted
    service: name=php5-fpm state=restarted

(Die Templates spare ich mir hier jetzt mal, das sind einfache Jinja2-Templates mit {{ solchen Replacements }})

Das sieht dann schon ein bisschen unübersichtlicher aus, ist aber auch ganz einfach. Die Handler am Ende sind dann noch Tasks, die über das notify nur getriggert werden, wenn auch wirklich was passiert ist. So wird der Webserver nicht 200x neugestartet, sondern nur, wenn die Konfigurationsdatei ausgetauscht wurde.

Das ganze speichern wir jetzt als playbook.yaml.

Ansible will jetzt noch wissen, wo der Kram ausgeführt werden soll, dafür gibt es Inventory-Files. Die können auch ganz einfach aussehen:

[testserver]
ansibletest.com

Fertig. Das ganze dann mit ansible-playbook playbook.yaml -i inventory aufrufen und die Magie mit anschauen.

(Das Playbook gibt es hier nochmal am Stück als Gist)

Das war jetzt natürlich nur ein sehr kleiner Ausschnitt von dem, was mit Ansible möglich ist, und man könnte die Frage stellen, ob es sich schon für so kleine Aufgabenstellungen lohnt — ich finde aber schon. In meinem bisherigen Leben habe ich schon soviel Server aufgesetzt und immer wieder an den gleichen Stellen gegoogelt, was ich nun in die Konfiguration schreiben muss, damit PHP funktioniert, etc — hätte ich mich nur schon früher damit beschäftigt, hätte ich wohl einige Zeit gespart.

Ich freue mich auf jeden Fall darauf, Server in Zukunft nicht mehr anders vorzubereiten.

(Abgesehen vom Yaml, darauf freue ich mich nicht.)