…the personal…

Aside

…is political

From Stallman’s GNU Manifesto:

Why I Must Write GNU
====================

I consider that the Golden Rule requires that if I like
a program I must share it with other people who like
it. Software sellers want to divide the users and
conquer them, making each user agree not to share with
others. I refuse to break solidarity with other users
in this way. I cannot in good conscience sign
a nondisclosure agreement or a software license
agreement. For years I worked within the Artificial
Intelligence Lab to resist such tendencies and other
inhospitalities, but eventually they had gone too far:
I could not remain in an institution where such things
are done for me against my will.

So that I can continue to use computers without
dishonor, I have decided to put together a sufficient
body of free software so that I will be able to get
along without any software that is not free. I have
resigned from the AI Lab to deny MIT any legal excuse
to prevent me from giving GNU away.

Why GNU Will Be Compatible with Unix
====================================

Unix is not my ideal system, but it is not too bad. The
essential features of Unix seem to be good ones, and
I think I can fill in what Unix lacks without spoiling
them. And a system compatible with Unix would be
convenient for many other people to adopt.

How GNU Will Be Available
=========================

GNU is not in the public domain. Everyone will be
permitted to modify and redistribute GNU, but no
distributor will be allowed to restrict its further
redistribution. That is to say, proprietary
modifications will not be allowed. I want to make sure
that all versions of GNU remain free.

Why Many Other Programmers Want to Help
=======================================

I have found many other programmers who are excited
about GNU and want to help.

Many programmers are unhappy about the
commercialization of system software. It may enable
them to make more money, but it requires them to feel
in conflict with other programmers in general rather
than feel as comrades. The fundamental act of
friendship among programmers is the sharing of
programs; marketing arrangements now typically used
essentially forbid programmers to treat others as
friends. The purchaser of software must choose between
friendship and obeying the law. Naturally, many decide
that friendship is more important. But those who
believe in law often do not feel at ease with either
choice. They become cynical and think that programming
is just a way of making money.

By working on and using GNU rather than proprietary
programs, we can be hospitable to everyone and obey the
law. In addition, GNU serves as an example to inspire
and a banner to rally others to join us in sharing.
This can give us a feeling of harmony which is
impossible if we use software that is not free. For
about half the programmers I talk to, this is an
important happiness that money cannot replace.

less is more or usable clickpad

Aside

One of the unfair advantages of Apple hardware is the quality of their touchpads.

The synaptics clickpad in my yoga 2 ain’t Apple-quality, that’s for sure. It’s still quite nice to use, though, but the default configuration is pretty conservative. Here’s what makes it working for me on xenial with x11:

  • The libinput driver. Tweaking the synaptics one is an interesting exercise if one has hours for experimentation, but, ultimately, one will fail. So, let’s get rid of synaptics and make sure it’s libinput (requires X11 session restart):
sudo apt purge xserver-xorg-input-synaptics
sudo apt install xserver-xorg-input-libinput
  • No soft buttons. Soft buttons are evil. One-, two- and three-finger clicks are fine. Also, tapping is good.
#!/usr/bin/env bash

xinput --set-prop "SynPS/2 Synaptics TouchPad" "libinput Click Method Enabled" 0 1
xinput --set-prop "SynPS/2 Synaptics TouchPad" "libinput Tapping Enabled" 1

(I’m lazy, so this gets executed on every login instead of being put into an X11 configuration snippet.)

go the fuck to sleep

Aside

intro, where complaints are made excessively

Note: this short article in no way criticises systemd. It’s not systemd's fault, that – while it provides a nice framework for managing various power states – it does not come with any built-in functionality besides bare kernel interface. If that works for you and you don’t need to handle any quirks of your hardware, you don’t need this article.

But I digress. Until systemd's suspend and hibernate will provide the same functionality as pm-utils, one might just want to tell systemd to use pm-utils. It’s easy enough to do.

the actual part where things are described

Disclaimer: I take no responsibility for any damage this might do to any system. I’m assuming that the reader knows what they’re doing and are reasonably familiar with command line interface and systemd.

First, let’s install pm-utils. On Debian-based systems apt-get install pm-utils will do nicely.

Second, let’s locate the relevant service files. On Debian-based systems one or more of the following files should do:

/lib/systemd/system/systemd-hibernate.service
/lib/systemd/system/systemd-hybrid-sleep.service
/lib/systemd/system/systemd-suspend.service

As I’m not using hibernation or hybrid sleep, I’ve decided to override only the suspend service so I’ve put the following into /etc/systemd/system/systemd-suspend.service:

#  Use pm-utils instead of systemd-sleep

[Unit]
Description=Suspend
Documentation=man:pm-suspend(8)
DefaultDependencies=no
Requires=sleep.target
After=sleep.target

[Service]
Type=oneshot
ExecStart=/usr/sbin/pm-suspend

The only relevant change here is to replace the systemd-sleep binary in the ExecStart= stanza with pm-suspend.

Reloading the systemd configuration (systemd daemon-reload) or restarting it (systemd daemon-reexec) should do the trick. (One could probably also use systemctl edit systemd-suspend.service, but I’m new to this whole systemd thingy.)

(Note: this is a shortcut. It’s absolutely possible to port all functionality of pm-utils to use the framework provided by systemd – I just haven’t had enough time to do that. See systemd-sleep(8) and systemd-sleep.conf(5) manpages for more information.)

TIL: Fira Sans font considered invisible.

Aside

…well, some versions of it. On some systems. Sometimes.

Apparently the version from Google Web Fonts that I’ve been using until today is not rendered properly on some versions of some Linux distributions. Apparently the problem is known and the temporary fix is to not use Google Web Fonts as a source for this font.

…it would be nice if debugging the issue wouldn’t have taken a combined one man-hour of two reasonably knowledgeable people.

Reproducible results. Computing. Does not compute.

New GPG key

Aside

I’m finally moving to more secure GPG key, replacing the more-than-decade-old 1024 bit DSA key with a new 4096 bit RSA one. I’ve uploaded the new key to the pool.sks-keyserver.net and am publishing here my transition statement (which is a complete ripoff of the one suggested by the best practice document). The transition statement is signed by my two keys, old and new.

-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1,SHA512

Key transition statement
========================

From: Miroslaw Baran
Date: 22/11/2014

I've recently set up a new OpenPGP key, and will be transitioning away
from my old one.

The old key will continue to be valid for some time, but i prefer all
future correspondence to come to the new one. I would also like this
new key to be re-integrated into the web of trust. This message is
signed by both keys to certify the transition.

the old key was:
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
pub   1024D/0x8F3B66A6FC494FC4 2000-12-06
      Key fingerprint = DDBE 8A23 7348 1CA7 FC91  56CC 8F3B 66A6 FC49 4FC4
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

And the new key is:
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
pub   4096R/0x5931F4435518D7D3 2014-11-16 [expires: 2016-11-15]
      Key fingerprint = EDFF 6C46 1AC1 4AB2 7CC8  02C2 5931 F443 5518 D7D3
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

To fetch the full key from a public key server, you can simply do:
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  gpg --keyserver pool.sks-keyservers.net 
    --recv-key 'EDFF 6C46 1AC1 4AB2 7CC8  02C2 5931 F443 5518 D7D3'
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

If you already know my old key, you can now verify that the new key is
signed by the old one:
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  gpg --check-sigs 'EDFF 6C46 1AC1 4AB2 7CC8  02C2 5931 F443 5518 D7D3'
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

If you don't already know my old key, or you just want to be double
extra paranoid, you can check the fingerprint against the one above:
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  gpg --fingerprint 'EDFF 6C46 1AC1 4AB2 7CC8  02C2 5931 F443 5518 D7D3'
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

If you are satisfied that you've got the right key, and the UIDs match
what you expect, I'd appreciate it if you would sign my key. You can do
that by issuing the following command:

NOTE: if you have previously signed my key but did a local-only
signature (lsign), you will not want to issue the following, instead
you will want to use `--lsign-key`, and not send the signatures to the
keyserver

~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  gpg --sign-key 'EDFF 6C46 1AC1 4AB2 7CC8  02C2 5931 F443 5518 D7D3'
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

I'd like to receive your signatures on my key. You can either send me
an e-mail with the new signatures (if you have a functional MTA on
your system):
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  gpg --export 'EDFF 6C46 1AC1 4AB2 7CC8  02C2 5931 F443 5518 D7D3' |
  gpg --encrypt -r 'EDFF 6C46 1AC1 4AB2 7CC8  02C2 5931 F443 5518 D7D3' --armor |
  mail -s 'OpenPGP Signatures' '<miroslaw+a+signatures@makabra.org>'
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

Additionally, I highly recommend that you implement a mechanism to keep
your key material up-to-date so that you obtain the latest revocations,
and other updates in a timely manner. You can do regular key updates by
using parcimonie to refresh your keyring. Parcimonie is a daemon that
slowly refreshes your keyring from a keyserver over Tor. It uses
a randomized sleep, and fresh tor circuits for each key. The purpose is
to make it hard for an attacker to correlate the key updates with your
keyring.

I also highly recommend checking out the excellent Riseup GPG best
practices doc, from which I stole all of the text for this transition
message: <https://we.riseup.net/debian/openpgp-best-practices>.

Please let me know if you have any questions, or problems, and sorry
for the inconvenience.

Miroslaw Baran
-----BEGIN PGP SIGNATURE-----

iEYEARECAAYFAlRw4toACgkQjztmpvxJT8QEDACfSHNQiQsrGEz0rN7Ri4R/Xv8V
7f8AoIspSQgBF5vmigQxPvRabAbKt2NViQIcBAEBCgAGBQJUcOLaAAoJEEkcTgNJ
juYuEy0P/2xhCLVuQN4Xe6Q9vXh5DMdgYOjI4BLl1Fr8NDncet2cpJIuzjkMYX2l
Nk4a7yg6OXQ1UOfdhd+TYcNlmnGudypnkjDqmZ7UqZp0MwwZFBbYbGw2WzH1pFqS
Rd8JIAE/9fw+VE9kBflXWaTiLPzi0CXvjVoBaN+GCnjE34o1RBUCxsnh5Xyyw3CS
EqdY800F5OV6L7fEa/QHhYqtq9URt7KSyJ+TQsuYoF6o84ReFvBou501mTUFRZrs
zgZdhMyHn/h+nr83DT2YpfFJMi+s/6tM6/jl8vetNZbwQkRwmETd3hnLmQgNHMMO
1Lt/7+I7Ed968+cVAdzKCWqswMBhOyzcJXv2D3blFBLkyTRFB1b6l/zSR5qw9T9B
51iCtcHcSAqXDyuEsmprD4/jQwOvJcwLop5E0GIMAY2sIySS/W+yNCQzNssvou40
dnq1F6P3Q04wXueT9BPWzuZcnuDUZSSQBkC9LY18nuWTU6q4Dk7ACetsHpp2mM2l
Z5+syaWt9PPWuboBlml/PN5Hj7t3AMjUfzm+5OPkIbmypV8t/3IKllHSefCiUmkU
9LObD8XcVIr71BK6W6Sb2K3RFhAHYKbw7vJXPBm/MXd2XylKj9B5NzAaYP2WA/jS
AgkSiQPpt+Ryru5Xa8ZuEmTyeY4rtwESzg8uFdl9uHKlYR+y054/
=Qi+W
-----END PGP SIGNATURE-----

To verify the signatures on the transition statement you may need first to download my new key:

  gpg --keyserver pool.sks-keyservers.net \
    --recv-key 'EDFF 6C46 1AC1 4AB2 7CC8  02C2 5931 F443 5518 D7D3'

and then execute the following:

  wget -qO - https://makabra.org/gpg-key-transition-20141122.md.asc |
    gpg --verify

If you’ve signed my old key and are happy with the result of the verification, please do consider signing my new key too.

A hack most terrible

Aside

XSL stylesheet for transforming XML jabber-GG transport user data into spectrum2 sqlite user database:

<?xml version="1.0" encoding="utf-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">

<xsl:output method="text" indent="no"/>

<xsl:template match="/user">
  BEGIN TRANSACTION;
  INSERT OR REPLACE INTO users (jid, uin, password, language, encoding, last_login, vip)
    VALUES
    ('<xsl:value-of select="/user/jid"/>',
     '<xsl:value-of select="/user/uin"/>',
     '<xsl:value-of select="/user/password"/>',
     '',
     '',
     DATETIME('NOW'),
     0);
  COMMIT;

<xsl:for-each select="/user/userlist/contact">
  BEGIN TRANSACTION;
  INSERT INTO buddies (user_id, uin, subscription, groups, nickname, flags)
     select
       id,
       '<xsl:value-of select="@uin"/>',
       '<xsl:value-of select="@subscribe"/>',
       'Transport Gadu-Gadu',
       '',
       0
     from users where uin='<xsl:value-of select="/user/uin"/>';
  COMMIT;
</xsl:for-each>

  BEGIN TRANSACTION;
  INSERT INTO users_settings (user_id, var, type, value)
    select id, 'enable_transport', 4, '1' from users where uin='<xsl:value-of select="/user/uin"/>';
  COMMIT;
  BEGIN TRANSACTION;
  INSERT INTO users_settings (user_id, var, type, value)
    select id, 'send_headlines', 4, '0' from users where uin='<xsl:value-of select="/user/uin"/>';
  COMMIT;
  BEGIN TRANSACTION;
  INSERT INTO users_settings (user_id, var, type, value)
    select id, 'stay_connected', 4, '0' from users where uin='<xsl:value-of select="/user/uin"/>';
  COMMIT;

</xsl:template>
</xsl:stylesheet>

I’m almost sorry. (It worked, though.)

PHABRICATI DIEM, PVNC

Aside

the whys

I’ve planned to play with one or another source code management platform since quite a time, but only recently have found enough time to actually try it.

My criteria were very far from professional: I was looking for a project that:

  • is functional enough that using it instead of github won’t be too much of a pain,
  • is easy enough to install (from zero to functional installation in five hours time tops, and that including reading the documentation for the first time),
  • runs well on apache (because I already have a reasonably well-configured apache instance running),
  • works with mysql (like with the apache, I already have well-tuned mysql instance),
  • last but not least, relies on packaged software only (because I am lazy)

That unfortunately ruled out redmine and all ruby-on-rails-based github clones out there, including the otherwise appealing gitorious. The most interesting contender from the python side of the world – rhodecode – switched from free software to closed source, and the only other name I remembered was phabricator.

I’ve heard about the project for the first time during one of Facebook Dublin’s Infrastructure Open House meetings and it definitely piqued my interest then – it is, basically, an integrated software engineering platform that’s used by Facebook internally to manage all their code. It is also an open source project available under Apache licence. Written in well-managed PHP, it runs – or is advertised to run – on almost everything.

the hows

Upstream guides for both installation and setup are quite good, notes below handle the differences.

difference #1: apache + mod_fcgid + worker mpm

I have mod_fcgid configured to use a wrapper script from a directory that’s mapped to the /fcgi-bin alias:

<IfModule mod_fcgid.c>
    ⋮
    AddType application/x-php         php phtml php3
    AddType application/x-php-source  phps
    AddHandler php-fcgid .php
    Action php-fcgid /fcgi-bin/php-fcgi-wrapper
    Alias /fcgi-bin/ /var/www/fcgi-bin.d/php5-default/

    <FilesMatch ".+\.ph(p[345]?|t|tml)$">
      SetHandler php-fcgid
    </FilesMatch>

    <Location /fcgi-bin/>
        SetHandler fcgid-script
        Options +ExecCGI
    </Location>
    ⋮
</IfModule>

For Phabricator to work with this configuration you have to add the first rewrite rule, to make sure that the fcgi invocations will not be touched – if the path to the fcgi handler is not whitelisted, the last rule with its greedy regex will break the php fcgi execution.

<VirtualHost>
    ⋮
    RewriteRule ^/fcgi-bin            -                       [L]
    RewriteRule ^/rsrc/(.*)           -                       [L,QSA]
    RewriteRule ^/favicon.ico         -                       [L,QSA]
    RewriteRule ^(.*)$                /index.php?__path__=$1  [B,L,QSA]
    ⋮
</VirtualHost>

difference#2: managing phd through init daemon

I’m using the following service file to keep the phd services up:

[Unit]
Description=the phabricator daemon service
After=syslog.target network.target remote-fs.target nss-lookup.target

[Service]
Type=forking
WorkingDirectory=/srv/blueprint/phabricator/bin
ExecStart=/srv/blueprint/phabricator/bin/phd start
ExecStop=/srv/blueprint/phabricator/bin/phd stop
Restart=always
User=phd
Group=phd

[Install]
WantedBy=multi-user.target

difference#3: make diffusion’s ssh service listen on a custom port

I’m using ‘vcs’ as the user name and decided to run customised ssh service listening on ports 22 and 2401 on a dedicated IP to manage the ssh-based VCS operations. (The openssh-server package from wheezy backports is needed for the AuthorizedKeysCommand support.)

/etc/systemd/system/phabricator-ssh.service:

[Unit]
Description=phabricator ssh service
After=network.target auditd.service phd.service
ConditionPathExists=!/etc/ssh/sshd_not_to_be_run

[Service]
EnvironmentFile=-/etc/default/phabricator
ExecStart=/usr/sbin/sshd -D $SSHD_OPTS
ExecReload=/bin/kill -HUP $MAINPID
KillMode=process
Restart=on-failure

[Install]
WantedBy=multi-user.target
Alias=phabricator-sshd.service

/etc/default/phabricator-ssh:

# (line breaks for clarity)
SSHD_OPTS="-f /etc/ssh/sshd_config_phabricator \
           -h /etc/ssh/ssh_host_dsa_key \
           -h /etc/ssh/ssh_host_rsa_key \
           -h /etc/ssh/ssh_host_ecdsa_key"

/etc/ssh/sshd_config_phabricator:

# NOTE: You must have OpenSSHD 6.2 or newer; support for AuthorizedKeysCommand
# was added in this version.

AuthorizedKeysCommandUser vcs
AuthorizedKeysCommand /usr/local/lib/phabricator/bin/ssh-hook
AllowUsers vcs

# You may need to tweak these options, but mostly they just turn off everything
# dangerous.

ListenAddress 144.76.160.154:22
ListenAddress 144.76.160.154:2401
ListenAddress [2a01:4f8:200:20e2:1::c]:22
ListenAddress [2a01:4f8:200:20e2:1::c]:2401
Protocol 2
PermitRootLogin no
AllowAgentForwarding no
AllowTcpForwarding no
PrintMotd no
PrintLastLog no
PasswordAuthentication no
AuthorizedKeysFile none

PidFile /var/run/phabricator-sshd.pid

the results

Fully featured phabricator installation, with git, mercurial and svn available through https and ssh protocols, project/task management, wiki, pastebin clone etc., with LDAP and github account integration.

Not too bad for a Sunday afternoon project, if I may say so myself.