<?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>Mike Renfro's Blog &#187; infrastructures</title>
	<atom:link href="http://blogs.cae.tntech.edu/mwr/category/infrastructures/feed/" rel="self" type="application/rss+xml" />
	<link>http://blogs.cae.tntech.edu/mwr</link>
	<description>A partial repository of whatever comes to mind</description>
	<lastBuildDate>Sat, 31 Oct 2009 23:02:35 +0000</lastBuildDate>
	<generator>http://wordpress.org/?v=2.8.4</generator>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
			<item>
		<title>Stupid Puppet Trick: Identifying Groups of Hosts</title>
		<link>http://blogs.cae.tntech.edu/mwr/2008/07/13/stupid-puppet-trick-identifying-groups-of-hosts/</link>
		<comments>http://blogs.cae.tntech.edu/mwr/2008/07/13/stupid-puppet-trick-identifying-groups-of-hosts/#comments</comments>
		<pubDate>Mon, 14 Jul 2008 03:08:21 +0000</pubDate>
		<dc:creator>Mike Renfro</dc:creator>
				<category><![CDATA[infrastructures]]></category>
		<category><![CDATA[puppet]]></category>

		<guid isPermaLink="false">http://blogs.cae.tntech.edu/mwr/2008/07/13/stupid-puppet-trick-identifying-groups-of-hosts/</guid>
		<description><![CDATA[My Ruby skills are practically non-existant, but I&#8217;ve managed to put together a relatively readable custom fact for identifying my Torque queues by a node&#8217;s hostname. Behold, HostgroupFact! Now I can factor out my hosts.equiv files back to a parent class, rather than duplicating the same file specifications on a per-queue basis.

class cluster-host inherits public-host [...]]]></description>
			<content:encoded><![CDATA[<p>My Ruby skills are practically non-existant, but I&#8217;ve managed to put together a relatively readable custom fact for identifying my Torque queues by a node&#8217;s hostname. Behold, <a href="http://reductivelabs.com/trac/puppet/wiki/Recipes/HostgroupFact">HostgroupFact</a>! Now I can factor out my hosts.equiv files back to a parent class, rather than duplicating the same file specifications on a per-queue basis.</p>
<pre>
class cluster-host inherits public-host {
    # ...
    file { "/etc/hosts.equiv":
        source  =&gt; "puppet:///files/apps/rsh-server/hosts.equiv.$hostgroup",
        owner   =&gt; root,
        group   =&gt; root,
        mode    =&gt; 644,
        require =&gt; Package[rsh-server],
    }
}
</pre>
]]></content:encoded>
			<wfw:commentRss>http://blogs.cae.tntech.edu/mwr/2008/07/13/stupid-puppet-trick-identifying-groups-of-hosts/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Stupid Puppet Trick: Poor Man&#8217;s Undo</title>
		<link>http://blogs.cae.tntech.edu/mwr/2008/07/12/stupid-puppet-trick-poor-mans-undo/</link>
		<comments>http://blogs.cae.tntech.edu/mwr/2008/07/12/stupid-puppet-trick-poor-mans-undo/#comments</comments>
		<pubDate>Sun, 13 Jul 2008 01:16:07 +0000</pubDate>
		<dc:creator>Mike Renfro</dc:creator>
				<category><![CDATA[infrastructures]]></category>
		<category><![CDATA[puppet]]></category>

		<guid isPermaLink="false">http://blogs.cae.tntech.edu/mwr/2008/07/12/stupid-puppet-trick-poor-mans-undo/</guid>
		<description><![CDATA[If I apply a set of classes to a puppet client, I may need to roll back those classes&#8217; changes later. Granted, I could just edit out those classes, reformat the system, and rebuild it from scratch, but there may be times when I want to undo my changes in a more granular fashion. So [...]]]></description>
			<content:encoded><![CDATA[<p>If I apply a set of classes to a puppet client, I may need to roll back those classes&#8217; changes later. Granted, I could just edit out those classes, reformat the system, and rebuild it from scratch, but there may be times when I want to undo my changes in a more granular fashion. So here&#8217;s my latest revelation (which is undoubtedly documented elsewhere already, but I didn&#8217;t find anything sufficiently simple last time I looked).</p>
<p>Along the lines of <a href="http://reductivelabs.com/trac/puppet/wiki/PuppetBestPractice">Puppet Best Practice 2.0</a>, I&#8217;m trying to compartmentalize all my building blocks into separate modules, even the really simple ones that just install a package or two. So here&#8217;s the contents of a trivial hello module for Debian:</p>
<pre>
# /etc/puppet/modules/hello/manifests/init.pp
class hello {
  package { "hello":
    ensure =&gt; latest;
  }
}
</pre>
<p>Nothing complicated here: install this package via the default package provider. Add an <code>include hello</code> to my node&#8217;s manifest, and the hello package gets installed.</p>
<p>Now for the &#8220;undo&#8221; class:</p>
<pre>
# /etc/puppet/modules/hello/manifests/disabled.pp
class hello::disabled inherits hello {
  Package["hello"] {
    ensure =&gt; purged
  }
}
</pre>
<p>And this is neat. Properly written, the disabling class can undo all the changes made by the parent class. Modify my node&#8217;s manifest from <code>include hello</code> to <code>include hello::disabled</code> and I can switch that class on and off like, well, a switch.</p>
]]></content:encoded>
			<wfw:commentRss>http://blogs.cae.tntech.edu/mwr/2008/07/12/stupid-puppet-trick-poor-mans-undo/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>I Killed the Mail Server Today</title>
		<link>http://blogs.cae.tntech.edu/mwr/2008/07/09/i-killed-the-mail-server-today/</link>
		<comments>http://blogs.cae.tntech.edu/mwr/2008/07/09/i-killed-the-mail-server-today/#comments</comments>
		<pubDate>Thu, 10 Jul 2008 03:00:57 +0000</pubDate>
		<dc:creator>Mike Renfro</dc:creator>
				<category><![CDATA[Debian]]></category>
		<category><![CDATA[Stupid!]]></category>
		<category><![CDATA[Xen]]></category>
		<category><![CDATA[infrastructures]]></category>
		<category><![CDATA[puppet]]></category>

		<guid isPermaLink="false">http://blogs.cae.tntech.edu/mwr/2008/07/09/i-killed-the-mail-server-today-2/</guid>
		<description><![CDATA[
It all started so simply: I was going to set up a little Xen instance to be my next cluster submit host, and needed a spare address for it:

I started setting up an instance for ch208i.cae.tntech.edu, since it was no longer on the Xen host like it was several months ago. Crap, the reason it&#8217;s [...]]]></description>
			<content:encoded><![CDATA[<div><a href="http://icanhascheezburger.com/2008/07/07/funny-pictures-i-have-the-dumb/"><img class="mine_1410833" src="http://icanhascheezburger.wordpress.com/files/2008/07/funny-pictures-cat-cannot-brain-today.jpg" alt="cat" /></a></div>
<p>It all started so simply: I was going to set up a little Xen instance to be my next cluster submit host, and needed a spare address for it:</p>
<ol>
<li>I started setting up an instance for ch208i.cae.tntech.edu, since it was no longer on the Xen host like it was several months ago. Crap, the reason it&#8217;s no longer on the Xen instance is because I moved it to its own dedicated hardware &#8212; it&#8217;s still my main ftp/mirror server. Ctrl-C that one.</li>
<li>Hmm, what&#8217;s available from old Xen instances? mail2.cae.tntech.edu.cfg from when I was testing out a new mail server setup last fall &#8212; doesn&#8217;t ping, doesn&#8217;t show up in <code>xm list</code>, no problem.
<pre>xen-create-image --hostname=mail2.cae.tntech.edu --ip=149.149.254.23 \
    --gateway=149.149.254.4 --netmask=255.255.255.0 --size=10Gb --memory=256Mb \
    --swap=1Gb --debootstrap --force</pre>
<p>A few minutes later, my instance is debootstrapped and ready to go.</li>
<li>Oh, crap. Why am I getting an error on <code>xm create</code> that says my LVM is already in use on a domU somewhere?</li>
<li>Further crap. Looking in <code>/etc/xen/mail.cae.tntech.edu.cfg</code> for the production mail server, it apparently uses the old mail2.cae.tntech.edu LVMs. Wonderful. <code>ssh mail</code>? It works since sshd was already memory-resident, but <code>/root/.profile</code> doesn&#8217;t exist. And neither does much of anything else.</li>
<li>Great. I&#8217;ve just killed the mail server. Off to the Amanda server to do a quick restore of its data. What? I never put mail.cae.tntech.edu into the backup list? Not normally the end of the world, since the mail stores are held accessed over NFS from the main file server, but what about my dovecot and postfix configurations?</li>
<li>Oh, well. Time to see how good my puppet manifests are for the mail server.</li>
</ol>
<p>Not too bad, as it turns out. Total downtime was only a couple hours, including having to redo the postfix and dovecot configurations (which were then copied off to the puppetmaster). I still have a few more things to fix, but mail delivery is up, and imap is running. TLS support for my sending mail from home isn&#8217;t up yet, but it&#8217;ll be fixed shortly.</p>
<p>I still need to fix that submit host, though. Next time, I think I&#8217;ll use an IP address reserved for my office.</p>
<p><strong>Update:</strong> after getting a partial TLS/SASL setup going late Wednesday night, I went to sleep without realizing I&#8217;d killed mail delivery again. Finally got it straightened out Thursday morning.</p>
]]></content:encoded>
			<wfw:commentRss>http://blogs.cae.tntech.edu/mwr/2008/07/09/i-killed-the-mail-server-today/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Some Days, I Just Hate Solaris</title>
		<link>http://blogs.cae.tntech.edu/mwr/2008/06/03/some-days-i-just-hate-solaris/</link>
		<comments>http://blogs.cae.tntech.edu/mwr/2008/06/03/some-days-i-just-hate-solaris/#comments</comments>
		<pubDate>Tue, 03 Jun 2008 21:49:32 +0000</pubDate>
		<dc:creator>Mike Renfro</dc:creator>
				<category><![CDATA[Solaris]]></category>
		<category><![CDATA[infrastructures]]></category>

		<guid isPermaLink="false">http://blogs.cae.tntech.edu/mwr/2008/06/03/some-days-i-just-hate-solaris/</guid>
		<description><![CDATA[Back in 2000, when some of us in engineering were talking about how best to improve our facilities for high-performance and research computing for our graduate students, we came to a few conclusions:

Software was more important than hardware.
Some software ran only under Windows, some had no Windows version at all.
Of the non-Windows software people cared [...]]]></description>
			<content:encoded><![CDATA[<p>Back in 2000, when some of us in engineering were talking about how best to improve our facilities for high-performance and research computing for our graduate students, we came to a few conclusions:</p>
<ul>
<li>Software was more important than hardware.</li>
<li>Some software ran only under Windows, some had no Windows version at all.</li>
<li>Of the non-Windows software people cared about, there was always a version for Solaris. There was often a version for most other Unixes, but regardless of the company, they always had a Solaris version.</li>
<li>Sun&#8217;s matching grant program for education was awesome.</li>
</ul>
<p>And to be fair, for some operations, our Sun Blade 1000 workstations blow the doors off of our Dell Precision Workstations with 3x the clock cycles. We&#8217;ve had very little hardware trouble from the Suns, and the aforementioned matching grant program and judicious use of third-party upgrade vendors let us buy two decked out Ultra 80 workstations on a budget that was originally allocated for one decked out workstation and one considerably lower-specced one.</p>
<p>But there&#8217;s little to no excuse for the following:</p>
<ul>
<li><a href="http://groups.google.com/group/comp.unix.solaris/msg/fdb9e7d3a0bef32a">patchadd rewrites every byte of /var/sadm/install/contents every time you do a file operation</a>. During jumpstarts, I manage to put that file in a tmpfs for faster access, but before that, I couldn&#8217;t do a single Solaris-only Jumpstart install in less than half a day.</li>
<li>Solaris 10 includes Samba. Solaris 10&#8217;s Samba includes winbind, which is what I use on my Debian systems to convert Active Directory accounts to Unix ones. But the Solaris 10 winbind doesn&#8217;t include the idmap_rid backend for consistently converting an Active Directory RID into a Unix UID, which confuses NFS mightily. I thought blastwave&#8217;s or sunfreeware&#8217;s Samba packages might be better, but they weren&#8217;t. I found <a href="http://docs.sun.com/app/docs/doc/819-3063/ciajejfa?a=view">these instructions for configuring winbind and idmap_rid for Solaris</a>, but they&#8217;re squirreled off in a manual for Sun Cluster Data Services. What reason might they have for not compiling in idmap_rid by default? Am I the only person who uses Active Directory to generate UIDs for a central NFS and Samba server?</li>
<li>Today, during an attempt to install and test Matlab 7.6, I found that <a href="http://www.opensolaris.org/jive/message.jspa?messageID=242029#242029">X11 forwarding is broken on recently-patched Solaris systems</a> like mine. A similar bug came up in 2005 and sat unfixed for a few months. The usual fix of telling sshd to only listen on IPv4 interfaces in sshd_config isn&#8217;t enough, though. You actually have to add the <code>-4</code> argument to the sshd service file.</li>
</ul>
<p>I hate throwing away tens of thousands of dollars of perfectly functional hardware. I could install Debian&#8217;s sparc port on them, but why? I&#8217;d lose access to Ansys, Matlab, and all the other packages that are the reason I have these systems in the first place. And letting them languish like they did for years before I got into the managed infrastructure business seems a waste. Solaris 10, puppet, and the newer firmware that allows PXE booting is such a vast improvement over earlier versions for what I need to do, but there&#8217;s still some distance to go before it&#8217;s up to Debian standards.</p>
<p>If we went through the same evaluation process in 2002, I&#8217;d probably not have any Solaris sytems at all. Matlab, Maple, Ansys, Abaqus, etc. were all coming out with (or had already come out with) Linux versions. We&#8217;d have spent a lot less on hardware, and some jobs just love the extra clock cycles available on an Intel CPU.</p>
]]></content:encoded>
			<wfw:commentRss>http://blogs.cae.tntech.edu/mwr/2008/06/03/some-days-i-just-hate-solaris/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Making Solaris Packages from Commercial Software</title>
		<link>http://blogs.cae.tntech.edu/mwr/2008/05/21/making-solaris-packages-from-commercial-software/</link>
		<comments>http://blogs.cae.tntech.edu/mwr/2008/05/21/making-solaris-packages-from-commercial-software/#comments</comments>
		<pubDate>Wed, 21 May 2008 21:17:12 +0000</pubDate>
		<dc:creator>Mike Renfro</dc:creator>
				<category><![CDATA[Solaris]]></category>
		<category><![CDATA[infrastructures]]></category>

		<guid isPermaLink="false">http://blogs.cae.tntech.edu/mwr/2008/05/21/making-solaris-packages-from-commercial-software/</guid>
		<description><![CDATA[Creating a managed infrastructure can go pretty slowly when you&#8217;re beset with a combination of bare competence and a work schedule that&#8217;s overrun with non-infrastructural tasks. So yes, it&#8217;s been just under a year since I wrote up how to make Debian packages from commercial software. On to getting similar capabilities out of the Solaris [...]]]></description>
			<content:encoded><![CDATA[<p>Creating a managed infrastructure can go pretty slowly when you&#8217;re beset with a combination of bare competence and a work schedule that&#8217;s overrun with non-infrastructural tasks. So yes, it&#8217;s been just under a year since I wrote up <a href="http://blogs.cae.tntech.edu/mwr/2007/05/28/making-debian-packages-from-commercial-software/">how to make Debian packages from commercial software</a>. On to getting similar capabilities out of the Solaris systems.</p>
<p><strong>The packages</strong></p>
<p>I already use Blastwave and pkg-get to install third-party free software applications, so I figured it would be easiest to use the same tools on my packaging. So for a first example, I installed Maple 11.00 manually into /opt/maple/11 on a Solaris 10 system. Then I made a temporary working folder and build folder, made an opt folder there, and moved the maple folder from the regular opt to my build folder&#8217;s opt. I also made a usr/local/bin in my build folder, and made relative symlinks from the main Maple executables to their assumed homes in usr/local/bin. The abridged results from the temporary working folder looked like this:</p>
<pre>
# pwd
/root/work/maple11-11.00
# ls -l
total 6
drwxr-xr-x   4 root     root         512 May 22 09:27 build
-rw-r--r--   1 root     root          41 May 21 17:59 copyright
-rw-r--r--   1 root     root           0 May 22 09:36 depend
-rw-r--r--   1 root     root         143 May 22 09:35 pkginfo
# cat copyright
Copyright MapleSoft, All Rights Reserved
# cat pkginfo
PKG=MAPLmaple11
NAME=maple11
VERSION=11.00
ARCH=sun4u
DESC=Interactive computer algebra system
BASEDIR=/
CATEGORY=application
VENDOR=MapleSoft
EMAIL=renfro@tntech.edu
# ls -al build/opt/maple/11
total 504
drwxrwxr-x  17 root     other        512 May 22 08:43 .
drwxrwxr-x   3 root     other        512 May 22 08:42 ..
drwxr-xr-x   2 root     other        512 May 22 08:42 afm
drwxr-xr-x   2 root     other        512 May 22 08:42 bin
drwxr-xr-x   3 root     other       2048 May 22 08:42 bin.SUN_SPARC_SOLARIS
drwxr-xr-x   9 root     other        512 May 22 08:42 data
drwxr-xr-x   2 root     other        512 May 22 08:42 etc
drwxr-xr-x   2 root     other       3072 May 22 08:42 examples
drwxr-xr-x   3 root     other        512 May 22 08:42 extern
-rw-r--r--   1 root     other     153861 May 21 14:12 Install.html
drwxr-xr-x   2 root     other       1536 May 22 08:42 java
drwxrwxr-x   7 root     other        512 May 22 08:42 jre.SUN_SPARC_SOLARIS
drwxr-xr-x   4 root     other       1536 May 22 08:43 lib
drwxr-xr-x   2 root     other        512 May 22 08:43 license
drwxr-xr-x   3 root     other        512 May 22 08:43 man
-rw-rw-r--   1 root     other      60064 May 21 14:15 Maple_11_InstallLog.log
-rw-r--r--   1 root     other      10285 May 21 14:12 readme.txt
drwxr-xr-x   6 root     other        512 May 22 08:43 samples
drwxr-xr-x   2 root     other        512 May 22 08:43 test
drwxr-xr-x   2 root     other        512 May 22 08:42 X11_defaults
# ls -al build/usr/local/bin
total 10
drwxr-xr-x   2 root     root         512 May 22 08:56 .
drwxr-xr-x   3 root     root         512 May 22 08:47 ..
lrwxrwxrwx   1 root     root          31 May 22 08:55 maple11 -&gt; ../../../opt/maple/11/bin/maple
lrwxrwxrwx   1 root     root          30 May 22 08:56 mint11 -&gt; ../../../opt/maple/11/bin/mint
lrwxrwxrwx   1 root     root          32 May 22 08:55 xmaple11 -&gt; ../../../opt/maple/11/bin/xmaple
</pre>
<p>Now, given that folder structure, I could adapt <a href="http://www.blastwave.org/standards/pkgcreation.php">Blastwave&#8217;s package creation instructions</a> to create some workable Solaris packages:</p>
<pre>
# (echo "i pkginfo"; echo "i copyright" ; echo "i depend" ; cd build ; find . | pkgproto ) &gt; prototype
# pkgmk -b / -a `uname -p`
# filename=maple11-11.00-SunOS`uname -r`-`uname -p`.pkg
# pkgtrans -s /var/spool/pkg /root/$filename MAPLmaple11
# cd /root
# gzip $filename
</pre>
<p>Once mkpkg is all done with its work, I have a valid maple11-11.00-SunOS5.10-sparc.pkg.gz Solaris package in my /root folder. After testing it with regular pkgadd, I&#8217;m ready to put it into a private pkg-get repository.</p>
<p><strong>The pkg-get repository</strong></p>
<p>Compared to <a href="http://blogs.cae.tntech.edu/mwr/2007/05/28/my-own-private-debian-repository/">a Debian repository</a>, a pkg-get repository is pretty simple. From the top-level folder in the repository on the ftp server:</p>
<pre>
# find sparc -print
sparc
sparc/5.10
sparc/5.10/maple11-11.00-SunOS5.10-sparc.pkg.gz
sparc/5.10/descriptions
sparc/5.10/catalog
</pre>
<p>A pkg-get repository&#8217;s top-level folders are named by processor type, i.e., the results of <code>uname -p</code>. Each processor type folder contains folders for each OS release level (from <code>uname -r</code>). Each release level folder contains packages for that CPU and OS, plus a descriptions and a catalog file.</p>
<p>The catalog file is created with Phil Brown&#8217;s <a href="http://www.bolthole.com/solaris/makecontents">makecontents</a> script. It could potentially handle creating the descriptions, file, too, but I guess he never needed them. But the pkg-get script I got from blastwave.org definitely wants a descriptions file, so I&#8217;ll need to create that, too.</p>
<p>The way I&#8217;m creating the descriptions file is with the following script (on a Debian ftp server, so there may be some GNU-isms or bash-isms in the following code):</p>
<pre>
#!/bin/sh
PKG_GET_DIR=/wherever/has/the/sparc/and/i386/folders
cd ${PKG_GET_DIR}
for name in sparc i386; do
    if [ -d $name ]; then
        cd $name
        for version in 5*; do
            if [ -d $version ]; then
                cd $version
                for package in *.gz; do
                    name=`grep $package catalog | awk '{print $1}'`
                    echo -ne "$name - "
                    zcat $package | head | strings | grep DESC= | cut -d= -f2-
                done &gt; descriptions
                cd ..
            fi
        done
        cd ..
    fi
done
</pre>
<p>which leaves me with a catalog file containing (so far, since I&#8217;ve only made one package):</p>
<pre>
maple11 11.00 MAPLmaple11 maple11-11.00-SunOS5.10-sparc.pkg.gz
</pre>
<p>and a descriptions file containing:</p>
<pre>
maple11 - Interactive computer algebra system
</pre>
<p>And now I can install them on a second host that&#8217;s never seen Maple installed before with:</p>
<pre>
pkg-get -s ftp://host/path/to/repository/ -U ; pkg-get -s ftp://host/path/to/repository/ install maple11
</pre>
<p>and afterwards get:</p>
<pre>
# which maple11
/usr/local/bin/maple11
# maple11
    |\\^/|     Maple 11 (SUN SPARC SOLARIS)
._|\\|   |/|_. Copyright (c) Maplesoft, a division of Waterloo Maple Inc. 2007
 \\  MAPLE  /  All rights reserved. Maple is a trademark of
 &lt;____ ____&gt;  Waterloo Maple Inc.
      |       Type ? for help.
&gt; quit
bytes used=412112, alloc=393144, time=0.07
</pre>
]]></content:encoded>
			<wfw:commentRss>http://blogs.cae.tntech.edu/mwr/2008/05/21/making-solaris-packages-from-commercial-software/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>Giving a Presentation at the Tennessee Higher Education IT Symposium</title>
		<link>http://blogs.cae.tntech.edu/mwr/2008/04/22/giving-a-presentation-at-the-tennessee-higher-education-it-symposium/</link>
		<comments>http://blogs.cae.tntech.edu/mwr/2008/04/22/giving-a-presentation-at-the-tennessee-higher-education-it-symposium/#comments</comments>
		<pubDate>Tue, 22 Apr 2008 11:57:15 +0000</pubDate>
		<dc:creator>Mike Renfro</dc:creator>
				<category><![CDATA[Debian]]></category>
		<category><![CDATA[Linux/Unix]]></category>
		<category><![CDATA[Solaris]]></category>
		<category><![CDATA[infrastructures]]></category>
		<category><![CDATA[puppet]]></category>

		<guid isPermaLink="false">http://blogs.cae.tntech.edu/mwr/2008/04/22/giving-a-presentation-at-the-tennessee-higher-education-it-symposium/</guid>
		<description><![CDATA[I&#8217;m heading to the IT Symposium this morning to give a talk on creating a managed Unix infrastructure from scratch, somewhat of a summary of several things I&#8217;ve posted here over the last year or so. Thanks to the folks on #puppet who read over them and gave editing suggestions.

Slides for presentation
Handouts for presentation

Update: So [...]]]></description>
			<content:encoded><![CDATA[<p>I&#8217;m heading to the <a href="http://www.tntech.edu/itsymposium/">IT Symposium</a> this morning to give a talk on creating a managed Unix infrastructure from scratch, somewhat of a summary of several things I&#8217;ve posted here over the last year or so. Thanks to the folks on #puppet who read over them and gave editing suggestions.</p>
<ul>
<li><a href='http://blogs.cae.tntech.edu/mwr/files/2008/04/unix_infrastructure_management_from_scratch_slides.pdf' title='Slides for presentation'>Slides for presentation</a></li>
<li><a href='http://blogs.cae.tntech.edu/mwr/files/2008/04/unix_infrastructure_management_from_scratch_handouts.pdf' title='Handouts for presentation'>Handouts for presentation</a></li>
</ul>
<p><strong>Update:</strong> So yesterday, I get an email regarding my presentation (well, the slides, at least). No reason to clutter up the main page with it though, so if you&#8217;re not happy with the slides and want to express your displeasure, read the rest after the jump and see if I&#8217;ve addressed your concerns already.<span id="more-62"></span></p>
<blockquote><p>
Hi Mike,</p>
<p>I&#8217;ve visited your site before and found your Debian preseeding info to be useful.</p>
<p>That said, I just went through your presentation slides and must say I&#8217;m very disappointed.  It contains numerous examples of what gives sysadmins a bad name.  Egotistical, &#8220;I&#8217;m right, you&#8217;re stupid&#8221;, &#8220;I did this because I&#8217;m way too busy doing more important things than you&#8221;, etc. comments abound.</p>
<p>On several occasions your first bullet-point was &#8220;just do it&#8221;, or &#8220;you need this&#8221;.  Hey Mike, people don&#8217;t come to conferences and presentations to listen to a smart-ass.</p>
<p>You mentioned that the people in #puppet gave you useful feedback.  Next time you give a presentation, also get feedback from non-geeks.  They&#8217;ll help you filter out the cruft that makes you look like a spoiled 5-year old talking about his new widget set at show-and-tell.</p>
<p>I hope for the sake of the attendees that your verbal presentation was better than your slideshow.
</p></blockquote>
<p>To respond to the comments more or less in order:</p>
<ul>
<li>Sorry you didn&#8217;t like my slides. At first, I thought you were an irritated audience member who waited a couple of weeks before emailing me. But since you&#8217;re apparently only judging this based off the slides, that&#8217;s different.</li>
<li>&#8220;I&#8217;m right, you&#8217;re stupid&#8221; is in the eye of the reader. Though you can&#8217;t tell without the soundtrack, it tended to work out more like &#8220;I used to do things one way, which probably is the most common way everyone else does it. It didn&#8217;t scale for the following reasons, and here&#8217;s what I&#8217;m doing instead.&#8221;</li>
<li>&#8220;I did it this way because I&#8217;m way too busy doing more important things than you&#8221; is a bit of an exaggerated inference. Am I busy? Sure. Am I busy doing things that most sysadmins don&#8217;t have to deal with? As far as I can tell, yes; most of the sysadmins in my immediate vicinity (and from past experience over the last 15-20 years) don&#8217;t have major duties outside systems administration, just like most of the engineers don&#8217;t have major duties outside their specialty or lab. These non-sysadmin tasks aren&#8217;t necessarily more important <em>per se</em>, but they&#8217;re important in my particular job description. The hours these other tasks take up in my week force me to find more efficient methods to do the systems administration tasks; others will possibly hit the same walls I have at different times &#8212; maybe when they have to keep track of 300 servers in 10 different roles, where all servers in a particular role have to be interchangeable. Maybe when they get a 1000 node cluster where a particular application has to be installed identically on every node, and on every node to be purchased in the future. My belief is that as time goes on, we&#8217;re all going to be managing more systems, not fewer, and that methods we use for managing a few systems relatively well don&#8217;t scale to larger groups of computers.</li>
<li>&#8220;Just do it&#8221; or &#8220;You need this&#8221; shows up in three places: using version control, using NTP for time synchronization, and using SMTP for email. I stand by each of those points, being entirely convinced by the verbiage at <a href="http://infrastructures.org/">infrastructures.org</a> that was my primary source material. I cannot fathom why someone would use something other than SMTP for sending email, why they wouldn&#8217;t want version control of some form as the code that automates their systems administration tasks grows more complicated, or why they&#8217;d use a different protocol to synchronize their system clocks. To me, each of those is as self-evident as &#8220;your SAN should have redundant power supplies&#8221; and &#8220;racks are a good way to house a bunch of servers in a small space&#8221;. You may have counterexamples, but since you didn&#8217;t provide any, I&#8217;m left in the dark.</li>
<li>The folks on #puppet did give me some useful feedback. As for other feedback, I did ask a coworker to look at the slides, and he saw no problems with them. However, he&#8217;s a full-time Windows systems administrator, so his opinion may be suspect. As for non-geeks, they&#8217;re really not the intended audience, were generally absent from the conference, and aren&#8217;t too likely to be interested in systems administration techniques.</li>
<li>Cruft in the verbal presentation? Guilty, but some might call it illustrative anecdotes. Personally, I&#8217;ve always tried to work in <a href="http://www.sciencecartoonsplus.com/">Sidney Harris</a>&#8216; &#8220;I think you should be more explicit here in step two&#8221; joke into at least one over-equationed lecture per semester. The students seem to enjoy it:<br />
<img src='http://blogs.cae.tntech.edu/mwr/files/2008/05/math07.gif' alt='I think you should be more explicit here in step two' /><br />
Cruft in the slides? Matter of opinion, I guess. I did run out of time, but I honestly hadn&#8217;t done enough practice runs to see how long it would actually take.</li>
<li>As for the spoiled five-year-old showing off his new widget set at show-and-tell, I have trouble understanding the issue. Lots of the talks at these conferences are basically a show-and-tell: other talks included &#8220;Software Deployment Using Ghost&#8221;, &#8220;Virtualizing Business Continuity &#8212; Getting Your Systems Back Online,&#8221; &#8220;DBA Task Automation II: Extending the Basics, Best Practices, Processes and Icing,&#8221; etc. When I submit an abstract saying that I&#8217;m going to give a talk about what goes into a &#8220;managed infrastructure,&#8221; its benefits over regular administration methods, and talk about a particular tool we use to accomplish some of these tasks, exactly what do I change in material? What do I change in delivery (that you didn&#8217;t see)? You&#8217;ve never told coworkers &#8220;holy crap, this Linux thing is awesome! It&#8217;s like Unix, but free and runs on regular PCs!&#8221; or similar? Nothing about using PHP to format stuff out of a database for some dynamic web pages? Nothing about a CMS or blogging platform that lets you do all the things a CMS or blog is supposed to do? Nothing about rrdtool, Nagios, cacti, apt-get, Perl/Python/Ruby or some other tool that you didn&#8217;t write, but by gosh it&#8217;s going to make all of your lives easier?</li>
</ul>
]]></content:encoded>
			<wfw:commentRss>http://blogs.cae.tntech.edu/mwr/2008/04/22/giving-a-presentation-at-the-tennessee-higher-education-it-symposium/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>Stupid Puppet Trick: Agreeing to the Sun Java License with Debconf Preseeds and Puppet</title>
		<link>http://blogs.cae.tntech.edu/mwr/2008/02/05/stupid-puppet-trick-agreeing-to-the-sun-java-license-with-debconf-preseeds-and-puppet/</link>
		<comments>http://blogs.cae.tntech.edu/mwr/2008/02/05/stupid-puppet-trick-agreeing-to-the-sun-java-license-with-debconf-preseeds-and-puppet/#comments</comments>
		<pubDate>Tue, 05 Feb 2008 17:26:30 +0000</pubDate>
		<dc:creator>Mike Renfro</dc:creator>
				<category><![CDATA[Debian]]></category>
		<category><![CDATA[infrastructures]]></category>
		<category><![CDATA[puppet]]></category>

		<guid isPermaLink="false">http://blogs.cae.tntech.edu/mwr/2008/02/05/stupid-puppet-trick-agreeing-to-the-sun-java-license-with-debconf-preseeds-and-puppet/</guid>
		<description><![CDATA[I had a user ask for Java to be installed on the cluster systems, so I started up by making a simple JRE5 module for puppet, but this first one didn&#8217;t quite work:

class jre5 {
  package { "sun-java5-jre":
    ensure =&#62; latest;
  }
}

It doesn&#8217;t work because Sun wants you to agree [...]]]></description>
			<content:encoded><![CDATA[<p>I had a user ask for Java to be installed on the cluster systems, so I started up by making a simple JRE5 module for puppet, but this first one didn&#8217;t quite work:</p>
<pre>
class jre5 {
  package { "sun-java5-jre":
    ensure =&gt; latest;
  }
}
</pre>
<p>It doesn&#8217;t work because Sun wants you to agree to its license before installing the JRE. There&#8217;s a couple of ways around this. First, the old-school method:</p>
<pre>
ssh host "yes | apt-get -y install sun-java5-jre"
</pre>
<p>where &#8216;yes&#8217; is a standard Unix program that just prints out &#8220;yes&#8221; over and over until the program on the other side of the pipe terminates. But &#8220;ssh host foo&#8221; is not the way of the managed infrastructure. </p>
<p>The second method, much more friendly to centralized management, is to first install debconf-utils on a candidate system, and then install sun-java5-jre on the same system. Once that&#8217;s done, you can query the debconf database to see how it stored your answers to the Sun license agreement:</p>
<pre>
ch226-12:~# debconf-get-selections | grep sun-
sun-java5-bin   shared/accepted-sun-dlj-v1-1    boolean true
sun-java5-jre   shared/accepted-sun-dlj-v1-1    boolean true
sun-java5-jre   sun-java5-jre/jcepolicy note
sun-java5-jre   sun-java5-jre/stopthread        boolean true
sun-java5-bin   shared/error-sun-dlj-v1-1       error
sun-java5-jre   shared/error-sun-dlj-v1-1       error
sun-java5-bin   shared/present-sun-dlj-v1-1     note
sun-java5-jre   shared/present-sun-dlj-v1-1     note
</pre>
<p>Save those results (debconf seeds) into a file on the gold server. Then we can modify our jre5 class as follows:</p>
<pre>
class jre5 {
  package { "sun-java5-jre":
    require      =&gt; File["/var/cache/debconf/jre5.seeds"],
    responsefile =&gt; "/var/cache/debconf/jre5.seeds",
    ensure       =&gt; latest;
  }

  file { "/var/cache/debconf/jre5.seeds":
    source =&gt; "puppet:///jre5/jre5.seeds",
    ensure =&gt; present;
  }
}
</pre>
<p>Now our class will download the preseeded answers for the Java license, download and install the JRE, and then use the preseeded answers to skip past the license agreement. I had never messed with debconf seeding previously, since I had either just imaged my systems, or provided config files that would be used when I restarted any daemons or programs that depended on those files. Now debconf-utils is part of my standard system class definition.</p>
<p>Note that this method doesn&#8217;t work with the default puppet provided in Debian Etch (version 0.20) &#8212; the responsefile parameter for Debian packages was only added in puppet 0.22.</p>
]]></content:encoded>
			<wfw:commentRss>http://blogs.cae.tntech.edu/mwr/2008/02/05/stupid-puppet-trick-agreeing-to-the-sun-java-license-with-debconf-preseeds-and-puppet/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>The autostow is Dead, Long Live stowedpackage!</title>
		<link>http://blogs.cae.tntech.edu/mwr/2008/02/01/the-autostow-is-dead-long-live-stowedpackage/</link>
		<comments>http://blogs.cae.tntech.edu/mwr/2008/02/01/the-autostow-is-dead-long-live-stowedpackage/#comments</comments>
		<pubDate>Fri, 01 Feb 2008 21:15:52 +0000</pubDate>
		<dc:creator>Mike Renfro</dc:creator>
				<category><![CDATA[infrastructures]]></category>
		<category><![CDATA[puppet]]></category>

		<guid isPermaLink="false">http://blogs.cae.tntech.edu/mwr/2008/02/01/the-autostow-is-dead-long-live-stowedpackage/</guid>
		<description><![CDATA[I had posted earlier about distributing stowed packages via rsync and puppet to my managed systems, but that method wasn&#8217;t quite what I wanted:

There was one more file to manage outside my regular puppet manifests, and I&#8217;d have to remember to keep them both up to date and in sync.
There wasn&#8217;t an easy way of [...]]]></description>
			<content:encoded><![CDATA[<p><a href="http://blogs.cae.tntech.edu/mwr/2007/05/19/client-application-management-part-2-for-stow-packages/">I had posted earlier</a> about distributing stowed packages via rsync and puppet to my managed systems, but that method wasn&#8217;t quite what I wanted:</p>
<ol>
<li>There was one more file to manage outside my regular puppet manifests, and I&#8217;d have to remember to keep them both up to date and in sync.</li>
<li>There wasn&#8217;t an easy way of ensuring that other versions of a particular package got unstowed before deploying out the desired version.</li>
<li>The entire stow tree would be copied out to every system, regardless of whether OpenMPI was a good fit for the web server.</li>
</ol>
<p>So, here&#8217;s my new method:</p>
<ol>
<li>Keep my same metastow module loaded on the rsync server. The metastow module contains one top-level directory per puppet architecture (i686, x86_64, etc.). Each of those architecture folders is a stow tree containing every stowed package for that architecture.</li>
<li>Add a stowedpackage definition to my puppet manifests as follows:
<pre>
define stowedpackage ( $basepackage, $version,
    $rsyncserver='gold.cae.tntech.edu',
    $rsyncmodule='metastow',
    $stowdestdir='/usr/local/stow' ) {
    file { "stow-initiator_${basepackage}-${version}":
        source =&gt; "puppet:///files/stow-initiator_${basepackage}-${version}",
        path   =&gt; "/etc/puppet/stow-initiator_${basepackage}-${version}",
    }
    exec { download:
        command     =&gt; "/usr/bin/rsync -a --delete ${rsyncserver}::${rsyncmodule}/${hardwaremodel}/${basepackage}-${version} ${stowdestdir}",
        refreshonly =&gt; true,
        subscribe   =&gt; File["stow-initiator_${basepackage}-${version}"],
        alias       =&gt; "download_${basepackage}-${version}"
    }
    exec { unstow-others:
        command     =&gt; "cd ${stowdestdir} &amp;&amp; stow --delete ${basepackage}-*",
        refreshonly =&gt; true,
        subscribe   =&gt; Exec["download_${basepackage}-${version}"],
        alias       =&gt; "unstow-others_${basepackage}-${version}"
    }
    exec { stow:
        command     =&gt; "cd ${stowdestdir} ; stow ${basepackage}-${version}",
        refreshonly =&gt; true,
        subscribe   =&gt; Exec["unstow-others_${basepackage}-${version}"]
    }
}
</pre>
</li>
<li>Use the stowedpackage definition in other parts of my manifests:
<pre>
# Create OpenMPI installation and configuration.
class openmpi {

    stowedpackage {
        "openmpi-1.0.1":
            basepackage=&gt;"openmpi",
            version=&gt;"1.0.1";
    }

}
</pre>
</li>
<li>Add a trigger file to the puppetmaster&#8217;s /etc/puppet/files folder:
<pre>
/etc/puppet/files# date &gt; stow-initiator_openmpi-1.0.1
</pre>
</li>
]]></content:encoded>
			<wfw:commentRss>http://blogs.cae.tntech.edu/mwr/2008/02/01/the-autostow-is-dead-long-live-stowedpackage/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Client Configuration Management</title>
		<link>http://blogs.cae.tntech.edu/mwr/2007/10/31/client-configuration-management/</link>
		<comments>http://blogs.cae.tntech.edu/mwr/2007/10/31/client-configuration-management/#comments</comments>
		<pubDate>Thu, 01 Nov 2007 01:17:21 +0000</pubDate>
		<dc:creator>Mike Renfro</dc:creator>
				<category><![CDATA[infrastructures]]></category>
		<category><![CDATA[puppet]]></category>

		<guid isPermaLink="false">http://blogs.cae.tntech.edu/mwr/2007/10/31/client-configuration-management/</guid>
		<description><![CDATA[Back at the infrastructures.org mothership, client configuration management is described as everything that makes a host unique and/or part of a particular group or domain. And for Unix-like systems, everything pretty much comes down to configuration files, services being enabled/disabled, and cron jobs.
Hmm.

Configuration files
Services
Cron jobs

Looks like Puppet pretty much handles all of that. As long [...]]]></description>
			<content:encoded><![CDATA[<p>Back at the infrastructures.org mothership, <a href="http://www.infrastructures.org/bootstrap/config.shtml">client configuration management</a> is described as everything that makes a host unique and/or part of a particular group or domain. And for Unix-like systems, everything pretty much comes down to configuration files, services being enabled/disabled, and cron jobs.</p>
<p>Hmm.</p>
<ul>
<li><a href="http://reductivelabs.com/trac/puppet/wiki/TypeReference#file">Configuration files</a></li>
<li><a href="http://reductivelabs.com/trac/puppet/wiki/TypeReference#service">Services</a></li>
<li><a href="http://reductivelabs.com/trac/puppet/wiki/TypeReference#cron">Cron jobs</a></li>
</ul>
<p>Looks like Puppet pretty much handles all of that. As long as I can describe aspects of my systems with puppet classes and modules, I&#8217;ve got reusable, consistent configurations on any servers I care to manage.</p>
]]></content:encoded>
			<wfw:commentRss>http://blogs.cae.tntech.edu/mwr/2007/10/31/client-configuration-management/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Client File Access</title>
		<link>http://blogs.cae.tntech.edu/mwr/2007/10/31/client-file-access/</link>
		<comments>http://blogs.cae.tntech.edu/mwr/2007/10/31/client-file-access/#comments</comments>
		<pubDate>Thu, 01 Nov 2007 01:00:16 +0000</pubDate>
		<dc:creator>Mike Renfro</dc:creator>
				<category><![CDATA[Debian]]></category>
		<category><![CDATA[infrastructures]]></category>
		<category><![CDATA[puppet]]></category>

		<guid isPermaLink="false">http://blogs.cae.tntech.edu/mwr/2007/10/31/client-file-access/</guid>
		<description><![CDATA[The infrastructures.org folks list two primary goals of what they call &#8220;client file access&#8220;: first, consistent access to users&#8217; home directories, and second, consistent access to end-user applications. Some of the things they warn against, such as automounters and the /net directory, we never thought of using to begin with. Their need to consider systems [...]]]></description>
			<content:encoded><![CDATA[<p>The infrastructures.org folks list two primary goals of what they call &#8220;<a href="http://www.infrastructures.org/bootstrap/fileclient.shtml">client file access</a>&#8220;: first, consistent access to users&#8217; home directories, and second, consistent access to end-user applications. Some of the things they warn against, such as automounters and the /net directory, we never thought of using to begin with. Their need to consider systems with limited disk space and a need to mount a software share via NFS is less of an issue with us, too: disks large enough to hold our regular software load are relatively cheap, so there shouldn&#8217;t be much of a problem there. And since we&#8217;re supposed to be deploying applications consistently via Puppet, there shouldn&#8217;t be any inconsistency in where an application is installed. As far as consistent access to the home directories, we accomplish this with a two-pronged solution in Puppet &#8212; one on the file server, and one on the clients:<br />
<span id="more-48"></span><br />
On the Debian file server, we include the following class:</p>
<pre>
class nfs-server {
  package { nfs-kernel-server: ensure =&gt; installed }

  file { exports:
    path =&gt; $operatingsystem ? {
      default =&gt; "/etc/exports"
    },
    owner =&gt; root, group =&gt; root, mode =&gt; 644,
    source =&gt; "puppet://gold.cae.tntech.edu/files/apps/nfs-server/exports",
    require =&gt; Package[nfs-kernel-server]
  }

  service { nfs-kernel-server:
    ensure =&gt; running,
    enable =&gt; true,
    hasstatus =&gt; true,
    subscribe =&gt; [Package[nfs-kernel-server], File[exports]]
  }
  service { portmap:
    ensure =&gt; running,
    enable =&gt; true,
  }
}
</pre>
<p>We also include the following in its node definition:</p>
<pre>
    file {
        "/etc/exports.d":
        source  =&gt; "puppet:///files/apps/nfs-kernel-server/exports.d",
        ensure  =&gt; directory,
        ignore  =&gt; ".svn",
        purge   =&gt; true,
        recurse =&gt; inf;
    }

    concatenated_file {
        "/etc/exports":
            dir =&gt; "/etc/exports.d";
    }
</pre>
<p>Each file dropped in /etc/exports.d is a fragment of /etc/exports. Right now, we&#8217;re using one fragment per exported filesystem. As an example, here&#8217;s /etc/exports.d/_opt_solaris_stow:</p>
<pre>
/opt/solaris/stow \\
        149.149.254.12(rw,sync,no_root_squash) \\
        149.149.254.13(rw,sync,no_root_squash) \\
        149.149.254.14(rw,sync,no_root_squash) \\
        149.149.254.15(rw,sync,no_root_squash) \\
        149.149.254.220(rw,sync,no_root_squash)
</pre>
<p>David Schmitt&#8217;s concatenated_file definition combines all the export fragments into one /etc/exports file:</p>
<pre>
define concatenated_file ($dir, $mode = 0644, $owner = root, $group = root)
{
    file {
        $name:
            ensure   =&gt; present,
            checksum =&gt; md5,
            mode     =&gt; $mode,
            owner    =&gt; $owner,
            group =&gt; $group;
    }
    exec { "find ${dir} -maxdepth 1 -type f ! -name '*puppettmp' -print0 | sort -z | xargs -0 cat &gt; ${name}":
        refreshonly =&gt; true,
        subscribe   =&gt; File[$dir],
        alias       =&gt; "concat_${name}",
    }
}
define concatenated_file_part ($dir, $content = '', $ensure = present,
                               $mode = 0644, $owner = root, $group = root) {
    file { "${dir}/${name}":
        ensure  =&gt; $ensure,
        content =&gt; $content,
        mode    =&gt; $mode,
        owner   =&gt; $owner,
        group   =&gt; $group,
        alias   =&gt; "cf_part_${name}",
    }
}
</pre>
<p>On the client side, we just make sure we can mount the NFS share. For example:</p>
<pre>
    file {
        "/home/CAE":
            ensure =&gt; directory,
            owner  =&gt; root,
            group  =&gt; root,
            mode   =&gt; 755,
    }
    mount { "/home/CAE":
        require =&gt; File["/home/CAE"],
        atboot  =&gt; true,
        fstype  =&gt; "nfs",
        device  =&gt; "files.cae.tntech.edu:/home/CAE",
        ensure  =&gt; mounted,
        options =&gt; "defaults",
        dump    =&gt; "0",
        pass    =&gt; "0",
    }
    package { "nfs-common": ensure =&gt; installed }
</pre>
]]></content:encoded>
			<wfw:commentRss>http://blogs.cae.tntech.edu/mwr/2007/10/31/client-file-access/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>
