]> git.sur5r.net Git - bacula/docs/blob - docs/manual/python.tex
Doc updates
[bacula/docs] / docs / manual / python.tex
1 %%
2 %%
3
4 \section*{Python Scripting}
5 \label{_ChapterStart60}
6 \index[general]{Python Scripting}
7 \index[general]{Scripting!Pyton}
8 \addcontentsline{toc}{section}{Python Scripting}
9
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.
19
20 \subsection*{Python Configuration}
21 \index[general]{Python Configuration}
22 \index[general]{Configuration!Python}
23 \addcontentsline{toc}{subsection}{Python Configuration}
24
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
29 installed.
30
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.
34
35 When the Director starts, it looks to see if you have a {\bf
36 Scripts Directory} defined, if so, it looks in that directory for
37 a file named {\bf DirStartUp}. If it is found, Bacula will pass this
38 file to Python for execution.
39
40 \subsection*{Bacula Evetns}
41 \index[general]{Bacula Events}
42 \index[general]{Events}
43 \addcontentsline{toc}{subsection}{Bacula Events}
44 A Bacula event is a point in the Bacula code where Bacula
45 will call a subroutine (actually a method) that you have 
46 defined in the Python StartUp script. Events correspond 
47 to some significant event such as a Job Start, a Job End,
48 Bacula needs a new Volume Name, ... When your script is
49 called, it will have access to all the Bacula variables
50 specific to the Job (attributes of the Job Object), and
51 it can even call some of the Job methods (subroutines)
52 or set new values in the Job attributes, such as the 
53 Priority. You will see below how the events are used.
54
55 \subsection*{Python Objects}
56 \index[general]{Python Objects}
57 \index[general]{Objects!Python}
58 \addcontentsline{toc}{subsection}{Python Objects}
59
60 There are four Python objects that you will need to work with:
61 \begin{description}
62 \item [The Bacula Object]
63    The Bacula object is created by the Bacula daemon (the Director
64    in the present case) when the daemon starts. It is available to
65    the Python startup script, {\bf DirStartup}, by importing the
66    Bacula definitions with {\bf import bacula}. The methods
67    available with this object are described below. 
68
69 \item [The Bacula Events Class]
70    You create this class in the startup script, and you pass
71    it to the Bacula Object's {\bf set_events} method. The 
72    purpose of the Bacula Events Class is to define what global
73    or daemon events you want to monitor. When one of those events
74    occurs, your Bacula Events Class will be called at the method
75    corresponding to the event. There are currently three events,
76    JobStart, JobEnd, and Exit, which are described in detail below.
77    
78 \item [The Job Object]
79    When a Job starts, and assuming you have defined a JobStart method
80    in your Bacula Events Class, Bacula will create a Job Object. This
81    object will be passed to the JobStart event. The Job Object has a
82    has good number of read-only members or attributes providing many
83    details of the Job, and it also has a number of writable attributes
84    that allow you to pass information into the Job.  These attributes
85    are described below.
86    
87 \item [The Job Events Class]
88    You create this class in the JobStart method of your Bacula Events
89    class, and it allows you to define which of the possible Job Object
90    events you want to see. You must pass an instance of your Job Events
91    class to the Job Object set_events() method.
92    Normally, you will probably only have one
93    Job Events Class, which will be instantiated for each Job. However,
94    if you wish to see different events in different Jobs, you may have
95    as many Job Events classes as you wish.
96 \end{description}
97
98
99 The first thing the startup script must do is to define what global Bacula
100 events (daemon events), it wants to see. This is done by creating a 
101 Bacula Events class, instantiating it, then passing it to the 
102 {\bf set_events} method. There are three possible
103 events.
104
105 \begin{description}
106 \item [JobStart]
107    \index[dir]{JobStart}
108    This Python method, if defined, will be called each time a Job is started.
109    The method is passed the class instantiation object as the first argument,
110    and the Bacula Job object as the second argument.  The Bacula Job object
111    has several built-in methods, and you can define which ones you
112    want called. If you do not define this method, you will not be able
113    to interact with Bacula jobs.
114
115 \item [JobEnd]
116    This Python method, if defined, will be called each time a Job terminates.
117    The method is passed the class instantiation object as the first argument,
118    and the Bacula Job object as the second argument.  
119
120 \item [Exit]
121    This Python method, if defined, will be called when the Director terminates.
122    The method is passed the class instantiation object as the first argument.
123 \end{description}
124
125 Access to the Bacula variables and methods is done with:
126
127      import bacula
128
129 A simple definition of the Bacula Events Class might be the following:
130
131 \footnotesize
132 \begin{verbatim}
133 import sys, bacula
134 class BaculaEvents:
135   def JobStart(self, job):
136      ...
137 \end{verbatim}
138 \normalsize
139
140 Then to instantiate the class and pass it to Bacula, you
141 would do:
142
143 \footnotesize
144 \begin{verbatim}
145 bacula.set_events(BaculaEvents()) # register Bacula Events wanted
146 \end{verbatim}
147 \normalsize
148
149 And at that point, each time a Job is started, your BaculaEvents JobStart
150 method will be called.
151
152 Now to actually do anything with a Job, you must define which Job events
153 you want to see, and this is done by defining a JobEvents class containing
154 the methods you want called.  Each method name corresponds to one of the
155 Job Events that Bacula will generate.
156
157 A simple Job Events class might look like the following:
158
159 \footnotesize
160 \begin{verbatim}
161 class JobEvents:
162   def NewVolume(self, job):
163      ...
164 \end{verbatim}
165 \normalsize
166
167 Here, your JobEvents class method NewVolume will be called each time
168 the Job needs a new Volume name.  To actually register the events defined
169 in your class with the Job, you must instantiate the JobEvents class and
170 set it in the Job {\be set_events} variable. Note, this is a bit different 
171 from how you registered the Bacula events. The registration process must
172 be done in the Bacula JobStart event (your method).  So, you would modify 
173 Bacula Events (not the Job events) as follows:
174
175 \footnotesize
176 \begin{verbatim}
177 import sys, bacula
178 class BaculaEvents:
179   def JobStart(self, job):
180      events = JobEvents()         # create instance of Job class
181      job.set_events(events)       # register Job events desired
182      ...
183 \end{verbatim}
184 \normalsize
185
186 The following are the methods (subroutines) provided within the
187 directory by the {\bf job} object.
188 \begin{description}
189 \item [set_events] The set_events takes a single
190 argument, which is the instantation of the Job Events class
191 that contains the methods that you want called. The method
192 names that will be called must correspond to the Bacula
193 defined events. You may define additional methods but Bacula
194 will not use them.
195 \item [run] The run method takes a single string
196 argument, which is the run command (same as in the Console)
197 that you want to submit to start a new Job. The value
198 returned by the run method is the JobId of the job that
199 started, or -1 if there was an error.
200 \item [write] The write method is used to be able to send
201 print output to the Job Report. This will be described later.
202 \end{description}
203
204 The following attributes are read/write within the Director 
205 for the {\bf job} object.
206
207 \begin{description}
208 \item [Priority] Read or set the Job priority.
209 Note, that a Job Priority is effective only before
210 the Job actually starts.
211 \end{description}
212
213 The following read-only attributes are available within the Director
214 for the {\bf job} object.
215
216 \begin{description}
217 \item [DirName] The name of the Director daemon.
218 \item [Level]
219 \item [Type]
220 \item [JobId]
221 \item [Client]
222 \item [NumVols]
223 \item [Pool]
224 \item [Storage]
225 \item [Catalog]
226 \item [MediaType]
227 \item [JobName]
228 \item [JobStatus]
229 \end{description}
230
231 The following write-only attributes are available within the
232 Director:
233
234 \begin{description}
235 \item [JobReport] Send line to the Job Report.
236 \item [VolumeName] Set a new Volume name. Valid only during the
237    NewVolume event.
238 \end{description}
239
240
241 An example script for the Director startup file is provided in
242 {\bf examples/python/DirStartup.py} as follows:
243
244 \footnotesize
245 \begin{verbatim}
246 #
247 # Bacula Python interface script for the Director
248 #
249
250 # You must import both sys and bacula
251 import sys, bacula
252
253 # This is the list of Bacula daemon events that you
254 #  can receive.
255 class BaculaEvents:
256   def __init__(self):
257      # Called here when a new Bacula Events class is
258      #  is created. Normally not used 
259      noop = 1
260
261   def JobStart(self, job):
262      """
263        Called here when a new job is started. If you want
264        to do anything with the Job, you must register
265        events you want to receive.
266      """
267      events = JobEvents()         # create instance of Job class
268      events.job = job             # save Bacula's job pointer
269      job.set_events(events)       # register events desired
270      sys.stderr = events          # send error output to Bacula
271      sys.stdout = events          # send stdout to Bacula
272      jobid = job.JobId; client = job.Client
273      numvols = job.NumVols 
274      job.JobReport="Python Dir JobStart: JobId=%d Client=%s NumVols=%d\n" % (jobid,client,numvols) 
275
276   # Bacula Job is going to terminate
277   def JobEnd(self, job):    
278      jobid = job.JobId
279      client = job.Client 
280      job.JobReport="Python Dir JobEnd output: JobId=%d Client=%s.\n" % (jobid, client) 
281
282   # Called here when the Bacula daemon is going to exit
283   def Exit(self, job):
284       print "Daemon exiting."
285      
286 bacula.set_events(BaculaEvents()) # register daemon events desired
287
288 """
289   These are the Job events that you can receive.
290 """
291 class JobEvents:
292   def __init__(self):
293      # Called here when you instantiate the Job. Not
294      # normally used
295      noop = 1
296      
297   def JobInit:
298      # Called when the job is first scheduled
299      noop = 1
300      
301   def JobRun:
302      # Called just before running the job after initializing
303      #  This is the point to change most Job parameters.
304      #  It is equivalent to the JobRunBefore point.
305      noop = 1
306
307   def NewVolume(self, job):
308      jobid = job.JobId
309      client = job.Client 
310      numvol = job.NumVols
311      volname = "TestA-001"
312      job.JobReport = "JobId=%d Client=%s NumVols=%d VolumeName=%s" % (jobid, client, numvol,volname)
313      job.JobReport="Python before New Volume set for Job.\n"
314      job.VolumeName=volname
315
316
317 \end{verbatim}
318 \normalsize