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;
  • 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.

Huge CBS Log files

If there’s some problem with Windows Updates (or it can be due to other reasons too), the CBS log file can grow faster than it’s rotated and after a while it can’t be rotated.

The log files are under C:\Windows\Logs\CBS.

Both CBS.log and any uncompressed log files can be hold by the Trusted Installer service preventing deletion. So, to clean up safely:

net stop TrustedInstaller
del C:\Windows\Logs\CBS\CBS*.log
net start TrustedInstaller

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:

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

To this:

\-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
sqlite> select * from EXTERNALS;
sqlite> delete from externals where local_relpath = 'foo';
sqlite> .quit

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()});