tutorial

Quick and dirty way to strip ANSI terminal output in PHP

From time to time, I write up little PHP scripts to run a command via exec() and dump the output to the screen. Most of the time these are quick throwaway scripts, but sometimes I need them to persist a little longer, or share the output with others, so I make them look a little nicer.

One annoying thing that happens if you interact with CLI tools that generate colorized output is that PHP doesn't translate the terminal (ANSI) color codes into HTML colors, so you end up looking at output like:

Kubernetes master is running at https://10.96.0.1:443

Sensio Labs maintains an excellent ansi-to-html PHP library, and if you're building anything that should be persistent or robust, you should use it. But I wanted a one-line solution for one simple script I was working on, so I spent a couple minutes building out the following regex:

Migrating JeffGeerling.com from Drupal 7 to Drupal 8 - How-to video series

Drupal 8 Live migration YouTube series image for JeffGeerling.com

This website is currently (as of February 2020) running on Drupal 7. Drupal 8 was released in November 2015—half a decade ago. Drupal 7 support has been extremely long-lived, as it will not be end-of-life'd until November 2021. As with all software, once it is out of date, and security patches are no longer provided, it becomes harder to ensure the software is secure, much less running well on the latest servers and PHP versions!

Therefore, I decided it was time to start migrating JeffGeerling.com to Drupal 8. And I figured instead of fumbling through the process all by myself, and maybe posting a couple blog posts about the process at the end, I'd adopt a new mantra: Let's fail together! (Just kidding—sorta.)

Upgrade the Raspberry Pi 4's firmware / bootloader for better thermals

In October, the Raspberry Pi Foundation released an updated bootloader/firmware for the Raspberry Pi 4 which dramatically reduces power consumption and overall temperatures on the Pi 4 by setting the USB controller and CPU into a more power-friendly mode.

I wanted to post here the instructions for checking the current version, and upgrading, because I have a large number of Pis to upgrade over time, and I needed a quick reference. For more details, check out the Raspberry Pi Documentation page Raspberry Pi 4 boot EEPROM.

Checking if the current bootloader is up to date

Upgrade system packages and install the rpi-eeprom utility:

$ sudo apt update
$ sudo apt -y full-upgrade
$ sudo apt install -y rpi-eeprom

Check if an update is required:

$ sudo rpi-eeprom-update

If you see a difference in the output, you can restart to update to the newer version. If everything's the same, you're already on the latest version.

Re-gripping a Nikon D700 DSLR

The Nikon D700 holds a special place in my heart. I started getting serious about photography right around the time digital SLR cameras (DSLRs) were overtaking film cameras in terms of quality and sales quantity. My first non-snapshot camera was a manual-focus Minolta X-700, and I'm sad I sold it years ago. The D700 was the first 'semi-pro' level DSLR I used; though I never owned one until recently.

Nikon D700 60mm 2.8 Macro lens Hero image

I rented and borrowed the Nikon D3, D3s, and D700 a number of times when they were the state of the art, and I still love the way the D700 renders images. The fact that it shoots at 12 megapixels means it's more forgiving with handheld photography at slower shutter speeds (since motion blur gets much worse as resolution increases). It doesn't do video at all... but as a photographer's camera, besides maybe the Nikon Df, there isn't a DSLR that I've enjoyed using as much for as long.

The Raspberry Pi 4 needs a fan, here's why and how you can add one

December 2020 Update: Lo and behold, the Pi Foundation tacitly acknowledges the Pi needs a fan in the official case, because now they sell the Case Fan!

The Raspberry Pi Foundation's Pi 4 announcement blog post touted the Pi 4 as providing "PC-like level of performance for most users". The Foundation even offers a Raspberry Pi 4 Desktop Kit.

The desktop kit includes the official Raspberry Pi 4 case, which is an enclosed plastic box with nothing in the way of ventilation.

Cleaning up after adding files in Drupal Behat tests

I've been going kind of crazy covering a particular Drupal site I'm building in Behat tests—testing every bit of core functionality on the site. In this particular case, a feature I'm testing allows users to upload arbitrary files to an SFTP server, then Drupal shows those filenames in a streamlined UI.

I needed to be able to test the user action of "I'm a user, I upload a file to this directory, then I see the file listed in a certain place on the site."

These files are not managed by Drupal (e.g. they're not file field uploads), but if they were, I'd invest some time in resolving this issue in the drupalextension project: "When I attach the file" and Drupal temporary files.

Since they are just random files dropped on the filesystem, I needed to:

Make composer operations with Drupal way faster and easier on RAM

tl;dr: Run composer require zaporylie/composer-drupal-optimizations:^1.0 in your Drupal codebase to halve Composer's RAM usage and make operations like require and update 3-4x faster.

A few weeks ago, I noticed Drupal VM's PHP 5.6 automated test suite started failing on the step that runs composer require drupal/drush. (PSA: PHP 5.6 is officially dead. Don't use it anymore. If you're still using it, upgrade to a supported version ASAP!). This was the error message I was getting from Travis CI:

PHP Fatal error:  Allowed memory size of 2147483648 bytes exhausted (tried to allocate 32 bytes) in phar:///usr/bin/composer/src/Composer/DependencyResolver/RuleWatchNode.php on line 40

I ran the test suite locally, and didn't have the same issue (locally I have PHP's CLI memory limit set to -1 so it never runs out of RAM unless I do insane-crazy things.

AirPods get stuck in low-quality 16 kHz audio mode when starting a VM

I always love when I find a really dumb solution that works reliably to fix a problem that should never really be a problem in the first place. But having worked with audio devices before—though nothing nearly as complex as the AirPods—I am willing to cut Apple some slack in building a seamless aural experience with using AirPods across phone calls, VOIP, iOS devices, Macs, music, and Apple TVs... it's hard to execute perfectly, and as I said in my review of the AirPods two years ago, these little earbuds are as close to perfection when it comes to a wireless sound solution for someone like me.

Anyways, here's the problem:

Sometimes (maybe 10% of the time) when I run vagrant up to build a local development environment for one of my software projects, and I'm listening to music, my AirPods suddenly switch into super-low-quality audio mode. It sounds like you're listening to a song played through a long subway tunnel or something.

The best way to get the full PHP version string

Recently, to automate building, tagging, and pushing my geerlingguy/php-apache Docker Hub image (see this issue), I needed to find a way to reliably determine the PHP major.minor.release version string. You'd think this would be simple.

Well, using Docker, I would run the image and then try:

# php --version
PHP 7.3.0-1+0~20181206202713.23+stretch~1.gbp076afd (cli) (built: Dec  6 2018 20:27:14) ( NTS )
Copyright (c) 1997-2018 The PHP Group
Zend Engine v3.3.0-dev, Copyright (c) 1998-2018 Zend Technologies
    with Zend OPcache v7.3.0-1+0~20181206202713.23+stretch~1.gbp076afd, Copyright (c) 1999-2018, by Zend Technologies

That's great; it outputs the version right at the start. But there are a few problems here: