<?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>John Goulah</title>
	<atom:link href="http://blog.johngoulah.com/feed/" rel="self" type="application/rss+xml" />
	<link>http://blog.johngoulah.com</link>
	<description>Musings of linux, open source, and distributed systems</description>
	<lastBuildDate>Tue, 23 Apr 2013 22:59:34 +0000</lastBuildDate>
	<language>en-US</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.5</generator>
		<item>
		<title>Crossing the Production Barrier: Development at Scale</title>
		<link>http://blog.johngoulah.com/2013/04/crossing-the-production-barrier-development-at-scale/</link>
		<comments>http://blog.johngoulah.com/2013/04/crossing-the-production-barrier-development-at-scale/#comments</comments>
		<pubDate>Tue, 23 Apr 2013 22:59:34 +0000</pubDate>
		<dc:creator>jgoulah</dc:creator>
				<category><![CDATA[Conferences]]></category>
		<category><![CDATA[Databases]]></category>
		<category><![CDATA[mysql]]></category>

		<guid isPermaLink="false">http://blog.johngoulah.com/?p=995</guid>
		<description><![CDATA[Slides from my talk at Percona 2013 Crossing the Production Barrier: Development at Scale from jgoulah]]></description>
				<content:encoded><![CDATA[<p>Slides from my talk at <a href="http://www.percona.com/live/mysql-conference-2013/home" title="percona 2013" target="_blank">Percona 2013</a></p>
<p><iframe src="http://www.slideshare.net/slideshow/embed_code/19814108" width="479" height="511" frameborder="0" marginwidth="0" marginheight="0" scrolling="no" style="border:1px solid #CCC;border-width:1px 1px 0;margin-bottom:5px" allowfullscreen webkitallowfullscreen mozallowfullscreen> </iframe>
<div style="margin-bottom:5px"> <strong> <a href="http://www.slideshare.net/jgoulah/crossing-the-production-barrier-development-at-scale" title="Crossing the Production Barrier: Development at Scale" target="_blank">Crossing the Production Barrier: Development at Scale</a> </strong> from <strong><a href="http://www.slideshare.net/jgoulah" target="_blank">jgoulah</a></strong> </div>
]]></content:encoded>
			<wfw:commentRss>http://blog.johngoulah.com/2013/04/crossing-the-production-barrier-development-at-scale/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Ganglia Grill Graphs</title>
		<link>http://blog.johngoulah.com/2013/03/ganglia-grill-graphs/</link>
		<comments>http://blog.johngoulah.com/2013/03/ganglia-grill-graphs/#comments</comments>
		<pubDate>Tue, 26 Mar 2013 03:55:53 +0000</pubDate>
		<dc:creator>jgoulah</dc:creator>
				<category><![CDATA[Graphs]]></category>
		<category><![CDATA[cyberq]]></category>
		<category><![CDATA[ganglia]]></category>
		<category><![CDATA[gmetric]]></category>
		<category><![CDATA[graphs]]></category>
		<category><![CDATA[grill]]></category>

		<guid isPermaLink="false">http://blog.johngoulah.com/?p=954</guid>
		<description><![CDATA[One of my favorite things to do (other than stare at a computer all day) is to cook. I recently bought a new smoker grill, and quickly realized that I was running outside the entire day to tune the vents to keep the temperature in the range I wanted for a 12 hour slow cook. [...]]]></description>
				<content:encoded><![CDATA[<p>One of my favorite things to do (other than stare at a computer all day) is to cook.  I recently bought a new smoker grill,  and quickly realized that I was running outside the entire day to tune the vents to keep the temperature in the range I wanted for a 12 hour slow cook.  I did a little bit of research and turns out there are some decent devices that provide a fan to keep the temperature consistent.  Even better,  there was one equipped with a web server that can be accessed over wi-fi, called the <a href="http://store.thebbqguru.com/weborderentry/CyberQ%20WiFi" title="CyberQ" target="_blank">CyberQ</a>. </p>
<p>Its not cheap, but life is short, and it will maintain the temperature you set up to 475 degrees Fahrenheit.  I already have Ganglia setup in my house for basic server monitoring (you run linux servers in your house too right?) and since the device connects to the home network I figured it would be easy enough to query and graph.  Luckily the people that made this device were nice enough to provide an XML endpoint that is easy to parse for all the information you want.  There are a few different endpoints but I request the <em>config.xml</em> version since it gives you the most information.  </p>
<p>So I <a href="https://github.com/jgoulah/gmetric-cyberq" title="gmetric-cyberq" target="_blank">wrote a gmetric</a> to query the box and throw the data into a few ganglia graphs.  As of this writing I graph the fan speed, the pit temp, and the three food temps it can provide. There is a bunch of other data returned,  but this was most important for me initially. </p>
<p>While this device would normally be used for low and slow cooks, I did a faster high temp grill cook just to try it out.  I set the temp to the max of 475 and you can see it took a bit of time to bring the grill up to that temp, and the fan output to get it there.  Once it got there, you can see it drop when I opened up the lid to put the food on.  The rest of the fluctuation is due to opening the lid and flipping the food:</p>
<p><a href="http://blog.johngoulah.com/2013/03/ganglia-grill-graphs/pit-temp/" rel="attachment wp-att-955"><img src="http://blog.johngoulah.com/wp-content/uploads/2013/03/pit-temp.jpg" alt="pit-temp" width="482" height="184" class="alignleft size-full wp-image-955" /></a></p>
<p><a href="http://blog.johngoulah.com/2013/03/ganglia-grill-graphs/fan/" rel="attachment wp-att-960"><img src="http://blog.johngoulah.com/wp-content/uploads/2013/03/fan.jpg" alt="fan" width="480" height="183" class="alignleft size-full wp-image-960" /></a></p>
<p><br style="clear:both;"/></p>
<p>and then here is the food, two steaks cook rather quickly at that high of a temperature:</p>
<p><br style="clear:both;"/></p>
<p><a href="http://blog.johngoulah.com/2013/03/ganglia-grill-graphs/food1/" rel="attachment wp-att-962"><img src="http://blog.johngoulah.com/wp-content/uploads/2013/03/food1.jpg" alt="food1" width="480" height="185" class="alignleft size-full wp-image-962" /></a></p>
<p><a href="http://blog.johngoulah.com/2013/03/ganglia-grill-graphs/food-temp/" rel="attachment wp-att-961"><img src="http://blog.johngoulah.com/wp-content/uploads/2013/03/food-temp.jpg" alt="food-temp" width="480" height="183" class="alignleft size-full wp-image-961" /></a></p>
<p><br style="clear:both;"/></p>
]]></content:encoded>
			<wfw:commentRss>http://blog.johngoulah.com/2013/03/ganglia-grill-graphs/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Building Your Own Cloud From Scratch</title>
		<link>http://blog.johngoulah.com/2013/01/building-your-own-cloud/</link>
		<comments>http://blog.johngoulah.com/2013/01/building-your-own-cloud/#comments</comments>
		<pubDate>Tue, 22 Jan 2013 01:50:23 +0000</pubDate>
		<dc:creator>jgoulah</dc:creator>
				<category><![CDATA[Cloud Computing]]></category>
		<category><![CDATA[Systems]]></category>
		<category><![CDATA[cloud]]></category>
		<category><![CDATA[debian]]></category>
		<category><![CDATA[kvm]]></category>
		<category><![CDATA[libvirt]]></category>
		<category><![CDATA[qemu]]></category>
		<category><![CDATA[virt-install]]></category>

		<guid isPermaLink="false">http://blog.johngoulah.com/?p=890</guid>
		<description><![CDATA[Intro There are a lot of private cloud solutions out there with great things built into them already to complete a full cloud stack &#8211; networking, dashboards, storage, and a framework that puts all the pieces together, amongst other things. But there is also a decent amount of overhead to getting these frameworks setup, and [...]]]></description>
				<content:encoded><![CDATA[<h2>Intro</h2>
<p>There are a lot of private <a href="http://www.openstack.org/" title="openstack" target="_blank">cloud</a> <a href="http://www.eucalyptus.com/" title="eucalyptus" target="_blank">solutions</a> out there with great things built into them already to complete a full cloud stack &#8211; networking, dashboards, storage, and a framework that puts all the pieces together, amongst other things. But there is also a decent amount of overhead to getting these frameworks setup, and maybe you want more flexibility over some of the components, or even just something a little more homegrown. What might a lightweight cloud machine bootstrapping process look like if it where implemented from scratch?</p>
<h2>Getting Started</h2>
<p>We can use <a href="http://libvirt.org/" title="libvirt" target="_blank">libvirt</a> and <a href="http://wiki.qemu.org/KVM" title="kvm-qemu" target="_blank">KVM/QEMU</a> to put something reasonably robust together,  start by installing those packages:</p>
<pre>apt-get install qemu-kvm libvirt libvirt-bin virtinst virt-viewer</pre>
<p>The next important thing is to setup a <a href="http://wiki.debian.org/BridgeNetworkConnections#Libvirt_and_bridging" title="libvirt and bridging" target="_blank">bridge</a> for proper networking on this host.  This will allow the guests to use the bridge to communicate on the same network. There should be a few articles <a href="http://wiki.libvirt.org/page/Networking#Altering_the_interface_config" target="_blank">out there</a> that can help you set this up, but the basics are that you want your bridge assigned the IP that your eth0 interface previously had, and then add the eth0 interface to the bridge. In this example <em>192.168.1.101</em> is the IP of the host machine:</p>
<pre>
# cat /etc/network/interfaces
auto lo
iface lo inet loopback

iface eth0 inet manual

auto br0
iface br0 inet static
  address 192.168.1.101
  netmask 255.255.255.0
  gateway 192.168.1.1
  network 192.168.1.0
  bridge_ports eth0
  
ifup br0
</pre>
<h2>Building the Image</h2>
<p>The first step is setting up a base template that you create your instances from.  So grab an iso to start from,  we&#8217;ll use debian, but this process works with any distro:</p>
<pre>% wget http://cdimage.debian.org/debian-cd/6.0.6/amd64/iso-cd/debian-6.0.6-amd64-netinst.iso</pre>
<p>And allocate a file on disk to the size you&#8217;d like your template to be.  I created one here at 8GB, it can always be expanded later, so this should only need to be big enough to hold the initial base image that all instances will start from. Generally smaller is better because of the copy step when instances get created later. </p>
<pre>% dd if=/dev/zero of=/var/lib/libvirt/images/debbase.img bs=1M count=8192</pre>
<p>Now you can start the linux installation, noting the <em>&#8211;graphics</em> args for the ability to connect with VNC.  Our installation target disk is the one we created above, <em>debbase.img</em>, and we are giving it 512M RAM and 1 CPU. </p>
<pre>% virt-install --name=virt-base-deb --ram=512 --graphics vnc,listen=0.0.0.0  --network=bridge=br0 \
--accelerate --virt-type=kvm --vcpus=1 --cpuset=auto --cpu=host --disk /var/lib/libvirt/images/debbase.img \
--cdrom debian-6.0.6-amd64-netinst.iso</pre>
<p>Once thats started up you can use VNC on your client machine to connect to this instance graphically and run through the normal install setup.  There are <a href="http://en.wikipedia.org/wiki/Virtual_Network_Computing#See_also" title="vnc clients" target="_blank">plenty of clients</a> out there but a decent one is <a href="http://sourceforge.net/projects/cotvnc/" title="chicken of the vnc" target="_blank">Chicken of the VNC</a>.  Its also possible at this step that you&#8217;d create the image off a <a href="http://en.wikipedia.org/wiki/Preboot_Execution_Environment">PXE boot</a> or similar bootstrapping mechanism.</p>
<h4>Extract the Partition</h4>
<p>Here we take advantage of QEMU ability to load Linux kernels and init ramdisks directly, thereby circumventing bootloaders such as GRUB. It then can be launched with the physical partition containing the root filesystem as the virtual disk.</p>
<p>There are two steps to make this work.  First you&#8217;ll need the vmlinuz and initrd files, and the easiest way to get those is to copy them from the base image we setup above:</p>
<pre>
% scp BASEIP:/boot/vmlinuz-2.6.32-5-amd64 /var/lib/libvirt/kernels/
% scp BASEIP:/boot/initrd.img-2.6.32-5-amd64 /var/lib/libvirt/kernels/
</pre>
<p>The next step is to extract the root partition from that same base image. We want to take a look at how those partitions are laid out so that we can get the right numbers to pass to the <a href="http://en.wikipedia.org/wiki/Dd_(Unix)" title="dd" target="_blank">dd</a> command.  </p>
<pre>
% sfdisk -l -uS /var/lib/libvirt/images/debbase.img

Disk /var/lib/libvirt/images/debbase.img: 1044 cylinders, 255 heads, 63 sectors/track
Warning: extended partition does not start at a cylinder boundary.
DOS and Linux will interpret the contents differently.
Units = sectors of 512 bytes, counting from 0

   Device Boot    Start       End   #sectors  Id  System
/var/lib/libvirt/images/debbase.img1   *      2048  15988735   15986688  83  Linux
/var/lib/libvirt/images/debbase.img2      15990782  16775167     784386   5  Extended
/var/lib/libvirt/images/debbase.img3             0         -          0   0  Empty
/var/lib/libvirt/images/debbase.img4             0         -          0   0  Empty
/var/lib/libvirt/images/debbase.img5      15990784  16775167     784384  82  Linux swap / Solaris
</pre>
<p>We are going to pull the first partition out, note how the numbers line up to the first line corresponding to <em>debbase.img1</em> line. We start at sector 2048 and get 15986688 sectors of 512 bytes each:</p>
<pre>% dd if=/var/lib/libvirt/images/debbase.img of=/var/lib/libvirt/debian-tmpl skip=2048 count=15986688 bs=512</pre>
<h4>Templatize the Image</h4>
<p>Now we have a disk file that serves as our image template. There&#8217;s a few things we want to change directly on this template. Note that we are using a few all caps placeholders ending in <em>-TMPL</em> that we&#8217;ll replace later with sed. We can edit the templates files by mounting the disk:</p>
<pre>
% mkdir -p /tmp/newtmpl
% mount -t ext3 -o loop /var/lib/libvirt/debian-tmpl /tmp/newtmpl
% chroot /tmp/newtmpl
</pre>
<p>Note at this point we are <a href="http://en.wikipedia.org/wiki/Chroot" title="chroot" target="_blank">chrooted</a> and these commands are acting against our template disk file. </p>
<p>Clear out the old IPs tied to our NIC when the base image networking was setup:</p>
<pre>
% echo "" > /etc/udev/rules.d/70-persistent-net.rules
</pre>
<p>We&#8217;re going to put a placeholder for our hostname in <em>/etc/hostname</em>:</p>
<pre>
% echo "HOSTNAME-TMPL" > /etc/hostname
</pre>
<p>Set a nameserver template in <em>/etc/resolv.conf</em>:</p>
<pre>
% echo "nameserver NAMESERVER-TMPL" > /etc/resolv.conf 
</pre>
<p>In the file <em>/etc/network/interfaces</em>:</p>
<pre>

# The loopback network interface
auto lo
iface lo inet loopback

auto eth0
iface eth0 inet static
address ADDRESS-TMPL
netmask NETMASK-TMPL
gateway GATEWAY-TMPL
</pre>
<p>This will give us console access when we boot it.  Make sure <em>/etc/inittab</em> has this line (usually just uncomment it):</p>
<pre>
T0:23:respawn:/sbin/getty -L ttyS0 9600 vt100
</pre>
<h2>Creating an Instance</h2>
<p>Now we have all the pieces together to launch an instance from our image.  This script will create the instance given the IP and hostname.  It does no error checking for readability reasons, and is well commented so that you know whats going on:</p>
<pre>
#!/bin/bash

# read in '<ip> <host>' from command line
virt_ip=$1
virt_host=$2

# build the fqdn based off the short host name
virt_fqdn=${virt_host}.linux.bogus

# fill in your network defaults
virt_gateway=192.168.1.1
virt_netmask=255.255.225.0
virt_nameserver=192.168.1.101

# how the disk/ram/cpu is sized
virt_disk=10G
virt_ram=512
virt_cpus=1

# random mac address
virt_mac=$(openssl rand -hex 6 | sed 's/\(..\)/\1:/g; s/.$//')

cp /var/lib/libvirt/images/debian-tmpl /var/lib/libvirt/images/${virt_host}-disk0

# optionally resize the disk
qemu-img resize /var/lib/libvirt/images/${virt_host}-disk0 ${virt_disk}
loopback=`losetup -f --show /var/lib/libvirt/images/${virt_host}-disk0`
fsck.ext3 -fy $loopback
resize2fs $loopback ${virt_disk}
losetup -d $loopback

mountbase=/tmp/${virt_host}
mkdir -p ${mountbase}
mount -o loop /var/lib/libvirt/images/${virt_host}-disk0 ${mountbase}

# replace our template vars
sed -i -e "s/ADDRESS-TMPL/$virt_ip/g" \
       -e "s/NETMASK-TMPL/$virt_netmask/g" \
       -e "s/GATEWAY-TMPL/$virt_gateway/g" \
       -e "s/HOSTNAME-TMPL/$virt_fqdn/g" \
       -e "s/NAMESERVER-TMPL/$virt_nameserver/g" \
  ${mountbase}/etc/network/interfaces \
  ${mountbase}/etc/resolv.conf \
  ${mountbase}/etc/hostname

# unmount and remove the tmp files
umount /tmp/${virt_host}
rm -rf /tmp/${virt_host}*

# run a file system check on the disk
fsck.ext3 -pv /var/lib/libvirt/images/${virt_host}-disk0

# specify the kernel and initrd (these we copied with scp earlier)
vmlinuz=/var/lib/libvirt/kernels/vmlinuz-2.6.32-5-amd64
initrd=/var/lib/libvirt/kernels/initrd.img-2.6.32-5-amd64

# install the new domain with our specified parameters for cpu/disk/memory/network
virt-install --name=$virt_host --ram=$virt_ram \
--disk=path=/var/lib/libvirt/images/${virt_host}-disk0,bus=virtio,cache=none \
--network=bridge=br0 --import --accelerate --vcpus=$virt_cpus --cpuset=auto --mac=${virt_mac} --noreboot --graphics=vnc \
--cpu=host --boot=kernel=$vmlinuz,initrd=$initrd,kernel_args="root=/dev/vda console=ttyS0 _device=eth0 \
_ip=${virt_ip} _hostname=${virt_fqdn} _gateway=${virt_gateway} _dns1=${virt_nameserver} _netmask=${virt_netmask}"

# start it up
virsh start $virt_host
</pre>
<p>assuming we named it <em>buildserver</em>, run the above like:</p>
<pre>
% buildserver 192.168.1.197 jgoulah
</pre>
<h2>Conclusion</h2>
<p>This is really just the first step, but now that you can bring a templated disk up you can decide a little more about how you&#8217;d like networking to work for your cloud.  You can either continue to use static IP assignment as shown here, and use <a href="http://en.wikipedia.org/wiki/Nsupdate" title="nsupdate" target="_blank">nsupdate</a> to insert dns entries when new guests come up,  or you can set things up such that the base image uses dhcp, and you can <a href="http://lani78.wordpress.com/2012/07/23/make-your-dhcp-server-dynamically-update-your-dns-records-on-ubuntu-12-04-precise-pangolin/" target="_blank">configure your dhcp server</a> <a href="http://www.held.org.il/blog/2011/01/make-dhcp-auto-update-dynamic-dns/" target="_blank">to update records in dns</a> when clients come online.  You may also want to bake your favorite config management system into the template so that you can bootstrap the nodes and maintain configurations on them. Have fun!</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.johngoulah.com/2013/01/building-your-own-cloud/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Ditching Vino for X11vnc</title>
		<link>http://blog.johngoulah.com/2013/01/ditching-vino-for-x11vnc/</link>
		<comments>http://blog.johngoulah.com/2013/01/ditching-vino-for-x11vnc/#comments</comments>
		<pubDate>Tue, 01 Jan 2013 19:07:30 +0000</pubDate>
		<dc:creator>jgoulah</dc:creator>
				<category><![CDATA[Systems]]></category>
		<category><![CDATA[chef]]></category>
		<category><![CDATA[cookbook]]></category>
		<category><![CDATA[gnome]]></category>
		<category><![CDATA[opscode]]></category>
		<category><![CDATA[vino]]></category>
		<category><![CDATA[x11vnc]]></category>

		<guid isPermaLink="false">http://blog.johngoulah.com/?p=872</guid>
		<description><![CDATA[I&#8217;d been using gnome vino as a VNC server for years on my media computer. This way I can use touchpad to control it from my iPad. It works fine, but a little bit clunky and badly documented, plus its tied directly to gnome. The other day I woke up to a filled drive (~2TB) [...]]]></description>
				<content:encoded><![CDATA[<p>I&#8217;d been using <a href="http://en.wikipedia.org/wiki/Vino_(VNC_server)" title="vino" target="_blank">gnome vino</a> as a <a href="http://en.wikipedia.org/wiki/Virtual_Network_Computing" title="VNC" target="_blank">VNC server</a> for years on my media computer.  This way I can use <a href="https://itunes.apple.com/us/app/touchpad/id297623931?mt=8" title="touchpad" target="_blank">touchpad</a> to control it from my iPad.  It works fine,  but a little bit clunky and badly documented, plus its tied directly to gnome.  The other day I woke up to a filled drive (~2TB) of vino errors.  I killed it off and cleaned up the error log file and tried to start it up again.  No go this time due to some startup errors.  This isn&#8217;t the first time I&#8217;ve fought with it,  surely something better exists.</p>
<p>This led me to <a href="http://en.wikipedia.org/wiki/X11vnc" title="X11vnc" target="_blank">X11vnc</a>.  A bit of fresh air its fairly easy to setup and get going very quickly.  I&#8217;ll first show how to do it manually and then present my open sourced chef cookbook.</p>
<h2>Manual Install</h2>
<p>First thing is to install it:</p>
<pre>sudo apt-get install x11vnc</pre>
<p>Setup a password file:</p>
<pre>sudo x11vnc -storepasswd YOUR_PASS_HERE /etc/x11vnc.pass</pre>
<p>Create an upstart config:</p>
<pre>sudo touch /etc/init/x11vnc.conf</pre>
<p>Open it and put this into it:</p>
<pre>
start on login-session-start
script
x11vnc -xkb -noxrecord -noxfixes -noxdamage -display :0 -rfbauth /etc/x11vnc.pass \
 -auth /var/run/lightdm/root/:0 -forever -bg -o /var/log/x11vnc.log
end script
</pre>
<p>and start it up:</p>
<pre>sudo service x11vnc start</pre>
<p>Simple, easy, and just works.  </p>
<h2>Chef Cookbook</h2>
<p>Naturally, I ported this to a <a href="http://community.opscode.com/cookbooks/x11vnc" title="x11vnc" target="_blank">chef cookbook which you can find here</a>.  I have to admit I&#8217;m not totally happy with it yet, mainly because it doesn&#8217;t restart x11vnc on config changes.  In some cases such as our production servers, we actually prefer this so that we don&#8217;t accidentally roll out a broken config change and have an auto-restart bring everything to its knees (there are some ways to avoid this but thats another post).  In any case on my home computer I prefer it to restart if I make changes,  but I&#8217;m struggling to get upstart to stop the process correctly due to what seems to be some disassociation with its pid file.  The other thing is the recipe currently assumes you are using Ubuntu or something similar,  but can easily be extended.  Hope this helps someone else out there!</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.johngoulah.com/2013/01/ditching-vino-for-x11vnc/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Quick Tip: Find the QEMU VM to Virtual Interface Mapping</title>
		<link>http://blog.johngoulah.com/2012/12/find-the-qemu-to-virtual-interface-mapping/</link>
		<comments>http://blog.johngoulah.com/2012/12/find-the-qemu-to-virtual-interface-mapping/#comments</comments>
		<pubDate>Thu, 27 Dec 2012 21:13:26 +0000</pubDate>
		<dc:creator>jgoulah</dc:creator>
				<category><![CDATA[Debugging]]></category>
		<category><![CDATA[Systems]]></category>
		<category><![CDATA[kvm]]></category>
		<category><![CDATA[libvirt]]></category>
		<category><![CDATA[qemu]]></category>
		<category><![CDATA[virsh]]></category>
		<category><![CDATA[virtual interface]]></category>
		<category><![CDATA[vnet]]></category>

		<guid isPermaLink="false">http://blog.johngoulah.com/?p=867</guid>
		<description><![CDATA[The other day we were getting some messages on our network switch that a host was flapping between ports. It turns out we had two virtual hosts on different machines using the same MAC address (not good). We had the interface and MAC information, and wanted to find what vm domains mapped to these. Its [...]]]></description>
				<content:encoded><![CDATA[<p>The other day we were getting some messages on our network switch that a host was flapping between ports. It turns out we had two virtual hosts on different machines using the same MAC address (not good).  We had the interface and MAC information, and wanted to find what vm domains mapped to these.  Its easy if you know the domain name of the vm node, you can get back the associated information like so:</p>
<pre>
% sudo virsh domiflist goulah  
Interface  Type       Source     Model       MAC
-------------------------------------------------------
vnet2      bridge     br0        -           52:54:00:19:40:18
</pre>
<p>But if you only have the virtual interface, how would you get the domain?  I remembered virsh dumpxml will show all of the dynamic properties about the VM, including those which are not available in the static XML definition of the VM in <em>/etc/libvirt/qemu/foo.xml</em>. Which vnetX interface is attached to which VM is one of these additional dynamic properties. So we can grep for this! I concocted up a simple (not very elegant) function which given the vnet interface will return the domain associated to it:</p>
<pre>
function find-vnet() { for vm in $(sudo virsh list | grep running | awk '{print $2}'); do sudo virsh dumpxml $vm|grep -q "$1" &#038;&#038; echo $vm; done }
</pre>
<p>It just looks through all the running domains and prints the domain name if it finds the interface you&#8217;re looking for. So now you can do:</p>
<pre>
% find-vnet vnet2
goulah
</pre>
<p>I wonder if others out there have a clever way of doing this or if this is really the best way? If you know of a better way leave a comment. Perhaps the problem is not common enough that a libvirt built-in command exists.</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.johngoulah.com/2012/12/find-the-qemu-to-virtual-interface-mapping/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Looking Under the Covers of StatsD</title>
		<link>http://blog.johngoulah.com/2012/10/looking-under-the-covers-of-statsd/</link>
		<comments>http://blog.johngoulah.com/2012/10/looking-under-the-covers-of-statsd/#comments</comments>
		<pubDate>Sat, 27 Oct 2012 17:24:06 +0000</pubDate>
		<dc:creator>jgoulah</dc:creator>
				<category><![CDATA[Debugging]]></category>
		<category><![CDATA[carbon]]></category>
		<category><![CDATA[etsy]]></category>
		<category><![CDATA[Graphite]]></category>
		<category><![CDATA[netcat]]></category>
		<category><![CDATA[node.js]]></category>
		<category><![CDATA[StatsD]]></category>
		<category><![CDATA[tcpdump]]></category>

		<guid isPermaLink="false">http://blog.johngoulah.com/?p=844</guid>
		<description><![CDATA[Intro StatsD is a network daemon that runs on the Node.js platform and listens for statistics, like counters and timers. Packets are then sent to one or more pluggable backend services. The default service is Graphite. Every 10 seconds the stats sent to StatsD are aggregated and forwarded on to this backend service. It can [...]]]></description>
				<content:encoded><![CDATA[<h2>Intro</h2>
<p><a href="https://github.com/etsy/statsd" title="statsd" target="_blank">StatsD</a> is a network daemon that runs on the <a href="http://nodejs.org/" title="node.js" target="_blank">Node.js</a> platform and listens for statistics, like counters and timers.   Packets are then sent to one or more pluggable backend services. The default service is <a href="http://graphite.readthedocs.org/" title="graphite" target="_blank">Graphite</a>.  Every 10 seconds the stats sent to StatsD are aggregated and forwarded on to this backend service.  It can be useful to see what stats are going through both sides of the connection &#8211; from the client to StatsD and then from StatsD to Graphite. </p>
<h2>Management Interface</h2>
<p>The first thing to know is there is a simple management interface built in that you can interact with.  By using either telnet or <a href="http://netcat.sourceforge.net/" title="netcat" target="_blank">netcat</a> you can find information directly from the command line.  By default this is listening on port 8126, but that is configurable in StatsD.   </p>
<p>The simplest thing to do is send the <em>stats</em> command:</p>
<pre>% echo "stats" | nc statsd.domain.com 8126          
uptime: 365
messages.last_msg_seen: 0
messages.bad_lines_seen: 0
graphite.last_flush: 5
graphite.last_exception: 365</pre>
<p>This tells us a bit about the current state of the server, including the uptime, and the last time a flush was sent to the backend. Our server has only been running for 365 seconds.  It also lets us know when the length of time since StatsD received its last message, bad lines sent to it,  and the last exception.  Things look pretty normal.</p>
<p>You can also get a dump of the current timers:</p>
<pre>(echo "timers" | nc statsd.domain.com 8126) &gt; timers</pre>
<p>As well as a dump of the current counters:</p>
<pre>(echo "counters" | nc statsd.domain.com 8126) &gt; counters</pre>
<p>Take a look at the files generated to get an idea of the metrics StatsD is currently holding.</p>
<h2>On the Wire</h2>
<p>Beyond that, its fairly simple to debug certain StatsD or Graphite issues by looking at whats going on in realtime on the connection itself. On the StatsD host,  be sure you&#8217;re looking at traffic across the default StatsD listen port (8125), and specifically here I&#8217;m grep&#8217;ing for the stat that I&#8217;m about to send which will be called <em>test.goulah.myservice</em>:</p>
<pre>% sudo tcpdump -t -A -s0 dst port 8125 | grep goulah
listening on eth0, link-type EN10MB (Ethernet), capture size 65535 bytes</pre>
<p>Then we fake a simple client on the command line to send a sample statistic to StatsD like so: </p>
<pre>echo "test.goulah.myservice:1|c" | nc -w 1 -u statsd.domain.com 8125</pre>
<p>Back on the StatsD host,  you can see the metric come through:</p>
<pre>e......."A.test.goulah.myservice:1|c</pre>
<p>There is also the line of communication from StatsD to the Graphite host.  Every 10 seconds it flushes its metrics.  Start up another tcpdump command, this time on port 2003, which is the port carbon is listening on the Graphite side:</p>
<pre>% sudo tcpdump -t -A -s0 dst port 2003 | grep goulah
listening on eth0, link-type EN10MB (Ethernet), capture size 65535 bytes</pre>
<p>Every 10 seconds you should see a bunch of stats go by.  This is what you are flushing into the Graphite backend.  In our case I&#8217;m doing a grep for goulah, and showing the data aggregated for the metric we sent earlier.  Notice there are two metrics here that look slightly different than the metric we sent though.  StatsD sends two lines for every metric.  The first is the aggregated metric prefixed with the <em>stats</em> namespace. StatsD also sends the raw data prefixed by <em>stats_counts</em>.  This is the difference in the <em>value per second</em> calculated and the raw value.  In our case they identical: </p>
<pre>stats.test.goulah.myservice 0 1351355521
stats_counts.test.goulah.myservice 0 1351355521</pre>
<h2>Conclusion</h2>
<p>Now we can get a better understanding of what StatsD is doing under the covers on our system.  If metrics don&#8217;t show up on the Graphite side it helps to break things into digestible pieces to understand where the problem lies.  If the metrics aren&#8217;t even getting to StatsD,  then of course they can&#8217;t make it to Graphite.  Or perhaps they are getting to StatsD but you are not seeing the metrics you would expect when you look at the graphs.  This is a good start on digging into those types of problems.</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.johngoulah.com/2012/10/looking-under-the-covers-of-statsd/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Proxying Your iPad/iPhone Through OpenVPN</title>
		<link>http://blog.johngoulah.com/2012/10/proxying-your-ipadiphone-through-openvpn/</link>
		<comments>http://blog.johngoulah.com/2012/10/proxying-your-ipadiphone-through-openvpn/#comments</comments>
		<pubDate>Sat, 06 Oct 2012 23:29:18 +0000</pubDate>
		<dc:creator>jgoulah</dc:creator>
				<category><![CDATA[iOS]]></category>
		<category><![CDATA[VPN]]></category>
		<category><![CDATA[ios]]></category>
		<category><![CDATA[iPad]]></category>
		<category><![CDATA[iphone]]></category>
		<category><![CDATA[openvpn]]></category>
		<category><![CDATA[PAC]]></category>
		<category><![CDATA[proxy]]></category>
		<category><![CDATA[SOCKS]]></category>
		<category><![CDATA[virtual private network]]></category>

		<guid isPermaLink="false">http://blog.johngoulah.com/?p=813</guid>
		<description><![CDATA[Intro It comes up often how to connect to our office openvpn network using an iPad or iPhone. On OSX its pretty simple, use Viscosity or Tunnelblick. But to my knowledge there is nothing like that for iDevices. However its possible to connect these using a SOCKS proxy. The SOCKS server lives on your laptop [...]]]></description>
				<content:encoded><![CDATA[<h2>Intro</h2>
<p>It comes up often how to connect to our office <a title="openvpn" href="http://openvpn.net/" target="_blank">openvpn</a> network using an iPad or iPhone. On OSX its pretty simple, use <a title="viscosity" href="http://www.sparklabs.com/viscosity/" target="_blank">Viscosity</a> or <a title="tunnelblick" href="http://code.google.com/p/tunnelblick/" target="_blank">Tunnelblick</a>. But to my knowledge there is nothing like that for iDevices. However its possible to connect these using a SOCKS proxy. The SOCKS server lives on your laptop connected to the VPN, and the iPhone/iPad will be setup to connect through that. Obviously you should only do this on a secured wireless network and/or secure the SOCKS server so that only you have access. I wrote these notes a couple years ago and figured its worth sharing since it comes up once in a while.</p>
<h2>Setting Up the SOCKS Server</h2>
<p>Setting up the server is really easy, we can use ssh &#8211; just run this command on your laptop that is connected to your VPN</p>
<pre>ssh -N -D 0.0.0.0:1080 localhost</pre>
<p>If you want it to run in the background also use the -f option. You may also want to setup some access control with <a title="iptables" href="http://en.wikipedia.org/wiki/Iptables" target="_blank">iptables</a>, which is a bit out of scope of this article but more information can be found <a title="socks5" href="http://www.catonmat.net/blog/linux-socks5-proxy" target="_blank">here</a>.</p>
<h2>Setting Up the iPhone/iPad to use SOCKS</h2>
<h3>Setup the PAC File</h3>
<p>The only way to configure the iPhone/iPad to use SOCKS is to setup a <a title="PAC" href="http://en.wikipedia.org/wiki/Proxy_auto-config" target="_blank">PAC file</a>. Create a file with the <em>.pac</em> extension, and put this into it:</p>
<pre>function FindProxyForURL(url, host)
{
return "SOCKS 192.168.X.XXX";
}</pre>
<p>Make sure to use the IP address of your laptop that we setup the SOCKS server on. Now put this file in any web accessible location. It doesn&#8217;t matter if its internal to your network or external, as long as you can access it from the web. How to actually serve a page is beyond the scope of this article, but if you&#8217;ve gotten this far you probably know how to do this.</p>
<h2>Configure the iPhone/iPad</h2>
<p>Now you just have to tell the iPad to use the PAC file so that it will proxy web requests through the laptops VPN.</p>
<p>Click:  <strong>Settings</strong> -&gt; <strong>WiFi</strong></p>
<p>Then click the blue arrow to the right of your access point and under HTTP Proxy choose Auto. In the URL field, put the full URL to the PAC file that we setup. Make sure to put the <em>http://</em> protocol in this URL line. For example this may look something like: http://yourserver.com/myproxy.pac</p>
<p>Sometimes getting this setting to stick is tricky. I recommend clicking out of the text field into another field and letting the iPhone spinner in the upper left finish.</p>
<h2>Conclusion</h2>
<p>If you did everything right you should be able to hit websites behind your VPN connection. One way to debug that its working is to startup ssh with the -vvv option. When you request pages through the proxy you will see a bunch of output. If there is no output you&#8217;re not using the proxy.</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.johngoulah.com/2012/10/proxying-your-ipadiphone-through-openvpn/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Development is Production Too</title>
		<link>http://blog.johngoulah.com/2012/07/development-is-production-too/</link>
		<comments>http://blog.johngoulah.com/2012/07/development-is-production-too/#comments</comments>
		<pubDate>Sat, 21 Jul 2012 01:56:27 +0000</pubDate>
		<dc:creator>jgoulah</dc:creator>
				<category><![CDATA[Conferences]]></category>
		<category><![CDATA[chef]]></category>
		<category><![CDATA[configuration managment]]></category>
		<category><![CDATA[Deployment]]></category>
		<category><![CDATA[development]]></category>
		<category><![CDATA[environments]]></category>
		<category><![CDATA[production]]></category>

		<guid isPermaLink="false">http://blog.johngoulah.com/?p=797</guid>
		<description><![CDATA[I was at OSCON this week, and my friend Erik Kastner and I did a talk about development environments. Specifically what to avoid and how to keep environments consistent across development and production. As usual the slides are not fully explanatory without seeing the accompanying talk but here they are anyway: Development is Production Too [...]]]></description>
				<content:encoded><![CDATA[<p>I was at <a href="http://www.oscon.com/oscon2012" title="OSCON" target="_blank">OSCON</a> this week, and my friend <a href="https://twitter.com/kastner" target="_blank">Erik Kastner</a> and I did a talk about development environments.  Specifically what to avoid and how to keep environments consistent across development and production.  As usual the slides are not fully explanatory without seeing the accompanying talk but here they are anyway:</p>
<p><iframe src="http://www.slideshare.net/slideshow/embed_code/13708412?rel=0" width="427" height="356" frameborder="0" marginwidth="0" marginheight="0" scrolling="no" style="border:1px solid #CCC;border-width:1px 1px 0;margin-bottom:5px" allowfullscreen> </iframe>
<div style="margin-bottom:5px"> <strong> <a href="http://www.slideshare.net/jgoulah/development-is-production-too" title="Development is Production Too" target="_blank">Development is Production Too</a> </strong> from <strong><a href="http://www.slideshare.net/jgoulah" target="_blank">jgoulah</a></strong> </div>
]]></content:encoded>
			<wfw:commentRss>http://blog.johngoulah.com/2012/07/development-is-production-too/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Using the New &#8220;load_recipe&#8221; Chef Function with Shef</title>
		<link>http://blog.johngoulah.com/2012/05/using-the-new-load_recipe-chef-function-with-shef/</link>
		<comments>http://blog.johngoulah.com/2012/05/using-the-new-load_recipe-chef-function-with-shef/#comments</comments>
		<pubDate>Tue, 29 May 2012 02:21:17 +0000</pubDate>
		<dc:creator>jgoulah</dc:creator>
				<category><![CDATA[Coding]]></category>
		<category><![CDATA[chef]]></category>
		<category><![CDATA[config management]]></category>
		<category><![CDATA[irb]]></category>
		<category><![CDATA[ruby]]></category>
		<category><![CDATA[shef]]></category>

		<guid isPermaLink="false">http://blog.johngoulah.com/?p=782</guid>
		<description><![CDATA[If you are developing chef recipes it really helps to use the command line tool called shef. Shef is just a REPL to run chef in an interactive ruby session. If you haven&#8217;t ever tried it, you can find some nice instructions over here to get you going. Shef gives an easy way to iterate [...]]]></description>
				<content:encoded><![CDATA[<p>If you are developing <a href="http://www.opscode.com/chef/" title="chef" target="_blank">chef</a> recipes it really helps to use the command line tool called <a href="http://wiki.opscode.com/display/chef/Shef" title="shef" target="_blank">shef</a>.  Shef is just a REPL to run chef in an interactive ruby session.  If you haven&#8217;t ever tried it,  you can find some nice instructions <a href="http://blog.jonliv.es/2012/02/07/chef-development-with-shef/" title="shef" target="_blank">over here</a> to get you going. </p>
<p>Shef gives an easy way to iterate on your recipes so that you can make small changes and see the effects.   However, I found the <em>include_recipe</em> function would only load the recipe one time,  and complain that its seen the recipe before on subsequent tries.   I added a small patch that implemented a new function called <em>load_recipe</em> that will allow you to reimport the recipe. The problem is that once the recipe is loaded again,  the resource list is reimported giving us the same set of resources twice.</p>
<p>You can see the list of resources that are loaded up like so</p>
<pre>chef:recipe > puts run_context.resource_collection.all_resources
package[php]
package[php-common]</pre>
<p>If you were to call <em>load_recipe</em> again the list would double, and the new code would be run second when calling <em>run_chef</em></p>
<pre>chef:recipe > puts run_context.resource_collection.all_resources
package[php]
package[php-common]
package[php]
package[php-common]</pre>
<p>The trick is that you can clear this list with this command</p>
<pre>
run_context.resource_collection = Chef::ResourceCollection.new</pre>
<p>So to use <em>load_recipe</em> you should call the above before it to clear the current list.  This can be done in one line like so</p>
<pre>
run_context.resource_collection = Chef::ResourceCollection.new; load_recipe "php"</pre>
<p>Hopefully I&#8217;ll be able to patch things to add a <em>reload_recipe</em> that overwrites the old resources so you don&#8217;t have to use this trick,  but for now this will work to get quick iterations going.</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.johngoulah.com/2012/05/using-the-new-load_recipe-chef-function-with-shef/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Percona Live 2012 &#8211; The Etsy Shard Architecture</title>
		<link>http://blog.johngoulah.com/2012/04/percona-live-2012-the-etsy-shard-architecture/</link>
		<comments>http://blog.johngoulah.com/2012/04/percona-live-2012-the-etsy-shard-architecture/#comments</comments>
		<pubDate>Sun, 15 Apr 2012 19:58:42 +0000</pubDate>
		<dc:creator>jgoulah</dc:creator>
				<category><![CDATA[Conferences]]></category>
		<category><![CDATA[Databases]]></category>
		<category><![CDATA[Systems]]></category>
		<category><![CDATA[architecture]]></category>
		<category><![CDATA[databases]]></category>
		<category><![CDATA[etsy]]></category>
		<category><![CDATA[mysql]]></category>
		<category><![CDATA[shard]]></category>

		<guid isPermaLink="false">http://blog.johngoulah.com/?p=774</guid>
		<description><![CDATA[I attended Percona Conf in Santa Clara last week. It was a great 3 days of lots of people dropping expert MySQL knowledge. I learned a lot and met some great people. I gave a talk about the Etsy shard architecture, and had a lot of good feedback and questions. A lot of people do [...]]]></description>
				<content:encoded><![CDATA[<p>I attended <a href="http://www.percona.com/live/mysql-conference-2012/" target="_blank">Percona Conf</a> in Santa Clara last week.  It was a great 3 days of lots of people dropping expert MySQL knowledge.   I learned a lot and met some great people.</p>
<p>I gave a talk about the Etsy shard architecture,  and had a lot of good feedback and questions.  A lot of people do active/passive,  but we run everything in active/active master-master.  This helps us keep a warm buffer pool on both sides,  and if one side goes out we only lose about half of the queries until its pulled and they start hashing to the other side.   Some details on how this works in the slides below.</p>
<div style="width:425px" id="__ss_12506796"> <strong style="display:block;margin:12px 0 4px"><a href="http://www.slideshare.net/jgoulah/the-etsy-shard-architecture-starts-with-s-and-ends-with-hard" title="The Etsy Shard Architecture: Starts With S and Ends With Hard" target="_blank">The Etsy Shard Architecture: Starts With S and Ends With Hard</a></strong> <iframe src="http://www.slideshare.net/slideshow/embed_code/12506796?rel=0" width="425" height="355" frameborder="0" marginwidth="0" marginheight="0" scrolling="no"></iframe>
<div style="padding:5px 0 12px"> View more presentations from <a href="http://www.slideshare.net/jgoulah" target="_blank">jgoulah</a> </div>
</p></div>
]]></content:encoded>
			<wfw:commentRss>http://blog.johngoulah.com/2012/04/percona-live-2012-the-etsy-shard-architecture/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>
