SSH: Automatic notifications on login (Pushover)

The following snippet enables you to automatically trigger Pushover notifications for every SSH login on your server / NAS / desktop:

API_TOKEN=abcdefg1234hijklmno567890pqrstuv
API_USER=vutsrqp098765onmlkjih4321gfedcba
if [ -n "$SSH_CLIENT" ]; then
  USER_IP=`echo $SSH_CLIENT|awk '{print $1}'`
  TITLE="SSH: ${USER}@$(hostname -f) (${USER_IP})"
  TEXT="$(date)"

  curl -s \
  -F "token=$API_TOKEN" \
  -F "user=$API_USER" \
  -F "title=$TITLE" \
  -F "message=$TEXT" \
  -F "priority=0" \
  https://api.pushover.net/1/messages.json >/dev/null 2>&1
fi
Screenshot of Pushover notification
Just replace `API_TOKEN` and `API_USER` variables with your personal values. You can also customize the `priority` parameter to suite your needs. `1` would be high priority, whereas `2` requires you to acknowledge the respective notifications.

Put the above snippet into your server’s `/etc/ssh/sshrc` file to automatically inform you about every SSH login. Using `sshrc` is the „convenient“ solution and does not work, when the a user decides to override it e.g. with a `~/.ssh/rc` file. Refer to the following Stackoverflow discussion for further information and possible alternatives: https://askubuntu.com/questions/179889/how-do-i-set-up-an-email-alert-when-a-ssh-login-is-successful

Installing Delve on OS X / macOS fails

While trying to debug Go scripts with Visual Studio, I stumbled upon issues configuring Delve on macOS. Delve is a full featured debugging tool for the Go programming language and Visual Studio Code seems to make us of it. Unfortunately the installation might not be as straightforward as described in the official installation documentation. The Brew installation fails while / after generating certificates:

==> Installing delve from go-delve/delve
==> Downloading https://github.com/derekparker/delve/archive/v1.0.0-rc.2.tar.gz
Already downloaded: /Users/beematik/Library/Caches/Homebrew/delve-1.0.0-rc.2.tar.gz
security: SecKeychainSearchCopyNext: The specified item could not be found in the keychain.
==> Generating dlv-cert
==> openssl req -new -newkey rsa:2048 -x509 -days 3650 -nodes -config dlv-cert.cfg -extensions codesign_reqext -batch -out dlv-cert.c
==> [SUDO] Installing dlv-cert as root
==> sudo security add-trusted-cert -d -r trustRoot -k /Library/Keychains/System.keychain dlv-cert.cer
Last 15 lines from /Users/[...]/Library/Logs/Homebrew/delve/02.sudo:
2017-12-31 11:52:35 +0100

sudo
security
add-trusted-cert
-d
-r
trustRoot
-k
/Library/Keychains/System.keychain
dlv-cert.cer


If reporting this issue please do so at (not Homebrew/brew or Homebrew/core):
https://github.com/go-delve/homebrew-delve/issues

These open issues may also help:
Upgrade to delve fails https://github.com/go-delve/homebrew-delve/issues/20

Whatever the reason of this issue might be, there is a suitable workaround available:

cd $HOME/Library/Caches/Homebrew
tar xf delve-*.gz
cd delve-*
sh scripts/gencert.sh
# Type in your sudo password
brew install go-delve/delve/delve

References

  • https://github.com/derekparker/delve/blob/master/Documentation/installation/osx/install.md
  • https://github.com/go-delve/homebrew-delve/issues/19#issuecomment-330442033

Affected System

  • OS X El Capitan 10.11.6
  • Homebrew 1.4.1
  • Delve 1.0.0-rc.2

Installing Python with PIP on Boot2Docker

Boot2Docker is quite awesome for getting started with Docker on Windows or OS X / macOS. Tools like „minishift“ do still use Boot2Docker to simplify their setup. Unfortunately Boot2Docker does not provide a solid package manager by default (like most Linux distributions do nowadays with apt, yum, etc.). But as Boot2Docker is based on Tiny Linux, it offers tce-load for some basic package management.

tce-load even provides a full-blown python package, what enables us to install Python with PIP on Boot2Docker. Running the following snippet gets you up and running:

tce-load -wi python
curl https://bootstrap.pypa.io/get-pip.py | sudo python -

Further references

  • List of installable packages for tce-load: http://distro.ibiblio.org/tinycorelinux/tcz_2x.html
  • Documentation of the tce-load command: http://wiki.tinycorelinux.net/wiki:tce-load

OpenShift: “systemd” is different from docker cgroup driver: “cgroupfs”

Messing around with OpenShift Origin 3.6.0 and their Docker Quickstart guide I stumbled upon some configuration incompatibilities with Kubernetes:

F0819 08:47:34.208186    9065 node.go:282] failed to run Kubelet: failed to create kubelet: misconfiguration: kubelet cgroup driver: "systemd" is different from docker cgroup driver: "cgroupfs"

The issue is caused due to using cgrougfs as Cgroup Driver for Docker. You can verify your Docker config by running docker info | grep Cgroup. You can change your Cgroup Driver to systemd using the native.cgroupdriver parameter for the Docker Daemon. Add the following arg to your /etc/systemd/system/docker.service.d/docker-thinpool.conf (ExecStart) file and /etc/default/docker (DOCKER_OPTS):

--exec-opt native.cgroupdriver=systemd

Relaunch the dockerd afterwards and verify your changes:

systemctl daemon-reload
systemctl restart docker.service
docker info | grep Cgroup

Further references

docker change cgroup driver to systemd

I want to docker to start with systemd cgroup driver. for some reason it using only cgroupfs on my centos 7 server. here is startup config file. # systemctl cat docker # /usr/lib/systemd/system/d…

openshift/origin docker container fails to start: failed to create kubelet: misconfiguration: kubelet cgroup driver: “systemd” is different from docker cgroup driver: “cgroupfs” · Issue #14766 · openshift/origin

Affected System configuration

$ docker version

Client:
 Version:      17.06.1-ce
 API version:  1.30
 Go version:   go1.8.3
 Git commit:   874a737
 Built:        Thu Aug 17 22:51:12 2017
 OS/Arch:      linux/amd64

Server:
 Version:      17.06.1-ce
 API version:  1.30 (minimum version 1.12)
 Go version:   go1.8.3
 Git commit:   874a737
 Built:        Thu Aug 17 22:50:04 2017
 OS/Arch:      linux/amd64
 Experimental: false

$ lsb_release -a
Distributor ID: Ubuntu
Description:    Ubuntu 16.04.3 LTS
Release:    16.04
Codename:   xenial

fastlane supply: Google Api Error (Google Play)

fastlane is an awesome tool to release your iOS and Android apps. It handles all your tedious tasks, like generating screenshots, dealing with code signing, and releasing your application. From my experience fastlane is pretty reliable and a true blessing when developing mobile applications. supply is the component of fastlane that is responsible for updating Android apps (binaries), release management (e.g. beta & alpha tracks) and the respective metadata (store listing and screenshots) on the Google Play Store.

Using supply to automate the alpha releases, I had to deal with the following error message:

[10:04:54]: Updating track 'alpha'...
[10:04:55]: Uploading all changes to Google Play...

[!] Google Api Error: multiApkShadowedActiveApk: Version 2100384 of this app can not be downloaded by any devices as they will all receive APKs with higher version codes.

Not only does this complication keep the builds failing, it also prevents releasing new alpha builds – therefore effectively jamming the release cycle. According to a related GitHub Issues the error gets triggered after promoting a release directly from alpha to production (skipping the beta track). As of this writing there is a pretty fresh (14 hours old) Pull Request, which tries to circumvent the outlined problem. Until the possible fix is released, you can workaround the problem by manually uploading a new APK to the alpha track. All subsequent builds should be fixed.


  • The described problem could be reproduced with supply 2.19.0 on Ubuntu 16.04.

Debian Recovery Mode: Turn on networking

Sometime things go wrong… and sometimes things go terribly wrong. So you might find yourself in the depths of your favorite distribution’s recovery mode late in the night. Depending on the nature of your Linux distribution you might be served with the possibility to enable networking foresighted (e.g. via GRUB). Or… there is no such option at all and you are on your own to figure out how to fix your failed update, missing dependencies or incompatible packages — all that, without the plethora of solutions offered by the almighty internet.

Fortunately there is a straight-forward way to get your Ethernet bits flowing:

ifconfig eth0 up
dhclient eth0

# Validate local IP / network config
ifconfig

Building OpenCL on macOS: CL/cl.h not found

Compiling a third party project on macOS, I stumbled upon the following compilation error after running make:

Scanning dependencies of target[...]
[ 33%] Building CXX object CMakeFiles/[...].dir/main.cpp.o
In file included from /Users/[...]/main.cpp:11:
/Users/[...]/CLCalculator.h:14:10: fatal error: 'CL/cl.h' file not found
#include <CL/cl.h>
         ^
1 error generated.
make[2]: *** [CMakeFiles/[...].dir/main.cpp.o] Error 1
make[1]: *** [CMakeFiles/[...].dir/all] Error 2
make: *** [all] Error 2

Unfortunately the application was originally not intended for macOS / OS X platforms. There are quite some examples of similar encounters in the vastness of the internet. But… there is a simple way to make your the respective code cross-plattform and compatible with macOS / OS X:

#if defined(__APPLE__) || defined(__MACOSX)
#include <OpenCL/cl.h>
#else
#include <CL/cl.h>
#endif

Just replace the #include <CL/cl.h> statement with the snippet above and run make again – great…

Error Logging for Ionic 2 with Sentry (Raven.js)

Sentry is a realtime, platform-agnostic error logging and aggregation platform, that helps me catch errors across different projects. Raven.js is Sentry’s official browser JavaScript client and supports „quite a few“ technologies and frameworks (like plain-old JavaScript, Node.js: Express, Koa, Connect, Angular.js 1, Angular, Ember, React, Vue,…).

Ionic 2 comes with an excellent Error-Handling by default. It simply smashes all exceptions right into the developer’s face (the „React approach“ to handle things). This in itself is alright for development, but in production you should probably log all exceptions with solutions like Sentry.

To log exceptions with Sentry on Ionic 2, I decided to extend the existing IonicErrorHandler to additionally forward the logs to Sentry. The snippet below gives an example:

import * as Raven from 'raven-js';
import {NgModule, ErrorHandler} from '@angular/core';
import {IonicApp, IonicModule, IonicErrorHandler} from 'ionic-angular';
import {MyApp} from './app.component';
import {FoobarPage} from '../pages/home/home';

Raven
  .config('*YOUR DSN*')
  .install();

class RavenErrorHandler extends IonicErrorHandler implements ErrorHandler {
  handleError(err: any): void {
    super.handleError(err)
    Raven.captureException(err.originalError);
  }
}

@NgModule({
  declarations: [MyApp, FoobarPage],
  imports: [
    IonicModule.forRoot(MyApp)
  ],
  bootstrap: [IonicApp],
  entryComponents: [MyApp, FoobarPage],
  providers: [{provide: ErrorHandler, useClass: RavenErrorHandler}]
})
export class AppModule {}

Python Pillow 3 with Alpine Linux

Using Alpine Linux as a base for Docker images does have some implications and odd bugs. Trying to get Taiga (Backend) running with Alpine Linux I stumbled upon the following error log:

ValueError: --enable-zlib requested but zlib not found, aborting.

Even explicitly installing zlib (as required) does not help getting rid of the issue:

apk add --no-cache zlib zlib-dev

To get it working / recognizing the system’s zlib you need to

  • extend the CFLAGS environmental variable
CFLAGS="$CFLAGS -L/lib"
  • or create a softlink for the zlib library before executing the Pillow installation:
ln -s /lib/libz.so /usr/lib/

Further References:

ERROR ITMS-90071: CodeResources file must be a symbolic link

Using a continuous integration solution to efficiently develop iOS applications, I stumble upon the following issue when trying to upload an .ipa file using Apple’s Application Loader (Version 3.0)

ERROR ITMS-90071: “This bundle is invalid. The CodeResources file must be a symbolic link to _CodeSignature/CodeResources. Make certain that the bundle is on a locally-mounted volume [not a remote SMB volume], and be certain to use the Mac OS X Finder to compress it.”

The error might be caused by the way your CI solution creates your resulting archive or just due to running the build process from a command line instead of old-fashioned XCode with GUI.

To fix this issue you need to manually change the structure of your application file.

# extract your application archive file (ends with .ipa)
unzip Foobar.ipa -d tmp/

# change to the application folder (ends with .app)
cd tmp/Payload/Foobar.app

# overwrite or create the mentioned symbolic link
ln -fs _CodeSignature/CodeResources CodeResources

# change to the tmp/ folder
cd ../..

# recreate the application archive file (.ipa)
zip -yr9 Foobar.ipa Payload/

You should then be able to successfully upload your iOS application with Apple’s gorgeous Application Loader.

You can also use the copy’n’pastable example below (resulting file is called Fixed.ipa).

unzip *.ipa -d tmp/
cd tmp/Payload/*.app
ln -fs _CodeSignature/CodeResources CodeResources
cd ../..
zip -yr9 Fixed.ipa Payload/
cd ..
mv tmp/Fixed.ipa .
rm -r tmp
ls -lah