Twig Technology

[...] incredibly interested in all the things you could do with twigs.

Christmas Support Call

| Comments

Christmas. where we all return to the place of our birth and fix our parents’ computers. My dad finally let me touch his computer. Not because he finally agreed to let me install backup software or a password manager for him, though: He couldn’t install Firefox on his Mac, because Firefox said his OS was too old.

Turns out, he was still running Lion.

So I go to the App store, thinking I should upgrade him to Sierra. “Dad, what’s your Apple ID?” “What does one of those look like?” “Never mind, you’ve never installed anything on this computer since you won it in that raffle years ago. We need to create a new one, I guess”. He has literally only used it for Skype since Lion came out.

Safety First

Create Apple ID, confirm email, answer security questions. “Dad, who was your first friend in high school?” “Dunno.” “What was the name of your first pet?” This is followed by a long story about that time his hamster stole my grandma’s cake, but he has no memory of what the beast was called. moving on… Install macOS Sierra. takes an hour or so? Mac keeps going to sleep and needs waking up.

More Updates

computer reboots, app store says “we have updates!”. I select the firmware update. “dad, do you even use iMovie and iPhotos?” “Nuh, what are those?” “let’s update them anyhow, to get rid of the red notification popup” “Hi! I’m the microsoft updater, and need to install a very important security update for Office 2011!” “OK, go ahead!” Although, why is this a separate updater outisde the app store? Is Microsoft too good for Apple’s walled garden? “Your new firmware is installed, do you want to reboot now?” “No, Microsoft is still updating shit. wait a mo”

Revenge of the Apple ID

okay, microsoft is happy, reboot for firmware upgrade and wait. rebooted, app store still wants to install new iMovie/iPhoto versions. okay… “Enter your Apple ID” okay. “that apple ID cannotbe used to update this software, because reasons” “why, google?” “it was probably pre-installed, and accepted by another Apple ID”. “Dad, did anyone else set up this computer for you?” “it came pre-installed with everything” “okay, fuck it, let’s install firefox”

Mission accomplished?

Firefox installed, start it. “this extension (toolbar for his webmail service) is not supported by your version of firefox. please install our partner-branded version of firefox instead” goddamnit. a toolbar that’s telling me not to use the stock firefox? what has science wrought!?

Of course, every future problem that he has with this computer is now my fault, especially once he loses the Post-It with his new Apple ID password, and macOS starts prompting him for it on a daily basis. Good thing he uses a PC for any “real” work.

No Submodule Mapping Found in .gitmodules for Path Foo

| Comments

Travis CI errored. No submodule mapping …

Today my Travis builds started to error becasue of a submodule that I deleted from my repository a long time ago. Turns out, I probably didn’t do that right.

Travis CI clones only the most recent 50 revisions, which probably has something to do with this. I did the same thing locally, then ran git submodule --init --recursive, and the error message was reproduced. Stack Overflow and Google led me on the right trail, git had some kind of cached information about the folder which I could see when doing git ls-files --stage | grep 160000. To remove it, I had to run git rm --cached foo, then commit and push. Now my builds are green again, and all is well.

My guess is that when I removed the submodule, I removed the folder without the —cached option, and that’s what eventually caused the mistake, delayed only by the window of 50 commits that Travis checks out? Thre are still parts of git that are mysterious to me.

Release Management and Version Numbering With GIT

| Comments

Simple version numbering

Eventually, every program you write needs a version number. When customers file bug reports, it’s useful to know what version of the program they were using, for example. Here’s a very simple program that does nothing but print a version number:

#include <stdio.h>
#define VERSION "1.0.0-beta"
void main(void) {
    printf("foobar version %s\n", VERSION);

For the longest time, this is how I managed the version numbering in Eressea, but the more I automate things, the more I realize that this is really annoying.

Version numbers do not belong in code

Defining the version number in the code, like we do here, causes us to have to change the code every time we build a new release, which possibly creates a new commit, merge conflicts, and a whole number of problems we don’t want. So let’s not do that, but define the version externally:

#include <stdio.h>
#ifndef VERSION
#define VERSION "1.0.0-beta"
void main(void) {
    printf("version %s\n", VERSION);

Now we can pass a -DVERSION=\“1.1.0\” argument to gcc, and this version number will override the one in the source. However, now we don’t store the current version anywhere except in the final executable. This is where git’s tags come in. Tags are a way of marking a version in git with a name, and picking a standard format for our releases, we can give the command git tag -f v1.2.0 to mark our code with a version number. We can get the most recent tag with git describe --tags, and if the current checkout is not directly on the tag, git will add a postfix to the tag to describe the revision we are at, like so: v1.2.0-439-gb1a8ccd (where b1a8ccd is the SHA1 hash of the current revision). Putting it all together, we get:

gcc main.c -DVERSION=\"$(git describe --match 'v*.*.*' --tags)\"

Depending on your build system, this belongs in your Makefile or your CMake rules.


I now have a system that automatically sets the version string of my program to something that is both descriptive and useful. Every time I make a new release, I have to tag it (my release script does this automatically). For significant releases, I still update the VERSION definition in the source code, but my own builds mostly don’t care about it.

Most importantly, every time I get a bug report that includes a version number from a build that I have made, it relates directly to a git revision. I can try to reproduce that bug with the exact code that was used to produce it in the first place!

Continuous Deployment of Websites With Travis CI

| Comments

In my not-so-humble opinion, Travis CI is one of the greatest things to come out of Germany. It’s a free CI service for your public github projects (or paid for your private ones). I use it for everything I make, and today I went down the rabbit hole to figure out how to use it not just for continuous integration, but also continuous deployment of my websites.

So let’s say you already have your website checked into a github repository. Every Travis setup is defined in a file called .travis.yml, and because we want to separate this file and the .git directory from our website code, we move the site to a directory of its own. Move all of your existing files into a folder named source. In my case, this consisted of a couple of html files, some subdirectories and a .htaccess file:

mkdir source
git mv *.* .ht* source

Next, I like to create a directory for bash scripts named s (I’m a lazy typist), and then add a script that runs my build to it:

mkdir s
echo '#!/bin/bash' > s/travis-build
chmod 755 s/travis-build

Open s/travis-build in your favorite editor, and insert the following:

abort() {
    local message=$1
    echo $message
    exit -1
[ -z $FTP_PASS ] && abort "FTP_PASS is undefined"
[ -z $FTP_USER ] && abort "FTP_USER is undefined"
[ -z $FTP_SITE ] && abort "FTP_SITE is undefined"
 -e 'mirror -c -e -R source ~ ; exit'

I’m assuming here that the website lives in the home directory of your FTP server account, change the ~ to ~/public_html or any other remote directory if that’s not the case.

Finally, create a file named .travis.yml in your repository’s root directory, and make it look like this:

sudo: false
    - lftp
os: linux
script: s/travis-build

You may have noticed that the travis-build script expects a few environment variables to be set, among them FTP_USER and FTP_PASS for the username and password of the account. For security reasons, we certainly do not want to put out FTP password into a public github repository, so we’re using a feature of Travis that allows us to encrypt environment variables. To do this, you need to install the Travis command line client, and then run the following commands (insert your own password, username and ftp server data where appropriate):

travis encrypt FTP_PASS=password --add env.matrix
travis encrypt FTP_USER=username --add env.matrix
travis encrypt --add env.matrix

Now create an account with Travis, add your repository to the ones that it should monitor for building, and push all your changes. Voila! Your website is now automatically deployed after each push.

For bonus points, if your website has integration tests, run those in your s/travis-build script before the lftp command, and if they fail, skip the deployment.

NextGenTel Inteno DG150 DNS Settings

| Comments

Lately, my internet has been hardly working at all. I finally traced this down to the Inteno DG150 router that NextGenTel provides to its customers. It seems that occasionally, the DNS server in that box just dies and doesn’t restart. I have an additional wireless AP, two laptops, a gaming PC, two servers, a phone and a tablet, plus occasional guests hooked up to it, so I may be stressing this thing more than the average user, but restarting it twice a day was getting old, so I had to look for solutions.

EnnoDB 1.3 Released

| Comments

EnnoDB 1.3 fixes a critical bug and introduces several new convenience features for administrators.

  • bug: when updating an existing key, the in-memory database was corrupted (aka the catbug).
  • configuration through /etc/ennodb/ennodb.ini
  • added a read-only mode in which no new log entries are written
  • added -v option to print version number

Announcing EnnoDB

| Comments

Today I am announcing the first official version of EnnoDB, a new entry in the busy field of NoSQL databases. It’s goal is not to be a tool for Big Data problems, but more for the Medium to Small Data that fits into memory.

I originally wrote this software as an exercise, but it got out of hand and became actually useful. In other words, you may want to think twice before using this with mission-critical data. I wouldn’t, and I wrote the thing!

Source code is available on github under a BSD style license.

Security, Norwegian Style

| Comments

Today I had to log in to NAV’s pages to read a response to a message I sent them. To do this, I need to log in. To log in, I need to use one of their supported authentication mechanisms. All of them are terrible.

Four Hour Commute: Lessons Learned

| Comments

For the first time in my life, I have had to commute for a job, travelling two hours each way to Oslo and back home. This has not been easy, and now that it’s over, I thought I should share some of my experiences.