import posts from scribbles
30
gemlog/box-salt.gmi
Normal file
|
@ -0,0 +1,30 @@
|
||||||
|
Last year, I figured out how to use HashiCorp Vagrant to provision and manage virtual machines on a Chromebook. I used that for some lightweight tinkering and to learn a bit more about how to use Salt for configuration management in a safe and self-contained environment.
|
||||||
|
|
||||||
|
=> gemini://gmi.runtimeterror.dev/create-vms-chromebook-hashicorp-vagrant/ runtimeterror: Create Virtual Machines on a Chromebook with HashiCorp Vagrant
|
||||||
|
=> https://docs.saltproject.io/en/master/topics/tutorials/walkthrough.html#salt-in-10-minutes/ Salt in 10 Minutes
|
||||||
|
|
||||||
|
Well, I'm about to need to do a lot more Salt work, so last night I decided to refresh my Vagrant setup a bit. I switched to using some newer machine images ("boxes"), and made some tweaks to support the latest "onedir" Salt releases. Being able to quickly spin up/down a lab environment with minions running various Linux flavors is a huge help to my development process.
|
||||||
|
|
||||||
|
=> https://docs.saltproject.io/salt/install-guide/en/latest/topics/upgrade-to-onedir.html#what-is-onedir Salt Documentation: What is onedir?
|
||||||
|
|
||||||
|
```
|
||||||
|
$ vagrant status
|
||||||
|
Current machine states:
|
||||||
|
|
||||||
|
salt running (libvirt) # master, ubuntu 22.04
|
||||||
|
minion01 running (libvirt) # ubuntu 22.04
|
||||||
|
minion02 running (libvirt) # ubuntu 20.04
|
||||||
|
minion03 running (libvirt) # rocky 8
|
||||||
|
minion04 running (libvirt) # rocky 9
|
||||||
|
```
|
||||||
|
|
||||||
|
To make it easier to deploy, test, break, tear down, and redeploy the environment:
|
||||||
|
* The Salt master blindly auto-accepts all minion keys.
|
||||||
|
* The minions register the roles:saltlab grain to aid in targeting.
|
||||||
|
* The master uses gitfs to pull the starter Salt content from this very Github repo.
|
||||||
|
* Additionally, the contents of `salt_content/local` get rsynced to `/srv/` when the master starts up to make it easier to write/test Salt content locally. This is a one-way rsync from host to VM (and not the other way around), so make sure to write your Salt content on the host and use `vagrant rsync` to push changes into the VM.
|
||||||
|
|
||||||
|
The full details of this setup are in my GitHub:
|
||||||
|
=> https://github.com/jbowdre/vagrant-saltlab vagrant-saltlab: A small Vagrant lab environment for learning Salt
|
||||||
|
|
||||||
|
Okay, back to work!
|
4
gemlog/box-salt.yaml
Normal file
|
@ -0,0 +1,4 @@
|
||||||
|
id: "urn:uuid:900a918d-f85d-456f-98e8-26b2eae214c0"
|
||||||
|
title: "A Box of Salt"
|
||||||
|
published: "2024-02-06T15:06:42-06:00"
|
||||||
|
updated: "2024-02-06T15:06:42-06:00"
|
33
gemlog/fish-magic.gmi
Normal file
|
@ -0,0 +1,33 @@
|
||||||
|
I've been using (and loving) fish shell for a little while now, and I still frequently discover clever behaviors that make my CLI tasks more enjoyable.
|
||||||
|
|
||||||
|
=> https://fishshell.com/ fish shell
|
||||||
|
|
||||||
|
Today's discovery: fish will automatically escape single quotes when pasting text into the command line.
|
||||||
|
|
||||||
|
=> https://fishshell.com/docs/current/cmds/fish_clipboard_paste.html fish_clipboard_paste - get text from the system’s clipboard
|
||||||
|
|
||||||
|
> If it outputs to the commandline, it will automatically escape the output if the cursor is currently inside single-quotes so it is suitable for single-quotes (meaning it escapes ' and \\).
|
||||||
|
|
||||||
|
So if I work up an ugly one-liner for determining the IP address of whatever interface is attached to the default route:
|
||||||
|
|
||||||
|
```
|
||||||
|
ip addr show $(ip route | grep default | awk '{print $5}') | grep 'inet ' | awk '{print $2}' | cut -d/ -f1
|
||||||
|
```
|
||||||
|
|
||||||
|
And then decide I'd like to make that into a reusable alias, I can copy that line and paste it in after
|
||||||
|
|
||||||
|
=> https://fishshell.com/docs/current/cmds/alias.html alias - create a function
|
||||||
|
|
||||||
|
```
|
||||||
|
alias get_ip='
|
||||||
|
```
|
||||||
|
|
||||||
|
and fish will automagically take care of escaping all those troublesome single quotes
|
||||||
|
|
||||||
|
```
|
||||||
|
alias get_ip='ip addr show $(ip route | grep default | awk '{print $5}') | grep 'inet ' | awk '{print $2}' | cut -d/ -f1'
|
||||||
|
```
|
||||||
|
|
||||||
|
Neat!
|
||||||
|
|
||||||
|
=> /res/2024-02-01-fish-screenshot.png Image: Command-line interface displaying text commands and outputs for IP address configurations.
|
4
gemlog/fish-magic.yaml
Normal file
|
@ -0,0 +1,4 @@
|
||||||
|
id: "urn:uuid:ae09eb2b-e3b6-4b0c-9bbc-256af5df934a"
|
||||||
|
title: "Fish Magic"
|
||||||
|
published: "2024-02-01T14:40:03-06:00"
|
||||||
|
updated: "2024-02-01T14:40:03-06:00"
|
4
gemlog/hyperpolyglot-unix-shells.gmi
Normal file
|
@ -0,0 +1,4 @@
|
||||||
|
I primarily use fish shell on the systems I own, but many of the systems I manage don't include fish so I have to use bash, zsh, or something more exotic. It can be hard to keep track of how to translate expressions and conventions between shells.
|
||||||
|
|
||||||
|
This handy-dandy reference should help:
|
||||||
|
=> https://hyperpolyglot.org/unix-shells Hyperpolyglot: Unix Shells
|
4
gemlog/hyperpolyglot-unix-shells.yaml
Normal file
|
@ -0,0 +1,4 @@
|
||||||
|
id: "urn:uuid:ab1ec906-4ded-483b-b51e-d143d0548d7b"
|
||||||
|
title: "Hyperpolyglot: Unix Shells"
|
||||||
|
published: "2024-01-26T15:27:00-06:00"
|
||||||
|
updated: "2024-01-26T15:27:00-06:00"
|
24
gemlog/loopy-keyboards.gmi
Normal file
|
@ -0,0 +1,24 @@
|
||||||
|
I'm such a sucker for absolutely bonkers software keyboards for mobile phones.
|
||||||
|
|
||||||
|
I used (and kind of loved) a bunch of different keyboards back in the day, including the super-low-profile Minuum and gesture-powered Fleksy. But one of the wildest (and most interesting) keyboards I tried was 8pen.
|
||||||
|
|
||||||
|
=> http://minuum.com/ Minuum keyboard
|
||||||
|
=> https://www.app.fleksy.com/ Fleksy keyboard
|
||||||
|
=> https://www.youtube.com/watch?v=q3OuCR0EpGo 8pen keyboard
|
||||||
|
|
||||||
|
Seriously, look at this ridiculous layout:
|
||||||
|
|
||||||
|
=> /res/images/2024-02-12-8pen-layout.png Image: Colored lines intersect behind a magnifying glass, which centers on letters and symbols arranged in a circle on a white background - but it's a keyboard, somehow?
|
||||||
|
|
||||||
|
It's wild, right? Once I figured out how to use it, I got to be pretty fast and accurate at text entry - and it's designed in such a way that (once you learn it) you don't have to look at the keyboard at all.
|
||||||
|
|
||||||
|
8pen was (perhaps predictably) abandoned at some point, but I just discovered that there's a refreshed, expanded, and open-source clone of it now:
|
||||||
|
|
||||||
|
=> https://github.com/8VIM/8VIM 8vim on GitHub
|
||||||
|
=> https://play.google.com/store/apps/details?id=inc.flide.vi8 8vim on Google Play
|
||||||
|
|
||||||
|
It's also been enhanced with Vim-inspired editor ability, or something.
|
||||||
|
|
||||||
|
I used 8vim to type (some) of this message and it only took forever. I'm sure I will get the hang of this again in no time.
|
||||||
|
|
||||||
|
=> /res/images/2024-02-12-8vim-keyboard.png Image: A smartphone screen displaying a text editor app with a unique keyboard layout. The text discusses an open-source clone of an abandoned project, 8vim Keyboard, and mentions the user's experience adapting to it.
|
4
gemlog/loopy-keyboards.yaml
Normal file
|
@ -0,0 +1,4 @@
|
||||||
|
id: "urn:uuid:f3b6f67f-ab54-407e-a3ed-c5881ffd93ea"
|
||||||
|
title: "Loopy Keyboards"
|
||||||
|
published: "2024-02-12T19:44:00-06:00"
|
||||||
|
updated: "2024-02-12T19:44:00-06:00"
|
13
gemlog/self-hosting-search-engine.gmi
Normal file
|
@ -0,0 +1,13 @@
|
||||||
|
I've lately been playing a bit with a self-hosted instance of SearXNG, an utterly-unpronounceable privacy-respecting open-source metasearch engine.
|
||||||
|
|
||||||
|
=> https://github.com/searxng/searxng SearXNG on GitHub
|
||||||
|
=> https://en.wikipedia.org/wiki/Metasearch_engine Metasearch engine on Wikipedia
|
||||||
|
|
||||||
|
Rather than maintaining its own index or running its own crawlers (as something like YaCy does), SearXNG simply asks other engines for their results to a given query (remember Dogpile from back in the day?). The really cool thing with SearXNG is that it also gives you, the user, a whole lot of control over what engines it uses to create its aggregated results.
|
||||||
|
|
||||||
|
=> https://yacy.net/ YaCy homepage
|
||||||
|
=> /res/images/2024-02-21-searxng-prefs.png Image: SearXNG Preferences page listing some of the available search engines
|
||||||
|
|
||||||
|
It's pretty neat, and the results so far have been fairly decent. If you'd like to give it a try, my instance is at grep.vim.wtf. (At least until I get bored with it.)
|
||||||
|
|
||||||
|
=> https://grep.vim.wtf/ SearXNG on grep.vim.wtf
|
4
gemlog/self-hosting-search-engine.yaml
Normal file
|
@ -0,0 +1,4 @@
|
||||||
|
id: "urn:uuid:90cde3a0-afb0-4a28-8c7f-c7559086fcfa"
|
||||||
|
title: "Self-Hosting a Search Engine"
|
||||||
|
published: "2024-02-21T10:30:39-06:00"
|
||||||
|
updated: "2024-02-21T10:30:39-06:00"
|
19
gemlog/upptime-serverless-server-monitoring.gmi
Normal file
|
@ -0,0 +1,19 @@
|
||||||
|
While tinkering with something unrelated last night, I stumbled upon a service status page provided by Upptime. I thought it looked neat, and then I dug into it a bit more, and now I think it's really neat.
|
||||||
|
|
||||||
|
=> https://upptime.js.org/ Upptime Homepage
|
||||||
|
=> https://upptime.js.org/docs/ Upptime Documentation
|
||||||
|
|
||||||
|
Most other (self-hosted/managed) uptime monitoring solutions I've played with require deploying a server (or container) to monitor your other servers. _Who monitors the monitors?_
|
||||||
|
|
||||||
|
Upptime is a bit different. It operates as a set of GitHub Actions to check the configured sites every 5 minutes, and it stores the results in a version-controlled repository. It uses GitHub Pages to generate a really nice-looking status page which provides historical uptime as well as response times, complete with pretty graphs. If something goes down, Upptime automatically creates an Issue in the repo to track the problem, and it can also send an alert via email or Slack or Discord or a number of other methods (though it doesn't currently support ntfy). And if any of Upptime's workflows fail, you'll get a notification through GitHub, too (monitor: monitored).
|
||||||
|
|
||||||
|
=> https://github.com/orgs/upptime/discussions/862 Upptime Discussion: Ntfy.sh notification support
|
||||||
|
|
||||||
|
It didn't take much tinkering to get Upptime configured and operational for keeping tabs on some of my public sites, and I'm rather pleased with how well it works:
|
||||||
|
|
||||||
|
=> https://status.runtimeterror.dev/ "Upptime Terror", the status page for my public sites
|
||||||
|
|
||||||
|
=> /res/upptime-screenshot.png Image: Green-themed website status page displaying real-time data from a GitHub repository. It shows a 100% uptime for various services with average response times ranging from 545 ms to 747 ms.
|
||||||
|
|
||||||
|
Check out the docs to learn more:
|
||||||
|
=> https://upptime.js.org/docs/ Upptime Documentation
|
4
gemlog/upptime-serverless-server-monitoring.yaml
Normal file
|
@ -0,0 +1,4 @@
|
||||||
|
id: "urn:uuid:5837bf68-f5a5-4602-8d67-a164d08a5313"
|
||||||
|
title: "Upptime: Serverless Server Monitoring"
|
||||||
|
published: "2024-01-30T11:07:00-06:00"
|
||||||
|
updated: "2024-01-30T11:07:00-06:00"
|
29
gemlog/weather-profile-lol.gmi
Normal file
|
@ -0,0 +1,29 @@
|
||||||
|
I recently saw Kris's omg.lol profile page with integrated live local weather conditions, and I thought that was exceptionally neat. I immediately wanted to do the same with data from my Weatherflow Tempest weather station, but wasn't sure how I could do that without putting my API token in the browser. So I promptly abandoned the idea and moved on to other things.
|
||||||
|
|
||||||
|
=> https://kris.omg.lol/ @kris on omg.lol
|
||||||
|
=> https://shop.tempest.earth/products/tempest Tempest Weather System
|
||||||
|
|
||||||
|
I later realized that I could use another system to grab data from the authenticated API, and post that somewhere world-readable for the profile page to retrieve it.
|
||||||
|
|
||||||
|
So I cobbled together a sort of API proxy: a simple GitHub Actions workflow that runs every ~5 minutes. It uses secrets stored securely in my GitHub repo to fetch the weather data from the Weatherflow Tempest API, filters for just the current conditions data (not the giant mess of future-forecast details), and posts that to my paste.lol pastebin.
|
||||||
|
|
||||||
|
=> https://github.com/jbowdre/lolz/blob/main/.github/workflows/tempest.yml Tempest Update GitHub Workflow
|
||||||
|
=> https://weatherflow.github.io/Tempest/api/ WeatherFlow Tempest API & Developer Platform
|
||||||
|
=> https://paste.jbowdre.lol/tempest.json My Tempest pastebin
|
||||||
|
|
||||||
|
I could then use JavaScript to retrieve the weather details from the pastebin. I cobbled together a quick local HTML page for testing as I worked through how to get the data displayed and formatted correctly.
|
||||||
|
|
||||||
|
=> https://github.com/jbowdre/lolz/blob/main/tempest.html Tempest Test HTML
|
||||||
|
=> /res/2024-02-08-tempest-test-page.png Image: A plain, unstyled web page for testing the weather display
|
||||||
|
|
||||||
|
Once I got the scripting sorted out, I was able to easily transfer the script block and relevant spans to my omg.lol profile page - where I think it looks quite dope, if I do say so myself.
|
||||||
|
|
||||||
|
=> https://jbowdre.lol/ @jbowdre on omg.lol
|
||||||
|
=> /res/2024-02-08-omg-profile-page.png Image: Weather details in a glowing green terminal font
|
||||||
|
|
||||||
|
Big thanks to Kris for the inspiration and the examples I needed to get this working.
|
||||||
|
|
||||||
|
> Update: I've shared more details on how this all works over at the bigger blog, and the code is available on GitHub.
|
||||||
|
|
||||||
|
=> gemini://gmi.runtimeterror.dev/display-tempest-weather-static-site/ runtimeterror: Displaying Data from a Tempest Weather Station on a Static Site
|
||||||
|
=> https://github.com/jbowdre/lolz John's lolz on GitHub
|
4
gemlog/weather-profile-lol.yaml
Normal file
|
@ -0,0 +1,4 @@
|
||||||
|
id: "urn:uuid:05e62b8a-d4ef-49b6-a85b-16bd9458dd59"
|
||||||
|
title: "(Near) Realtime Weather on profile.lol"
|
||||||
|
published: "2024-03-04T10:47:22-06:00"
|
||||||
|
updated: "2024-03-04T10:47:22-06:00"
|
18
gemlog/zigbee-home-automation.gmi
Normal file
|
@ -0,0 +1,18 @@
|
||||||
|
In addition to tinkering with and documenting the weather integration on my omg.lol page, this weekend I also shifted how my Home Assistant instance manages Zigbee devices.
|
||||||
|
|
||||||
|
=> https://runtimeterror.dev/display-tempest-weather-static-site/ runtimeterror: Displaying Data from a Tempest Weather Station on a Static Site
|
||||||
|
|
||||||
|
I had been using the deCONZ add-on and integration with a Phoscon ConBee II stick for several years. This setup has been fairly functional, but having to drill down into a separate web app (or, worse: a nested VNC session) to manage the Zigbee network was kind of a buzz kill.
|
||||||
|
|
||||||
|
=> https://www.home-assistant.io/integrations/deconz/ deCONZ Integration
|
||||||
|
=> https://www.amazon.com/dresden-elektronik-ConBee-Universal-Gateway/dp/B07PZ7ZHG5 Phoscon ConBee II Universal Zigbee Gateway
|
||||||
|
|
||||||
|
So this weekend I decided to switch over to the Zigbee Home Automation integration. ZHA brings Zigbee coordination directly to Home Assistant rather than just connecting in third-party software to handle that role.
|
||||||
|
|
||||||
|
=> https://www.home-assistant.io/integrations/zha/ Zigbee Home Automation Integration
|
||||||
|
|
||||||
|
I only have a small handful of Zigbee devices so I wasn't too worried about the migration process, but at the same time I am pleased to report that it went fairly smoothly. I took a backup of the deCONZ config (just in case), stopped the deCONZ add-on (without removing the integration, just in case), installed the ZHA integration, and pointed it to the same ConBee stick. All of my lights and switches were discovered immediately, and I was able to get the new entities assigned to the correct rooms without any fuss. Battery-powered devices like the water leak sensors needed to be manually paired, but those also came in pretty quickly once the correct button was pressed.
|
||||||
|
|
||||||
|
Then it was just a matter of updating my various automations and scenes with the new entity identifiers. This was also a great opportunity to clean up some of those long-neglected automations, and they're not working better than ever.
|
||||||
|
|
||||||
|
I'm really pleased with this change, and only wish I'd performed the migration sooner. Zigbee feels like a first-class citizen in Home Assistant now, so I'll definitely be looking to acquire more devices soon.
|
4
gemlog/zigbee-home-automation.yaml
Normal file
|
@ -0,0 +1,4 @@
|
||||||
|
id: "urn:uuid:f8621073-3adc-4a5d-8da4-8cdd75e80516"
|
||||||
|
title: "Zibgee Home Automation"
|
||||||
|
published: "2024-02-12T16:25:00-06:00"
|
||||||
|
updated: "2024-02-12T16:25:00-06:00"
|
BIN
static/res/2024-01-30-upptime-screenshot.png
Normal file
After Width: | Height: | Size: 226 KiB |
BIN
static/res/2024-02-01-fish-screenshot.png
Normal file
After Width: | Height: | Size: 42 KiB |
BIN
static/res/2024-02-08-omg-profile-page.png
Normal file
After Width: | Height: | Size: 107 KiB |
BIN
static/res/2024-02-08-tempest-test-page.png
Normal file
After Width: | Height: | Size: 55 KiB |
BIN
static/res/2024-02-12-8pen-layout.png
Normal file
After Width: | Height: | Size: 74 KiB |
BIN
static/res/2024-02-12-8vim-keyboard.png
Normal file
After Width: | Height: | Size: 204 KiB |
BIN
static/res/2024-02-21-searxng-prefs.png
Normal file
After Width: | Height: | Size: 148 KiB |