<?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; Debian</title>
	<atom:link href="http://blogs.cae.tntech.edu/mwr/category/debian/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>Setting up Project Quotas under XFS in Debian GNU/Linux</title>
		<link>http://blogs.cae.tntech.edu/mwr/2009/09/01/setting-up-project-quotas-under-xfs-in-debian-gnulinux/</link>
		<comments>http://blogs.cae.tntech.edu/mwr/2009/09/01/setting-up-project-quotas-under-xfs-in-debian-gnulinux/#comments</comments>
		<pubDate>Tue, 01 Sep 2009 15:45:37 +0000</pubDate>
		<dc:creator>Mike Renfro</dc:creator>
				<category><![CDATA[Debian]]></category>
		<category><![CDATA[Linux/Unix]]></category>

		<guid isPermaLink="false">http://blogs.cae.tntech.edu/mwr/?p=119</guid>
		<description><![CDATA[Quick and dirty notes for getting XFS project quotas running: I&#8217;m working on making storage areas for various capstone design class groups, vehicle teams, etc. I&#8217;d like to ensure that they don&#8217;t take an excessive amount of storage, too. These instructions are slightly different than what I&#8217;d found elsewhere, and I&#8217;m hoping to have someone [...]]]></description>
			<content:encoded><![CDATA[<p>Quick and dirty notes for getting XFS project quotas running: I&#8217;m working on making storage areas for various capstone design class groups, vehicle teams, etc. I&#8217;d like to ensure that they don&#8217;t take an excessive amount of storage, too. These instructions are slightly different than what I&#8217;d found elsewhere, and I&#8217;m hoping to have someone confirm that what I&#8217;m doing is correct and update the appropriate man pages accordingly.</p>
<p>So assuming we have a project for ME4444, group 3 (I already had projects defined for groups 1 and 2 from earlier tests):</p>
<pre># grep /home /etc/fstab
/dev/md1000/home        /home   xfs     defaults,usrquota,prjquota      0      1
# echo "me4444-03:/home/projects/me4444-03" &gt;&gt; /etc/projects
# echo "me4444-03:3" &gt;&gt; /etc/projid
# mkdir /home/projects/me4444-03
# xfs_quota -x -c "project -s me4444-03"
Setting up project me4444-03 (path /home/projects/me4444-03)...
Processed 1 /etc/projects paths for project me4444-03
# xfs_quota -x -c "limit -p bsoft=5g bhard=10g me4444-03"
# xfs_quota -x -c "report -p"
Project quota on /home (/dev/md1000/home)
                               Blocks
Project ID       Used       Soft       Hard    Warn/Grace
---------- --------------------------------------------------
me4444-01           0          0    1048576     00 [--------]
me4444-02           0    5242880   10485760     00 [--------]
me4444-03           0    5242880   10485760     00 [--------]</pre>
<p>Now group 3 has a 5 GB &#8220;soft&#8221; quota, can exceed that for up to 7 days at a time, but can never exceed their 10 GB &#8220;hard&#8221; quota. All that&#8217;s left is setting up directory permissions and Samba configuration so that the authorized users can store things there.</p>
]]></content:encoded>
			<wfw:commentRss>http://blogs.cae.tntech.edu/mwr/2009/09/01/setting-up-project-quotas-under-xfs-in-debian-gnulinux/feed/</wfw:commentRss>
		<slash:comments>0</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>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>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>
		<item>
		<title>Watching Remote System Status with Nagios and NRPE</title>
		<link>http://blogs.cae.tntech.edu/mwr/2007/10/05/watching-remote-system-status-with-nagios-and-nrpe/</link>
		<comments>http://blogs.cae.tntech.edu/mwr/2007/10/05/watching-remote-system-status-with-nagios-and-nrpe/#comments</comments>
		<pubDate>Fri, 05 Oct 2007 22:16:34 +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/05/watching-remote-system-status-with-nagios-and-nrpe/</guid>
		<description><![CDATA[I know I&#8217;m late to the game with this part of my setup, but nonetheless, I&#8217;m happy with the results. The short form of it is that Debian&#8217;s nagios-nrpe-server package lets my central Nagios server keep track of my clients&#8217; disk space, load averages, etc. Granted, I already had most of that visible through Ganglia, [...]]]></description>
			<content:encoded><![CDATA[<p>I know I&#8217;m late to the game with this part of my setup, but nonetheless, I&#8217;m happy with the results. The short form of it is that Debian&#8217;s <a href="http://packages.debian.org/etch/nagios-nrpe-server">nagios-nrpe-server</a> package lets my central Nagios server keep track of my clients&#8217; disk space, load averages, etc. Granted, I already had most of that visible through Ganglia, too, but Ganglia&#8217;s more of a grapher and collector, and not a notifier. I used to keep track of that stuff with <a href="http://spong.sourceforge.net/">Spong</a>, but when I switched over to Nagios, that functionality went missing. Now, if one of the graduate students (let&#8217;s call him &#8220;new guy&#8221;) fills up 288 GB of /tmp and tells his advisor &#8220;the program crashed for some reason&#8221;, I won&#8217;t be finding the bloody remains days later when another student asks me why their program won&#8217;t run at all.</p>
<p><a href='http://blogs.cae.tntech.edu/mwr/files/2007/10/nrpe-output.png' title='nrpe-output.png'><img src='http://blogs.cae.tntech.edu/mwr/files/2007/10/nrpe-output.png' alt='nrpe-output.png' /></a></p>
<p>Puppet and other configuration excerpts follow.</p>
<p>classes/nagios-nrpe-server.pp:</p>
<pre>
class nagios-nrpe-server {
    # nagios-nrpe-server for remote monitoring
    package {
        [ "nagios-nrpe-server", "nagios-plugins" ]:
            ensure =&gt; installed;
    }
    file {
        "/etc/nagios":
            ensure =&gt; directory,
            owner  =&gt; root,
            group  =&gt; root,
            mode   =&gt; 0755;
        "/etc/nagios/nrpe_local.cfg":
            source =&gt; "puppet:///files/apps/nagios-nrpe-server/nrpe_local.cfg";
    }
    service {
        "nagios-nrpe-server":
            ensure    =&gt; running,
            pattern   =&gt; "/usr/sbin/nrpe",
            subscribe =&gt; File["/etc/nagios/nrpe_local.cfg"],
            require   =&gt; Package["nagios-nrpe-server"];
    }
}
</pre>
<p>files/apps/nagios-nrpe-server/nrpe_local.cfg:</p>
<pre>
allowed_hosts=127.0.0.1,NAGIOSIP
command[check_disk_root]=/usr/lib/nagios/plugins/check_disk -w 20 -c 10 -p /
command[check_disk_boot]=/usr/lib/nagios/plugins/check_disk -w 20 -c 10 -p /boot
command[check_disk_tmp]=/usr/lib/nagios/plugins/check_disk -w 20 -c 10 -p /tmp
command[check_disk_var]=/usr/lib/nagios/plugins/check_disk -w 20 -c 10 -p /var
command[check_disk_amanda]=/usr/lib/nagios/plugins/check_disk -w 20 -c 10 -p /opt/amanda
command[check_disk_home]=/usr/lib/nagios/plugins/check_disk -w 20 -c 10 -p /home
</pre>
<p>excerpt from /etc/nagios2/conf.d/hosts.cfg:</p>
<pre>
define service{
        use                     generic-service
        host_name               ch226-21, ch226-22, ch226-23, ch226-24, ch226-25, ch226-26, ch226-27, ch226-28, ch226-29, ch226-30, ch226-31, ch226-32
        service_description     Disk Usage - /
        check_command           check_nrpe_1arg!check_disk_root
        contact_groups  admins
}
define service{
        use                     generic-service
        host_name               ch226-21, ch226-22, ch226-23, ch226-24, ch226-25, ch226-26, ch226-27, ch226-28, ch226-29, ch226-30, ch226-31, ch226-32
        service_description     Disk Usage - /tmp
        check_command           check_nrpe_1arg!check_disk_tmp
        contact_groups  admins
}
</pre>
]]></content:encoded>
			<wfw:commentRss>http://blogs.cae.tntech.edu/mwr/2007/10/05/watching-remote-system-status-with-nagios-and-nrpe/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Solution to a Vexing update-alternatives Problem</title>
		<link>http://blogs.cae.tntech.edu/mwr/2007/09/22/solution-to-a-vexing-update-alternatives-problem/</link>
		<comments>http://blogs.cae.tntech.edu/mwr/2007/09/22/solution-to-a-vexing-update-alternatives-problem/#comments</comments>
		<pubDate>Sat, 22 Sep 2007 22:13:18 +0000</pubDate>
		<dc:creator>Mike Renfro</dc:creator>
				<category><![CDATA[Debian]]></category>

		<guid isPermaLink="false">http://blogs.cae.tntech.edu/mwr/2007/09/22/solution-to-a-vexing-update-alternatives-problem/</guid>
		<description><![CDATA[So I&#8217;ve got Debian packages made from lots of large proprietary software titles, but one of them (Hyperworks)  had been throwing errors on several of the systems I tried to install it on, normally something like:

Setting up hyperworks8 (8.1+0.2) ...
update-alternatives: slave link name /usr/bin/amfbuilder duplicated
dpkg: error processing hyperworks8 (--configure):  subprocess post-installation script returned [...]]]></description>
			<content:encoded><![CDATA[<p>So I&#8217;ve got <a href="http://blogs.cae.tntech.edu/mwr/2007/05/28/making-debian-packages-from-commercial-software/">Debian packages made from lots of large proprietary software titles</a>, but one of them (Hyperworks)  had been throwing errors on several of the systems I tried to install it on, normally something like:<br />
<code><br />
Setting up hyperworks8 (8.1+0.2) ...<br />
update-alternatives: slave link name /usr/bin/amfbuilder duplicated<br />
dpkg: error processing hyperworks8 (--configure):  subprocess post-installation script returned error exit status 2<br />
Errors were encountered while processing:<br />
  hyperworks8<br />
E: Sub-process /usr/bin/dpkg returned an error code (1)<br />
</code></p>
<p>I tried lots of quick fixes:</p>
<ul>
<li>purge, clean, and reinstall &#8212; no good.</li>
<li>purge, clean, clear out /etc/alternatives and /usr/bin of any detritus from earlier package versions &#8212; no luck there, either</li>
<li>edit /var/lib/dpkg/info/hyperworks8.postinst to remove the amfbuilder line &#8212; that just moved the error onto another program included in the package</li>
</ul>
<p>Finally, I found a /var/lib/dpkg/alternatives/hw file and removed it. It contained nothing but my Hyperworks-related settings, so that was safe. Afterwards, no more errors.</p>
]]></content:encoded>
			<wfw:commentRss>http://blogs.cae.tntech.edu/mwr/2007/09/22/solution-to-a-vexing-update-alternatives-problem/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Authentication Servers, the Next Generation</title>
		<link>http://blogs.cae.tntech.edu/mwr/2007/08/02/authentication-servers-the-next-generation/</link>
		<comments>http://blogs.cae.tntech.edu/mwr/2007/08/02/authentication-servers-the-next-generation/#comments</comments>
		<pubDate>Thu, 02 Aug 2007 23:48:51 +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/08/02/authentication-servers-the-next-generation/</guid>
		<description><![CDATA[I&#8217;m mildly embarrassed by my previous setup authentication servers, but this one should be a vast improvement. A reminder of the existing constraints and conditions:

Lots of Linux systems and a few Solaris systems, some of which dual-boot and aren&#8217;t accessible as *nix systems during normal hours of the day
An Active Directory already in place
An overworked [...]]]></description>
			<content:encoded><![CDATA[<p>I&#8217;m mildly embarrassed by <a href="http://blogs.cae.tntech.edu/mwr/2007/05/16/authentication-servers/">my previous setup authentication servers</a>, but this one should be a vast improvement. A reminder of the existing constraints and conditions:
<ul>
<li>Lots of Linux systems and a few Solaris systems, some of which dual-boot and aren&#8217;t accessible as *nix systems during normal hours of the day</li>
<li>An Active Directory already in place</li>
<li>An overworked administration team that has lots of other stuff to do besides create user accounts</li>
</ul>
<p>As I had indicated at the end of the previous authentication server post, my experience with <a href="http://www.samba.org/samba/docs/man/Samba-HOWTO-Collection/winbind.html">winbind</a> has gotten decidedly more positive lately. My previous experience with it in 2001-2002 was entirely negative, since either due to design limitations or my own incompetence, I was unable to get multiple systems running winbind to agree on what the users&#8217; UIDs and GIDs were, which made NFS unworkable. As of 2007, things have improved vastly.<span id="more-32"></span></p>
<p>So what do I need the authentication server structure to do for me?
<ol>
<li>keep a canonical mapping of usernames and groups to UIDs and GIDs</li>
<li>keep a list of which users are allowed to access particular hosts or services</li>
<li>keep a canonical list of passwords for those users</li>
</ol>
<p>NSS and Winbind will handle the first goal. PAM and the pam_listfile module will handle the second goal. And PAM and Kerberos will handle the third. Winbind and Kerberos will both verify everything against the existing Active Directory. The gold server will generate a master list of allowed users via puppet and file fragments, and all the clients will use that list by default.</p>
<p>The puppet manifest for an Active Directory member system looks like:</p>
<pre>
# For our purposes, an Active Directory member should:

# 1. Run winbind to enumerate users and groups beyond what's already in
#    /etc/passwd and /etc/group (requires working machine account in
#    domain)

# 2. Keep a list of valid users for the local system, since not all
#    domain users should get automatic shell access

# 3. Check passwords via Kerberos

class active-directory-member {
    package {
        [ "winbind", "krb5-config", "libpam-krb5" ]:
            ensure    =&gt; installed;
    }
    service { [ "winbind" ]:
        pattern   =&gt; "/usr/sbin/winbindd",
        ensure    =&gt; running,
        subscribe =&gt; [ File["/etc/samba/smb.conf"],
                       File["/var/lib/samba/secrets.tdb"] ];
    }
    file {
        "/etc/samba/smb.conf":
            source =&gt; "puppet:///files/apps/samba/smb.conf";

        "/var/lib/samba":
            ensure =&gt; directory,
            owner  =&gt; root,
            group  =&gt; root,
            mode   =&gt; 755;

        "/var/lib/samba/secrets.tdb":
            source =&gt; "puppet:///private/secrets.tdb",
            owner  =&gt; root,
            group  =&gt; root,
            mode   =&gt; 600;

        "/etc/nsswitch.conf":
            source =&gt; "puppet:///files/apps/active-directory-member/nsswitch.conf";

        "/etc/pam.d/common-account":
            source =&gt; "puppet:///files/apps/active-directory-member/common-account";

        "/etc/krb5.conf":
            source =&gt; "puppet:///files/apps/active-directory-member/krb5.conf";

        "/etc/pam.d/common-auth":
            source =&gt; "puppet:///files/apps/active-directory-member/common-auth";

        "/etc/security/users.conf":
            source =&gt; "puppet:///files/apps/pam_listfile/users.conf.default";
    }
}
</pre>
<p>Most of this is pretty straightforward Puppet management (&#8221;I need winbind, libpam-krb5, and krb5-config installed.&#8221; &#8220;Make sure winbind is running, and restart it if the machine account file or the Samba configuration file changes.&#8221; &#8220;Grab these Kerberos config files from the puppet server.&#8221;) A few things that might be non-obvious:</p>
<p>I&#8217;ve got a private fileserver area on the puppet server. I use this to store system-specific security information, such as ssh keys and the Samba machine account (secrets.tdb) for Active Directory. Barring a puppet-level breakin on the gold server or a root-level breakin on the CVS server, this is safe. Only systems with properly signed keys get access to their specific private folder, and they don&#8217;t get access to any other system&#8217;s private folder.</p>
<p>The Samba configuration I use for systems that only need winbind running is pretty minimal:</p>
<pre>
[global]
   netbios name = %h-linux
   workgroup = CAE
   log file = /var/log/samba/log.%m
   max log size = 1000
   syslog = 0
   panic action = /usr/share/samba/panic-action %d
   security = ADS
   realm = CAE.TNTECH.EDU
   allow trusted domains = No
   idmap backend = idmap_rid:CAE=5000-100000000
   idmap uid = 5000-100000000
   idmap gid = 5000-100000000
   template shell = /bin/bash
   winbind use default domain = Yes
   winbind nested groups = Yes
; The following was the default behaviour in sarge
; but samba upstream reverted the default because it might induce
; performance issues in large organizations
; See #368251 for some of the consequences of *not* having
; this setting and smb.conf(5) for all details
;
;   winbind enum groups = yes
;   winbind enum users = yes
   winbind enum users = No
   winbind enum groups = No
</pre>
<p>but it&#8217;s good enough to tell winbind where to look for username, UID, and GID information. <code>netbios name</code> is set differently from the default to ensure that we don&#8217;t have a conflict on dual-boot systems between their Windows machine account and their Linux machine account. On Linux-only systems, I could get away with using the default, but this setting works in both cases, so I&#8217;ll likely keep it as-is.</p>
<p>Since all my winbind systems use the same <a href="http://samba.org/samba/docs/man/Samba-HOWTO-Collection/idmapper.html">idmap</a> backend and read the same RIDs from Active Directory (added in Samba 3.0.8, November 2004), they all calculate the same UIDs and GIDs. No NFS problems there any more. One step that&#8217;s not yet automated is <a href="http://us1.samba.org/samba/docs/man/Samba-HOWTO-Collection/domain-member.html#ads-member">the initial creation of an Active Directory machine account</a>. On larger rollouts, I expect I&#8217;ll ssh into each system and run that part by hand. Eventually, I plan to either put this into a puppet manifest or into my preseed configuration. I&#8217;ll also need to make sure that I periodically sync the machine accounts from the local systems to the gold server, since Active Directory machine accounts change their own passwords from time to time.</p>
<p>nsswitch.conf has added entries for winbind on the passwd, group, and shadow databases:</p>
<pre>
# /etc/nsswitch.conf
#
# Example configuration of GNU Name Service Switch functionality.
# If you have the `glibc-doc-reference' and `info' packages installed, try:
# `info libc "Name Service Switch"' for information about this file.

passwd:         compat winbind
group:          compat winbind
shadow:         compat winbind

hosts:          files dns
networks:       files

protocols:      db files
services:       db files
ethers:         db files
rpc:            db files

netgroup:       nis
</pre>
<p>common-account and common-auth are where most Debian PAM-aware applications look for account and authentication information, respectively.</p>
<pre>
#
# /etc/pam.d/common-account - authorization settings common to all services
#
# This file is included from other service-specific PAM config files,
# and should contain a list of the authorization modules that define
# the central access policy for use on the system.  The default is to
# only deny service to users whose accounts are expired in /etc/shadow.
#
account sufficient      pam_unix.so
account required        pam_listfile.so onerr=fail sense=allow file=/etc/security/users.conf item=user
account required        pam_winbind.so
</pre>
<p>If we&#8217;re looking up an account entry (not a password):</p>
<ol>
<li>If they&#8217;re in the local passwd file, they&#8217;re allowed.</li>
<li>If they&#8217;re in the list of allowed users, they&#8217;re allowed. Otherwise, they&#8217;re not, so don&#8217;t go any further.</li>
<li>If you&#8217;ve gotten this far, and they&#8217;re in the Active Directory, they&#8217;re allowed.</li>
</ol>
<pre>
#
# /etc/pam.d/common-auth - authentication settings common to all services
#
# This file is included from other service-specific PAM config files,
# and should contain a list of the authentication modules that define
# the central authentication scheme for use on the system
# (e.g., /etc/shadow, LDAP, Kerberos, etc.).  The default is to use the
# traditional Unix authentication mechanisms.
#
auth    sufficient      pam_unix.so nullok_secure
auth    required        pam_krb5.so use_first_pass
</pre>
<p>If we&#8217;re looking up a password entry:</p>
<ol>
<li>If you can verify them from the local shadow file, they&#8217;re allowed. No need to look any further.</li>
<li>If you can verify them from the Active Directory via Kerberos, they&#8217;re allowed.</li>
</ol>
<p>krb5.conf is set the same way as I noted in the previous post. Mostly, it just needs to have <code>kdc</code> entries for each Active Directory server, and <code>admin_server</code> set to the Active Directory master, and <code>default_realm</code> set to the Active Directory domain name.</p>
<p>users.conf is generated on the puppetmaster by concatenating one file per user from a users.conf.d directory. Each file contains one line: the user&#8217;s username. Eventually, we may modify things to make each file a group of users (one faculty&#8217;s advisees, all the members of an advanced class, etc.), but for now, <code>echo bob &gt; /etc/puppet/files/apps/pam_listfile/users.conf.d/bob</code> works ok for us. The puppetmaster&#8217;s manifest now includes:</p>
<pre>
    concatenated_file {
        "/etc/puppet/files/apps/pam_listfile/users.conf.default":
            dir =&gt; "/etc/puppet/files/apps/pam_listfile/users.conf.d"
    }
</pre>
<p>using David Schmitt&#8217;s /etc/puppet/manifests/definitions/concatenated_file.pp &#8212; at one point, I had the client systems running concatenated_file themselves, but the latency and md5 load for 270+ one-line files on the puppetmaster was ridiculous.</p>
]]></content:encoded>
			<wfw:commentRss>http://blogs.cae.tntech.edu/mwr/2007/08/02/authentication-servers-the-next-generation/feed/</wfw:commentRss>
		<slash:comments>6</slash:comments>
		</item>
		<item>
		<title>The New File Server: Puppet and Modules</title>
		<link>http://blogs.cae.tntech.edu/mwr/2007/08/02/the-new-file-server-puppet-and-modules/</link>
		<comments>http://blogs.cae.tntech.edu/mwr/2007/08/02/the-new-file-server-puppet-and-modules/#comments</comments>
		<pubDate>Thu, 02 Aug 2007 21:24:10 +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/08/02/the-new-file-server-puppet-and-modules/</guid>
		<description><![CDATA[On to Puppet. I&#8217;ve not yet factored everything about the new server out into separate modules or classes; that&#8217;ll come later. But things that will either get reused on other systems (e.g., Active Directory ties) or things that need to be generated consistently and repeatedly (e.g., Amanda configurations) have been factored out. The new server&#8217;s [...]]]></description>
			<content:encoded><![CDATA[<p>On to Puppet. I&#8217;ve not yet factored everything about the new server out into separate modules or classes; that&#8217;ll come later. But things that will either get reused on other systems (e.g., Active Directory ties) or things that need to be generated consistently and repeatedly (e.g., Amanda configurations) have been factored out. The new server&#8217;s manifest looks like:<span id="more-31"></span></p>
<pre>
node ch208r {
    include cae-host

    # ch208r (new file server) needs:

    # Disk tools (XFS support, LVM support, parted)
    package {
        [ "xfsdump", "lvm2", "parted" ]: ensure =&gt; installed;
    }
    # Backup tools (see amandaconfig module for details)
    include amanda
    amanda::amandaconfig {
        "holding":
            labelstr   =&gt; "HOLDING",
            dumpcycle  =&gt; 1,
            tapecycle  =&gt; 2,
            runtapes   =&gt; 1;
        "daily":
            labelstr   =&gt; "DAILY",
            dumpcycle  =&gt; 35,
            tapecycle  =&gt; 10,
            runtapes   =&gt; 1;
        "archival":
            labelstr   =&gt; "ARCH[2-9]",
            dumpcycle  =&gt; 0,
            tapecycle  =&gt; 1000,
            runtapes   =&gt; 4;
    }

    cron {
        "amdump-daily":
            command =&gt; "/usr/local/sbin/mkdisklist &gt; /etc/amanda/daily/disklist; /usr/sbin/amdump daily; /usr/sbin/amdump holding ; du -shc /opt/amanda/work | tail -1 | mutt -s 'Amanda Disk Usage' 1234567890@vtext.com",
            ensure  =&gt; present,
            user    =&gt; backup,
            hour    =&gt; 0,
            minute  =&gt; 15;
    }

    file {
        "/etc/amanda/holding/disklist":
            source =&gt; "puppet:///files/apps/amanda-server/disklist.holding";
    }

    # Environmental monitoring
    package {
        [ "ipmitool", "openipmi" ]: ensure =&gt; installed;
    }
    file {
        "/etc/modules":
            source =&gt; "puppet:///files/apps/ipmitool/modules";
    }

    mount { "/home":
        atboot  =&gt; true,
        device  =&gt; "/dev/md1000/home",
        ensure  =&gt; mounted,
        fstype  =&gt; "xfs",
        options =&gt; "defaults",
        dump    =&gt; "0",
        pass    =&gt; "1",
        require =&gt; [ Package["xfsdump"], Package["lvm2"] ];
    }

    include active-directory-fileserver
    # - NFS export of /home/CAE
    package {
        [ "nfs-kernel-server" ]: ensure =&gt; installed;
    }

    # - scponly for remote file access (no shell access allowed)
    package {
        [ "scponly" ]:
            ensure =&gt; installed;
    }

}
</pre>
<p>Since the active-directory-fileserver class ties strongly into an active-directory-member class, and that class warrants an entire followup artcle for <a href="http://blogs.cae.tntech.edu/mwr/2007/05/16/authentication-servers/">my authentication notes</a>, <s>I&#8217;ll hold off on that part for now</s> <a href="http://blogs.cae.tntech.edu/mwr/2007/08/02/authentication-servers-the-next-generation/">which can be found here</a>. But the Amanda configuration code, that&#8217;s worth talking about now.</p>
<p>If you&#8217;ve never used <a href="http://www.amanda.org/">Amanda</a>, it&#8217;s arguably the best multi-system, multi-platform Free Software backup solution out there. We&#8217;ve kept it in constant service since late 2002, making this the third major fileserver we&#8217;ve put it on. <a href="http://www.amanda.org/docs/install.html#id325457">It&#8217;s a little fiddly to get installed properly</a>:</p>
<blockquote><p>
Create the config directory (eg. /usr/local/etc/amanda/confname) and copy the example/ files into that directory. Edit these files to be correct for your site, consulting the amanda(8) man page if necessary. You can also send mail to mailto://amanda-users@amanda.org if you are having trouble deciding how to set things up. You will also need to create the directory for the log and database files for the configuration to use (eg /usr/local/var/amanda/confname), and the work directory on the holding disk. These directories need to agree with the parameters in amanda.conf. Don&#8217;t forget to make all these directories writable by the dump user!</p></blockquote>
<p>but worth it. Since I have no less than three different Amanda configurations to set up (one for rotating daily backups, one for monthly archival backups, and one to back up the Amanda holding disk as disaster insurance), I figured it was time to make Puppet create my configuration files in addition to copying them to the file server. It wasn&#8217;t nearly as difficult as I&#8217;d expected, and hopefully this will provide an example that&#8217;s easy enough to follow, complicated enough to be useful, and uses enough of Puppet&#8217;s module capabilities to keep others from hitting the same walls I did. I don&#8217;t claim any of them are perfect, but they&#8217;re currently working and relatively clean.</p>
<p>First, I made a modules directory in the puppet root (/etc/puppet, in my case). Then I added the following entry into puppet&#8217;s fileserver.conf:</p>
<pre>
[modules]
  # path isn't actually used here
  allow A.B.C.0/24
</pre>
<p>where A.B.C.0/24 corresponds to the class C subnet that can access the modules. In the modules folder, I created an amandaconfig folder, which currently has the following contents:</p>
<pre>
/etc/puppet/modules# ls -lR amandaconfig
amandaconfig:
total 12
drwxr-xr-x 3 root root 4096 2007-08-02 15:36 files
drwxr-xr-x 3 root root 4096 2007-08-02 15:36 manifests
drwxr-xr-x 3 root root 4096 2007-08-02 15:36 templates

amandaconfig/files:
total 12
-rw-r----- 1 root root 1827 2007-08-02 09:41 disklist.systems
-rwxr-xr-x 1 root root  416 2007-07-31 14:31 mkdisklist
-rwxr-xr-x 1 root root  390 2007-07-31 14:35 mkdisklist.archival

amandaconfig/manifests:
total 4
-rw-r--r-- 1 root root 2554 2007-08-01 17:21 init.pp

amandaconfig/templates:
total 8
-rw-r--r-- 1 root root 1418 2007-08-02 09:52 amanda.conf.erb
-rw-r--r-- 1 root root   13 2007-07-25 21:05 changer.conf.erb
</pre>
<p>The files directory should contain auxiliary files for the module that don&#8217;t need to be edited on a per-configuration basis. Mine contains a couple of shell scripts to create amanda disklist files by iterating over the file server&#8217;s home directories, and a list of system partitions on other servers and workstations I need to back up daily. The manifests directory contains the Puppet code to create a series of working Amanda configurations, and the templates directory contains files that need to have some search/replace operations done on a per-configuration basis.</p>
<p>I also added an <code>import "amandaconfig"</code> to the top of my site.pp to make sure the new Amanda module was usable.</p>
<p>The contents of manifests/init.pp:</p>
<pre>
# Create a new Amanda configuration set.
class amanda {
    package {
        [ "amanda-server", "amanda-client", "mtx", "dump" ]:
            ensure =&gt; latest;
    }

    file {
        "/opt/amanda":
            ensure =&gt; directory,
            owner  =&gt; root,
            group  =&gt; root,
            mode   =&gt; 0755;

        "/opt/amanda/work":
            ensure =&gt; directory,
            owner  =&gt; backup,
            group  =&gt; backup,
            mode   =&gt; 0700;

        "/usr/local/sbin/mkdisklist":
            source =&gt; "puppet:///amandaconfig/mkdisklist",
            owner  =&gt; root,
            group  =&gt; backup,
            mode   =&gt; 0750;

        "/usr/local/sbin/mkdisklist.archival":
            source =&gt; "puppet:///amandaconfig/mkdisklist.archival",
            owner  =&gt; root,
            group  =&gt; backup,
            mode   =&gt; 0750;

        "/etc/amanda/disklist.systems":
            source =&gt; "puppet:///amandaconfig/disklist.systems",
            owner  =&gt; root,
            group  =&gt; backup,
            mode   =&gt; 0640;
    }

    define amandaconfig (
        $confdir = "/etc/amanda",
        $logdir = "/var/log/amanda",
        $libdir = "/var/lib/amanda",
        $user = "backup",
        $group = "backup",
        $dumpcycle = 1,
        $tapecycle = 2,
        $runtapes = 1,
        $labelstr = "LABEL"
    ) {

        file {
            "$confdir/$name":
                ensure =&gt; directory,
                owner  =&gt; $user,
                group  =&gt; $group,
                mode   =&gt; 0770;

            "$confdir/$name/amanda.conf":
                content =&gt; template("amandaconfig/amanda.conf.erb"),
                ensure  =&gt; present,
                owner   =&gt; $user,
                group   =&gt; $group,
                mode    =&gt; 0755;

            "$confdir/$name/changer.conf":
                content =&gt; template("amandaconfig/changer.conf.erb"),
                ensure  =&gt; present,
                owner   =&gt; $user,
                group   =&gt; $group,
                mode    =&gt; 0755;

            "$confdir/$name/tapelist":
                ensure =&gt; present,
                owner  =&gt; $user,
                group  =&gt; $group,
                mode   =&gt; 0600;

            "$libdir/$name":
                ensure =&gt; directory,
                owner  =&gt; $user,
                group  =&gt; $group,
                mode   =&gt; 0770;

            "$logdir/$name":
                ensure =&gt; directory,
                owner  =&gt; $user,
                group  =&gt; $group,
                mode   =&gt; 0770;

        }
    }
}
</pre>
<p>Everything in the amanda class outside the amandaconfig definition gets evaluated when the node manifest gets to its <code>include amanda</code> line. So the necessary holding disks are created, packages are installed, etc. After that, I can answer the questions for what makes each Amanda configuration unique in the <code>amanda::amandaconfig</code> stanza. For example:
<ul>
<li>the &#8220;holding&#8221; configuration that backs up the holding disk each day alternates between two tapes labeled HOLDING001 and HOLDING002.</li>
<li>the &#8220;daily&#8221; configuration backs up the file server&#8217;s system disks, several other systems&#8217; system disks, and all the users&#8217; and groups&#8217; home directories each day into the holding disk, which we flush off to tape every few days to a series of tapes labeled DAILY001, DAILY002, &#8230;</li>
<li>the &#8220;archival&#8221; configuration backs up the users&#8217; and groups&#8217; home directories into the holding disk, which is immediately backed up to tapes labeled ARCH201, ARCH202, &#8230; ARCH999.</li>
</ul>
<p>As for the templates, they&#8217;re <a href="http://www.ruby-doc.org/stdlib/libdoc/erb/rdoc/classes/ERB.html">ERB</a>-formatted configuration files. amanda.conf is the only interesting one, since changer.conf.erb is actually a static file and should be moved into the files folder with mkdisklist and friends:</p>
<pre>
org "TTU CAE Network"
mailto "root"
dumpuser "&lt;%= user %&gt;"

inparallel 4
netusage 600
reserve 0

dumpcycle &lt;%= dumpcycle %&gt; days
tapecycle &lt;%= tapecycle %&gt; tapes

runtapes &lt;%= runtapes %&gt;
tpchanger "/usr/lib/amanda/chg-zd-mtx"
changerdev "/dev/sg3"
changerfile "changer"
tapedev "/dev/nst0"
tapetype PV-124T_LTO3
labelstr "^&lt;%= labelstr %&gt;[0-9][0-9]*$"

infofile "&lt;%= libdir %&gt;/&lt;%= name %&gt;/curinfo"
logdir "&lt;%= logdir %&gt;/&lt;%= name %&gt;"

indexdir "&lt;%= libdir %&gt;/&lt;%= name %&gt;/index"

holdingdisk opt {
    comment "/opt/amanda/work"
    directory "/opt/amanda/work"
    use -1 gb
}

define tapetype PV-124T_LTO3 {
    comment "Dell PowerVault 124T - LTO3"
    length 402432 mbytes
    filemark 0 kbytes
    speed 71064 kps
}

define dumptype holding-full {
    comment "Full dump of the holding disk always"
    program "GNUTAR"
    compress none
    holdingdisk never
    skip-incr yes
    priority high
    dumpcycle 0
}

define dumptype comp-root {
    comment "Entire partitions backed up with dump"
    compress fast
    index yes
    priority low
}

define dumptype homedir-full {
    comment "User home directories backed up with tar"
    program "GNUTAR"
    compress fast
    index yes
    priority medium
    holdingdisk auto
}

define dumptype homedir-full-archival {
    comment "User home directories backed up with tar"
    program "GNUTAR"
    compress fast
    index yes
    priority medium
    record no
}
</pre>
<p>You can read through the Amanda documentation for what all those settings actually mean. The relevant part is that Puppet will parse through the template looking for variables to replace, and will replace them with either the defaults used in the amandaconfig definition, or with ones passed as arguments to the amandaconfig call.</p>
]]></content:encoded>
			<wfw:commentRss>http://blogs.cae.tntech.edu/mwr/2007/08/02/the-new-file-server-puppet-and-modules/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>The New File Server: Preseeding and LVM</title>
		<link>http://blogs.cae.tntech.edu/mwr/2007/08/02/the-new-file-server-preseeding-and-lvm/</link>
		<comments>http://blogs.cae.tntech.edu/mwr/2007/08/02/the-new-file-server-preseeding-and-lvm/#comments</comments>
		<pubDate>Thu, 02 Aug 2007 20:17:46 +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/08/02/the-new-file-server-preseeding-and-lvm/</guid>
		<description><![CDATA[Remember that no one cares if you can back up &#8212; only if you can restore.
&#8211; Amanda 2.5.2 Documentation
So we&#8217;ve got a new file server in the middle of initial installation and configuration. The file server is one of our most mission-critical systems &#8212; if mail goes down, a half-dozen people care. If the web [...]]]></description>
			<content:encoded><![CDATA[<blockquote><p>Remember that no one cares if you can back up &#8212; only if you can restore.</p>
<div align="right">&#8211; <a href="http://www.amanda.org/docs/using.html#restoring_with_amanda">Amanda 2.5.2 Documentation</a></p></blockquote>
<p>So we&#8217;ve got a new file server in the middle of initial installation and configuration. The file server is one of our most mission-critical systems &#8212; if mail goes down, a half-dozen people care. If the web server goes down, a few more would care, but it&#8217;s not a life-or-death issue. But the file server? That&#8217;s important. Students I&#8217;ve never met, students who wouldn&#8217;t know the difference between a shell prompt and a hole in the ground, students who couldn&#8217;t care less about parallel computing or anything else I put effort into on this area &#8212; they&#8217;ll notice the file server being down.</p>
<p>And all things considered, I like it that way. I know that a student or faculty member is statistically more likely to lose data on their local hard drive, their flash drive, or their removable media of choice than I am to lose it on a RAID-5, hot-spare-ready, redundant power supplies drive array connected to a RAID-1, redundant power supplies server. We&#8217;ve had one data loss experience since 2001 when I started doing this. And we only lost data because of
<ul>
<li>Human error in moving the external RAID in our server rack</li>
<li>Having Amanda holding disk space on the external RAID in addition to what was on the system&#8217;s internal drives</li>
</ul>
<p>and I&#8217;m not too keen to repeat it. I didn&#8217;t get more than 2 hours of sleep at a time for most of a week while I was constantly having to load a different tape in the changer. Thankfully, I didn&#8217;t have to camp out in the server room the whole time, since I could manipulate the changer via ssh. But it was both embarrassing and a major drag away from anything I&#8217;d have rather been doing at the time.</p>
<p>But the new file server is physically ready, and &gt;90% ready as far as configuration and software are concerned. More details on this after the jump.<span id="more-30"></span></p>
<p>As far as the server specifications go, we&#8217;ve got
<ul>
<li>Dell PowerEdge 2950 server with Energy Smart options</li>
<li>1 quad-core Xeon 1.6 GHz CPU</li>
<li>2 GB RAM</li>
<li>8 146 GB SAS drives (2.5 inch, 10K RPM) in a RAID-5 with hotspare</li>
<li>redundant power supplies</li>
<li>4-year warranty</li>
</ul>
<p>For the external disk array, we&#8217;ve got a Dell PowerVault MD1000 with 15 750 GB SATA drives in a RAID-5 with hotspare. The tape changer is a Dell PowerVault 124T LTO-3 with a barcode reader and capacity for eight 400 GB (native capacity) tapes.</p>
<p>My management goal with this system is to never type <code>apt-get install</code>, <code>crontab -e</code>, or <code>xemacs</code> on it. I want preseeding and puppet to handle all package installation, package configuration, and as many other administration duties as possible. That way, in the unlikely event of a physical disaster, I can get services back up and running as quickly as possible, and I can redeploy these services on to a future server if needed.</p>
<p><a href="http://blogs.cae.tntech.edu/mwr/2007/04/17/unattended-debian-installations-or-how-i-learned-to-stop-worrying-and-love-the-preseedcfg/">My original preseed.cfg</a> contains the vast majority of what I needed for this server. The biggest difference is in the partitioning scheme:
<ul>
<li>I want the file server to use LVM in case I need to change how space is divided up</li>
<li>I want separate partitions for /tmp and /var to help prevent users from sucking up all the space in the system areas</li>
<li>I need a separate space for Amanda&#8217;s holding disk, since we don&#8217;t back up a full tape of data each day, and you don&#8217;t want to back up your holding directory into your holding directory each day</li>
</ul>
<p>So my new preseeded partitioning instructions work out as</p>
<pre>
d-i partman-auto/disk string /dev/discs/disc0/disc
d-i partman-auto/method string lvm
d-i partman-auto/purge_lvm_from_device boolean true
d-i partman-lvm/confirm boolean true
d-i partman-auto/init_automatically_partition \\
	select Guided - use entire disk and set up LVM

d-i partman-auto/expert_recipe string                         \\
      boot-root ::                                            \\
              40 300 300 ext3                                 \\
                      $primary{ } $bootable{ }                \\
                      method{ format } format{ }              \\
                      use_filesystem{ } filesystem{ ext3 }    \\
                      mountpoint{ /boot }                     \\
              .                                               \\
              500 10000 1000000000 ext3                       \\
                      method{ format } format{ } $lvmok{ }    \\
                      use_filesystem{ } filesystem{ ext3 }    \\
                      mountpoint{ / }                         \\
              .                                               \\
              600000 600000 600000 ext3                       \\
                      method{ format } format{ } $lvmok{ }    \\
                      use_filesystem{ } filesystem{ ext3 }    \\
                      mountpoint{ /opt/amanda }               \\
              .                                               \\
              500 9000 5000 ext3                              \\
                      method{ format } format{ } $lvmok{ }    \\
                      use_filesystem{ } filesystem{ ext3 }    \\
                      mountpoint{ /var }                      \\
              .                                               \\
              500 9000 5000 ext3                              \\
                      method{ format } format{ } $lvmok{ }    \\
                      use_filesystem{ } filesystem{ ext3 }    \\
                      mountpoint{ /tmp }                      \\
              .                                               \\
              64 512 200% linux-swap $lvmok{ }                \\
                      method{ swap } format{ }                \\
              .

d-i partman/confirm_write_new_label boolean true
d-i partman/choose_partition \\
	select Finish partitioning and write changes to disk
d-i partman/confirm boolean true
</pre>
<p>This ends up giving me a system disk layout as follows:</p>
<pre>
Filesystem            Size  Used Avail Use% Mounted on
/dev/mapper/ch208r-root
                      230G  707M  218G   1% /
/dev/sda1             274M   17M  243M   7% /boot
/dev/mapper/ch208r-opt+amanda
                      564G  422M  535G   1% /opt/amanda
/dev/mapper/ch208r-tmp
                      4.7G  138M  4.4G   4% /tmp
/dev/mapper/ch208r-var
                      4.7G  264M  4.2G   6% /var
</pre>
<p>The next thing I discovered is that fdisk, cfdisk, and anything using DOS-style partition tables has trouble with comically-large volumes like our 9.75 TB (pre-formatting) RAID volume. <a href="http://www.coraid.com/support/linux/contrib/chernow/gpt.html">This document from Coraid</a> gives enough information about using parted and GPT to let us partition the new array. Next, it turns out that the old reliable <a href="http://lwn.net/Articles/187321/">ext3 filesystem has an 8 TB size limit</a> on it, so we went with xfs on the external array.</p>
]]></content:encoded>
			<wfw:commentRss>http://blogs.cae.tntech.edu/mwr/2007/08/02/the-new-file-server-preseeding-and-lvm/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>
