diary at Telent Netowrks

NixOS on Linode KVM#

Mon, 19 Dec 2016 21:28:08 +0000

This is much easier than you'd think by Googling - but still complicated enough to be worth writing down. Note that this description is rather on the terse side, and probably more understandable if you've done a NixOS install on "regular" hardware previously.

1) create a new Linode instance

2) select it in Linode Manager

3) make some disks: for each of these, go to 'Create a new Disk' and fill in the appropriate fields

4) now go to 'create a new configuration profile'

5) before you turn it on, go to the Settings tab and disable Lassie - otherwise it just gets confusing having it reboot when you're not expecting

6) first time boot will be into the Rescue system, so go to the Rescue tab and click 'Reboot into Rescue Mode'

7) now connect to it using lish. You should be shown a typical boot sequence ending in something like

Welcome to Finnix!

[*] Total memory: 1998MiB, shared ramdisk: 1543MiB [*] Finnix media found at sdh [*] System: Intel Xeon E5-2680 v3 2.50GHz [*] Running Linux kernel 4.1.2-finnix on x86_64 [*] Finnix 111 ready; 464 packages, 146M compressed

root@ttyS0:~#

8) now it's time to download the ISO. From the Getting NixOS page, find the URL for the latest 64 bit Minimal Installation CD and then run something rather like

root@ttyS0:~# curl -k https://d3g5gsiof5omrk.cloudfront.net/nixos/16.09/nixos-16.09.1272.81428dd/nixos-minimal-16.09.1272.81428dd-x86_64-linux.iso |dd bs=1M of=/dev/sda
root@ttyS0:~# sync
root@ttyS0:~# halt

9) Now we can boot into the NixOS installer. Check that you still have lish running in a terminal window (reconnect to it if not), then click 'Boot' in the Dashboard. You should see a Grub menu appear: cursor down to the 'NixOS ... without modeset' option then hit TAB to edit the command. Append console=ttyS0, then hit RETURN to boot. You get a NixOS boot sequence in lish, then

[root@nixos:~]#

10) This is a good time to bring up the NixOS manual in a browser tab, especially if you can't remember what you did last time

11) Create a partition table on /dev/sdb and a primary partition that fills it, then put a filesystem on it:

[root@nixos:~]# fdisk /dev/sdb

Welcome to fdisk (util-linux 2.28.1). Changes will remain in memory only, until you decide to write them. Be careful before using the write command.

Device /dev/sdb already contains a ext4 signature. The signature will be removed by a write command.

Device does not contain a recognized partition table. Created a new DOS disklabel with disk identifier 0x01a28df9.

Command (m for help): n Partition type p primary (0 primary, 0 extended, 4 free) e extended (container for logical partitions) Select (default p): p Partition number (1-4, default 1): 1 First sector (2048-2097151, default 2048): Last sector, +sectors or +size{K,M,G,T,P} (2048-2097151, default 2097151):

Created a new partition 1 of type 'Linux' and of size 1023 MiB.

Command (m for help): w The partition table has been altered. Calling ioctl() to re-read partition table. [ 441.705223] sdb: sdb1 Syncing disks.

[root@nixos:~]# mkfs -t ext4 /dev/sdb1

(This looks verbose but it's almost all default options - what I actually typed to produce that output was n, RETURN, RETURN, RETURN, RETURN, w, Control-D)

12) mount the disks

[root@nixos:~]# mount /dev/sdc /mnt
[root@nixos:~]# mkdir /mnt/boot
[root@nixos:~]# mount /dev/sdb1 /mnt/boot

13) now you can run nixos-generate-config --root /mnt. Edit the generated /mnt/etc/nixos/configuration.nix and uncomment/amend/check the following items

14) and run

[root@nixos:~]# nixos-install    # stuff happens, at length
[root@nixos:~]# umount /mnt/boot
[root@nixos:~]# umount /mnt

15) now it's time to try booting from the "hard disk": go back to the Linode Manager and create another Configuration Profile

Select the new profile in Dashboard and hit 'Reboot'. Eventually, you will see the very welcome Welcome to NixOS banner and be presented with a login prompt.

16) Login as root, using the password you set duing nixos-install. Check you have network connectivity. Arrange credentials (password or ssh key or whatever) for whatever non-root user(s) you put in configuration.nix. Try ssh into the box. When you're happy it works, use C-a d to exit lish. Your work here is done.

Hotplug scripts in NixOS#

Thu, 15 Dec 2016 08:46:21 +0000

Prompted partly by the new Met police online traffic incident reporting tool (but it's been something i've been thinking about for a while) I bought an action camera the other day: it's a "Savfy", which is a cheap clone of the SJ4000 (which is itself a cheap clone of a Gopro).

Since I need to plug it into a USB port every day or two to recharge (battery life is a claimed 1.5 hours, haven't tested this yet) I thought it would be good to automate downloading the data off it as well. This is almost my first foray into systemd and udev, and certainly the first time I've tried it in NixOS, so I have reproduced my findings below.

First, we need to recognise when the camera is connected. It's USB mass storage, which means it shows up as a SCSI disk device (e.g. sdb). In /etc/nixos/configuration.nix we add a stanza something like this:

  services.udev = {
    path = [ "/home/dan/udev/bin" ];
    extraRules = ''
    ACTION=="add", KERNEL=="sd*[0-9]", ENV{ID_SERIAL}=="NOVATEKN_vt-DSC*", RUN+="${pkgs.systemd}/bin/systemctl --no-block start copyCamFiles@%k.service"
    '' ;
  };

There are a few things worth noting here.

Great. We've got the trigger, where's the service? Again in configuration.nix

  systemd.services."copyCamFiles@" = {
    bindsTo = [ "dev-%i.device"] ;
    environment = { 
        RSYNC = "${pkgs.rsync}/bin/rsync"; 
        MOUNT = "${pkgs.utillinux}/bin/mount"; 
        UMOUNT = "${pkgs.utillinux}/bin/umount"; 
    };
    serviceConfig = {
        Type = "simple";
        ExecStart = "${pkgs.bash}/bin/bash /home/dan/udev/bin/cp-actioncam.sh %I";
    };
  };

The @-sign in the service name means this isn't actually a service, it's a template (i.e. we can pass parameters to it to instantiate services). When it's invoked by udev, the parameter passed will be the device name of the newly-added partition. We export the pathnames of some utilities that the script will need, because I haven't built a nixos derivation for the script itself. simple as a service type means (I hope) that it's not started unless asked for and that nothing is going to try to restart it when it terminates.

Finally, here's the cp-actioncam.sh script

#!/usr/bin/env bash
DEVNAME=$1
MP=/run/tmpmounts/$$/
set -e
unmount() {
    $UMOUNT $MP;
    rmdir $MP;
}
trap unmount 0
OUT=/home/dan/Videos/actioncam
mkdir -p $MP $OUT 
$MOUNT /dev/$DEVNAME $MP  
$RSYNC -a $MP $OUT

And there you have it. There are a bunch of refinements that could profitably be made: most obviously, notifying the user somehow when the copying is finished and the device may be unplugged, and not putting root-owned files into a non-root-users home directory. But this will do for now.

Some browser tabs I can now close:

Huawei E3372 with OpenWRT#

Sat, 12 Nov 2016 22:25:34 +0000

I've just moved house. The new house has no broadband or even phone line, and when I last asked about the progress of getting a line connected I was told that "Your order is currently in the newsites stage and the offsite ducting has started" and it was going to take most of a month before I could even start ordering broadband.

Which means I need mobile broadband stuff. I looked on Ebay for USB LTE sticks, and I looked on comparison sites for cheap data SIM-only deals, and ended up with a Huawei E3372h. To make this work with OpenWRT took a couple of evenings swearing at it, so here's the end result: note that all of these things were for me sufficient but may not be to you necessary.

chat
comgt
comgt-ncm
dhcpcd
kernel
kmod-mii
kmod-usb-net
kmod-usb-net-cdc-ether
kmod-usb-net-cdc-ncm
kmod-usb-net-cdc-subset
kmod-usb-net-huawei-cdc-ncm
kmod-usb-serial
kmod-usb-serial-option
kmod-usb-serial-wwan
kmod-usb-wdm
libpthread
librt
libusb-1.0
libusb-compat
usb-modeswitch
usbutils
wwan
zlib

config interface 'WAN'
        option proto 'ncm'
        option apn 'everywhere'
        option ifname 'wwan0'
        option pdptype 'IP'
        option device '/dev/ttyUSB0'
        option delay 15

I get about 12-17Mb/s (over wireless, sitting next to the router) according to fast.com which is not superfast considering the hardware is supposed to be capable of 150Mb/s and the package I'm paying for is "up to 60Mb/s". There may still be something I'm missing in the configuration. Whether I spend much more time looking at it is going to depend mostly on how much faff it takes to get proper broadband installed. It might be a while

I can't believe it's not buttons#

Thu, 13 Oct 2016 23:03:30 +0000

"Second will be some slightly nicer play/next/previous buttons". As predicted. I don't claim they're pretty, just that they're an advance on what went before.

Next: through a combination of dogfooding and Agile backlog reprioritisation, I as the product owner and customer representative have determined that I as the development team should next tackle "make it not behave apparently randomly when adding tracks to the playqueue after it has played what was previously in the queue".

Maybe in the process I can reduce the number of arbitrary reference cursors that are littered thoughout it.

Plank#

Wed, 12 Oct 2016 23:02:46 +0000

In between my ongoing attempts to buy a house I am still playing on and off with making Sledge into a thing I might actually want to use. First on the list is showing the currently-playing track name and not just its length. Second will be some slightly nicer play/next/previous buttons. Third, maybe making it more robust against pressing "refresh". Ongoing and not yet finished, stripping out the cheesy CSS text shadows etc to make it look less like a 1990s OSF/Motif application and more like "flat UI" - a design trend of which I thoroughly approve. I will be terribly disappointed when the fashion pendulum swings back towards requiring artistic skills for a web page to look modern, because (as you can see) I have none.

(Why is this blog entry titled "Plank"? What else would you call a flat sledge?)