Techstack n – 1 is dead!

TL;DR TechStack n-1 is dead. It ended with the rise of the clouds and software release cycles going down to weeks due to containerized CIs.

Beeing OpenSource-based, Ubuntu already had the concept of point releases every 6 months when the Docker and K8s hit the world and gave automated CIs a big boost in making system containers. Some years after Docker itself switched to a 3-month release cycle. So did the Linux Kernel with 2-3 months. Firefox 4-weeks.

And Microsoft? Windows 10 became a platform. Service Releases for the end customers every 6 months. Insider Program became a built-in feature of Windows 10. Now you can call that a rolling release!

Given that and comparing that to the old paradigm of “we don’t run edgy software” it may take 8 weeks or 6 months until we have already reached TechStack n – 2.

Now compare that with the speed of your management decision processes!

Sure, not every feature is important but some of them are business critical just like WSL2. Or sometimes you get a security requirement like please change the base image of the systems. Sometimes you save time and money if you just deploy applications as services by helm chart instead of fixing a custom setup for weeks. Sometimes it’s easier to just rollback a deployment on Kubernetes than replaying a build process in hope to rebuild a lost artifact (build once, deploy many).

And then you have security: there infrastructure is also changing. Snapshot technologies are on the rise (hypervisors/ostree/next gen filesystems like ZFS and BTRFS).

Back to WSL2. Why? Dev/Production parity. And maintaining one tool chain based on an image. Still you could use VMs and some indeed still do you Vagrant with all it’s problems Both Apple and Microsoft strife for best developer experience on their systems, simple because OpenSource and Linux has triumphed and it is run on the future market which is cloud native.

That is why every big company is behind the (corporate) Linux Foundation and (corporate) CNCF (Cloud Native Computing Foundation). And that is probably why their certs are so cheap: because we need skilled developers that know their platform.

So, how do we keep up? Clouds are evolving fast and are ephemeral. So we need to become that too.

Not everyone is living at the edge and that’s also a requirement for a healthy system.

We need early adopters that can surf on the static noise generated by cloud native experiments, that can see where the ocean is moving. These are the OpenSource contributors and the ones birding GitHub repositories on their laptops.

We need those who can build stable container ships that sail the ocean. Those who know what’s happening on the technology radar.

We need skeptical ones that can see beyond fancy applications and hero myths to the bottom of underlying bare metal infrastructure.

We need people with long time experience knowing old and forgotten tricks.

Running that old techstack n-1 paradigm in modern environments has become dangerous and negligent.

PS.: Sure, for datacenters keep running your RHEL or CentOS with support until 2026!

Download an LFS backed file from without `git` and `git-lfs` installed

Well, the API is there and you can do it already!

Just dig into the what git is doing by a test-clone with any LFS repo:

export GIT_CURL_VERBOSE=1                                                                               
export GIT_TRACE_CURL=1                                 
git clone <my-repo> 2>&1 | tee git-clone.log                                                

From there you are able to figure what is happing on SSH:

Now: download an LFS backed file from without git and git-lfs installed!

#!/usr/bin/env bash

PROJECT="${1}" # your-company/or-repo/whatever
FILEPATH="${2}" # foo/bar.tar.gz
REF="${3:-master}" # branch
SSHID="${4:-$HOME/.ssh/ecdsa_id}" # like $HOME/.ssh/mycompany

OID="$(set -o pipefail; curl -fSL -H "PRIVATE-TOKEN: ${GITLAB_TOKEN}" "${PROJECT//\//%2F}/repository/files/${FILEPATH//\//%2F}/raw?ref=${REF}" -o - | grep '^oid' | cut -d: -f2)"
AUTH="$(set -o pipefail; ssh -o IdentitiesOnly=yes -o IdentityFile="${SSHID}" git-lfs-authenticate "${PROJECT}.git" download | jq -er '.header.Authorization')"
mkdir -p "${FILEPATH%%/*}"
curl -H "Authorization: $AUTH" "${PROJECT}.git/gitlab-lfs/objects/${OID}" -o "${FILEPATH}"
file "${FILEPATH}"

And you can even do it without using SSH!

#!/usr/bin/env bash

PROJECT="${1}" # your-company/or-repo/whatever
FILEPATH="${2}" # foo/bar.tar.gz
BRANCH="${3:-master}" # branch

# get LFS file info
IFS=$'\n' LFS_OBJECT_INFO=($(curl -fsSL -H "PRIVATE-TOKEN: ${GITLAB_TOKEN}" "${PROJECT//\//%2F}/repository/files/${FILEPATH//\//%2F}/raw?ref=${BRANCH}" -o -))
OID="$(echo "${LFS_OBJECT_INFO[@]}" | grep -oP "oid sha256:\K[^\s]+")"
SIZE="$(echo "${LFS_OBJECT_INFO[@]}" | grep -oP "size \K[^\s]+")"
# request actions for given lfs objects
LFS_OBJECT_REQUEST_JSON="$(jq -rnc --arg oid $OID --arg size $SIZE --arg ref "refs/heads/$BRANCH" '{"operation":"download","objects":[{"oid":$oid,"size":$size}],"transfers":["lfs-standalone-file","basic"],"ref":{"name": $ref }}')"
LFS_OBJECT_ACTION_DOWNLOAD="$(set -o pipefail; curl -sSlf -H "Content-Type: application/json" -X POST -d "$JSON" "https://oauth2:${GITLAB_TOKEN}${PROJECT}.git/info/lfs/objects/batch" | jq -er '.objects[0]')"
AUTH="$(echo "$LFS_OBJECT_ACTION_DOWNLOAD" | jq -er '.header.Authorization')"
DOWNLOAD_URL="$(echo "$LFS_OBJECT_ACTION_DOWNLOAD" | jq -er '.href')"
mkdir -p "${FILEPATH%%/*}"
curl -H "Authorization: ${AUTH}" "${DOWNLOAD_URL}" -o "${FILEPATH}"

AWS CLI V2 is general available since Februray 2020. BUT …

It is distributed as binary package (built on python and with pyinstaller that has bundled native libs) BUT…

  • Problem #1 this requires a decent GLIBC and probably won’t run on older redhat distributions
  • Problem #2 as it turns out many people use the official docker images to build their images and push to AWS ECR. and since these images are based on alpine and therefore use MUSL and NOT GLIBC it simply won’t run (but well people have seen now alpine pipelines in AWS builds although they do NOT support any other linux than their own; probably THEY HAVE TO)
  • Problem #3 you now have to download the application to update it (hey, the way to install software on windows or mac? but hey an own updater with aws/install –update)
  • Problem #4 forget installing and updating from pip for now; well you can directly pip from repo BUT it’s tricky. although the version says 2.0.38 (no beta or alpha!) it still requires a botocore==2.0.0dev42. i guess they should suffix a “ga” for “General Availability”.
  • Problem #5 If you belong to the majority (or the people with broken python installations) please refrain from saying “I have no problems! It’s better now!”

Anyway, they have some nyce features now and it seems they packed aws-shell right into to CLI:

#blacklivesmatter in Software Industry und So…

Ich sehe das so: Systemischer Rassismus* führte dazu dass eine heterogene aber ethnische Gruppe von Menschen bezüglich ihrer Hautfarbe benachteiligt wurden. Mittlerweile wog die Ungleichgewicht durch die ganzen kleinen Benachteiligungen so stark, dass informell und formell jetzt eine Ausbalancierung stattfindet; “The White Man’s Legacy” sozusagen…

Leider wird dabei wieder gegen falsche Ziele oder über das Ziel hinaus geschoßen. Es ist aber vor allem in unserer Zeit der Selbstradikalisierung besonders einfach, sich mit dem “correct a wrong” zu profilieren. Es zählt wie in der Politik ohnehin oft nur noch das “moralisch korrekte”, da sich damit am einfachsten ill-informed Follower rekrutieren lassen. Ethisch gerechte sowie rationale Entscheidungen treten in den Hintergrund.

Getreu “yesterday’s heroes, tomorrow’s fool” dürfen wir wohl damit leben, dass Leitsätze wie “Wenn nur einer im Team sich damit mehr inkludiert fühlt, dann machen wir das” unseren Hedonismus beflügeln und dadurch auch ein Pressure auf Need-to-Change entsteht. Auch wenn dadurch mal was einfach total deppert benamst wird.

Ich denke das gute Kommunikation bei denen, die sich diskriminiert fühlen, dazu führen kann, auch mal den Blickwinkel zu justieren. Nur weil in einem Chat jemand mal das falsche Wort getroffen hat, heißt dass nicht, dass es ein böse Person ist.

“Big solutions for Small problems”.

Davon abzulassen einen “Code of Conduct” zum Selbstzweck zu weaponizen – oder das mal zu erkennen. Steht man nicht for Logik und Verstand ein kann das bei vielen Justice Warriorn schnell zu einer toxischen Kommunikationskultur führen (you know “logic is a patriarchal thing”). Trotzem, das Selbstwertgefühl dieser Personen sollte man nicht verletzen! Entweder arrangiert man sich, wenn nicht passt man vielleicht doch nicht zu der Gruppe.

Ich bin aber auch ein Vertreter davon, dass Sprache Realität schafft. Aber es bringt nix Denkmäler sinnlos zu zerstören, weil damit viele auch Sinnbilder einer Kultur verbinden. Es muss Verständniss geschaffen werden, welche negativen Bilder besser Narrative andere damit verbinden. Wenn zu kritisch, dann vielleicht ab damit ins Museum? Oder: “yeah, it’s time to lower the rebel flag!

Vielleicht müssen wir ein Stück weit mit dem “Unsinn” mitschwimmen, und es vielleicht auch mal als Anregung sehen unsere eigenen Sichtweisen in Frage zu stellen.

Ist es nicht ähnlich wie beim Feminismus? eine Frauenquote betrachte ich strukturell als ungerecht, aber wir wissen mittlerweile auch, dass Frauen sich sehr positiv auf den Climatus auswirken, eben Diversität. Das Problem ist eher der Maskulinismus, das Patriarchat, das nur als Anti-These zum Feminismus steht und es nicht geschafft hat, sich zu emanzipieren. So, ist jetzt besser zu sagen: ich schwimme als Whity mit allem mit, oder bin ich eher ein Mensch mit Intelligenz, Verantwortungsbewußtsein der sich erlaubt zu sagen: “Ich verstehe deine Punkte, aber Master kommt aus dem lateinischen ”

Und apropos Patriarchat: es ist tot, das Problem ist wir leben noch in den Resten von Rom.

Vielleicht sollte man sich auch mal überlegen welche Persönlichsdefizite oder -defekte man selbst hat und warum man sich so getriggert fühlt. Und das fängt bei dem Quälgeist der heutigen Zeit, Narzismus an, der ja bekannterweise durch Sozialisisation entstehen kann. Aber es geht ja weiter… Depression, Borderline, bipolar…

Naja, mehr Gedanken zu dem Thema von Bryan Lunduke: Linux Kernel blacklists “blacklist”

UPDATE: That’s it about: CNN’s Van Jones brought to tears as Joe Biden wins US election

5¢ on YAML in the DevOps world

Envsubst as a GitHub Action, Serverless Frameworks that just look like a YAML wrapper around an API, YAML based TaskRunners that somewhat reensemble the requirements of a CI . Not sure if everyoke understood the convention over configuration thing and why would do descriptive instead of imperative (CloudFormation anyone?). It reminds me more of people now pushing thin layered YAML wrappers since the micro NPM projects now look a bit old-school on the curriculum vitae 🙄 Well, obviously it’s about getting things to be easier to grasp. But then again sometimes find odd solutions when you hit the limits. The question is rather: who does find the most usable one? Interesting read:

CSV tools

Some CSV utils which may come handy since most teams are dealing with that kind of formats 😉
  • – part of my default toolset 😉
  • – part of my default toolset 😉
  • – interesting read
  • – yeah, the ripgrep guy
  • – now part of my default toolset (yeah, json but faster than jq with “flatten” filter; line grep is powerful)
  • – patch/diff for CSV and spreadsheet data
  • – in trial

Pure BASH interactive CLI/TUI menu (single-/muliti-select/checkboxes)

First version. To be refactord.


Inspired by


  • This is a hacky first implementation for my shell tools/dotfiles (ZSH)
  • Intention is to use it for CLI wizards (my aim is NOT a full blown curses TUI window interface)
  • I converted TPUT to ANSII-sequences to spare command executions (e.g. tput ed | xxd --plain)

Permission to copy and modify is granted under the Creative Commons Attribution 4.0 license

Gedankenspiel: Automatisierung bei Big Corporate

Zielsetzung: Wir möchten von eigenes Autos auf Taxi als Dienstleister wechseln.

Wir kennen allerdings das Taxi-Business zu wenig, fühlen uns unsicher und bestellen daher erstmal Fahrer, die in unseren eigenen Autos Taxi fahren sollen. Die Fahrer sind aber keine ausgebildeten Taxi-Fahrer, kennen die Strassen nicht, und das Navi ist leider ein propritäres Produkt mit veralteter Karte. Allerdings von namhaften Hersteller, was nicht wirklich was bringt. Ebenso bieten wir auch unseren Fahrern Kaffee von Starbucks, damit sie nicht einschlafen und die Straßen lernen können.

Ziemlicher Käse, oder?

Kubernetes wäre in dem Fall das Car-Sharing. oder Uber die Amazon-Services. Und weil Amazon es eh besser kann, denken wir, wir könnten unseren “Taxi-Fahrern ohne Plan” ja von Über gemietete Autos hinstellen, in der Hoffnung, das sie die Straßen dann effizienter abfahren.

Oder auf deutsch: warum Migration in Baby-Steps manchmal Unsinn ist. Automatisiert was geht, und nehmt bitte Abstand von halbgahren Lösungen, weil Kontrollfreaks nunnal FUD und Babysteps propagieren. Die Zeit, die für #reinventingthewheel oder das “wir wollen es erstmal verstehen oder sehen dass es funktioniert” drauf geht, kann man getrost auch ins Development stecken. Infrastructure first. Nehmt euch DevOps die euch ne Infrastruktur und ne CI hinstellen und lässt sie machen. Umso schneller steigt ihr in eure eigenes Taxis ein und müsst euch um den Weg zum Ziel keine Gedanken mehr machen. Je besserer die Automatisierung läuft, desto weniger Fehler gibt es. Eine Liste mit zig Punkten, die trotzdem manuell abgearbeitet werden muss, bleibt nunmal fehlerträchtig und es geht nur menschliche Zeit und Nerven darauf. Und Devs lernen auch nichts, außer menschliche Fehler zu wiederholen. Also, noch mehr Frust satt an einer CI zu arbeiten, die Dinge wirklich einfacher machen würde. Time to Rollback. Time to go live. Instant response. Zeit für Tests und Qualität statt immer der gleiche Bullshit.

Auch ja, und dann gab es noch diese fetten Limosinen aka. vertikale Bare Metal Skalierung. Hat sich leider im Berufsverkehr als unpraktikabel erwiesen. Aber hübsch sehen sie ja aus. Wer’s braucht…

PHP: just in case posix_isatty() is missing

From StackOverflow

Short function

function is_a_tty() 
    static $result;
    if (is_null(result)) {
        $fp = fopen('php://stdin', 'r');
        $stat = fstat($fp);
        $mode = $stat['mode'] & 0170000; // S_IFMT
        $result = $mode == 0020000; // S_IFCHR
    return $result;

Info Class from StackOverflow by leigh


class IOMode
    public $stdin;
    public $stdout;
    public $stderr;

    private function getMode(&$dev, $fp)
        $stat = fstat($fp);
        $mode = $stat['mode'] & 0170000; // S_IFMT

        $dev = new StdClass;

        $dev->isFifo = $mode == 0010000; // S_IFIFO
        $dev->isChr  = $mode == 0020000; // S_IFCHR
        $dev->isDir  = $mode == 0040000; // S_IFDIR
        $dev->isBlk  = $mode == 0060000; // S_IFBLK
        $dev->isReg  = $mode == 0100000; // S_IFREG
        $dev->isLnk  = $mode == 0120000; // S_IFLNK
        $dev->isSock = $mode == 0140000; // S_IFSOCK

    public function __construct()
        $this->getMode($this->stdin, fopen('php://stdin', 'r'));
        $this->getMode($this->stdout, fopen('php://stdout', 'w'));
        $this->getMode($this->stderr, fopen('php://stderr', 'w'));

$io = new IOMode;


$ php io.php
// Character device as input
// $io->stdin->isChr  == true

$ echo | php io.php
// Input piped from another command
// $io->stdin->isFifo == true

$ php io.php < infile
// Input from a regular file (name taken verbatim from C headers)
// $io->stdin->isReg  == true

$ mkdir test
$ php io.php < test
// Directory used as input
// $io->stdin->isDir  == true

$ php io.php
// $io->stdout->isChr  == true

$ php io.php | cat
// $io->stdout->isFifo == true

$ php io.php > outfile
// $io->stdout->isReg  == true

$ php io.php
// $io->stderr->isChr  == true

$ php io.php 2>&1 | cat
// stderr redirected to stdout AND piped to another command
// $io->stderr->isFifo == true

$ php io.php 2>error
// $io->stderr->isReg  == true

I hope those PHP stuff finally dies 🙁

Infojunk November 2018

Hacking / MITM-API-Testing





  • KataCode Playground with fully funcional real browser shells for learning without barriers (using Containers?)
  • GoTTY
    How about gotty -w docker run -it --rm anapsix/nyancat:alpine?