<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>Matt Brock&#039;s SysAdmin+ Blog &#187; SysAdmin</title>
	<atom:link href="http://blog.mattbrock.co.uk/category/sysadmin/feed/" rel="self" type="application/rss+xml" />
	<link>http://blog.mattbrock.co.uk</link>
	<description>The Writings of a Freelance Infrastructure Consultant</description>
	<lastBuildDate>Thu, 09 May 2013 11:46:43 +0000</lastBuildDate>
	<language>en-US</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.5.1</generator>
		<item>
		<title>New website for my system administration and infrastructure consultancy business</title>
		<link>http://blog.mattbrock.co.uk/2013/05/08/new-website-for-my-system-administration-and-infrastructure-consultancy-business/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=new-website-for-my-system-administration-and-infrastructure-consultancy-business</link>
		<comments>http://blog.mattbrock.co.uk/2013/05/08/new-website-for-my-system-administration-and-infrastructure-consultancy-business/#comments</comments>
		<pubDate>Wed, 08 May 2013 11:23:26 +0000</pubDate>
		<dc:creator>Matt Brock</dc:creator>
				<category><![CDATA[SysAdmin]]></category>
		<category><![CDATA[Technology]]></category>
		<category><![CDATA[Bootstrap]]></category>
		<category><![CDATA[business]]></category>
		<category><![CDATA[consultancy]]></category>
		<category><![CDATA[consultant]]></category>
		<category><![CDATA[CSS]]></category>
		<category><![CDATA[freelance]]></category>
		<category><![CDATA[H5BP]]></category>
		<category><![CDATA[hiring]]></category>
		<category><![CDATA[HTML]]></category>
		<category><![CDATA[HTML5]]></category>
		<category><![CDATA[HTML5 Boilerplate]]></category>
		<category><![CDATA[infrastructure]]></category>
		<category><![CDATA[Initializr]]></category>
		<category><![CDATA[marketing]]></category>
		<category><![CDATA[Matt Brock]]></category>
		<category><![CDATA[mattbrock.co.uk]]></category>
		<category><![CDATA[self employed]]></category>
		<category><![CDATA[site]]></category>
		<category><![CDATA[system administration]]></category>
		<category><![CDATA[system administrator]]></category>
		<category><![CDATA[template]]></category>
		<category><![CDATA[Twitter Bootstrap]]></category>
		<category><![CDATA[website]]></category>
		<category><![CDATA[work]]></category>

		<guid isPermaLink="false">http://blog.mattbrock.co.uk/?p=2325</guid>
		<description><![CDATA[I became a self employed system administrator in 2011 and (touch wood) my freelance infrastructure business has been going fairly well so far. I thought it was about time I built a marketing website for my business, and I wanted to create a simple, professional-looking site without having to spend too much time building it. [...]]]></description>
				<content:encoded><![CDATA[<p>I became a self employed system administrator in 2011 and (touch wood) my freelance infrastructure business has been going fairly well so far. I thought it was about time I built a marketing website for my business, and I wanted to create a simple, professional-looking site without having to spend too much time building it.</p>
<p>After some research I ended up using the excellent <a href="http://www.initializr.com">Initializr</a> to produce a template website built from <a href="http://html5boilerplate.com">HTML5 Boilerplate (H5BP)</a> and <a href="http://twitter.github.io/bootstrap/">Twitter Bootstrap</a>. H5BP provides a solid HTML5 core with optimisations for JavaScript, CSS, Apache, Google Analytics, etc., and Twitter Bootstrap provides a simple but very powerful HTML/CSS layout framework which cleverly handles things like rendering on mobile devices so that you don&#8217;t have to worry about it.</p>
<p>It was very easy to modify the template and build the simple marketing website I wanted. The end result isn&#8217;t the most advanced design ever created, and it&#8217;s instantly recognisable as a Bootstrap site to anyone else who&#8217;s used it, but that&#8217;s OK. I&#8217;m just trying to market my business, not win design awards. I&#8217;d certainly recommend Initializr to anyone else who understands HTML and CSS and wants to get a decent site up and running as quickly as possible.</p>
<p>The end result can be seen at <a href="http://mattbrock.co.uk/">mattbrock.co.uk</a>.</p>
<p>(If you&#8217;re interested in hiring me for sysadmin consultancy work, just <a href="mailto:info@mattbrock.co.uk">email me</a>.)</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.mattbrock.co.uk/2013/05/08/new-website-for-my-system-administration-and-infrastructure-consultancy-business/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Bash script to extract photos from vCard files</title>
		<link>http://blog.mattbrock.co.uk/2013/02/04/bash-script-to-extract-photos-from-vcard-files/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=bash-script-to-extract-photos-from-vcard-files</link>
		<comments>http://blog.mattbrock.co.uk/2013/02/04/bash-script-to-extract-photos-from-vcard-files/#comments</comments>
		<pubDate>Mon, 04 Feb 2013 20:08:33 +0000</pubDate>
		<dc:creator>Matt Brock</dc:creator>
				<category><![CDATA[SysAdmin]]></category>
		<category><![CDATA[base64]]></category>
		<category><![CDATA[Bash]]></category>
		<category><![CDATA[contacts]]></category>
		<category><![CDATA[convert]]></category>
		<category><![CDATA[extract]]></category>
		<category><![CDATA[Homebrew]]></category>
		<category><![CDATA[ImageMagick]]></category>
		<category><![CDATA[photos]]></category>
		<category><![CDATA[script]]></category>
		<category><![CDATA[vCard]]></category>
		<category><![CDATA[VCF]]></category>

		<guid isPermaLink="false">http://blog.mattbrock.co.uk/?p=2261</guid>
		<description><![CDATA[If you ever find yourself wanting to extract the contact photos from vCard/VCF files then this may be the script for you. I know that this works on a vCard export of multiple contacts from the Contacts app in OS X Mountain Lion. It&#8217;s possible you might have to tweak it a bit for vCard [...]]]></description>
				<content:encoded><![CDATA[<p>If you ever find yourself wanting to extract the contact photos from vCard/VCF files then this may be the script for you. I know that this works on a vCard export of multiple contacts from the Contacts app in OS X Mountain Lion. It&#8217;s possible you might have to tweak it a bit for vCard files from other sources. <span id="more-2261"></span> This script also resizes the exported photos to 201&#215;201 pixels. If you want to modify this conversion then just change the &#8220;convert&#8221; line near the bottom accordingly. If you don&#8217;t want to resize the photos then simply delete this line and the bit where it checks for the presence of ImageMagick (or comment these bits out). If you do want to resize the images then you&#8217;ll need to have</p>
<p><a href="http://www.imagemagick.org/script/index.php">ImageMagick</a> installed (&#8220;brew install imagemagick&#8221; if you&#8217;re on a Mac with <a href="http://mxcl.github.com/homebrew/">Homebrew</a> installed, which it really ought to be). You&#8217;ll also need to make sure you have <a href="http://www.fourmilab.ch/webtools/base64/">base64</a> installed, which it probably already will be. If you&#8217;re copying and pasting this script, make sure you replace the ^M near the bottom of the script with a literal ^M (normally you type Ctrl-V then Ctrl-M to get a literal ^M). The script will take the vCard file you specify as input and create a subdirectory called <em>photos</em> containing the photos from your contacts.</p>
<pre class="prettyprint">#!/bin/bash

progname=$(basename $0)
usage="Usage:\t$progname -f vCard_file \n\t$progname -h"

while getopts "f:h" options ; do
  case $options in
    f) vcard_file=$OPTARG ;;
    h) echo -e $usage ; exit ;;
  esac
done

if [ ! "$vcard_file" ] ; then
  echo -e $usage
  exit 1
fi

if [[ ! $(head -1 $vcard_file) =~ "BEGIN:VCARD" ]] ; then
  echo "$vcard_file does not appear to be a vCard file"
  exit 1
fi

if ! which base64 &gt; /dev/null ; then
  echo "base64 is not installed"
  exit 1
fi

if ! which convert &gt; /dev/null ; then
  echo "ImageMagick is not installed"
  echo "Either install it or comment out the ImageMagick stuff"
  exit 1
fi

if [ -d photos ] ; then
  echo "photos directory already exists"
  exit 1
fi

if ! mkdir photos ; then
  echo "Failed to create photos directory"
  exit 1
fi

regex1="^N:"
regex2="^PHOTO;"
regex3=":|;"

echo -ne "Extracting photos"
cat $vcard_file | while read line ; do
  if [[ $line =~ $regex1 ]] ; then
    filename=$(echo $line | awk -F '[:;]' '{printf("%s%s",$3,$2)}' | \
      sed 's/[^a-zA-Z]//g')
    echo -ne "."
    cat /dev/null &gt; photos/$filename.tmp
  elif [[ $line =~ $regex2 ]] ; then
    echo $line | sed 's/PHOTO;ENCODING=b;TYPE=JPEG://' &gt;&gt; photos/$filename.tmp
  elif [[ ! $line =~ $regex3 ]] ; then
    echo $line &gt;&gt; photos/$filename.tmp
  fi
done
echo -ne " done\n"

echo -ne "Removing empty photos..."
find photos -empty -exec rm -f {} +
echo -ne " done\n"

echo -ne "Converting photos"
cd photos
for file in *.tmp ; do
  filename=$(echo $file | awk -F '.' '{print $1}')
  echo -ne "."
  cat $file | tr -d '\n' | tr -d '^M' | base64 -d &gt; $filename.jpg
  convert $filename.jpg -resize 201x201 $filename.jpg
  rm -f $file
done
echo -ne " done\n"</pre>
]]></content:encoded>
			<wfw:commentRss>http://blog.mattbrock.co.uk/2013/02/04/bash-script-to-extract-photos-from-vcard-files/feed/</wfw:commentRss>
		<slash:comments>5</slash:comments>
		</item>
		<item>
		<title>Get a continuously updating display of client IP addresses on a web server using X-Forwarded-For</title>
		<link>http://blog.mattbrock.co.uk/2013/01/19/get-a-continuously-updating-display-of-client-ip-addresses-on-a-web-server-using-x-forwarded-for/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=get-a-continuously-updating-display-of-client-ip-addresses-on-a-web-server-using-x-forwarded-for</link>
		<comments>http://blog.mattbrock.co.uk/2013/01/19/get-a-continuously-updating-display-of-client-ip-addresses-on-a-web-server-using-x-forwarded-for/#comments</comments>
		<pubDate>Sat, 19 Jan 2013 15:34:54 +0000</pubDate>
		<dc:creator>Matt Brock</dc:creator>
				<category><![CDATA[SysAdmin]]></category>
		<category><![CDATA[Bash]]></category>
		<category><![CDATA[client IP addresses]]></category>
		<category><![CDATA[continuously updating]]></category>
		<category><![CDATA[DDoS]]></category>
		<category><![CDATA[DoS]]></category>
		<category><![CDATA[Elastic Load Balancer]]></category>
		<category><![CDATA[ELB]]></category>
		<category><![CDATA[load balancer]]></category>
		<category><![CDATA[netstat]]></category>
		<category><![CDATA[ngrep]]></category>
		<category><![CDATA[watch]]></category>
		<category><![CDATA[web server]]></category>
		<category><![CDATA[X-Forwarded-For]]></category>

		<guid isPermaLink="false">http://blog.mattbrock.co.uk/?p=2223</guid>
		<description><![CDATA[Sometimes it&#8217;s desirable to have a continuously updating display of the IP addresses which are hitting a web server, with an indication of how many times each IP address has made a request. This may be because you suspect a DoS or DDoS attack, or there may appear to be some other odd activity, or [...]]]></description>
				<content:encoded><![CDATA[<p>Sometimes it&#8217;s desirable to have a continuously updating display of the IP addresses which are hitting a web server, with an indication of how many times each IP address has made a request. This may be because you suspect a DoS or DDoS attack, or there may appear to be some other odd activity, or you may simply be curious. If a web server is sitting directly on the Internet then it&#8217;s possible to do this fairly easily with a tool such as netstat. Often, however, a web server is behind an ELB or another type of load balancer, which means that if you try to use netstat then you&#8217;ll just see the load balancer&#8217;s IP address, not the address of the client which made the request. But if your load balancer is passing the X-Forwarded-For header (as it really ought to be) then you can use this header instead of the client IP to get a continuously updating display. <span id="more-2223"></span> First, you&#8217;ll need to make sure the tools</p>
<p><a href="http://ngrep.sourceforge.net">ngrep</a> and <a href="http://en.wikipedia.org/wiki/Watch_(Unix)">watch</a> are installed. Then run the following Bash script (replacing eth0 with the correct interface if it&#8217;s not eth0):</p>
<pre class="prettyprint">#!/bin/bash

ngrep -il -d eth0 -W byline "x-forwarded-for" "port 80" | grep -i \
  x-forwarded-for | awk -F '[., ]' '{printf( "%s.%s.%s.%s\n", $2,$3,$5,$5 );}' \
  &gt; /tmp/ngrep.tmp &amp;
watch -tn 10 'cat /tmp/ngrep.tmp | sort -n | uniq -c | sort -nr | head -30'</pre>
<p>When you run this script you should see a continuously updating display which looks something like this:</p>
<pre>80 11.22.33.44
60 55.66.77.88
40 44.33.22.11
20 88.77.66.55
...</pre>
<p>It may start to slow down after a while. If that happens then just hit CTRL-C and run it again.</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.mattbrock.co.uk/2013/01/19/get-a-continuously-updating-display-of-client-ip-addresses-on-a-web-server-using-x-forwarded-for/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Python script to convert ICS-exported List from Reminders app to plaintext</title>
		<link>http://blog.mattbrock.co.uk/2013/01/14/python-script-to-convert-ics-exported-list-from-reminders-app-to-plaintext/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=python-script-to-convert-ics-exported-list-from-reminders-app-to-plaintext</link>
		<comments>http://blog.mattbrock.co.uk/2013/01/14/python-script-to-convert-ics-exported-list-from-reminders-app-to-plaintext/#comments</comments>
		<pubDate>Mon, 14 Jan 2013 18:59:01 +0000</pubDate>
		<dc:creator>Matt Brock</dc:creator>
				<category><![CDATA[SysAdmin]]></category>
		<category><![CDATA[Technology]]></category>
		<category><![CDATA[convert]]></category>
		<category><![CDATA[export]]></category>
		<category><![CDATA[ICS]]></category>
		<category><![CDATA[List]]></category>
		<category><![CDATA[plaintext]]></category>
		<category><![CDATA[Python]]></category>
		<category><![CDATA[Python script]]></category>
		<category><![CDATA[Reminders app]]></category>

		<guid isPermaLink="false">http://blog.mattbrock.co.uk/?p=2212</guid>
		<description><![CDATA[I make extensive use of the Reminders app in Mountain Lion* to keep track of tasks and to-do items, and I wanted a way to export a list of reminders to plaintext, so I knocked up a quick Python script to take an ICS file exported from a List in Reminders (which you can do [...]]]></description>
				<content:encoded><![CDATA[<p>I make extensive use of the Reminders app in Mountain Lion<sup>*</sup> to keep track of tasks and to-do items, and I wanted a way to export a list of reminders to plaintext, so I knocked up a quick Python script to take an ICS file exported from a List in Reminders (which you can do from the File menu) and output it in plaintext. <span id="more-2212"></span> If this is something you find yourself needing to do, this might work for you:</p>
<pre class="prettyprint">#!/usr/local/bin/python
# -*- coding: utf-8 -*-

import re
from optparse import OptionParser

parser = OptionParser()
parser.add_option("-f", "--file", dest="filename", metavar="FILE", 
  help="read reminders from ICS FILE")
parser.add_option("-c", "--include-completed", action="store_true", 
  dest="include_completed", help="include completed tasks")
(options, args) = parser.parse_args()

if not options.filename:
  print "No filename specified; -h for help"
  exit(1)

with open(options.filename) as file:
  ics_export = file.readlines()
file.close

todos = []
for ics_line in ics_export:
  if "STATUS:COMPLETED" in ics_line and options.include_completed is None:
    exclude = True
  elif "STATUS:" in ics_line:
    exclude = False
  if "SUMMARY:" in ics_line and exclude is False:
    bits = re.split(":", ics_line)
    todos.append(bits[1].rstrip())

todos.sort(key=lambda y: y.lower())
for todo in todos:
  print "•", todo</pre>
<p><sup>* Synced to my iPhone and other Macs via ownCloud on my Linux server, but that&#8217;s a story for another day.</sup></p>
]]></content:encoded>
			<wfw:commentRss>http://blog.mattbrock.co.uk/2013/01/14/python-script-to-convert-ics-exported-list-from-reminders-app-to-plaintext/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Creating a two-node CentOS 6 cluster with floating IP using Pacemaker and Corosync</title>
		<link>http://blog.mattbrock.co.uk/2013/01/09/creating-a-two-node-centos-6-cluster-with-floating-ip-using-pacemaker-and-corosync/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=creating-a-two-node-centos-6-cluster-with-floating-ip-using-pacemaker-and-corosync</link>
		<comments>http://blog.mattbrock.co.uk/2013/01/09/creating-a-two-node-centos-6-cluster-with-floating-ip-using-pacemaker-and-corosync/#comments</comments>
		<pubDate>Wed, 09 Jan 2013 14:30:40 +0000</pubDate>
		<dc:creator>Matt Brock</dc:creator>
				<category><![CDATA[SysAdmin]]></category>
		<category><![CDATA[CentOS 6]]></category>
		<category><![CDATA[chkconfig]]></category>
		<category><![CDATA[cluster]]></category>
		<category><![CDATA[Corosync]]></category>
		<category><![CDATA[crm]]></category>
		<category><![CDATA[floating IP]]></category>
		<category><![CDATA[Heartbeat]]></category>
		<category><![CDATA[Pacemaker]]></category>
		<category><![CDATA[quorum]]></category>
		<category><![CDATA[STONITH]]></category>
		<category><![CDATA[yum]]></category>

		<guid isPermaLink="false">http://blog.mattbrock.co.uk/?p=2198</guid>
		<description><![CDATA[Up until recently I was using Heartbeat to create two-node Linux clusters with floating IPs, but now Heartbeat is no longer being developed I needed to figure out how to use Corosync and Pacemaker for this instead. Unfortunately this is quite a lot more in-depth than the simple configuration that was required for Heartbeat. Anyway, [...]]]></description>
				<content:encoded><![CDATA[<p>Up until recently I was using Heartbeat to create two-node Linux clusters with floating IPs, but now Heartbeat is no longer being developed I needed to figure out how to use Corosync and Pacemaker for this instead. Unfortunately this is quite a lot more in-depth than the simple configuration that was required for Heartbeat. Anyway, based on my recent experiences, here&#8217;s a quick guide for if you find yourself in a similar situation. This works for me on CentOS 6. Whether it works on CentOS 5 and/or other Linux distributions I don&#8217;t currently know as I haven&#8217;t tried it.</p>
<p><span id="more-2198"></span></p>
<h2>Installation and initial configuration</h2>
<p>Install the required packages and prepare the configuration file:</p>
<pre>yum install pacemaker
cp /etc/corosync/corosync.conf.example /etc/corosync/corosync.conf</pre>
<p>Change <tt>bindnetaddr</tt> to your network address (e.g. 192.168.1.0) in <i>/etc/corosync/corosync.conf</i>.</p>
<p>Create <i>/etc/corosync/service.d/pcmk</i> and put the Pacemaker startup config into it:</p>
<pre>service {
        name: pacemaker
        ver: 1 
}</pre>
<p>Start corosync and pacemaker:</p>
<pre>service corosync start
service pacemaker start</pre>
<p>Make sure they start on boot:</p>
<pre>chkconfig corosync on
chkconfig pacemaker on</pre>
<p><b>Repeat all of the above</b> on the second node.</p>
<p>Then disable STONITH on the primary node:</p>
<pre>crm configure property stonith-enabled=false</pre>
<p>Add a floating IP on the primary node (change IP address and netmask as needed):</p>
<pre>crm configure primitive ClusterIP ocf:heartbeat:IPaddr2 params ip=192.168.1.110
  cidr_netmask=24 op monitor interval=30s</pre>
<p>Disable quorum on the primary node (necessary for running only two nodes):</p>
<pre>crm configure property no-quorum-policy=ignore</pre>
<p>Prevent resources from moving back after a node recovers:</p>
<pre>crm configure rsc_defaults resource-stickiness=100</pre>
<p>Use the commands in the Administration section below to ensure that the floating IP is on the correct machine &#8211; if this is not the case then temporarily shut down Pacemaker on whichever machine has the floating IP so that it moves across to the desired node:</p>
<pre>service pacemaker stop</pre>
<h2>Administration</h2>
<p>Display the current configuration:</p>
<pre>crm configure show</pre>
<p>Status monitor:</p>
<pre>crm status</pre>
<p>Show which node has the cluster IP:</p>
<pre>crm resource status ClusterIP</pre>
<p>Reset the config to default:</p>
<pre>cibadmin -E --force</pre>
<p>Verify that there are no problems with the current config:</p>
<pre>crm_verify -L</pre>
]]></content:encoded>
			<wfw:commentRss>http://blog.mattbrock.co.uk/2013/01/09/creating-a-two-node-centos-6-cluster-with-floating-ip-using-pacemaker-and-corosync/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>HttpOnly flag for persistence cookies in HAProxy</title>
		<link>http://blog.mattbrock.co.uk/2012/05/30/httponly-flag-for-persistence-cookies-in-haproxy/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=httponly-flag-for-persistence-cookies-in-haproxy</link>
		<comments>http://blog.mattbrock.co.uk/2012/05/30/httponly-flag-for-persistence-cookies-in-haproxy/#comments</comments>
		<pubDate>Wed, 30 May 2012 16:02:25 +0000</pubDate>
		<dc:creator>Matt Brock</dc:creator>
				<category><![CDATA[SysAdmin]]></category>
		<category><![CDATA[HAProxy]]></category>
		<category><![CDATA[HttpOnly]]></category>
		<category><![CDATA[patch]]></category>
		<category><![CDATA[PCI compliance]]></category>
		<category><![CDATA[persistence cookies]]></category>
		<category><![CDATA[sticky sessions]]></category>
		<category><![CDATA[XSS attacks]]></category>

		<guid isPermaLink="false">http://blog.mattbrock.co.uk/?p=2162</guid>
		<description><![CDATA[A client arranged penetration testing in order to achieve PCI compliance and it was found that not all cookies contained the HttpOnly flag, which is an automatic fail because apparently you are more vulnerable to XSS attacks if you don&#8217;t set your cookies to use HttpOnly. This problem turned out to be caused by the [...]]]></description>
				<content:encoded><![CDATA[<p>A client arranged penetration testing in order to achieve PCI compliance and it was found that not all cookies contained the HttpOnly flag, which is an automatic fail because apparently you are more vulnerable to XSS attacks if you don&#8217;t set your cookies to use HttpOnly. </p>
<p>This problem turned out to be caused by the HAProxy load balancer not adding HttpOnly to its persistence (sticky session) cookies, so I checked the HAProxy manual and did some googling, but I couldn&#8217;t find any way of making HAProxy&#8217;s persistence cookies add the HttpOnly flag.</p>
<p>The <a href="http://haproxy.1wt.eu/">HAProxy website</a> says &#8220;if you want to suggest a useful feature, please discuss it on the mailing list&#8221; so I&#8217;ve tried to do just that but have not had any response yet. In the meantime, I&#8217;ve modified the code myself so that the HttpOnly flag is added to all persistence cookies. For version 1.4.21 of HAProxy, patching <i>src/proto_http.c</i> with the following will add my modification to achieve this:</p>
<pre>5348a5349,5350
> 			len += sprintf(trash+len, "; HttpOnly");
> </pre>
<p>Hopefully this is something the HAProxy developers will add permanently as an option, otherwise it&#8217;s quite awkward for HAProxy users needing to pass compliance tests whilst using persistence cookies.</p>
<p><b>Edit:</b> Willy, the developer of HAProxy, has replied on the mailing list to indicate that he&#8217;ll be adding an &#8216;httponly&#8217; option to the &#8216;cookie&#8217; parameter in version 1.5 of HAProxy, so that&#8217;s great news. In the meantime, my little hack above can be used for those needing HttpOnly on version 1.4.</p>
<p><b>Edit:</b> This has now been added as an option in version 1.4.22 of HAProxy.</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.mattbrock.co.uk/2012/05/30/httponly-flag-for-persistence-cookies-in-haproxy/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Virtualisation with KVM and LVM on CentOS 6 via the command line</title>
		<link>http://blog.mattbrock.co.uk/2012/02/12/virtualisation-with-kvm-and-lvm-on-centos-6-via-the-command-line/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=virtualisation-with-kvm-and-lvm-on-centos-6-via-the-command-line</link>
		<comments>http://blog.mattbrock.co.uk/2012/02/12/virtualisation-with-kvm-and-lvm-on-centos-6-via-the-command-line/#comments</comments>
		<pubDate>Sun, 12 Feb 2012 14:12:01 +0000</pubDate>
		<dc:creator>Matt Brock</dc:creator>
				<category><![CDATA[SysAdmin]]></category>
		<category><![CDATA[acpid]]></category>
		<category><![CDATA[administration]]></category>
		<category><![CDATA[Apache]]></category>
		<category><![CDATA[avahi-daemon]]></category>
		<category><![CDATA[backing up]]></category>
		<category><![CDATA[backups]]></category>
		<category><![CDATA[brctl]]></category>
		<category><![CDATA[CentOS]]></category>
		<category><![CDATA[CentOS 6]]></category>
		<category><![CDATA[chkconfig]]></category>
		<category><![CDATA[CLI]]></category>
		<category><![CDATA[cloning]]></category>
		<category><![CDATA[command line]]></category>
		<category><![CDATA[CPU core]]></category>
		<category><![CDATA[cpuset]]></category>
		<category><![CDATA[dd]]></category>
		<category><![CDATA[disk images]]></category>
		<category><![CDATA[guest]]></category>
		<category><![CDATA[host]]></category>
		<category><![CDATA[httpd]]></category>
		<category><![CDATA[ifconfig]]></category>
		<category><![CDATA[Kickstart]]></category>
		<category><![CDATA[KVM]]></category>
		<category><![CDATA[libvirtd]]></category>
		<category><![CDATA[Linux]]></category>
		<category><![CDATA[lvcreate]]></category>
		<category><![CDATA[LVM]]></category>
		<category><![CDATA[LVM snapshots]]></category>
		<category><![CDATA[lvremove]]></category>
		<category><![CDATA[lvrename]]></category>
		<category><![CDATA[MAC address]]></category>
		<category><![CDATA[message bus]]></category>
		<category><![CDATA[migrating]]></category>
		<category><![CDATA[migration]]></category>
		<category><![CDATA[network bridge]]></category>
		<category><![CDATA[partitions]]></category>
		<category><![CDATA[RAM]]></category>
		<category><![CDATA[resize]]></category>
		<category><![CDATA[resizing]]></category>
		<category><![CDATA[restore]]></category>
		<category><![CDATA[root]]></category>
		<category><![CDATA[swap]]></category>
		<category><![CDATA[Ubuntu]]></category>
		<category><![CDATA[vcpu]]></category>
		<category><![CDATA[virsh]]></category>
		<category><![CDATA[virt-clone]]></category>
		<category><![CDATA[virt-filesystems]]></category>
		<category><![CDATA[virt-install]]></category>
		<category><![CDATA[virt-resize]]></category>
		<category><![CDATA[virt-top]]></category>
		<category><![CDATA[virtual machine]]></category>
		<category><![CDATA[virtualisation]]></category>
		<category><![CDATA[virtualization]]></category>
		<category><![CDATA[VM]]></category>
		<category><![CDATA[VNC]]></category>
		<category><![CDATA[volumes]]></category>
		<category><![CDATA[XML]]></category>
		<category><![CDATA[yum]]></category>

		<guid isPermaLink="false">http://blog.mattbrock.co.uk/?p=2113</guid>
		<description><![CDATA[I&#8217;ve found plenty of articles out there explaining how to use KVM with graphical GUI tools. On most of the CentOS servers I administer, however, I use Kickstart to create a customised and minimal GUI-free install to keep things as simple and efficient as possible. Here, therefore, are some guidelines for how to set up [...]]]></description>
				<content:encoded><![CDATA[<p>I&#8217;ve found plenty of articles out there explaining how to use KVM with graphical GUI tools. On most of the CentOS servers I administer, however, I use Kickstart to create a customised and minimal GUI-free install to keep things as simple and efficient as possible. Here, therefore, are some guidelines for how to set up a virtualisation environment and virtual machines using KVM on CentOS 6 via the CLI.</p>
<p><span id="more-2113"></span></p>
<p>I&#8217;m using LVM for the disk volumes because that&#8217;s supposedly better for IO efficiency than using disk images stored on the host filesystem, so a bit of familiarity with LVM is ideally needed before getting started.</p>
<h2>Initial host setup</h2>
<p>Firstly it&#8217;s necessary to make sure you have all the necessary software installed:</p>
<pre>yum -y groupinstall Virtualization "Virtualization Client"
  "Virtualization Platform" "Virtualization Tools" ;
  yum -y install libguestfs-tools</pre>
<p>Next check that libvirtd is running:</p>
<pre>service libvirtd status</pre>
<p>If not, make sure that messagebus and avahi-daemon are running, then start libvirtd:</p>
<pre>service messagebus start
service avahi-daemon start
service libvirtd start</pre>
<p>Use chkconfig to ensure that all three of these services start automatically on system boot.</p>
<p>Next it&#8217;s necessary to set up the network bridge so that the virtual machines can function on the network in the same way as physical servers. To do this, copy <em>/etc/sysconfig/network-scripts/ifcfg-eth0</em> (or whichever is the file for the active network interface) to <em>/etc/sysconfig/network-scripts/ifcfg-br0</em>.</p>
<p>In <em>/etc/sysconfig/network-scripts/ifcfg-eth0</em>, comment out all the lines for &#8216;BOOTPROTO&#8217;, &#8216;DNS1&#8242;, &#8216;GATEWAY&#8217;, &#8216;IPADDR&#8217; and &#8216;NETMASK&#8217;, then add this line:</p>
<pre class="code-java">BRIDGE="br0"</pre>
<p>Then edit <em>/etc/sysconfig/network-scripts/ifcfg-br0</em>, comment out the &#8216;HWADDR&#8217; line, change the &#8216;DEVICE&#8217; to &#8220;br0&#8243;, and change the &#8216;TYPE&#8217; to &#8220;Bridge&#8221; (or add this line in if it&#8217;s not here; note the capital &#8220;B&#8221; at the start of &#8220;Bridge&#8221;).</p>
<p>Then restart the network:</p>
<pre>service network restart</pre>
<p>The bridge should now be up and running. You can check its status with:</p>
<pre>ifconfig
brctl show</pre>
<h2>Creating the disk volumes for a new virtual machine</h2>
<p>We need to create new LVM volumes for the root and swap partitions in the new virtual machine. I&#8217;m assuming LVM is already being used, that the volume group is called &#8216;sysvg&#8217;, and that there is sufficient free space available in the sysvg group for the new volumes. If your volume group has a different name then just modify the instructions below accordingly. Change the volume sizes to suit your requirements:</p>
<pre>lvcreate -L 20G -n vm-root sysvg
lvcreate -L 4096M -n vm-swap sysvg</pre>
<h2>Installing the operating system on the new virtual machine</h2>
<p>Here I&#8217;m installing CentOS 6 on the guest machine using Kickstart, although I will also explain how to perform a normal non-automated installation. You&#8217;ll need to modify the instructions accordingly to install different operating systems.</p>
<p>To make CentOS easily available for the installation, firstly make sure you have Apache installed and running. If necessary, install it with:</p>
<pre>yum -y install httpd</pre>
<p>Then start it with:</p>
<pre>service httpd start</pre>
<p>Then create the directory <em>/var/www/html/CentOS</em> and copy the contents of the CentOS DVDs into it.</p>
<p>If you&#8217;re using Kickstart then you&#8217;ll need these lines in your Kickstart config file to make sure that it can find the files from the CentOS DVDs. The IP address of the host in this example is 192.168.1.1, so change that as needed:</p>
<pre>install
url --url http://192.168.1.1/CentOS</pre>
<p>These lines are also required to make sure that Kickstart can find and use the LVM volumes created earlier:</p>
<pre>zerombr
clearpart --all --initlabel
bootloader --location=mbr
part / --fstype ext4 --size 1 --grow --ondrive=vda
part swap --size 1 --grow --ondrive=vdb</pre>
<p>Once the Kickstart file is ready, call it <em>ks.cfg</em> and copy it to <em>/var/www/html</em></p>
<p>This command installs CentOS on the guest using a Kickstart automated installation. The guest is called &#8216;vm&#8217;, it has a dedicated physical CPU core (core number 2) and 1 GB of RAM allocated to it. Again, the IP address of the host is 192.168.1.1, so change that as needed:</p>
<pre>virt-install --name=vm --cpuset=2 --ram=1024
  --network bridge=br0 --disk=/dev/mapper/sysvg-vm--root
  --disk=/dev/mapper/sysvg-vm--swap --vnc --vnclisten=0.0.0.0
  --noautoconsole --location /var/www/html/CentOS
  --extra-args "ks=http://192.168.1.1/ks.cfg"</pre>
<p>The installation screen can be seen by connecting to the host via VNC. This isn&#8217;t necessary for a Kickstart installation (unless something goes wrong). If you want to do a normal install rather than a Kickstart install then you will need to use VNC to get to the installation screen, and in that case you&#8217;ll want to use the virt-install command above but just leave off everything from &#8216;&#8211;extra-args&#8217; onwards.</p>
<p>Also, you may want to install directly from a CDROM image, in which case replace the &#8216;&#8211;location&#8217; bit with &#8216;&#8211;cdrom=&#8217; and the path to the CD image, e.g. to install Ubuntu in your VM you might put &#8216;&#8211;cdrom=/tmp/ubuntu-12.04.1-server-i386.iso&#8217;.</p>
<p>(If virtual servers are already using VNC on the host then you will need to add the appropriate number to the VNC port number to connect to, e.g. the standard VNC port is 5900, and if there are already two virtual servers using VNC on the host then you will need to connect VNC to port 5902 for this install.)</p>
<h2>General administration of virtual machines</h2>
<p>Once you&#8217;ve got your virtual machine installed, you&#8217;ll need to know the various commands for everyday administration of KVM virtual machines. In these examples, change the name of the VM from &#8216;vm&#8217; to whatever yours is called.</p>
<p>To show general info about virtual machines, including names and current state:</p>
<pre>virsh list --all</pre>
<p>To see a top-style monitor window for all VMs:</p>
<pre>virt-top</pre>
<p>To show info about a specific virtual machine:</p>
<pre>virsh dominfo vm</pre>
<p>To start a virtual machine:</p>
<pre>virsh start vm</pre>
<p>To pause a virtual machine:</p>
<pre>virsh suspend vm</pre>
<p>To resume a virtual machine:</p>
<pre>virsh resume vm</pre>
<p>To shut down a virtual machine (the &#8216;acpid&#8217; service must be running on the guest for this to work):</p>
<pre>virsh shutdown vm</pre>
<p>To force a hard shutdown of a virtual machine:</p>
<pre>virsh destroy vm</pre>
<p>To remove a domain (don&#8217;t do this unless you&#8217;re sure you really don&#8217;t want this virtual machine any more):</p>
<pre>virsh undefine vm</pre>
<h2>Cloning virtual machines</h2>
<p>To clone a guest VM, firstly it&#8217;s necessary to create new disk volumes for the clone, then we use the virt-clone command to clone the existing VM:</p>
<pre>lvcreate -L 20G -n newvm-root sysvg
lvcreate -L 4096M -n newvm-swap sysvg
virt-clone -o vm -n newvm -f /dev/mapper/sysvg-newvm--root
  -f /dev/mapper/sysvg-newvm--swap</pre>
<p>Then dump the XML for the new VM:</p>
<pre>virsh dumpxml newvm &gt; /tmp/newvm.xml</pre>
<p>Edit <em>/tmp/newvm.xml</em>. Look for the &#8216;vcpu&#8217; line and change the &#8216;cpuset&#8217; number to the CPU core you want to dedicate to this VM. Then make this change effective:</p>
<pre>virsh define /tmp/newvm.xml</pre>
<p>You&#8217;ll also need to grab the MAC address from the XML. Keep this available as we&#8217;ll need it in a minute:</p>
<pre>grep "mac address" /tmp/newvm.xml | awk -F ' '{print $2}'</pre>
<p>Start up the new VM and connect to it via VNC as per the instructions in the Installation section above. Edit <em>/etc/sysconfig/network</em> and change the hostname to whatever you want to use for this new machine. Then edit <em>/etc/sysconfig/network-scripts/ifcfg-eth0</em> and change the &#8216;HOSTNAME&#8217; and &#8216;IPADDR&#8217; to the settings you want for this new machine. Change the &#8216;HWADDR&#8217; to the MAC address you obtained a moment ago, making sure that the letters are capitalised.</p>
<p>Then reboot and the new VM should be ready.</p>
<h2>Backing up and migrating virtual machines</h2>
<p>In order to take backups and to be able to move disk volumes from virtual machines to other hosts, we basically need to create disk image files from the LVM volumes. We&#8217;ll first snapshot the LVM volume and take the disk image from the snapshot, as this significantly reduces the amount of time that the VM needs to remain paused (i.e. effectively offline) for. We remove the snapshot at the end of the process so that the VM&#8217;s IO is not negatively affected.</p>
<p>This disk image, once created, can then be stored in a separate location as a backup, and/or transferred to another host server in order to copy or move the VM there.</p>
<p>So, make sure that the VM is paused or shut down, then create a LVM snapshot, then resume the VM, then create the image from the snapshot, then remove the snapshot:</p>
<pre>virsh suspend vm
lvcreate -L 100M -n vm-root-snapshot -s /dev/sysvg/vm-root
virsh resume vm
dd if=/dev/mapper/sysvg-vm--root--snapshot
  of=/tmp/vm-root.img bs=1M
lvremove /dev/mapper/sysvg-vm--root--snapshot</pre>
<p>You can then do what you like with <em>/tmp/vm-root.img</em> &#8211; store it as a backup, move it to another server, and so forth.</p>
<p>In order to restore from it or create a VM from it on a new server, firstly use &#8216;lvcreate&#8217; to create the LVM volume for restore if it isn&#8217;t already there, then copy the disk image to the LVM volume:</p>
<pre>dd if=/tmp/vm-root.img of=/dev/mapper/sysvg-vm--root bs=1M</pre>
<p>You may also need to perform this procedure for the swap partition depending on what you are trying to achieve.</p>
<p>You&#8217;ll also want to back up the current domain configuration for the virtual machine:</p>
<pre>virsh dumpxml vm &gt; /tmp/vm.xml</pre>
<p>Then just store the XML file alongside the disk image(s) you&#8217;ve taken.</p>
<p>If you&#8217;re moving the virtual machine to a new server then once you&#8217;ve got the root and swap LVM volumes in place, you&#8217;ll need to create the domain for the virtual machine on the new server. Firstly edit the XML file and change the locations of disk volumes to the layout on the new server if it&#8217;s different to the old server, then define the new domain:</p>
<pre>virsh define /tmp/vm.xml</pre>
<p>You should then be able to start up the &#8216;vm&#8217; virtual machine on the new server.</p>
<h2>Resizing partitions on a guest</h2>
<p>Let&#8217;s say we want to expand the root partition on our VM from 20G to 25G. Firstly make sure the VM is shut down, then use virt-filesystems to get the information we need for the resize procedure:</p>
<pre>virsh shutdown vm
virt-filesystems -lh -a /dev/mapper/sysvg-vm--root</pre>
<p>This will probably tell you that the available filesystem on that volume is <em>/dev/sda1</em>, which is how these tools see the virtual machine&#8217;s <em>/dev/vda1</em> partition. We&#8217;ll proceed on the basis that this is the case, but if the filesystem device name is different then alter the command below accordingly.</p>
<p>Next we create a new volume, then we perform the virt-resize command from the old volume to the new volume, then we set the new volume as the active root partition for our domain:</p>
<pre>lvcreate -L 25G -n vm-rootnew sysvg
virt-resize --expand /dev/sda1 /dev/mapper/sysvg-vm--root
  /dev/mapper/sysvg-vm--rootnew
lvrename /dev/sysvg/vm-root /dev/sysvg/vm-rootold
lvrename /dev/sysvg/vm-rootnew /dev/sysvg/vm-root
virsh start vm</pre>
<p>Then, when you&#8217;re sure the guest is running OK with the new resized partition, remove the old root partition volume:</p>
<pre>lvremove /dev/mapper/sysvg-vm--rootold</pre>
]]></content:encoded>
			<wfw:commentRss>http://blog.mattbrock.co.uk/2012/02/12/virtualisation-with-kvm-and-lvm-on-centos-6-via-the-command-line/feed/</wfw:commentRss>
		<slash:comments>23</slash:comments>
		</item>
		<item>
		<title>PostgreSQL tuning: ensuring that as many sorts as possible are done in memory and not on disk</title>
		<link>http://blog.mattbrock.co.uk/2011/12/01/postgresql-tuning-ensuring-that-as-many-sorts-as-possible-are-done-in-memory-and-not-on-disk/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=postgresql-tuning-ensuring-that-as-many-sorts-as-possible-are-done-in-memory-and-not-on-disk</link>
		<comments>http://blog.mattbrock.co.uk/2011/12/01/postgresql-tuning-ensuring-that-as-many-sorts-as-possible-are-done-in-memory-and-not-on-disk/#comments</comments>
		<pubDate>Thu, 01 Dec 2011 22:02:23 +0000</pubDate>
		<dc:creator>Matt Brock</dc:creator>
				<category><![CDATA[SysAdmin]]></category>
		<category><![CDATA[available RAM]]></category>
		<category><![CDATA[Bash]]></category>
		<category><![CDATA[Bash script]]></category>
		<category><![CDATA[CentOS]]></category>
		<category><![CDATA[disk cache]]></category>
		<category><![CDATA[free]]></category>
		<category><![CDATA[in memory]]></category>
		<category><![CDATA[Linux]]></category>
		<category><![CDATA[local0]]></category>
		<category><![CDATA[log_destination]]></category>
		<category><![CDATA[log_temp_files]]></category>
		<category><![CDATA[on disk]]></category>
		<category><![CDATA[postgres]]></category>
		<category><![CDATA[PostgreSQL]]></category>
		<category><![CDATA[postgresql.conf]]></category>
		<category><![CDATA[Red Hat]]></category>
		<category><![CDATA[reset work_mem]]></category>
		<category><![CDATA[set work_mem]]></category>
		<category><![CDATA[slow queries]]></category>
		<category><![CDATA[sorts]]></category>
		<category><![CDATA[swap]]></category>
		<category><![CDATA[swapping]]></category>
		<category><![CDATA[syslog]]></category>
		<category><![CDATA[temp files]]></category>
		<category><![CDATA[temporary file]]></category>
		<category><![CDATA[temporary files]]></category>
		<category><![CDATA[tuning]]></category>
		<category><![CDATA[virtual memory]]></category>
		<category><![CDATA[work_mem]]></category>

		<guid isPermaLink="false">http://blog.mattbrock.co.uk/?p=2048</guid>
		<description><![CDATA[(This post assumes a PostgreSQL installation located at /var/lib/pgsql on a Red Hat-type Linux system such as Red Hat Enterprise Linux or CentOS. If your system differs from this, you may need to modify some of the paths accordingly.) In PostgreSQL, sorts larger than a certain size will get performed on disk instead of in [...]]]></description>
				<content:encoded><![CDATA[<p>(This post assumes a PostgreSQL installation located at <em>/var/lib/pgsql</em> on a Red Hat-type Linux system such as Red Hat Enterprise Linux or CentOS. If your system differs from this, you may need to modify some of the paths accordingly.)</p>
<p>In PostgreSQL, sorts larger than a certain size will get performed on disk instead of in memory, and this makes them much slower as a result. Ideally all sorts should be done in memory (except for the ones that are genuinely too big to fit into your available RAM, because swapping to virtual memory should be avoided at all costs).</p>
<p><span id="more-2048"></span></p>
<h1>Seeing which sorts are happening on disk</h1>
<p>To see which sorts are being performed on disk, the following parameters need to be enabled in <em>/var/lib/pgsql/data/postgresql.conf</em>:</p>
<pre>log_destination = 'syslog'
log_temp_files = 0</pre>
<p>PostgreSQL syslog logging goes to the &#8216;local0&#8242; facility by default, so in <em>/etc/syslog.conf</em> make sure that you have &#8216;local0.none&#8217; added to the line for <em>/var/log/messages</em>, and add the following line:</p>
<pre>local0.* /var/log/pgsql</pre>
<p>Then restart syslog and reload PostgreSQL:</p>
<pre>service syslog restart
service postgresql reload</pre>
<p>You should now start seeing details of your disk-based sorts in <em>/var/log/pgsql</em>. Each one will start with a line containing the phrase &#8216;LOG:  temporary file&#8217; and will show other details below this line including the SQL of the query which contained the sort. After a while you will see patterns emerging. </p>
<h1>Making sorts happen in memory instead of on disk</h1>
<p>If you have disk-based sorts occurring frequently, you can find the size of the largest of the frequent queries and then set this as the standard threshold for sorts. The parameter for this in <em>/var/lib/pgsql/data/postgresql.conf</em> is &#8216;work_mem&#8217;. For example, if you had frequent disk-spaced sorts using up to 64MB, you would set the following in <em>/var/lib/pgsql/data/postgresql.conf</em>:</p>
<pre>work_mem = 64MB</pre>
<p><strong>Be very careful, however</strong>, because this setting gets used by each query in each thread, so if you set this too high you could rapidly run out of RAM and cause the system to start swapping, which would be disastrous. The best thing to do is increase this bit by bit until as many as possible of your frequent queries are sorting in RAM but without running out of available memory. To see how much RAM is actually available on your system, use the command &#8216;free&#8217;. As Linux tends to use up the majority of available RAM for its disk cache, the number you actually care about is the &#8216;free&#8217; column in the &#8216;buffers/cache&#8217; row &#8211; this is how much RAM is really available. For example, here we can see that there are just over 11 GB of free RAM available:</p>
<pre># free
             total       used       free     shared    buffers     cached
Mem:      12300988   12013536     287452          0     277788   10801424
-/+ buffers/cache:     934324   11366664
Swap:      4192956        240    4192716</pre>
<p>Once you&#8217;ve dealt with sorts for frequent queries, you might find there are still the occasional disk-based sorts happening for a small number of particularly intensive queries. For those, you can increase the sort memory threshold on a per-query basis and then put it back to the standard setting once the query is finished. To do this, prepend your query with:</p>
<pre>SET work_mem = '500MB';</pre>
<p>changing &#8217;500MB&#8217; to whatever size is appropriate for you, then append the query with:</p>
<pre>RESET work_mem;</pre>
<p>to return it to the standard threshold. Again, <strong>be careful</strong> that you don&#8217;t use up all the system&#8217;s available RAM because then the dreaded swapping will occur.</p>
<p>Once you&#8217;ve done all this, as many sorts as possible will be happening in memory instead of on disk, and your PostgreSQL installation should be performing considerably better as a result of this tuning.</p>
<h1>Getting information from the logfile into a more useful format</h1>
<p>When PostgreSQL logs temporary files (disk-based sorts), the log entries can be rather messily distributed in the logfile, especially if you&#8217;re logging other things, such as slow queries, at the same time. I knocked up the following Bash script to quickly extract the details of the sorts into a more useful format:</p>
<pre class="prettyprint">#!/bin/bash

PROG=$(basename $0)
PPROG=$(echo $PROG | awk -F '.' '{print $1}')
TMPFILE1=/tmp/$PPROG.tmp1
TMPFILE2=/tmp/$PPROG.tmp2
LOGFILE=$1

if [ -z "$1" ] ; then
  echo "Usage: $PROG LOGFILE"
  exit 
fi

cat /dev/null &gt; $TMPFILE2

grep "temporary file" $LOGFILE &gt; $TMPFILE1

cat $TMPFILE1 | while read LINE ; do
  NO1=$(echo $LINE | awk -F '[][-]' '{print $2}' )
  NO2=$(echo $LINE | awk -F '[][-]' '{print $4}' )
  cat $LOGFILE | 
    awk -F '[][-]' "($2 ~ /$NO1/) &amp;&amp; ($4 ~ /$NO2/) {print $0}" 
    &gt;&gt; $TMPFILE2
  echo "" &gt;&gt; $TMPFILE2
done

cat $TMPFILE2

rm -f $TMPFILE1 $TMPFILE2</pre>
]]></content:encoded>
			<wfw:commentRss>http://blog.mattbrock.co.uk/2011/12/01/postgresql-tuning-ensuring-that-as-many-sorts-as-possible-are-done-in-memory-and-not-on-disk/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Mac OS X Lion review</title>
		<link>http://blog.mattbrock.co.uk/2011/07/26/mac-os-x-lion-review/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=mac-os-x-lion-review</link>
		<comments>http://blog.mattbrock.co.uk/2011/07/26/mac-os-x-lion-review/#comments</comments>
		<pubDate>Tue, 26 Jul 2011 15:55:46 +0000</pubDate>
		<dc:creator>Matt Brock</dc:creator>
				<category><![CDATA[SysAdmin]]></category>
		<category><![CDATA[Technology]]></category>
		<category><![CDATA[Address Book]]></category>
		<category><![CDATA[AirDrop]]></category>
		<category><![CDATA[animation]]></category>
		<category><![CDATA[Apple]]></category>
		<category><![CDATA[Auto Save]]></category>
		<category><![CDATA[blur]]></category>
		<category><![CDATA[Dock]]></category>
		<category><![CDATA[Exposé]]></category>
		<category><![CDATA[Front Row]]></category>
		<category><![CDATA[Full-Screen Apps]]></category>
		<category><![CDATA[gestures]]></category>
		<category><![CDATA[HDMI]]></category>
		<category><![CDATA[iCal]]></category>
		<category><![CDATA[iCal Server]]></category>
		<category><![CDATA[iOS]]></category>
		<category><![CDATA[Launchpad]]></category>
		<category><![CDATA[Leopard]]></category>
		<category><![CDATA[Mac]]></category>
		<category><![CDATA[Mac Mini]]></category>
		<category><![CDATA[Mac OS X]]></category>
		<category><![CDATA[Mac OS X Lion]]></category>
		<category><![CDATA[Mail]]></category>
		<category><![CDATA[mice]]></category>
		<category><![CDATA[Mission Control]]></category>
		<category><![CDATA[opacity]]></category>
		<category><![CDATA[OS X Leopard Server]]></category>
		<category><![CDATA[quitting without asking]]></category>
		<category><![CDATA[Resume]]></category>
		<category><![CDATA[review]]></category>
		<category><![CDATA[scroll bars]]></category>
		<category><![CDATA[Show indicator lights for open applications]]></category>
		<category><![CDATA[Sidebar icon size]]></category>
		<category><![CDATA[Snow Leopard]]></category>
		<category><![CDATA[Spaces]]></category>
		<category><![CDATA[System Preferences]]></category>
		<category><![CDATA[Terminal]]></category>
		<category><![CDATA[To Do items]]></category>
		<category><![CDATA[trackpads]]></category>
		<category><![CDATA[Versions]]></category>
		<category><![CDATA[window resizing]]></category>
		<category><![CDATA[⌘-Tab]]></category>

		<guid isPermaLink="false">http://blog.mattbrock.co.uk/?p=2004</guid>
		<description><![CDATA[My experience with Lion so far has been, to say the least, mixed. I thought I&#8217;d list some of my experiences in the form of a brief review. Launchpad: Tedious scrolling through multiple screens of apps in order to launch one of them? No thanks. Dreadful. Mission Control: It seems like a good idea in [...]]]></description>
				<content:encoded><![CDATA[<p>My experience with Lion so far has been, to say the least, mixed. I thought I&#8217;d list some of my experiences in the form of a brief review.</p>
<p><span id="more-2079"></span></p>
<p><strong>Launchpad:</strong> Tedious scrolling through multiple screens of apps in order to launch one of them? No thanks. Dreadful.</p>
<p><strong>Mission Control:</strong> It seems like a good idea in principle to combine Exposé and Spaces, but in doing so some useful functionality is lost: minimised windows are no longer shown; multiple desktops are now one-dimensional rather than two-dimensional; I no longer have a number in the Menu Bar telling me which desktop I&#8217;m currently on; and it&#8217;s harder to see the contents of the other desktops. All a bit of a shame really.</p>
<p><strong>Full-Screen Apps:</strong> This seems initially useful, but: it doesn&#8217;t make use of multiple monitors; the keyboard shortcut only seems to work some of the time; it disables my hot corner to quickly get to the Desktop; switching between windows within a fullscreen app (e.g. Mail) is sometimes impossible; and it adds confusion because all windows already have a Zoom button, so now they all have two maximise buttons instead of one.</p>
<p><strong>Resume/Auto Save/Versions:</strong> This seems like a good idea in theory, but I doubt many of the apps I use will implement this for a long time, if ever.</p>
<p><strong>AirDrop:</strong> I was really looking forward to this one but didn&#8217;t realise that it only works on some recent Macs, i.e. none of mine. So that was very disappointing.</p>
<p><strong>Mail:</strong> The redesign is quite nice both aesthetically and ergonomically. Nothing ground-breaking, but nice. I&#8217;ve already become very dependent on the conversation view to the point where I now wish they&#8217;d hurry up and enable it for my iPhone too.</p>
<p><strong>Address Book/iCal:</strong> The horrible graphics in these are ugly and ridiculous, and Address Book has much less space for useful information as a result. I thought Apple had stopped this sort of nonsense years ago and didn&#8217;t expect to see it come back now. Also, iCal is having severe problems talking to my work calendar, and the work calendar is iCal Server running on OS X Leopard Server, so it&#8217;s particularly annoying that that doesn&#8217;t work properly [now fixed by using SSL for CalDAV]. Having said all that, I do like the new &#8216;planner&#8217; pane on the &#8216;Day&#8217; view &#8211; that&#8217;s now replaced &#8216;Week&#8217; as my standard view as a result.</p>
<p><strong>Front Row:</strong> Instead of bringing this up to date, which would have been sensible especially now that Mac minis have HDMI outputs, they&#8217;ve just removed it instead. Great. Thanks, Apple. I don&#8217;t use it that much in comparison to Plex on my <a href="http://blog.mattbrock.co.uk/2010/07/10/my-mac-mini-based-media-centre/">Mac mini-based media centre</a>, but it would have been nice to have functionality added instead of the whole thing being taken away. Very poor show indeed.</p>
<p><strong>Terminal:</strong> I love the new &#8216;Blur&#8217; option for window backgrounds, and I&#8217;ve come up with a really nice combination of blur and opacity for my active and inactive windows. But why, when I open new tabs, do they start SSHing into random servers when I don&#8217;t want them to? I presume this is something to do with Resume but it&#8217;s bloody annoying and I want it to stop! [Turns out it was necessary to change the 'New tabs open with' settings in the Startup tab in Terminal Preferences.]</p>
<p><strong>UI changes:</strong> Being able to resize a window from any edge is very welcome &#8211; I wish they&#8217;d done this years ago. It&#8217;s nice to see the back of the oversized Aqua scroll bars at last (but desirable to change the scroll bar setting to show &#8216;Always&#8217; in the General System Preference because this is a computer, not an iPhone). The overall look and feel is like a more subtle, streamlined version of Snow Leopard, which is quite nice generally. I worried about the icons in sidebars (in Finder and Mail most noticeably) being stupidly oversized, but thankfully I then found the &#8216;Sidebar icon size&#8217; option in the General System Preference &#8211; setting that to &#8216;Small&#8217; makes everything OK again. And the increased use of animation is quite enjoyable and might occasionally be vaguely useful for new computer users. All the new gesture stuff is irrelevant to me because I don&#8217;t have any of the new Macs with big trackpads, and I prefer using mice anyway (though not Apple mice because they&#8217;re an ergonomic nightmare). Oh, and suddenly finding scrolling going in the wrong direction wasn&#8217;t particularly useful, but thankfully that was easy to turn off in the Mouse System Preference.</p>
<p><strong>System stuff:</strong> Make sure you have &#8216;Show indicator lights for open applications&#8217; ticked in the Dock System Preference, partly because that&#8217;s a traditional behaviour which helps to actually make the Dock useful, and partly because if you don&#8217;t then Lion will randomly quit open apps without asking. Another bit of weirdness is the &#8216;Mail, Contacts &amp; Calendars&#8217; System Preference, which seems to serve no useful purpose whatsoever other than to confuse users by duplicating settings which you&#8217;ve already got in Mail, iCal, etc.</p>
<p>So there we go. Once you&#8217;ve turned all the annoyances off it&#8217;s basically just a neater, slicker version of Snow Leopard with a few things missing, so I&#8217;m not exactly blown away by this new OS. I think the main problem is that trying to mix Mac OS X and iOS causes a conflicting mess of too many different UI paradigms. Apple should either have stuck with tweaking the Mac OS X foundations or rebuilding the whole thing from the ground up, not ending up with something in between the two which doesn&#8217;t quite work.</p>
<p><strong>Edit:</strong> It&#8217;s quite interesting to compare the rather dark tone of this review to the optimistic positivity of my <a href="http://blog.mattbrock.co.uk/2009/08/29/snow-leopard/">Snow Leopard</a> and <a href="http://blog.mattbrock.co.uk/2007/11/13/mac-os-x-leopard/">Leopard</a> reviews. It makes Lion feel like even more of a step back than a step forward.</p>
<p><strong>Edit:</strong> Reading back on my reviews of previous versions of OS X, I&#8217;m reminded of what a mess Apple made of To Do Items in Mail when that was <a href="http://blog.mattbrock.co.uk/2007/11/13/mac-os-x-leopard/">added to Leopard</a>. I see they&#8217;ve fixed that by simply removing them again, which I guess is fair enough really.</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.mattbrock.co.uk/2011/07/26/mac-os-x-lion-review/feed/</wfw:commentRss>
		<slash:comments>17</slash:comments>
		</item>
		<item>
		<title>Using Amazon&#8217;s EC2 cloud service to host our entire web infrastructure</title>
		<link>http://blog.mattbrock.co.uk/2011/03/29/using-amazons-ec2-cloud-service-to-host-our-entire-web-infrastructure/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=using-amazons-ec2-cloud-service-to-host-our-entire-web-infrastructure</link>
		<comments>http://blog.mattbrock.co.uk/2011/03/29/using-amazons-ec2-cloud-service-to-host-our-entire-web-infrastructure/#comments</comments>
		<pubDate>Tue, 29 Mar 2011 13:34:21 +0000</pubDate>
		<dc:creator>Matt Brock</dc:creator>
				<category><![CDATA[SysAdmin]]></category>
		<category><![CDATA["Amazon Web Services"]]></category>
		<category><![CDATA["Elastic Compute Cloud"]]></category>
		<category><![CDATA["Simple Storage Service"]]></category>
		<category><![CDATA["the cloud"]]></category>
		<category><![CDATA[A record]]></category>
		<category><![CDATA[Amazon]]></category>
		<category><![CDATA[Amazon EC2]]></category>
		<category><![CDATA[Amazon S3]]></category>
		<category><![CDATA[AWS]]></category>
		<category><![CDATA[AWS Management Console]]></category>
		<category><![CDATA[Bash script]]></category>
		<category><![CDATA[blacklisting]]></category>
		<category><![CDATA[CentOS]]></category>
		<category><![CDATA[cloud]]></category>
		<category><![CDATA[cloud infrastructure]]></category>
		<category><![CDATA[CNAME]]></category>
		<category><![CDATA[colo]]></category>
		<category><![CDATA[colocation]]></category>
		<category><![CDATA[data centre]]></category>
		<category><![CDATA[disaster recovery]]></category>
		<category><![CDATA[DR]]></category>
		<category><![CDATA[EBS]]></category>
		<category><![CDATA[EBS snapshots]]></category>
		<category><![CDATA[EBS volume]]></category>
		<category><![CDATA[EC2]]></category>
		<category><![CDATA[EC2 CLI]]></category>
		<category><![CDATA[EC2 command line tools]]></category>
		<category><![CDATA[Elastic Block Store]]></category>
		<category><![CDATA[Elastic IP]]></category>
		<category><![CDATA[Elastic Load Balancing]]></category>
		<category><![CDATA[ELB]]></category>
		<category><![CDATA[email]]></category>
		<category><![CDATA[instance types]]></category>
		<category><![CDATA[load balancing]]></category>
		<category><![CDATA[migration]]></category>
		<category><![CDATA[Paul Norman]]></category>
		<category><![CDATA[reverse DNS]]></category>
		<category><![CDATA[RightScale]]></category>
		<category><![CDATA[S3]]></category>
		<category><![CDATA[s3cmd]]></category>
		<category><![CDATA[snapshots]]></category>
		<category><![CDATA[spam]]></category>
		<category><![CDATA[system administrator]]></category>
		<category><![CDATA[web application infrastructure]]></category>
		<category><![CDATA[web hosting]]></category>
		<category><![CDATA[web infrastructure]]></category>

		<guid isPermaLink="false">http://blog.mattbrock.co.uk/?p=1894</guid>
		<description><![CDATA[Following our successful migration to Amazon&#8217;s S3 service for media storage and delivery, we decided to move our entire server infrastructure from its traditional data centre colocation to Amazon&#8217;s Elastic Compute Cloud (or &#8216;EC2&#8242;). Using this cloud-based infrastructure instead of data centre colocation provides two main benefits for us. Firstly, EC2 is much more flexible [...]]]></description>
				<content:encoded><![CDATA[<p>Following our <a href="http://blog.mattbrock.co.uk/2009/06/09/migrating-to-cloud-services-for-delivering-media-content/">successful migration</a> to Amazon&#8217;s <a href="http://aws.amazon.com/s3/">S3</a> service for media storage and delivery, we decided to move our entire server infrastructure from its traditional data centre colocation to Amazon&#8217;s <a href="http://aws.amazon.com/ec2/">Elastic Compute Cloud (or &#8216;EC2&#8242;)</a>. Using this cloud-based infrastructure instead of data centre colocation provides two main benefits for us. </p>
<p><span id="more-1894"></span></p>
<p>Firstly, EC2 is much more flexible than traditional colocation. Our infrastructure can now be expanded or altered, quite radically if necessary, in hours or even minutes, just by typing a few commands or clicking a few buttons. Previously, making similar changes would have taken weeks of planning, ordering, delivery, physical installation, software installation, etc.</p>
<p>Secondly, EC2 works out cheaper. EC2 server instances tend to work out cheaper than their physical colocation equivalents, especially when you&#8217;re able to plan ahead with <a href="http://aws.amazon.com/ec2/pricing/">pricing</a> by using Amazon&#8217;s &#8216;Reserved&#8217; pricing instead of their standard &#8216;On-Demand&#8217; pricing. Also, because of EC2&#8242;s flexibility, it&#8217;s only ever necessary to run precisely the infrastructure required at the present moment, so you&#8217;re never paying for more than you need. With a traditional colocation setup, the lack of flexibility means that you will always have more hardware than you need at the present moment in order to cope with possible traffic spikes, hardware failures, etc., and that extra hardware increases the cost even further.</p>
<p>Getting up and running with EC2 is pretty straightforward. You just need to provide payment details, set up security details, and then you&#8217;re free to fire up server instances and try it out. There are various instance types to choose from depending on the hardware spec you need. Much of this can now be done via the <a href="http://aws.amazon.com/console/">Amazon Web Services (&#8216;AWS&#8217;) Management Console</a>, although you can also install the <a href="http://docs.amazonwebservices.com/AWSEC2/latest/UserGuide/index.html?setting-up-your-tools.html">EC2 command line tools</a> in order to operate EC2 via the CLI. I prefer using the CLI, probably because I&#8217;ve been doing it that way for longer, but also I guess there are still some things you can do via the CLI which you can&#8217;t do via the AWS Management Console.</p>
<p>Any decent system administrator will want to set up and configure instances according to his own tastes and requirements, and the best way to do this is to start an instance from an image that&#8217;s closest to what you want, then modify it accordingly, then create your own image from that running instance. I originally started up an instance from a CentOS image provided by <a href="http://www.rightscale.com/">RightScale</a>, then modified it heavily according to my own preferences, then created an image of my own from it. This image is what I called the &#8216;base&#8217; image. </p>
<p>I then created several different instance types for each of the different types of servers we have in our infrastructure. For each of these I started from the &#8216;base&#8217; image, installed the applications required for that instance type, then created a new image from it, so that I ended up with several images: one for web server instances, another for mail server instances, and so on. Each instance type has a certain set of events which need to occur when that instance is first run, e.g. working out its own external hostname, setting up certain directories that are needed, etc., and for this I have a startup script in <i>/etc/rc.d/init.d</i> on each instance which works out whether it&#8217;s a brand new instance and, if so, performs all these tasks.</p>
<p>Once all the required instance types have been created and made available as images which can be started as required, it&#8217;s almost possible to start up a full web application infrastructure with all the components required for it. However, there are a few extra things to think about first.</p>
<p>Firstly, it&#8217;s necessary to consider disaster recovery. Conveniently, most of our instances do not contain any unique data which would be missed if the instance died, and if an instance dies then it&#8217;s normally just a case of firing up a new one to take its place. Obviously requirements will vary from one company to another, but in our case only the database instance contains unique data, i.e. the live database. I solved the disaster recovery requirement for the database instance by utilising an AWS storage solution called <a href="http://aws.amazon.com/ebs/">Elastic Block Store (or &#8216;EBS&#8217;)</a>. An EBS volume is a storage volume which can be connected to a running instance and which can also be snapshotted. So, all the data for our live database is on an EBS volume connected to the database instance, and this gets backed up and snapshotted every night. I have a Bash script which does this automatically from cron, and which also removes any shapshots older than 28 days. </p>
<p>Therefore, if the database instance dies, I can just fire up a new instance and connect the EBS volume to the new instance. In the unlikely event that the EBS volume dies, I can just create a new one from the latest snapshot and connect it to the database instance. This is therefore a very handy DR solution for the live database, and EBS volumes have the added bonus of being faster than the standard instance-based storage, which is obviously ideal for a database.</p>
<p>All instance images and EBS snapshots are stored on S3. S3 is an exceptionally safe form of storage, so the chances of anything getting lost on it are incredibly low, and this very low level of risk might be reassurance enough for many companies. In our case, however, I&#8217;m exceptionally paranoid so I also take backups of everything we have on S3 (including all our media which is <a href="http://blog.mattbrock.co.uk/2009/06/09/migrating-to-cloud-services-for-delivering-media-content/">also stored there</a>). Every month I use the rsync-style functionality within the very handy <a href="http://s3tools.org/s3cmd">s3cmd</a> tool to incrementally backup all our S3 buckets to a disk on a server in our office.</p>
<p>Another consideration is how to load balance the front-end servers. Amazon provide a great solution for this called <a href="http://aws.amazon.com/elasticloadbalancing/">Elastic Load Balancing</a>. This can be used to quickly and easily create a load balancer which can be configured to distribute whatever traffic you like across whichever instances you need. It even has support for sticky sessions. The only problem I&#8217;ve found with ELB is that it requires you to point a CNAME at the load balancer rather than an A record, which means that you can&#8217;t use root domains (i.e. apple.com instead of www.apple.com) because the DNS spec does not allow a root domain to be a CNAME. There are various hacks to get around this, but none of them are perfect, and it&#8217;s a problem I hope Amazon will solve soon. In the meantime, <a href="https://forums.aws.amazon.com/thread.jspa?threadID=32044">this thread</a> in the AWS developer forums gives more information.</p>
<p>It&#8217;s also necessary to consider the delivery of email. Unfortunately, due to the ease with which server infrastructures can be created on EC2, a lot of spammers use it to send email, which means that EC2 IP addresses are heavily blacklisted. For each EC2 instance you wish to send email from, therefore, you need to follow a process which helps Amazon to ensure that you&#8217;re not sending spam. Firstly, you need to assign an Elastic IP to the instance. An Elastic IP is an IP address you can request and then keep for your own use, assigning it to whichever instance you like at any given time instead of using whichever IP address that instance happened to have by default. Once the Elastic IP is assigned to the mail server instance, you just need to <a href="https://aws-portal.amazon.com/gp/aws/html-forms-controller/contactus/ec2-email-limit-rdns-request">tell Amazon</a> to set up reverse DNS for that Elastic IP and remove its email sending limitations. This process works well, and we haven&#8217;t had any problems sending mail from our mail server instance since completing it.</p>
<p>As with the general EC2 functions, EBS, ELB and Elastic IPs can be controlled via the AWS Management Console, but the CLI tools tend to be more powerful than the console. CLI commands for EBS and Elastic IPs are included within the EC2 command line tools, but ELB has <a href="http://aws.amazon.com/developertools/2536?_encoding=UTF8&amp;jiveRedirect=1">its own set of CLI tools</a>.</p>
<p>The actual migration of our infrastructure to EC2 was similar to other infrastructure migrations I&#8217;ve done in the past, but with the added bonus of EC2&#8242;s flexibility. This means that you can set up the infrastructure roughly how you think it will need to be, and then tweak it as you go along by starting and stopping instances, changing instance types, etc., instead of having to predict things as best you can then hope for the best. Since the migration, our entire infrastructure has been successfully running in the cloud for several months, and we continue to be very happy with Amazon Web Services. We closed our account with our colo provider some time ago, then sold all our physical servers.</p>
<p>For those of you who haven&#8217;t yet started using EC2, or who haven&#8217;t got very far with it yet, lots of useful details on the practicalities of hosting on EC2 can be found in <a href="http://www.paul-norman.co.uk/2011/02/hosting-a-website-on-amazon-ec2/">this excellent series of blog posts</a> written by my friend Paul Norman. </p>
<p>There&#8217;s a lot more you can do with EC2 which I haven&#8217;t covered, but hopefully this post gives an idea of how easy it is to set up a web infrastructure on there, and by reading the documentation and following the updates from Amazon, you can easily work out which additional details you need.</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.mattbrock.co.uk/2011/03/29/using-amazons-ec2-cloud-service-to-host-our-entire-web-infrastructure/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
	</channel>
</rss>
