Weekly Ramblings for November 3rd, 2019

Savanni D'Gerinel 3 Nov, 2019
Along the Tracks, 2019-05

Hello, everyone, and welcome back to another round of my weekly ramblings!

This week I was still a bit under the weather, but I did a lot of work and started setting up my new machine.

NixOS

For me, setting up a machine is a complicated process. I typically run NixOS where I can, and I run MacOS with a Nix overlay when I cannot. For running MacOS, where the OS comes pre-installed and ready on the pre-configured hardware, system setup can take less than half an hour. I have to install nix, clone my nix-shell repository, then run nix-env -i all, and suddenly I have a full system with all of my configuration options.

But, with NixOS, I do not have any configuration options any more. I am having to build from the base system up. My last NixOS machine has been gone for several years, the configuration options on that machine have been lost, and wouldn’t really work on the new machine, anyway.

I went with AMD fo this build, and there were a couple of different quirks that I had to resolve.

  • Thinkpad x395
  • Ryzen 7 processor

First of all, and since this is my first time really dealing with the UEFI boot, be sure to turn off Secure Boot! NixOS cannot be booted in secure mode at this time, so it is very necessary to turn this off. Primary symptom was that I would reach the UEFI boot menu, select a NixOS USB key, and would immediately get back to the UEFI boot menu. This is particularly annoying because there is no error message and no log to check.

Second one is that the stable versions of NixOS ship with a 4.x Linux kernel, and it turns out that recent AMD processors really require a 5.x kernel to resolve quite a few different bugs, especially with ACPI. That meant switching to the latest linux kernel by setting boot.kernelPackages = pkgs.linuxPackages_latest;.

I have done quite a bit in the way of configuring my new system. I have shared my entir NixOS configuration on Github. Relevant options for a Thinkpad probably come down to just these, with everything else being specific more to me.

  boot.loader.systemd-boot.enable = true;
  boot.loader.efi.canTouchEfiVariables = true;
  boot.kernelPackages = pkgs.linuxPackages_latest;
  boot.kernelModules = [ "kvm-amd" ];
  boot.extraModulePackages = with config.boot.kernelPackages; [ ];

  systemd.services.systemd-udev-settle.serviceConfig.ExecStart = ["" "${pkgs.coreutils}/bin/true"];

  boot.kernelParams = [ "acpi_backlight=none" ];
  programs.light.enable = true;
  services.actkbd = {
    enable = true;
    bindings = [
      { keys = [ 225 ]; events = [ "key" ]; command = "/run/current-system/sw/bin/light -s sysfs/backlight/amdgpu_bl0 -A 10"; }
      { keys = [ 224 ]; events = [ "key" ]; command = "/run/current-system/sw/bin/light -s sysfs/backlight/amdgpu_bl0 -U 10"; }
    ];
  };

Still got more to do here, as I don’t have the screen locking when I suspend the machine, and sometimes the machine hard locks on suspend instead of actually suspending. But I’ve made progress!

Derivations

It turns out that very few of my MacOS derivations work on NixOS. It appears that on NixOS, the derivation builders generally don’t have internet access, and so derivations that download as part of the build don’t work.

As an example, my derivation for floki depends on running npm install in a normal build script, and that npm install doesn’t have access to the internet.

For some of these, the only thing I shoul need to do is to learn how to use node2nix. But for Floki it gets more complicated because Floki is not a Javascript app, but a Clojure app that compiles to Javacript.


  • all of my development derivations
  • Fitnesstrax
  • Photography tools
  • Steam

I have a lot more to do in order to be fully running on my new machine. Much more than I expected when I started on this, but it is all educational.

Furthermore, I think of it is training, and it certainly gives me more hands-on experience with NixOS that I can share here.

But, I’m running late on this post, so that’s it for this week! I’ll let you know about additional progress over the weekend.

Weekly Ramblings for October 26th, 2019

Savanni D'Gerinel 26 Oct, 2019
_DSC2984

Every week I try to post a set of ramblings about things I find interesting or things that I have done in tech for the most recent week.

However, I’ve spent weeks sick. Longest illness of my life, to the point that I felt better while on bed rest eight days post-op than I did eight days into this illness.

In the midst of this, though, I was able to celebrate my 41st birthday, complete with wine, cheese, friends, and me threatening a cake with a knife. My pastry creations don’t fare well, but they are very, very tasty.

Go

A few weeks ago attended a Go tournament for the first time. This was an official handicap tournament under the rules of the American Go Association. In theory, the results have been reported to the AGA and I will get an official rating, though that hasn’t happened yet. I’m sure it’s because AGA is not a technical organization and everything has to be manually entered.

On OGS, I currently have a rating of 16 kyu. I entered the tournament at 15 kyu. I then won three of my four games. In some cases, I received six and eight stone handicaps, and in both cases I was victorious by a significant margin. While some of the problem is that my opponents have never had to fight against such a handicap, which really does change the nature of the game significantly, I do feel that I should have entered as a 14 or even a 13 kyu.

Either way, that tournament, and playing Go Quest (all blitz games), I have certainly gotten a lot more momentum in my playing, especially because it has been easy to play at least one 13x13 game on the train ride from Davis Square to South Station. This inspiration has made it relatively easy for me to play one or two full size games in an evening after all of my chores are done, or while I am unwinding from work.

In case you are interested, this is my account on OGS.

Por miaj esperantistaj sekvantoj, mi trovis afiŝon Baza strategio de goo. Mi bonvenas defion el alia Esperantisto.

New Machine

I have a new machine coming my way. I switched off of Linux onto MacOS about two years ago when my office pressured me to switch operating systems, and I also made the decision to continue having only one computer, which means that I have effectively not owned my own machine for a couple of years.

In some ways, this has been really nice. I’ve had access to a library of games that did not used to be available for Linux. But in other ways, it has been hard. As much as I have tried to continue using Nix to keep my environments isolated and to be able to consistently have a known good baseline state for every development environment, in practice some of the tools that we use as a matter of course actually resist such isolation. Yes, I’m glaring at you, Ruby. See about my nixpkgs bug report here. That bug has been resolved, but that, plus the next contract I joined, hammered home that at Cloud City we really do not use tools that lend themselves to isolation, and for work purposes I cannot wait for fixes to Nixpkgs.

I would actually rather just set up a separate VM for each client, but MacOS is very unfriendly towards virtual machines and I was never able to get an installation to actually work.

Time Machine has already had three catastrophic failures this year. While I have not lost data, that is only sheer dumb luck. In the case of this failure, Time Machine’s recovery strategy is to delete the original backup and then start on a new backup, leaving me with multiple days of no backups while the new one is being built. Apple should bloody well be ashamed of themselves for that. Further, when I was using rsnapshot on Linux, the only failure I ever had over the course of years was actually a physical hard drive failure. That is the degree of reliability that I expect.

So, I’m really looking forward to switching back to NixOS.

One of the benefits that I’d forgetten about is that the GTK bindings for Rust are much more complete than the Cocoa bindings, so I can just start on porting Fitnesstrax to a GUI application immediately instead of also taking the time to rewire a widget set. Now that i am well again, I can actually start thinking about resuming development on the project.

The only drawback is that I’ll likely lose access to Aurora HDR, which I have been using for my photography for a few years. This isn’t necessarily terrible, as I did a lot of very good photography before switching to MacOS, but the tools available on Linux are really substandard. I tried to build an HDR application for Linux many years ago, but unfortunately the math was too hard. It is always possible that I will return to that project, as it is as interesting to me as Fitnesstrax, but that is not in my schedule for today. Note that there are HDR processors for Linux, but they are horribly user-unfriendly. The one and only GUI tool exposes a bunch of different tone mappers, but it does so with excessively technical names such as “Debevec”, “Mantiuk”, and “Fattal”. None of the tone mappers can be used together, and the settings have undescriptive names such as “Phi” and “Key Value”. Hence why I wanted to develop my own tool, but it turns out that the core math problem, developing an HDR map from the original sources, was beyond my ability.

Hollow Knight

As I mentioned, I was sick for almost two weeks. Not hospital-level sick, but coughing, low energy, my entire face hurting kind of sick. With the lack of energy, I haven’t studied, written or coded outside of work.

What did I do?

I played a lot of Hollow Knight.

I actually started back at the beginning of the game. This is easily the best game released in the last two years, but it was so hard that I got completely stumped in my last play-through. This time, though, I actually am doing much better. Partly, I am looking at the wiki to make sure that I find important items. Mostly, though, I’ve practiced some of the more… ahem acrobatic techniques, and I’ve learned to spam spells, and that has made some of the bosses, like the second encounter with Hornet, much easier.

Now, I said that the game was be best released in the last few years, and there’s a few reasons why.

The most obvious one is that the action is clear and crisp. Other games, like Salt and Sanctuary, are plenty good, but they are more about tanking than about developing any real skill. Hollow Knight obviously has upgrades that make the game easier, but generally no battle can be won just by tanking, only by developing skill, combining the right techniques and having some good luck. This is very satisfying.

But my real love for the game comes from the very consistent mood through the entire arena. You are exploring a fallen kingdom, one which tried many times to survive, but simply couldn’t. And while the wild areas around it seem to be doing fine, the kingdom itself; through the architecture, color schemes, and music; all speak to a place of sadness, loss, and resignation. I have never before encountered a game that was so consistent in maintaining a mood and theme, and this was done masterfully, with beauty mixed so carefully with nostalgia.

Hence… why I decided to spend my sick time re-playing a game that caused me to nearly throw my controller across the room back in March.


And that’s it for this week. Now that I am well again I should be able to resume posting regularly. I hope you all enjoy reading my ramblings.

Weekly Roundup

Savanni D'Gerinel 29 Sep, 2019
Arches, 2019-09

While normally I post these on Friday, this last week was quite busy and left me no time to write.

And, in fact, I have very little to write about. I had a trip with my partner to New Hope, Pennsylvania. It was, as always, quite lovely, but there is very little to do in New Hope.

I returned to start a job with a new client company, in the company’s office for the first time since starting at Cloud City, and meet for the first time a co-worker with whom I’ve paired for literally hundreds of hours of work.

First day had a rocky start, with me first forgetting my bike lock after getting to Assembly Station, and then watching as one train after another pulls into the station, completely full. Like, people trying to press in so they can clear the doors full. Moral of the story: don’t take the orange line during rush hour. Or, during rush hour there is no reason for people to get off the train at Assembly, and the addition of a parking garage there means that the train just keeps on acquiring passengers until downtown.

This week will again be busy, primarily spending all of the week in the client office, but also with a vet appointment and other random things.

So, yeah, this is a boring update. Hopefully I’ll have more next week, but until then, have fun and do something interesting!

Tech Chaos for September 20th, 2019

Savanni D'Gerinel 20 Sep, 2019
That's No Moon!, 2019-07

TGIF, and welcome back, y’all!

I am currently struggling with some pretty severe mental health issues, so about the only thing I have the energy to do is write today. Worst part of this mental health issue is that it is mostly about anxiety, and fearing the worst in an upcoming event. But I cannot do anything to put the anxiety aside, and I cannot do anything to bring the event on faster so I can find out the results, so… sucks to be me at the moment.

I will try to keep it coherent today.

Fitnesstrax 0.0.3

Over the course of the weekend, I released Fitnesstrax 0.0.3 on my nix channel. Unfortunately, even though I thought I got this squared away last week, the channel actually does not work as a channel. You can instead use the channel by cloning the repository and including it like so:

  ld = import /Users/savanni/src/luminescent-dreams/luminescent-dreams-nixpkgs/nixpkgs/default.nix {};`

This release involves a rather significant overhaul of the edit interface in order to accommodate more workout types.

In order to add Pushups and Situps (part of my regular workout routine), and soon to also add things like Tai Chi that are based solely on the amount of time that I spend practicing, I really needed to look at the user interface for the application. When I started, I was thinking that it would be cool to just have a section for Time/Distance workouts and another section for Set/Rep workouts, and logically another section for Time-only workouts. And this is obviously absurd. People want to add workouts and get a relevant user interface for each.

Much of my efforts over the weekend involved overhauling the interface. Now, each record can be edited separately. Workouts get added from a drop-down menu. Workouts get rendered through dynamic dispatch of what workout type is there. You no longer get “sections” for each major workout category, but just get more of a record for the day.

Really, this should have been obvious from the beginning. But, now it is there and I can store all of my pushup and situp workouts in the app that I have been working on for ages.

An irony to this whole thing is that I want to swap the app out for a native application, and that is going to be a huge task. My goal here is to get all of my workout types into a coherent UI with the minimal amount of effort so that I can then really focus on building a native UI.

A New Machine

Speaking of a native UI (bear with me here), I have finally decided that I need to get a new machine. I strongly, strongly prefer to only have to manage one computer, but as a consultant, it is rather difficult to merge my work computer and my personal computer. I use tools such as Nix and Docker to keep my environments from colliding with one another. Unfortunately, not all of my clients are particularly okay with creating truly isolated environments. Also, I recently did work with Ruby, and there was, at the time, a problem with some of the derivations for Ruby gems in Nix. I had to install Ruby with RVM in order to move forward, and for a bit it looked like I had already irrecoverably corrupted my machine.

So, although my new client will be giving me a dedicated computer to work with, I have decided that I really need to have a personal computer that I can keep very well packaged and clean, a work computer that I can regularly wipe and reinstall, and a client computer when the client has more particular needs. In the third case, my work computer may actually go silent for months while I spend my work hours on the client.

In deciding that I need a new machine, I also decided that I really, really, really want to go back to Linux. This actually means that instead of recoding the Fitnesstrax UI for MacOS, and doing the Rust language binding work for the Cocoa libraries, I am instead going to recode for GTK. In some sense, though, this also makes sense. Apple really has fitness tracking cornered on MacOS, and I sincerely doubt that I would get many users there. By contrast, Linux only has the online services, so I expect to get some early users from privacy-minded demographics.

Specs for the new machine: super lightweight laptop, longest battery life I can manage, 16GB of memory, 1TB SSD. Turns out, this is being really hard to find. I have found a customized machine from Lenovo that fits the bill, but shipping time is something like 4 weeks from now. It looks like I can get a machine from System76, but I will have to research. My past experience is that their laptops are rather bulky and have very poor battery life.

React Hooks

While I was reading onboarding documents for my new client, I noticed that they use React Hooks through their code. I knew nothing about them, but I realized that Fitnesstrax already runs the correct version of React to use them. So, I overhauled one of my components. I am actually very pleased with the result. My stateful components remain stateful, but the useState hook hugely reduces the amount of boilerplate code that I have to set up in order to manage component state!

I am unlikely to do anything more with React Hooks in my open source work for the forseeable future since I intend to switch over to GTK work, but it is a new tool that I recommend that everyone looks at.

Licensing and Pulling Power back from Corporate Interests

I have been using a lot of BSD-3 licensed code for a long time, and I have also been distributing my code under the BSD-3 license. But, corporations love this license. Unlike the GPL, it allows them to make products cheaply without providing any benefit back to the open source developer who put their precious time into the software that their projects depend on. Further, I know that in recent years corporations want to see your Github work as a condition for hiring.

I feel that the situation here is very complicated. I want to be able to work on things that bring benefits to individuals. But it is very unlikely that anyone would actually pay me for my open source work. I am most interested in having software, such as Fitnesstrax and Emseries adopted by as many individual users and open source developers as possible, but I also want corporations to either unambiguously hire me or pay me for my work.

Realistically, nobody but me is currently using any of my work. So, let’s set that aside and simply consider class solidarity. Specifically, solidarity with marginalized tech workers who have difficulty getting employed, do not have the time to put into open source work, or who simply do not want to give their free time away to corporations.

The GPL of course comes to mind, but certain black developers that I follow have started evangelizing the Parity and Prosperity licenses and the License Zero method of licensing software for commercial and closed source use. I am trying to begin conversations with folks about what that really turns into and how that would affect my open source development model. I hope to share more thoughts here as soon as I understand.

Employment

Last topic: employment.

Recruiters come looking for me on a pretty regular basis, but they pretty much ignore that I’ve specifically requested to never be contacted about Python positions. I have over a decade of Python programming experience, and I categorically hate the ecosystem. I also fail to understand why anyone would not want type guarantees at the time that their program starts running. Tell me: why would you want to have to write extra tests to validate that you are always calling functions correctly? Do you really want to find out about these things when they fail in production? Get real, folks.

I have a really damned good job with Cloud City Development. Great co-workers, management that actually does behave in solidarity with the employees, and a variety of jobs. This includes a job that I did over the last two months to accelarate how countries improve their public health policies! I don’t like our tech platform, but the culture really tips the balance wildly in favor of the company.

I even vaguely think that my managers would secretly been pleased if I had gone on climate strike today instead of having a major anxiety breakdown.

So, if any recuriters read this, know that you have an incredible bar to cross to even get a response from me. And at this time, the bar looks like this:

  • Rust, Typescript, Haskell, Nix
  • Linux-first development environment
  • Combating global climate change, building products that safeguard customer privacy rights, or aiding public health.

As a quick hint: if the product must be connected to the cloud, it does not safeguard customer privacy rights. I don’t care how revolutionary you think you are. My data, especially my health and fitness data, should literally never leave my devices.

And that’s it for this week! I hope to make this a regular column, though perhaps I will have to keep it shorter when I am doing focused work.

Setting up a Custom Nix Channel

Savanni D'Gerinel 13 Sep, 2019

Happy Friday the 13th, everyone!

This week has gone extremely well, with me finishing a project for work that will actcually help save lives. Lots of lives. And I for the life of me cannot actually think of any way in which the application can be used to create harm.

At the same time, I’m tuning my tools, and this week, that means my shell.

I’ve been working on switching my shell environment away from being a nix-shell all the time and back to being something more like the config.nix based environment that the Nix maintainers envisioned.

In the midst of this, I decided that it would also be good for me to grab all of the derivations that I’ve been duplicating from one project repository to another, and drop them into a custom nix channel.

I describe all of my development environments in a shell.nix file that I keep with the application that I’m developing. Part of my discpline also involves standardizing on a particular version of my tools, such as Rust-1.33 instead of whatever version of Rust is currently available in the public NixPkgs repository. Until this week, that meant keeping a Rust derivation file in the project repository. That inevitably leadf to me duplicating gthat derivation file (and Node, and other things), across a variety of repositories.

This was probably optional with my work repositories, but the repositories I build for Luminescent Dreams ship with the shell.nix and default.nix, and so have to also ship with the other derivations.

My own custom channel became the obvious solution, but I did not think of it until late last week.

So, while the format is actually very straightforward, I did not find documentation on how to set up the channel repository and for a while did not think of the simplest, most obvious way of finding out the format. So, here I document it all.

You will start out by building a very simple derivation set in a default.nix file:

{ system ? builtins.currentSystem }:
let
  pkgs = import <nixpkgs> { inherit system; };
  self = in self
in rec {
    rust_1_33_0 = pkgs.callPackage ./pkgs/dev/rust-1.33 {
      inherit pkgs;
    };

    nodejs_9_10_0 = pkgs.callPackage ./pkgs/dev/node9.nix {
      inherit pkgs;
    };
    ...
  }

Every element in this set; in this case rust_1_33_0, nodejs_9_10_0, and so forth; will be available in the channel.

Next, make sure you actually define he derivations described here. Errors won’t be detected until somebody who subscribes to the channel actually tries to install something. Obvious errors, like failing to pass a parameter to a derivation, will completely break the channel and are thus easy to find.

Finally, move one directory up from your default.nix, and tar the entire directory:

> ls -l

total <whatever>
drwxr-xr-x 4 savanni staff  128 Sep 12 11:02 nixpkgs

I actually do not know whether the name of the directory matters, but I mimicked the naming convention that I found in the main nixpkgs channels. Tar up the nixpkgs directory, with bz2 compression, to the file nixexprs.tar.bz2:

> tar -cjf nixexprs.tar.bz2 nixpkgs

Finally, upload nixpkgs.tar.bz2 to a public location. This file alone is all it takes to make a channel.

To use the channel, add it to your nix channel list, but be sure to include the exact url. For instance, to get my Luminescent Dreams channel, this is your command:

nix-channel --add http://luminescent-dreams-apps.s3-website-us-west-2.amazonaws.com/nixexprs.tar.bz2 luminescent-dreams

My Channel

I am now running my own custom channel for Luminescent Dreams, in which I distribute both the exact versions of the tools that I use and the software that I develop. As of today, that includes:

  • rust-1.33.0
  • nodejs-9.10.0
  • nodejs-10.15.3
  • ansible-2.7.4
  • certbot-0.19.0
  • packer-1.1.3
  • terraform-0.12.2
  • vault-1.0.1
  • fitnesstrax-0.0.1
  • fitnesstrax-0.0.2

Soon I’ll add orizentic, palimpsest, and digikam-export to the channel.


Dreamer, Shaper, Seeker, Maker