All posts by Rich

Running NightmareJS on CentOS 6

Most posts on this site aren’t exactly riveting to read, but they might just save you hours and hours of work.  This one is no different!

NightmareJS is fantastic, but due to its reliance on Electron and a strange mix of dependencies, getting it to work on CentOS is very involved.  Lucky for you, I’ve compiled all of the necessary commands and even compiled binaries/libraries to save you from losing what’s left of your hair.

These instructions have been tested on CentOS 6.7.

Install Prerequisites

X-related Packages

Xvfb is required to provide the pseudo-headless-X environment; libXScrnSaver is required to add

[root@backend ~]$ yum install xorg-x11-server-Xvfb libXScrnSaver

MS fonts

(More info:

[root@backend ~]# yum install curl cabextract xorg-x11-font-utils fontconfig
 [root@backend ~]# rpm -i

Upgrade gcc library

I’ve already done the hard work for you and compiled gcc 6.3 from source on CentOS 6.8, 64 bit.  Download the library at  Extract it to the home directory of whichever user you’re logged in as (in my case, root).  Then, install it using the following instructions:

[root@backend ~]# cd /usr/lib64/
 [root@backend lib64]# mv ~/ .
 [root@backend lib64]# ls -alF*
 lrwxrwxrwx 1 root root 19 Oct 1 2015 ->*
 -rwxr-xr-x 1 root root 987096 Jul 22 2015*
 -rwxr-xr-x 1 root root 11508835 Apr 25 18:53*
 #Notice the symbolic link to 6.0.13
 [root@backend lib64]# rm
 [root@backend lib64]# ln -s
 [root@backend lib64]# ls -alF /usr/lib64/*
 lrwxrwxrwx 1 root root 19 Apr 26 18:34 /usr/lib64/ ->*
 -rwxr-xr-x 1 root root 987096 Jul 22 2015 /usr/lib64/*
 -rwxr-xr-x 1 root root 11508835 Apr 25 18:53 /usr/lib64/*
 #Notice the symbolic link to 6.0.22
 [root@backend lib64]# cd
 [root@backend ~]# strings /usr/lib64/ | grep GLIB

Before, we only had strings up until GLIBCXX_3.4.13, but now we have strings up until GLIBCXX_3.4.22. (Our version of Electron requires GLIBCXX_3.4.15)

Update glib library

Follow the nice instructions of some friendly gents over on GitHub to install an updated version of glib that will support Electron (NightmareJS).  More info:

[root@backend ~]# cd /opt
 [root@backend opt]# wget
 [root@backend opt]# tar xzf gcc-4.7.2.tar.gz
 [root@backend opt]# rm gcc-4.7.2.tar.gz
 [root@backend opt]# cd /etc/
 [root@backend]# nano gcc-4.7.2.conf

Into this file, paste the following:

[root@backend]# ldconfig
 [root@backend]# ldconfig -p | grep "libglib"

Check for glib-2.49.4.

Set up D-Bus library

This step might not be necessary.  On the first machine I performed these steps, I didn’t need to do this, but on the second one, I did.  When running your NightmareJS script, if you get an error about the D-Bus library not being set up correctly, execute this simple command (Thanks to Tork Wrench).

[root@backend ~]# dbus-uuidgen > /var/lib/dbus/machine-id

Finally – Running NightmareJS!

[dev@backend ~]$ cd project/
 [dev@backend your-project]$ rm -rf node_modules/
 [dev@backend your-project]$ npm install
 [dev@backend your-project]$ DEBUG=nightmare*,electron* xvfb-run -a --server-args="-screen 0 1280x2000x24" node your-script.js -- --progress=false --single-run --watch=false

Note – this is likely not the best command for you; in fact it almost certainly is not. Experimentation will be needed in adding/removing/changing flags.  However, this should hopefully be enough to verify that NightmareJS is in a functional state.

*I made it all the way through this post without making an obvious pun about how hard it is to get NightmareJS running on CentOS.  I hope I’ve made you proud!

Upgrading MySQL 5.5 to MariaDB 10.0 on Ubuntu 12.04.3 LTS

I couldn’t find instructions for upgrading from MySQL 5.5 to MariaDB 10.0 on Ubuntu 12.04.3 LTS. Fortunately, MariaDB and Ubuntu didn’t let me down, and provided a smooth installation process. Here’s a log of my console session in case it helps anyone else out there!

Excellent resources used:

root@buttercup:/home/rich# cd backups/
root@buttercup:/home/rich/backups# ls
2013-10-01 19-01-27.tar.gz  2014-04-06 4-00-01.tar.gz  2014-05-11 4-00-01.tar.gz  2014-06-15 4-00-01.tar.gz  2014-08-03 4-00-01.tar.gz  2014-09-07 4-00-01.tar.gz  mon.tar.gz
2013-11-03 4-00-01.tar.gz  2014-04-13 4-00-01.tar.gz  2014-05-18 4-00-01.tar.gz  2014-06-22 4-00-01.tar.gz  2014-08-10 4-00-01.tar.gz  2014-09-14 4-00-01.tar.gz  sat.tar.gz
2013-12-01 4-00-01.tar.gz  2014-04-20 4-00-01.tar.gz  2014-05-25 4-00-01.tar.gz  2014-07-13 4-00-01.tar.gz  2014-08-17 4-00-01.tar.gz  2014-09-21 4-00-01.tar.gz  thu.tar.gz
2014-02-02 4-00-01.tar.gz  2014-04-27 4-00-01.tar.gz  2014-06-01 4-00-01.tar.gz  2014-07-20 4-00-01.tar.gz  2014-08-24 4-00-01.tar.gz  2014-09-28 4-00-01.tar.gz  tue.tar.gz
2014-03-02 4-00-01.tar.gz  2014-05-04 4-00-01.tar.gz  2014-06-08 4-00-01.tar.gz  2014-07-27 4-00-01.tar.gz  2014-08-31 4-00-01.tar.gz  fri.tar.gz                wed.tar.gz
root@buttercup:/home/rich/backups# cd ..
root@buttercup:/home/rich/scripts# cp -r /etc/mysql /etc/mysql-backup-10-3-14
root@buttercup:/home/rich/scripts# ls /etc/mysql-backup-10-3-14/
conf.d  debian.cnf  debian-start  my.cnf
root@buttercup:/home/rich/scripts# ls /etc/mysql
conf.d  debian.cnf  debian-start  my.cnf
root@buttercup:/home/rich/scripts# service mysql stop
mysql stop/waiting
root@buttercup:/home/rich/scripts# apt-get remove mysql-common mysql-server-5.5 mysql-server-core-5.5 mysql-client-5.5 mysql-client-core-5.5
Reading package lists... Done
Building dependency tree       
Reading state information... Done
The following packages were automatically installed and are no longer required:
  node-node-uuid libgsasl7 libv8- libax25 m4 libhtml-template-perl procmail sendmail-cf sendmail-base libssl-dev libssl-doc zlib1g-dev libntlm0 libev4 libv8-dev
  libc-ares2 thunderbird-globalmenu libdb4.8 libev-dev libc-ares-dev openbsd-inetd
Use 'apt-get autoremove' to remove them.
The following packages will be REMOVED:
  libdbd-mysql-perl libmailutils2 libmysqlclient18 mysql-client-5.5 mysql-client-core-5.5 mysql-common mysql-server mysql-server-5.5 mysql-server-core-5.5
0 upgraded, 0 newly installed, 9 to remove and 377 not upgraded.
After this operation, 97.3 MB disk space will be freed.
Do you want to continue [Y/n]? Y
(Reading database ... 179727 files and directories currently installed.)
Removing mysql-server ...
Removing mysql-server-5.5 ...
Removing mysql-client-5.5 ...
Removing libdbd-mysql-perl ...
Removing libmailutils2 ...
Removing libmysqlclient18 ...
Removing mysql-client-core-5.5 ...
Removing mysql-common ...
Removing mysql-server-core-5.5 ...
Processing triggers for ureadahead ...
Processing triggers for man-db ...
Processing triggers for libc-bin ...
ldconfig deferred processing now taking place
root@buttercup:/home/rich/scripts# apt-get autoremove
Reading package lists... Done
Building dependency tree       
Reading state information... Done
The following packages will be REMOVED:
  libax25 libc-ares-dev libc-ares2 libdb4.8 libdbi-perl libev-dev libev4 libgsasl7 libhtml-template-perl libnet-daemon-perl libntlm0 libplrpc-perl libssl-dev libssl-doc
  libterm-readkey-perl libv8- libv8-dev m4 node-node-uuid openbsd-inetd procmail sendmail-base sendmail-cf thunderbird-globalmenu zlib1g-dev
0 upgraded, 0 newly installed, 25 to remove and 371 not upgraded.
After this operation, 22.1 MB disk space will be freed.
Do you want to continue [Y/n]? Y
(Reading database ... 179412 files and directories currently installed.)
Removing libax25 ...
Removing libc-ares-dev ...
Removing libc-ares2 ...
Removing libdb4.8 ...
Removing libdbi-perl ...
Removing libev-dev ...
Removing libev4 ...
Removing libgsasl7 ...
Removing libhtml-template-perl ...
Removing libplrpc-perl ...
Removing libnet-daemon-perl ...
Removing libntlm0 ...
Removing libssl-dev ...
Removing libssl-doc ...
Removing libterm-readkey-perl ...
Removing libv8-dev ...
Removing libv8- ...
Removing sendmail-cf ...
Removing sendmail-base ...
Removing m4 ...
Removing node-node-uuid ...
Removing openbsd-inetd ...
 * Stopping internet superserver inetd                                                                                                                                     [ OK ] 
Removing procmail ...
Removing thunderbird-globalmenu ...
Removing zlib1g-dev ...
Processing triggers for man-db ...
Processing triggers for libc-bin ...
ldconfig deferred processing now taking place
Processing triggers for install-info ...
Processing triggers for ureadahead ...
root@buttercup:/home/rich/scripts# cd
root@buttercup:~# sudo apt-get install python-software-properties
Reading package lists... Done
Building dependency tree       
Reading state information... Done
The following packages will be upgraded:
1 upgraded, 0 newly installed, 0 to remove and 370 not upgraded.
Need to get 23.5 kB of archives.
After this operation, 0 B of additional disk space will be used.
Get:1 precise-updates/main python-software-properties all [23.5 kB]
Fetched 23.5 kB in 0s (104 kB/s)                      
(Reading database ... 177156 files and directories currently installed.)
Preparing to replace python-software-properties (using .../python-software-properties_0.82.7.7_all.deb) ...
Unpacking replacement python-software-properties ...
Processing triggers for man-db ...
Setting up python-software-properties ( ...
root@buttercup:~# sudo apt-key adv --recv-keys --keyserver hkp:// 0xcbcb082a1bb943db
Executing: gpg --ignore-time-conflict --no-options --no-default-keyring --secret-keyring /tmp/tmp.a1Ik7tcUIy --trustdb-name /etc/apt/trustdb.gpg --keyring /etc/apt/trusted.gpg --primary-keyring /etc/apt/trusted.gpg --recv-keys --keyserver hkp:// 0xcbcb082a1bb943db
gpg: requesting key 1BB943DB from hkp server
gpg: key 1BB943DB: public key "MariaDB Package Signing Key " imported
gpg: no ultimately trusted keys found
gpg: Total number processed: 1
gpg:               imported: 1
root@buttercup:~# sudo add-apt-repository 'deb precise main'
root@buttercup:~# sudo apt-get update
Hit stable Release.gpg
Hit newrelic Release.gpg                                                                                                                                 
Hit stable Release                                                                                                                                          
Hit precise Release.gpg                                                                                                                             
Get:1 precise-updates Release.gpg [198 B]                                                                                                           
Hit precise-backports Release.gpg                                                                                                                   
Get:2 precise-security Release.gpg [198 B]                                                                                              
Hit newrelic Release                                                                                                                             
Get:3 precise Release.gpg [198 B]                                                                                          
Hit stable/main amd64 Packages                                                                                                                 
Hit precise Release                                                                                                                    
Get:4 precise-updates Release [98.7 kB]                                                                                                             
Get:5 precise-security Release [50.7 kB]                                                                                                              
Hit newrelic/non-free amd64 Packages                                                                                                                     
Hit stable/main i386 Packages                                                                                                                              
Hit precise Release.gpg                                                                                                                                
Get:6 precise Release [2,261 B]                                                                                                              
Ign stable/main TranslationIndex                                                                                                                            
Hit precise Release.gpg                                                                                                                                 
Hit newrelic/non-free i386 Packages                                                                                                                      
Ign newrelic/non-free TranslationIndex                                                                                                                   
Get:7 precise/main Sources [997 B]                                                                                                            
Hit precise Release                                                                                                                                     
Get:8 precise/main amd64 Packages [5,718 B]                                                                                                   
Get:9 precise/main i386 Packages [5,712 B]                                                                                                    
Hit precise Release                                                                                                                                     
Ign precise/main TranslationIndex                                                                                
Get:10 precise-security/main Sources [111 kB]                                                                         
Hit precise-backports Release                                                                                                                      
Hit precise/main Sources                                                                                                                                
Hit precise/main Sources                                                                                                                      
Hit precise/main Sources                                                                                            
Hit precise/restricted Sources                                                                                                            
Hit precise/universe Sources                                                                                                              
Hit precise/multiverse Sources                                                                                                            
Hit precise/main amd64 Packages                                                                                                           
Hit precise/restricted amd64 Packages                                                                                                     
Hit precise/universe amd64 Packages                                                                                 
Hit precise/multiverse amd64 Packages                                                                                                     
Hit precise/main i386 Packages                                                                                                            
Hit precise/restricted i386 Packages                                                                                
Hit precise/universe i386 Packages                                                                                  
Hit precise/multiverse i386 Packages                                                                                                      
Hit precise/main TranslationIndex                                                                                                         
Hit precise/multiverse TranslationIndex                                                                                                   
Hit precise/restricted TranslationIndex                                                                                                   
Hit precise/main amd64 Packages                                                                                                               
Ign stable/main Translation-en_US                                                                                                                 
Hit precise/main i386 Packages                                                                                                                
Ign precise/main TranslationIndex                                                                                       
Hit precise/main amd64 Packages                                                                                         
Hit precise/main i386 Packages                                                                                                                
Hit precise/main TranslationIndex                                                                                                             
Ign stable/main Translation-en                                                                                                                    
Hit precise/universe TranslationIndex                                                                               
Get:11 precise-updates/main Sources [479 kB]                                                                        
Ign newrelic/non-free Translation-en_US                                                                                                        
Hit precise/main Translation-en                                                                                                               
Ign newrelic/non-free Translation-en                                                                                     
Get:12 precise-security/restricted Sources [2,494 B]                                            
Get:13 precise-security/universe Sources [32.7 kB]                                    
Get:14 precise-security/multiverse Sources [1,785 B]                                                        
Get:15 precise-security/main amd64 Packages [426 kB]                                
Ign precise/main Translation-en_US                                                                
Ign precise/main Translation-en                                            
Get:16 precise-updates/restricted Sources [8,056 B]         
Get:17 precise-updates/universe Sources [110 kB]                                    
Get:18 precise-updates/multiverse Sources [8,886 B]                                
Get:19 precise-updates/main amd64 Packages [837 kB]                              
Get:20 precise-security/restricted amd64 Packages [4,627 B]                           
Get:21 precise-security/universe amd64 Packages [98.1 kB]                               
Get:22 precise-security/multiverse amd64 Packages [2,447 B]                             
Get:23 precise-security/main i386 Packages [458 kB]                                      
Ign precise/main Translation-en_US                                                      
Get:24 precise-security/restricted i386 Packages [4,620 B]    
Get:25 precise-security/universe i386 Packages [104 kB]                             
Get:26 precise-updates/restricted amd64 Packages [13.7 kB]                        
Get:27 precise-updates/universe amd64 Packages [248 kB]                            
Ign precise/main Translation-en                                                        
Get:28 precise-security/multiverse i386 Packages [2,638 B]                           
Hit precise-security/main TranslationIndex                         
Hit precise-security/multiverse TranslationIndex
Hit precise-security/restricted TranslationIndex           
Hit precise-security/universe TranslationIndex             
Get:29 precise-updates/multiverse amd64 Packages [15.3 kB]
Get:30 precise-updates/main i386 Packages [868 kB]     
Hit precise-security/main Translation-en              
Hit precise-security/multiverse Translation-en        
Hit precise-security/restricted Translation-en
Hit precise-security/universe Translation-en          
Get:31 precise-updates/restricted i386 Packages [13.7 kB]
Get:32 precise-updates/universe i386 Packages [255 kB]
Get:33 precise-updates/multiverse i386 Packages [15.5 kB]
Hit precise-updates/main TranslationIndex
Hit precise-updates/multiverse TranslationIndex
Hit precise-updates/restricted TranslationIndex
Hit precise-updates/universe TranslationIndex
Hit precise-backports/main Sources
Hit precise-backports/restricted Sources
Hit precise-backports/universe Sources
Hit precise-backports/multiverse Sources
Hit precise-backports/main amd64 Packages
Hit precise-backports/restricted amd64 Packages
Hit precise-backports/universe amd64 Packages
Hit precise-backports/multiverse amd64 Packages
Hit precise-backports/main i386 Packages
Hit precise-backports/restricted i386 Packages
Hit precise-backports/universe i386 Packages
Hit precise-backports/multiverse i386 Packages
Hit precise-backports/main TranslationIndex
Hit precise-backports/multiverse TranslationIndex
Hit precise-backports/restricted TranslationIndex
Hit precise-backports/universe TranslationIndex
Hit precise/main Translation-en
Hit precise/multiverse Translation-en
Hit precise/restricted Translation-en
Hit precise/universe Translation-en
Hit precise-updates/main Translation-en
Hit precise-updates/multiverse Translation-en
Hit precise-updates/restricted Translation-en
Hit precise-updates/universe Translation-en
Hit precise-backports/main Translation-en
Hit precise-backports/multiverse Translation-en
Hit precise-backports/restricted Translation-en
Hit precise-backports/universe Translation-en
Fetched 4,284 kB in 3s (1,380 kB/s)
Reading package lists... Done
root@buttercup:~# sudo apt-get install mariadb-server
Reading package lists... Done
Building dependency tree       
Reading state information... Done
The following extra packages will be installed:
  libaio1 libdbd-mysql-perl libdbi-perl libhtml-template-perl libmariadbclient18 libmysqlclient18 libnet-daemon-perl libplrpc-perl libreadline5 mariadb-client-10.0
  mariadb-client-core-10.0 mariadb-common mariadb-server-10.0 mariadb-server-core-10.0 mysql-common
Suggested packages:
  libipc-sharedcache-perl libterm-readkey-perl tinyca mailx mariadb-test
The following NEW packages will be installed:
  libaio1 libdbd-mysql-perl libdbi-perl libhtml-template-perl libmariadbclient18 libmysqlclient18 libnet-daemon-perl libplrpc-perl libreadline5 mariadb-client-10.0
  mariadb-client-core-10.0 mariadb-common mariadb-server mariadb-server-10.0 mariadb-server-core-10.0 mysql-common
0 upgraded, 16 newly installed, 0 to remove and 370 not upgraded.
Need to get 36.3 MB of archives.
After this operation, 125 MB of additional disk space will be used.
Do you want to continue [Y/n]? Y
Get:1 precise/main libaio1 amd64 0.3.109-2ubuntu1 [6,396 B]
Get:2 precise/main libreadline5 amd64 5.2-11 [128 kB]
Get:3 precise/main mysql-common all 10.0.14+maria-1~precise [8,828 B]
Get:4 precise/main mariadb-common all 10.0.14+maria-1~precise [3,300 B]
Get:5 precise/main libmariadbclient18 amd64 10.0.14+maria-1~precise [919 kB]
Get:6 precise/main libnet-daemon-perl all 0.48-1 [43.1 kB]
Get:7 precise/main libplrpc-perl all 0.2020-2 [36.0 kB]
Get:8 precise/main libdbi-perl amd64 1.616-1build2 [849 kB]
Get:9 precise/main libmysqlclient18 amd64 10.0.14+maria-1~precise [2,958 B]
Get:10 precise/main mariadb-client-core-10.0 amd64 10.0.14+maria-1~precise [1,820 kB]
Get:11 precise/main libdbd-mysql-perl amd64 4.020-1build2 [106 kB]
Get:12 precise/main libhtml-template-perl all 2.10-1 [65.0 kB]
Get:13 precise/main mariadb-client-10.0 amd64 10.0.14+maria-1~precise [5,440 kB]
Get:14 precise/main mariadb-server-core-10.0 amd64 10.0.14+maria-1~precise [5,636 kB]
Get:15 precise/main mariadb-server-10.0 amd64 10.0.14+maria-1~precise [21.2 MB]                                     
Get:16 precise/main mariadb-server all 10.0.14+maria-1~precise [2,998 B]                                            
Fetched 36.3 MB in 16s (2,182 kB/s)                                                                                                                                              
Preconfiguring packages ...
Selecting previously unselected package libaio1.
(Reading database ... 177156 files and directories currently installed.)
Unpacking libaio1 (from .../libaio1_0.3.109-2ubuntu1_amd64.deb) ...
Selecting previously unselected package libreadline5.
Unpacking libreadline5 (from .../libreadline5_5.2-11_amd64.deb) ...
Selecting previously unselected package mysql-common.
Unpacking mysql-common (from .../mysql-common_10.0.14+maria-1~precise_all.deb) ...
Selecting previously unselected package mariadb-common.
Unpacking mariadb-common (from .../mariadb-common_10.0.14+maria-1~precise_all.deb) ...
Selecting previously unselected package libnet-daemon-perl.
Unpacking libnet-daemon-perl (from .../libnet-daemon-perl_0.48-1_all.deb) ...
Selecting previously unselected package libplrpc-perl.
Unpacking libplrpc-perl (from .../libplrpc-perl_0.2020-2_all.deb) ...
Selecting previously unselected package libdbi-perl.
Unpacking libdbi-perl (from .../libdbi-perl_1.616-1build2_amd64.deb) ...
Selecting previously unselected package libmariadbclient18.
Unpacking libmariadbclient18 (from .../libmariadbclient18_10.0.14+maria-1~precise_amd64.deb) ...
Selecting previously unselected package libmysqlclient18.
Unpacking libmysqlclient18 (from .../libmysqlclient18_10.0.14+maria-1~precise_amd64.deb) ...
Selecting previously unselected package libdbd-mysql-perl.
Unpacking libdbd-mysql-perl (from .../libdbd-mysql-perl_4.020-1build2_amd64.deb) ...
Selecting previously unselected package mariadb-client-core-10.0.
Unpacking mariadb-client-core-10.0 (from .../mariadb-client-core-10.0_10.0.14+maria-1~precise_amd64.deb) ...
Selecting previously unselected package mariadb-client-10.0.
Unpacking mariadb-client-10.0 (from .../mariadb-client-10.0_10.0.14+maria-1~precise_amd64.deb) ...
Selecting previously unselected package mariadb-server-core-10.0.
Unpacking mariadb-server-core-10.0 (from .../mariadb-server-core-10.0_10.0.14+maria-1~precise_amd64.deb) ...
Processing triggers for man-db ...
Setting up mysql-common (10.0.14+maria-1~precise) ...

Configuration file `/etc/mysql/my.cnf'
 ==> Modified (by you or by a script) since installation.
 ==> Package distributor has shipped an updated version.
   What would you like to do about it ?  Your options are:
    Y or I  : install the package maintainer's version
    N or O  : keep your currently-installed version
      D     : show the differences between the versions
      Z     : start a shell to examine the situation
 The default action is to keep your current version.
*** my.cnf (Y/I/N/O/D/Z) [default=N] ? Y
Installing new version of config file /etc/mysql/my.cnf ...
Setting up mariadb-common (10.0.14+maria-1~precise) ...
Selecting previously unselected package mariadb-server-10.0.
(Reading database ... 177540 files and directories currently installed.)
Unpacking mariadb-server-10.0 (from .../mariadb-server-10.0_10.0.14+maria-1~precise_amd64.deb) ...
Selecting previously unselected package libhtml-template-perl.
Unpacking libhtml-template-perl (from .../libhtml-template-perl_2.10-1_all.deb) ...
Selecting previously unselected package mariadb-server.
Unpacking mariadb-server (from .../mariadb-server_10.0.14+maria-1~precise_all.deb) ...
Processing triggers for ureadahead ...
Processing triggers for man-db ...
Setting up libaio1 (0.3.109-2ubuntu1) ...
Setting up libreadline5 (5.2-11) ...
Setting up libnet-daemon-perl (0.48-1) ...
Setting up libplrpc-perl (0.2020-2) ...
Setting up libdbi-perl (1.616-1build2) ...
Setting up libhtml-template-perl (2.10-1) ...
Setting up libmysqlclient18 (10.0.14+maria-1~precise) ...
Setting up libdbd-mysql-perl (4.020-1build2) ...
Setting up libmariadbclient18 (10.0.14+maria-1~precise) ...
Setting up mariadb-client-core-10.0 (10.0.14+maria-1~precise) ...
Setting up mariadb-client-10.0 (10.0.14+maria-1~precise) ...
Setting up mariadb-server-core-10.0 (10.0.14+maria-1~precise) ...
Setting up mariadb-server-10.0 (10.0.14+maria-1~precise) ...
Installing new version of config file /etc/logrotate.d/mysql-server ...
Installing new version of config file /etc/mysql/debian-start ...
Installing new version of config file /etc/apparmor.d/usr.sbin.mysqld ...
 * Stopping MariaDB database server mysqld                                                                                                                                 [ OK ] 
141003 18:06:32 [Note] InnoDB: Using mutexes to ref count buffer pool pages
141003 18:06:32 [Note] InnoDB: The InnoDB memory heap is disabled
141003 18:06:32 [Note] InnoDB: Mutexes and rw_locks use GCC atomic builtins
141003 18:06:32 [Note] InnoDB: Memory barrier is not used
141003 18:06:32 [Note] InnoDB: Compressed tables use zlib
141003 18:06:32 [Note] InnoDB: Using Linux native AIO
141003 18:06:32 [Note] InnoDB: Using CPU crc32 instructions
141003 18:06:32 [Note] InnoDB: Initializing buffer pool, size = 256.0M
141003 18:06:32 [Note] InnoDB: Completed initialization of buffer pool
141003 18:06:32 [Note] InnoDB: Highest supported file format is Barracuda.
141003 18:06:33 [Note] InnoDB: 128 rollback segment(s) are active.
141003 18:06:33 [Note] InnoDB: Waiting for purge to start
141003 18:06:33 [Note] InnoDB:  Percona XtraDB ( 5.6.20-68.0 started; log sequence number 72018642640
141003 18:06:33 [Note] Plugin 'FEEDBACK' is disabled.
141003 18:06:33 [Note] InnoDB: FTS optimize thread exiting.
141003 18:06:33 [Note] InnoDB: Starting shutdown...
141003 18:06:35 [Note] InnoDB: Shutdown completed; log sequence number 72018647790
 * Starting MariaDB database server mysqld                                                                                                                                 [ OK ] 
 * Checking for corrupt, not cleanly closed and upgrade needing tables.
Setting up mariadb-server (10.0.14+maria-1~precise) ...
Processing triggers for libc-bin ...
ldconfig deferred processing now taking place
root@buttercup:~# service mysql start
mysql start/running, process 12179
root@buttercup:~# mysql -p
Enter password: 
Welcome to the MariaDB monitor.  Commands end with ; or \g.
Your MariaDB connection id is 19
Server version: 10.0.14-MariaDB-1~precise-log binary distribution

Copyright (c) 2000, 2014, Oracle, SkySQL Ab and others.

Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.

MariaDB [(none)]> show databases;
| Database           |
| information_schema |
| mysql              |
| performance_schema |
| xxx_backend     |
| xxx_yy          |
| test               |
6 rows in set (0.00 sec)

MariaDB [(none)]> quit
root@buttercup:~# mysql_upgrade -p
Enter password: 
Phase 1/4: Checking mysql database
Processing databases
mysql.column_stats                                 OK
mysql.columns_priv                                 OK
mysql.db                                           OK
mysql.event                                        OK
mysql.func                                         OK
mysql.gtid_slave_pos                               OK
mysql.help_category                                OK
mysql.help_keyword                                 OK
mysql.help_relation                                OK
mysql.help_topic                                   OK                                         OK
mysql.index_stats                                  OK
mysql.innodb_index_stats                           OK
mysql.innodb_table_stats                           OK
mysql.ndb_binlog_index                             OK
mysql.plugin                                       OK
mysql.proc                                         OK
mysql.procs_priv                                   OK
mysql.proxies_priv                                 OK
mysql.roles_mapping                                OK
mysql.servers                                      OK
mysql.table_stats                                  OK
mysql.tables_priv                                  OK
mysql.time_zone                                    OK
mysql.time_zone_leap_second                        OK
mysql.time_zone_name                               OK
mysql.time_zone_transition                         OK
mysql.time_zone_transition_type                    OK
mysql.user                                         OK
Phase 2/4: Running 'mysql_fix_privilege_tables'...
Phase 3/4: Fixing table and database names
Phase 4/4: Checking and upgrading tables
Processing databases
xxx_backend.addon                               OK
xxx_backend.addon_package                       OK

... (LOTS more output removed) ...

Slow rsnapshot/rdiff-backup/rbackup/rsync backups?

Our server started to crawl under a very normal workload.  Grinding away with loads as high as 40 (yes, forty).  I finally ejected and restarted daemons, killed processes, and even rebooted the server.  I’d imagine you’ve been in situations like this before!  Maybe you’re in one like it right now.

In situations like this, there are two main components to resolving the issue: 1. Determining what the problem is, and 2. Doing something about it.

The Problem

For me, the culprit this time was the rsnapshot backup tool.  It’s essentially a script that works with cron and rsync/cp/rm to create a rotating set of backups using hard links to minimize resource consumption.  Unfortunately, as it turns out, rsnapshot was completely hammering our server, causing the system to go spiraling into a cyclical high-load-of-doom state that it never really recovered from.  Even the 60 minute window between hourly backups wasn’t enough time for the system to recover.

Specifically, the problem with rsnapshot isn’t that it hogs the CPU; rather, it’s disk-bound.  There’s so much IO taking place that everything screeches to a halt because the system can’t even read from or write to the disk.

The Solution

You might try using nice on your cron job, only to find that it doesn’t help. After that, you might try updating your rsnapshot.conf to include nice before the rsync/rm/cp commands. You might even try hacking the perl source to rsnapshot to insert your nice directly.

Let me save you some effort. Using nice alone won’t help, because we’re talking about IO here, not processor cycles. Also, updating rsnapshot.conf won’t help, because rsnapshot won’t allow you to use nice -n19 /usr/bin/rsync as your cmd_rsync.

What you really need to do is to create intermediate scripts that enforce the nice (CPU) and ionice (IO) restrictions on the commands. You need three new files. Create them as root in the location specified (both optional) and set them as world-executable:


/usr/bin/ionice -c3 /bin/nice -n19 /usr/bin/rsync $*


/usr/bin/ionice -c3 /bin/nice -n19 /bin/rm $*


/usr/bin/ionice -c3 /bin/nice -n19 /bin/cp $*

Then, simply update your /etc/rsnapshot.conf file to point to these commands instead of the standard ones:


# LINUX USERS: Be sure to uncomment "cmd_cp". This gives you extra features.
# EVERYONE ELSE: Leave "cmd_cp" commented out for compatibility.
# See the README file or the man page for more details.
#cmd_cp /bin/cp
cmd_cp /usr/local/bin/cp-nice

# uncomment this to use the rm program instead of the built-in perl routine.
#cmd_rm /bin/rm
cmd_rm /usr/local/bin/rm-nice

# rsync must be enabled for anything to work. This is the only command that
# must be enabled.
#cmd_rsync /usr/bin/rsync
cmd_rsync /usr/local/bin/rsync-nice

If your experience is anything like mine (remember, we had loads spiking to 40), your backups will complete faster, your loads will remain low, and your system will be responsive again. Yay, ionice!

(Hat tip to David Cantrell)

Convert hourly wage to salary, and other easy mental calculations

I’m surprised more people don’t know these quick, easy brain hacks!

To convert hourly wage to annual salary, multiply by 2 and add 3 zeros. ($15/hr = ~$30,000/year)
To convert annual salary to hourly wage, divide by 2 and remove 3 zeros. ($30,000/year = ~$15/hr)

To find the return of an investment in the US stock market over a period adjusted for inflation and including taxes:

  • For one year, add 3%. ($1000 one year later = ~$1030)
  • For three years, add 10% ($1000 three years later = ~$1100)
  • For five years, add 15% ($1000 five years later = ~$1150)
  • For ten years, add 30% ($1000 ten years later = ~$1300)

(Assuming 9% interest compounded yearly, a 30% tax rate, and a 3% inflation rate)

Got any more simple mental calculations or conversions?  Let me know in the comments!

Disable WordPress’ KSES to prevent HTML filtering

WordPress has a healthy bit of functionality that filters out dangerous HTML tags from posts and comments. The super-helpful recursive acronym sheds a bit of light on what KSES filtering does – KSES Stops Evil Scripts.

This is all fine and dandy until you decide that you don’t want WordPress to perform this filtering. Perhaps you’re in a controlled environment, or in our case, doing a deep integration between two systems.

None of this is really a problem until you hit up Google and find some pretty solid misinformation. The first hit (right now, for me, at least) states that KSES is not the problem:

And this isn’t really a problem (who trusts this hippie with long hair, anyway?) until you realize that Matt Mullenweg’s name looks familiar because, uhh, he practically invented WordPress.

But then you catch a glimmer of hope – you see the text, “Posted 8 years ago”.  Eight years?! Hmm… Perchance this information is a bit outdated?

The sole reason I am writing this post is in the hopes that it can unseat the current dictator for Google searches for “disable kses”.  If my coup is successful, developers everywhere might be able to spend less time being burned by WordPress’ idiosyncracies (kses, wpautop, WP magic quotes, etc) and more time playing with puppies.

The problem

Yes.  KSES does apply to comments and posts.  Copied straight from the source:

function kses_init_filters() {
	// Normal filtering
	add_filter('title_save_pre', 'wp_filter_kses');

	// Comment filtering
	if ( current_user_can( 'unfiltered_html' ) )
		add_filter( 'pre_comment_content', 'wp_filter_post_kses' );
		add_filter( 'pre_comment_content', 'wp_filter_kses' );

	// Post filtering
	add_filter('content_save_pre', 'wp_filter_post_kses');
	add_filter('excerpt_save_pre', 'wp_filter_post_kses');
	add_filter('content_filtered_save_pre', 'wp_filter_post_kses');

See those bits about “titles”, “comments”, “excerpts”, and “content”? Yes, all of these things are affected by our nasty nemesis, KSES, or, if you’d like to use its full name, kses_init_filters().

The solution

Rejoice! There is a solution!


Yup. That’s it. Srsly. If you want to be nice and restore KSES once you’re done doing your sneakybusiness, you can just call kses_init_filters() to restore the filters again.

So, to make this super clear:

//A sad place

//Puppies!  Happily create/update posts without WordPress munging your HTML.

//Back to the sad place

Have fun with the puppies!

Safe Driving and Coupons Website

Just a bit of a plug here for you to check out a site that I’ve been working on for a client. It’s called Collision Guard, and it’s a safe driving and auto discount website. I joined the team after the site had been live for a few months on a feverishly hacked together infrastructure of very repetitive and inefficient PHP and jQuery. This was back in late 2010; I’ve been working on the site ever since.

Since joining the team, I’ve pretty much rewritten the site from scratch. Some notable aspects of the setup:

  • Fast cached geolocation via Maxmind’s API
  • Extensive usage of RedBean (a PHP ORM; very nice, but definitely not perfect)
  • A custom templating system
  • Seamless integration with WordPress
  • Custom statistics tracking
  • Custom bulk emailing with tracking
  • Some fairly fancy backend jQuery interfaces (those in the automotive industry are not very tech savvy)
  • etc.

Anyway, it’s been a fun site to work on, and Brian and the gang have been super team members.  Make sure to check out the site, learn about texting while driving, download some oil change coupons, and let me know what you think. 🙂

Facebook Graph API – Upload Photos – “Requires upload file”

Quick post here since I see a lot of questions about this out there.

If you’re trying to upload photos via Facebook’s Graph API and you’re getting an OAuthException with a message of “(#324) Requires upload file”, I can help you out.

Something seems to have changed with facebook.php recently – if you’re going to upload files, you have to explicitly set fileUpload to be true in the API. In my setup code, I just add a line as demonstrated below:

// Create our Application instance.
$facebook = new Facebook(array(
'appId' => $fbconfig['appid'],
'secret' => $fbconfig['secret'],
'cookie' => true,
'fileUpload' => true,

Alternatively, if you’ve already set up your $facebook object, you can call:

Happy coding!

Slow Excel Spreadsheet? Try this.

(2016 update – Lots of great recommendations in the comments.  Check them out!)

There are a number of things that can cause an Excel spreadsheet to slow down. Sometimes, the spreadsheet can become unusable, requiring up to a minute for saving or even the most basic of changes. Here’s a brief checklist of the most frequent causes of Excel slowdowns.

(Have a spreadsheet slow-down that I haven’t described below? Let me know in the comments! Thanks! 🙂 -Rich)

  • Network problems. If the spreadsheet is accessed over the network (local or remote), network issues can delay saving.
  • Macros/VBA code. If you are using macros (or Visual Basic for Applications), make sure you don’t have unnecessary macros running, or macros that perform unnecessary calculations.
  • Burdensome animation. Try disabling animation. 2003: Tools > Options > Edit > Turn off “Provide feedback with animation”. 2007: Excel Button > Excel Options > Advanced > General > Provide feedback with animation (uncheck)
  • Complicated calculations. If you’re doing lots of calculations, you can disable auto-updating of these calculations. When you do so, your spreadsheet will not update until you explicitly desire (e.g. when you hit the F9 key). To disable auto-updating in 2007, go to the Excel Button > Excel Options > Formulas > Workbook Calculation, and select “Manual”.
  • Duplicate Conditional Formatting Rules. Conditional formatting can be a processor-intensive task if your rules aren’t set up right. Manage your conditional formatting rules (2007) via the ribbon at Home > Conditional Formatting > Manage Rules… Try to consolidate similar rules into one rule (e.g. a rule for an entire column instead of a rule for each cell in the column)
  • Funky Formatting. Formatting can really slow down a spreadsheet, especially on slower machines. Try removing all formatting: Removing All Formatting.
  • Unnecessary junk. Sometimes, an Excel file can become backlogged with a bunch of unnecessary junk. Try saving as a CSV (comma-separated) file, which will strip out everything except for the data. (Make sure to not save over your original file in case this workaround does not, well, work! 🙂 )
  • Unknown, but it seems to help sometimes. Install the Lookup Wizard add-in.
  • Other issues. Do you know of another issue that causes Excel to slow down? Let me know in the comments!

Assorted helpful links:

Drupal(jQuery UI + Devel): $.widget is not a function

jQuery whines incessantly


Real helpful error. I’ve verified that $.widget() is a function and has been included. So, why am I getting this error? (In fact, now that I think of it, Javascript/jQuery has the most obtuse and misleading error messages of any language I have ever programmed in. However, it’s also one of the most ubiquitous languages as well. Interesting.)

Enough meta whining; what’s the problem?

Drupal developers love jQuery, and hence the jquery_ui module. They also love the Devel module. Unsurprisingly, the developers of the Devel module love jQuery UI as well, and have included portions of the UI API directly within the Devel module. This works nicely until you decide that you love the jQuery UI, and install jquery_ui. When you call jquery_ui_add(array(…)) from your code, if you include any files that the Devel module has already included (an outdated version thereof, I might add), then you’ve got two (nearly) identical files of included code that clash brilliantly.

And hence the lovely error, “$.widget is not a function”. Wouldn’t “$.widget is already defined” make a bit more sense?

Fix it, fix it, fix it!

Fortunately, there are many ways to fix this error.

  • Write a patch/Get the authors of the Devel module to add the jQuery UI module as a dependency (and remove the direct jQuery UI includes from the module). Easily the best, but most time-consuming solution.
  • Write a patch/Get the authors of the jQuery UI module to check if a given jQuery UI file has already been added via drupal_add_js(). If it has been, don’t include the file again. Might still cause conflicts because of differing versions
  • Hack the Devel module:
    • Enable the jQuery UI module, and remove the code from the Devel module that includes the jQuery UI files local to the Devel module
    • Replace the jQuery UI files in the Devel module with the same files from your jQuery UI installation. Then, in your code, only include the files that the Devel module uses (ui.draggable.js and ui.mouse.js currently) if the Devel module is disabled. This solution takes a bit of effort but might be the quickest workaround.
  • etc (I’m sure there are many more options)

Personally, I’m using the last option. The code I’m using to detect whether or not the Devel module is enabled (and act accordingly) is:

		jquery_ui_add(array('ui.draggable', 'ui.datepicker'));

Happy drupaling!

Thanks to Wei Wang, who tipped me off:

Text-version of the error for the Google machine:

$.widget is not a function
Line 391


After writing up this post, I realized that the first option is really not that tough. (Note that if you follow these steps, you’ll have to repeat them every time you update the Devel module.) Add the following line to the Devel Themer module’s

dependencies[] = jquery_ui

Now, find the ‘devel_themer_init()’ function in devel_themer.module, and comment out the following lines (104 and 105 for the current version):

    drupal_add_js($path .'/ui.mouse.js');
    drupal_add_js($path .'/ui.draggable.js');

Immediately following the newly commented out lines, insert the following:

	jquery_ui_add(array('ui.draggable', 'ui.mouse'));

You’re done! Booyah.

Removing symbolic links to directories

Having trouble removing a symlink from your POSIX compliant (Linux/Unix/OSX/MyDogSamix) system?  A quick Google yields some interesting results, which may or may not be helpful.

Most likely, you’ll find a bunch of condescending links highlighting the fact that you can just ‘rm <symlink>’ the symbolic link.  Silly newb. However, if this is a directory, you might have problems.

The most important thing to remember is that to remove a symlink that points to a directory, you must not include the trailing slash.

In other words:

[fdev@warproof sites]$ ls ../sites/
all  default  sites
[fdev@warproof sites]$ rm sites/
rm: cannot remove `sites/': Not a directory
[fdev@warproof sites]$ rm sites
[fdev@warproof sites]$ ls
all  default

Notice that the first attempt (‘rm sites/’) failed, while the second attempt (‘rm sites’) did not. YMMV, but in this case, I blame my autocompletion (aka tab completion) – it automatically adds the trailing slash. Remove that slash, and you’ll remove the symlink.

May all your deletions be error-free.