Installing PHP7 on FreeBSD 10

Specifically, at time of writing, it’s PHP 7.0.3 on FreeBSD 10.1. Note that I would expect PHP7 to be officially available in FreeBSD and would hope that these instructions become redundant fast. Check for this with:

pkg search php70

At time of writing, the port we’re looking at is in development on Github here and it was announced on the FreeBSD ports mailing list here.

As you may gather from the above, PHP7 is available via ports only, not pkgng as yet. To install, proceed as follows:

portsnap fetch
cd /usr/ports
git clone https://github.com/miwi-fbsd/miwi-ports.git git-ports-php7
cd git-ports-php7
rsync -av ./* ../
portsnap fetch extract

Now remove your existing php:

pkg info | grep php
pkg remove ... ... ...

And install php70:

cd /usr/ports/lang/php70
make
make install

Follow this by installing any other PHP extensions you require. Note that in /usr/ports/Mk/bsd.php.mk I had to add the following at line 283 for database/php70-pdo_mysql to install:

_USE_PHP_VER70= ${_USE_PHP_ALL} phar sqlite3

Also note that Apache 2.4 is required. But who’s using 2.2 these days? Right..?

Migrate Helpdesk from Cerberus 5 to Zendesk

After seven years of using Cerberus as our helpdesk system at INEX, we decided it was time to upgrade / move on. Following a fairly exhaustive (and painful!) search, we settled on Zendesk as having the right mix of features:

  • agent collision detection
  • a very nice API with an official PHP client supporting composer
  • a familiar workflow to what we were used to
  • enough configurable settings to make it do what we wanted without having to wade through a kitchen sink of options
  • mobile apps for both iOS and Android

The first hurdle was migrating all the existing tickets from Cerberus to Zendesk. There’s a number of ways we could have gone about this but the Cerberus schema was fairly intuitive and Laraval makes bootstrapping an application with database access really easy. As such, we simply iterated over the tickets in the Cerberus database and imported them into Zendesk (with attachments and by creating organisations and users on the fly).

See the code on GitHub at inex/cerb5-to-zendesk.

Glendalough, Co. Wicklow

Creative Commons License
Glendalough Photos 20150209 by Barry O’Donovan is licensed under a Creative Commons Attribution 4.0 International License.

Doctrine2 Provider for Laravel 5 with Authentication Support

About a year ago, I released a Doctrine2 provider for Laravel 4. We’ve just updated this as a new package for Laravel 5.  Full details can be seen in the project’s README.md.

This package creates four bindings into Laravel’s IoC:

  • Doctrine\ORM\EntityManagerInterface (which is an instance of Doctrine\ORM\EntityManager), also available via the D2EM facade;
  • Doctrine\Common\Cache\Cache (which is an instance of the appropriate cache provider), also available via the D2Cache facade;
  • Doctrine\ORM\Mapping\ClassMetadataFactory (used in this package by the console generator commands); and
  • the Doctrine2Bridge\Support\Repository helper object which used by the D2R facade to instantiate repositories such as D2R::r( 'User' ).

An example of using the D2Cache and D2EM

D2Cache::save( $key, $value );
D2Cache::fetch( $key );

$object = new Entities\Object;
D2EM::persist( $object );
D2EM::flush();

It includes support for Laravel’s authentication system by way of a Doctrine2 based user provider with some example classes. Simply put – this allows a Doctrine2 database table storing users’ usernames and passwords to be used as the backend for Laravel 5 authentication.

Full documentation of the authentication with examples can be found here.

Available on Packagist and forkable on GitHub.

Debugging NFS Slowness

During patching for the recent GHOST bug, I updated all packages (including kernel) on a Ubuntu 14.04 file server (filer). This filer provided static content (mainly tens of thousands of images) to a number of web servers. You can see the effect in the following load graph from the filer:

Load average on the filer
Load average on the filer

You may notice from the above, that there were actually two issues. The first was solved by upgrading the filer from 14.04 to 14.10 based on a number of online references to symptoms and fixes. About an hour after this upgrade, a new form of NFS slowness manifested and, needless to say, sites that rendered in <1sec were now taking >15secs.

Diagnosing the second issue took a while longer but some tips and utilities include:

  • check /var/log and see if any log files are increasing rapidly;
  • check top and check any processes with high / unusual utilisation;
  • use iostat (apt-get install sysstat) and pay particular attention to any devices with high volumes of transactions per second. In my case it was the root filesystem rather than any of the mounted partitions exported by NFS.
  • use iotop (apt-get install iotop) and note any processes with high utilisation (in my case jbd2/xvda1-8 was at 100% and xvda1-8 is my root partition)

The jbd2 process is the ext4 journaling process. At this point you can evaluate fsck’ing your partition but I wanted to see if I could discover what was happening here. I enabled some debugging via:

# enable tracing:
echo 1 > /sys/kernel/debug/tracing/events/ext4/ext4_sync_file_enter/enable
# wait a couple of seconds and:
cat /sys/kernel/debug/tracing/trace
# and disable tracing:
echo 0 > /sys/kernel/debug/tracing/events/ext4/ext4_sync_file_enter/enable

What I found were lots of:

nfsd-2085  [001] .... 53730942.155573: ext4_sync_file_enter: dev 202,1 ino 276278 parent 149955 datasync 0
nfsd-2071  [001] .... 53730942.158743: ext4_sync_file_enter: dev 202,1 ino 276278 parent 149955 datasync 0
...

where every entry related to the same inode number (276278). We found this via:

find / -inum 276278
/var/lib/nfs/v4recovery

The solution was to stop nfs_kernal_server, remove that directory entirely, add it back and restart the nfs_kernel_server. We got the permissions wrong on the first attempt but this’ll be obvious from dmesg / kernel log messages such as:

kernel: [53731827.778104] NFSD: Failed to remove expired client state directory 8d97cccceb37641d3804a84683a9282a
kernel: [53731827.779204] NFSD: failed to write recovery record (err -13); please check that /var/lib/nfs/v4recovery exists and is writeableNFSD: Failed to remove expired client state directory 8d97cccceb37641d3804a84683a9282a

Nagios Plugin to Check Extreme Networks Devices

Over at INEX we’ve embarked on a forklift upgrade of the primary peering LAN using Extreme Networks Summit x670’s and x460’s. As usual, we need to monitor these 24/7 and we have just written a new Extreme Networks chassis monitoring script which should work with most Extreme devices.

It will check and generate alerts on the following items:

  • a warning if the device was recently rebooted;
  • a warning / critical if any found temperature sensors are in a non-normal state;
  • a warning / critical if any found fans are in a non-normal state;
  • a warning / critical if any found PSUs are in a non-normal state (or missing);
  • a warning / critical if the 5 sec CPU utilisation is above set thresholds;
  • a warning / critical if the memory utilisation is above set thresholds.

You’ll find the script in this Github repository: barryo/nagios-plugins.

A some verbose output follows:

./check_chassis_extreme.php -c  -h 10.11.12.13 -v 
 
CPU: 5sec - 4% 
Last reboot: 4007.7666666667 minutes ago 
Uptime: 2.8 days. 
PSU: 1 - presentOK (Serial: 1429W-xxxxx; Source: ac) 
PSU: 2 - presentOK (Serial: 1429W-xxxxx; Source: ac) 
Fan: 101 - OK (4388 RPM) 
Fan: 102 - OK (9273 RPM) 
Fan: 103 - OK (4428 RPM) 
Fan: 104 - OK (9273 RPM) 
Fan: 105 - OK (4551 RPM) 
Fan: 106 - OK (9452 RPM) 
Temp: 39'C 
Over temp alert: NO 
Memory used in slot 1: 29% 
OK - CPU: 5sec - 4%. Uptime: 2.8 days.  PSUs: 1 - presentOK; 
  2 - presentOK;. Overall system power state: redundant power 
  available. Fans: [101 - OK (4388 RPM)]; [102 - OK (9273 RPM)];
  [103 - OK (4428 RPM)]; [104 - OK (9273 RPM)]; [105 - OK (4551 
  RPM)]; [106 - OK (9452 RPM)];. Temp: 39'C. 
  Memory (slot:usage%): 1:29%.

OS X Built-in tftp Server

Turned out to be very useful during a recent RMA maintenance window:

sudo launchctl load -F /System/Library/LaunchDaemons/tftp.plist
sudo launchctl start com.apple.tftpd

The default tftp file path is /private/tftpboot. [Original source]

You can stop it with:

sudo launchctl unload -F /System/Library/LaunchDaemons/tftp.plist

And, speaking of tftp – there are some interesting projects on GitHub: hooktftp, php-tftpserver and ptftpd.