ballpointcarrot dot netZola2023-10-31T00:00:00+00:00https://www.ballpointcarrot.net/atom.xmlDusting off the Cobwebs2023-09-26T00:00:00+00:002023-09-26T00:00:00+00:00Unknownhttps://www.ballpointcarrot.net/posts/dusting-off-the-cobwebs/<p>I've been meaning to come back to this space and give it the standard periodic cleaning (as <a href="/posts/im-still-here">has been done</a> in <a href="/posts/well-i-shouldve-been">the past</a> a <a href="/posts/yearly-refresh-time">couple of times</a>).</p>
<h2 id="what-s-changed">What's changed?</h2>
<p>Since the last post in 2021 (which I'm super proud of, it was the
best-performing post I've had), I've helped raise a kid to 2 years old (he was
1 month old when that last post landed), changed jobs (went through a layoff,
and found new employment elsewhere); my primary social media platform was
purchased by a person with more money and ego than sense, and has turned it
into a cesspool of fascist propaganda and hate speech; and the world has
continued dealing with the continuing COVID
pandemic. </p>
<h2 id="no-i-mean-what-s-changed-on-the-site">No, I mean what's changed on the <em>site</em>?</h2>
<p>Oh, right.</p>
<p>Well, the very obvious one is there's a new style and theme attached. Gone is
the smooth lines and colorful graphics, and now we have a simple text-forward
site. <em>This is by choice.</em> I've stumbled down a rabbit hole of blog posts
containing concerns that "web pages are too large", and some <a href="https://www.reddit.com/r/webdev/comments/mkewwn/this_motherfucking_website_no_seriously_a_must/gtfjtrt/">satirical and
expletive-laden</a>
examples to the contrary.</p>
<p>The overall sense that I got from the above is that, the less amount of
unnecessary data being requested by your users, the better. So, the
simplification of this site tracks with that goal. We have a simple font
selection set (which will render mostly the same); the colors are inspired by
the Catppuccin color theme (which I'm using all over my tools, it's seriously
great), and I've tried to limit image usage to only the necessary places.</p>
<h2 id="what-s-next">What's next?</h2>
<p>Being a parent sucks a lot of the free time away from tinkering, so likely not
a ton. That said, I've admired what <a href="https://werd.io">Ben Werdmuller</a> does, and
I've been a fan of the Indieweb movement in general, so I'll likely do some work to
enable more of this site to use Indieweb-related functionality. I think I've
taken a bit of a step back with this recent change, and so I'll do some cleanup
in the near term to get be back to some level of microformats usage (right now,
I'm just wanting to get the style change out the door, and I'll iterate on that
in later days).</p>
<p>And hey, <a href="/tags/advent-of-code">Advent of Code</a> comes back here in December, so I'll maybe have some
things to write there. Gonna have a think on which language to use...</p>
/uses/2023-09-26T00:00:00+00:002023-10-31T00:00:00+00:00Unknownhttps://www.ballpointcarrot.net/uses/<p>This is a "uses" page, which details what I use on a daily basis in my work as
a developer and general computing nerd, as well as other tools, utilities and
resources that I find handy and wish to share with others. The concept was
popularized by <a href="https://uses.tech">uses.tech</a>.</p>
<p>I try to keep this list current. In order to keep myself honest, I'll display the last updated date here, so I can be
publicly ridiculed when I get out of date.</p>
<blockquote>
<p>Last updated: Tuesday, 31 October 2023
</p>
</blockquote>
<h2 id="hardware">Hardware</h2>
<table><thead><tr><th>Class</th><th>Thing</th><th>Used for</th></tr></thead><tbody>
<tr><td>Personal Laptop</td><td>Lenovo Thinkpad T14s Gen 2</td><td>Code, Web browsing, Primary "Compute" system</td></tr>
<tr><td>Other laptop</td><td>Macbook Pro M1</td><td>Was laid off, but company let me keep it. Now a media device mostly.</td></tr>
<tr><td>Desktop</td><td>Custom built, AMD Ryzen 3800x</td><td>Gaming Home Theater PC</td></tr>
<tr><td>Mobile</td><td>OnePlus 11 5G (CPH2451)</td><td>Doomscrolling and wasting time</td></tr>
<tr><td>Keyboard</td><td><a href="https://www.keychron.com/pages/keychron-q8-customizable-mechanical-keyboard">Keychron Q8 Alice</a> with <a href="https://www.amazon.com/gp/product/B0BHWK8CHW/">MELETRIX WS Grey</a> switches.</td><td>A <strong>lot</strong> of typing.</td></tr>
<tr><td>Over-the-ear Headphones</td><td>Audio-Technica ATH-M50x</td><td>Conference calls, Music listening</td></tr>
<tr><td>In-ear Headphones</td><td>Moondrop Kato</td><td>"sit and listen" music sessions</td></tr>
<tr><td>Audio Amplifier</td><td>HIBY FC4</td><td>Used mostly with the IEMs, "sit and listen" music</td></tr>
</tbody></table>
<h2 id="software">Software</h2>
<table><thead><tr><th>Class</th><th>Tool of Choice</th><th>Notes</th></tr></thead><tbody>
<tr><td>Personal Laptop OS</td><td><a href="https://endeavouros.com">EndeavourOS</a></td><td>Love the Arch ecosystem, but not the install process.</td></tr>
<tr><td>Display Manager</td><td><a href="https://www.kde.org">KDE</a></td><td>Miss using a tiling WM, but also happy to have creature comforts baked in.</td></tr>
<tr><td>Text Editor</td><td><a href="https://neovim.io">NeoVim</a></td><td>Making heavy use of the <a href="https://www.lazyvim.org">LazyVim</a> starter. I can never solidly decide between vim and emacs.</td></tr>
<tr><td>Web Browser</td><td><a href="https://vivaldi.com">Vivaldi</a></td><td>Love having tree-view tabs on the left side of the screen.</td></tr>
<tr><td><a href="https://en.wikipedia.org/wiki/Shell_%28computing%29">Shell</a></td><td><a href="https://fishshell.com">fish</a></td><td>Decorated with <a href="https://starship.rs">Starship</a>. Was a long-time ZSH user, but the auto-complete of fish tempted me.</td></tr>
<tr><td>Notes</td><td><a href="https://logseq.com">LogSeq</a></td><td>Started putting my notes here, Syncing between my devices with <a href="https://syncthing.net">Syncthing</a>.</td></tr>
</tbody></table>
Running Rust on AWS Lambda on ARM642021-10-06T00:00:00+00:002021-10-06T00:00:00+00:00Unknownhttps://www.ballpointcarrot.net/posts/rust-arm-lambdas/<blockquote>
<p>TL;DR: Rust on ARM64 Lambda: check out <a href="https://github.com/ballpointcarrot/lambda-rust-arm64">my example repo</a></p>
</blockquote>
<p>I've been a hobbyist Rust developer for a while now, playing with random tools and mostly having false starts on projects that I'd like to build, but then the energy to do so wanes before I can complete them. Because of that, I always look for new applications for Rust to fit somewhere in my day-to-day, so that I can give myself some practice.</p>
<p>I also work very closely with AWS Serverless tooling in my daily work at <a href="https://stedi.com">Stedi</a>. Recently, AWS posted an update to the Lambda service that they were providing <a href="https://aws.amazon.com/about-aws/whats-new/2021/09/better-price-performance-aws-lambda-functions-aws-graviton2-processor/">Graviton2-based Lambda functions</a> as part of the service, and I immediately thought to myself, "How would I do a Rust lambda that way?"</p>
<p>Lambda gives you the ability to create a <a href="https://docs.aws.amazon.com/lambda/latest/dg/runtimes-custom.html">"Custom" runtime</a> - all you need to do is provide a executable that acts as a bootstrap for running the function (aptly named "bootstrap" in the runtime code). By building that as a rust binary with the correct architecture, we can run Rust code natively on the Lambda!</p>
<h1 id="project-setup">Project Setup</h1>
<p>I started with a vanilla cargo project, and added the following into the cargo.toml:</p>
<pre data-lang="toml" style="background-color:#24273a;color:#cad3f5;" class="language-toml "><code class="language-toml" data-lang="toml"><span>[[bin]]
</span><span>name = </span><span style="color:#a6da95;">"bootstrap"
</span><span>path = </span><span style="color:#a6da95;">"src/main.rs"
</span><span>
</span><span>[dependencies]
</span><span>lambda_runtime = </span><span style="color:#a6da95;">"^0.4"
</span><span>tokio = </span><span style="color:#a6da95;">"^1"
</span><span>serde = { version = </span><span style="color:#a6da95;">"^1"</span><span>, features = [</span><span style="color:#a6da95;">"derive"</span><span>] }
</span><span>serde_json = </span><span style="color:#a6da95;">"^1"
</span></code></pre>
<p>The <code>[[bin]]</code> section allows us to specify the binary filename for what's built (and saves us renaming the file after compilation). The dependencies are all references and dependencies of <a href="https://github.com/awslabs/aws-lambda-rust-runtime">the AWS Rust runtime crates</a> - that's where the code for the function we'll be using is pulled from.</p>
<p>we just have one file in the source directory, at <code>src/main.rs</code>:</p>
<pre data-lang="rust" style="background-color:#24273a;color:#cad3f5;" class="language-rust "><code class="language-rust" data-lang="rust"><span style="color:#c6a0f6;">use </span><span>lambda_runtime::{handler_fn, Context, Error};
</span><span style="color:#c6a0f6;">use </span><span>serde_json::{json, Value};
</span><span>
</span><span>#[tokio::main]
</span><span>async </span><span style="font-style:italic;color:#91d7e3;">fn </span><span style="color:#8aadf4;">main</span><span>() -> </span><span style="font-style:italic;color:#eed49f;">Result</span><span><(), Error> {
</span><span> </span><span style="font-style:italic;color:#91d7e3;">let</span><span> funct </span><span style="color:#c6a0f6;">= </span><span style="color:#8aadf4;">handler_fn</span><span>(func);
</span><span> lambda_runtime::run(funct).await</span><span style="color:#c6a0f6;">?</span><span>;
</span><span> </span><span style="font-style:italic;color:#eed49f;">Ok</span><span>(())
</span><span>}
</span><span>
</span><span>async </span><span style="font-style:italic;color:#91d7e3;">fn </span><span style="color:#8aadf4;">func</span><span>(</span><span style="font-style:italic;color:#ee99a0;">event</span><span>: Value, </span><span style="color:#c6a0f6;">_</span><span>: Context) -> </span><span style="font-style:italic;color:#eed49f;">Result</span><span><Value, Error> {
</span><span> </span><span style="font-style:italic;color:#91d7e3;">let</span><span> first_name </span><span style="color:#c6a0f6;">=</span><span> event[</span><span style="color:#a6da95;">"firstName"</span><span>].</span><span style="color:#8aadf4;">as_str</span><span>().</span><span style="color:#8aadf4;">unwrap_or</span><span>(</span><span style="color:#a6da95;">"world"</span><span>);
</span><span> </span><span style="font-style:italic;color:#eed49f;">Ok</span><span>(json!({</span><span style="color:#a6da95;">"message"</span><span>: format!(</span><span style="color:#a6da95;">"Hello, </span><span style="color:#f5a97f;">{}</span><span style="color:#a6da95;">!"</span><span>, first_name)}))
</span><span>}
</span></code></pre>
<p>For those less savvy with Rust code, this defines the 'bootstrap' runtime under <code>main()</code>, and calls the async function <code>func()</code> to act as the lambda function body. Our function responds with a message of "Hello, World!" in a JSON response by default, or can respond with a specific greeting when passed a "firstName" JSON value as part of its input.</p>
<p>Now, you could build this locally, but because of the way that the lambda function is called, local runs will panic:</p>
<pre style="background-color:#24273a;color:#cad3f5;"><code><span>± cargo run
</span><span> Finished dev [unoptimized + debuginfo] target(s) in 0.39s
</span><span> Running `target/debug/bootstrap`
</span><span>thread 'main' panicked at 'Missing AWS_LAMBDA_RUNTIME_API env var: NotPresent', /home/ckruse/.asdf/installs/rust/stable/registry/src/github.com-1ecc6299db9ec823/lambda_runtime-0.4.1/src/lib.rs:57:58
</span></code></pre>
<p>The immediate goal here is to run it in lambda, and not locally, so we'll save testing it out on our own for a later time.</p>
<h2 id="cross-compiling">Cross-Compiling</h2>
<p>The example that is provided in the AWS Rust runtime repository shows them using a <a href="https://github.com/awslabs/aws-lambda-rust-runtime#aws-cli">custom linker and rustup target</a> in order to cross-compile for x86-based lambdas. I attempted to dive into how to get a arm64-based linker, but in the process of trying to figure out how to get that linker installed locally (no convenient packages for Ubuntu, sorry), I stumbled across a project that provides cross-compilation tooling for various platforms via Docker. That made my life a lot easier - Using the <a href="https://github.com/messense/rust-musl-cross">rust-musl-cross</a> Docker container, all I have to do is wrap the call to <code>cargo build</code>, and it builds for the proper architecture:</p>
<pre data-lang="sh" style="background-color:#24273a;color:#cad3f5;" class="language-sh "><code class="language-sh" data-lang="sh"><span style="color:#6e738d;">#!/bin/sh
</span><span>
</span><span>build_arch</span><span style="color:#c6a0f6;">=</span><span style="color:#a6da95;">aarch64-musl
</span><span>
</span><span>docker run</span><span style="font-style:italic;color:#ee99a0;"> --rm -it -v </span><span style="color:#a6da95;">"$(pwd)"</span><span>:/home/rust/src messense/rust-musl-cross:$build_arch $@
</span></code></pre>
<p>Armed with that (pardon the pun), I can now call <code>./musl-build cargo build --release</code>, and I get a resulting binary at <code>target/aarch64-unknown-linux-musl/release/bootstrap</code>.</p>
<p>The final step, as called out in the AWS Rust runtime docs, is to bundle that executable up in a Zip file, so that the Lambda service can construct what it needs to on its side. I've made the <code>package.sh</code> file in the repo to handle that and act as a basic build script (I'll probably convert this to a Makefile later when feeling energetic):</p>
<pre data-lang="sh" style="background-color:#24273a;color:#cad3f5;" class="language-sh "><code class="language-sh" data-lang="sh"><span style="color:#6e738d;">#!/bin/sh
</span><span>
</span><span>mkdir</span><span style="font-style:italic;color:#ee99a0;"> -p</span><span> dist
</span><span>
</span><span style="color:#c6a0f6;">if </span><span style="color:#8aadf4;">[ </span><span style="color:#c6a0f6;">! </span><span style="font-style:italic;color:#ee99a0;">-d</span><span> target/aarch64-unknown-linux-musl </span><span style="color:#8aadf4;">]</span><span style="color:#c6a0f6;">; then
</span><span> ./musl-build cargo build</span><span style="font-style:italic;color:#ee99a0;"> --release
</span><span style="color:#c6a0f6;">fi
</span><span>
</span><span style="color:#6e738d;"># TODO: use vars for arch folder and binary name
</span><span>cp target/aarch64-unknown-linux-musl/release/bootstrap dist/
</span><span style="color:#8aadf4;">cd</span><span> dist </span><span style="color:#c6a0f6;">&& </span><span>zip package.zip bootstrap </span><span style="color:#c6a0f6;">&& </span><span style="color:#8aadf4;">cd</span><span> ..
</span></code></pre>
<p>Now, after running that command, I can grab the file at <code>dist/package.zip</code> and go take that to AWS Lambda to run:</p>
<p>With no arguments provided:</p>
<p><img src="https://www.ballpointcarrot.net/posts/rust-arm-lambdas/./rust-arm-lambda-default.png" alt="Rust Lambda without name" /></p>
<p>With a name provided:</p>
<pre data-lang="json" style="background-color:#24273a;color:#cad3f5;" class="language-json "><code class="language-json" data-lang="json"><span>{
</span><span> </span><span style="color:#a6da95;">"firstName"</span><span>: </span><span style="color:#a6da95;">"Christopher"
</span><span>}
</span></code></pre>
<p><img src="https://www.ballpointcarrot.net/posts/rust-arm-lambdas/./rust-arm-lambda-name.png" alt="Rust Lambda with firstName" /></p>
<h1 id="conclusion">Conclusion</h1>
<p>I hope you can use this to make a running start building out lambda function code on the new Graviton2-based Lambda runners. Let me know if this helped you out!</p>
Daily: 2019-07-012019-07-01T00:00:00+00:002019-07-01T00:00:00+00:00Unknownhttps://www.ballpointcarrot.net/dailies/2019-07-01/<p>Running through updates in various places, and realized for something meant to be "daily", I haven't updated for a while.</p>
<p>May have to reduce the friction of updating here. Could be a fun project on its own.</p>
Finding my Loaf of Bread2019-05-07T00:00:00+00:002019-05-07T00:00:00+00:00Unknownhttps://www.ballpointcarrot.net/posts/finding-my-loaf-of-bread/<p>I made my first loaf of bread last Saturday.</p>
<p>I've been watching a lot of <a href="https://thegreatbritishbakeoff.co.uk/">"The Great British Bakeoff"</a> (or "Baking Show" if you're in the US, because of <a href="http://www.pbs.org/publiceditor/blogs/pbs-public-editor/whats-in-a-name/">trademark reasons</a>). Watching people on your television make intricate, creative, and most importantly <em>delicious-looking</em> baked goods, the desire to try it yourself becomes irresistable. Both my wife and I have tried some things we've seen on the show, to decent result. However, I've never really been a "Baker" - I've generally avoided the big hot box that sits underneath the stove, and would tell people that me and that box didn't really get along well.</p>
<p>Despite this, the drive to try it out was too much to handle. I made use of the fact that my wife was out of town this past weekend to give me some buffer time: if things turned out well, I'd have a nice surprise for her when she returned; if I screwed up things or made a complete mess of the kitchen, I'd have time to destroy the evidence. :D</p>
Daily: 2019-04-042019-04-04T00:00:00+00:002019-04-04T00:00:00+00:00Unknownhttps://www.ballpointcarrot.net/dailies/2019-04-04/<p>Participated in a discussion on people learning ruby, and it reminded me of _why and his <a href="https://poignant.guide/">Poignant Guide</a>.</p>
<p>Sure, by now it's dated, and the syntax doesn't hold up to best practices 100%, but even reading through it today, it's entertaining and captures your interest.</p>
<p>It's why I still consider ruby my "I need to get shit done" language - it just feels right.</p>
Daily: 2019-04-032019-04-03T00:00:00+00:002019-04-03T00:00:00+00:00Unknownhttps://www.ballpointcarrot.net/dailies/2019-04-03/<p>Just put all of my choir stuff for the next two weeks on the calendar. I may spend more time at the Cathedral than I do at home over the week leading up to Easter.</p>
Daily: 2019-04-022019-04-02T00:00:00+00:002019-04-02T00:00:00+00:00Unknownhttps://www.ballpointcarrot.net/dailies/2019-04-02/<p>I wonder, with the rapid rise of Kubernetes, how long it takes before it is replaced/fizzles out. I've seen separate opinions, and I just don't have enough experience with it to know which way I think.</p>
Daily: 2019-04-012019-04-01T00:00:00+00:002019-04-01T00:00:00+00:00Unknownhttps://www.ballpointcarrot.net/dailies/2019-04-01/<p>Best April Fool's gag of the day for me was the ThinkGeek <a href="https://twitter.com/thinkgeek/status/1112806973421092869">Mimic delivery package</a>.</p>
<p>StackOverflow's <a href="/images/so-geocities.png">Geocities theme</a> was pretty good, too.</p>
Daily: 2019-03-312019-03-31T00:00:00+00:002019-03-31T00:00:00+00:00Unknownhttps://www.ballpointcarrot.net/dailies/2019-03-31/<p>Knocked out a few leetcode problems today. Relied pretty heavily on the Rust docs while doing it, but that's because I don't have the Rust stdlib under my belt yet.</p>
<p>Results were better than expected, although I took longer to get to solutions than I wanted. Anyway, forward progress.</p>
Making the Shell Less Scary - Starting out2019-03-31T00:00:00+00:002019-03-31T00:00:00+00:00Unknownhttps://www.ballpointcarrot.net/posts/shell-less-scary-first-commands/<p>I will fully admit that I grew up comfortable working on a computer without a GUI. From my early days, I had an old computer that I mainly used to play games (some things never change, but current ones don't come on 5 1/4" floppies); in order to get those games to run, I learned from my Mom how to access the correct drive, and the commands to run in order to start up the game.</p>
<p>Today, even though we have fancy GUI apps to do a lot of the work that we need to get done on a daily basis, I still find that it's easier for me to quickly open a terminal window, enter a few commands, and complete whatever task I was doing. Not everything benefits from this approach (imagine doing image editing with a text editor!), but tasks involving finding files, moving files around the system, and working on remote systems works are things that I would much prefer a terminal for.</p>
<p>Today I'm going to dive into a few of the commands that do just the things that I was talking about. These are some of the commands that you would end up using on a day-to-day basis in a terminal window; hopefully I can shine some light on some corners of them that you don't expect.</p>
Daily: 2019-03-302019-03-30T00:00:00+00:002019-03-30T00:00:00+00:00Unknownhttps://www.ballpointcarrot.net/dailies/2019-03-30/<p>Today was a relax day; I did no programming today. Instead, I went out and cleaned up the garden, and played video games. It's good to have a change of pace every once in a while. Also, working the body tends to refresh the mind.</p>