Emacs, tramp, and Guix

I’ve been experimenting with Guix on an unused Intel NUC that’s been collecting dust in my office. The Iinstallation process was easy but remotely accessing the host has been a problem. ssh-ing to the host works fine but I can’t open remote files over ssh via tramp in Emacs. Every time I try Emacs complains Can't find proper ls and refuses to open the file. Argh.


tl;dr Add (add-to-list 'tramp-remote-path 'tramp-own-remote-path) to your Emacs config if tramp can’t find ls on a Guix-based host.


Keep reading if you’re curious about the process I used to debug my config.

First, I tried to manually reproduce how I thought tramp was interacting with the NUC: ssh user@guix_host "ls /". No joy, just a listing of the root directory.

Is tramp using a restricted shell? I repeat the same test running ls inside of another /bin/sh instance like so: ssh user@guix_host "sh -c -r \"ls /\"". It works. Drat!

Next, I enabled verbose tramp logging by setting tramp-verbose to 11 and tried opening a remote file again. Afaik this is the only way to see the low level back and forth between tramp and a remote host. WARNING: This will produce a lot of output and most of it you won’t need. Searching for any occurence of ls I discovered tramp was raising an exception in tramp-get-ls-command.

Aha!

I freshened my local clone of Emacs – I’m using a custom build off the emacs-29 branch – and started looking through tramp’s source for the function’s definition. Some grepping led me to lisp/net/tramp-sh.el. Tramp uses a list of paths stored in tramp-remote-path to locate commands on a remote host. Let’s try (add-to-list 'tramp-remote-path "/run/current-system/profile/bin").

Same error. Digging more deeply into how tramp constructs remote paths I discover tramp-own-remote-path:

Another way to find the remote path is to use the path assigned to the remote user by the remote host. TRAMP does not normally retain this remote path after login. However, tramp-own-remote-path preserves the path value, which can be used to update tramp-remote-path.

This sounds promising.

I know Guix uses shell profiles to set up user search paths. Tramp’s default behavior would be to discard those paths which could account for the error. Following the docs I add (add-to-list 'tramp-remote-path 'tramp-own-remote-path), restart Emacs, and try again. It works!

It’s been a minute

The last few months have been rough. I was laid off in mid-January in what turned out to be the first of many tech layoffs. Dealing with that news was difficult at first but I’ve gradually come to terms with my current predicament. At this point I’ve sent out 100s of resumes and had genuine interest from a handful of potential employers. I’ve come close to actual offers 3 times but no joy as of yet. The cluelessness demonstrated by companies and recruiters has been frustrating and disappointing. Reminds me a bit of the dotcom bust in the early 2000s. I have a bunch of notes on my experiences as a candidate I intend to publish here soon.

In addition to my ongoing job hunt I’ve also been processing my father’s death. He passed away late last summer after a long illness. I’m grateful for the time I was able to spend with him, especially towards the end. I’m also grateful that I had several years to try to prepare myself. It turns out you can never be fully prepared for a major loss but any preparation is better than none. I can’t begin to imagine the difficulty of losing a loved one or close friend suddenly. My heart goes out to anyone forced to deal with so much grief with practically no warning.

I’ve spent a lot of time writing. I always enjoyed writing and wished I’d had more time for it. Well, at least until now. I’ve been working on a fiction book set in the present day southeastern United States. It explores family bonds, the power of love and hate, and letting go of the past. It’s an idea I’ve played with for a couple of years and I’m excited to spend significant time on it. I’ve written six, soon to be seven, chapters and probably have that many more to go. I’m not sure what I’ll do with it once I’m done. Serialize it here? Self publish? Something else? For now, I’m going to just enjoy the creative process.

I have another idea for a short non-fiction book aimed at new technical managers. The gist of it can be roughly summarized as “how to not suck as a technical manager during your first year”. I want to help new technical leaders skip several painful lessons and hard truths every new manager seems destined to rediscover and conquer on their own. I want it to be the book I wish had existed when I first started leading a team with relatively little support from my boss.

There are two hands-on projects I’d also like to focus on lest ye think I’m getting too far away from my nerdy roots. The first is Dagger. I think it has an interesting approach to describing and orchestrating workflows. Major kudos to Metaflow and the community behind it for blazing the trail and demonstrating what’s possible.

The second is documenting my adventures with Guix. The guarantees which come with systems like Nix and Guix are really appealing to me. A couple of years ago I gave Nix a try but felt like I was always either fighting with the packaging language or searching the web for solutions to basic problems. I’ve heard Nix’s docs are much better now as is the dev experience but my inner Scheme fanboy leans in favor of Guix. I find the system to be more comprehensible compared to Nix even though I’ve spent roughly the same amount of time with both (~2 weeks as of today). I’ve found the System Crafters GitHub org and YouTube channel to be excellent resources on Guix and Emacs.

Thanks if you’ve made it to the end. I have more posts planned soon so stay tuned! Oh, and if you know anyone looking for a seasoned technical manager specializing in backend systems please drop me a line.