Category Archives: tech

Random inputs in unit testing

CC by StockMonkeys.com

I recently had an upstream reviewer telling me that I should not randomise my test input because “randomness does not provide a useful input to the test and sets a bad example of practices for writing tests”.

I am going to explain here why this is wrong and it’s actually good practice to randomise inputs. Let me start by saying that random test failures are not the same thing as spurious test failures. I’ll come back to that later.

Continue reading Random inputs in unit testing

LXD on Linode servers

I was recently trying to get LXD working on my Linode server, but was getting this error:

$ lxc launch ubuntu:16.04 wordpress       
Creating wordpress
Starting wordpress
error: Error calling 'lxd forkstart wordpress /var/lib/lxd/containers /var/log/lxd/wordpress/lxc.conf': err='exit status 1'
  lxc 20161010203338.247 ERROR lxc_seccomp - seccomp.c:get_new_ctx:224 - Seccomp error -17 (File exists) adding arch: 2
  lxc 20161010203338.247 ERROR lxc_start - start.c:lxc_init:430 - failed loading seccomp policy
  lxc 20161010203338.247 ERROR lxc_start - start.c:__lxc_start:1313 - failed to initialize the container

The fantastic Stéphane Graber helped me to work out that the default Linode kernel doesn’t have the right bits compiled into it, and I should be using an Ubuntu kernel instead.

So, following the guide at https://www.linode.com/docs/tools-reference/custom-kernels-distros/run-a-distribution-supplied-kernel-with-kvm to upgrade my kernel, it now works.

Droning on!

I went and bought myself a DJI Phantom 4. Holy crap, I’m impressed. 12MP images and 4k video. Not to mention all the other bells and whistles like collision avoidance, auto return to home and when you put it in speed mode, it does 70km/h!

Here’s the first of a couple of videos I put together for it:

Webex using Ubuntu LXD containers

If you read my previous post WebEx in Ubuntu LXC containers you’ll have learned how to get Cisco’s Webex running on Ubuntu in a 12.04 container.

I figured it was time to work out how to get it running in the newer LXD containers available in 16.04, here’s how I did it.

Install LXD

apt-get install lxd
sudo lxd init

When it asks you about networking, use the existing lxcbr0 bridge, do not let it use a new bridge as by default it will create lxdbr0. We need to stay on lxcbr0 so that networking continues to work in the old containers.

Create the LXD container

lxd init ubuntu:precise webex

This will download a new 12.04 template if you don’t already have one, it will take a while depending on your Internet connection.

Cheat by copying the old rootfs

I’m not going to rebuild my rootfs from scratch, the old one is perfectly usable! So as root, we can copy it from the old LXC area:

cp -rp /var/lib/lxc/webex/rootfs /var/lib/lxd/containers/webex/

Configure the container

The old container rootfs was a privileged container so we need to do the same on this LXD copy:

lxd config set webex security.privileged true

To make the sound device available you need to set up the sound device in the container. Here I am adding all the devices under /dev/snd/ on my own host, note that yours may differ so edit the commands accordingly:

lxc config device add webex /dev/snd/controlC0 unix-char path=/dev/snd/controlC0
lxc config device add webex /dev/snd/hwC0D0 unix-char path=/dev/snd/hwC0D0
lxc config device add webex /dev/snd/hwC0D3 unix-char path=/dev/snd/hwC0D3
lxc config device add webex /dev/snd/pcmC0D0p unix-char path=/dev/snd/pcmC0D0p
lxc config device add webex /dev/snd/pcmC0D3p unix-char path=/dev/snd/pcmC0D3p
lxc config device add webex /dev/snd/seq unix-char path=/dev/snd/seq
lxc config device add webex /dev/snd/timer unix-char path=/dev/snd/timer

You may remember I was using ssh X forwarding in the old container. We don’t need to do that any more as we can get direct access to the video from the container by using this config:

lxc config device add webex /dev/dri/card0 unix-char path=/dev/dri/card0
lxc config device add webex /dev/dri/controlD64 unix-char path=/dev/dri/controlD64
lxc config device add webex /dev/dri/renderD128 unix-char path=/dev/dri/renderD128
lxc config device add webex /dev/dri/fb0 unix-char path=/dev/fb0
lxc config device add webex /dev/video0 unix-char path=/dev/video0
lxc config device add webex X11 disk source=/tmp/.X11-unix path=/tmp/.X11-unix

Again your devices under /dev/dri may differ a little to mine, change accordingly.

Now, start the container and start a bash shell in it:

lxc start webex
lxc exec webex bash

You’ll now have a root prompt in the container. You can test that sound is working by doing something like:

sudo -u ubuntu aplay /usr/share/sounds/alsa/Front_Center.wav

In root’s home we need to make a script to start firefox for us, it looks like this:

root@webex:~# cat webex.sh  
#!/bin/bash 
DISPLAY=:0 su -c firefox - ubuntu

Make sure to chmod +x webex.sh

Now, all things being good, you can do this to launch Firefox:

lxc exec webex ./webex.sh

Launch Webex as you normally would and verify that it works. If it’s OK, you can remove the old SSH service as it’s not needed any more.

apt-get remove openssh-server

In my next post, I’ll explain how to convert the configuration into a more handy LXD profile that you can use for any container.

On Successful Teams …

To build a successful team, you need several facets all working in harmony.

Self-motivation and desire

Successful teams consist of people who are self-motivated and have an innate desire to succeed.

Communication

It’s a cliché but good communication is essential. The team must be open, transparent and share details of its members’ work. Keeping secrets fosters mistrust.

Proactive

Good teams spend less time responding to external events and more time being proactive about making sure they are in control.

Adaptation and resilience

A good team is adaptive and resilient to change. A good team will be prepared to throw away work if it means a more successful outcome by doing something differently.

Decision making

Everyone should know how and by whom decisions are made.

Mutual support

Mutually supportive team members create something that is larger than the sum of their parts. They will be prepared to help each other at any time.

Reliability and predictability

If you are both reliable and predictable, you will succeed. This means not only delivering on time, but reliable to each other in the team.

Yubikey as Google Authenticator on Ubuntu

Second factor authentication (2FA) is a fact of life these days for serious security. Many sites accept and use Google Authenticator which uses a time-based code on your phone that changes every 30 seconds.

A Yubikey as shown is also another 2FA device that is able to work as a USB HID (it appears as a keyboard) and can send one-time codes when the button is pressed, which is loads more convenient than opening up an app on your phone.

yubikeyBecause it doesn’t have a clock, however, it might not seem apparent how you can use it as a Google Authenticator replacement, but there is a way!

Yubico has a few tools that you can use to program the key. On Ubuntu you can grab them by installing the yubikey-personalization package:

sudo apt-get install yubikey-personalization

You will also need a Python script that handles a few things that you need to interact with the Yubikey:

wget https://raw.github.com/xaviershay/yubi-goog/master/yubi_goog.py

Finally, you will need the Google Authenticator secret key. It’s not easy to get this from an existing configured Google Authenticator but if you are using it for SSH it may be on your SSH host in first line of the $HOME/.google_authenticator file. If not, you need to talk to your admin.

OK¸ now you can program your Yubikey. The Yubikey has got two slots for configuration. I put mine in slot 2 but you can use slot 1 as required.

ykpersonalize -2 -o chal-resp -o chal-hmac -o hmac-lt64 -a $(./yubi_goog.py --convert-secret | cat) -y

This will prompt you for the Google Authenticator secret (Change the -1 to a -2 if you want to use slot 2). Now, you are ready to generate the 6-digit codes that Google Authenticator uses.

As I said above, the codes are time-based but the Yubikey doesn’t have a clock so you need to use the yubi_goog.py script to send the right challenge to the key, which will respond with the code:

./yubi_goog.py --yubi-no-sudo

If you used slot 1 instead of slot 2 you’ll need to change the hard-coded slot around line 103 of yubi_goog.py where it constructs the ykchalresp command.

So this is nice but we can make it more convenient by using a global shortcut. I use KDE as my desktop environment but you should be able to adapt this to other desktops.

There may be a better way of sending keystrokes to the focused window in KDE than this, but I am using a program called xte that you  can find in the xautomation package:

sudo apt-get install xautomation

Now, open up your system settings and go into the Workspace/Shortcuts section. Then click on the “Custom Shortcuts”. (This may be under Common Appearance and Behaviour/Shortcuts and Gestures if you’re using an old version of KDE like the one on Trusty 14.04).

Then click the Edit drop down and further select the New → Global Shortcut → Command/URL. This will give you a new shortcut called New Action by default (you can click on that and rename it) which has three tabs on the right, Comment / Trigger / Action.

Under Trigger you can assign a global shortcut. I am using Ctrl-Alt-Y (Y for Yubikey).

Under Action you need to paste some code in the Command/URL text box. Assuming you put yubi_goog.py in /usr/local/bin:

echo str $(/usr/local/bin/yubi_goog.py --yubi-no-sudo) | xte; echo key Return | xte

What this will do now is when you press Ctrl-Alt-Y, it generates a code and passes it to xte along with a Return keypress. xte sends the provided input to the currently focused window.

config.png

Much quicker than opening up the Google Authenticator app every time!

(PS If someone tells me how to do this on Ubuntu desktop I’ll add the instructions here)

WebEx in Ubuntu LXC containers

If, like me, you’ve Googled around looking for a solution to get Cisco WebEx working in Ubuntu and nothing really explained it properly, or you ended up with a messed up system, then I am here to help!

Most of the stuff I’ve seen requires a 32-bit installation of Firefox, which doesn’t help me much since I use a 64-bit OS, so I decided to put it all in a container (which is good practice anyway for anything that installs binaries).

Here, I’m installing my container as root as it removes a load of hassle later. You can install them as a regular user but you need more configuration, which overcomplicates things. I’ll leave it as an exercise to the reader to figure that out.

Create a 32-bit container, I’m calling mine “webex”:

sudo lxc-create -n webex -t download

It’ll prompt you for details, answer ‘ubuntu’, ‘trusty’, ‘i386’. and

Edit the config at /var/lib/lxc/webex/config and add these lines:

lxc.cgroup.devices.allow = c 116:* rwm
lxc.mount.entry = /dev/snd dev/snd none rw,bind,create=dir 0 0

These allow the container to access the host’s sound device.

Now start up the container and access its console:

sudo lxc-start -n webex
sudo lxc-attach -n webex

The first thing I do is install openssh-server

sudo apt-get install openssh-server

and then install firefox and a java plugin. Some blogs say you need Oracle Java, but I find that OpenJDK works fine.

sudo apt-get install firefox icedtea-7-plugin openjdk-7-jre

At this point, go ahead and set a password for the ubuntu user:

passwd ubuntu

Log out of the root console and now you can SSH into the ubuntu account like this:

ssh -Y ubuntu@webex

(I’ve left out the bit where ‘webex’ resolves to a real machine, just add it to your ssh config)

The -Y tells ssh to forward Xserver connections back to the host.

Now, we can test the sound to make sure that the config worked, try something like this:

aplay /usr/share/sounds/alsa/Front_Center.wav

If you hear the test sound, then it’s all good. If you don’t hear it, and get an error, then you’ll have to Google. In my case, the command was working without any error but there was no sound. I fixed this by adding a custom .asoundrc in the ubuntu user’s home directory:

pcm.!default {
 type plug
 slave.pcm {
 type hw
 card 1
 device 0
 }
}

defaults.ctl.card 1

It’s highly likely you may have to edit this for your sound hardware, but then again it may work. I’m not an ALSA expert, do some Googling if there’s still no sound, you just need to find the right device. You can test more quickly with a line like this:

aplay -D plughw:1,0 /usr/share/sounds/alsa/Front_Center.wav

Vary the device numbers of 1,0. Hopefully you’ll get it working eventually.

Now start up firefox and visit the test WebEx site:

https://www.webex.com/test-meeting.html

Start up a test meeting – and then close down firefox straight away. You did this step to get a .webex directory created, but it needs fixing. In the .webex directory you’ll see some files like this:

ubuntu@webex:~/.webex$ ls -F
1524/ remembercheckbox.bak tmpfile/

The numbered directory may be a different number, but you will have one nonetheless. Change into the directory and you’ll see some files, some of which are .so files. The problem lies in that these files depend on other libraries which are not present in Ubuntu’s latest releases (they were installed with the ia32-libs package which no longer exists). However, we can work out what’s needed and just install the packages manually.

First, we need to install a helper to find the files:

sudo apt-get install apt-file
sudo apt-file update

Now find the files that are missing:

ldd *.so | grep "not found" | sort -u

Now review what’s missing, you will see output like this (it may not be exactly the same):

libasound.so.2 => not found
libjawt.so => not found
libXmu.so.6 => not found
libXtst.so.6 => not found
libXv.so.1 => not found

Now for each missing file, we use apt-file to find out which package will install it:

apt-file search libXmu.so.6

And then install with:

sudo apt-get install -y libxmu6

After you finish this for each file, you should be all set. Start up firefox again and visit the test WebEx meeting. With any luck, the audio buttons will now be active and you can start your WebEx meeting!

Note, I am still missing a file that provides libjawt.so, but things still work for me. Go figure …

A rant on printer DRM

EDIT: I found this which works like a charm: http://www.fixyourownprinter.com/forums/laser/72904

This post is unashamedly a total rant about printer DRM. If you don’t enjoy a good rant, you’d better stop reading now.

I have the relatively cheap Samsung ML-2240 laser printer. It recently started running out of toner so I ordered a new cartridge.

RANT ONE: I can’t just buy the damn toner to refill it, you need a whole new drum cartridge, wasting perfectly good hardware. What the fuck?

I plugged in the cartridge and turned on the printer. Its light frustratingly stayed red, which means something is wrong. I plugged the old cartridge back in to check the printer wasn’t broken, and the light went green (albeit with a low toner light).

Hmmm.

I contacted the people who sent me the cartridge and complained. After a few back and forth emails, it turns out that my printer has got regional DRM and because I bought it in the UK it won’t accept cartridges from here in Australia.

RANT TWO: My printer has got fucking regional restrictions on where it can be used. What the fuck?

RANT THREE: I did some reading and it turns out that the chip also has a page counter in it and will lock out the cartridge when it gets to 1500 pages! What the fuck?

I ended up mail ordering a hacked cartridge chip from a UK retailer to replace the one in the Australian cartridge, so that it can be reused in the UK printer. I was shocked by what I read in the instructions:

RANT FOUR: If the chip thinks the toner cartridge has totally run out of toner, it permanently bricks the cartridge. What the fuck?

DRM – DEFECTIVE BY DESIGN.

I’m done with Samsung. Here’s a message to the Samsung printer people:

FUCK YOU NVID^WSAMSUNG