From 4efe6bcd92f637a18cc5289961ec0a654ac8801e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Timo=20M=E4kinen?= Date: Fri, 10 May 2013 17:20:15 +0300 Subject: [PATCH] bacula: Initial version of module. --- bacula/files/bacula_catalog_dump | 7 + bacula/files/fileset.Catalog.conf | 11 + bacula/files/fileset.Default.conf | 12 + bacula/manifests/init.pp | 424 +++++++++++++++++++++++++++ bacula/templates/bacula-dir.conf.erb | 82 ++++++ bacula/templates/bacula-fd.conf.erb | 26 ++ bacula/templates/bacula-sd.conf.erb | 34 +++ bacula/templates/bconsole.conf.erb | 11 + bacula/templates/client.conf.erb | 12 + bacula/templates/device.conf.erb | 10 + bacula/templates/job.conf.erb | 8 + bacula/templates/storage.conf.erb | 14 + 12 files changed, 651 insertions(+) create mode 100755 bacula/files/bacula_catalog_dump create mode 100644 bacula/files/fileset.Catalog.conf create mode 100644 bacula/files/fileset.Default.conf create mode 100644 bacula/manifests/init.pp create mode 100644 bacula/templates/bacula-dir.conf.erb create mode 100644 bacula/templates/bacula-fd.conf.erb create mode 100644 bacula/templates/bacula-sd.conf.erb create mode 100644 bacula/templates/bconsole.conf.erb create mode 100644 bacula/templates/client.conf.erb create mode 100644 bacula/templates/device.conf.erb create mode 100644 bacula/templates/job.conf.erb create mode 100644 bacula/templates/storage.conf.erb diff --git a/bacula/files/bacula_catalog_dump b/bacula/files/bacula_catalog_dump new file mode 100755 index 0000000..0727a0c --- /dev/null +++ b/bacula/files/bacula_catalog_dump @@ -0,0 +1,7 @@ +#!/bin/sh + +# compact database +echo "vacuum;" | sqlite3 /srv/bacula/bacula.db + +# dump database to file +echo ".dump" | sqlite3 /srv/bacula/bacula.db > /srv/bacula/bacula.sql diff --git a/bacula/files/fileset.Catalog.conf b/bacula/files/fileset.Catalog.conf new file mode 100644 index 0000000..721f2b0 --- /dev/null +++ b/bacula/files/fileset.Catalog.conf @@ -0,0 +1,11 @@ + +FileSet { + Name = "Catalog" + Include { + Options { + signature = MD5 + } + File = "/srv/bacula/bacula.sql" + } +} + diff --git a/bacula/files/fileset.Default.conf b/bacula/files/fileset.Default.conf new file mode 100644 index 0000000..0094367 --- /dev/null +++ b/bacula/files/fileset.Default.conf @@ -0,0 +1,12 @@ + +FileSet { + Name = "Default" + Include { + Options { + signature = SHA1 + onefs = yes + } + File = "|sh -c 'mount | awk \"{ if (/^\\/dev\\//) { print \\$3} }\"'" + } +} + diff --git a/bacula/manifests/init.pp b/bacula/manifests/init.pp new file mode 100644 index 0000000..9920fa5 --- /dev/null +++ b/bacula/manifests/init.pp @@ -0,0 +1,424 @@ + +# Install puppet certificates to be used by Bacula +# +class bacula::certificates { + + file { "/etc/pki/tls/private/bacula.key": + ensure => present, + source => "${::puppet_ssldir}/private_keys/${::homename}.pem", + mode => "0640", + owner => "root", + group => "bacula", + } + + file { "/etc/pki/tls/certs/bacula.crt": + ensure => present, + source => "${::puppet_ssldir}/certs/${::homename}.pem", + mode => "0644", + owner => "root", + group => "root", + } + +} + + +# Install bacula client +# +# === Parameters +# +# $password: +# Password used by director for connecting. Defaults +# to md5 hash from puppet fqdn_rand function output. +# +class bacula::client($password=undef) { + + if !$password { + $password_real = md5(fqdn_rand(99999999999999999999999999)) + } else { + $password_real = $password + } + + include bacula::certificates + + package { "bacula-client": + ensure => installed, + before => Class["bacula::certificates"], + } + + file { "/etc/bacula/bacula-fd.conf": + ensure => present, + content => template("bacula/bacula-fd.conf.erb"), + mode => 0640, + owner => "root", + group => "bacula", + require => Package["bacula-client"], + notify => Service["bacula-fd"], + } + + @@file { "/etc/bacula/bacula-dir.d/client-${homename}.conf": + ensure => present, + content => template("bacula/client.conf.erb"), + mode => "0640", + owner => "root", + group => "bacula", + tag => "bacula", + } + + service { "bacula-fd": + ensure => running, + enable => true, + require => Class["bacula::certificates"], + } + +} + + +# Install Bacula console +# +# Note that console will be able to connect all defined Bacula +# directors. +# +class bacula::console { + + include bacula::certificates + + package { "bacula-console": + ensure => installed, + before => Class["bacula::certificates"], + } + + File <<| tag == "bacula-console" |>> + +} + + +# Install Bacula director +# +# === Parameters +# +# $datadir: +# Data directory for storing database and bootstraps. +# Defaults to /srv/bacula. +# $dbadapter: +# Database type for catalog. Only sqlite and mysql are +# supported. Defaults to sqlite. +# $dbserver: +# Database server address. Defaults to "localhost". Not needed +# for sqlite. +# $dbname: +# Database name. Defaults to "bacula". Not needed for sqlite. +# $dbuser: +# Database user name. Defaults to "bacula". Not needed for sqlite. +# $dbpassword: +# Database password. Not needed for sqlite. +# $password: +# Password required for connecting to director. Defaults +# to md5 hash from puppet fqdn_rand function output. +# +class bacula::director($password=undef, + $datadir="/srv/bacula", + $dbadapter="sqlite", + $dbserver="localhost", + $dbname="bacula", + $dbuser="bacula", + $dbpassword=undef) { + + include bacula::certificates + include bacula::console + + if !$password { + $password_real = md5(fqdn_rand(99999999999999999999999999)) + } else { + $password_real = $password + } + + case $dbadapter { + "sqlite": { + exec { "create-bacula-catalog": + command => "/usr/libexec/bacula/make_sqlite3_tables && mv /var/spool/bacula/bacula.db /srv/bacula", + user => "bacula", + path => "/bin:/usr/bin:/sbin:/usr/sbin", + creates => "/srv/bacula/bacula.db", + require => File["/srv/bacula"], + before => Service["bacula-director"], + } + } + "mysql": { + if !$dbpassword { + fail("\$dbpassword is required for bacula::director") + } + } + default: { + fail("Unknown \$dbadapter for bacula::director") + } + } + + package { "bacula-director": + name => $dbadapter ? { + "sqlite" => "bacula-director-sqlite", + "mysql" => "bacula-director-mysql", + }, + ensure => installed, + before => Class["bacula::certificates"], + } + + file { "/etc/bacula/bacula-dir.conf": + ensure => present, + content => template("bacula/bacula-dir.conf.erb"), + mode => "0640", + owner => "root", + group => "bacula", + require => Package["bacula-director"], + notify => Service["bacula-director"], + } + file { "/etc/bacula/bacula-dir.d": + ensure => directory, + mode => "0750", + owner => "root", + group => "bacula", + purge => true, + recurse => true, + require => Package["bacula-director"], + notify => Service["bacula-director"], + } + + @@file { "/etc/bacula/bconsole.conf": + ensure => present, + content => template("bacula/bconsole.conf.erb"), + mode => "0640", + owner => "root", + group => "bacula", + tag => "bacula-console", + require => Package["bacula-console"], + } + + file { "/etc/sysconfig/bacula-dir": + ensure => present, + content => "DIR_USER=bacula\nDIR_GROUP=bacula\n", + mode => "0644", + owner => "root", + group => "root", + require => Package["bacula-director"], + notify => Service["bacula-director"], + } + + file { $datadir: + ensure => directory, + mode => "0770", + owner => "bacula", + group => "bacula", + seltype => "var_spool_t", + require => Package["bacula-director"], + } + selinux::manage_fcontext { "${datadir}(/.*)?": + type => "var_spool_t", + before => File[$datadir], + } + if $datadir != "/srv/bacula" { + file { "/srv/bacula": + ensure => link, + target => $datadir, + owner => "bacula", + group => "bacula", + seltype => "var_spool_t", + require => File[$datadir], + } + selinux::manage_fcontext { "/srv/bacula(/.*)?": + type => "var_spool_t", + before => File[$datadir], + } + } + + File <<| tag == "bacula" |>> { + require => File["/etc/bacula/bacula-dir.d"], + notify => Service["bacula-director"], + } + + # catalog backup job (also runs db compacting) + bacula::fileset { "Catalog": + source => "puppet:///modules/bacula/fileset.Catalog.conf", + } + bacula::job { "BackupCatalog": + options => [ + "Level = Full", + "FileSet = Catalog", + 'RunBeforeJob = "/usr/local/sbin/bacula_catalog_dump"', + 'RunAfterJob = "rm /srv/bacula/bacula.sql"', + 'Write Bootstrap = "/srv/bacula/%n.bsr"', + "Priority = 11", + ], + } + file { "/usr/local/sbin/bacula_catalog_dump": + ensure => present, + source => "puppet:///modules/bacula/bacula_catalog_dump", + mode => "0755", + owner => "root", + group => "root", + before => Service["bacula-director"], + } + + service { "bacula-director": + name => "bacula-dir", + ensure => running, + enable => true, + require => [ File["/srv/bacula"], Class["bacula::certificates"], ], + } + +} + + +# Create new Bacula fileset +# +# === Parameters +# +# $name: +# Fileset name. +# $source: +# Path to fileset source file. Defaults to +# "puppet:///files/bacula/fileset.${name}.conf". +# +# === Sample usage +# +# bacula::fileset { "Default": +# source => "puppet:///modules/bacula/fileset.Default.conf", +# } +# +define bacula::fileset($source="puppet:///files/bacula/fileset.${name}.conf") { + + file { "/etc/bacula/bacula-dir.d/fileset-${name}.conf": + ensure => present, + source => $source, + mode => "0640", + owner => "root", + group => "bacula", + require => File["/etc/bacula/bacula-dir.d"], + notify => Service["bacula-dir"], + } + +} + + +# Create new Bacula job +# +# === Parameters +# +# $name: +# Job name +# $jobdefs: +# Resource where default values for job are taken. +# Defaults to "DefaultJob". +# +# === Sample usage +# +# bacula::job { $homename: } +# +define bacula::job($jobdefs="DefaultJob", $options=[]) { + + @@file { "/etc/bacula/bacula-dir.d/job-${name}.conf": + ensure => present, + content => template("bacula/job.conf.erb"), + mode => "0640", + owner => "root", + group => "bacula", + tag => "bacula", + } + +} + + +# Install Bacula storage daemon +# +# === Parameters +# +# $password: +# Password required for conneting to this storage daemon. +# Defaults to md5 hash from puppet fqdn_rand function output. +# +class bacula::storage($password = undef) { + + if !$password { + $password_real = md5(fqdn_rand(99999999999999999999999999)) + } else { + $password_real = $password + } + + include bacula::certificates + + package { "bacula-storage": + name => "bacula-storage-sqlite", + ensure => installed, + before => Class["bacula::certificates"], + } + + file { "/etc/bacula/bacula-sd.conf": + ensure => present, + content => template("bacula/bacula-sd.conf.erb"), + mode => "0640", + owner => "root", + group => "bacula", + require => Package["bacula-storage"], + notify => Service["bacula-sd"], + } + + file { "/etc/bacula/bacula-sd.d": + ensure => directory, + mode => "0750", + owner => "root", + group => "bacula", + purge => true, + recurse => true, + require => Package["bacula-storage"], + } + + service { "bacula-sd": + ensure => running, + enable => true, + require => Class["bacula::certificates"], + } + +} + + +# Create new backup device +# +# === Parameters +# +# $name: +# Name for backup device. +# $device: +# Filename for storage device (eg. /dev/nst0). +# $media: +# Media type supported by this device. +# +# === Sample usage +# +# bacula::device { "Tape": +# device => "/dev/nst0", +# media => "LTO3", +# } +# +define bacula::device($device, $media) { + + include bacula::storage + + file { "/etc/bacula/bacula-sd.d/${name}.conf": + ensure => present, + content => template("bacula/device.conf.erb"), + mode => "0640", + owner => "root", + group => "bacula", + require => File["/etc/bacula/bacula-sd.d"], + notify => Service["bacula-sd"], + } + + @@file { "/etc/bacula/bacula-dir.d/device-${name}.conf": + ensure => present, + content => template("bacula/storage.conf.erb"), + mode => "0640", + owner => "root", + group => "bacula", + tag => "bacula", + } + +} + diff --git a/bacula/templates/bacula-dir.conf.erb b/bacula/templates/bacula-dir.conf.erb new file mode 100644 index 0000000..3c67d12 --- /dev/null +++ b/bacula/templates/bacula-dir.conf.erb @@ -0,0 +1,82 @@ + +Director { + Name = "bacula-dir" + WorkingDirectory = "/srv/bacula" + PidDirectory = "/var/run" + QueryFile = "/etc/bacula/query.sql" + Password = "<%= @password_real %>" + TLS Enable = yes + TLS Require = yes + TLS Key = /etc/pki/tls/private/bacula.key + TLS Certificate = /etc/pki/tls/certs/bacula.crt + TLS CA Certificate File = <%= @puppet_ssldir %>/certs/ca.pem + TLS Verify Peer = yes +} + +Messages { + Name = "Standard" + MailCommand = "mail -s \"Bacula Message\" %r" + OperatorCommand = "mail -s \"Bacula Operator Message\" %r" + mail = root = all, !skipped + operator = root = mount + append = "/var/log/bacula/bacula.log" = all, !skipped + catalog = all +} + +Catalog { + Name = "Catalog" +<% if @dbadapter == "sqlite" -%> + dbname = bacula + user = "bacula" + password = "" +<% else -%> +<% if @dbserver == 'localhost' -%> +<% if @dbadapter == 'mysql' -%> + DB Socket = "/var/lib/mysql/mysql.sock" +<% end -%> +<% else -%> + DB Address = "<%= @dbserver %>" +<% end -%> + dbname = "<%= @dbname %>" + user = "<%= dbuser %>" + password = "<%= dbpassword %>" +<% end %> +} + +Pool { + Name = "Default" + Pool Type = Backup + Recycle = no +} + +Schedule { + Name = "Default" + Run = Level=Full on 1 at 3:00 + Run = Level=Incremental on 2-31 at 3:00 +} + +JobDefs { + Name = "DefaultJob" + Type = Backup + Level = Incremental + Messages = Standard + Schedule = Default + FileSet = Default + Pool = Default + Storage = Default + Write Bootstrap = "/srv/bacula/%c.bsr" + Priority = 10 +} + +Job { + Name = "RestoreJob" + Type = Restore + Client = "<%= @homename %>" + FileSet = "Default" + Storage = Default + Messages = Standard + Pool = Default + Where = "/var/tmp" +} + +@|"sh -c 'find /etc/bacula/bacula-dir.d/*.conf -exec echo @{} \\;'" diff --git a/bacula/templates/bacula-fd.conf.erb b/bacula/templates/bacula-fd.conf.erb new file mode 100644 index 0000000..1564125 --- /dev/null +++ b/bacula/templates/bacula-fd.conf.erb @@ -0,0 +1,26 @@ + +Director { + Name = "bacula-dir" + Password = "<%= @password_real %>" + TLS Enable = yes + TLS Require = yes + TLS Key = /etc/pki/tls/private/bacula.key + TLS Certificate = /etc/pki/tls/certs/bacula.crt + TLS CA Certificate File = <%= @puppet_ssldir %>/certs/ca.pem +} + +FileDaemon { + Name = "<%= @homename %>" + WorkingDirectory = /var/spool/bacula + Pid Directory = /var/run + TLS Enable = yes + TLS Require = yes + TLS Key = /etc/pki/tls/private/bacula.key + TLS Certificate = /etc/pki/tls/certs/bacula.crt + TLS CA Certificate File = <%= @puppet_ssldir %>/certs/ca.pem +} + +Messages { + Name = "Standard" + director = bacula-dir = all, !skipped, !restored +} diff --git a/bacula/templates/bacula-sd.conf.erb b/bacula/templates/bacula-sd.conf.erb new file mode 100644 index 0000000..e9ea737 --- /dev/null +++ b/bacula/templates/bacula-sd.conf.erb @@ -0,0 +1,34 @@ + +Storage { + Name = "<%= @homename %>" + WorkingDirectory = "/var/spool/bacula" + Pid Directory = "/var/run" + TLS Enable = yes + TLS Require = yes + TLS Key = /etc/pki/tls/private/bacula.key + TLS Certificate = /etc/pki/tls/certs/bacula.crt + TLS CA Certificate File = <%= @puppet_ssldir %>/certs/ca.pem + TLS Verify Peer = yes +} + +Director { + Name = "bacula-dir" + Password = "<%= @password_real %>" + TLS Enable = yes + TLS Require = yes + TLS Key = /etc/pki/tls/private/bacula.key + TLS Certificate = /etc/pki/tls/certs/bacula.crt + TLS CA Certificate File = <%= @puppet_ssldir %>/certs/ca.pem + TLS Verify Peer = yes +} + +Messages { + Name = "Standard" + MailCommand = "mail -s \"Bacula Message\" %r" + OperatorCommand = "mail -s \"Bacula Operator Message\" %r" + mail = root = all, !skipped, !info + operator = root = mount + director = bacula-dir = all +} + +@|"sh -c 'find /etc/bacula/bacula-sd.d/*.conf -exec echo @{} \\;'" diff --git a/bacula/templates/bconsole.conf.erb b/bacula/templates/bconsole.conf.erb new file mode 100644 index 0000000..d42f0cb --- /dev/null +++ b/bacula/templates/bconsole.conf.erb @@ -0,0 +1,11 @@ + +Director { + Name = "bacula-dir" + Address = "vm23.home.foo.sh" + Password = "<%= @password_real %>" + TLS Enable = yes + TLS Require = yes + TLS Key = /etc/pki/tls/private/bacula.key + TLS Certificate = /etc/pki/tls/certs/bacula.crt + TLS CA Certificate File = <%= @puppet_ssldir %>/certs/ca.pem +} diff --git a/bacula/templates/client.conf.erb b/bacula/templates/client.conf.erb new file mode 100644 index 0000000..51c2b90 --- /dev/null +++ b/bacula/templates/client.conf.erb @@ -0,0 +1,12 @@ + +Client { + Name = "<%= @homename %>" + Address = <%= @homename %> + Catalog = "Catalog" + Password = "<%= @password_real %>" + TLS Enable = yes + TLS Require = yes + TLS Key = /etc/pki/tls/private/bacula.key + TLS Certificate = /etc/pki/tls/certs/bacula.crt + TLS CA Certificate File = <%= @puppet_ssldir %>/certs/ca.pem +} diff --git a/bacula/templates/device.conf.erb b/bacula/templates/device.conf.erb new file mode 100644 index 0000000..546066e --- /dev/null +++ b/bacula/templates/device.conf.erb @@ -0,0 +1,10 @@ + +Device { + Name = "<%= @name %>" + Media Type = <%= @media %> + Archive Device = <%= @device %> + AutomaticMount = yes; + AlwaysOpen = no; + RemovableMedia = yes; + RandomAccess = no; +} diff --git a/bacula/templates/job.conf.erb b/bacula/templates/job.conf.erb new file mode 100644 index 0000000..ad6066a --- /dev/null +++ b/bacula/templates/job.conf.erb @@ -0,0 +1,8 @@ +Job { + Name = "<%= @name %>" + Client = "<%= @homename %>" + JobDefs = "<%= @jobdefs %>" +<% @options.each do |val| -%> + <%= val %> +<% end -%> +} diff --git a/bacula/templates/storage.conf.erb b/bacula/templates/storage.conf.erb new file mode 100644 index 0000000..00429b7 --- /dev/null +++ b/bacula/templates/storage.conf.erb @@ -0,0 +1,14 @@ + +Storage { + Name = "<%= @name %>" + Address = <%= @homename %> + Password = "<%= scope.lookupvar('bacula::storage::password_real') %>" + Device = "<%= @name %>" + Media Type = <%= @media %> + TLS Enable = yes + TLS Require = yes + TLS Key = /etc/pki/tls/private/bacula.key + TLS Certificate = /etc/pki/tls/certs/bacula.crt + TLS CA Certificate File = <%= @puppet_ssldir %>/certs/ca.pem +} +