It’s my first year workversary at FireHydrant. It’s been a fun ride: learned a lot, shipped a lot, and made a lot of new friends. I’m glad to be here! I was initially hired to work primarily on Signals, our on-call alerting offering. However, as folks who have worked with me would testify, I would get my hands on anything that is within my reach. And I did! Here are some of the notable things I…
Despite the many programming languages and frameworks I have used, I think Ruby on Rails really nailed it for their database integrations. Specifically, I find it incredibly helpful in development loop to find out the database schema from within my editor by fuzzy-searching db/schema.rb. One step further to that is annotation on the models file, using something like drwl/annotaterb. I miss that…
I use OAuth2 Proxy in my home cluster, which runs NixOS. My update policy for this cluster is, quite literally, best effort when the vibes feel like it I remember to. Recently, a change was introduced upstream in nixos/nixpkgs, where the OAuth2 Proxy integration with Nginx had a regression for my use case of forwarding authorization header as X-User and X-Email. This problem was preventing me…
The project which inspired this post is now live on GitHub! Check it out and let me know what you think: firehydrant/signals-migrator. Terraform end-users are programmers who would write .tf files. As such, if you are one, you would be familiar with a line like so: resource 'aws_vpc' 'team_rocket' { cidr_block = '10.0.0.0/16' } Within the ecosystem, Terraform also has custom providers. Some…
The project which inspired this post is now live on GitHub! Check it out and let me know what you think: firehydrant/signals-migrator. In a recent project, I was working on a command line application with tricky data manipulation scenario. Imagine if you were moving members from mailing lists (e.g. Google Groups) to group chat service (e.g. Slack), where the goal is for members of the mailing list…
With Go modules being de facto dependency manager for a while now, we can use its feature to define versions of tools which are not directly imported as libraries in our source code. The bite-sized tips below are sorted from official recommendations to personal opinions. The baseline ¶ Go modules documentation to this day still recommends one approach using tools.go. In short, create a tools.go…
Hi there! I’m Wilson, a software developer with side quests on cooking, coffee, and bicycles in San Francisco Bay Area. These days, I mostly write Go, some CSS, and a little bit of JavaScript when necessary. I also write Ruby occasionally, as a treat. I like to talk about Linux, containers, declarative infrastructure, and the human components of a system. This site was built with Hugo. Styling was…
Hi, I’m Wilson, a software developer at NVIDIA based in San Francisco Bay Area, California. I really like to make things go fast ⚡️ Existence of this page does not imply job search status. It is left up for reference on what it’s like to work with me! My focus is on building developer experience and reliable infrastructure. You may find my work to be incredibly useful if you are…
I find this pretty cool and useful when working on a remote instance through SSH and need to check what an image looks like. Check it out yourself: hzeller/timg.
Starting Go 1.18, the function ReadBuildInfo from runtime/debug can be used to retrieve the build information of the current program, including version control revision. bi, ok := debug.ReadBuildInfo() if !ok { panic('cannot retrieve buildinfo. is go go-ing?') } for _, i := range bi.Settings { if i.Key == 'vcs.revision'{ fmt.Println(i.Value) } } Why? ¶ Providing the exact commit revision to…
Recently I found myself wanting to use a Python program in Nix, where the program itself manages its dependencies with Poetry. It’s a small and not actively maintained project, thus I would have to package it myself in Nix. I’m simulating the hurdles I had to go through using a simple project for this exercise. Source code for Python program can be found in wilsonehusin/hello-poetry2nix, while…
AirTags use CR2023 batteries and some manufacturers put on bitterant to prevent children nibbling on it. This bitterant is usually nothing significant to electronics, but apparently enough to prevent contact for AirTags. The outlined gray-ish on the back (left) is the bitterant mentioned earlier. Rub isopropyl alcohol using cotton swab until it fades away (right), then try again. A successful…
All groups which exists in Linux can be found in /etc/group. $ cat /etc/group root:x:0: wheel:x:1:wilson kmem:x:2: tty:x:3: messagebus:x:4: disk:x:6: audio:x:17: ... nogroup:x:65534: To list the groups of which current user is member of, use groups command. $ groups users wheel networkmanager podman
Have you ever noticed that ls sometimes provides relative path, while other times uses full path? $ ls ~/.config/nixpkgs config.nix $ ls ~/.config/nixpkgs/* # append wildcard suffix /home/wilson/.config/nixpkgs/config.nix The program ls actually is unaware of the trailing * because the current shell expanded the operator then passed the list of files. From the perspective of ls, the two commands…
Everything is a file in Linux, including information about processes. Environment variables of a given process are also stored in a file: /proc/[pid]/environ. However, it’s not really readable. $ sudo cat /proc/1527/environ…
Apparently the two mean different things. From Arch Linux Wiki: Suspend to RAM (aka suspend, aka sleep) The S3 sleeping state as defined by ACPI. Works by cutting off power to most parts of the machine aside from the RAM, which is required to restore the machine’s state. Because of the large power savings, it is advisable for laptops to automatically enter this mode when the computer is…
Sometimes, I feel like life and creative work is similar to open world games: a lot of side quests may show up when you least expect them. I have been doing a lot of exploratory projects lately around NixOS and homelab. In that development flow, my “enterprise software developer” brain often finds forks on the thought path. 💡 Oh this could be a neat separate project! –Me I used to be able…
Having Kubernetes as a platform to deploy applications was a convenient escape hatch from managing my home server without having to understand Nix too much. However, having learned more about Nix in the recent weeks, I am increasingly convinced that I would rather have Nix services with Nginx as reverse proxy. Some familiar Kubernetes feature substitutes in NixOS: Ingress: NixOS has…
Technical documents often include outputs of shell script. For a while, I have been using the same language code shell for shell output, which usually returns incorrect syntax highlighting. The wrongness varies from parser-to-parser. $ echo 'this is not perfect' 'this is not perfect' Turns out, codeblocks for shell-session is a thing! $ echo 'this is more accurate!' 'this is more accurate!'
I figured it is time to consolidate my random notes which are scattered all over the place. Honestly, it has been time for a while. My previous attempts include Apple Notes, Obsidian, and most recently HedgeDoc. There are many things to like about each, but none of them managed to capture critical mass of merit points to be the only medium for all my notes. After trying out several options, I…
Equivalent (or subset) of systemd in Linux, but for Mac. Configured with .plist file in XML format. Specification can be found in the manual page: $ man launchd.plist Apple’s support page points to the following directories for configurations: Folder Usage /System/Library/LaunchDaemons Apple-supplied system daemons /System/Library/LaunchAgents Apple-supplied agents that apply to all users on a…
While there are blessed paths to build containers with Nix tooling, Nix comes with store paths which we can take advantage of in building containers. For the record, I never claim this to be a good idea. Crash course on Nix purity ¶ If you’re already familiar with Nix, feel free to skip this section and jump to containers. Nix purists like to describe Nix’s trait as “pure”.…
My home cluster has Tailscale running on the node while Kubernetes Ingress only listens to the Tailscale IP. In other words, services which I have deployed on my home cluster are only accessible through my Tailnet. Tailnet is a private network for the given Tailscale account. Devices within the same tailnet can reach each other “as if they are within the same network”. Like a LAN…
From the Linux man page: pkexec allows an authorized user to execute PROGRAM as another user. If username is not specified, then the program will be executed as the administrative super user, root. When running uninstall on my Steam Deck via sudo pacman -Rs [program] (see Arch Linux wiki for reference), I somehow uninstalled sudo. As non-root user, I need root privileges to reinstall sudo via sudo…
import { writable } from 'svelte/store'; const key = 'myKey'; const defaultValue = 'myDefaultValue'; // Fetch value from storage, if any. Otherwise, use defaultValue. const initialValue = localStorage.getItem(key) || defaultValue; // Initialize writable instance with initial value. const store = writable(initialValue); // If the stored value changes, make sure to update localStorage too.…
Earlier this year, I converted an existing gaming computer into a small homelab cluster to be a personal server. I consider this journey to be a quest on incorporating better quality software in organizing my digital archives. In some ways, I find the ability to easily justify this decision as a perk of being a software engineer by trade, especially when complemented with battle scars from…
Try it out! If you are more interested to have fun with the subject immediately, then let some fun be had. For more story on how things got here, read on! We are almost hitting the 3,000 minutes limit and we still have a week left. I saw this message on day job’s Slack workspace, which bothered me enough to investigate. I had set up our development team to use GitHub Actions as I have grown…
Despite having a traditional background1 to the software industry, there are things I still had to learn on the job. Sure, everyone had to learn about non-technical bits, like running effective 1:1 meetings or politely nagging a review from your coworker. However, the technical side also had surprises in store for me. Case studies ¶ Specifically in this post, I’m writing about scenarios…