Skip to content

Instantly share code, notes, and snippets.

View julianlam's full-sized avatar
🤔
I may be slow to respond.

Julian Lam julianlam

🤔
I may be slow to respond.
View GitHub Profile
@julianlam
julianlam / tp-link-ac600-ac1300-drivers-linux.md
Last active April 16, 2024 02:13
Installing drivers for the TP-Link T2U/T3U Plus (AC600 or AC1300) Wireless Adapter #blog
@julianlam
julianlam / expose-directory-on-host-to-lxc-container.md
Last active April 7, 2024 04:01
Exposing a directory on the host machine to an LXC container #blog

Exposing a directory on the host machine to an LXC container

  1. Log into the container and create an empty directory, this will be the mount point
  2. Log out and stop the container.
  3. Open to your container's config file
    • For regular LXC containers: /var/lib/lxc/mycontainer/config
    • For unprivileged LXC containers: $HOME/.local/share/lxc/mycontainer/config
  4. Add a new line above the lxc.mount directive, that follows the format below. Substitute proper paths as necessary:
    • lxc.mount.entry = /path/to/folder/on/host /path/to/mount/point none bind 0 0
  • Both of these paths are relative to the host machine.
@julianlam
julianlam / laptop-s2idle-to-deep.md
Last active January 2, 2024 17:00
Changing laptop suspend from s2idle to deep sleep #blog

One thing I noticed ever since I bought my second Dell XPS was that the battery life was relatively abysmal when the laptop was asleep. I'd suspend my laptop at work, bring the laptop home, and the next morning I'd be down 25-50% of my battery life! More than once, I'd leave my laptop for a couple days and come back to a completely dead laptop1.

My first inclination was that the laptop was waking up on its own. It does happen occasionally with Linux (which, in an of itself, is pretty concerning2), but in this case, I was reasonably certain it wasn't the case, as evidenced by the battery drop overnight when waking a still-sleeping laptop.

While there are a plethora of articles online about sleep/standby (suspend to RAM) and hibernate (suspend to disk), the root cause was that some hardware configurations support three different modes of sleep: s2idle, shallow, and deep.

According to the [Linux Kernel documentation](https://www.kernel.org/doc/html/v4.15/admin-guide/pm/sleep-states

@julianlam
julianlam / dmm-ceros-locksafe-review.md
Last active October 10, 2023 14:59
DMM Ceros Locksafe; A Review #blog

Product photo of the DMM Ceros Locksafe Carabiner

Soon after field testing the Mammut Smart 2.0, I became acutely aware that the carabiner I had paired with the device — the Metolius Element II — was sub-optimal:

  1. The I-shaped stock in the basket end meant that there was less surface area in contact with the rope, and brake effectiveness was reduced.
  2. Lack of anti-crossloading features meant that the carabiner sometimes flipped/rotated during usage.

The two features I needed for it to pair nicely with the Smart:

  1. Round stock at the HMS end
@julianlam
julianlam / test-driving-mammut-smart-2.md
Last active October 9, 2023 01:07
Test driving the Mammut Smart 2.0; A Review #blog

The Mammut Smart Belay Device

Having been climbing more seriously for the last 6 years, my exposure to belay devices has been restricted to that which my local gym allows — that is — the Grigri.

Since its introduction in 1992, the Grigri has become a ubiquitous item at climbing gyms and crags. As an assisted belay device, it offers unparalleled performance and positions itself as a solid alternative to older belay plates and tubes.

When I discovered that there were other products on the market that offered similar benefits to the Grigri, I jumped at the chance to test-drive them. My search brought me to two popular contenders, the Black Diamond ATC Pilot, and the Mammut Smart 2.0.

I later purchased a Smart from my local retailer and finally had the opportunity to put it to use today. The following is a brief usage review including some pros, cons, and surprises. T

@julianlam
julianlam / provisioning-unprivileged-lxc-containers-via-login-or-script.md
Last active September 7, 2023 12:45
Provisioning and usage of unprivileged LXC containers via indirect login or script #blog

Provisioning and usage of unprivileged LXC containers via indirect login or script

As I've discovered, managing LXC containers is fairly straightforward, but when building out a system for provisioning out user maintained instances of NodeBB, it was imperative that unprivileged LXC containers were used, so that in the event of shell breakout from NodeBB followed by privilege escalation of the saas user, the root user in the LXC container would only be an unprivileged user on the host machine.

During the course of development, I ran into numerous blockers when it came to managing LXC containers in unexpected circumstances. Namely:

  • Using LXC in a subshell is not directly supported. This usually happens under one of the following two circumstances:
    • After switching users via su or executing lxc-* commands as another user via sudo
    • Executing lxc-* commands via a program, application, or script. In my case, a Node.js application.
@julianlam
julianlam / html-string-into-dom.md
Created August 15, 2023 15:47
Inserting an HTML string to the DOM #blog

Question: How do you insert an HTML string (e.g. <p>this is a paragraph <a href="#">with an anchor!</a></p>) into the DOM?

It's easy with jQuery, $(htmlString). But what if you don't want to use jQuery? It's also pretty straightforward.

const container = document.getElementById('container');
let html = '<p>this is a paragraph <a href="#">with an anchor!</a></p>';
html = new DOMParser().parseFromString(html, 'text/html').body.childNodes;

container.append(...html);
@julianlam
julianlam / nodejs-trust-caddy-certificate-authority.md
Last active July 12, 2023 18:06
How to have Node.js trust Caddy self-signed certificate #blog

Caddy has a neat feature where all routes automatically come with HTTPS enabled. Caddy achieves this by self-signing its own certificate via a certificate authority that is (or can be) added to the system CA list.

However, Node.js comes bundled with its own certificate authority list, so even if Caddy's CA is added to the system, Node won't allow it.

Here's how to allow calls to local https services served by Caddy:

  1. If needed, run caddy trust as root to install the Root CA.
  2. Run node with the environment variable NODE_EXTRA_CA_CERTS and point it to the local CA file.
    • Not sure what that is? Maybe you're on Debian or a derivative (e.g. Ubuntu, Pop!_OS, etc.): NODE_EXTRA_CA_CERTS=/etc/ssl/certs/ca-certificates.crt
@julianlam
julianlam / lactation-energy-bites.md
Last active June 11, 2023 22:08
No-Bake Lactation/Energy Bites #blog

My wife found this recipe for energy bites that contain galactagogues — milk-promoting foods and herbs that could aid in building milk supply.

They also double as a really tasty (and energy-rich) snack for days when you just want something quick!

I had this recipe written down in my notebook, but I refer to it often enough I may as well put it up here as well. It also contains measurements for the tackier liquid ingredients in GRAMS, because measuring larger volumes of things like peanut butter and honey by volume don't make much sense due to variability.


Ingredients

@julianlam
julianlam / freshtomato-on-asus-routers.md
Last active February 5, 2023 06:27
Installing FreshTomato on an ASUS router using Linux #blog

I recently replaced my Ubiquiti AirCube-AC because I missed the sheer configurability of Tomato. It's been years since I used a router with this installed, but Ubiquiti's UI for the AirCube is fairly hobbled as it is a fairly new product, and as it is meant to be a "set it and forget it" device used more commonly by WISPs in rural areas (among other use cases).

After some light web research I discovered that Tomato by Shibby, a popular fork of the Tomato firmware, had been discontinued, and that he was now advocating FreshTomato, so after a quick donation to thank him for his work, I downloaded the appropriate build of FreshTomato for my router.

My first attempt was simply using the firmware update tool in the router interface, which failed spectacularly1. Some more light web research revealed that this was no longer an allowed way to upload a custom firmware.

So the