<?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>-= n8v =-</title>
	<atom:link href="http://n8v.enteuxis.org/feed/" rel="self" type="application/rss+xml" />
	<link>http://n8v.enteuxis.org</link>
	<description></description>
	<lastBuildDate>Tue, 25 Sep 2012 00:43:19 +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>How to install JavaScript tools for Nagios</title>
		<link>http://n8v.enteuxis.org/2012/09/how-to-install-javascript-tools-for-nagios/</link>
		<comments>http://n8v.enteuxis.org/2012/09/how-to-install-javascript-tools-for-nagios/#comments</comments>
		<pubDate>Tue, 25 Sep 2012 00:43:19 +0000</pubDate>
		<dc:creator>nathan</dc:creator>
				<category><![CDATA[Figuring IT Out]]></category>
		<category><![CDATA[bash]]></category>
		<category><![CDATA[js]]></category>
		<category><![CDATA[Nagios]]></category>
		<category><![CDATA[node]]></category>
		<category><![CDATA[phantomjs]]></category>

		<guid isPermaLink="false">http://n8v.enteuxis.org/?p=573</guid>
		<description><![CDATA[Node Install Node on the Nagios machine (My Nagios XI VM running CentOS&#8230; for other platforms see nodejs.org) wget http://nodejs.tchol.org/repocfg/el/nodejs-stable-release.noarch.rpm sudo yum localinstall --nogpgcheck nodejs-stable-release.noarch.rpm sudo yum install nodejs-compat-symlinks npm rm nodejs-stable-release.noarch.rpm Install the &#8220;commander&#8221; package by TJ Holowaychuk for...]]></description>
				<content:encoded><![CDATA[<h2>Node</h2>

<p>Install Node on the Nagios machine (My Nagios XI VM running CentOS&#8230; for other platforms see nodejs.org)</p>


<div class="wp_syntax"><div class="code"><pre class="bash"><span class="kw2">wget</span> http:<span class="sy0">//</span>nodejs.tchol.org<span class="sy0">/</span>repocfg<span class="sy0">/</span>el<span class="sy0">/</span>nodejs-stable-release.noarch.rpm
<span class="kw2">sudo</span> yum localinstall <span class="re5">--nogpgcheck</span> nodejs-stable-release.noarch.rpm
<span class="kw2">sudo</span> yum <span class="kw2">install</span> nodejs-compat-symlinks npm
<span class="kw2">rm</span> nodejs-stable-release.noarch.rpm</pre></div></div>


<p>Install the &#8220;commander&#8221; package by TJ Holowaychuk for easier option processing.</p>


<div class="wp_syntax"><div class="code"><pre class="bash">$ <span class="kw2">sudo</span> <span class="re2">HTTP_PROXY</span>=<span class="re1">$HTTP_PROXY</span> npm <span class="kw2">install</span> <span class="re5">-g</span> commander
npm http GET https:<span class="sy0">//</span>registry.npmjs.org<span class="sy0">/</span>commander
npm http <span class="nu0">200</span> https:<span class="sy0">//</span>registry.npmjs.org<span class="sy0">/</span>commander
npm http GET https:<span class="sy0">//</span>registry.npmjs.org<span class="sy0">/</span>commander<span class="sy0">/</span>-<span class="sy0">/</span>commander-1.0.4.tgz
npm http GET https:<span class="sy0">//</span>registry.npmjs.org<span class="sy0">/</span>keypress
npm http <span class="nu0">200</span> https:<span class="sy0">//</span>registry.npmjs.org<span class="sy0">/</span>keypress
npm http GET https:<span class="sy0">//</span>registry.npmjs.org<span class="sy0">/</span>keypress<span class="sy0">/</span>-<span class="sy0">/</span>keypress-0.1.0.tgz
commander<span class="sy0">@</span>1.0.4 <span class="sy0">/</span>usr<span class="sy0">/</span>lib<span class="sy0">/</span>node_modules<span class="sy0">/</span>commander
└── keypress<span class="sy0">@</span>0.1.0</pre></div></div>


<h2>Install PhantomJS and CasperJS</h2>

<p>Again on the NagiosXI VM:</p>


<div class="wp_syntax"><div class="code"><pre class="bash"><span class="co0"># Get PhantomJS and install it in /opt/ with a symlink in /usr/local/bin/</span>
<span class="co0">#  http://phantomjs.org/download.html</span>
<span class="kw2">wget</span> http:<span class="sy0">//</span>phantomjs.googlecode.com<span class="sy0">/</span>files<span class="sy0">/</span>phantomjs-1.6.1-linux-x86_64-dynamic.tar.bz2
<span class="kw2">bunzip2</span> phantomjs-1.6.1-linux-x86_64-dynamic.tar.bz2
<span class="kw2">tar</span> xf phantomjs-1.6.1-linux-x86_64-dynamic.tar
&nbsp;
<span class="kw2">sudo</span> <span class="kw2">mv</span> phantomjs-1.6.1-linux-x86_64-dynamic <span class="sy0">/</span>opt<span class="sy0">/</span>
<span class="kw2">sudo</span> <span class="kw2">ln</span> <span class="re5">-s</span> <span class="sy0">/</span>opt<span class="sy0">/</span>phantomjs-1.6.1-linux-x86_64-dynamic<span class="sy0">/</span> <span class="sy0">/</span>opt<span class="sy0">/</span>phantomjs
<span class="kw2">sudo</span> <span class="kw2">ln</span> <span class="re5">-s</span> <span class="sy0">/</span>opt<span class="sy0">/</span>phantomjs<span class="sy0">/</span>bin<span class="sy0">/</span>phantomjs <span class="sy0">/</span>usr<span class="sy0">/</span>local<span class="sy0">/</span>bin<span class="sy0">/</span>
&nbsp;
<span class="kw2">which</span> phantomjs      <span class="co0"># should return /usr/local/bin/phantomjs</span>
phantomjs <span class="re5">--version</span>   <span class="co0"># should return `1.6.1` with no errors</span>
&nbsp;
<span class="co0"># Check out and install the latest CasperJS with Git</span>
<span class="co0">#   http://casperjs.org/installation.html</span>
<span class="kw2">sudo</span> yum <span class="kw2">install</span> <span class="kw2">git</span> <span class="re5">-y</span>
&nbsp;
<span class="kw2">git</span> clone https:<span class="sy0">//</span>github.com<span class="sy0">/</span>n1k0<span class="sy0">/</span>casperjs.git 
&nbsp;
<span class="kw2">sudo</span> <span class="kw2">mv</span> casperjs<span class="sy0">/</span> <span class="sy0">/</span>opt<span class="sy0">/</span>casperjs
<span class="kw2">sudo</span> <span class="kw2">ln</span> <span class="re5">-s</span> <span class="sy0">/</span>opt<span class="sy0">/</span>casperjs<span class="sy0">/</span>bin<span class="sy0">/</span>casperjs  <span class="sy0">/</span>usr<span class="sy0">/</span>local<span class="sy0">/</span>bin<span class="sy0">/</span>
&nbsp;
&nbsp;
<span class="kw2">which</span> casperjs    <span class="co0"># should return /usr/local/bin/casperjs</span>
casperjs <span class="re5">--version</span>  <span class="co0"># should return `1.0.0-RC1`</span></pre></div></div>

]]></content:encoded>
			<wfw:commentRss>http://n8v.enteuxis.org/2012/09/how-to-install-javascript-tools-for-nagios/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Looking for innocence</title>
		<link>http://n8v.enteuxis.org/2012/08/566/</link>
		<comments>http://n8v.enteuxis.org/2012/08/566/#comments</comments>
		<pubDate>Fri, 03 Aug 2012 18:04:42 +0000</pubDate>
		<dc:creator>nathan</dc:creator>
				<category><![CDATA[Figuring IT Out]]></category>
		<category><![CDATA[js]]></category>

		<guid isPermaLink="false">http://n8v.enteuxis.org/?p=566</guid>
		<description><![CDATA[I want programming computers to be like coloring with crayons and playing with duplo blocks&#8230; I just want to make computers suck less. &#8211; Ryan Dahl, creator of Nodejs.]]></description>
				<content:encoded><![CDATA[<blockquote>I want programming computers to be like coloring with crayons and playing with duplo blocks&#8230; I just want to make computers suck less.
</blockquote>

<p>&#8211; <a href="http://news.ycombinator.com/item?id=4310723">Ryan Dahl, creator of Nodejs.</a></p>
]]></content:encoded>
			<wfw:commentRss>http://n8v.enteuxis.org/2012/08/566/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Toggling light/dark Solarized color theme in Emacs 23</title>
		<link>http://n8v.enteuxis.org/2012/05/toggling-lightdark-solarized-color-theme-in-emacs-23/</link>
		<comments>http://n8v.enteuxis.org/2012/05/toggling-lightdark-solarized-color-theme-in-emacs-23/#comments</comments>
		<pubDate>Fri, 04 May 2012 20:20:28 +0000</pubDate>
		<dc:creator>nathan</dc:creator>
				<category><![CDATA[Figuring IT Out]]></category>
		<category><![CDATA[Emacs]]></category>

		<guid isPermaLink="false">http://n8v.enteuxis.org/?p=519</guid>
		<description><![CDATA[I never write about Emacs because I&#8217;m such a n00b and most of my ELisp &#8220;programming&#8221; has consisted of pasting random code from the Internet into my ~/.emacs file and hoping it works. But finally today I wrote a lick...]]></description>
				<content:encoded><![CDATA[<p>I never write about Emacs because I&#8217;m such a n00b and most of my ELisp &#8220;programming&#8221; has consisted of pasting random code from the Internet into my <var>~/.emacs</var> file and hoping it works. But finally today I wrote a lick of it and it worked!</p>

<p>I&#8217;ve been using <a href="http://ethanschoonover.com/solarized">Ethan Schoonover&#8217;s obsessively comfortable &#8220;Solarized&#8221; color scheme</a> for a while now, but I&#8217;ve become annoyed how many keys I have to mash to switch from light to dark. So I set a <a href="http://www.gnu.org/software/emacs/manual/html_node/elisp/Global-Variables.html">global variable</a> to track the current state and mapped <kbd>Ctrl-c, d</kbd> (which I at least wasn&#8217;t using) to a function to toggle between the two states.</p>


<div class="wp_syntax"><div class="code"><pre class="lisp"><span class="br0">&#40;</span><span class="kw1">when</span> window-system
&nbsp;
  <span class="co1">;; ColorTheme - see http://www.emacswiki.org/cgi-bin/wiki/ColorTheme</span>
  <span class="co1">;; and see gallery at http://www.cs.cmu.edu/~maverick/GNUEmacsColorThemeTest/</span>
  <span class="co1">;; try also M-x color-theme-select</span>
&nbsp;
  <span class="br0">&#40;</span>message <span class="st0">&quot;loading color-theme&quot;</span><span class="br0">&#41;</span>
  <span class="br0">&#40;</span>add-to-<span class="kw1">list</span> 'load-path <span class="st0">&quot;~/.emacs.d/color-theme-6.6.0&quot;</span><span class="br0">&#41;</span>
&nbsp;
  <span class="br0">&#40;</span>require 'color-theme<span class="br0">&#41;</span>
&nbsp;
  <span class="co1">;; Ethan Schoonover's Solarized theme from</span>
  <span class="co1">;; https://github.com/sellout/emacs-color-theme-solarized</span>
  <span class="br0">&#40;</span>load-file <span class="st0">&quot;~/.emacs.d/emacs-colors-solarized/color-theme-solarized.el&quot;</span><span class="br0">&#41;</span>
&nbsp;
  <span class="co1">;; Set initial theme to &quot;dark&quot;</span>
  <span class="br0">&#40;</span><span class="kw1">setq</span> dark-or-light 'dark<span class="br0">&#41;</span>
  <span class="br0">&#40;</span>color-theme-solarized dark-or-light<span class="br0">&#41;</span>
&nbsp;
  <span class="co1">;; Shortcut to toggle between light and dark</span>
  <span class="br0">&#40;</span>global-set-key <span class="br0">&#40;</span>kbd <span class="st0">&quot;C-c d&quot;</span><span class="br0">&#41;</span>
                    <span class="br0">&#40;</span><span class="kw1">lambda</span> <span class="br0">&#40;</span><span class="br0">&#41;</span>
                      <span class="br0">&#40;</span>interactive<span class="br0">&#41;</span>
		      <span class="br0">&#40;</span><span class="kw1">if</span> <span class="br0">&#40;</span><span class="kw1">eq</span> dark-or-light 'light<span class="br0">&#41;</span>
			  <span class="br0">&#40;</span><span class="kw1">setq</span> dark-or-light 'dark<span class="br0">&#41;</span>
			  <span class="br0">&#40;</span><span class="kw1">setq</span> dark-or-light 'light<span class="br0">&#41;</span>
			<span class="br0">&#41;</span>
                      <span class="br0">&#40;</span>color-theme-solarized dark-or-light<span class="br0">&#41;</span><span class="br0">&#41;</span><span class="br0">&#41;</span>
  <span class="br0">&#41;</span></pre></div></div>


<p>And ooh, I just found this awesome <a href="http://steve-yegge.blogspot.com/2008/01/emergency-elisp.html">crash course on Elisp by Steve Yegge</a> which I will certainly consult next time I have a reason to write my own (i.e., I can&#8217;t paste it from some random Internet).</p>

<p>And then after it was all over I finally found <a href="http://www.emacswiki.org/emacs/ColorTheme#toc17">some instructions for doing it</a> which would&#8217;ve been easy enough to paste.  Ah well, I&#8217;ve learned something.</p>
]]></content:encoded>
			<wfw:commentRss>http://n8v.enteuxis.org/2012/05/toggling-lightdark-solarized-color-theme-in-emacs-23/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Escapism</title>
		<link>http://n8v.enteuxis.org/2012/03/516/</link>
		<comments>http://n8v.enteuxis.org/2012/03/516/#comments</comments>
		<pubDate>Tue, 27 Mar 2012 19:32:20 +0000</pubDate>
		<dc:creator>nathan</dc:creator>
				<category><![CDATA[Figuring IT Out]]></category>

		<guid isPermaLink="false">http://n8v.enteuxis.org/?p=516</guid>
		<description><![CDATA[]]></description>
				<content:encoded><![CDATA[<p><a href="http://dilbert.com/fast/2012-03-27/"><img src="http://dilbert.com/dyn/str_strip/000000000/00000000/0000000/100000/50000/6000/100/156146/156146.strip.print.gif"></a></p>
]]></content:encoded>
			<wfw:commentRss>http://n8v.enteuxis.org/2012/03/516/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>PHPUnit for XAMPP on Windows with Cygwin</title>
		<link>http://n8v.enteuxis.org/2011/09/phpunit-for-xampp-on-windows-with-cygwin/</link>
		<comments>http://n8v.enteuxis.org/2011/09/phpunit-for-xampp-on-windows-with-cygwin/#comments</comments>
		<pubDate>Mon, 26 Sep 2011 23:30:41 +0000</pubDate>
		<dc:creator>nathan</dc:creator>
				<category><![CDATA[Figuring IT Out]]></category>
		<category><![CDATA[Cygwin]]></category>
		<category><![CDATA[PHP]]></category>
		<category><![CDATA[phpunit]]></category>
		<category><![CDATA[symfony]]></category>
		<category><![CDATA[Windows]]></category>
		<category><![CDATA[xampp]]></category>

		<guid isPermaLink="false">http://n8v.enteuxis.org/?p=510</guid>
		<description><![CDATA[Steps to get PHPUnit to run on my XAMPP setup with Cygwin, so I can write and run Symfony2 unit tests. 1. Upgrade PEAR Download http://pear.php.net/go-pear.phar to C:\xampp\php\go-pear.phar Run this in cmd.exe (cygwin prompts hosed somehow), taking all defaults c:\xampp\php&#62;go-pear.bat...]]></description>
				<content:encoded><![CDATA[<p>Steps to get PHPUnit to run on my XAMPP setup with Cygwin, so I can write and run Symfony2 unit tests.</p>

<h3>1. Upgrade PEAR</h3>

<ol>
<li><p>Download <code>http://pear.php.net/go-pear.phar</code>  to <var>C:\xampp\php\go-pear.phar</var></p></li>
<li><p>Run this <strong>in <var>cmd.exe</var></strong> (cygwin prompts hosed somehow), taking all defaults</p></li>
</ol>


<div class="wp_syntax"><div class="code"><pre class="dos">c:\xampp\php<span class="sy0">&gt;</span>go-pear.bat</pre></div></div>


<ol>
<li>Yay.</li>
</ol>


<div class="wp_syntax"><div class="code"><pre class="dos">c:\xampp\php<span class="sy0">&gt;</span>pear version
PEAR Version: 1.9.4
PHP Version: 5.3.5
Zend Engine Version: 2.3.0
Running on: Windows NT FAI1046162 6.1 build 7600 <span class="sy0">(</span>Unknow Windows version Enterpr
ise Edition<span class="sy0">)</span> i586</pre></div></div>


<h3>2. Install/upgrade PHPUnit</h3>

<p>Now we can use the cygwin shell.  Not sure <a href="http://forum.kohanaframework.org/discussion/7346/installing-phpunit-on-windows-xampp/p1">all these channels are needed</a>, I did this out of order.</p>


<div class="wp_syntax"><div class="code"><pre class="bash"><span class="kw3">cd</span> <span class="sy0">/</span>cygdrive<span class="sy0">/</span>c<span class="sy0">/</span>xampp<span class="sy0">/</span>php
pear update-channels
pear channel-discover components.ez.no
pear channel-discover pear.symfony-project.com
pear channel-discover pear.phpunit.de
&nbsp;
pear <span class="kw2">install</span> <span class="re5">--alldeps</span> phpunit<span class="sy0">/</span>PHPUnit</pre></div></div>


<h3>3. Use it</h3>

<p>XAMPP and/or PHPUnit come with a wrapper called <var>phpunit.bat</var>, which has now been upgraded, but you may need to set your <var>PHPBIN</var> environment var. Also I already have <var>c:\xampp\php</var> in my <var>$PATH</var>.</p>


<div class="wp_syntax"><div class="code"><pre class="bash"><span class="kw3">export</span> <span class="re2">PHPBIN</span>=c:<span class="sy0">/</span>xampp<span class="sy0">/</span>php<span class="sy0">/</span>php.exe
&nbsp;
<span class="kw3">cd</span> <span class="sy0">/</span>path<span class="sy0">/</span>to<span class="sy0">/</span>mysf2project
phpunit.bat <span class="re5">-c</span> app</pre></div></div>


<p>Now PHPUnit works. Make tests and make them work!</p>
]]></content:encoded>
			<wfw:commentRss>http://n8v.enteuxis.org/2011/09/phpunit-for-xampp-on-windows-with-cygwin/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Sorting, deleting from a PropelObjectCollection</title>
		<link>http://n8v.enteuxis.org/2011/06/sorting-deleting-propel-object-collectio/</link>
		<comments>http://n8v.enteuxis.org/2011/06/sorting-deleting-propel-object-collectio/#comments</comments>
		<pubDate>Thu, 30 Jun 2011 06:23:13 +0000</pubDate>
		<dc:creator>nathan</dc:creator>
				<category><![CDATA[Figuring IT Out]]></category>
		<category><![CDATA[orm]]></category>
		<category><![CDATA[PHP]]></category>
		<category><![CDATA[propel]]></category>
		<category><![CDATA[symfony]]></category>
		<category><![CDATA[symfony1.4]]></category>

		<guid isPermaLink="false">http://n8v.enteuxis.org/?p=503</guid>
		<description><![CDATA[Propel 1.6 (and Propel 1.5 before it) is pretty sweet (thank you François!). I had some confusion with my model&#8217;s array of related objects though, thinking it was a regular PHP array. Actually it&#8217;s a Collection, specifically a PropelObjectCollection, which...]]></description>
				<content:encoded><![CDATA[<p>Propel 1.6 (and Propel 1.5 before it) is pretty sweet (thank you François!). I had some confusion with my model&#8217;s array of related objects though, thinking it was a regular PHP array. Actually it&#8217;s a <em>Collection</em>, specifically a PropelObjectCollection, which implements <a href="http://www.php.net/manual/en/class.arrayobject.php">PHP 5&#8242;s ArrayObject interface</a>. <a href="http://propel.posterous.com/propel-gets-collections">You can do a lot of cool things with them.</a></p>

<h2>Sorting</h2>

<p>Not immediately obvious, however, was how to sort them. This did the trick for my case (I have a Sequence field manually re-calculable through a <a href="http://jqueryui.com/demos/sortable/">jQueryUI sortable widget</a>. Also note the cool <a href="http://php.net/manual/en/functions.anonymous.php">inline anonymous function syntax</a> available since PHP 5.3. Incidentally, I&#8217;m not sure the terms <em>lambda</em> or <em>closure</em> are helpful because they&#8217;re not <em>quite</em> like Lisp lambdas or JavaScript closures.</p>


<div class="wp_syntax"><div class="code"><pre class="php"><span class="co1">// Re-sort them by Sequence, numerically</span>
<span class="re0">$this</span><span class="sy0">-&gt;</span><span class="me1">collSegments</span><span class="sy0">-&gt;</span><span class="me1">uasort</span><span class="br0">&#40;</span><span class="kw2">function</span><span class="br0">&#40;</span><span class="re0">$a</span><span class="sy0">,</span> <span class="re0">$b</span><span class="br0">&#41;</span> <span class="br0">&#123;</span>
    <span class="kw1">return</span> <span class="re0">$a</span><span class="sy0">-&gt;</span><span class="me1">getSequence</span><span class="br0">&#40;</span><span class="br0">&#41;</span> <span class="sy0">-</span> <span class="re0">$b</span><span class="sy0">-&gt;</span><span class="me1">getSequence</span><span class="br0">&#40;</span><span class="br0">&#41;</span><span class="sy0">;</span>
<span class="br0">&#125;</span><span class="br0">&#41;</span><span class="sy0">;</span></pre></div></div>



<div class="wp_syntax"><div class="code"><pre class="php"><span class="co1">// Re-sort them as strings, case-insensitively.</span>
<span class="re0">$this</span><span class="sy0">-&gt;</span><span class="me1">collSegments</span><span class="sy0">-&gt;</span><span class="me1">uasort</span><span class="br0">&#40;</span><span class="kw2">function</span><span class="br0">&#40;</span><span class="re0">$a</span><span class="sy0">,</span> <span class="re0">$b</span><span class="br0">&#41;</span> <span class="br0">&#123;</span>
    <span class="kw1">return</span> <a href="http://www.php.net/strnatcasecmp"><span class="kw3">strnatcasecmp</span></a><span class="br0">&#40;</span><span class="re0">$a</span><span class="sy0">-&gt;</span>__toString<span class="br0">&#40;</span><span class="br0">&#41;</span><span class="sy0">,</span> <span class="re0">$b</span><span class="sy0">-&gt;</span>__toString<span class="br0">&#40;</span><span class="br0">&#41;</span><span class="sy0">;</span>
<span class="br0">&#125;</span><span class="br0">&#41;</span><span class="sy0">;</span></pre></div></div>


<h2>Deleting</h2>

<p>Thanks to the <a href="http://www.propelorm.org/docs/api/1.6/runtime/propel-runtime-collection/PropelArrayCollection.html">PropelArrayCollection API Documentation</a></p>


<div class="wp_syntax"><div class="code"><pre class="php">  <span class="coMULTI">/*
   * Remove the provided Segment object.
   *
   * @param Segment $s
   * @return Segment $s that was deleted.
   */</span>
  <span class="kw2">public</span> <span class="kw2">function</span> deleteSegment<span class="br0">&#40;</span>Segment <span class="re0">$s</span><span class="br0">&#41;</span> <span class="br0">&#123;</span>
      <span class="re0">$s</span><span class="sy0">-&gt;</span><span class="me1">delete</span><span class="br0">&#40;</span><span class="br0">&#41;</span><span class="sy0">;</span>
      <span class="re0">$key</span> <span class="sy0">=</span> <span class="re0">$this</span><span class="sy0">-&gt;</span><span class="me1">collSegments</span><span class="sy0">-&gt;</span><span class="me1">search</span><span class="br0">&#40;</span><span class="re0">$s</span><span class="br0">&#41;</span><span class="sy0">;</span>
      <span class="re0">$ret</span> <span class="sy0">=</span> <span class="re0">$this</span><span class="sy0">-&gt;</span><span class="me1">collSegments</span><span class="sy0">-&gt;</span><span class="me1">remove</span><span class="br0">&#40;</span><span class="re0">$key</span><span class="br0">&#41;</span><span class="sy0">;</span>
      <span class="kw1">return</span> <span class="re0">$s</span><span class="sy0">;</span>
  <span class="br0">&#125;</span></pre></div></div>


<p>So elsewhere,</p>


<div class="wp_syntax"><div class="code"><pre class="php">	      <span class="re0">$this</span><span class="sy0">-&gt;</span><span class="me1">deleteSegment</span><span class="br0">&#40;</span><span class="re0">$s</span><span class="br0">&#41;</span><span class="sy0">;</span></pre></div></div>

]]></content:encoded>
			<wfw:commentRss>http://n8v.enteuxis.org/2011/06/sorting-deleting-propel-object-collectio/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Relaunch the Mac OS X Dock</title>
		<link>http://n8v.enteuxis.org/2011/06/relaunch-the-macosx-dock/</link>
		<comments>http://n8v.enteuxis.org/2011/06/relaunch-the-macosx-dock/#comments</comments>
		<pubDate>Wed, 15 Jun 2011 01:50:46 +0000</pubDate>
		<dc:creator>nathan</dc:creator>
				<category><![CDATA[Figuring IT Out]]></category>
		<category><![CDATA[MacOSX]]></category>
		<category><![CDATA[snow leopard]]></category>

		<guid isPermaLink="false">http://n8v.enteuxis.org/?p=493</guid>
		<description><![CDATA[Problem On my Snow Leopard machine this kept happening. The &#8220;open&#8221; indicator (glowing silver ball under the app icon) in the Dock was flaky, only showing for a few apps though more were running. The task switcher (which you see...]]></description>
				<content:encoded><![CDATA[<h2>Problem</h2>

<p>On my Snow Leopard machine this kept happening.</p>

<ul>
<li>The &#8220;open&#8221; indicator  (glowing silver ball under the app icon) in the Dock was flaky, only showing for a few apps though more were running.</li>
<li>The task switcher (which you see when you <code>option-tab</code>/<code>alt-tab</code>) didn&#8217;t show all running apps. That RUINS it for me. I always use option-tab. </li>
<li>I hate rebooting.</li>
</ul>

<h2>Workaround&#8211;Restart the Dock process.</h2>

<p>Open Terminal&dagger; and use one command:</p>


<div class="wp_syntax"><div class="code"><pre class="bash"><span class="kw2">killall</span> <span class="re5">-HUP</span> Dock</pre></div></div>


<p>Don&#8217;t be afraid of &#8220;killall&#8221;. HUP means &#8220;Hang Up&#8221; and is the normal way of telling something to relaunch.</p>

<p><a href="http://www.acmetech.com/blog/2005/09/30/mac-os-x-restart-the-dock/">Thanks to AcmeTech&#8217;s old post</a>.</p>

<p>&dagger; Terminal is located in the Utilities folder in the Applications folder. Or the quick Spotlight way is <code>command-space</code>, <samp>Terminal</samp>.</p>
]]></content:encoded>
			<wfw:commentRss>http://n8v.enteuxis.org/2011/06/relaunch-the-macosx-dock/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Integrating Nagios with Test Driven Development</title>
		<link>http://n8v.enteuxis.org/2011/06/integrating-nagios-with-test-driven-development/</link>
		<comments>http://n8v.enteuxis.org/2011/06/integrating-nagios-with-test-driven-development/#comments</comments>
		<pubDate>Wed, 08 Jun 2011 21:31:10 +0000</pubDate>
		<dc:creator>nathan</dc:creator>
				<category><![CDATA[Giving back]]></category>
		<category><![CDATA[monitoring]]></category>
		<category><![CDATA[Nagios]]></category>
		<category><![CDATA[Perl]]></category>
		<category><![CDATA[programming]]></category>
		<category><![CDATA[sysadmin]]></category>
		<category><![CDATA[tdd]]></category>
		<category><![CDATA[testing]]></category>

		<guid isPermaLink="false">http://n8v.enteuxis.org/?p=444</guid>
		<description><![CDATA[A while back I realized something important: Monitoring tools are to the sysadmin what testing tools are to the developer. Recently I realized that there need to be more ways to bring both toolsets together. Here&#8217;s one, tying the Nagios...]]></description>
				<content:encoded><![CDATA[<p>A while back I realized something important:</p>

<blockquote>
  <p><strong>Monitoring tools are to the sysadmin what testing tools are to the developer.</strong></p>
</blockquote>

<p>Recently I realized that there need to be more ways to bring both toolsets together. Here&#8217;s one, tying the <a href="http://nagios.com">Nagios monitoring toolset</a> to anything that emits the popular <a href="http://testanything.org">Test Anything Protocol</a>.</p>

<p><span id="more-444"></span></p>

<p><img alt="" src="http://assets.nagios.com/images/header/Nagios.png" title="Nagios® logo" class="alignright" width="212" height="50" style="padding: 2em; margin: 1em" />
The <em>sysadmin community</em> loves monitoring tools. Partly because of <a href="http://www.amazon.com/Management-System-Administrators-Thomas-Limoncelli/dp/0596007833">Tom Limoncelli&#8217;s time management book</a>, I&#8217;ve been using Nagios for several years now to monitor all sorts of IT hardware and software. It includes features for scheduling check scripts and contact rules (page me during weekdays, page someone else at night), and dashboard views for the visually oriented (curiously unnecessary once you have alerting configured well). I&#8217;ve found it takes investment of time and attention to configure all the checks you want, but it&#8217;s worth it. Because of its open-source, extensible nature, Nagios is especially good for monitoring weird things that other enterprise monitoring systems aren&#8217;t even aware of.  There are a lot of <a href="http://www.nagios.org/about/propaganda/books">books about Nagios</a> available, and I&#8217;d recommend them for anyone new to Nagios. I found <a href="http://www.apress.com/9781590596098">James Trumbull&#8217;s book published by APress</a> particularly useful, though it looks like it might be due for a new edition by now.</p>

<p><img alt="" src="http://testanything.org/i/tap.png" title="TAP - Test Anything Protocol" class="alignright" width="135" height="135" style="margin:1em" />
The <em>developer community</em> has become increasingly interested in software quality control and <a href="http://en.wikipedia.org/wiki/Test-driven_development">test driven development (TDD)</a>. I first became interested because of the Perl community&#8217;s emphasis on <a href="http://qa.perl.org/phalanx/kwalitee.html">Kwalitee testing</a> ever so long ago. There are even more good books and online resources about testing than there are about monitoring. I have been noticing everywhere though, that <a href="http://en.wikipedia.org/wiki/Test_Anything_Protocol">Perl&#8217;s simple and ancient Test Anything Protocol</a> has become somewhat of a standard, with <a href="http://en.wikipedia.org/wiki/Test_Anything_Protocol#List_of_TAP_Producers">testing tools in many languages (including JavaScript, PHP, Python, Ruby, Java, C, C++, C#/VB/.NET and database-specific languages) producing it</a>. Everything from <a href="http://jc.ngo.org.uk/trac-bin/trac.cgi/wiki/LibTap">low-level unit tests in C</a> to frontend cross-browser functional testing tools like <a href="http://search.cpan.org/perldoc?Test::WWW::Selenium">Selenium</a>. And TAP is so simple, it&#8217;s easy to wrap a TAP harness around other test frameworks.</p>

<p>One strategy&#8211;from the security world&#8211;on which sysadmins and developers both agree is <strong>enumerating goodness</strong> (take note, <a href="http://www.ranum.com/security/computer_security/editorials/dumb/">&#8220;antivirus&#8221; is Doing It Wrong</a>). Basically, it&#8217;s too hard to guess all the myriad ways your technology might fail and then write monitoring or test scripts for them. Instead, focus your monitoring and testing on covering the important functionality of your product.</p>

<p>But at what level of detail should we monitor?  When the monitoring system wakes you up at 2 am, which do you want it to say?</p>

<ol>
<li><code>CRITICAL</code>. No users can log in to http://myapp/login.</li>
<li><code>CRITICAL</code>. The app can&#8217;t contact the database.</li>
<li><code>CRITICAL</code>. The database server is down/unpingable.</li>
</ol>

<p>My preference is &#8220;4. All of the above&#8221;, because the user-facing effect is sometimes hard to guess from the sysadmin-facing event (and vice versa). Nagios is good at #3 and maybe #2. #1 is more in the realm of functional testing, and your app may already have functional test scripts that could provide this sort of information.</p>

<h2>check_tap.pl</h2>

<p>A Nagios plugin for consuming <a href="http://testanything.org">Test Anything Protocol</a>. Basically it combines <a href="http://search.cpan.org/perldoc?Nagios::Plugin">Test::Harness</a> with <a href="http://search.cpan.org/perldoc?Nagios::Plugin">Nagios::Plugin</a>.</p>

<p><strong><a href="https://gist.github.com/1005409">Read, download, or fork <var>check_tap.pl</var> from the Github Gist</a>.</strong></p>

<h2>Plugin Documentation (more or less straight from <code>check_tap.pl --help</code>)</h2>

<div style="margin: 2em; padding:1em; background:#efd">

<h2>check_tap.pl</h2>

<p>This plugin allows Nagios to check the output of anything that emits
Test Anything Protocol output. So you can wed Nagios&#8217;s monitoring and
alerting infrastructure to your unit and functional tests for deep
application-level monitoring in development or even in production.</p>

<h3>Usage:</h3>

<pre><code>check_tap.pl [ -v|--verbose ] [-t &lt;timeout&gt;]
[ -c|--critical=&lt;critical threshold&gt; ]
[ -w|--warning=&lt;warning threshold&gt; ]
[ -s|--script = '&lt;/full/path/to/test.t&gt;' ] (Required. multiple OK)
[ -e|--exec = '/full/path/to/runnable ARGS'
[ -l|--lib = '/path/to/perl/libs' ] (Multiple OK)
</code></pre>

<h4>-?, &#8211;usage</h4>

<p>Print usage information</p>

<h4>-h, &#8211;help</h4>

<p>Print detailed help screen</p>

<h4>-V, &#8211;version</h4>

<p>Print version information</p>

<h4>&#8211;extra-opts=[section][@file]</h4>

<p>Read options from an ini file. See http://nagiosplugins.org/extra-opts
   for usage and examples.</p>

<h4>-s, &#8211;script=&#8221;/path/to/executable/test.t args&#8221;</h4>

<p>REQUIRED. Defines the path to the test script you want to run.
   Use multiple -s flags to run multiple tests.</p>

<h4>-l, &#8211;lib=&#8221;/path/to/perl/lib/dir&#8221;</h4>

<p>Optional path for Perl libs to add to @INC.
   Use multiple -l flags to specify multiple lib dirs.</p>

<h4>-e, &#8211;exec=&#8221;/path/to/executable args&#8221;</h4>

<p>Defines a non-Perl executable with which you want to run the &#8211;script.</p>

<h4>-w, &#8211;warning=INTEGER:INTEGER</h4>

<p>Minimum and maximum number of allowable test FAILURES, outside of which a
   warning will be generated. Default is 0 tolerable failures.</p>

<h4>-c, &#8211;critical=INTEGER:INTEGER</h4>

<p>Minimum and maximum number of allowable test FAILURES, outside of
   which a critical will be generated. Default is 0 tolerable failures.</p>

<h4>-t, &#8211;timeout=INTEGER</h4>

<p>Seconds before plugin times out (default: 15)</p>

<h4>-v, &#8211;verbose</h4>

<p>Show details for command-line debugging (can repeat up to 3 times)</p>

<h3>Verbosity</h3>

<p>Use <code>-v</code> to see a bit more info in the one line, including the first
test that failed. This is especially useful because Nagios will
include it in the alert/notification.</p>

<p>Use <code>-vv</code> to see test summary and failures.</p>

<p>Use <code>-vvv</code> to see full test script output.</p>

<h2>Warning and Critical Thresholds</h2>

<p>THRESHOLDs for -w and -c specify the allowable amount of test failures
before the plugin returns WARNING or CRITICAL. Use &#8216;max&#8217; or &#8216;min:max&#8217;.</p>

<p>The default of 0 tolerated failures is good for people like you who
have high standards. But you might want to crank up the CRITICAL
threshold if you want to differentiate between WARNING and CRITICAL
amounts of fail.</p>

<p>See more threshold examples at

http://nagiosplug.sourceforge.net/developer-guidelines.html#THRESHOLDFORMAT</p>

<h3>Examples:</h3>


<div class="wp_syntax"><div class="code"><pre class="bash">    check_tap.pl <span class="re5">-s</span> <span class="sy0">/</span>full<span class="sy0">/</span>path<span class="sy0">/</span>to<span class="sy0">/</span>testfoo.pl</pre></div></div>


<p>will run &#8216;testfoo.pl&#8217; and return OK if 0 tests fail, but CRITICAL if
any fail. Excluding TODO or SKIPped tests, of course.</p>


<div class="wp_syntax"><div class="code"><pre class="bash">    check_tap.pl <span class="re5">-s</span> <span class="sy0">/</span>full<span class="sy0">/</span>path<span class="sy0">/</span>to<span class="sy0">/</span>testfoo.pl <span class="re5">-c</span> <span class="nu0">2</span></pre></div></div>


<p>will return OK if 0 tests fail, WARNING if more than 0 tests fail,
and CRITICAL if more than 2 fail.</p>

<h3>Non-Perl and remote test scripts</h3>


<div class="wp_syntax"><div class="code"><pre class="bash">    check_tap.pl <span class="re5">-e</span> <span class="st_h">'/usr/bin/ruby -w'</span>  <span class="re5">-s</span> <span class="sy0">/</span>full<span class="sy0">/</span>path<span class="sy0">/</span>to<span class="sy0">/</span>testfoo.r</pre></div></div>


<p>will run &#8216;testfoo.r&#8217; using Ruby with the -w flag.</p>

<p>You can use any shell command and argument which produces TAP output,
for example:</p>


<div class="wp_syntax"><div class="code"><pre class="bash">    check_tap.pl <span class="re5">-e</span> <span class="st_h">'/usr/bin/curl -sk'</span> <span class="re5">-s</span> <span class="st_h">'http://url/to/mytest.php'</span></pre></div></div>



<div class="wp_syntax"><div class="code"><pre class="bash">    check_tap.pl <span class="re5">-e</span> <span class="st_h">'/usr/bin/cat'</span> <span class="re5">-s</span> <span class="st_h">'/path/to/testoutput.tap'</span></pre></div></div>


<p>In fact, anything TAP::Harness or <code>prove</code> regards as a source or
executable.</p>

<p>Remember that Nagios or NRPE will likely be running this command as a
different, less-privileged user than you&#8217;re using now.</p>

<h3>License</h3>

<p>This nagios plugin is free software, and comes with ABSOLUTELY NO WARRANTY.
It may be used, redistributed and/or modified under the terms of the GNU
General Public Licence (see http://www.fsf.org/licensing/licenses/gpl.txt).</p>

</div>

<h2>Installation and Nagios configuration</h2>

<p>Save <var>check_tap.pl</var> anywhere that makes sense and the <code>nagios</code> user can access. The default plugin location depends on your distribution. For RHEL and ilk, plugins are in <var>/usr/lib/nagios/plugins/</var>.</p>

<p>In <var>misccommands.cfg</var>:</p>


<div class="wp_syntax"><div class="code"><pre class="bash"><span class="co0"># runs Perl test script given in $ARG1$</span>
define <span class="kw3">command</span> <span class="br0">&#123;</span>
        command_name    check_tap
        command_line    <span class="sy0">/</span>usr<span class="sy0">/</span>lib<span class="sy0">/</span>nagios<span class="sy0">/</span>plugins<span class="sy0">/</span>check_tap.pl <span class="re5">-v</span> \
               <span class="re5">-s</span> <span class="re1">$ARG1</span>$ <span class="re5">-w</span> <span class="re1">$ARG2</span>$ <span class="re5">-c</span> <span class="re1">$ARG3</span>$
<span class="br0">&#125;</span>
&nbsp;
<span class="co0"># gets TAP output from the full URL in $ARG1$</span>
define <span class="kw3">command</span> <span class="br0">&#123;</span>
        command_name    check_tap_remote_url
        command_line    <span class="sy0">/</span>usr<span class="sy0">/</span>lib<span class="sy0">/</span>nagios<span class="sy0">/</span>plugins<span class="sy0">/</span>check_tap.pl <span class="re5">-v</span> \
               <span class="re5">-e</span> <span class="st_h">'/usr/bin/curl -sk'</span> <span class="re5">-s</span> <span class="re1">$ARG1</span>$ \
               <span class="re5">-w</span> <span class="re1">$ARG2</span>$ <span class="re5">-c</span> <span class="re1">$ARG3</span>$
<span class="br0">&#125;</span>
&nbsp;
<span class="co0"># gets TAP output from the relative URL in $ARG1$ at host $HOSTADDRESS$</span>
define <span class="kw3">command</span> <span class="br0">&#123;</span>
        command_name    check_tap_remote_host
        command_line    <span class="sy0">/</span>usr<span class="sy0">/</span>lib<span class="sy0">/</span>nagios<span class="sy0">/</span>plugins<span class="sy0">/</span>check_tap.pl <span class="re5">-v</span> \
              <span class="re5">-e</span> <span class="st_h">'/usr/bin/curl -sk'</span> \
              <span class="re5">-s</span> http:<span class="sy0">//</span><span class="re1">$HOSTADDRESS</span>$<span class="re1">$ARG1</span>$ \
              <span class="re5">-w</span> <span class="re1">$ARG2</span>$ <span class="re5">-c</span> <span class="re1">$ARG3</span>$
<span class="br0">&#125;</span></pre></div></div>


<p>You can also use <a href="http://exchange.nagios.org/directory/Addons/Monitoring-Agents/NRPE-%252D-Nagios-Remote-Plugin-Executor/details">NRPE for *nix</a> or <a href="http://www.nsclient.org/nscp/">NSCLient++/nscp</a> 
or <a href="http://exchange.nagios.org/directory/Addons/Monitoring-Agents/NC_Net/details">NC_Net</a>
for Windows (you&#8217;ll also need Perl, like <a href="http://strawberryperl.com/">Strawberry Perl</a>) to run <var>check_tap.pl</var> on a machine other than the Nagios server. I&#8217;ll leave that as an exercise for the reader, or maybe a future blog post.</p>

<p>In <var>services.cfg</var>:</p>


<div class="wp_syntax"><div class="code"><pre class="bash">define service <span class="br0">&#123;</span>
  use                  generic-service
  check_command        check_tap<span class="sy0">!/</span>path<span class="sy0">/</span>to<span class="sy0">/</span>my<span class="sy0">/</span>test.t<span class="sy0">!</span><span class="nu0">0</span><span class="sy0">!</span><span class="nu0">0</span>
  service_description  Local <span class="kw3">test</span> script on Nagios server
<span class="br0">&#125;</span>
&nbsp;
define service <span class="br0">&#123;</span>
  use                  generic-service
  check_command        check_tap_remote_url<span class="sy0">!</span>http:<span class="sy0">//</span>webhost99<span class="sy0">/</span>nagios<span class="sy0">/</span>mytest.php<span class="sy0">!</span><span class="nu0">0</span><span class="sy0">!</span><span class="nu0">0</span>
  service_description  Remote <span class="kw3">test</span> script accessible by URL
<span class="br0">&#125;</span>
&nbsp;
define service <span class="br0">&#123;</span>
  use                  generic-service
  host_name            webhost1, webhost2
  check_command        check_tap_remote_host<span class="sy0">!/</span>nagios<span class="sy0">/</span>mytest.php<span class="sy0">!</span><span class="nu0">0</span><span class="sy0">!</span><span class="nu0">0</span>
  service_description  Remote <span class="kw3">test</span> script
<span class="br0">&#125;</span></pre></div></div>


<h2>Host-based security for URL-accessible test scripts</h2>

<p>It would be good to <a href="http://httpd.apache.org/docs/2.2/howto/access.html">limit access</a> to the URL-accessible test scripts to your Nagios server and development/admin network. So for Apache, <var>.htaccess</var> or <var>httpd.conf</var>:</p>


<div class="wp_syntax"><div class="code"><pre class="apache"><span class="kw1">Order</span> <span class="kw1">deny</span>,<span class="kw1">allow</span>
<span class="kw1">Deny</span> from <span class="kw2">all</span>
<span class="kw1">Allow</span> from nagioshost.example.com
<span class="kw1">Allow</span> from developers.example.com</pre></div></div>


<p>For IIS you can click on stuff for the same result or use the <a href="http://msdn.microsoft.com/en-us/library/8aeskccd.aspx"><code>deny</code> element in your <var>web.config</var> file</a>. For other web servers, RTFM.</p>

<h2>Doughnuts for Developers</h2>

<p>Wow! Now I can use Nagios&#8217;s monitoring, alerting, performance logging, acknowledging, scheduling, dashboarding, and thresholding features for my unit and functional tests! I can run them with different rules in build and production! I can detect random and senseless acts of system administration! I can detect new bugs as soon as I write them! I can hook Nagios up to the sprinkler system to put a damper on that hotheaded programmer in the next cube! I can write frontend functional tests with Selenium or AutoIt or AppleScript and have Nagios alert (the sysadmins of course) when any of my app&#8217;s core functionality breaks!!!</p>

<p>There are plenty of other test harnesses out there, but Nagios has some big advantages, especially for monitoring production systems.</p>

<h2>Shortcuts for Sysadmins</h2>

<p>Two last things which are more good news for sysadmins:</p>

<h3>Custom test scripts for things Nagios won&#8217;t easily check</h3>

<p>Writing your own Nagios plugins is a little bit hard, even with <a href="http://cpansearch.perl.org/src/TONVOON/Nagios-Plugin-0.35/t/check_stuff.pl">the example plugin I worked on ever so long ago</a>. Writing TAP test scripts, on the other hand, is easy! So, after you&#8217;ve set up Nagios monitoring for all the low-hanging fruit like hardware utilization and network availability, write a test script for some of the harder to monitor signs of enumerable goodness. Here&#8217;s an example:</p>


<div class="wp_syntax"><div class="code"><pre class="perl"><span class="co1">#!/usr/bin/perl</span>
<span class="kw2">use</span> warnings<span class="sy0">;</span> <span class="kw2">use</span> strict<span class="sy0">;</span>
&nbsp;
<span class="co1"># This allows the script to run as a CGI or on the command line.</span>
<span class="co1"># We have to output the header in a BEGIN block or Test::Simple will</span>
<span class="co1">#   output the plan too soon.</span>
<span class="kw2">BEGIN</span> <span class="br0">&#123;</span>
    <span class="kw1">if</span> <span class="br0">&#40;</span><span class="re0">$ENV</span><span class="br0">&#123;</span>REQUEST_METHOD<span class="br0">&#125;</span><span class="br0">&#41;</span> <span class="br0">&#123;</span>
        <span class="kw2">use</span> CGI <a href="http://perldoc.perl.org/functions/qw.html"><span class="kw3">qw</span></a><span class="br0">&#40;</span>header<span class="br0">&#41;</span><span class="sy0">;</span>
        <a href="http://perldoc.perl.org/functions/print.html"><span class="kw3">print</span></a> header<span class="br0">&#40;</span><span class="st0">&quot;text/plain&quot;</span><span class="br0">&#41;</span><span class="sy0">;</span>
    <span class="br0">&#125;</span>
<span class="br0">&#125;</span>
&nbsp;
<span class="kw2">use</span> Test<span class="sy0">::</span><span class="me2">Simple</span> tests<span class="sy0">=&gt;</span><span class="nu0">4</span><span class="sy0">;</span>
<span class="kw2">use</span> Test<span class="sy0">::</span><span class="me2">File</span><span class="sy0">;</span>
&nbsp;
<span class="co1"># These use Test::File to test file permissions and size.</span>
<span class="co1"># See http://search.cpan.org/perldoc?Test::File</span>
file_writeable_ok <span class="st0">&quot;path/to/cache&quot;</span><span class="sy0">;</span>  
file_not_writeable_ok <span class="st0">&quot;path/to/index.html&quot;</span><span class="sy0">;</span> 
<span class="kw1">my</span> <span class="re0">$backup_file</span> <span class="sy0">=</span> <span class="st0">&quot;/usr/local/backups/myapp-backup.tar.bz2&quot;</span><span class="sy0">;</span>
file_min_size_ok <span class="re0">$backup_file</span><span class="sy0">,</span> <span class="nu0">911377</span><span class="sy0">;</span>
&nbsp;
<span class="co1"># -M is a file test operator returning the file's last modifed age in days.</span>
<span class="co1"># See http://perldoc.perl.org/functions/-X.html</span>
ok <span class="sy0">-</span>M <span class="re0">$backup_file</span> <span class="sy0">&lt;</span> <span class="nu0">1</span><span class="sy0">,</span> <span class="st0">&quot;Backup file is newer than 1 day old&quot;</span><span class="sy0">;</span></pre></div></div>


<p>Just run that script as a CGI or with NRPE etc. and you&#8217;ve got instant monitoring of things like backup success, which is otherwise kind of hard to hook in to Nagios. You could get even fancier with checksums or whatever you want.</p>

<p><a href="http://search.cpan.org/perldoc?Test::Tutorial">See Test::Tutorial for more.</a> Or look for TAP tools for your favorite language; they&#8217;re probably out there.</p>

<h3>Tolerating ambiguity</h3>

<p>In some cases, a certain amount of failure is acceptable. I&#8217;ve been monitoring connectivity between crucial hosts with a test script. I don&#8217;t want to be bothered by this check if one of our Citrix VMs isn&#8217;t available to the gateway server for a while, but it&#8217;s a problem if they&#8217;re ALL inaccessible because of a firewall issue or something. The configurable warning/critical thresholds on <var>check_tap.pl</var> allow me to define how much aggregate failure is worth getting excited about&#8211;something that&#8217;s hard to do with vanilla Nagios configuration.</p>

<p>Here&#8217;s the gist of my test script. <code>ping_ok()</code> and <code>service_ok()</code> come from a module I wrote 50 years ago to check basic connectivity/responsiveness with <a href="http://search.cpan.org/perldoc?Net::Ping">Net::Ping</a>.</p>


<div class="wp_syntax"><div class="code"><pre class="perl">diag <span class="st0">&quot;Checking Citrix farm connectivity from DMZ<span class="es0">\n</span>&quot;</span><span class="sy0">;</span>
<span class="kw1">my</span> <span class="re0">@stas</span> <span class="sy0">=</span> <a href="http://perldoc.perl.org/functions/qw.html"><span class="kw3">qw</span></a><span class="br0">&#40;</span>
   citrixdc01<span class="sy0">.</span>mydomain<span class="sy0">.</span>com
   citrixdc02<span class="sy0">.</span>mydomain<span class="sy0">.</span>com
<span class="br0">&#41;</span><span class="sy0">;</span>
<span class="kw1">foreach</span> <span class="br0">&#40;</span><span class="re0">@stas</span><span class="br0">&#41;</span> <span class="br0">&#123;</span>
    ping_ok<span class="br0">&#40;</span><span class="co5">$_</span><span class="sy0">,</span> <span class="st_h">'http'</span><span class="br0">&#41;</span><span class="sy0">;</span>	
    service_ok<span class="br0">&#40;</span><span class="co5">$_</span><span class="sy0">,</span> <span class="st_h">'http'</span><span class="sy0">,</span> <span class="st0">&quot;XML service on $_ is responding in some way&quot;</span> <span class="br0">&#41;</span><span class="sy0">;</span>
<span class="br0">&#125;</span>
&nbsp;
&nbsp;
&nbsp;
<span class="kw1">my</span> <span class="re0">@citrix_farm</span> <span class="sy0">=</span> <a href="http://perldoc.perl.org/functions/qw.html"><span class="kw3">qw</span></a><span class="br0">&#40;</span>
   citrixps01<span class="sy0">.</span>mydomain<span class="sy0">.</span>com
   citrixps02<span class="sy0">.</span>mydomain<span class="sy0">.</span>com
   <span class="sy0">...</span>
   citrixps29<span class="sy0">.</span>mydomain<span class="sy0">.</span>com
   citrixps30<span class="sy0">.</span>mydomain<span class="sy0">.</span>com
<span class="br0">&#41;</span><span class="sy0">;</span>
<span class="kw1">foreach</span> <span class="br0">&#40;</span><span class="re0">@stas</span><span class="sy0">,</span> <span class="re0">@citrix_farm</span><span class="br0">&#41;</span> <span class="br0">&#123;</span>
    service_ok<span class="br0">&#40;</span><span class="co5">$_</span><span class="sy0">,</span> <span class="st_h">'1494'</span><span class="sy0">,</span> <span class="st0">&quot;ICA service on $_ is responding in some way&quot;</span> <span class="br0">&#41;</span><span class="sy0">;</span>
<span class="br0">&#125;</span></pre></div></div>


<p>I can just use the &#8220;warning&#8221; and &#8220;critical&#8221; arguments to <var>check_tap.pl</var> to set my thresholds for how many inaccessible servers I want to tolerate.</p>

<p>So there you go. Sysadmins and developers rejoice!</p>
]]></content:encoded>
			<wfw:commentRss>http://n8v.enteuxis.org/2011/06/integrating-nagios-with-test-driven-development/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Open files in Emacs from the Cygwin command line</title>
		<link>http://n8v.enteuxis.org/2011/05/open-files-in-emacs-from-the-cygwin-command-line/</link>
		<comments>http://n8v.enteuxis.org/2011/05/open-files-in-emacs-from-the-cygwin-command-line/#comments</comments>
		<pubDate>Fri, 27 May 2011 23:43:09 +0000</pubDate>
		<dc:creator>nathan</dc:creator>
				<category><![CDATA[Figuring IT Out]]></category>
		<category><![CDATA[bash]]></category>
		<category><![CDATA[Cygwin]]></category>
		<category><![CDATA[Emacs]]></category>
		<category><![CDATA[Windows]]></category>

		<guid isPermaLink="false">http://n8v.enteuxis.org/?p=430</guid>
		<description><![CDATA[I just got this working today. The weirdnesses of Cygwin&#8217;s half Unix-half Windows nature had stymied me before, but I&#8217;ve prevailed! I&#8217;ve got Gnu Emacs 23.3 for Windows installed in c:/emacs, and a fairly recent install of Cygwin on Windows...]]></description>
				<content:encoded><![CDATA[<p>I just got this working today. The weirdnesses of Cygwin&#8217;s half Unix-half Windows nature had stymied me before, but I&#8217;ve prevailed!</p>

<p>I&#8217;ve got <a href="http://ftp.gnu.org/gnu/emacs/windows/">Gnu Emacs 23.3 for Windows</a> installed in <var>c:/emacs</var>, and a fairly recent install of <a href="http://cygwin.com/">Cygwin</a> on Windows 7.</p>

<p>Saved this script in <var>~/cygemacs.sh</var></p>


<div class="wp_syntax"><div class="code"><pre class="bash"><span class="co0">#!/usr/bin/bash</span>
c:<span class="sy0">/</span>emacs<span class="sy0">/</span>bin<span class="sy0">/</span>emacsclientw.exe <span class="re5">-n</span> <span class="re5">-a</span> <span class="st0">&quot;c:/emacs/bin/runemacs.exe&quot;</span> <span class="sy0">`</span>cygpath <span class="re5">-wa</span> $<span class="sy0">@`</span></pre></div></div>


<p>Then in my <var>~/.bashrc</var>:</p>


<div class="wp_syntax"><div class="code"><pre class="bash"><span class="kw3">alias</span> <span class="re2">ec</span>=<span class="st0">&quot;~/cygemacs.sh&quot;</span></pre></div></div>


<p>Now I can be all like,</p>


<div class="wp_syntax"><div class="code"><pre class="bash">$ ec ~<span class="sy0">/</span>.minttyrc</pre></div></div>


<p>And it opens a new frame in my running Emacs (I have <code>(server-start)</code> in my <var>~/.emacs</var>), or starts Emacs and opens the file if Emacs isn&#8217;t running yet.</p>

<p>See also: <a href="http://www.emacswiki.org/emacs/EmacsClient">EmasClient at EmacsWiki</a>.</p>

<h3>Bonus tips</h3>

<p>Yes I&#8217;m still using Subversion but also gitting going with Git.</p>

<p>And courtesy of <a href="http://shreevatsa.wordpress.com/2007/01/06/using-emacsclient/">The Lumber Room</a>, <var>in ~/.bashrc</var> and others:</p>


<div class="wp_syntax"><div class="code"><pre class="bash">    <span class="kw3">export</span> <span class="re2">SVN_EDITOR</span>=<span class="st_h">'c:/emacs/bin/emacsclientw.exe -a c:/emacs/bin/runemacs.exe '</span></pre></div></div>


<p>And silence that annoying &#8220;kill client buffer z0mgbbq?!?&#8221; warning:</p>


<div class="wp_syntax"><div class="code"><pre class="lisp">  <span class="br0">&#40;</span>remove-hook 'kill-buffer-query-functions 'server-kill-buffer-query-<span class="kw1">function</span><span class="br0">&#41;</span></pre></div></div>

]]></content:encoded>
			<wfw:commentRss>http://n8v.enteuxis.org/2011/05/open-files-in-emacs-from-the-cygwin-command-line/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>sfPropel15Plugin error, &#8220;class &#8216;FooPeer&#8217; does not have a method &#8216;getUniqueColumnNames&#8217;&#8221;</title>
		<link>http://n8v.enteuxis.org/2011/05/sfpropel15plugin-error-class-foopeer-does-not-have-a-method-getuniquecolumnnames/</link>
		<comments>http://n8v.enteuxis.org/2011/05/sfpropel15plugin-error-class-foopeer-does-not-have-a-method-getuniquecolumnnames/#comments</comments>
		<pubDate>Thu, 26 May 2011 19:26:25 +0000</pubDate>
		<dc:creator>nathan</dc:creator>
				<category><![CDATA[Figuring IT Out]]></category>
		<category><![CDATA[propel]]></category>
		<category><![CDATA[symfony]]></category>
		<category><![CDATA[symfony 1.4]]></category>

		<guid isPermaLink="false">http://n8v.enteuxis.org/?p=425</guid>
		<description><![CDATA[Stupid me made the same mistake twice in a row so I&#8217;m documenting it for humanity. I&#8217;m updating an old Symfony project to use Symfony 1.3/1.4 and Propel 1.5 through François Zaninotto&#8217;s sfPropel15Plugin. Problem: I followed the README, right? But&#8230;...]]></description>
				<content:encoded><![CDATA[<p>Stupid me made the same mistake twice <em>in a row</em> so I&#8217;m documenting it for humanity.</p>

<p>I&#8217;m updating an old Symfony project to use Symfony 1.3/1.4 and Propel 1.5 through François Zaninotto&#8217;s <a href="http://www.symfony-project.org/plugins/sfPropel15Plugin">sfPropel15Plugin</a>.</p>

<h2>Problem:</h2>

<p>I followed the README, right? But&#8230;</p>


<div class="wp_syntax"><div class="code"><pre class="bash">$ .<span class="sy0">/</span>symfony propel:build <span class="re5">--forms</span>
<span class="sy0">&gt;&gt;</span> schema    converting <span class="st0">&quot;C:/web/myproject/config/schema.yml&quot;</span> to XML
<span class="sy0">&gt;&gt;</span> schema    putting C:<span class="sy0">/</span>web<span class="sy0">/</span>myproject<span class="sy0">/</span>config<span class="sy0">/</span>generated-schema.xml
<span class="sy0">&gt;&gt;</span> propel    Running <span class="st0">&quot;om&quot;</span> phing task
<span class="sy0">&gt;&gt;</span> file-     C:<span class="sy0">/</span>web<span class="sy0">/</span>myproject<span class="sy0">/</span>config<span class="sy0">/</span>generated-schema.xml
<span class="sy0">&gt;&gt;</span> autoload  Resetting application autoloaders
<span class="sy0">&gt;&gt;</span> autoload  Resetting CLI autoloader
<span class="sy0">&gt;&gt;</span> propel    generating form classes
PHP Warning:  call_user_func<span class="br0">&#40;</span><span class="br0">&#41;</span> expects parameter <span class="nu0">1</span> to be a valid callback, class <span class="st_h">'FooPeer'</span> does not have a method <span class="st_h">'getUniqueColumnNames'</span> <span class="kw1">in</span> C:\web\myproject\plugins\sfPropel15Plugin\lib\generator\sfPropelFormGenerator.class.php on line <span class="nu0">485</span>
PHP Stack trace:
PHP   <span class="nu0">1</span>. <span class="br0">&#123;</span>main<span class="br0">&#125;</span><span class="br0">&#40;</span><span class="br0">&#41;</span> C:\web\myproject\symfony:<span class="nu0">0</span>
PHP   <span class="nu0">2</span>. include<span class="br0">&#40;</span><span class="br0">&#41;</span> C:\web\myproject\symfony:<span class="nu0">14</span>
PHP   <span class="nu0">3</span>. sfSymfonyCommandApplication-<span class="sy0">&gt;</span>run<span class="br0">&#40;</span><span class="br0">&#41;</span> C:\symfony1.3\lib\<span class="kw3">command</span>\cli.php:<span class="nu0">20</span>
PHP   <span class="nu0">4</span>. sfTask-<span class="sy0">&gt;</span>runFromCLI<span class="br0">&#40;</span><span class="br0">&#41;</span> C:\symfony1.3\lib\<span class="kw3">command</span>\sfSymfonyCommandApplication.class.php:<span class="nu0">76</span>
PHP   <span class="nu0">5</span>. sfBaseTask-<span class="sy0">&gt;</span>doRun<span class="br0">&#40;</span><span class="br0">&#41;</span> C:\symfony1.3\lib\task\sfTask.class.php:<span class="nu0">97</span>
PHP   <span class="nu0">6</span>. sfPropelBuildTask-<span class="sy0">&gt;</span>execute<span class="br0">&#40;</span><span class="br0">&#41;</span> C:\symfony1.3\lib\task\sfBaseTask.class.php:<span class="nu0">68</span>
PHP   <span class="nu0">7</span>. sfTask-<span class="sy0">&gt;</span>run<span class="br0">&#40;</span><span class="br0">&#41;</span> C:\web\myproject\plugins\sfPropel15Plugin\lib\task\sfPropelBuildTask.class.php:<span class="nu0">135</span>
PHP   <span class="nu0">8</span>. sfBaseTask-<span class="sy0">&gt;</span>doRun<span class="br0">&#40;</span><span class="br0">&#41;</span> C:\symfony1.3\lib\task\sfTask.class.php:<span class="nu0">173</span>
PHP   <span class="nu0">9</span>. sfPropelBuildFormsTask-<span class="sy0">&gt;</span>execute<span class="br0">&#40;</span><span class="br0">&#41;</span> C:\symfony1.3\lib\task\sfBaseTask.class.php:<span class="nu0">68</span>
PHP  <span class="nu0">10</span>. sfGeneratorManager-<span class="sy0">&gt;</span>generate<span class="br0">&#40;</span><span class="br0">&#41;</span> C:\web\myproject\plugins\sfPropel15Plugin\lib\task\sfPropelBuildFormsTask.class.php:<span class="nu0">72</span>
PHP  <span class="nu0">11</span>. sfPropelFormGenerator-<span class="sy0">&gt;</span>generate<span class="br0">&#40;</span><span class="br0">&#41;</span> C:\symfony1.3\lib\generator\sfGeneratorManager.class.php:<span class="nu0">126</span>
PHP  <span class="nu0">12</span>. sfGenerator-<span class="sy0">&gt;</span>evalTemplate<span class="br0">&#40;</span><span class="br0">&#41;</span> C:\web\myproject\plugins\sfPropel15Plugin\lib\generator\sfPropelFormGenerator.class.php:<span class="nu0">106</span>
PHP  <span class="nu0">13</span>. require<span class="br0">&#40;</span><span class="br0">&#41;</span> C:\symfony1.3\lib\generator\sfGenerator.class.php:<span class="nu0">84</span>
PHP  <span class="nu0">14</span>. sfPropelFormGenerator-<span class="sy0">&gt;</span>getUniqueColumnNames<span class="br0">&#40;</span><span class="br0">&#41;</span> C:\web\myproject\plugins\sfPropel15Plugin\data\generator\sfPropelForm\default\template\sfPropelFormGeneratedTemplate.php:<span class="nu0">34</span>
PHP  <span class="nu0">15</span>. call_user_func<span class="br0">&#40;</span><span class="br0">&#41;</span> C:\web\myproject\plugins\sfPropel15Plugin\lib\generator\sfPropelFormGenerator.class.php:<span class="nu0">485</span>
... etc ...</pre></div></div>


<h2>Solution</h2>

<p>I <a href="http://www.mail-archive.com/symfony-users@googlegroups.com/msg32719.html">removed too much of the default config in propel.ini.</a>.</p>

<p>Make sure this original line is still intact in <var>propel.ini</var>, even though you&#8217;ve removed/commented out all the <code>propel.behavior</code> lines that point to the old <var>sfPropelPlugin</var>:</p>


<div class="wp_syntax"><div class="code"><pre class="ini">propel.behavior.default                        <span class="sy0">=</span><span class="re2"> symfony,symfony_i18n</span></pre></div></div>

]]></content:encoded>
			<wfw:commentRss>http://n8v.enteuxis.org/2011/05/sfpropel15plugin-error-class-foopeer-does-not-have-a-method-getuniquecolumnnames/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
	</channel>
</rss>
