Recently I had some trouble to get bacula’s copy jobs running. Here are my experiences.
By the way: There are no differences between copy and migrate jobs in terms of configuration (except for the job type in the job resource of bacula-dir.conf), so you can use this little tutorial for both of them.
First of all you need to realize that bacula’s copy jobs do not run automatically, no matter how you run or configure them. Even though it would be a nice idea to have a copy job run automatically after the corresponding backup job has finished (e.g. to transfer the backed up files from disk to tape), bacula does not support this feature yet. You have to run the copy job yourself after the corresponding backup job has finished. But how do you do this?
My first approach was to start the copy job one minute after the original backup job has started. Consider the following scenario in your bacula-dir.conf:
Job {
Name = "Backup1"
Type = Backup
Schedule = "DailyCycle"
...
}
Job {
Name = "Copy1"
Type = Copy
Schedule = "DailyCycleCopy"
Priority 100
...
}
Schedule {
Name = "DailyCycle"
Run = Full mon-sun at 20:00
}
Schedule {
Name = "DailyCycleCopy"
Run = Full mon-sun at 20:01
}
In this example, the copy job runs one minute after the corresponding backup job (assuming that all other settings e.g. for the pool and storage resources are done right). But it WON’T work. Yes, the copy job starts one minute after the backup job, and because of its lower priority (100 is a lower priority than the default 10) it waits until the backup job has finished and does not run in parallel. But the copy job cannot find the backup job. It might find the backup job from the day before, or it might terminate immediately without doing anything. Maybe it has to do with the database update of the backup job that will take too long. So the copy job runs before the backup job has updated the database. In my case I was using a local MySQL database for the bacula server installation.
Next I was stumbling across the “Run = …” keyword in the job resource. It is supposed to run another job right before its own job. I was doing something like this:
Job {
Name = "Backup1"
Type = Backup
...
}
Job {
Name = "Copy1"
Type = Copy
Run = "Backup1"
Schedule = "DailyCycle"
Priority 100
...
}
Again because of its lower priority, the copy job should first start the backup job, wait until the backup job has finished and then start itself. I don’t know how the Run directive should work. But for me it was not working at all. The backup job did not start at all, and the copy job terminated immediately without doing anything.
Last I was following some advice from the internet and tried using the RunScript directive:
Job {
Name = "Backup1"
Type = Backup
Schedule = "DailyCycle"
RunScript {
Command = "echo 'run job=Copy1 yes' | bconsole'"
RunsWhen = After
RunsOnFailure = No
RunsOnSuccess = Yes
RunsOnClient = No
}
...
}
Job {
Name = "Copy1"
Type = Copy
...
}
First it did not work either. This is because of the pipe symbol “|” in the Command directive. I had to change it to point to an external shell script wrapper without using any special characters:
...
RunScript {
Command = "/etc/bacula/startJob.sh Copy1"
...
/etc/bacula/startJob.sh:
#!/bin/bash
echo "run job=$1 yes " | bconsole
Here we go. Finally copy jobs were working. The backup job was starting at the scheduled time. After finishing successfully it runs the external shell script which in turn starts the copy job. There is enough time for the backup job to finish, so the copy job recognizes the just finished backup job and transfers its data to tape.
I was using bacula version 5.2.x. Maybe this behaviour will change in future bacula versions.