3rd and final message, I hope:

#####################
bacula-dir.conf:

Please note that I reference various resources named 'None', and a schedule
named "Manual'. These are empty dummy resources, that are really defined. I
have used these to more visually show me that a given job doesn't use those
resources, even though the config parser requires them to be present. Any
client, schedule, fileset, pool, etc that you reference must exist.
#####################
Storage {
  Name = "Synology-Local"
  Description = "Synology-Local"
  SdPort = 9103
  Address = "td-bacula"
  Password = "REDACTED-SD PASSWORD"
  Device = "Synology-Local"
  MediaType = "Synology-Local"
  Autochanger = "Synology-Local"
  MaximumConcurrentJobs = 50
}
Storage {
  Name = "B2-TD-Full"
  Description = "B2-TD-Full"
  SdPort = 9103
  Address = "td-bacula"
  Password = "REDACTED-SD PASSWORD"
  Device = "B2-TD-Full"
  MediaType = "B2-TD-Full"
  Autochanger = "B2-TD-Full"
  MaximumConcurrentJobs = 50
}
Storage {
  Name = "B2-TD-Diff"
  ...
}
Storage {
  Name = "B2-TD-Inc"
  ...
}
Pool {
  Name = "Synology-Local-Full"
  Description = "Synology-Local-Full"
  PoolType = "Backup"
  NextPool = "B2-TD-Full"
  LabelFormat = "Synology-Local-Full-"
  LabelType = "Bacula"
  MaximumVolumeJobs = 1   # Not essential for local jobs, and has caused a
race condition previously.
  Storage = "Synology-Local"
  ActionOnPurge=Truncate   # This enables truncation after a volume has
been purged.
  FileRetention = 95days
  JobRetention = 95days
  VolumeRetention = 95days
}
Pool {
  Name = "Synology-Local-Diff"
  ...
  FileRetention = 45days
  JobRetention = 45days
  VolumeRetention = 45days
}
Pool {
  Name = "Synology-Local-Inc"
  ...
  FileRetention = 21days
  JobRetention = 21days
  VolumeRetention = 21days
}
Pool {
  Name = "B2-TD-Full"
  Description = "B2-TD-Full"
  PoolType = "Backup"
  LabelFormat = "B2-TD-Full-"
  LabelType = "Bacula"
  MaximumVolumeJobs = 1   # Essential for cloud volumes. We want to be able
to delete old volumes quickly to reduce cloud spend.
  Storage = "B2-TD-Full"
  CacheRetention = 1minute
  ActionOnPurge=Truncate   # This enables truncation after a volume has
been purged.
  FileRetention = 95days
  JobRetention = 95days
  VolumeRetention = 95days
}
Pool {
  Name = "B2-TD-Diff"
  ...
  FileRetention = 45days
  JobRetention = 45days
  VolumeRetention = 45days
}
Pool {
  Name = "B2-TD-Inc"
  ...
  FileRetention = 21days
  JobRetention = 21days
  VolumeRetention = 21days
}

Client {
  Name = "td-hostname-fd"
  Address = "td-hostname.local"
  FdPort = 9102
  Password = "REDACTED"
  Catalog = "MyCatalog"
  AutoPrune = yes
}

JobDefs {
  Name = "Synology-Local"
  Type = "Backup"
  Level = "Incremental"
  Messages = "Standard"
  AllowDuplicateJobs = no # We don't want duplicate jobs. What action is
taken is determined by the variables below.
  # See flowchart Figure 23.2 in Bacula 15.x Main manual, probably page 245
in the PDF.
  CancelLowerLevelDuplicates = yes # If a lower level job (example: inc) is
running or queued and a higher level job (Example: diff or full) is added
to the queue, then the lower level job will be cancelled.
  CancelQueuedDuplicates = yes # This will cancel any queued duplicate jobs.
  Pool = "Synology-Local-Inc"
  FullBackupPool = "Synology-Local-Full"
  IncrementalBackupPool = "Synology-Local-Inc"
  DifferentialBackupPool = "Synology-Local-Diff"
  Client = "td-bacula-fd"
  Fileset = "Windows-All-Drives-fs"
  Schedule = "Daily"
  WriteBootstrap = "/mnt/synology/bacula/BSR/%n.bsr"
  MaxFullInterval = 30days
  MaxDiffInterval = 7days
  SpoolAttributes = yes
  Priority = 10
  ReRunFailedLevels = yes # (if previous full or diff failed, current job
will be upgraded to match failed job's level). a failed job is defined as
one that has not terminated normally, which includes any running job of the
same name. Cannot allow duplicate queued jobs. Will also trigger on fileset
changes, regardless of whether you used 'ignorefilesetchanges'.
  RescheduleOnError = no
  Accurate = yes
}


Job {
  Name = "admin-prune-allpools-job"   # Step 1: prune, so volumes can be
truncated.
  Type = admin                        # step 2: truncate, so volumes are
reduced to their minimum size on disk.
  Level = Full
  Schedule = "Daily"
  Storage = "None"
  Fileset = "None"
  Pool = "None"
  JobDefs = "Synology-Local"
  Runscript {
     RunsWhen = before
     RunsOnClient = no  # Default yes, there is no client in an Admin job &
Admin Job RunScripts *only* run on the Director :)
     Command = "/opt/bacula/etc/prune-allpools.sh" # essentially, runs
"echo -e "prune volume allpools yes\nquit\n"  | bconsole -c
/path/to/bconsole.conf"
  }
  Priority = 1
}

Job {
  Name = "admin-truncate-volumes-job"   # Step 1: prune, so volumes can be
truncated.
  Type = admin                          # step 2: truncate, so volumes are
reduced to their minimum size on disk.
  Level = Full
  Schedule = "Daily"
  Storage = "None"
  Fileset = "None"
  Pool = "None"
  JobDefs = "Synology-Local"
  Runscript {
     RunsWhen = before
     RunsOnClient = no  # Default yes, there is no client in an Admin job &
Admin Job RunScripts *only* run on the Director :)
     Command = "/opt/bacula/etc/truncate-volumes.sh" # essentially, runs
(for each storage) "echo -e "truncate allpools
storage=$STORAGE-NAME\nquit\n" | bconsole -c /path/to/bconsole.conf
  }
  Priority = 2
}

Job {
  Name = "Backup-td-hostname-job"
  Level = "Incremental"
  Client = "td-hostname-fd"
  Fileset = "Windows-All-Drives-fs"
  Storage = "Synology-Local"
  Pool = "Synology-Local-Inc"
  JobDefs = "Synology-Local"
  Priority = 13   # each job has its own priority (job 1, priority 10, job
2, priority 11, etc). This is due to some issues with race conditions
related to MaximumVolumeJobs=1. If you don't use MaximumVolumeJobs=1 on
your local storage, you might not need to stagger job priorities like this.
  Schedule = "Daily"
}

Job {
  Name = "admin-copy-control-launcher-job"   # Launching copy control jobs
from a script so the 'pooluncopiedjobs' lookup will be fresh as of when the
daily backups have completed.
  Type = admin                               # Otherwise the jobs selected
for copy will date from when the copy control job was queued.
  Enabled = yes
  Level = Full
  Schedule = "Copy-End-Of-Day"   # no need for a separate schedule.
Priority will ensure this runs after backup jobs complete.
  Storage = "None"
  Fileset = "None"
  Pool = "None"
  JobDefs = "Synology-Local"
  Runscript {
     RunsWhen = before
     RunsOnClient = no  # Default yes, there is no client in an Admin job &
Admin Job RunScripts *only* run on the Director :)
     Command = "/opt/bacula/etc/copy-control-launcher.sh" # runs (for each
copy control job): echo -e "run job=$copy_control_LEVEL\nquit\n"  |
bconsole -c /path/to/bconsole.conf
  }
  Priority = 20
}

Job {
  Name = "Copy-Control-Full-job"   # Launching a different copy control job
for each backup level to prevent copy control jobs with different pools
from being cancelled as duplicates.
  Type = Copy
  Level = Full
  Client = td-bacula-fd
  Schedule = "Manual"
  FileSet = "None"
  Messages = Standard
  Pool = Synology-Local-Full
  Storage = "Synology-Local"
  Maximum Concurrent Jobs = 4
  Selection Type = PoolUncopiedJobs
  Priority = 21
  JobDefs = "Synology-Local"
}
Job {
  Name = "Copy-Control-Diff-job"   # Launching a different copy control job
for each backup level to prevent copy control jobs with different pools
from being cancelled as duplicates.
  ...
  Pool = Synology-Local-Diff
  ...
  Priority = 22
  ...
}
Job {
  Name = "Copy-Control-Inc-job"   # Launching a different copy control job
for each backup level to prevent copy control jobs with different pools
from being cancelled as duplicates.
  ...
  Pool = Synology-Local-Inc
  ...
  Priority = 23
  ...
}


Job {
  Name = "admin-cloud-volume-part-sweeper-job"
  Type = admin
  Level = Full
  Schedule = "NightlyAfterCopy" # it isn't necessary to use a different
schedule. Priority will ensure this runs at the right point in the process.
  Storage = "None"
  Fileset = "None"
  Pool = "None"
  JobDefs = "Synology-Local"
  Runscript {
     RunsWhen = before
     RunsOnClient = no  # Default yes, there is no client in an Admin job &
Admin Job RunScripts *only* run on the Director :)
     Command = "/opt/bacula/etc/cloud-volume-part-sweeper.sh" # Runs: echo
-e "cloud allpools storage=$STORAGE-RESOURCE upload\nquit\n" | bconsole -c
/path/to/bconsole.conf
  }
  Priority = 30
}


#####################
bacula-dir.conf snippet ends
#####################

After all this, then my DR tasks run, backing up conf files and volume
keys, then database.
My actual scripts are a LOT longer than the one liners, with a lot of
comments to remind me what things do. There is a bunch of error checking. I
am willing to share these scripts with folks on the list, but I haven't put
them on github or anything, and I'm a little concerned they could be
somewhat amateurish. If there is anything important, it's the cloud volume
part sweeper script. It has a lot of error checking after the fact, to make
sure volume parts really uploaded. The part upload sweeper exits 1 after
it's attempted to upload as many parts as possible, if it finds any
problems.

Let me know if you need more info.


Regards,
Robert Gerber
402-237-8692
[email protected]
_______________________________________________
Bacula-users mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/bacula-users

Reply via email to