It's about the journey: Compiling 64-bit Unison / GTK2 on Windows

Unison File Synchronizer

The excellent MSYS2 (mingw64 and mingw32) subsytem makes compiling native Windows compilations "as easy as compilation can be". However, as with everything in life, sometimes when trying to do one thing (compile a program), you end up chasing other vaguely related issues (one exotic compile error after another).

For synchronizing files between servers and workstations I use the open source GPLv3 licensed Unison File Synchronizer [1]. Although the text interface version of Unison compiles straight-out-of-the box on mingw64, the GTK2 interface proved to be a bit more cumbersome.

To compile Unison with the GTK2 interface, lablgtk [2] is needed, an OCaml interface to GTK.

So, the journey began with firing up a shell in a fresh mingw64 environment, and installing the build prerequisites:

pacman -Sy --noconfirm base-devel git \
mingw-w64-x86_64-{glib2,gtk2,ocaml,pango,toolchain}

After downloading the latest source (2.18.5 [3]) and trying to compile it (using make ) after running

./configure --prefix=/mingw64 --disable-gtktest

the first error message is shown:

mingw64/include/gtk-2.0/gdk/gdkwin32.h:40:36: fatal error: gdk/win32/gdkwin32keys.h: No such file or directory

It seems that GTK2 version 2.24.31 contains an error [4], and incorrectly still references the file …

more ...

Zen provisioning: Bootstrap the installation of Ansible using Vagrant

zen

I'm a big fan of the DevOps attitude of "cattle" versus "pets": machines should be built in a repeatable, automated and consistent way. If there's something wrong, don't be afraid to replace a sick "cow" instead of trying to revive your "pet".

This Zen mindset also helps when preparing for demos, trainings and workshops: Usually I need a number of machines, and what better way than create them by using automation ? For that I'm using the tools Ansible, Packer, Vagrant and VirtualBox - they are all Open Source and can be used on a number of platforms (e.g. Windows, Linux and Mac OS X).

Ansible is a tool for managing systems and deploying applications, licensed under the GNU General Public License version 3 (my personal favorite).

Vagrant is a tool for managing virtual machines and is licensed under the MIT license.

VirtualBox is a virtualization environment for local use, licensed under the GNU General Public License version 2.

Packer creates a machine image by installing an operating system to a multitude of local and cloud platforms, for example VMWare, VirtualBox as well as Docker, Amazon EC2 and DigitalOcean. Packer is licensed under the Mozilla Public License Version 2.0.

How …

more ...

Compile Emacs for Windows using MSYS2 and mingw64

Emacs 25.1

Emacs 25.1 was officially released on September 17th, 2016. The excellent MSYS2 subsystem and the open source gcc compiler make it super-easy to build binaries on/for Windows (7, 8, 10). In three easy steps from source to binaries:

1: Install and prepare the MSYS2 subsytem

Download and run the installer at http://repo.msys2.org/distrib/msys2-x86_64-latest.exe After installing, run MSYS2 64bit which drops you in a Bash shell. Update all packages using the following command:

pacman -Syuu

Sometimes updates of the runtime/filesystem can cause update errors. This is no cause for panic - kill and restart the terminal. For building 64-bit Windows binaries, always use mingw64.exe to start the terminal.

Install all packages necessary for building:

pacman -Sy --noconfirm base-devel git \
mingw-w64-x86_64-{giflib,gnutls,jbigkit,lib{jpeg-turbo,png,rsvg,tiff,xml2},toolchain,xpm-nox}

2: Clone the Emacs source

To simplify building, you can define the environment variables BUILDDIR (where the binaries are built), INSTALLDIR (where the binaries will be installed to), and SOURCEDIR (where the source lives, the git repository). Note that since you're in the MSYS2 subsystem, paths are Unix-style, using forward slashes. This command creates SOURCEDIR if it doesn't exist yet, clones the …

more ...

Automating repetitive git / setup tasks

repetitite work

Imagine you work on a large number of projects. Each of those projects has its own git repository and accompanying notes file outside of the repo. Each git repository has its own githooks and custom setup.

Imagine having to work with multiple namespaces on different remote servers. Imagine setting up these projects by hand, multiple times a week.

Automation to the rescue ! Where I usually use Bash shell scripts to automate workflows, I'm moving more and more towards Python. It's cross-platform and sometimes easier to work with, as you have a large number of libraries at your disposal.

I wrote a simple Python script that does all of those things more or less 'automated'. Feed the script the name of the repository you want to clone, and optionally a namespace, patchfile and templatefile variable (either command-line or using a configuration file). The script will then:

  • clone the repository
  • modify the repository (e.g. apply githooks)
  • optionally modify the repository based on given variables
  • create a new notes file from a template
  • optionally modify the notes file based on given variables

The advantage is that you can use a configuration file containing the location of the remote git repository, the patchfile …

more ...

automatic XML validation when using git

XML

Recently I worked on a project which involved manually editing a bunch of XML files. Emacs is my favorite ~operating system~ editor, and it has XML validation built in (using the nXML mode). It highlights validation errors while-you-type. Unfortunately, even with Emacs showing potential issues in RED COLOR, I managed to commit a number of broken XML files to my local git repository. Subsequently when I pushed my errors to the remote 'origin' git repository, the errors broke builds.

Of course this can be completely prevented by locally using pre-commit hooks. If your local git repository validates XML files before you can commit them, and denies invalid XML files, then one part of the problem is solved.

A pre-receive hook on the receiving server side can do the same as a pre-commit hook locally: Validate XML files before letting somebody push a commit which can break the build process.

I looked around the Internet but couldn't find a lightweight quick script to do only and exactly that. That's the reason I whipped up a basic pre-commit and pre-receive hook, written in Python.

You can find the very basic and rough code at https://github.com/PeterMosmans/git-utilities. By changing the …

more ...

The future is here: HTTP/2

Last month I held a number of presentations on the latest and greatest HTTP/2 protocol. It's an area where there's currently a lot of demand for knowledge and practical tips. Most people are surprised to find out that the're actually already using it on a daily base.

If you're interested you could check out an Ansible role which installs a number of client-side and server-side tools all HTTP/2 enabled:

  • curl - A data transferring tool with HTTP/2 support
  • h2load - A benchmarking tool for HTTP/2 and SPDY servers
  • nghttp - A HTTP/2 client with SPDY support
  • nghttpd - A HTTP/2 server with SPDY support
  • nghttpx - A transparent HTTP/2 proxy with SPDY support
  • openssl - A cryptographic library with ALPN support (1.0.2-chacha)

The following libraries will be installed:

  • libcrypto - OpenSSL
  • libcurl - CURL library
  • libnghttp2 - A HTTP/2 and HPACK C library
  • libspdylay - A SPDY library
  • libssl - OpenSSL

You can find the role at https://github.com/PeterMosmans/ansible-role-http2

more ...

Safely storing Ansible playbook secrets

see the forest for the trees

More and more organizations use dedicated software to safely handle the creation and management of secrets (for example SSL certificate keys, private variables and passwords). Three 'well known' solutions are Square's Keywhiz, Hashicorp's Vault and crypt in combination with etcd or consul.

As with all security solutions the roll-out can be quite cumbersome. The correct implementation (think key management, think audit trails, think key recovery) of any one of these solutions is difficult. And difficult means that most people won't use it, at least not right away (remember SELinux ?).

There are a number of tools available to encrypt secrets within (Ansible) repositories. One of them for instance is Ansible Vault (look here for a more in-depth review). Although the idea of selectively encrypting data is a good one, text-oriented version control systems like git or Subversion aren't meant to store binary blobs of encrypted data. Moreover you still run the risk of accidentally uploading or sharing unencrypted files. Mitigations like adding filenames of unencrypted secrets to a .gitignore file are error-prone.

How to facilitate developers and system operators to store secrets in a safe place, outside the repositories where Ansible playbooks and configuration files are kept ?

This article describes a …

more ...

OpenSSL the Ansible vault... using PBKDF2

OpenSSL the Ansible vault

Ansible is a popular open-source software platform for configuring and managing computers. It helps sysadmins to provision new servers in a reliable and repeatable way, and helps developers who want to push their code as fast as possible. It takes scripts (playbooks) as input, which a lot of people can and do share with each other. The beauty of open source. Playbooks can contain sensitive data like passwords and SSL keys - stuff that you don't want to share, or incidentally upload to GitHub.

Last year Ansible added a tool to its arsenal to easily encrypt structured datafiles (containing sensitive data), called Ansible Vault. You can specify a key or keyfile when running a playbook, which decrypts the data on-the-fly. Encrypted data can still be edited

I love it when people make it easier to use encryption. The easier it becomes, the more people will use it, the safer everybody will be.

Another beauty of open source is that you can inspect the code. And modify it! I wanted to be able to encrypt and decrypt the data where/when you cannot use Ansible vault, by using other tools and languages like OpenSSL and Bash script.

Under the hood Ansible vault …

more ...

git on Windows - location of configuration files

Git is used as distributed version control system for the majority of projects I work on. On Windows I use the official Git for Windows version, as well as the 'native' mingw/MSYS2 git binary when using the MSYS2 shell.

The location of the system and global gitconfig configuration files varies, depending on which environment (native Windows command, Windows shell or MSYS2 shell) you're using, and depending on which binary (Git for Windows versus native git). There's a logic to it, but it can be hard to figure out...

Git version 2 introduced a much easier method of finding where the git configuration files are stored, the --show-origin flag. This parameter tells you exactly where each of the configuration files can be found.

Retrieve the locations (and name value pairs) of all git configuration files:

git config --list --show-origin

Retrieve the location (and name value pairs) of the system git configuration file:

git config --list --system --show-origin

Retrieve the unique locations of all git configuration files:

git config --list --show-origin | awk '{print $1}' | uniq

Local

Regardless from where you use git on Windows, the repository (local) configuration always resides at the same location, in the root directory of your repository …

more ...

test_bn fails for OpenSSL on Windows

Compiling OpenSSL on Windows using MSYS and mingw64 is pretty straightforward. However, one of the tests (test_bn) to verify OpenSSL fails: The temporary file that test_bncreates contains Windows newline characters (\r\n) instead of the Unix type newline charater (\n).

The original regular expression checks for a zero (0) at the beginning of a line, and a newline character (\n).

(!/^0$$/)

A change to the regular expression that test_bn uses fixes this problem, and can be used on Unix as well as Windows environments. This makes the Makefile more cross-platform friendly. The modified regular expression checks for a zero (0) at the beginning of a line, an optional Windows newline character (\r) and a newline character (\n).

(!/^0\r?$$/)

md5sum: 1032dff7f957c4d1cdfa96af305c152b
Here's the patchfile (can be applied in the source directory using patch -Np1)
--- openssl-1.0.1g/test/Makefile 2014-04-07 16:55:44 +0000 +++ patched/test/Makefile 2014-05-06 00:07:20 +0000 @@ -227,7 +227,7 @@ @../util/shlib_wrap.sh ./$(BNTEST) >tmp.bntest @echo quit >>tmp.bntest @echo "running bc" - @) {if (/^test (.*)/) {print STDERR "\nverify $$1";} elsif (!/^0$$/) {die "\nFailed! bc: $$_";} else {print STDERR "."; $$i++;}} print STDERR "\n$$i tests passed\n"' + @) {if (/^test (.*)/) {print STDERR "\nverify …
more ...