4 \section*{Python Scripting}
5 \label{_ChapterStart60}
6 \index[general]{Python Scripting}
7 \index[general]{Scripting!Python}
8 \addcontentsline{toc}{section}{Python Scripting}
10 You may be asking what Python is and why a scripting language is
11 needed in Bacula. The answer to the first question is that Python
12 is an Object Oriented scripting language with features similar
13 to those found in Perl, but the syntax of the language is much
14 cleaner and simpler. The answer to why have scripting in Bacula is to
15 give the user more control over the whole backup process. Probably
16 the simplest example is when Bacula needs a new Volume name, with
17 a scripting language such as Python, you can generate any name
18 you want, based on the current state of Bacula.
20 \subsection*{Python Configuration}
21 \index[general]{Python Configuration}
22 \index[general]{Configuration!Python}
23 \addcontentsline{toc}{subsection}{Python Configuration}
25 Python must be enabled during the configuration process by adding
26 a \verb:--:with-python, and possibly specifying an alternate
27 directory if your Python is not installed in a standard system
28 location. If you are using RPMs you will need the python-devel package
31 When Python is configured, it becomes an integral part of Bacula and
32 runs in Bacula's address space, so even though it is an interpreted
33 language, it is very efficient.
35 When the Director starts, it looks to see if you have a {\bf
36 Scripts Directory} Directive defined (normal default {\bf
37 /etc/bacula/scripts}, if so, it looks in that directory for a file named
38 {\bf DirStartUp.py}. If it is found, Bacula will pass this file to Python
39 for execution. The {\bf Scripts Directory} is a new directive that you add
40 to the Director resource of your bacula-dir.conf file.
42 Note: Bacula does not install Python scripts by default because these
43 scripts are for you to program. This means that with a default
44 installation with Python enabled, Bacula will print the following error
48 09-Jun 15:14 bacula-dir: ERROR in pythonlib.c:131 Could not import
49 Python script /etc/bacula/scripts/DirStartUp. Python disabled.
52 The source code directory {\bf examples/python} contains sample scripts
53 for DirStartUp.py, SDStartUp.py, and FDStartUp.py that you might want
54 to use as a starting point. Normally, your scripts directory (at least
55 where you store the Python scripts) should be writable by Bacula, because
56 Python will attempt to write a compiled version of the scripts (e.g.
57 DirStartUp.pyc) back to that directory.
59 When starting with the sample scripts, you can delete any part that
60 you will not need, but you should keep all the Bacula Event and Job Event
61 definitions. If you do not want a particular event, simply replace the
62 existing code with a {\bf noop = 1}.
64 \subsection*{Bacula Events}
65 \index[general]{Bacula Events}
66 \index[general]{Events}
67 \addcontentsline{toc}{subsection}{Bacula Events}
68 A Bacula event is a point in the Bacula code where Bacula
69 will call a subroutine (actually a method) that you have
70 defined in the Python StartUp script. Events correspond
71 to some significant event such as a Job Start, a Job End,
72 Bacula needs a new Volume Name, ... When your script is
73 called, it will have access to all the Bacula variables
74 specific to the Job (attributes of the Job Object), and
75 it can even call some of the Job methods (subroutines)
76 or set new values in the Job attributes, such as the
77 Priority. You will see below how the events are used.
79 \subsection*{Python Objects}
80 \index[general]{Python Objects}
81 \index[general]{Objects!Python}
82 \addcontentsline{toc}{subsection}{Python Objects}
84 There are four Python objects that you will need to work with:
86 \item [The Bacula Object]
87 The Bacula object is created by the Bacula daemon (the Director
88 in the present case) when the daemon starts. It is available to
89 the Python startup script, {\bf DirStartup.py}, by importing the
90 Bacula definitions with {\bf import bacula}. The methods
91 available with this object are described below.
93 \item [The Bacula Events Class]
94 You create this class in the startup script, and you pass
95 it to the Bacula Object's {\bf set\_events} method. The
96 purpose of the Bacula Events Class is to define what global
97 or daemon events you want to monitor. When one of those events
98 occurs, your Bacula Events Class will be called at the method
99 corresponding to the event. There are currently three events,
100 JobStart, JobEnd, and Exit, which are described in detail below.
102 \item [The Job Object]
103 When a Job starts, and assuming you have defined a JobStart method
104 in your Bacula Events Class, Bacula will create a Job Object. This
105 object will be passed to the JobStart event. The Job Object has a
106 has good number of read-only members or attributes providing many
107 details of the Job, and it also has a number of writable attributes
108 that allow you to pass information into the Job. These attributes
111 \item [The Job Events Class]
112 You create this class in the JobStart method of your Bacula Events
113 class, and it allows you to define which of the possible Job Object
114 events you want to see. You must pass an instance of your Job Events
115 class to the Job Object set\_events() method.
116 Normally, you will probably only have one
117 Job Events Class, which will be instantiated for each Job. However,
118 if you wish to see different events in different Jobs, you may have
119 as many Job Events classes as you wish.
123 The first thing the startup script must do is to define what global Bacula
124 events (daemon events), it wants to see. This is done by creating a
125 Bacula Events class, instantiating it, then passing it to the
126 {\bf set\_events} method. There are three possible
131 \index[dir]{JobStart}
132 This Python method, if defined, will be called each time a Job is started.
133 The method is passed the class instantiation object as the first argument,
134 and the Bacula Job object as the second argument. The Bacula Job object
135 has several built-in methods, and you can define which ones you
136 want called. If you do not define this method, you will not be able
137 to interact with Bacula jobs.
140 This Python method, if defined, will be called each time a Job terminates.
141 The method is passed the class instantiation object as the first argument,
142 and the Bacula Job object as the second argument.
145 This Python method, if defined, will be called when the Director terminates.
146 The method is passed the class instantiation object as the first argument.
149 Access to the Bacula variables and methods is done with:
153 The following are the read-only attributes provided by the bacula object.
158 \item [Version] string consisting of "Version Build-date"
162 A simple definition of the Bacula Events Class might be the following:
168 def JobStart(self, job):
173 Then to instantiate the class and pass it to Bacula, you
178 bacula.set_events(BaculaEvents()) # register Bacula Events wanted
182 And at that point, each time a Job is started, your BaculaEvents JobStart
183 method will be called.
185 Now to actually do anything with a Job, you must define which Job events
186 you want to see, and this is done by defining a JobEvents class containing
187 the methods you want called. Each method name corresponds to one of the
188 Job Events that Bacula will generate.
190 A simple Job Events class might look like the following:
195 def NewVolume(self, job):
200 Here, your JobEvents class method NewVolume will be called each time
201 the Job needs a new Volume name. To actually register the events defined
202 in your class with the Job, you must instantiate the JobEvents class and
203 set it in the Job {\bf set\_events} variable. Note, this is a bit different
204 from how you registered the Bacula events. The registration process must
205 be done in the Bacula JobStart event (your method). So, you would modify
206 Bacula Events (not the Job events) as follows:
212 def JobStart(self, job):
213 events = JobEvents() # create instance of Job class
214 job.set_events(events) # register Job events desired
219 When a job event is triggered, the appropriate event definition is
220 called in the JobEvents class. This is the means by which your Python
221 script or code gets control. Once it has control, it may read job
222 attributes, or set them. See below for a list of read-only attributes,
223 and those that are writable.
225 In addition, the Bacula {\bf job} obbject in the Director has
226 a number of methods (subroutines) that can be called. They
229 \item [set\_events] The set\_events method takes a single
230 argument, which is the instantation of the Job Events class
231 that contains the methods that you want called. The method
232 names that will be called must correspond to the Bacula
233 defined events. You may define additional methods but Bacula
235 \item [run] The run method takes a single string
236 argument, which is the run command (same as in the Console)
237 that you want to submit to start a new Job. The value
238 returned by the run method is the JobId of the job that
239 started, or -1 if there was an error.
240 \item [write] The write method is used to be able to send
241 print output to the Job Report. This will be described later.
242 \item[cancel] The cancel method takes a single integer argument,
243 which is a JobId. If JobId is found, it will be canceled.
244 \item [DoesVolumeExist] The DoesVolumeExist method takes a single
245 string argument, which is the Volume name, and returns
246 1 if the volume exists in the Catalog and 0 if the volume
250 The following attributes are read/write within the Director
251 for the {\bf job} object.
254 \item [Priority] Read or set the Job priority.
255 Note, that setting a Job Priority is effective only before
256 the Job actually starts.
257 \item [Level] This attribute contains a string representing the Job
258 level, e.g. Full, Differential, Incremental, ... if read.
259 The level can also be set.
262 The following read-only attributes are available within the Director
263 for the {\bf job} object.
267 \item [Type] This attribute contains a string representing the Job
268 type, e.g. Backup, Restore, Verify, ...
269 \item [JobId] This attribute contains an integer representing the
271 \item [Client] This attribute contains a string with the name of the
273 \item [NumVols] This attribute contains an integer with the number of
274 Volumes in the Pool being used by the Job.
275 \item [Pool] This attribute contains a string with the name of the Pool
276 being used by the Job.
277 \item [Storage] This attribute contains a string with the name of the
278 Storage resource being used by the Job.
279 \item [Catalog] This attribute contains a string with the name of the
280 Catalog resource being used by the Job.
281 \item [MediaType] This attribute contains a string with the name of the
282 Media Type associated with the Storage resource being used by the Job.
283 \item [Job] This attribute contains a string containing the name of the
284 Job resource used by this job (not unique).
285 \item [JobName] This attribute contains a string representing the full
287 \item [JobStatus] This attribute contains a single character string
288 representing the current Job status. The status may change
289 during execution of the job.
290 \item [Priority] This attribute contains an integer with the priority
292 \item [CatalogRes] tuple consisting of (DBName, Address, User,
293 Password, Socket, Port, Database Vendor) taken from the Catalog resource
294 for the Job with the exception of Database Vendor, which is
295 one of the following: MySQL, PostgreSQL, SQLite, Internal,
296 depending on what database you configured.
298 After a Volume has been purged, this attribute will contain the
299 name of that Volume. At other times, this value may have no meaning.
302 The following write-only attributes are available within the
306 \item [JobReport] Send line to the Job Report.
307 \item [VolumeName] Set a new Volume name. Valid only during the
311 \subsection*{Python Console Command}
312 \index[general]{Python Console Command}
313 \index[general]{Console Command!Python}
314 \addcontentsline{toc}{subsection}{Python Console Command}
316 There is a new Console command named {\bf python}. It takes
317 a single argument {\bf restart}. Example:
322 This command restarts the Python interpreter in the Director.
323 This can be useful when you are modifying the DirStartUp script,
324 because normally Python will cache it, and thus the
325 script will be read one time.
328 \subsection*{Python Example}
329 \index[general]{Python Example}
330 \index[general]{Example!Python}
331 \addcontentsline{toc}{subsection}{Python Example}
333 An example script for the Director startup file is provided in
334 {\bf examples/python/DirStartup.py} as follows:
339 # Bacula Python interface script for the Director
342 # You must import both sys and bacula
345 # This is the list of Bacula daemon events that you
349 # Called here when a new Bacula Events class is
350 # is created. Normally not used
353 def JobStart(self, job):
355 Called here when a new job is started. If you want
356 to do anything with the Job, you must register
357 events you want to receive.
359 events = JobEvents() # create instance of Job class
360 events.job = job # save Bacula's job pointer
361 job.set_events(events) # register events desired
362 sys.stderr = events # send error output to Bacula
363 sys.stdout = events # send stdout to Bacula
364 jobid = job.JobId; client = job.Client
365 numvols = job.NumVols
366 job.JobReport="Python Dir JobStart: JobId=%d Client=%s NumVols=%d\n" % (jobid,client,numvols)
368 # Bacula Job is going to terminate
369 def JobEnd(self, job):
372 job.JobReport="Python Dir JobEnd output: JobId=%d Client=%s.\n" % (jobid, client)
374 # Called here when the Bacula daemon is going to exit
376 print "Daemon exiting."
378 bacula.set_events(BaculaEvents()) # register daemon events desired
381 These are the Job events that you can receive.
385 # Called here when you instantiate the Job. Not
390 # Called when the job is first scheduled
394 # Called just before running the job after initializing
395 # This is the point to change most Job parameters.
396 # It is equivalent to the JobRunBefore point.
399 def NewVolume(self, job):
400 # Called when Bacula wants a new Volume name. The Volume
401 # name returned, if any, must be stored in job.VolumeName
405 volname = "TestA-001"
406 job.JobReport = "JobId=%d Client=%s NumVols=%d VolumeName=%s" % (jobid, client, numvol,volname)
407 job.JobReport="Python before New Volume set for Job.\n"
408 job.VolumeName=volname
410 def VolumePurged(self, job):
411 # Called when a Volume is purged. The Volume name can be referenced
412 # with job.VolumeName