<?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>My Wushu Blog &#187; Backups</title>
	<atom:link href="http://www.mywushublog.com/tag/backups/feed/" rel="self" type="application/rss+xml" />
	<link>http://www.mywushublog.com</link>
	<description></description>
	<lastBuildDate>Tue, 31 Jan 2012 18:42:14 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.2.1</generator>
		<item>
		<title>Bacula in the Enterprise &#8211; Part 2</title>
		<link>http://www.mywushublog.com/2011/07/bacula-in-the-enterprise-part-2/</link>
		<comments>http://www.mywushublog.com/2011/07/bacula-in-the-enterprise-part-2/#comments</comments>
		<pubDate>Sat, 23 Jul 2011 19:10:26 +0000</pubDate>
		<dc:creator>Mike Carlson</dc:creator>
				<category><![CDATA[Featured]]></category>
		<category><![CDATA[Geekyness]]></category>
		<category><![CDATA[Backups]]></category>
		<category><![CDATA[Bacula]]></category>
		<category><![CDATA[FreeBSD]]></category>
		<category><![CDATA[Jenny]]></category>
		<category><![CDATA[ZFS]]></category>

		<guid isPermaLink="false">http://www.mywushublog.com/?p=1524</guid>
		<description><![CDATA[Software As mentioned many times, this is a FreeBSD based environment. Some good sysinfo output below: Operating system release: FreeBSD 8.2-RELEASE OS architecture: amd64 Kernel build dir location: /usr/obj/usr/src/sys/GENERIC Currently booted kernel: /boot/kernel/kernel Currently loaded kernel modules (kldstat(8)): zfs.ko opensolaris.ko Bootloader settings for the Director/Database node: The /boot/loader.conf has the ...]]></description>
			<content:encoded><![CDATA[<h1>Software</h1>
<p>As mentioned many times, this is a FreeBSD based environment. Some good sysinfo output below:</p>
<pre>
Operating system release: FreeBSD 8.2-RELEASE
OS architecture: amd64
Kernel build dir location: /usr/obj/usr/src/sys/GENERIC
Currently booted kernel: /boot/kernel/kernel

Currently loaded kernel modules (kldstat(8)):
zfs.ko
opensolaris.ko
</pre>
<p>Bootloader settings for the Director/Database node:</p>
<pre>
The /boot/loader.conf has the following contents:
kern.ipc.semmni=1024
kern.ipc.semmns=2048
kern.ipc.semmnu=1024
</pre>
<p>All of the storage nodes and the director are running a GENERIC kernel with very few system tweaking. One of the storage nodes has a Chelsio 10Gb controller, but that hasn&#8217;t had a high enough load to crack the 1Gb/sec barrier.</p>
<p>I&#8217;m using Bacula from the ports tree, and the directory has a special Make flag to build with gcc&#8217;s debugging symbols. Jenny worked on getting that setup when we were having some stability issues.</p>
<p>The Bacula configuration one the director node is backed by a git repository. It adds a little bit of complexity for a systems administrator, when they want to add a client, but the benefit is clear. This backup project actually enforces change control and tracks all of the commits by who.</p>
<p>I&#8217;ve also setup Redmine as a project front-end, and I&#8217;ve begun to file tickets and reference what commit fixed what. This not only tracks my progress, but it is the first time I&#8217;ve had a backup server that was clearly documented and had some type of accountability.<br />
<div id="attachment_1525" class="wp-caption aligncenter" style="width: 643px"><a href="http://www.mywushublog.com/wp-content/uploads/2011/07/redmine.png"><img src="http://www.mywushublog.com/wp-content/uploads/2011/07/redmine.png" alt="" title="redmine" width="633" height="412" class="size-full wp-image-1525" /></a><p class="wp-caption-text">A snippet of the Redmine site</p></div></p>
<h1>The Structure</h1>
<p>I&#8217;ve compared projects like bacula to a large box of LegosTM. It doesn&#8217;t enforce a structure by any means, and I&#8217;ve taken it upon myself to add meaning to the otherwise flat and incomprehensible bacula-dir.conf</p>
<p>The Bacula Port on FreeBSD installs all configuration files in <strong>/usr/local/etc</strong>.</p>
<p>Write, the Director, only contains the following in /usr/local/etc/bacula-dir.conf:</p>
<pre>
@/usr/local/etc/bacula/bacula-dir.conf
@/usr/local/etc/bacula/storage.conf
@/usr/local/etc/bacula/clients.conf
@/usr/local/etc/bacula/messages.conf
@/usr/local/etc/bacula/schedules.conf
@/usr/local/etc/bacula/pools.conf
</pre>
<p>As you can see, I place everything in etc/bacula/.</p>
<p>Here is a beautiful output of tree(1):</p>
<pre>
bacula
|-- bacula-dir.conf
|-- bin
|   |-- create_client.sh
|   `-- package_list.sh
|-- clients.conf
|-- clients.d
|   |-- 10am
|   |-- 10pm
|   |-- 11pm
|   |-- 12am
|   |-- 1am
|   |-- 2am
|   |-- 3am
|   |-- 4am
|   |-- 4pm
|   |-- 5am
|   |-- 5pm
|   |-- 6am
|   |-- 6pm
|   |-- 7am
|   |-- 7pm
|   |-- 8am
|   |-- 8pm
|   |-- 9am
|   |-- 9pm
|   |-- TEMPLATE-mac
|   |-- TEMPLATE-unix
|   `-- TEMPLATE-win32
|-- excludes.d
|   |-- common.conf
|   |-- mac.conf
|   |-- unix.conf
|   `-- win32.conf
|-- messages.conf
|-- pools.conf
|-- schedules.conf
|-- storage.conf
`-- storage.d
    |-- write-01.conf
    |-- write-02.conf
    |-- write-03.conf
    |-- write-04.conf
    |-- write-05.conf
    `-- write-06.conf
</pre>
<h1>Storage Nodes</h1>
<p>All of the storage nodes are using <strong>ZFS</strong> as the filesystem/Volume manager.</p>
<pre>
write-06# zpool list
NAME         SIZE   USED  AVAIL    CAP  HEALTH  ALTROOT
filevol001  90.6T  33.3T  57.3T    36%  ONLINE  -
</pre>
<p>They all have one volume, <strong>/filevol001</strong>, and I created 512 &#8220;drives&#8221; within that volume. Effectivly, each storage node has 512 drives, and clients are randomly assigned a drive.</p>
<p>Since I have 6 storage nodes, I wrote a little shell script to handle the directory creation:</p>

<div class="wp_syntax"><div class="code"><pre class="bash" style="font-family:monospace;"><span style="color: #666666; font-style: italic;">#!/bin/bash</span>
<span style="color: #007800;">i</span>=<span style="color: #000000;">1</span>
&nbsp;
<span style="color: #000000; font-weight: bold;">while</span> <span style="color: #7a0874; font-weight: bold;">&#91;</span> <span style="color: #007800;">$i</span> <span style="color: #660033;">-le</span> <span style="color: #000000;">512</span> <span style="color: #7a0874; font-weight: bold;">&#93;</span>
<span style="color: #000000; font-weight: bold;">do</span>
        <span style="color: #c20cb9; font-weight: bold;">install</span> <span style="color: #660033;">-d</span> <span style="color: #660033;">-o</span> bacula <span style="color: #660033;">-g</span> bacula <span style="color: #660033;">-m</span> <span style="color: #000000;">770</span> <span style="color: #000000; font-weight: bold;">/</span>filevol001<span style="color: #000000; font-weight: bold;">/</span>drive<span style="color: #007800;">$i</span>
        <span style="color: #7a0874; font-weight: bold;">&#40;</span><span style="color: #7a0874; font-weight: bold;">&#40;</span>i++<span style="color: #7a0874; font-weight: bold;">&#41;</span><span style="color: #7a0874; font-weight: bold;">&#41;</span>
<span style="color: #000000; font-weight: bold;">done</span></pre></div></div>

<p>Simple, right? I also wrote a script to generate the bacula-sd.conf file on a storage node as well:</p>

<div class="wp_syntax"><div class="code"><pre class="bash" style="font-family:monospace;"><span style="color: #666666; font-style: italic;">#!/bin/bash</span>
&nbsp;
usage<span style="color: #7a0874; font-weight: bold;">&#40;</span><span style="color: #7a0874; font-weight: bold;">&#41;</span>
<span style="color: #7a0874; font-weight: bold;">&#123;</span>
<span style="color: #c20cb9; font-weight: bold;">cat</span> <span style="color: #cc0000; font-style: italic;">&lt;&lt; EOF
    Usage $0 NUMBER &gt; /usr/local/etc/bacula-sd.conf
&nbsp;
    Where &quot;NUMBER&quot; is just a single digit indicating which storage node this is.
&nbsp;
    Example, for write-07:
    $ make_sd.sh 7 &gt; /usr/local/etc/bacula-sd.conf
EOF</span>
<span style="color: #7a0874; font-weight: bold;">&#125;</span>
&nbsp;
<span style="color: #007800;">i</span>=<span style="color: #000000;">1</span>
&nbsp;
<span style="color: #000000; font-weight: bold;">if</span> <span style="color: #7a0874; font-weight: bold;">&#91;</span><span style="color: #7a0874; font-weight: bold;">&#91;</span> <span style="color: #660033;">-z</span> <span style="color: #007800;">$1</span> <span style="color: #7a0874; font-weight: bold;">&#93;</span><span style="color: #7a0874; font-weight: bold;">&#93;</span>
<span style="color: #000000; font-weight: bold;">then</span>
    usage
    <span style="color: #7a0874; font-weight: bold;">exit</span>
<span style="color: #000000; font-weight: bold;">fi</span>
&nbsp;
<span style="color: #7a0874; font-weight: bold;">printf</span> <span style="color: #ff0000;">&quot;Storage {<span style="color: #000099; font-weight: bold;">\n</span>&quot;</span>
<span style="color: #7a0874; font-weight: bold;">printf</span> <span style="color: #ff0000;">&quot;<span style="color: #000099; font-weight: bold;">\t</span>Name = write-0$1.llnl.gov-sd<span style="color: #000099; font-weight: bold;">\n</span>&quot;</span>
<span style="color: #7a0874; font-weight: bold;">printf</span> <span style="color: #ff0000;">&quot;<span style="color: #000099; font-weight: bold;">\t</span>SDAddress = write-0$1.llnl.gov<span style="color: #000099; font-weight: bold;">\n</span>&quot;</span>
<span style="color: #7a0874; font-weight: bold;">printf</span> <span style="color: #ff0000;">&quot;<span style="color: #000099; font-weight: bold;">\t</span>SDPort = 9103<span style="color: #000099; font-weight: bold;">\n</span>&quot;</span>
<span style="color: #7a0874; font-weight: bold;">printf</span> <span style="color: #ff0000;">&quot;<span style="color: #000099; font-weight: bold;">\t</span>WorkingDirectory = <span style="color: #000099; font-weight: bold;">\&quot;</span>/var/db/bacula<span style="color: #000099; font-weight: bold;">\&quot;</span><span style="color: #000099; font-weight: bold;">\n</span>&quot;</span>
<span style="color: #7a0874; font-weight: bold;">printf</span> <span style="color: #ff0000;">&quot;<span style="color: #000099; font-weight: bold;">\t</span>Pid Directory = <span style="color: #000099; font-weight: bold;">\&quot;</span>/var/run<span style="color: #000099; font-weight: bold;">\&quot;</span><span style="color: #000099; font-weight: bold;">\n</span>&quot;</span>
<span style="color: #7a0874; font-weight: bold;">printf</span> <span style="color: #ff0000;">&quot;<span style="color: #000099; font-weight: bold;">\t</span>Maximum Concurrent Jobs = 516<span style="color: #000099; font-weight: bold;">\n</span>&quot;</span>
<span style="color: #7a0874; font-weight: bold;">printf</span> <span style="color: #ff0000;">&quot;}<span style="color: #000099; font-weight: bold;">\n</span>&quot;</span>
&nbsp;
<span style="color: #7a0874; font-weight: bold;">printf</span> <span style="color: #ff0000;">&quot;#<span style="color: #000099; font-weight: bold;">\n</span>&quot;</span>
<span style="color: #7a0874; font-weight: bold;">printf</span> <span style="color: #ff0000;">&quot;# List Directors who are permitted to contact Storage daemon<span style="color: #000099; font-weight: bold;">\n</span>&quot;</span>
<span style="color: #7a0874; font-weight: bold;">printf</span> <span style="color: #ff0000;">&quot;#<span style="color: #000099; font-weight: bold;">\n</span>&quot;</span>
<span style="color: #7a0874; font-weight: bold;">printf</span> <span style="color: #ff0000;">&quot;Director {<span style="color: #000099; font-weight: bold;">\n</span>&quot;</span>
<span style="color: #7a0874; font-weight: bold;">printf</span> <span style="color: #ff0000;">&quot;<span style="color: #000099; font-weight: bold;">\t</span>Name = write.llnl.gov-dir<span style="color: #000099; font-weight: bold;">\n</span>&quot;</span>
<span style="color: #7a0874; font-weight: bold;">printf</span> <span style="color: #ff0000;">&quot;<span style="color: #000099; font-weight: bold;">\t</span>Password = <span style="color: #000099; font-weight: bold;">\&quot;</span>ItsASecret<span style="color: #000099; font-weight: bold;">\&quot;</span><span style="color: #000099; font-weight: bold;">\n</span>&quot;</span>
<span style="color: #7a0874; font-weight: bold;">printf</span> <span style="color: #ff0000;">&quot;}<span style="color: #000099; font-weight: bold;">\n</span>&quot;</span>
&nbsp;
<span style="color: #7a0874; font-weight: bold;">printf</span> <span style="color: #ff0000;">&quot;#<span style="color: #000099; font-weight: bold;">\n</span>&quot;</span>
<span style="color: #7a0874; font-weight: bold;">printf</span> <span style="color: #ff0000;">&quot;# Restricted Director, used by tray-monitor to get the<span style="color: #000099; font-weight: bold;">\n</span>&quot;</span>
<span style="color: #7a0874; font-weight: bold;">printf</span> <span style="color: #ff0000;">&quot;#   status of the storage daemon<span style="color: #000099; font-weight: bold;">\n</span>&quot;</span>
<span style="color: #7a0874; font-weight: bold;">printf</span> <span style="color: #ff0000;">&quot;#<span style="color: #000099; font-weight: bold;">\n</span>&quot;</span>
<span style="color: #7a0874; font-weight: bold;">printf</span> <span style="color: #ff0000;">&quot;Director {<span style="color: #000099; font-weight: bold;">\n</span>&quot;</span>
<span style="color: #7a0874; font-weight: bold;">printf</span> <span style="color: #ff0000;">&quot;<span style="color: #000099; font-weight: bold;">\t</span>Name = write.llnl.gov-mon<span style="color: #000099; font-weight: bold;">\n</span>&quot;</span>
<span style="color: #7a0874; font-weight: bold;">printf</span> <span style="color: #ff0000;">&quot;<span style="color: #000099; font-weight: bold;">\t</span>Password = <span style="color: #000099; font-weight: bold;">\&quot;</span>ItsANotherSecret<span style="color: #000099; font-weight: bold;">\&quot;</span><span style="color: #000099; font-weight: bold;">\n</span>&quot;</span>
<span style="color: #7a0874; font-weight: bold;">printf</span> <span style="color: #ff0000;">&quot;<span style="color: #000099; font-weight: bold;">\t</span>Monitor = yes<span style="color: #000099; font-weight: bold;">\n</span>&quot;</span>
<span style="color: #7a0874; font-weight: bold;">printf</span> <span style="color: #ff0000;">&quot;}<span style="color: #000099; font-weight: bold;">\n</span>&quot;</span>
&nbsp;
<span style="color: #7a0874; font-weight: bold;">printf</span> <span style="color: #ff0000;">&quot;Messages {<span style="color: #000099; font-weight: bold;">\n</span>&quot;</span>
<span style="color: #7a0874; font-weight: bold;">printf</span> <span style="color: #ff0000;">&quot;<span style="color: #000099; font-weight: bold;">\t</span>Name = Standard<span style="color: #000099; font-weight: bold;">\n</span>&quot;</span>
<span style="color: #7a0874; font-weight: bold;">printf</span> <span style="color: #ff0000;">&quot;<span style="color: #000099; font-weight: bold;">\t</span>director = write.llnl.gov-dir = all<span style="color: #000099; font-weight: bold;">\n</span>&quot;</span>
<span style="color: #7a0874; font-weight: bold;">printf</span> <span style="color: #ff0000;">&quot;}<span style="color: #000099; font-weight: bold;">\n</span>&quot;</span>
&nbsp;
&nbsp;
<span style="color: #7a0874; font-weight: bold;">printf</span> <span style="color: #ff0000;">&quot;Device {<span style="color: #000099; font-weight: bold;">\n</span>&quot;</span>
<span style="color: #7a0874; font-weight: bold;">printf</span> <span style="color: #ff0000;">&quot;<span style="color: #000099; font-weight: bold;">\t</span>Name = W0$1FileStorage<span style="color: #000099; font-weight: bold;">\n</span>&quot;</span>
<span style="color: #7a0874; font-weight: bold;">printf</span> <span style="color: #ff0000;">&quot;<span style="color: #000099; font-weight: bold;">\t</span>Media Type = File<span style="color: #000099; font-weight: bold;">\n</span>&quot;</span>
<span style="color: #7a0874; font-weight: bold;">printf</span> <span style="color: #ff0000;">&quot;<span style="color: #000099; font-weight: bold;">\t</span>Archive Device = /filevol001<span style="color: #000099; font-weight: bold;">\n</span>&quot;</span>
<span style="color: #7a0874; font-weight: bold;">printf</span> <span style="color: #ff0000;">&quot;<span style="color: #000099; font-weight: bold;">\t</span>LabelMedia = yes;<span style="color: #000099; font-weight: bold;">\n</span>&quot;</span>
<span style="color: #7a0874; font-weight: bold;">printf</span> <span style="color: #ff0000;">&quot;<span style="color: #000099; font-weight: bold;">\t</span>Random Access = Yes;<span style="color: #000099; font-weight: bold;">\n</span>&quot;</span>
<span style="color: #7a0874; font-weight: bold;">printf</span> <span style="color: #ff0000;">&quot;<span style="color: #000099; font-weight: bold;">\t</span>AutomaticMount = yes;<span style="color: #000099; font-weight: bold;">\n</span>&quot;</span>
<span style="color: #7a0874; font-weight: bold;">printf</span> <span style="color: #ff0000;">&quot;<span style="color: #000099; font-weight: bold;">\t</span>RemovableMedia = no;<span style="color: #000099; font-weight: bold;">\n</span>&quot;</span>
<span style="color: #7a0874; font-weight: bold;">printf</span> <span style="color: #ff0000;">&quot;<span style="color: #000099; font-weight: bold;">\t</span>AlwaysOpen = no;<span style="color: #000099; font-weight: bold;">\n</span>&quot;</span>
<span style="color: #7a0874; font-weight: bold;">printf</span> <span style="color: #ff0000;">&quot;<span style="color: #000099; font-weight: bold;">\t</span>Maximum Concurrent Jobs = 2<span style="color: #000099; font-weight: bold;">\n</span>&quot;</span>
<span style="color: #7a0874; font-weight: bold;">printf</span> <span style="color: #ff0000;">&quot;}<span style="color: #000099; font-weight: bold;">\n</span>&quot;</span>
&nbsp;
<span style="color: #000000; font-weight: bold;">while</span> <span style="color: #7a0874; font-weight: bold;">&#91;</span> <span style="color: #007800;">$i</span> <span style="color: #660033;">-le</span> <span style="color: #000000;">512</span> <span style="color: #7a0874; font-weight: bold;">&#93;</span>
<span style="color: #000000; font-weight: bold;">do</span>
        <span style="color: #7a0874; font-weight: bold;">printf</span> <span style="color: #ff0000;">&quot;<span style="color: #000099; font-weight: bold;">\n</span>&quot;</span>
        <span style="color: #7a0874; font-weight: bold;">printf</span> <span style="color: #ff0000;">&quot;Device {<span style="color: #000099; font-weight: bold;">\n</span>&quot;</span>
        <span style="color: #7a0874; font-weight: bold;">printf</span> <span style="color: #ff0000;">&quot;<span style="color: #000099; font-weight: bold;">\t</span>Name = W0$1FileStorageD<span style="color: #007800;">$i</span><span style="color: #000099; font-weight: bold;">\n</span>&quot;</span>
        <span style="color: #7a0874; font-weight: bold;">printf</span> <span style="color: #ff0000;">&quot;<span style="color: #000099; font-weight: bold;">\t</span>Media Type = File<span style="color: #000099; font-weight: bold;">\n</span>&quot;</span>
        <span style="color: #7a0874; font-weight: bold;">printf</span> <span style="color: #ff0000;">&quot;<span style="color: #000099; font-weight: bold;">\t</span>Archive Device = /filevol001/drive<span style="color: #007800;">$i</span><span style="color: #000099; font-weight: bold;">\n</span>&quot;</span>
        <span style="color: #7a0874; font-weight: bold;">printf</span> <span style="color: #ff0000;">&quot;<span style="color: #000099; font-weight: bold;">\t</span>LabelMedia = yes;<span style="color: #000099; font-weight: bold;">\n</span>&quot;</span>
        <span style="color: #7a0874; font-weight: bold;">printf</span> <span style="color: #ff0000;">&quot;<span style="color: #000099; font-weight: bold;">\t</span>Random Access = Yes;<span style="color: #000099; font-weight: bold;">\n</span>&quot;</span>
        <span style="color: #7a0874; font-weight: bold;">printf</span> <span style="color: #ff0000;">&quot;<span style="color: #000099; font-weight: bold;">\t</span>AutomaticMount = yes;<span style="color: #000099; font-weight: bold;">\n</span>&quot;</span>
        <span style="color: #7a0874; font-weight: bold;">printf</span> <span style="color: #ff0000;">&quot;<span style="color: #000099; font-weight: bold;">\t</span>RemovableMedia = no;<span style="color: #000099; font-weight: bold;">\n</span>&quot;</span>
        <span style="color: #7a0874; font-weight: bold;">printf</span> <span style="color: #ff0000;">&quot;<span style="color: #000099; font-weight: bold;">\t</span>AlwaysOpen = no;<span style="color: #000099; font-weight: bold;">\n</span>&quot;</span>
        <span style="color: #7a0874; font-weight: bold;">printf</span> <span style="color: #ff0000;">&quot;<span style="color: #000099; font-weight: bold;">\t</span>Maximum Concurrent Jobs = 2<span style="color: #000099; font-weight: bold;">\n</span>&quot;</span>
        <span style="color: #7a0874; font-weight: bold;">printf</span> <span style="color: #ff0000;">&quot;}<span style="color: #000099; font-weight: bold;">\n</span>&quot;</span>
        <span style="color: #7a0874; font-weight: bold;">&#40;</span><span style="color: #7a0874; font-weight: bold;">&#40;</span>i++<span style="color: #7a0874; font-weight: bold;">&#41;</span><span style="color: #7a0874; font-weight: bold;">&#41;</span>
<span style="color: #000000; font-weight: bold;">done</span></pre></div></div>

<p>On the Directory, a storage node definition is saved in /usr/local/etc/bacula/storage.d/write-0{N}.conf, which is included in /usr/local/etc/bacula/storage.conf:</p>
<pre>
@/usr/local/etc/bacula/storage.d/write-01.conf
@/usr/local/etc/bacula/storage.d/write-02.conf
@/usr/local/etc/bacula/storage.d/write-03.conf
@/usr/local/etc/bacula/storage.d/write-04.conf
@/usr/local/etc/bacula/storage.d/write-05.conf
@/usr/local/etc/bacula/storage.d/write-06.conf
</pre>
<h1>Client Generation</h1>
<p>There are two components, the TEMPLATE file (there are three, TEMPLATE-unix, TEMPLATE-win32 and TEMPATE-mac) and the shell script.</p>
<h2>The Client TEMPLATE File</h2>
<p>Here is what one of the TEMPLATE files looks like:</p>
<pre>
#
# Client Definition, the Password here must match
#  the clients bacula-fd.conf Client definition.
#
# Using Vi/m, you can easily replaced HOSTNAME with
#  the short hostname of the client with:
#  %s/HOSTNAME/yourhostname/
#
#

Client {
    Name = HOSTNAME.llnl.gov
    Address = HOSTNAME.llnl.gov
    FDPort = 9102
    Catalog = Catalog001
    Password = "ItsASecret"
    File Retention = 40 days
    Job Retention = 1 months
    AutoPrune = yes
    Maximum Concurrent Jobs = 10
    Heartbeat Interval = 300
}

Console {
    Name = HOSTNAME.llnl.gov-acl
    Password = ItsASecret
    JobACL = "HOSTNAME.llnl.gov RestoreFiles", "HOSTNAME.llnl.gov"
    ScheduleACL = *all*
    ClientACL = HOSTNAME.llnl.gov
    FileSetACL = "HOSTNAME.llnl.gov FileSet"
    CatalogACL = Catalog001
    CommandACL = *all*
    StorageACL = *all*
    PoolACL = HOSTNAME.llnl.gov-File
}

Job {
    Name = "HOSTNAME.llnl.gov"
    Type = Backup
    Level = Incremental
    FileSet = "HOSTNAME.llnl.gov FileSet"
    Client = "HOSTNAME.llnl.gov"
    Storage = FileStorageD##
    Pool = HOSTNAME.llnl.gov-File
    Schedule = "@@"
    Messages = Standard
    Priority = 10
    Write Bootstrap = "/var/db/bacula/%c.bsr"
    Maximum Concurrent Jobs = 10
    Reschedule On Error = yes
    Reschedule Interval = 1 hour
    Reschedule Times = 1
    Max Wait Time = 30 minutes
    Cancel Lower Level Duplicates = yes
    Allow Duplicate Jobs = no
    RunScript {
        RunsWhen = Before
        FailJobOnError = no
        Command = "/etc/scripts/package_list.sh"
        RunsOnClient = yes
    }
}

Pool {
    Name = HOSTNAME.llnl.gov-File
    Pool Type = Backup
    Recycle = yes
    AutoPrune = yes
    Volume Retention = 1 months
    Maximum Volume Bytes = 10G
    Maximum Volumes = 100
    LabelFormat = "HOSTNAME.llnl.govFileVol"
    Maximum Volume Jobs = 5
}

Job {
    Name = "HOSTNAME.llnl.gov RestoreFiles"
    Type = Restore
    Client= HOSTNAME.llnl.gov
    FileSet="HOSTNAME.llnl.gov FileSet"
    Storage = FileStorageD##
    Pool = HOSTNAME.llnl.gov-File
    Messages = Standard
    #Where = /tmp/bacula-restores
}

FileSet {
    Name = "HOSTNAME.llnl.gov FileSet"
    Include {
        Options {
            signature = MD5
            compression = GZIP6
                        fstype = ext2
                        fstype = xfs
                        fstype = jfs
                        fstype = ufs
                        fstype = zfs
                        onefs = no
                        Exclude = yes
                        @/usr/local/etc/bacula/excludes.d/common.conf
        }
                File = /
                File = /usr/local
                Exclude Dir Containing = .excludeme
    }
    Exclude {
        @/usr/local/etc/bacula/excludes.d/unix.conf
    }
}
</pre>
<h2>The Create Client Script</h2>
<p>So here is what really makes creating clients easy for us, the create_client script.</p>
<p>I didn&#8217;t want to do it this way, really, so part of me is very ashamed of this tool. I would have preferred to re-write this in Python, or make a web page out of it, and let admins create clients from their desktop. Or, I would have loved to create a puppet module to handle this automagically (but that would exlcude everything that *isn&#8217;t* running Puppet, which is huge).</p>
<p>With that disclaimer, here is my create_client shell script:</p>

<div class="wp_syntax"><div class="code"><pre class="bash" style="font-family:monospace;"><span style="color: #666666; font-style: italic;">#!/usr/bin/env bash</span>
<span style="color: #666666; font-style: italic;"># usage: cclient -t unix -s 12am -h hostname</span>
<span style="color: #666666; font-style: italic;">#</span>
&nbsp;
<span style="color: #7a0874; font-weight: bold;">umask</span> 022
&nbsp;
<span style="color: #666666; font-style: italic;"># Variables</span>
<span style="color: #666666; font-style: italic;">## Randomize Schedule</span>
<span style="color: #007800;">SCHEDULES</span>=<span style="color: #ff0000;">&quot;4pm 5pm 6pm 7pm 8pm 9pm 10pm 11pm 12am 1am 2am 3am 4am 5am 6am 7am 8am 9am 10am&quot;</span>
<span style="color: #007800;">s</span>=<span style="color: #7a0874; font-weight: bold;">&#40;</span><span style="color: #007800;">$SCHEDULES</span><span style="color: #7a0874; font-weight: bold;">&#41;</span>
<span style="color: #007800;">num_s</span>=<span style="color: #800000;">${#s[*]}</span>
<span style="color: #007800;">RAND_SCHED</span>=<span style="color: #800000;">${s[$((RANDOM%num_s))]}</span>
<span style="color: #666666; font-style: italic;"># Randomize which storage node we use</span>
<span style="color: #007800;">NODES</span>=<span style="color: #ff0000;">&quot;write-06 write-01 write-06 write-01 write-02 write-03 write-04 write-05&quot;</span>
<span style="color: #007800;">n</span>=<span style="color: #7a0874; font-weight: bold;">&#40;</span><span style="color: #007800;">$NODES</span><span style="color: #7a0874; font-weight: bold;">&#41;</span>
<span style="color: #007800;">num_n</span>=<span style="color: #800000;">${#n[*]}</span>
<span style="color: #007800;">RAND_NODE</span>=<span style="color: #800000;">${n[$((RANDOM%num_n))]}</span>
&nbsp;
<span style="color: #7a0874; font-weight: bold;">export</span> <span style="color: #007800;">DRIVE</span>=<span style="color: #000000; font-weight: bold;">`</span>jot <span style="color: #660033;">-r</span> <span style="color: #000000;">1</span> <span style="color: #000000;">1</span> <span style="color: #000000;">512</span><span style="color: #000000; font-weight: bold;">`</span>
<span style="color: #7a0874; font-weight: bold;">export</span> <span style="color: #007800;">BDIR</span>=<span style="color: #ff0000;">&quot;/usr/local/etc/bacula&quot;</span>
<span style="color: #7a0874; font-weight: bold;">export</span> <span style="color: #007800;">TYPE</span>=<span style="color: #ff0000;">&quot;unix&quot;</span>
<span style="color: #7a0874; font-weight: bold;">export</span> <span style="color: #007800;">SCHEDULE</span>=<span style="color: #007800;">$RAND_SCHED</span>
<span style="color: #7a0874; font-weight: bold;">export</span> <span style="color: #007800;">HOSTNAME</span>=<span style="color: #ff0000;">&quot;&quot;</span>
<span style="color: #7a0874; font-weight: bold;">export</span> <span style="color: #007800;">STORAGE_NODE</span>=<span style="color: #007800;">$RAND_NODE</span>
<span style="color: #7a0874; font-weight: bold;">export</span> <span style="color: #007800;">GIT_DIR</span>=<span style="color: #ff0000;">&quot;/usr/local/etc/bacula/.git&quot;</span>
<span style="color: #7a0874; font-weight: bold;">export</span> <span style="color: #007800;">CLASS</span>=<span style="color: #ff0000;">&quot;desktop&quot;</span>
&nbsp;
<span style="color: #000000; font-weight: bold;">if</span> <span style="color: #7a0874; font-weight: bold;">&#91;</span> $<span style="color: #7a0874; font-weight: bold;">&#40;</span><span style="color: #c20cb9; font-weight: bold;">whoami</span><span style="color: #7a0874; font-weight: bold;">&#41;</span> == <span style="color: #ff0000;">&quot;root&quot;</span> <span style="color: #7a0874; font-weight: bold;">&#93;</span>
<span style="color: #000000; font-weight: bold;">then</span>
<span style="color: #c20cb9; font-weight: bold;">cat</span> <span style="color: #cc0000; font-style: italic;">&lt;&lt; EOF
                Please do not run this as root. This script runs a
                git add/commit, which is how changes are managed and
                tracked. If you run this as root, then it shows up
                as carlson39 or root.
&nbsp;
                If you encounter a problem with your normal OUN account,
                please contact Mike Carlson, or submit a bug here:
                https://st-scm.llnl.gov/redmine/snt/projects/bacula/issues/new
EOF</span>
&nbsp;
<span style="color: #7a0874; font-weight: bold;">exit</span> <span style="color: #000000;">1</span>
<span style="color: #000000; font-weight: bold;">fi</span>
&nbsp;
usage<span style="color: #7a0874; font-weight: bold;">&#40;</span><span style="color: #7a0874; font-weight: bold;">&#41;</span>
<span style="color: #7a0874; font-weight: bold;">&#123;</span>
<span style="color: #c20cb9; font-weight: bold;">cat</span> <span style="color: #cc0000; font-style: italic;">&lt;&lt; EOF
&nbsp;
        Usage: $0 [OPTION]... -h HOSTNAME
&nbsp;
        This script will generate a bacula client definition.
&nbsp;
        OPTIONS:
        -s      schedule, (4pm|5pm|6pm|7pm|8pm|9pm|10pm|11pm|12am|1am|2am|3am|4am|5am|6am|7am|8am|9am). The default schedule is random.
        -t      type, (unix|win32|mac), unix is the default
        -n      storage node (write-01|write-02|...), the default is random.
        -h      hostname (use the short hostname)
EOF</span>
<span style="color: #7a0874; font-weight: bold;">&#125;</span>
&nbsp;
<span style="color: #7a0874; font-weight: bold;">cd</span> <span style="color: #007800;">$BDIR</span>
&nbsp;
<span style="color: #000000; font-weight: bold;">while</span> <span style="color: #7a0874; font-weight: bold;">getopts</span> <span style="color: #ff0000;">'c:t:s:n:h:'</span> OPTION
<span style="color: #000000; font-weight: bold;">do</span>
        <span style="color: #000000; font-weight: bold;">case</span> <span style="color: #007800;">$OPTION</span> <span style="color: #000000; font-weight: bold;">in</span>
                c<span style="color: #7a0874; font-weight: bold;">&#41;</span>
                        <span style="color: #007800;">CLASS</span>=<span style="color: #007800;">$OPTARG</span>
                        <span style="color: #000000; font-weight: bold;">;;</span>
                t<span style="color: #7a0874; font-weight: bold;">&#41;</span>
                        <span style="color: #007800;">TYPE</span>=<span style="color: #007800;">$OPTARG</span>
                        <span style="color: #000000; font-weight: bold;">;;</span>
                s<span style="color: #7a0874; font-weight: bold;">&#41;</span>
                        <span style="color: #007800;">SCHEDULE</span>=<span style="color: #007800;">$OPTARG</span>
                        <span style="color: #000000; font-weight: bold;">;;</span>
                h<span style="color: #7a0874; font-weight: bold;">&#41;</span>
                        <span style="color: #007800;">HOSTNAME</span>=<span style="color: #007800;">$OPTARG</span>
                        <span style="color: #7a0874; font-weight: bold;">echo</span> <span style="color: #007800;">$HOSTNAME</span> <span style="color: #000000; font-weight: bold;">|</span> <span style="color: #c20cb9; font-weight: bold;">egrep</span> <span style="color: #660033;">-q</span> <span style="color: #ff0000;">&quot;(llnl.gov|ucllnl.org)&quot;</span>
                        <span style="color: #000000; font-weight: bold;">if</span> <span style="color: #7a0874; font-weight: bold;">&#91;</span> <span style="color: #007800;">$?</span> <span style="color: #660033;">-eq</span> <span style="color: #000000;">0</span> <span style="color: #7a0874; font-weight: bold;">&#93;</span>
                        <span style="color: #000000; font-weight: bold;">then</span>
                        <span style="color: #007800;">HOSTNAME</span>=<span style="color: #000000; font-weight: bold;">`</span><span style="color: #7a0874; font-weight: bold;">echo</span> <span style="color: #007800;">$HOSTNAME</span><span style="color: #000000; font-weight: bold;">|</span><span style="color: #c20cb9; font-weight: bold;">sed</span> <span style="color: #660033;">-e</span> <span style="color: #ff0000;">'s/.llnl.gov//'</span> <span style="color: #660033;">-e</span> <span style="color: #ff0000;">'s/.ucllnl.org//'</span><span style="color: #000000; font-weight: bold;">`</span>
                        <span style="color: #000000; font-weight: bold;">fi</span>
&nbsp;
                        <span style="color: #000000; font-weight: bold;">;;</span>
                n<span style="color: #7a0874; font-weight: bold;">&#41;</span>
                        <span style="color: #007800;">STORAGE_NODE</span>=<span style="color: #007800;">$OPTARG</span>
                        <span style="color: #000000; font-weight: bold;">;;</span>
                ?<span style="color: #7a0874; font-weight: bold;">&#41;</span>
                        usage
                        <span style="color: #7a0874; font-weight: bold;">exit</span>
                        <span style="color: #000000; font-weight: bold;">;;</span>
        <span style="color: #000000; font-weight: bold;">esac</span>
<span style="color: #000000; font-weight: bold;">done</span>
&nbsp;
<span style="color: #000000; font-weight: bold;">if</span> <span style="color: #7a0874; font-weight: bold;">&#91;</span><span style="color: #7a0874; font-weight: bold;">&#91;</span> <span style="color: #660033;">-z</span> <span style="color: #007800;">$CLASS</span> <span style="color: #7a0874; font-weight: bold;">&#93;</span><span style="color: #7a0874; font-weight: bold;">&#93;</span> <span style="color: #000000; font-weight: bold;">||</span> <span style="color: #7a0874; font-weight: bold;">&#91;</span><span style="color: #7a0874; font-weight: bold;">&#91;</span> <span style="color: #660033;">-z</span> <span style="color: #007800;">$TYPE</span> <span style="color: #7a0874; font-weight: bold;">&#93;</span><span style="color: #7a0874; font-weight: bold;">&#93;</span> <span style="color: #000000; font-weight: bold;">||</span> <span style="color: #7a0874; font-weight: bold;">&#91;</span><span style="color: #7a0874; font-weight: bold;">&#91;</span> <span style="color: #660033;">-z</span> <span style="color: #007800;">$SCHEDULE</span> <span style="color: #7a0874; font-weight: bold;">&#93;</span><span style="color: #7a0874; font-weight: bold;">&#93;</span> <span style="color: #000000; font-weight: bold;">||</span> <span style="color: #7a0874; font-weight: bold;">&#91;</span><span style="color: #7a0874; font-weight: bold;">&#91;</span> <span style="color: #660033;">-z</span> <span style="color: #007800;">$HOSTNAME</span> <span style="color: #7a0874; font-weight: bold;">&#93;</span><span style="color: #7a0874; font-weight: bold;">&#93;</span> <span style="color: #000000; font-weight: bold;">||</span> <span style="color: #7a0874; font-weight: bold;">&#91;</span><span style="color: #7a0874; font-weight: bold;">&#91;</span> <span style="color: #660033;">-z</span> <span style="color: #007800;">$STORAGE_NODE</span> <span style="color: #7a0874; font-weight: bold;">&#93;</span><span style="color: #7a0874; font-weight: bold;">&#93;</span>
<span style="color: #000000; font-weight: bold;">then</span>
        usage
        <span style="color: #7a0874; font-weight: bold;">exit</span> <span style="color: #000000;">1</span>
<span style="color: #000000; font-weight: bold;">fi</span>
&nbsp;
<span style="color: #c20cb9; font-weight: bold;">grep</span> <span style="color: #660033;">-w</span> <span style="color: #007800;">$HOSTNAME</span> <span style="color: #007800;">$BDIR</span><span style="color: #000000; font-weight: bold;">/</span>clients.conf
<span style="color: #000000; font-weight: bold;">if</span> <span style="color: #7a0874; font-weight: bold;">&#91;</span> <span style="color: #007800;">$?</span> <span style="color: #660033;">-eq</span> <span style="color: #000000;">0</span> <span style="color: #7a0874; font-weight: bold;">&#93;</span>
<span style="color: #000000; font-weight: bold;">then</span>
        <span style="color: #7a0874; font-weight: bold;">echo</span> <span style="color: #ff0000;">'client '</span><span style="color: #007800;">$HOSTNAME</span> <span style="color: #ff0000;">'already exists...'</span>
<span style="color: #000000; font-weight: bold;">else</span>
        <span style="color: #7a0874; font-weight: bold;">export</span> <span style="color: #007800;">RETRY_COUNT</span>=<span style="color: #ff0000;">&quot;2&quot;</span>
&nbsp;
        <span style="color: #000000; font-weight: bold;">if</span> <span style="color: #7a0874; font-weight: bold;">&#91;</span> <span style="color: #007800;">$STORAGE_NODE</span> == <span style="color: #ff0000;">&quot;write-01&quot;</span> <span style="color: #7a0874; font-weight: bold;">&#93;</span>
        <span style="color: #000000; font-weight: bold;">then</span>
                <span style="color: #007800;">DRIVE</span>=<span style="color: #000000; font-weight: bold;">`</span>jot <span style="color: #660033;">-r</span> <span style="color: #000000;">1</span> <span style="color: #000000;">33</span> <span style="color: #000000;">512</span><span style="color: #000000; font-weight: bold;">`</span>
                <span style="color: #c20cb9; font-weight: bold;">sed</span> <span style="color: #660033;">-e</span> <span style="color: #ff0000;">'s/HOSTNAME/'</span><span style="color: #007800;">$HOSTNAME</span><span style="color: #ff0000;">'/g'</span> <span style="color: #660033;">-e</span> <span style="color: #ff0000;">'s/FileStorageD##/FileStorageD'</span><span style="color: #007800;">$DRIVE</span><span style="color: #ff0000;">'/'</span> <span style="color: #660033;">-e</span> <span style="color: #ff0000;">'s/\@\@/'</span><span style="color: #007800;">$SCHEDULE</span><span style="color: #ff0000;">'/'</span> <span style="color: #660033;">-e</span> <span style="color: #ff0000;">'s/RETRY_COUNT/'</span><span style="color: #007800;">$RETRY_COUNT</span><span style="color: #ff0000;">'/g'</span> <span style="color: #007800;">$BDIR</span><span style="color: #000000; font-weight: bold;">/</span>clients.d<span style="color: #000000; font-weight: bold;">/</span>TEMPLATE-<span style="color: #007800;">$TYPE</span> <span style="color: #000000; font-weight: bold;">&gt;</span> <span style="color: #007800;">$BDIR</span><span style="color: #000000; font-weight: bold;">/</span>clients.d<span style="color: #000000; font-weight: bold;">/</span><span style="color: #007800;">$SCHEDULE</span><span style="color: #000000; font-weight: bold;">/</span><span style="color: #007800;">$HOSTNAME</span>.conf
                <span style="color: #7a0874; font-weight: bold;">echo</span> \<span style="color: #000000; font-weight: bold;">@</span><span style="color: #007800;">$BDIR</span><span style="color: #000000; font-weight: bold;">/</span>clients.d<span style="color: #000000; font-weight: bold;">/</span><span style="color: #007800;">$SCHEDULE</span><span style="color: #000000; font-weight: bold;">/</span><span style="color: #007800;">$HOSTNAME</span>.conf <span style="color: #000000; font-weight: bold;">&gt;&gt;</span> <span style="color: #007800;">$BDIR</span><span style="color: #000000; font-weight: bold;">/</span>clients.conf
        <span style="color: #000000; font-weight: bold;">else</span>
                <span style="color: #7a0874; font-weight: bold;">export</span> <span style="color: #007800;">SN</span>=<span style="color: #000000; font-weight: bold;">`</span><span style="color: #7a0874; font-weight: bold;">echo</span> <span style="color: #007800;">$STORAGE_NODE</span> <span style="color: #000000; font-weight: bold;">|</span> <span style="color: #c20cb9; font-weight: bold;">cut</span> <span style="color: #660033;">-c</span> <span style="color: #000000;">7</span>-<span style="color: #000000;">8</span><span style="color: #000000; font-weight: bold;">`</span>
                <span style="color: #c20cb9; font-weight: bold;">sed</span> <span style="color: #660033;">-e</span> <span style="color: #ff0000;">'s/HOSTNAME/'</span><span style="color: #007800;">$HOSTNAME</span><span style="color: #ff0000;">'/g'</span> <span style="color: #660033;">-e</span> <span style="color: #ff0000;">'s/FileStorageD##/W'</span><span style="color: #007800;">$SN</span><span style="color: #ff0000;">'FileStorageD'</span><span style="color: #007800;">$DRIVE</span><span style="color: #ff0000;">'/'</span> <span style="color: #660033;">-e</span> <span style="color: #ff0000;">'s/\@\@/'</span><span style="color: #007800;">$SCHEDULE</span><span style="color: #ff0000;">'/'</span> <span style="color: #660033;">-e</span> <span style="color: #ff0000;">'s/RETRY_COUNT/'</span><span style="color: #007800;">$RETRY_COUNT</span><span style="color: #ff0000;">'/g'</span> <span style="color: #007800;">$BDIR</span><span style="color: #000000; font-weight: bold;">/</span>clients.d<span style="color: #000000; font-weight: bold;">/</span>TEMPLATE-<span style="color: #007800;">$TYPE</span> <span style="color: #000000; font-weight: bold;">&gt;</span> <span style="color: #007800;">$BDIR</span><span style="color: #000000; font-weight: bold;">/</span>clients.d<span style="color: #000000; font-weight: bold;">/</span><span style="color: #007800;">$SCHEDULE</span><span style="color: #000000; font-weight: bold;">/</span><span style="color: #007800;">$HOSTNAME</span>.conf
                <span style="color: #7a0874; font-weight: bold;">echo</span> \<span style="color: #000000; font-weight: bold;">@</span><span style="color: #007800;">$BDIR</span><span style="color: #000000; font-weight: bold;">/</span>clients.d<span style="color: #000000; font-weight: bold;">/</span><span style="color: #007800;">$SCHEDULE</span><span style="color: #000000; font-weight: bold;">/</span><span style="color: #007800;">$HOSTNAME</span>.conf <span style="color: #000000; font-weight: bold;">&gt;&gt;</span> <span style="color: #007800;">$BDIR</span><span style="color: #000000; font-weight: bold;">/</span>clients.conf
        <span style="color: #000000; font-weight: bold;">fi</span>
&nbsp;
        <span style="color: #c20cb9; font-weight: bold;">chgrp</span> st-bacula-admins <span style="color: #007800;">$BDIR</span><span style="color: #000000; font-weight: bold;">/</span>clients.d<span style="color: #000000; font-weight: bold;">/</span><span style="color: #007800;">$SCHEDULE</span><span style="color: #000000; font-weight: bold;">/</span><span style="color: #007800;">$HOSTNAME</span>.conf
        <span style="color: #c20cb9; font-weight: bold;">git</span> add <span style="color: #007800;">$BDIR</span><span style="color: #000000; font-weight: bold;">/</span>clients.d<span style="color: #000000; font-weight: bold;">/</span><span style="color: #007800;">$SCHEDULE</span><span style="color: #000000; font-weight: bold;">/</span><span style="color: #007800;">$HOSTNAME</span>.conf <span style="color: #007800;">$BDIR</span><span style="color: #000000; font-weight: bold;">/</span>clients.conf
        <span style="color: #c20cb9; font-weight: bold;">git</span> commit
        <span style="color: #7a0874; font-weight: bold;">echo</span> <span style="color: #ff0000;">'created client definition: '</span><span style="color: #007800;">$BDIR</span><span style="color: #000000; font-weight: bold;">/</span>clients.d<span style="color: #000000; font-weight: bold;">/</span><span style="color: #007800;">$SCHEDULE</span><span style="color: #000000; font-weight: bold;">/</span><span style="color: #007800;">$HOSTNAME</span>.conf
        <span style="color: #7a0874; font-weight: bold;">echo</span> <span style="color: #ff0000;">'for '</span><span style="color: #007800;">$HOSTNAME</span><span style="color: #ff0000;">'.llnl.gov'</span>
<span style="color: #000000; font-weight: bold;">fi</span></pre></div></div>

<p>This is always a work in progress, but at the core, it is a simple sed wrapper with a lot of randomization and a git commit.</p>
<p>Why all the randomization?</p>
<p>Because I had to add around 1000 clients in a VERY short amount of time. We didn&#8217;t have a problem pushing the Bacula client to all of the platforms, nor the bacula-fd.conf file either. What I could not do was spend the time to create and manage all of the resources for each client. That is why I have so many devices/drives, so I can attempt to have a 1:1 without having to actually think about it.</p>
<p>So, I wrote ANOTHER script to wrap around this one when I need to do bulk client creations. I&#8217;m not going to post that, it just loops through the above command.</p>
<h2>Pre-Job command &#8211; Package List</h2>
<p>I only do this on the Unix/Linux clients, and I thought it was a cool idea. </p>
<p>Yeah, I will pat myself on the back a little bit for that :)</p>
<p>I exclude the Operating System from backups for two reasons, 1) to reduce backing up duplicate and reproducible data and 2) Our build/Imaging process is so quick and clean it is just faster to rebuild than restore everything.</p>
<p>Still, I needed a way to keep the state of installed packages/software.</p>
<p>This is where the pre-job command comes in handy. This part right here:</p>
<pre>
    RunScript {
        RunsWhen = Before
        FailJobOnError = no
        Command = "/etc/scripts/package_list.sh"
        RunsOnClient = yes
    }
</pre>
<p>That package_list.sh file looks like this:</p>

<div class="wp_syntax"><div class="code"><pre class="bash" style="font-family:monospace;">&nbsp;
<span style="color: #666666; font-style: italic;">#!/usr/bin/env bash</span>
&nbsp;
<span style="color: #7a0874; font-weight: bold;">export</span> <span style="color: #007800;">PLIST</span>=<span style="color: #ff0000;">&quot;/root/plist.txt&quot;</span>
&nbsp;
<span style="color: #000000; font-weight: bold;">case</span> <span style="color: #ff0000;">&quot;<span style="color: #780078;">`uname -s`</span>&quot;</span> <span style="color: #000000; font-weight: bold;">in</span>
Linux<span style="color: #7a0874; font-weight: bold;">&#41;</span>
                <span style="color: #000000; font-weight: bold;">if</span> <span style="color: #7a0874; font-weight: bold;">&#91;</span> <span style="color: #660033;">-x</span> <span style="color: #000000; font-weight: bold;">/</span>usr<span style="color: #000000; font-weight: bold;">/</span>bin<span style="color: #000000; font-weight: bold;">/</span>lsb_release <span style="color: #7a0874; font-weight: bold;">&#93;</span>; <span style="color: #000000; font-weight: bold;">then</span>
                        <span style="color: #007800;">DIST</span>=<span style="color: #000000; font-weight: bold;">`</span>lsb_release -d<span style="color: #000000; font-weight: bold;">`</span>
                <span style="color: #000000; font-weight: bold;">fi</span>
&nbsp;
                <span style="color: #666666; font-style: italic;"># RHEL</span>
                <span style="color: #000000; font-weight: bold;">if</span> <span style="color: #7a0874; font-weight: bold;">&#91;</span> <span style="color: #660033;">-x</span> <span style="color: #000000; font-weight: bold;">/</span>usr<span style="color: #000000; font-weight: bold;">/</span>bin<span style="color: #000000; font-weight: bold;">/</span>up2date <span style="color: #7a0874; font-weight: bold;">&#93;</span>; <span style="color: #000000; font-weight: bold;">then</span>
                        rpm <span style="color: #660033;">-qa</span> <span style="color: #000000; font-weight: bold;">&gt;</span> <span style="color: #007800;">$PLIST</span>
                <span style="color: #000000; font-weight: bold;">fi</span>
&nbsp;
                <span style="color: #666666; font-style: italic;"># RHEL 5</span>
                <span style="color: #000000; font-weight: bold;">if</span> <span style="color: #7a0874; font-weight: bold;">&#91;</span> <span style="color: #660033;">-x</span> <span style="color: #000000; font-weight: bold;">/</span>usr<span style="color: #000000; font-weight: bold;">/</span>bin<span style="color: #000000; font-weight: bold;">/</span>yum <span style="color: #7a0874; font-weight: bold;">&#93;</span>; <span style="color: #000000; font-weight: bold;">then</span>
                        <span style="color: #000000; font-weight: bold;">if</span> <span style="color: #7a0874; font-weight: bold;">&#91;</span> <span style="color: #660033;">-f</span> <span style="color: #000000; font-weight: bold;">/</span>var<span style="color: #000000; font-weight: bold;">/</span>run<span style="color: #000000; font-weight: bold;">/</span>yum.pid <span style="color: #7a0874; font-weight: bold;">&#93;</span>; <span style="color: #000000; font-weight: bold;">then</span>
                                <span style="color: #7a0874; font-weight: bold;">echo</span> <span style="color: #ff0000;">&quot;Yum currently in use, exiting gracefully...&quot;</span>
                                <span style="color: #7a0874; font-weight: bold;">exit</span> <span style="color: #000000;">0</span>
                        <span style="color: #000000; font-weight: bold;">else</span>
                        <span style="color: #000000; font-weight: bold;">/</span>usr<span style="color: #000000; font-weight: bold;">/</span>bin<span style="color: #000000; font-weight: bold;">/</span>yum list installed <span style="color: #000000; font-weight: bold;">|</span> <span style="color: #c20cb9; font-weight: bold;">awk</span> <span style="color: #ff0000;">'{print $1}'</span> <span style="color: #000000; font-weight: bold;">&gt;</span> <span style="color: #007800;">$PLIST</span>
                        <span style="color: #000000; font-weight: bold;">fi</span>
                <span style="color: #000000; font-weight: bold;">fi</span>
&nbsp;
                <span style="color: #666666; font-style: italic;"># Ubuntu</span>
                <span style="color: #000000; font-weight: bold;">if</span> <span style="color: #7a0874; font-weight: bold;">&#91;</span> <span style="color: #660033;">-x</span> <span style="color: #000000; font-weight: bold;">/</span>usr<span style="color: #000000; font-weight: bold;">/</span>bin<span style="color: #000000; font-weight: bold;">/</span><span style="color: #c20cb9; font-weight: bold;">dpkg</span> <span style="color: #7a0874; font-weight: bold;">&#93;</span>; <span style="color: #000000; font-weight: bold;">then</span>
                        <span style="color: #000000; font-weight: bold;">/</span>usr<span style="color: #000000; font-weight: bold;">/</span>bin<span style="color: #000000; font-weight: bold;">/</span><span style="color: #c20cb9; font-weight: bold;">dpkg</span> <span style="color: #660033;">--get-selections</span> <span style="color: #000000; font-weight: bold;">|</span> <span style="color: #c20cb9; font-weight: bold;">awk</span> <span style="color: #ff0000;">'{print $1}'</span> <span style="color: #000000; font-weight: bold;">&gt;</span> <span style="color: #007800;">$PLIST</span>
                <span style="color: #000000; font-weight: bold;">fi</span>
                <span style="color: #000000; font-weight: bold;">;;</span>
&nbsp;
FreeBSD<span style="color: #7a0874; font-weight: bold;">&#41;</span>
                pkg_info<span style="color: #000000; font-weight: bold;">|</span><span style="color: #c20cb9; font-weight: bold;">awk</span> <span style="color: #ff0000;">'{print $1}'</span> <span style="color: #000000; font-weight: bold;">&gt;</span> <span style="color: #007800;">$PLIST</span>
                <span style="color: #000000; font-weight: bold;">;;</span>
SunOS<span style="color: #7a0874; font-weight: bold;">&#41;</span>
                pkginfo <span style="color: #000000; font-weight: bold;">|</span><span style="color: #c20cb9; font-weight: bold;">awk</span> <span style="color: #ff0000;">'{print $1}'</span> <span style="color: #000000; font-weight: bold;">&gt;</span> <span style="color: #007800;">$PLIST</span>
                <span style="color: #000000; font-weight: bold;">;;</span>
<span style="color: #000000; font-weight: bold;">esac</span></pre></div></div>

<p>That file, /root/plist.txt, gets backed up.</p>
<p>Now we have a record of what was installed on our Unix platforms :)</p>
<p>That is it for now, see you at <a href="/#">Part 3</a></p>
]]></content:encoded>
			<wfw:commentRss>http://www.mywushublog.com/2011/07/bacula-in-the-enterprise-part-2/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Bacula in the Enterprise &#8211; Part 1</title>
		<link>http://www.mywushublog.com/2011/07/bacula-in-the-enterprise-part-1/</link>
		<comments>http://www.mywushublog.com/2011/07/bacula-in-the-enterprise-part-1/#comments</comments>
		<pubDate>Sat, 23 Jul 2011 00:45:21 +0000</pubDate>
		<dc:creator>Mike Carlson</dc:creator>
				<category><![CDATA[Featured]]></category>
		<category><![CDATA[Geekyness]]></category>
		<category><![CDATA[Backups]]></category>
		<category><![CDATA[Bacula]]></category>
		<category><![CDATA[FreeBSD]]></category>
		<category><![CDATA[ZFS]]></category>

		<guid isPermaLink="false">http://www.mywushublog.com/?p=1513</guid>
		<description><![CDATA[I&#8217;ve been using Bacula, the open source backup software, for over a year now. Things have been going well, and I would like to dedicate a post or two to the environment I built. Background Over a year ago, I took it upon myself to replace a single Legato Networker ...]]></description>
			<content:encoded><![CDATA[<p>I&#8217;ve been using Bacula, the open source backup software, for over a year now. Things have been going well, and I would like to dedicate a post or two to the environment I built.</p>
<h2>Background</h2>
<p>Over a year ago, I took it upon myself to replace a single Legato Networker server with Bacula. One of our collaborators had decided to ship us (for no reason at all really, I think they were cleaning out their data center) a Sun X4200 AMD server, and two StorageTek/Sun NAS servers.</p>
<p>I had no reason for the NAS heads, but the JBOD was full of drives and the Sun X4200 was useful enough. So, I gutted them (Since the StoragTek NAS heads were identical in almost every way to a standard X4200), put as much memory and CPU&#8217;s as I could in one system. This was my first Bacula server. It had around 2TB of FC storage and it made a nice replacement backup server for the 50 or so clients that were on the Networker server. The OS was not Solaris, as you might guess since I was using Sun hardware, but FreeBSD.</p>
<p>Since was focusing only on disk based backups, and FreeBSD has two fantastic large file systems (UFS2 and ZFS), this was my underlying storage platform. Combine that with the current choice of software (in the case, Bacula 5.0.x and PostgreSQL 8/9) from the Ports tree, it really makes the perfect open source software and hardware stack.</p>
<p>After spending a good amount of time wrapping my head around Bacula, and really, just carelessly diving into it, I was very happy with how fast and stable it was shaping up to be.</p>
<p>Around the same time, I was asked to pick up the project that literally went no where for years: The dreaded Backup Project for all of the S&amp;T directorate. A mix of all OS&#8217;s, desktops, servers, laptops, etc&#8230; and around 3000 active machines online with lots of important data.</p>
<p>No small feat, and there are many reasons why this had been a difficult project to wrangle. One thing for sure, is we knew we had a lot of unique programmatic data.</p>
<p>I knew what software I wanted to use, and I was pretty set on using commodity hardware and reasonably priced storage. The next part was to define some constants in the environment.</p>
<h2>The Initial Concepts</h2>
<p>First up, I knew of the largest painful aspects of our computing environment:</p>
<ol>
<li>Budget constraints &#8211; We are not rich, and IT always seems to be underfunded. This project had to be as frugal as possible, yet still deliver.</li>
<li>Diverse platforms &#8211; We have Windows, OS X and a mix of RHEL and Ubuntu for desktops. Server platforms range all across the board: Windows, OSX, RHEL, Solaris, FreeBSD, AIX, etc&#8230;</li>
<li>Mission critical data &#8211; Lets face it, the Lab doesn&#8217;t make a car, or a VCR. We have a LOT of critical scientific knowledge that is only stored in bits and bytes. That is our product, scientific data that is truly unique.</li>
<li>A campus like geography &#8211;  the Lab is 1 sq. mile with a mixture of trailers, new buildings, and some buildings that are over 50 years old. The network backbone ranges from 10Gbps to 10Mbps. The poses a problem when it comes to backups.</li>
</ol>
<div>With this in mind, theses are some of the initial concepts I latched onto:</div>
<div>
<ul>
<li>A distributed <strong>disk</strong> based storage backend for Bacula</li>
<li>Smaller retention window &#8211; 1 month</li>
<li>Reduce the amount of data that has to even go over the network</li>
<ul style="padding-left: 30px;">
<li>Skip &#8220;reproducible data&#8221; such has installed programs like Office, and exclude the OS itself</li>
<li>Enable client side compression. The effectively distributes the compression for all clients. Saves a lot of disk space :)</li>
</ul>
<li>Skip virtual machine images, like vmdk and vmem files, and treat important virtual machines as separate clients.</li>
</ul>
<div>For Bacula itself, I had decided that each client would have its own resources. Very little is shared between each client, so for example client-001 would get all of these resources:</div>
<ul>
<li>Pool = &#8220;Client-001-File&#8221;</li>
<ul style="padding-left: 30px;">
<li>Storage = a randomly assigned drive on one of the storage nodes</li>
<li>Maximum Volume bytes = 10Gb</li>
<li>Maximum Volumes = 100</li>
<li>AutoPrune and Recycling enabled</li>
</ul>
<li>Job = &#8220;client-001&#8243; (one for backup and one for restore)</li>
<li>FileSet = &#8220;client-001 FileSet&#8221;</li>
</ul>
<p>What this prevents is cross-client data contamination. What is also prevented, and I found out later, was concurrent backups. More on that later though.</p>
<p>After feeling a bit more comfortable with a simple all-in-one server, I was ready to spec out new hardware. This was good, because at the same time it was our end of year budget crunch, and hardware had to be procured.</p>
<h2>The Hardware</h2>
<p>For storage, I had a few concepts I was floating around.</p>
<p>One, was to use MooseFS, a distributed filesystem , across a bunch of cheap node with a modest amount of storage.</p>
<p>The other, idea was to buy a handful of servers with a lot of internal storage, around 18TB or so. Them distribute them across the &#8220;campus&#8221; as a kind of Bacula storage node cloud.</p>
<p>The last idea was to take a more traditional backup server approach, and buy a server with as much expandable storage as possible and back everything up to that.</p>
<p>In the end, when a bunch of hardware showed up (I had *some* control over the hardware, but not all aspects since some of the managers took it upon themselves to purchase everything), I scrapped the MooseFS idea after talking it over with Jenny, and we took the last two: 4 HP servers with 17TB or RAID6 internal storage, and a large 140TB SAN array (Winchester Systems, great stuff!) as the primary backup node:</p>
<p><div id="attachment_1522" class="wp-caption aligncenter" style="width: 310px"><a href="http://www.mywushublog.com/wp-content/uploads/2011/07/Overview.jpg"><img src="http://www.mywushublog.com/wp-content/uploads/2011/07/Overview-300x292.jpg" alt="" title="Overview" width="300" height="292" class="size-medium wp-image-1522" /></a><p class="wp-caption-text">Our Environment</p></div><br />
This model served us well for a while. We had a primary storage node that backed up a users primary desktop, and the smaller storage nodes were used to back up servers and infrastructure data.</p>
<p>There was room for improvement right away though. As soon as it was in production, I quickly mapped out what I felt were the next steps in making a robust backup environment.</p>
<p>More on that in another installment :)</p>
<p><a href="/2011/07/bacula-in-the-enterprise-part-2/">Continue to Part 2&#8230;</a></p>
]]></content:encoded>
			<wfw:commentRss>http://www.mywushublog.com/2011/07/bacula-in-the-enterprise-part-1/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Using Duplicity</title>
		<link>http://www.mywushublog.com/2011/07/using-duplicity/</link>
		<comments>http://www.mywushublog.com/2011/07/using-duplicity/#comments</comments>
		<pubDate>Thu, 21 Jul 2011 05:04:40 +0000</pubDate>
		<dc:creator>Mike Carlson</dc:creator>
				<category><![CDATA[Geekyness]]></category>
		<category><![CDATA[Backups]]></category>
		<category><![CDATA[Duplicity]]></category>
		<category><![CDATA[FreeBSD]]></category>

		<guid isPermaLink="false">http://www.mywushublog.com/?p=1503</guid>
		<description><![CDATA[A while ago, I posted about how I backup my server with Duplicity to Amazon&#8217;s S3 storage. To follow up, here is a little guide I wrote on using Duplicity in the everyday work environment Overview Duplicity is a backup tool that will create compressed and encrypted (uses gnupg) backup ...]]></description>
			<content:encoded><![CDATA[<p>A while ago, I posted about <a href="http://www.mywushublog.com/2009/04/using-amazon-s3-for-backups/">how I backup my server with Duplicity to Amazon&#8217;s S3 storage</a>.</p>
<p>To follow up, here is a little guide I wrote on using Duplicity in the everyday work environment</p>
<h2>Overview</h2>
<p>Duplicity is a backup tool that will create compressed and encrypted (uses gnupg) backup archives. It can use a variety of protocols as the target (file, ftp, webdav, imap, ssh/scp, rsync, hsi, s3 and hsi).</p>
<p>Since it is aware of previous backup jobs, incremental backups from that last full, and some basic collection management, it is preferred over simpler tools like rsync.</p>
<p>Since Duplicity uses GnuPG to compress and encrypt the save sets, you&#8217;ll need to enter a passphrase. This make duplicity a little difficult to automate, you can do one of two things:</p>
<ul>
<li>embed the the gnupg passphrase in the backup job, or use a gnupg-agent</li>
<li>disable encryption and just compress the save set</li>
</ul>
<p>To only compress and not encrypt, use the &#8221;&#8217;&#8211;no-encryption&#8221;&#8217; option.</p>
<h2>Installation</h2>
<p>Duplicity is available in the EPEL channel, so on RHEL 5 systems just type</p>
<pre>yum install duplicity</pre>
<p>On Ubuntu, you can install it using aptitude:</p>
<pre>aptitude install duplicity</pre>
<p>On FreeBSD, you can install it using:</p>
<pre>pkg_add -r duplicity</pre>
<h2>Preparation</h2>
<p>You&#8217;ll need a location to store your archives. Lets assume it is a locally mounted volume at /backups.</p>
<h2>Usage</h2>
<p>The syntax is pretty simple:</p>
<p>duplicity [full|incr|collection-status|list-current-files] source target-url</p>
<p>The &#8216;target-url&#8217; can be one of many protocols:</p>
<ul>
<li>file:///backups</li>
<li>scp://user@host/backups</li>
<li>webdav://user@backup-server/backups/</li>
</ul>
<p>Since we are assuming a locally mounted device, we&#8217;ll use the &#8221;&#8217;file:///&#8221;&#8217; url.</p>
<h3>Full Backups</h3>
<pre>duplicity full ~/ file:///backups/

GnuPG passphrase:
Local and Remote metadata are synchronized, no sync needed.
Last full backup date: none
Retype passphrase to confirm: 

--------------[ Backup Statistics ]--------------
StartTime 1274121911.36 (Mon May 17 11:45:11 2010)
EndTime 1274126391.50 (Mon May 17 12:59:51 2010)
ElapsedTime 4480.14 (1 hour 14 minutes 40.14 seconds)
SourceFiles 53369
SourceFileSize 43240385480 (40.3 GB)
NewFiles 53369
NewFileSize 43240385480 (40.3 GB)
DeletedFiles 0
ChangedFiles 0
ChangedFileSize 0 (0 bytes)
ChangedDeltaSize 0 (0 bytes)
DeltaEntries 53369
RawDeltaSize 43219504708 (40.3 GB)
TotalDestinationSizeChange 37539659285 (35.0 GB)
Errors 0
-------------------------------------------------</pre>
<h3>Incremental Backup</h3>
<p>Incremental backups are easy, just replace &#8216;full&#8217; with &#8216;incr&#8217;, and here, we also upped the Gzip compression level to &#8217;9&#8242;</p>
<pre>duplicity incr --gpg-options "-z 9" /home/mcarlson file:///media/0654-E203/backups
GnuPG passphrase:
Local and Remote metadata are synchronized, no sync needed.
Last full backup date: Mon May 17 11:45:04 2010
--------------[ Backup Statistics ]--------------
StartTime 1274130893.40 (Mon May 17 14:14:53 2010)
EndTime 1274131032.77 (Mon May 17 14:17:12 2010)
ElapsedTime 139.36 (2 minutes 19.36 seconds)
SourceFiles 53437
SourceFileSize 43628122482 (40.6 GB)
NewFiles 172
NewFileSize 434867245 (415 MB)
DeletedFiles 96
ChangedFiles 58
ChangedFileSize 1175654577 (1.09 GB)
ChangedDeltaSize 0 (0 bytes)
DeltaEntries 326
RawDeltaSize 444524537 (424 MB)
TotalDestinationSizeChange 442395156 (422 MB)
Errors 0
-------------------------------------------------</pre>
<h3>Restore</h3>
<p>You can either restore the entire archive with the &#8221;&#8217;restore&#8221;&#8217; option, or a set of files with &#8221;&#8217;files-to-restore&#8221;&#8217;:</p>
<p>Lets assume we did something like this:</p>
<pre>rm -rf FreeBSD</pre>
<p>This was obviously a mistake and we quickly need those files back:</p>
<pre>duplicity --file-to-restore src/FreeBSD file:///backups/ FreeBSD
GnuPG passphrase:
Local and Remote metadata are synchronized, no sync needed.
Last full backup date: Mon May 17 11:45:04 2010</pre>
<p>Lets verify that our files are in fact there again:</p>
<pre>ls -al FreeBSD
total 24
drwxr-xr-x  6 mcarlson mcarlson 4096 2009-08-31 15:51 .
drwxrwxr-x 65 mcarlson mcarlson 4096 2010-05-17 16:23 ..
drwxr-xr-x  2 mcarlson mcarlson 4096 2009-08-31 15:51 6.4
drwxr-xr-x  2 mcarlson mcarlson 4096 2009-08-31 15:25 7.0
drwxr-xr-x  2 mcarlson mcarlson 4096 2009-08-31 15:50 8.0
drwxr-xr-x  6 mcarlson mcarlson 4096 2009-08-31 15:52 i386</pre>
<h2>Managing your Archive(s)</h2>
<p>Duplicity does not store any policy or retention details, so it is up the the individual to remove older save sets.</p>
<h3>Collection Status</h3>
<p>First thing you can do is run get a status of your save sets. Duplicity will scan your target-url, in this case &#8216;file:///backups&#8217; and print a simple report on what backups types have ran, the date it was ran at, and the number of files:</p>
<pre>duplicity collection-status file:///media/0654-E203/backups

Local and Remote metadata are synchronized, no sync needed.
Last full backup date: Mon May 17 11:45:04 2010
Collection Status
-----------------
Connecting with backend: LocalBackend
Archive dir: /home/mcarlson/.cache/duplicity/0e6da04424dcfd02a2dae71879be23fa

Found 0 secondary backup chains.

Found primary backup chain with matching signature chain:
-------------------------
Chain start time: Mon May 17 11:45:04 2010
Chain end time: Mon May 17 14:14:48 2010
Number of contained backup sets: 2
Total number of contained volumes: 1447
 Type of backup set:                            Time:      Num volumes:
                Full         Mon May 17 11:45:04 2010              1430
         Incremental         Mon May 17 14:14:48 2010                17
-------------------------
No orphaned or incomplete backup sets found.</pre>
<h3>Collection Pruning</h3>
<p>You can remove older backup archives with &#8221;&#8217;remove-older-than&#8221;&#8217; or &#8221;&#8217;remove-all-but-n-full&#8221;&#8217;, and you can clean out failed save sets with the &#8221;&#8217;cleanup&#8221;&#8217; options.</p>
<p>All of these require the target-url as the 2nd argument.</p>
<p>Here, we will remove any archive that is older than 1 month (1M).</p>
<pre>duplicity remove-older-than 1M file:///backups/

Last full backup date: Sat May  1 00:20:02 2010
There are backup set(s) at time(s):
Thu Apr  1 00:15:17 2010
Sun Apr  4 00:01:23 2010
Sun Apr 11 00:01:29 2010
Which can't be deleted because newer sets depend on them.
Deleting backup sets at times:
Sun Apr 26 12:15:33 2009
Sun Apr 26 14:45:25 2009
Sun Apr 26 14:58:38 2009
Sun May  3 00:01:37 2009
Sun May 10 00:00:39 2009
Sun May 17 00:00:42 2009
Sun May 24 00:00:53 2009
Sun May 31 00:00:50 2009
Sun Jun  7 00:01:04 2009
Sun Jun 14 00:00:55 2009
Sun Jun 21 00:01:17 2009
Sun Jun 28 00:01:10 2009
Sun Jul  5 00:03:09 2009
Sun Jul 12 00:01:10 2009
Sun Jul 19 00:01:18 2009
Sun Jul 26 00:01:52 2009
Sun Aug  2 00:01:27 2009
Sun Aug  9 00:02:39 2009
Sun Aug 16 00:01:52 2009
Sun Aug 23 00:01:33 2009
Sun Aug 30 00:01:42 2009
Sat Sep  5 17:23:02 2009
Sun Sep  6 00:00:41 2009
Sun Sep 13 00:00:47 2009
Sun Mar  7 00:04:47 2010
Sun Mar 14 00:07:12 2010
Sun Mar 21 00:01:36 2010
Sun Mar 28 00:02:14 2010</pre>
]]></content:encoded>
			<wfw:commentRss>http://www.mywushublog.com/2011/07/using-duplicity/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Using Amazon&#8217;s S3 for Backups</title>
		<link>http://www.mywushublog.com/2009/04/using-amazon-s3-for-backups/</link>
		<comments>http://www.mywushublog.com/2009/04/using-amazon-s3-for-backups/#comments</comments>
		<pubDate>Sun, 26 Apr 2009 01:47:31 +0000</pubDate>
		<dc:creator>Mike Carlson</dc:creator>
				<category><![CDATA[Geekyness]]></category>
		<category><![CDATA[Backups]]></category>
		<category><![CDATA[FreeBSD]]></category>
		<category><![CDATA[MySQL]]></category>
		<category><![CDATA[PostgreSQL]]></category>
		<category><![CDATA[S3]]></category>

		<guid isPermaLink="false">http://www.mywushublog.com/?p=337</guid>
		<description><![CDATA[I don&#8217;t have a backup system for home (which is where this site, and others are located), and I have generally relied on duplicating enough of my important stuff between friends and other computers. That, and I have a RAID5 setup for my large storage, and then home directories and ...]]></description>
			<content:encoded><![CDATA[<p>I don&#8217;t have a backup system for home (which is where this site, and others are located), and I have generally relied on duplicating enough of my important stuff between friends and other computers. That, and I have a RAID5 setup for my large storage, and then home directories and website stuff is on a RAID1 ZFS volume. This doesn&#8217;t prevent accidental &#8220;oh-no&#8221;s, but it does protect me from some hardware failures.</p>
<p>Last year when I upgraded to the new server, I lost a lot of data because I forgot to backup all of my MySQL databases. I like to think I can learn from my mistakes, so a full year later I finally did something about it and signed up for Amazon&#8217;s S3 service.</p>
<p>The pricing is pretty nice, and I don&#8217;t have all that much data to backup. I figure, I&#8217;ll use up a few GB in total, and keep the monthly price around $1 &#8211; $2. That seems worth the price for off-site backup&#8217;s.</p>
<p>Now, I have 3 main websites that I need to backup, and one test site that I like to play around with:</p>
<ul>
<li><a href="http://www.m87-blackhole.org/">http://www.m87-blackhole.org/</a> &lt;- This is the first domain that I owned, and its the site where my family checks out new photos</li>
<li><a href="http://www.willowoakboarding.com/">http://www.willowoakboarding.com/</a> &lt;- My parent&#8217;s site for their boarding ranch. I&#8217;m glad they have no concept of a SLA, or that things need to be backed up :)</li>
<li><a href="http://www.mywushublog.com/">http://www.mywushublog.com/</a> &lt;- This site of course, where I claim my own identity on the internet</li>
<li><a href="http://www.evil-genius-network.com/">http://www.evil-genius-network.com/</a> &lt;- a test domain, but now I run a little OpenID service, For one&#8230;</li>
</ul>
<p>After a quick &#8220;FreeBSD s3 backup&#8221; Google search, I found Gary Dalton&#8217;s blog post: <a href="http://dvector.com/oracle/2008/10/18/backing-up-to-amazon-s3/">http://dvector.com/oracle/2008/10/18/backing-up-to-amazon-s3/</a>. After reading this post, I formulated my plan of attack:</p>
<ul>
<li>Sign up for S3, create a &#8220;bucket&#8221; for each site</li>
<li>Use something to interface with S3 ( <a href="http://duplicity.nongnu.org/">duplicity</a> )</li>
<li>Automate MySQL and PostgreSQL backups</li>
<li>Create a service account to run both s3 and db backup scripts as</li>
<li>Set up a cron job for backups</li>
</ul>
<p>So, after I signed up for S3, I had to create the buckets. I couldn&#8217;t find a way to do this though my Amazon account settings, so I created a little ruby script.<br />
<code><br />
$ sudo gem install aws-s3<br />
$ vim make-bucket.rb<br />
</code></p>

<div class="wp_syntax"><div class="code"><pre class="ruby" style="font-family:monospace;"><span style="color:#008000; font-style:italic;">#!/usr/local/bin/ruby</span>
&nbsp;
<span style="color:#CC0066; font-weight:bold;">require</span> <span style="color:#996600;">'aws/s3'</span>
&nbsp;
<span style="color:#6666ff; font-weight:bold;">AWS::S3::Base</span>.<span style="color:#9900CC;">establish_connection</span>!<span style="color:#006600; font-weight:bold;">&#40;</span>
<span style="color:#ff3333; font-weight:bold;">:access_key_id</span>     <span style="color:#006600; font-weight:bold;">=&gt;</span> <span style="color:#996600;">'my-s3-key-id'</span>,
<span style="color:#ff3333; font-weight:bold;">:secret_access_key</span> <span style="color:#006600; font-weight:bold;">=&gt;</span> <span style="color:#996600;">'my-s3-secret-access-key'</span>
<span style="color:#006600; font-weight:bold;">&#41;</span>
<span style="color:#6666ff; font-weight:bold;">AWS::S3::Bucket</span>.<span style="color:#9900CC;">create</span><span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#996600;">'mywushublog'</span><span style="color:#006600; font-weight:bold;">&#41;</span>
<span style="color:#6666ff; font-weight:bold;">AWS::S3::Bucket</span>.<span style="color:#9900CC;">create</span><span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#996600;">'willowoak'</span><span style="color:#006600; font-weight:bold;">&#41;</span>
<span style="color:#6666ff; font-weight:bold;">AWS::S3::Bucket</span>.<span style="color:#9900CC;">create</span><span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#996600;">'m87-blackhole'</span><span style="color:#006600; font-weight:bold;">&#41;</span>
<span style="color:#6666ff; font-weight:bold;">AWS::S3::Bucket</span>.<span style="color:#9900CC;">create</span><span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#996600;">'evil-genius-network'</span><span style="color:#006600; font-weight:bold;">&#41;</span></pre></div></div>

<p><code>$ ./make-bucket.rb</code><br />
Next, I had to install duplicity and py-boto<br />
<code>[root@server ~] cd /usr/ports/sysutils/duplicity<br />
[root@server duplicity] make install<br />
...<br />
[root@server duplicity] cd ../../devel/py-boto<br />
[root@server py-boto] make install clean<br />
...<br />
[root@server py-boto]</code><br />
Next step, create a user (with access to shared data, and website data) to run the backups with the adduser command&#8230;<br />
<code>[root@server py-boto] adduser -g shared-data -G www -s /bin/tcsh -w random s3backupuser<br />
...<br />
[roott@server py-boto] su - s3backupuser<br />
In tcsh, you can `set autolist' to have the shell automatically show<br />
all the possible matches when doing filename/directory expansion.<br />
%</code><br />
I&#8217;ll have to set my Access ID and Access Key in the s3backupuser&#8217;s environment, as well as a GnuPG passphrase so the backups are encrypted (and compressed). I mean, I trust Amazon, but not THAT much :)<br />
<code>% vim .cshrc<br />
setenv AWS_ACCESS_KEY_ID my-s3-key-id<br />
setenv AWS_SECRET_ACCESS_KEY my-s3-secrect-access-key<br />
setenv PASSPRASE AVeryRandonPassphraseForGnuPG</code><br />
Next, I copied the very useful automysqlbackup.sh script into a separate script for each website. I could have just dumped every database that was running, but I wanted to segregate each site&#8217;s databases into a different directory. So, I&#8217;m complicating my cron job by running multiple backup scripts, but I really want to make the end result easily readable and identifiable by me. So for each site, I create a directoy under /u01/backups:<br />
<code>%ll /u01/backups/<br />
total 8<br />
drwxr-x---  5 s3-backupuser  mysql  5 Apr 25 15:46 evil-genius-network<br />
drwxr-x---  5 s3-backupuser  mysql  5 Apr 25 15:47 m87-blackhole<br />
drwxr-x---  5 s3-backupuser  mysql  5 Apr 25 15:46 mywushublog<br />
drwxr-x---  5 s3-backupuser  mysql  5 Apr 25 15:47 willowoak</code><br />
Next was the s3-backups.sh script, which is very crude and simple. If I&#8217;m really motivated, I&#8217;ll make it nicer but I&#8217;m lazy and if I don&#8217;t need anymore functionality then I&#8217;ll just leave it. One thing I initially forgot was that I set my Amazon S3 variables in the users .cshrc profile. This is not a good place to have those things, it was just handy as I was running the duplicity commands manually. So I had to add those in, otherwise the cron job would fail.</p>
<p><strong>~/bin/s3-backups.sh</strong>:</p>

<div class="wp_syntax"><div class="code"><pre class="bash" style="font-family:monospace;"><span style="color: #666666; font-style: italic;">#!/bin/sh</span>
<span style="color: #007800;">PATH</span>=<span style="color: #000000; font-weight: bold;">/</span>sbin:<span style="color: #000000; font-weight: bold;">/</span>bin:<span style="color: #000000; font-weight: bold;">/</span>usr<span style="color: #000000; font-weight: bold;">/</span>sbin:<span style="color: #000000; font-weight: bold;">/</span>usr<span style="color: #000000; font-weight: bold;">/</span>bin:<span style="color: #000000; font-weight: bold;">/</span>usr<span style="color: #000000; font-weight: bold;">/</span>games:<span style="color: #000000; font-weight: bold;">/</span>usr<span style="color: #000000; font-weight: bold;">/</span>local<span style="color: #000000; font-weight: bold;">/</span>sbin:<span style="color: #000000; font-weight: bold;">/</span>usr<span style="color: #000000; font-weight: bold;">/</span>local<span style="color: #000000; font-weight: bold;">/</span>bin:<span style="color: #000000; font-weight: bold;">/</span>home<span style="color: #000000; font-weight: bold;">/</span>s3<span style="color: #000000; font-weight: bold;">/</span>bin
&nbsp;
<span style="color: #666666; font-style: italic;"># Amazon S3 keys, and GnuPG keys</span>
<span style="color: #007800;">AWS_ACCESS_KEY_ID</span>=
<span style="color: #007800;">AWS_SECRET_ACCESS_KEY</span>=
<span style="color: #007800;">PASSPHRASE</span>=
<span style="color: #7a0874; font-weight: bold;">export</span> AWS_ACCESS_KEY_ID
<span style="color: #7a0874; font-weight: bold;">export</span> AWS_SECRET_ACCESS_KEY
<span style="color: #7a0874; font-weight: bold;">export</span> PASSPHRASE
&nbsp;
<span style="color: #7a0874; font-weight: bold;">echo</span> <span style="color: #ff0000;">&quot;*************************************************&quot;</span>
<span style="color: #7a0874; font-weight: bold;">echo</span> <span style="color: #ff0000;">&quot;*   Backing up Website content....              *&quot;</span>
<span style="color: #7a0874; font-weight: bold;">echo</span> <span style="color: #ff0000;">&quot;*                                               *&quot;</span>
<span style="color: #7a0874; font-weight: bold;">echo</span> <span style="color: #ff0000;">&quot;*     www.willowoakboarding.com...              *&quot;</span>
duplicity <span style="color: #000000; font-weight: bold;">/</span>www<span style="color: #000000; font-weight: bold;">/</span>www.willowoakboarding.com s3+http:<span style="color: #000000; font-weight: bold;">//</span>s3.amazon.com<span style="color: #000000; font-weight: bold;">/</span>willowoak<span style="color: #000000; font-weight: bold;">/</span>www
<span style="color: #7a0874; font-weight: bold;">echo</span> <span style="color: #ff0000;">&quot;*     www.mywushublog.com...                    *&quot;</span>
duplicity <span style="color: #000000; font-weight: bold;">/</span>www<span style="color: #000000; font-weight: bold;">/</span>www.mywushublog.com s3+http:<span style="color: #000000; font-weight: bold;">//</span>s3.amazon.com<span style="color: #000000; font-weight: bold;">/</span>mywushublog<span style="color: #000000; font-weight: bold;">/</span>www
<span style="color: #7a0874; font-weight: bold;">echo</span> <span style="color: #ff0000;">&quot;*     www.m87-blackhole.org...                  *&quot;</span>
duplicity <span style="color: #000000; font-weight: bold;">/</span>www<span style="color: #000000; font-weight: bold;">/</span>www.m87-blackhole.org s3+http:<span style="color: #000000; font-weight: bold;">//</span>s3.amazon.com<span style="color: #000000; font-weight: bold;">/</span>m87-blackhole<span style="color: #000000; font-weight: bold;">/</span>www
<span style="color: #7a0874; font-weight: bold;">echo</span> <span style="color: #ff0000;">&quot;*************************************************&quot;</span>
<span style="color: #7a0874; font-weight: bold;">echo</span> <span style="color: #ff0000;">&quot;*   Backing up databases....                    *&quot;</span>
<span style="color: #7a0874; font-weight: bold;">echo</span> <span style="color: #ff0000;">&quot;*                                               *&quot;</span>
<span style="color: #7a0874; font-weight: bold;">echo</span> <span style="color: #ff0000;">&quot;*     www.willowoakboard.com...                 *&quot;</span>
duplicity <span style="color: #000000; font-weight: bold;">/</span>u01<span style="color: #000000; font-weight: bold;">/</span>backups<span style="color: #000000; font-weight: bold;">/</span>willowoak s3+http:<span style="color: #000000; font-weight: bold;">//</span>s3.amazon.com<span style="color: #000000; font-weight: bold;">/</span>willowoak<span style="color: #000000; font-weight: bold;">/</span>db
<span style="color: #7a0874; font-weight: bold;">echo</span> <span style="color: #ff0000;">&quot;*     www.mywushublog.com...                    *&quot;</span>
duplicity <span style="color: #000000; font-weight: bold;">/</span>u01<span style="color: #000000; font-weight: bold;">/</span>backups<span style="color: #000000; font-weight: bold;">/</span>mywushublog s3+http:<span style="color: #000000; font-weight: bold;">//</span>s3.amazon.com<span style="color: #000000; font-weight: bold;">/</span>mywushublog<span style="color: #000000; font-weight: bold;">/</span>db
<span style="color: #7a0874; font-weight: bold;">echo</span> <span style="color: #ff0000;">&quot;*     www.m87-blackhole.org...                  *&quot;</span>
duplicity <span style="color: #000000; font-weight: bold;">/</span>u01<span style="color: #000000; font-weight: bold;">/</span>backups<span style="color: #000000; font-weight: bold;">/</span>m87-blackhole s3+http:<span style="color: #000000; font-weight: bold;">//</span>s3.amazon.com<span style="color: #000000; font-weight: bold;">/</span>m87-blackhole<span style="color: #000000; font-weight: bold;">/</span>db
<span style="color: #7a0874; font-weight: bold;">echo</span> <span style="color: #ff0000;">&quot;*************************************************&quot;</span></pre></div></div>

<p>And last but not least, a cronjob to tie it all together:<br />
<code>% crontab -e<br />
@weekly ~/bin/s3-backups.sh<br />
@weekly ~/bin/mywushublog-mysql-backup.sh<br />
@weekly ~/bin/willowoak-mysql-backup.sh<br />
@weekly ~/bin/m87-blackhole-mysql-backup.sh<br />
@weekly ~/bin/evil-genius-network-mysql-backup.sh</code><br />
I can check the status of a backup by running <strong>duplicity</strong> with the &#8216;<em>collection-status</em>&#8216; flag:<br />
<code>%duplicity collection-status s3+http://s3.amazon.com/mywushublog/db<br />
Last full backup date: Sat Apr 25 15:08:02 2009<br />
Collection Status<br />
-----------------<br />
Connecting with backend: BotoBackend<br />
Archive dir: None<br />
Found 0 backup chains without signatures.<br />
Found a complete backup chain with matching signature chain:<br />
-------------------------<br />
Chain start time: Sat Apr 25 15:08:02 2009<br />
Chain end time: Sat Apr 25 15:08:02 2009<br />
Number of contained backup sets: 1<br />
Total number of contained volumes: 1<br />
Type of backup set:                            Time:      Num volumes:<br />
Full         Sat Apr 25 15:08:02 2009                 1<br />
-------------------------<br />
No orphaned or incomplete backup sets found.</code><br />
I can also list the files:<br />
<code>%duplicity list-current-files s3+http://s3.amazon.com/mywushublog/db<br />
Last full backup date: Sat Apr 25 15:08:02 2009<br />
Sat Apr 25 15:05:11 2009 .<br />
Sat Apr 25 15:05:10 2009 daily<br />
Sat Apr 25 15:05:10 2009 daily/mywushublog<br />
Sat Apr 25 15:05:10 2009 monthly<br />
Sat Apr 25 15:05:10 2009 weekly<br />
Sat Apr 25 15:05:11 2009 weekly/mywushublog<br />
Sat Apr 25 15:05:11 2009 weekly/mywushublog/mywushublog_week.17.2009-04-25_15h05m.sql.gz</code><br />
Pretty sweet automated backup process. It is a lot cheaper than tapes or additional disk storage. With S3, I also don&#8217;t have to worry about buying additional hardware, the maintenance of a library or tape drive (which is what I had a few years ago, what a headache).</p>
]]></content:encoded>
			<wfw:commentRss>http://www.mywushublog.com/2009/04/using-amazon-s3-for-backups/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
	</channel>
</rss>
<!-- This Quick Cache file was built for (  www.mywushublog.com/tag/backups/feed/ ) in 0.46364 seconds, on Feb 5th, 2012 at 11:08 am UTC. -->
<!-- This Quick Cache file will automatically expire ( and be re-built automatically ) on Feb 5th, 2012 at 12:08 pm UTC -->
