{"id":31,"date":"2007-08-02T16:24:10","date_gmt":"2007-08-02T21:24:10","guid":{"rendered":"http:\/\/blogs.cae.tntech.edu\/mwr\/2007\/08\/02\/the-new-file-server-puppet-and-modules\/"},"modified":"2024-10-27T14:26:19","modified_gmt":"2024-10-27T14:26:19","slug":"the-new-file-server-puppet-and-modules","status":"publish","type":"post","link":"https:\/\/sites.tntech.edu\/renfro\/2007\/08\/02\/the-new-file-server-puppet-and-modules\/","title":{"rendered":"The New File Server: Puppet and Modules"},"content":{"rendered":"<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:<!--more--><\/p>\n<pre>\nnode ch208r {\n    include cae-host\n\n    # ch208r (new file server) needs:\n\n    # Disk tools (XFS support, LVM support, parted)\n    package {\n        [ \"xfsdump\", \"lvm2\", \"parted\" ]: ensure =&gt; installed;\n    }\n    # Backup tools (see amandaconfig module for details)\n    include amanda\n    amanda::amandaconfig {\n        \"holding\":\n            labelstr   =&gt; \"HOLDING\",\n            dumpcycle  =&gt; 1,\n            tapecycle  =&gt; 2,\n            runtapes   =&gt; 1;\n        \"daily\":\n            labelstr   =&gt; \"DAILY\",\n            dumpcycle  =&gt; 35,\n            tapecycle  =&gt; 10,\n            runtapes   =&gt; 1;\n        \"archival\":\n            labelstr   =&gt; \"ARCH[2-9]\",\n            dumpcycle  =&gt; 0,\n            tapecycle  =&gt; 1000,\n            runtapes   =&gt; 4;\n    }\n\n    cron {\n        \"amdump-daily\":\n            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\",\n            ensure  =&gt; present,\n            user    =&gt; backup,\n            hour    =&gt; 0,\n            minute  =&gt; 15;\n    }\n\n    file { \n        \"\/etc\/amanda\/holding\/disklist\": \n            source =&gt; \"puppet:\/\/\/files\/apps\/amanda-server\/disklist.holding\"; \n    }\n\n    # Environmental monitoring\n    package {\n        [ \"ipmitool\", \"openipmi\" ]: ensure =&gt; installed;\n    }\n    file {\n        \"\/etc\/modules\":\n            source =&gt; \"puppet:\/\/\/files\/apps\/ipmitool\/modules\";\n    }\n\n    mount { \"\/home\":\n        atboot  =&gt; true,\n        device  =&gt; \"\/dev\/md1000\/home\",\n        ensure  =&gt; mounted,\n        fstype  =&gt; \"xfs\",\n        options =&gt; \"defaults\",\n        dump    =&gt; \"0\",\n        pass    =&gt; \"1\",\n        require =&gt; [ Package[\"xfsdump\"], Package[\"lvm2\"] ];\n    }\n\n    include active-directory-fileserver\n    # - NFS export of \/home\/CAE\n    package {\n        [ \"nfs-kernel-server\" ]: ensure =&gt; installed;\n    }\n\n    # - scponly for remote file access (no shell access allowed)\n    package {\n        [ \"scponly\" ]:\n            ensure =&gt; installed;\n    }\n\n}\n<\/pre>\n<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>\n<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>\n<blockquote><p>\nCreate 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>\n<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>\n<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>\n<pre>\n[modules]\n  # path isn't actually used here\n  allow A.B.C.0\/24\n<\/pre>\n<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>\n<pre>\n\/etc\/puppet\/modules# ls -lR amandaconfig\namandaconfig:\ntotal 12\ndrwxr-xr-x 3 root root 4096 2007-08-02 15:36 files\ndrwxr-xr-x 3 root root 4096 2007-08-02 15:36 manifests\ndrwxr-xr-x 3 root root 4096 2007-08-02 15:36 templates\n\namandaconfig\/files:\ntotal 12\n-rw-r----- 1 root root 1827 2007-08-02 09:41 disklist.systems\n-rwxr-xr-x 1 root root  416 2007-07-31 14:31 mkdisklist\n-rwxr-xr-x 1 root root  390 2007-07-31 14:35 mkdisklist.archival\n\namandaconfig\/manifests:\ntotal 4\n-rw-r--r-- 1 root root 2554 2007-08-01 17:21 init.pp\n\namandaconfig\/templates:\ntotal 8\n-rw-r--r-- 1 root root 1418 2007-08-02 09:52 amanda.conf.erb\n-rw-r--r-- 1 root root   13 2007-07-25 21:05 changer.conf.erb\n<\/pre>\n<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>\n<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>\n<p>The contents of manifests\/init.pp:<\/p>\n<pre>\n# Create a new Amanda configuration set.\nclass amanda {\n    package {\n        [ \"amanda-server\", \"amanda-client\", \"mtx\", \"dump\" ]:\n            ensure =&gt; latest;\n    }\n\n    file {\n        \"\/opt\/amanda\":\n            ensure =&gt; directory,\n            owner  =&gt; root,\n            group  =&gt; root,\n            mode   =&gt; 0755;\n\n        \"\/opt\/amanda\/work\":\n            ensure =&gt; directory,\n            owner  =&gt; backup,\n            group  =&gt; backup,\n            mode   =&gt; 0700;\n\n        \"\/usr\/local\/sbin\/mkdisklist\":\n            source =&gt; \"puppet:\/\/\/amandaconfig\/mkdisklist\",\n            owner  =&gt; root,\n            group  =&gt; backup,\n            mode   =&gt; 0750;\n\n        \"\/usr\/local\/sbin\/mkdisklist.archival\":\n            source =&gt; \"puppet:\/\/\/amandaconfig\/mkdisklist.archival\",\n            owner  =&gt; root,\n            group  =&gt; backup,\n            mode   =&gt; 0750;\n\n        \"\/etc\/amanda\/disklist.systems\":\n            source =&gt; \"puppet:\/\/\/amandaconfig\/disklist.systems\",\n            owner  =&gt; root,\n            group  =&gt; backup,\n            mode   =&gt; 0640;\n    }\n\n    define amandaconfig (\n        $confdir = \"\/etc\/amanda\",\n        $logdir = \"\/var\/log\/amanda\",\n        $libdir = \"\/var\/lib\/amanda\",\n        $user = \"backup\",\n        $group = \"backup\",\n        $dumpcycle = 1,\n        $tapecycle = 2,\n        $runtapes = 1,\n        $labelstr = \"LABEL\"\n    ) {\n\n        file {\n            \"$confdir\/$name\":\n                ensure =&gt; directory,\n                owner  =&gt; $user,\n                group  =&gt; $group,\n                mode   =&gt; 0770;\n\n            \"$confdir\/$name\/amanda.conf\":\n                content =&gt; template(\"amandaconfig\/amanda.conf.erb\"),\n                ensure  =&gt; present,\n                owner   =&gt; $user,\n                group   =&gt; $group,\n                mode    =&gt; 0755;\n\n            \"$confdir\/$name\/changer.conf\":\n                content =&gt; template(\"amandaconfig\/changer.conf.erb\"),\n                ensure  =&gt; present,\n                owner   =&gt; $user,\n                group   =&gt; $group,\n                mode    =&gt; 0755;\n\n            \"$confdir\/$name\/tapelist\":\n                ensure =&gt; present,\n                owner  =&gt; $user,\n                group  =&gt; $group,\n                mode   =&gt; 0600;\n\n            \"$libdir\/$name\":\n                ensure =&gt; directory,\n                owner  =&gt; $user,\n                group  =&gt; $group,\n                mode   =&gt; 0770;\n\n            \"$logdir\/$name\":\n                ensure =&gt; directory,\n                owner  =&gt; $user,\n                group  =&gt; $group,\n                mode   =&gt; 0770;\n\n        }\n    }\n}\n<\/pre>\n<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:<\/p>\n<ul>\n<li>the &#8220;holding&#8221; configuration that backs up the holding disk each day alternates between two tapes labeled HOLDING001 and HOLDING002.<\/li>\n<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>\n<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>\n<\/ul>\n<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>\n<pre>\norg \"TTU CAE Network\"\nmailto \"root\"\ndumpuser \"&lt;%= user %&gt;\"\n\ninparallel 4\nnetusage 600\nreserve 0\n\ndumpcycle &lt;%= dumpcycle %&gt; days\ntapecycle &lt;%= tapecycle %&gt; tapes\n\nruntapes &lt;%= runtapes %&gt;\ntpchanger \"\/usr\/lib\/amanda\/chg-zd-mtx\"\nchangerdev \"\/dev\/sg3\"\nchangerfile \"changer\"\ntapedev \"\/dev\/nst0\"\ntapetype PV-124T_LTO3\nlabelstr \"^&lt;%= labelstr %&gt;[0-9][0-9]*$\"\n\ninfofile \"&lt;%= libdir %&gt;\/&lt;%= name %&gt;\/curinfo\"\nlogdir \"&lt;%= logdir %&gt;\/&lt;%= name %&gt;\"\n\nindexdir \"&lt;%= libdir %&gt;\/&lt;%= name %&gt;\/index\"\n\nholdingdisk opt {\n    comment \"\/opt\/amanda\/work\"\n    directory \"\/opt\/amanda\/work\"\n    use -1 gb\n}\n\ndefine tapetype PV-124T_LTO3 {\n    comment \"Dell PowerVault 124T - LTO3\"\n    length 402432 mbytes\n    filemark 0 kbytes\n    speed 71064 kps\n}\n\ndefine dumptype holding-full {\n    comment \"Full dump of the holding disk always\"\n    program \"GNUTAR\"\n    compress none\n    holdingdisk never\n    skip-incr yes\n    priority high\n    dumpcycle 0\n}\n\ndefine dumptype comp-root {\n    comment \"Entire partitions backed up with dump\"\n    compress fast\n    index yes\n    priority low\n}\n\ndefine dumptype homedir-full {\n    comment \"User home directories backed up with tar\"\n    program \"GNUTAR\"\n    compress fast\n    index yes\n    priority medium\n    holdingdisk auto\n}\n\ndefine dumptype homedir-full-archival {\n    comment \"User home directories backed up with tar\"\n    program \"GNUTAR\"\n    compress fast\n    index yes\n    priority medium\n    record no\n}\n<\/pre>\n<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>\n","protected":false},"excerpt":{"rendered":"<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 &hellip; <\/p>\n<p class=\"link-more\"><a href=\"https:\/\/sites.tntech.edu\/renfro\/2007\/08\/02\/the-new-file-server-puppet-and-modules\/\" class=\"more-link\">Continue reading<span class=\"screen-reader-text\"> &#8220;The New File Server: Puppet and Modules&#8221;<\/span><\/a><\/p>\n","protected":false},"author":87,"featured_media":0,"comment_status":"closed","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[4,7,16],"tags":[],"class_list":["post-31","post","type-post","status-publish","format-standard","hentry","category-debian","category-infrastructures","category-puppet","entry"],"_links":{"self":[{"href":"https:\/\/sites.tntech.edu\/renfro\/wp-json\/wp\/v2\/posts\/31","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/sites.tntech.edu\/renfro\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/sites.tntech.edu\/renfro\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/sites.tntech.edu\/renfro\/wp-json\/wp\/v2\/users\/87"}],"replies":[{"embeddable":true,"href":"https:\/\/sites.tntech.edu\/renfro\/wp-json\/wp\/v2\/comments?post=31"}],"version-history":[{"count":1,"href":"https:\/\/sites.tntech.edu\/renfro\/wp-json\/wp\/v2\/posts\/31\/revisions"}],"predecessor-version":[{"id":493,"href":"https:\/\/sites.tntech.edu\/renfro\/wp-json\/wp\/v2\/posts\/31\/revisions\/493"}],"wp:attachment":[{"href":"https:\/\/sites.tntech.edu\/renfro\/wp-json\/wp\/v2\/media?parent=31"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/sites.tntech.edu\/renfro\/wp-json\/wp\/v2\/categories?post=31"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/sites.tntech.edu\/renfro\/wp-json\/wp\/v2\/tags?post=31"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}