Migrate apt keys from /etc/apt/trusted.gpg

As per man 8 apt-key‘s deprecation note, the /etc/apt/trusted.gpg file managed by apt-key is now deprecated.

New keys should be added to /usr/share/keyrings is this way:

curl -fsSL https://download.docker.com/linux/ubuntu/gpg \
  | gpg --dearmor \
  | sudo tee /usr/share/keyrings/docker-ce-archive-keyring.gpg \
  > /dev/null

This key can then be used in the source definition in this way:

deb [arch=amd64 signed-by=/usr/share/keyrings/docker-ce-archive-keyring.gpg] https://download.docker.com/linux/ubuntu jammy stable

Now, if you have a bunch of keys in /etc/apt/trusted.gpg and don’t fancy looking it up where they are from, you can do something like this:

  • Use gpg --keyring /etc/apt/trusted.gpg --list-keys to get your list, one entry might look like this:
pub   rsa2048 2014-12-29 [SC]
      37C84554E7E0A261E4F76E1ED26E6ED000654A3E
uid           [ unknown] Syncthing Release Management <release@syncthing.net>
sub   rsa2048 2014-12-29 [E]
sub   rsa4096 2015-05-11 [S] [expires: 2025-05-08]

The 37C84554E7E0A261E4F76E1ED26E6ED000654A3E in the second line is the key id.

  • Decide on a filename for the key, eg. syncthing-apt.gpg
  • Export the key
gpg --keyring /etc/apt/trusted.gpg --export 37C84554E7E0A261E4F76E1ED26E6ED000654A3E \
  | sudo tee /usr/share/keyrings/syncthing-apt.gpg > /dev/null
  • Update the source definition by adding signed-by=/usr/share/keyrings/syncthing-apt.gpg option-value pair
--- /etc/apt/sources.list.d/syncthing-release.list.orig 2023-07-12 07:49:21.682281426 +0200
+++ /etc/apt/sources.list.d/syncthing-release.list      2024-07-04 06:40:56.628558228 +0200
@@ -1 +1 @@
-deb [arch=amd64] http://apt.syncthing.net/ syncthing release
+deb [arch=amd64 signed-by=/usr/share/keyrings/syncthing-apt.gpg] http://apt.syncthing.net/ syncthing release
  • Remove the key from the old keyring
sudo gpg --keyring /etc/apt/trusted.gpg --delete-key 37C84554E7E0A261E4F76E1ED26E6ED000654A3E
  • Rinse and repeat until you added all the keys you still use

Inspired by: https://github.com/docker/docs/issues/11625 and https://www.gnupg.org/documentation/manuals/gnupg/GPG-Configuration-Options.html

APFS purgeable space

APFS has this weird feature of purgeable space which is basically disk space that should be empty but is still reported as used. If anything tries to claim disk space it will be purged but for any reporting purposes the disk might look full.

So in case you always seem to be on the brink of running out of disk space you might want to run this (at your own risk of course :))

sudo /System/Library/Filesystems/apfs.fs/Contents/Resources/apfs.util -P  /System/Volumes/Data/private/var/db/*

Note that this might take a while (few minutes) on a first run. Given that it might be deleting 100s of GB it makes sense.

As an example it looked like this for me:

$ df -h .
Filesystem     Size   Used  Avail Capacity iused     ifree %iused  Mounted on
/dev/disk3s1  926Gi  846Gi   43Gi    96% 4057305 448723440    1%   /System/Volumes/Data

$ time -p sudo /System/Library/Filesystems/apfs.fs/Contents/Resources/apfs.util -P  /System/Volumes/Data/private/var/db/*
request has flags: 0x0 type: 0x0 min_size 0 max_age 0 desired_amt 0 (size: 32)
Purging files on /System/Volumes/Data/private/var/db/Accessibility returned 0 (OK).  Deleted amount: 303885606912
real 220.16
user 0.01
sys 55.53

$ df -h .
Filesystem     Size   Used  Avail Capacity iused      ifree %iused  Mounted on
/dev/disk3s1  926Gi  563Gi  326Gi    64% 3657478 3415215200    0%   /System/Volumes/Data

Subsequent runs are really fast though:

$ time -p sudo /System/Library/Filesystems/apfs.fs/Contents/Resources/apfs.util -P  /System/Volumes/Data/private/var/db/*
request has flags: 0x0 type: 0x0 min_size 0 max_age 0 desired_amt 0 (size: 32)
Purging files on /System/Volumes/Data/private/var/db/Accessibility returned 0 (OK).  Deleted amount: 0
real 0.04
user 0.01
sys 0.02

Add WordPress site

WordPress setup is relatively straightforward but on my server there are some things that need to be done to keep it tidy.

  • Set up virtual host
~ $ sudo /etc/apache2/addvhost.sh
~ $ sudo systemctl reload apache

If domain is ready then create a certificate.

  • Set up a database
~ $ domain=...
~ $ vhost=${domain//./_}
~ $ sqlvhost=${vhost//_/\\_}
~ $ db_pass=$(pwgen 32 1)
~ $ mysql -uroot -p << SQL
CREATE DATABASE \`$vhost\` CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
CREATE USER '$vhost'@'localhost' IDENTIFIED BY '$db_pass';
GRANT USAGE ON *.* TO '$vhost'@'localhost';
GRANT ALL PRIVILEGES ON \`$sqlvhost\`.* TO '$vhost'@'localhost' WITH GRANT OPTION;
SQL
  • Get WP and create configuration
~ $ cd /var/www/$vhost
/var/www/VHOST $ wget https://wordpress.org/latest.tar.gz
/var/www/VHOST $ tar xzf latest.tar.gz -C web --strip-components=1
/var/www/VHOST $ rm latest.tar.gz
/var/www/VHOST $ cp -p ../it_fejese_com/web/.htaccess web/
/var/www/VHOST $ cd web
/var/www/VHOST $ chmod g+w wp-content
/var/www/VHOST/web $ sed -r \
    -e "s/(database_name_here|username_here)/$vhost/" \
    -e "s/password_here/$db_pass/" \
    -e "s/\(\s*'DB_CHARSET'\s*, '[^']*'\s*\)/('DB_CHARSET', 'utf8mb4')/" \
    -e "s/\(\s*'DB_COLLATE'\s*, '[^']*'\s*\)/('DB_COLLATE', 'utf8mb4_unicode_ci')/" \
    wp-config-sample.php > wp-config.php
/var/www/VHOST/web $ while grep -q 'put your unique phrase here' wp-config.php; do sed -i "0,/put your unique phrase here/s/put your unique phrase here/$(pwgen 64 1)/" wp-config.php; done
  • Finish WP setup

Go to $domain and finish WP installation.

  • Back up
/var/www/VHOST/web $ cd ..
/var/www/VHOST $ cp -p ../it_fejese_com/backup_db.sh ./
/var/www/VHOST $ cp -p ../it_fejese_com/.gitignore ./
/var/www/VHOST $ ./backup_db.sh
/var/www/VHOST $ git init
/var/www/VHOST $ git add :/
/var/www/VHOST $ git ci -m 'Initial commit'
/var/www/VHOST $ git init --bare /var/git/$USER/$vhost.git
/var/www/VHOST $ git remote add origin /var/git/$USER/$vhost.git/
/var/www/VHOST $ git push origin

That’s mostly it.

Fix svn:externals cached in working copy

The goal was to change an external reference and make it a part of the repository.  So from this:

repo
\-foo -> external: https://....

To this:

repo
\-foo (included in repo directly)

The procedure for this would be:

  1. Removing the externals reference
    repo$ svn pd svn:externals .
  2. Adding the content
    svn add foo
  3. And committing it
    svn ci -m 'Include foo in repo instead of external reference'

However there’s actually an additional step needed after step 1: committing the removal of the externals definition. Otherwise the working copy can get corrupted. I managed to get the working copy in a reasonable state except the foo directory was still recognised as an external.

As it turns out the list of externals in a working copy is stored in .svn/wc.db. Since the update around the removal of the externals reference failed halfway the entries from this database were not removed. Luckily it’s a standard, sqlite database so using the sqlite3 tool it’s possible to remove entries from the EXTERNALS table.

repo$ sqlite3 .svn/wc.db
SQLite version 3.8.2 2013-12-06 14:53:30
Enter ".help" for instructions
Enter SQL statements terminated with a ";"
sqlite> .tables
ACTUAL_NODE    NODES          PRISTINE       WC_LOCK
EXTERNALS      NODES_BASE     REPOSITORY     WORK_QUEUE
LOCK           NODES_CURRENT  WCROOT
sqlite> select * from EXTERNALS;
1|foo||2|normal|dir||||
sqlite> delete from externals where local_relpath = 'foo';
sqlite> .quit
repo$

So far it seems that it didn’t do any damage.
Of course if the working copy is small and clean then checking it out might be a simpler and faster solution. In my case it was a 20G working copy so I was trying to find a way around it.

Change main domain of wordpress site

Ideally you should be able to do this in the WP admin however you might have trouble logging in even as the site is trying to force the set domain. So in this case it might be easier to fix the db:

UPDATE wp_posts SET
 guid = REPLACE(guid, 'blog.fejese.com', 'it.fejese.com'),
 post_content = REPLACE(post_content, 'blog.fejese.com', 'it.fejese.com')
;
UPDATE wp_options SET
 option_value = REPLACE(option_value, 'blog.fejese.com', 'it.fejese.com')
;

Note thought that some plugins – the ones with integrations to external services – might need to be repaired but normally that should be no problem.

Hide Wikipedia fundraiser banner

You should support Wikipedia through the Wikimedia Foundation. However if you already have and you want to use wiki on another machine or browser, you can get rid of the banner by running this.

// create a date object
var d = new Date();
// save the current date
var now = Math.round(d.getTime() / 1000);
// add 2 years for good measures
d.setFullYear(d.getFullYear() + 2);
// set the cookie
$.cookie("centralnotice_hide_fundraising", '{"v":1,"created":' + now + ',"reason":"donate"}', {"expires": d});

Or in one (ugly) line:

$.cookie("centralnotice_hide_fundraising", '{"v":1,"created":' + Math.round(new Date().getTime() / 1000) + ',"reason":"donate"}', {"expires": new Date(new Date().getTime() + 2 * 365 * 24 * 60 * 60 * 1000).toGMTString()});