Tooltracker
Kovacsics Robert
One very common way of tracking tools that I have now seen at several companies is a spreadsheet, or equivalent chat/channel, where when you borrow a piece of equipment, you are meant to update the tracking spreadsheet.
The problem with this is that this is easiest to do on your desktop, but when you sit down at your desktop your mind goes to using the tool you borrowed, and forget to update. Or you are borrowing it to go to somewhere else, so you can’t update it until you come back, again leaving a lot of scope for forgetting.
So I have written a simple tool to make tracking less memory intensive, based on two insights:
- You almost certainly have your phone on you;
- It has a QR code reader and an e-mail client.
The first insight might not hold true if it’s on charge, but even with short battery lives it is more likely than not. And if it’s charging at your desk then we are no worse than the status quo.
But if you have your phone on you, you can do the tracking while you are walking to your desk/destination.
Using e-mail and QR codes does not require installing any other software, or registration, as both are usually installed on phones.
I was also learning Go, and as it happens this was a great project for getting to know Go better!
Emails and mail-transfer agents
So I was going to write a program which receives an e-mail – sounded simple, given I knew e-mail is just a text message along the lines of:
From: sender@senderorg.net
To: recipent@recipentfamily.home
Subject: Some line
Body is separated by an empty line.
And that I could write an SMTP (simple mail-transfer protocol) server which just waits and listens for these messages. The idea was that the company’s mail server could do the listening to the world, and forwarding relevant, authorized messages.
Though turns out there is more to this. Fortunately, Go has a lot of libraries, which did help me avoid reinventing the wheel.
Trial run
Once I had something basic up and running, I thought a good way of getting it tested is to use it for a mini treasure hunt at work. But what treasure? Candy often works as an incentive, so I bought a sharing box of chocolates. Though as I didn’t want to print QR codes on each piece of small chocolate, I used those origami cube/balloon/water bomb designs which are easy to make and I can just print a QR code on them before folding.
But they’re a bit plain as is.
Origami UV mapping
So I figured out the folding in reverse, to know how to print the texture to make it display properly once folded. And I had to print everyone’s favourite cube1!
If you are curious as to what the UV map looks like, you can head to the github repo to check it out. The tabs need some adjustment, but it works well enough. You can also make your own cubes: just open an existing one with Inkscape, import the desired texture, map it to one face, click Object → Pattern → Object to Pattern, then convert the rest of the faces to use the same pattern. There might need to be some shifting of the pattern, there was some trick to it that I have since forgotten.Sorry.
International mail
During the treasure hunt, I found out that e-mails aren’t as simple as just the text above, it turns out there are various encoding for representing 8 bit values in 7 bits. After all, it was only the late 90s that coders ventured out of their basements and discovered the rest of the world2! Fortunately there was a library to do the e-mail decoding for me too, so that I didn’t have to do it myself.
Authentication
So far, we have only received mail, assuming no malicious input. The sweet, innocent model of the early internet, wouldn’t it be nice if that still held? But hopefully I don’t need to remind you, there are malicious people on the internet, so I needed to implement some form of authentication. But this isn’t a problem I had to solve from scratch, the e-mail system already solves this, I could just piggy back on their solution: DKIM.
This ensures that the e-mail claiming to be from Fen at 123 Bogwater Avenue has at least been sent from 123 Bogwater Avenue. Essentially it’s the postman’s stamp saying that they picked up the mail from the indoor mailbox at 123 Bogwater Avenue. This was good enough for me – in practical terms this meant that the mail came from our company servers3.
IMAP
But it isn’t as simple as that either. Because the company is just using Outlook, which is not behind our firewall, I would have had to listen on an externally open port for forwarded mail to reach me. Which is a big no. So next I implemented a small IMAP client, the mail fetching bit, which in our analogy is just heading out to the post-box to collect new mail. Again, Go was a good choice here as some of the work was already solved for me.
Deployment
Almost done! But what we have currently is just software, it doesn’t yet run anywhere. I had to then create a solution to deploy it onto a server.
NixOS
My first choice was to make the tooltracker program into a Nix package, and just throw a NixOS image onto an AWS instance. This worked, though I was surprised to learn that AWS takes on the order of minutes to remove a machine instance.
But as Nix is a bit radical, I also ended up doing something simpler and more traditional.
Cloud-init
Somewhere between manually installing a VM, and creating a disk image with the given configuration installed, without ever running that machine, sits having a machine template, which runs some customisation script on first boot. So I ended up learning a bit about cloud-init, which is just this, except the documentation required better knowledge of its working than at least I had. Classic coding. I figured it out, you can look at the README if you are curious.
Ansible
Ansible is more or less just a way of writing the steps you use to provision a machine into a file (called a playbook) so that it can be reproduced later. It has some support for changing the script and rerunning it on an existing machine, but the support for that isn’t perfect4. But good enough here.
This is it! It’s a story of “I’ll just do something simple” meeting “this is a lot more complicated than I thought.” But isn’t that how it always goes? Fortunately it did manage to mostly all fit in within the period when I was interested in solving this problem, so it didn’t end up in the unfinished projects pile.
And I’ve learned more skills, and had fun, which is what it’s all about.
No companion cubes were incinerated in this experiment. ↩︎
Okay I apologise, this is unfair, it’s more accurate to say that in the late 90s more and more computers became connected together so old assumptions, such as all text is 7 bit ASCII, just didn’t hold. But it surprised me that it was so late. ↩︎
Though later it turned out that mail within the same domain isn’t signed. Which does then rely on the domain throwing away bad email claiming to be from that domain. ↩︎
Nor did I make an effort to make the playbook support rerunning. The whole provisioning just takes a couple of minutes. ↩︎