the corner office : tech blog

a tech blog, by Colin Pretorius


I had great plans for doing interesting things over the Christmas break, but I ended up spending the time sorting out the household's backups.

Until now, my backup system boiled down to semi-regularly rsyncing to one of two external hard drives, and some of my most important directories being far less regularly dumped into encrypted tarballs and synced to a free cloud storage provider.

My main worries are not having data only at home (one fire, flood or burglary away from losing everything), and not tracking changes to important files - even more of a worry these days with the rise of ransomware. After a few false starts, this is what I've settled on:

  • I discovered BorgBackup. It does exactly what I wanted: de-duplicating backups, so your backup 'archives' don't waste space (and in fact, you save space if lots of your files are similar), and it isn't hampered by renaming files and the like. That, and the backup data files are encrypted, so I'm not worried about them being backed up to the cloud.

  • Note to self: send printed copies of encryption keys to friends and family on other continents.

  • I've used borg with WSL, and uploading files seems to work well enough. I haven't tried cygwin. I couldn't back up directly to an external hard drive (iirc, due to a not-yet-implemented system call in WSL which caused borg to choke), but worked around that by setting up some VirtualBox vms and getting the data to them via ssh.

  • for pushing data to cloud storage, I'm using rclone. Like borg, a great piece of free software.

  • I settled on plcloud for online storage. They had a Christmas special which made it pretty cheap to get 2TB for a year. I'm nowhere near that now but if I start ripping our CD collection to flacs, which I want to do in 2018, then I'll be glad to have the headroom.

  • I also looked at Backblaze B2; they're well regarded and I may yet use them for additional redundancy. Their monthly storage costs are only slightly more expensive than Wasabi, but downloads are cheaper, and if you're going to trust your whole life to some encrypted files in a cloud provider's data centre, I think it's a good idea to to download everything occasionally to make sure that restoring your data actually works.

  • Needless to say, Amazon Glacier and Google's equivalent (whatever it was called) have ridiculously complicated and scary pricing models for their cold storage options, so they were non-starters.

{2018.01.06 23:54} : Comments (0)

Firefox caches

To move the cache dir out of your main profile directory, set



Note also comment about a vanilla Firefox separating the profile between Local and Roaming (mine isn't like that, but I've always pointed to a profile in another location.

{2017.12.30 11:08} : Comments (0)

Windows It Is

I lasted a little over a month, but finally gave up on Linux and switched to Windows 10. I enjoyed using Xubuntu, but there were a few frustrations, like erratic support for my bluetooth headphones, a random crash (not something I'm used to with Linux), and fiddly printer set-up, and an overly sensitive wireless mouse, and finally, very disappointing Intellij performance that I just didn't have the energy to try and troubleshoot.

That, and despite me preparing the family for ages ("this is going to be a Linux PC, so your Windows stuff will stay on the laptop"), when it came down to it, I didn't feel that what I was gaining from using Linux was worth it, given what everyone else at home was missing out on.

(Ironically, after switching to Windows, Ronwen said 'I miss Xubuntu'. The eldest has his Roblox on Windows, so he's happy. So perhaps we'll switch the laptop over to Xubuntu instead).

Beyond that, I have to grudgingly admit that Windows 10 is pretty solid, and with VirtualBox, and the performance and memory on this machine, using Linux VMs is not an issue, so Windows doesn't prevent me from using as much Linux as I'd like.

{2017.11.28 21:40} : Comments (0)

New PC

It's taken 11 loooong years since we moved to the UK, but I finally have a desktop PC again.

We've always had laptops because until we moved into the new house, we've never had a dedicated study - so always shuffling between spare room and living room as needed. This time around I hadn't actually thought about getting a PC, and was pretty close to ordering a new laptop when it I thought... why not?

One thing I learned - again - is that buying a laptop is far less complicated than buying a PC. All told, I spent nearly a month getting my head around the latest and greatest in PC hardware. Along the way I discovered PCPartPicker (great site), did a heap of research, waited (im)patiently for all the parts to arrive, built it (without frying or destroying anything), and am now a happy desktop owner, again.

The goal was a beefy PC with lots of memory, running Linux. A solid development machine, not a gaming machine, but with a 'you never know' at the back of my mind. I ended up with an AMD Ryzen 1700 (I'm a sucker for an underdog, but Ryzens are well and truly impressive), and a workable graphics card (because you never know...) and my first ever SSD, and 32GB memory (a decent whack of memory - not as decent as 64GB, but 64GB at today's prices is pure madness).

The main thrill of the Ryzen is 8 cores, 16 threads. Overkill? Maybe. The dream is me doing dev work on the machine, a couple of VMs running, with the eldest logged in remotely and playing MineCraft, without me even noticing.

Oh, and a case with a glass panel, so that my sons (of course), can see the LEDs from the motherboard and CPU. I don't remember those from 11 years ago.

{2017.10.14 23:17} : Comments (0)

Kotlin Properties

A minor Kotlin annoyance. If you have a Java class with a public final field, such that you just reference it as, then it'd be nice for a Kotlin equivalent to be accessible in the same way.

Problem is, Kotlin/Java interop converts that to Java Bean style, so a Kotlin has to be accessed as foo.getBar() from Java code. I was tearing my hear out wondering why the compiler thought the field I was accessing had 'private access' when it so obviously didn't.

Upshot: cue some editing when converting Java classes to Kotlin.

Probably not a huge issue for most 'idiomatic' Java, but I've long been a fan of exposing immutable fields for struct-ish types this way (subject to usual public API caveats etc; it's trivially easy for internal-only code to be refactored into method accessors if you ever need it, and in the meantime, you have cleaner code, cf. any language which supports properties).

{2017.09.14 18:35} : Comments (0)

Thoughts on Kotlin

Living on the edge, throwing caution to the wind, a walk on the wild side and all that, I decided to git checkout -b and give Kotlin a try on a personal budgeting app I use and occasionally tweak. I'll probably update this as I go along:

  • big win: able to start adding Kotlin code to an existing Java project with a few slabs of xml in pom.xml. Java code calling Kotlin classes in the same project and vice versa, inheritance in both directions. Brilliant.

  • C# features that I'm enjoying: extension methods, properties, named parameters, default parameters, var (and even better than C#, val).

  • C# features not there, which aren't a big deal but will be really welcome if Project Valhalla delivers for the JVM: value types and better generics.

  • the whole primary and secondary constructor thing reminds me of my foray into Scala. I'm still ambivalent about it, but trying to be open-minded. Where it gets messy is that suddenly you don't have the cleaner, Java-typical statics-then-instance, publics-then-privates and finals-then-mutable ordering of fields at the top of your class. There's presumably an idiomatic way of doing this, I just don't know it yet. I wonder whether the C++ tendency to keep privates and consts at the bottom of the file make more sense.

  • top-level functions. Great idea, and why not?

  • sad: why not save developers the RSI and call it Bool?

  • sad: no unsigned types. There's a post on the Kotlin forum where Jetbrains say "yes it would be nice but it's many many months of work".

  • the open question for me is always the extent to which the compiler can bypass boxing to get things done. This may not matter for lots of things but for serious performance, it matters (in the same vein in which your average "use BigDecimal dammit" responders on SO rather betray the kinds of systems they don't work on).

  • typealias is a nice idea, but if it was as strict as a typedef it'd be even better.

  • I like the fact that Kotlin re-uses and extends the Java libraries, rather than trying to reimplement everything.

{2017.08.09 11:42} : Comments (0)


Steve Yegge says it's cool.

I first noticed Kotlin a year or two ago. I was doing some Java dev at home and thought "this sucks, I really wish I had C# features on the JVM". I ended up reading about Xtend (Eclipse world) and Kotlin (Intellij world). When confronted with a new library or language, my first question is always "will I be able to compile or upgrade this in 10 years' time?". Many of my pet projects at home have been kicking around for that long or longer, and I've no shortage of fun things I'd rather be doing than migrating old code.

So, will Kotlin take off? Compared to some of the possibly-the-next-big-thing languages I've looked at over the years, Kotlin seems... different. I can't say why I think that. The fact that Jetbrains is behind it might be the thing that makes the difference. Maybe.

{2017.08.05 23:22} : Comments (0)

NTFS permissions

For my own reference, I keep forgetting:

Take ownership of everything:

takeown /R /F *

Reset permissions:

icacls * /T /Q /C /RESET

(all via)

{2017.08.01 20:31} : Comments (0)


Mp3 died and nobody noticed.

I'm old enough to remember when people were buying new PCs and they were "powerful enough to play mp3s".

{2017.05.17 22:30} : Comments (0)

Flashing my Nexus 7

I did a complete re-install of my years-old Nexus 7 2012 this morning after it choked on an upgrade and got stuck at boot time. Notes for posterity:

Links and downloads:

  • instructions from this page.
  • adb and fastboot: Google now release 'latest' packages so dodgy scripts on the net are no longer needed (announcement, direct).
  • download images directly from Google (I went with nakasi 5.1.1. If it remains sluggish may go back to Kit Kat).


  • unzipped adb and fastboot into c:/android-sdk/platform-tools. I don't imagine location has to be that, but that's what the instructions said so I went with it

  • unzip image and make sure files are in same directory (ie. same dir as fastboot.exe).

  • reboot Nexus into boot loader (power off, then hold Volume Down while pressing power button).

  • plug in USB cable

  • open command prompt in the platform-tools dir.

  • run the following:

    fastboot erase boot
    fastboot erase cache
    fastboot erase recovery
    fastboot erase system
    fastboot erase userdata
    fastboot oem unlock 
    fastboot flash bootloader bootloader-grouper-4.23.img 
    fastboot reboot-bootloader 
    fastboot -w update
  • reboot into bootloader again

  • run

    fastboot oem lock
  • reboot.

Worked like a charm for me. Full output:

C:\android-sdk\platform-tools>fastboot erase boot
< waiting for any device >
erasing 'boot'...
OKAY [  0.080s]
finished. total time: 0.085s

C:\android-sdk\platform-tools>fastboot erase cache
******** Did you mean to fastboot format this ext4 partition?
erasing 'cache'...
OKAY [  0.116s]
finished. total time: 0.119s

C:\android-sdk\platform-tools>fastboot erase recovery
erasing 'recovery'...
OKAY [  0.026s]
finished. total time: 0.028s

C:\android-sdk\platform-tools>fastboot erase system
******** Did you mean to fastboot format this ext4 partition?
erasing 'system'...
OKAY [  0.558s]
finished. total time: 0.560s

C:\android-sdk\platform-tools>fastboot erase userdata
******** Did you mean to fastboot format this ext4 partition?
erasing 'userdata'...
OKAY [  7.542s]
finished. total time: 7.544s

C:\android-sdk\platform-tools>fastboot oem unlock
(bootloader) erasing userdata...
(bootloader) erasing userdata done
(bootloader) erasing cache...
(bootloader) erasing cache done
(bootloader) unlocking...
(bootloader) Bootloader is unlocked now.
OKAY [ 25.253s]
finished. total time: 25.256s

C:\android-sdk\platform-tools>fastboot flash bootloader bootloader-grouper-4.23.img
target didn't report max-download-size
sending 'bootloader' (2100 KB)...
OKAY [  0.275s]
writing 'bootloader'...
OKAY [  1.234s]
finished. total time: 1.513s

C:\android-sdk\platform-tools>fastboot reboot-bootloader
rebooting into bootloader...
OKAY [  0.015s]
finished. total time: 0.017s

C:\android-sdk\platform-tools>fastboot -w update
target didn't report max-download-size
archive does not contain 'boot.sig'
archive does not contain 'recovery.sig'
archive does not contain 'system.sig'
archive does not contain 'vendor.img'
wiping userdata...
Creating filesystem with parameters:
    Size: 30080499712
    Block size: 4096
    Blocks per group: 32768
    Inodes per group: 8160
    Inode size: 256
    Journal blocks: 32768
    Blocks: 7343872
    Block groups: 225
    Reserved block group size: 1024
Created filesystem with 11/1836000 inodes and 159268/7343872 blocks
wiping cache...
Creating filesystem with parameters:
    Size: 464519168
    Block size: 4096
    Blocks per group: 32768
    Inodes per group: 7088
    Inode size: 256
    Journal blocks: 1772
    Blocks: 113408
    Block groups: 4
    Reserved block group size: 31
Created filesystem with 11/28352 inodes and 3654/113408 blocks
Bootloader Version...: 4.23
Baseband Version.....: N/A
Serial Number........: 015d25785843f405
checking product...
OKAY [  0.031s]
checking version-bootloader...
OKAY [  0.017s]
sending 'boot' (5184 KB)...
OKAY [  0.662s]
writing 'boot'...
OKAY [  0.217s]
sending 'recovery' (5738 KB)...
OKAY [  0.736s]
writing 'recovery'...
OKAY [  0.238s]
erasing 'system'...
OKAY [  0.115s]
sending 'system' (649455 KB)...
OKAY [ 81.590s]
writing 'system'...
OKAY [ 36.336s]
erasing 'userdata'...
OKAY [  4.909s]
sending 'userdata' (139157 KB)...
OKAY [ 17.318s]
writing 'userdata'...
OKAY [ 12.632s]
erasing 'cache'...
OKAY [  0.089s]
sending 'cache' (9052 KB)...
OKAY [  1.141s]
writing 'cache'...
OKAY [  1.080s]

finished. total time: 157.261s

C:\android-sdk\platform-tools>fastboot oem lock
(bootloader) Bootloader is locked now.
OKAY [  1.430s]
finished. total time: 1.433s


{2017.01.08 13:02} : Comments (0)

« Older


main blog


rssfeed posts

© Colin Pretorius