diff --git a/manifests/params.pp b/manifests/params.pp index 1757159..8f25d9d 100644 --- a/manifests/params.pp +++ b/manifests/params.pp @@ -48,6 +48,9 @@ $stop_on_stale_lockfile = undef $one_fs = undef + $systemd = false + $systemd_dir = '/etc/systemd/system' + $backup_hourly_cron = '*/2' $backup_time_minute = fqdn_rand(59, 'rsnapshot_minute') $backup_time_hour = fqdn_rand(23, 'rsnapshot_hour') diff --git a/manifests/server.pp b/manifests/server.pp index 2ac839e..15331a4 100644 --- a/manifests/server.pp +++ b/manifests/server.pp @@ -50,6 +50,8 @@ $rsync_numtries = $rsnapshot::params::rsync_numtries, $stop_on_stale_lockfile = $rsnapshot::params::stop_on_stale_lockfile, $du_args = $rsnapshot::params::du_args, + $systemd = $rsnapshot::params::systemd, + $systemd_dir = $rsnapshot::params::systemd_dir, ) inherits rsnapshot::params { include rsnapshot::server::install @@ -75,7 +77,6 @@ group => $server_user }-> - Rsnapshot::Server::Config <<| server == $::fqdn |>> { config_path => $::rsnapshot::server::config_path, log_path => $::rsnapshot::server::log_path, @@ -91,6 +92,23 @@ rsync_numtries => $::rsnapshot::server::rsync_numtries, stop_on_stale_lockfile => $::rsnapshot::server::stop_on_stale_lockfile, du_args => $::rsnapshot::server::du_args, + systemd => $systemd, + systemd_dir => $systemd_dir, } + # systemd services + if $systemd { + ['hourly', 'daily', 'weekly', 'monthly'].each |String $interval| { + $config_path_norm = regsubst($config_path, '\/$', '') + + file { "${systemd_dir}/rsnapshot-${interval}@.service": + ensure => file, + content => epp('rsnapshot/systemd_service.epp', + { + description => "Create an rsnapshot backup for %i (${interval})", + command => "${rsnapshot::server::cmd_rsnapshot} -c \"${config_path_norm}/%i-rsnapshot.conf\" ${interval}", + }) + } + } + } } diff --git a/manifests/server/config.pp b/manifests/server/config.pp index 100fa43..2880d8c 100644 --- a/manifests/server/config.pp +++ b/manifests/server/config.pp @@ -41,6 +41,8 @@ $wrapper_sudo = $rsnapshot::params::wrapper_sudo, $wrapper_rsync_sender = $rsnapshot::params::wrapper_rsync_sender, $wrapper_rsync_ssh = $rsnapshot::params::wrapper_rsync_ssh, + $systemd = $rsnapshot::params::systemd, + $systemd_dir = $rsnapshot::params::systemd_dir, ) { # Remove trailing slashes. @@ -80,47 +82,63 @@ require => File[$log_path] } - # cronjobs + # systemd service/timer + if $systemd { + ::rsnapshot::server::service{ $name: + backup_hourly_timer => regsubst($backup_hourly_cron, '\*', '0'), + backup_time_minute => $backup_time_minute, + backup_time_hour => $backup_time_hour, + backup_time_weekday => $backup_time_weekday, + backup_time_dom => $backup_time_dom, + retain_hourly => $retain_hourly, + retain_daily => $retain_daily, + retain_weekly => $retain_weekly, + retain_monthly => $retain_monthly, + systemd_dir => $systemd_dir, + } - ## hourly - if ($retain_hourly > 0) { - cron { "rsnapshot-${name}-hourly" : - command => "${rsnapshot::server::cmd_rsnapshot} -c ${config_file} hourly", - user => $server_user, - hour => $backup_hourly_cron, - minute => $backup_time_minute + # cronjobs + } else { + ## hourly + if ($retain_hourly > 0) { + cron { "rsnapshot-${name}-hourly": + command => "${rsnapshot::server::cmd_rsnapshot} -c ${config_file} hourly", + user => $server_user, + hour => $backup_hourly_cron, + minute => $backup_time_minute + } } - } - ## daily - if ($retain_daily > 0) { - cron { "rsnapshot-${name}-daily" : - command => "${rsnapshot::server::cmd_rsnapshot} -c ${config_file} daily", - user => $server_user, - hour => $backup_time_hour, - minute => ($backup_time_minute + 50) % 60 + ## daily + if ($retain_daily > 0) { + cron { "rsnapshot-${name}-daily": + command => "${rsnapshot::server::cmd_rsnapshot} -c ${config_file} daily", + user => $server_user, + hour => $backup_time_hour, + minute => ($backup_time_minute + 50) % 60 + } } - } - ## weekly - if ($retain_weekly > 0) { - cron { "rsnapshot-${name}-weekly" : - command => "${rsnapshot::server::cmd_rsnapshot} -c ${config_file} weekly", - user => $server_user, - hour => ($backup_time_hour + 3) % 24, - minute => ($backup_time_minute + 50) % 60, - weekday => $backup_time_weekday + ## weekly + if ($retain_weekly > 0) { + cron { "rsnapshot-${name}-weekly": + command => "${rsnapshot::server::cmd_rsnapshot} -c ${config_file} weekly", + user => $server_user, + hour => ($backup_time_hour + 3) % 24, + minute => ($backup_time_minute + 50) % 60, + weekday => $backup_time_weekday + } } - } - ## monthly - if ($retain_monthly > 0) { - cron { "rsnapshot-${name}-monthly" : - command => "${rsnapshot::server::cmd_rsnapshot} -c ${config_file} monthly", - user => $server_user, - hour => ($backup_time_hour + 7) % 24, - minute => ($backup_time_minute + 50) % 60, - monthday => $backup_time_dom + ## monthly + if ($retain_monthly > 0) { + cron { "rsnapshot-${name}-monthly": + command => "${rsnapshot::server::cmd_rsnapshot} -c ${config_file} monthly", + user => $server_user, + hour => ($backup_time_hour + 7) % 24, + minute => ($backup_time_minute + 50) % 60, + monthday => $backup_time_dom + } } } diff --git a/manifests/server/service.pp b/manifests/server/service.pp new file mode 100644 index 0000000..df84da9 --- /dev/null +++ b/manifests/server/service.pp @@ -0,0 +1,64 @@ +define rsnapshot::server::service ( + $backup_hourly_timer, + $backup_time_minute, + $backup_time_hour, + $backup_time_weekday, + $backup_time_dom, + $retain_hourly, + $retain_daily, + $retain_weekly, + $retain_monthly, + $systemd_dir = '/etc/systemd/system', +) { + # Get the minute/hour offsets for the various timers. + # These are identical to the cronjob. + $minute = ($backup_time_minute + 50) % 60; + $hour_weekly = ($backup_time_hour + 3) % 24; + $hour_monthly = ($backup_time_hour + 7) % 24; + + # Map the weekday to three-letter English. + $day = $backup_time_weekday ? { + 0 => 'Sun', + 1 => 'Mon', + 2 => 'Tue', + 3 => 'Wed', + 4 => 'Thu', + 5 => 'Fri', + 6 => 'Sat', + 7 => 'Sun', + default => 'Sun', + } + + # Create a map of the enabled services + $enabled = { + "hourly" => ($retain_hourly > 0), + "daily" => ($retain_daily > 0), + "weekly" => ($retain_weekly > 0), + "monthly" => ($retain_monthly > 0), + } + + # Create a map of the backup time patterns. + $times = { + "hourly" => "${backup_hourly_timer}:${backup_time_minute}", + "daily" => "${backup_time_hour}:${minute}", + "weekly" => "${day}, ${hour_weekly}:${minute}", + "monthly" => "*-*-${backup_time_dom} ${hour_monthly}:${minute}", + } + + # Create and enable the timers. + $times.each |String $interval, String $time| { + if $enabled[$interval] { + $unit = "rsnapshot-${interval}-${name}.timer" + file { "${systemd_dir}/${unit}": + ensure => file, + content => epp('rsnapshot/systemd_timer.epp', + { + description => "Create an rsnapshot backup for ${name} (${interval})", + on_calendar => $time, + unit => "rsnapshot-${interval}@${name}.service" + }) + } + ~> service { $unit: ensure => 'running', enable => true } + } + } +} diff --git a/templates/systemd_service.epp b/templates/systemd_service.epp new file mode 100644 index 0000000..4ea0e54 --- /dev/null +++ b/templates/systemd_service.epp @@ -0,0 +1,8 @@ +<%- | String $description, + String $command, +| -%> +[Unit] +Description=<%= $description %> + +[Service] +ExecStart=<%= $command %> diff --git a/templates/systemd_timer.epp b/templates/systemd_timer.epp new file mode 100644 index 0000000..f126795 --- /dev/null +++ b/templates/systemd_timer.epp @@ -0,0 +1,21 @@ +<%- | String $description, + String $on_calendar, + Optional[Boolean] $persistent = true, + Optional[String] $unit = undef, + Optional[String] $wanted_by = 'multi-user.target', +| -%> +[Unit] +Description=<%= $description %> + +[Timer] +OnCalendar=<%= $on_calendar %> +<% unless $unit =~ Undef { -%> +Unit=<%= $unit %> +<% } -%> +Persistent=<%= $persistent %> +<% unless $persistent =~ Undef { -%> +Persistent=<%= $persistent %> +<% } -%> + +[Install] +WantedBy=<%= $wanted_by %>