Today I Learned

Today I Learned

Today I Learned

đŸŒ± I probably learned something today. It was likely far too small to write a longer-form post about it.

2024

I needed to find and script a little around the platforms of a multi-architecture container image. This is what I came up with:

1
2
3
4
docker manifest inspect path-to/image:tag |\
jq -r '.manifests[].platform | select(.os != "unknown" and .architecture != "unknown") | "\(.os)-\(.architecture)"' |\
sort |\
uniq

It omits any unknown entries as they’re frequently attestations or signatures. It outputs a lovely list as follows:

1
2
3
4
5
6
7
linux-386
linux-amd64
linux-arm
linux-arm64
linux-ppc64le
linux-s390x
windows-amd64

The full shell wrapper, which includes a help message and only needs the image name as an argument, is here.

(2024-12-11)

GitLab parses hotlinks a little differently than GitHub. Rather than both issues and pull requests sharing #number, GitLab uses !number for merge requests and #number for issues. Not sure why this difference is, but it’s handy. So:

  • !22 becomes a link to merge request number 22
  • #22 becomes a link to issue number 22

(2024-12-10)

Altitude makes yeast breads ferment faster

Regardless of using sourdough starter or commercial yeast, any bread that relies on bulk fermentation takes less time at higher altitudes than recipes at sea level. For me, an “overnight” is more like 6 hours. Actually letting it go overnight means sticky, floppy dough - good for focaccia or “no-knead” breads, but bad for a boule.

The King Arthur Baking guide to baking at high altitude goes into detail on what to tweak, what that change possibly does, and why it works. For me, I’ve found that a touch more flour than called for and less time (usually) does the trick for yeast breads.

(2024-12-07)

Skopeo can inspect container image configuration

Skopeo can also inspect the configuration of a container, not just what’s in the OCI manifest. It’s great to get a handle on the default environment variables, working directory, and other defaults. Use the --config flag to get the configuration of an image as a big JSON file.

1
skopeo inspect --config --override-os="linux" --override-arch="amd64" docker://python:3.12

I also needed to specify the OS and CPU architecture I wanted to inspect. Skopeo defaults to what’s detected on the host and I’m on an ARM-based Mac. This returns something that’s easy to pipe through JQ for just what I need - in this case, the default environment variables of the Python:3.12 image for Intel-based Linux systems.

1
2
3
4
5
6
7
8
ᐅ skopeo inspect  --config --override-os="linux" --override-arch="amd64" docker://python:3.12 | jq '.config.Env'
[
  "PATH=/usr/local/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin",
  "LANG=C.UTF-8",
  "GPG_KEY=7169605F62C751356D054A26A821E680E5FA6305",
  "PYTHON_VERSION=3.12.7",
  "PYTHON_SHA256=24887b92e2afd4a2ac602419ad4b596372f67ac9b077190f459aba390faf5550"
]

(2024-12-03)

Thankfulness

There’s someone who’s made a great impact on your career. Maybe you’ve fallen out of touch. It’s a good time to say thank you 
 now, later, next week when everyone’s signed back in to work, etc. 💖

(then sign back out of LinkedIn 
 it’s not good for you)

(2024-11-27)

Selection bias

Actual conversation from earlier this week 
 sometimes I forget how broad “Federal tech” really is. This same conversation could happen about literally any piece of software. 😅

Me (to rep): “You seeing any folks using MISP these days? Is it coming up in any of your conversations?”

Rep: “Nope. Hasn’t in a few years. Folks still use that for threat intel?”

:: two hours later in team call ::

Different rep: “How many times have we seen MISP? It comes up all the time and there’s at least <long list of folks> I know using it.”

(2024-11-22)

Disabling Kyverno

TIL that you can put Kyverno in audit mode by setting a value in the Helm chart. It’s handy when you inherit a giant blob of policies that “worked on my cluster” but not on yours. All the failures are logged and the pods show up with warnings, but nothing is stopped. This allows you to figure out what would need addressing with a new set of policies in bulk, rather than toughing it out through a bunch of “break/fix” cycles.

1
2
3
4
kyvernoPolicies:
  enabled: true
  values:
    validationFailureAction: Audit

(2024-11-21)

Grype can use an image pull policy

One more saved-my-bacon tip: If you’re prone to having a ton of images cached locally, you may need to scan the latest build of that tag. It can always pull the latest image, similar to setting ImagePullPolicy: Always in Kubernetes.

1
default-image-pull-source: registry

(2024-11-19)

Grype has a config file

A nifty tidbit if you travel a lot. Grype has a config file. Before you leave the house, run grype db update to pull down the latest vulnerability data, then disable the auto-update features in the config file:

1
2
3
4
# sometimes the hotel wifi is awful and yesterday's data is good enough
check-for-app-update: false
db:
  auto-update: false

I revert it by having the exact opposite values commented out to swap back and forth easily, then doing a quick edit. Docs here - https://github.com/anchore/grype#configuration

(2024-11-18)

Helm sub-chart dependencies

TIL that Helm sub-charts cannot specify dependencies on each other or the order of operation they are installed in.

For example, you need a simple PHP app that relies on nginx for load balancing and SQL with some preseeded data or schema applied. It’s not possible to purely state dependencies such that PHP must wait for both nginx and SQL. SQL must wait for Flyway to pull what it needs from GitHub and initialize that database, but nginx has to let cert-manager do its’ thing first 
 and so on and so forth. 😬

Instead, health checks and init containers handle that by failing and retrying until the conditions for success are met 
 the grey-bearded sysadmin in me feels this is cludgey, but also dreads a return to PID lockfiles and load-bearing sleep statements.

(2024-11-15)

Python 2 is still a thing

So yeah, Python 2 is still hanging around. It’s not expedient to rewrite things for a short-lived demo or reusing exploit code. Luckily, pip still works - just need to use the Python Package Authority’s archive.

1
2
3
curl https://bootstrap.pypa.io/pip/2.7/get-pip.py -o get-pip.py
sudo python2.7 get-pip.py
sudo python2.7 -m pip install requests

This works fantastically in a devcontainer or a virtual machine to keep it isolated from my regular Python environment.

(2024-10-26)

Escaping brackets in code blocks in Jekyll

In Jekyll, anything with{{ }} will be interpreted as Liquid first. This breaks a bunch of templating languages. The code you want to show won’t display as intended in the code block.

Fix this with {% raw %} and {% endraw %} tags to wrap your code block. Maybe it’s “today i spent several hours relearning” or “today i knew i did this before and couldn’t find it, yet couldn’t bring myself to just google it” đŸ€ŠđŸ»â€â™€ïž

1
2
3
4
5
6
7
8
{% raw %}
```yaml
{{ .Chart.Name }}-{{ .Chart.Version }}  # helm
${{ github.repository }}  # github actions
end with three backticks
escape the backticks below to make it render right
\```
{% endraw %}

(2024-10-23)

Referrer headers and Confluence URLs

If you run Confluence internally, please remove your internal Confluence server’s URL from the referring header. This is a setting somewhere in your corporate inspection proxy.

Anyone running basic traffic analytics on their site, including this goober, can have a list of them easily. It’s 2024 and that’s an ancient version of Confluence, telling the entire world it exists every time your users click anything stored there. Take a moment and just check that your proxy/firewall/whatever is stripping these out. Then take another moment and update your stuff. 🙏

(2024-10-22)

POSSE testing

Hello again, world! I’m working on building out a set of scripts to automatically cross-post content from my site to other platforms - this should work 
 đŸŒ±

(2024-10-19)


These are cross-posted to other platforms as my first foray into POSSE (Publish on Own Site, Syndicate Elsewhere), so some formatting may get lost between platforms.

This post is licensed under CC BY 4.0 by the author.