Adding documentation, already in progress.
[pykickstart.git] / docs / programmers-guide
blob43be63e78a186971a6670eb3020021d0831a9752
3                         pykickstart Programmer's Guide
5                                by Chris Lumens
7                               October  14, 2005
10 Introduction
11 ============
12 pykickstart is a Python library for manipulating kickstart files.  It
13 contains a common data representation, a parser, and a writer.  This
14 library aims to be useful for all Python programs that need to work with
15 kickstart files.  The two most obvious examples are anaconda and
16 system-config-kickstart.  It is recommended that all other tools that need
17 to use kickstart files use this library so that we can maintain equivalent
18 levels of support across all tools.
20 The kickstart file format itself has only been defined in a rather ad-hoc
21 manner.  Various documents describe the format, commands, and their
22 effects.  However, each kickstart-related program implemented its own
23 parser.  As anaconda added support for new commands and options, other
24 programs drifted farther and farther out of sync with the "official"
25 format.  This leads to the problem that valid kickstart files are not
26 accepted by all programs, or that programs will strip out options it
27 doesn't understand so that the input and output files do not match.
29 pykickstart is an effort to correct this.  It was originally designed to
30 be a common code base for anaconda and system-config-kickstart, so making
31 the code generic and easily extendable were top priorities.  Another
32 priority was to formalize the currently recognized grammar in an easily
33 understood parser so that files that used to work would continue to.  I
34 believe these goals have been met.
36 This document will cover how to use pykickstart in your programs and how to
37 extend the basic parser to get customized behavior.  It includes a
38 description of the important classes and several working examples.
41 Getting Started
42 ===============
43 Before diving into the full documentation, it is useful to see an example
44 of how simple it is to use the default pykickstart in your programs.  Here
45 is a code snippet that imports the required classes, parses a kickstart
46 file, and leaves the results in the common data format.
48         #!/usr/bin/python
49         from pykickstart.data import *
50         from pykickstart.parser import *
52         ksdata = KickstartData()
53         kshandlers = KickstartHandlers(ksdata)
54         ksparser = KickstartParser(ksdata, kshandlers)
55         ksparser.readKickstart("ks.cfg")
57 The call to readKickstart() reads in the kickstart file and sets values in
58 ksdata.  After this call, you don't need kshandlers or ksparser anymore
59 but you will want to hold on to ksdata if you are interested in the
60 contents of the file.  If you want to do some manipulations and then write
61 out the results to a new file, that's as simple as:
63         from pykickstart.writer import KickstartWriter
64         kswriter = KickstartWriter(ksdata)
65         outfile = open("out.cfg", 'w")
66         outfile.write(kswriter.write())
67         outfile.close()
70 Classes
71 =======
72 The important classes that make up pykickstart are spread across a handful
73 of files.
75 constants.py
76 ------------
77 This file includes no classes, though it does include several important
78 constants representing various things in the KickstartData.  You should
79 import its contents like so:
81         from pykickstart.constants import *
83 data.py
84 -------
85 This file contains the classes that make up the common data
86 representation.  The center of the data format is the KickstartData class,
87 which contains many attributes representing the values from the input
88 file.  When a new KickstartData is instantiated, these attributes are set
89 to appropriate default values.  Some attributes are a simple string or
90 boolean, while some are a list of other classes or dictionaries.  For the
91 most part, each lines up with a single kickstart command.
93 The KickstartLogVolData, KickstartNetworkData, KickstartPartData,
94 KickstartRaidData, and KickstartVolGroupData classes are contained as list
95 elements in KickstartData.  Each corresponds to a command that may appear
96 multiple times.  They exist as separate classes so that attributes are
97 guaranteed to exist.
99 There are three different types of scripts - pre, post, and traceback -
100 but all are represented in the kickstart data by a single list.  The
101 Script class is contained in parser.py and contains an attribute that may
102 be used to discriminate between classes.
104 The install package list, excluded package list, and install groups list
105 are kept as separate.  Excluded packages have the leading "-" stripped
106 off, and groups have the leading "@" stripped.
108 See the class reference at the end of this documentation for a brief
109 explanation of useful functions in each class.
111 parser.py
112 ---------
113 This file represents the bulk of pykickstart code.
115 writer.py
116 ---------
117 This file contains the class that makes up the Kickstart writer.  The job
118 of this class is to take a KickstartData object and convert it into a
119 string.  This string should be a valid kickstart file that can then be
120 used in any program.  Ideally, it should be the same as the input file
121 though the order of options may have been shifted, as well as other
122 cosmetic differences.
124 It is important to note that KickstartWriter.write returns a string, but
125 does no file output.
127 See the class reference at the end of this documentation for a brief
128 explanation of useful functions in each class.
131 Class Reference
132 ===============
133 class DeprecatedOption:
134     def __init__ ():
135         Creates a new Option type that supports a "deprecated" option
136         attribute.  Command options with deprecated=1 will still be
137         processed, but will raise a DeprecationWarning that may be logged.
139 class KickstartData:
140     def __init__ ():
141         Creates a new KickstartData object and sets default values on
142         attributes.
144 class KickstartError:
145     def __init__ (val):
146         Creates a new KickstartError exception object with the given val
147         as the message.  This is a generic exception.
149 class KickstartHandlers:
150     def __init__ (ksdata):
151         Creates a new KickstartHandlers object and initializes the handler
152         dictionary to point at the default handlers.
154     def resetHandlers ():
155         Clears each handler to None.  This can be used to quickly clear
156         out the handlers before setting only the handlers a subclass is
157         interested in.
159     def deprecatedCommand (cmd):
160         Uses the Python warnings framework to issue a DeprecationWarning
161         for the given command keyword.
163     handlers:
164         A dictionary mapping commands to handling methods.  Individual
165         handlers may be set to None, in which case the command will be
166         ignored.  A subclass may override any or all of the handlers,
167         though each one should call the superclass's method to ensure the
168         ksdata is correct.  The default handlers only set ksdata.
170 class KickstartLogVolData:
171     def __init__ ():
172         Creates a new KickstartLogVolData object and sets default values
173         on attributes.  Instances of this class should be appended to
174         KickstartData.logVolList.
176 class KickstartNetworkData:
177     def __init__ ():
178         Creates a new KickstartNetworkData object and sets default values
179         on attributes.  Instances of this class should be appended to
180         KickstartData.networkList.
182 class KickstartParser:
183     def __init__ (ksdata, kshandlers):
184         Creates a new KickstartParser object and initializes the parser
185         state.  kshandlers may be None, in which case no function will be
186         run when a kickstart command is seen in the input file.
188     def addScript ():
189         Called when the parser determines that it has found the end of
190         a script section and should add the script to the ksdata's list.
191         This method may be overriden if specialized behavior is required,
192         though the superclass's method should still be called to make sure
193         the script ends up in the ksdata.
195     def addPackages (line):
196         Called while in the %packages section.  Takes a line from the
197         file, determines whether it is a group, package, or excluded
198         package, and adds it to the correct list in the ksdata.  This
199         method may be overriden if specialized behavior is required,
200         though the superclass's method should still be called to make sure
201         the package lists in the ksdata are correct.
203     def handleCommand (cmd, args):
204         Called while in the commands section.  Takes a line from the
205         file, gets the commands from the head of the line, and dispatches
206         the correct method from the KickstartHandlers.  If the
207         KickstartParser object is created with kshandlers=None, no method
208         will be called for the command but no error will be raised.  This
209         method may be overridden if specialized behavior is needed.
211     def handlePackageHdr (args):
212         Called when the %packages section header is first seen.  Handles
213         the options that may be given to %packages and sets these values
214         in the ksdata.  This method may be overridden if specialized
215         behavior is needed, though the superclass's method should still be
216         called.
218     def handleScriptHdr (args):
219         Called when one of the script headers - %pre, %post, or %traceback -
220         is first seen.  Handles the optiosn that may be given to those
221         sections headers and sets those falues in the internal script
222         representation.  This method may be overridden if specialized
223         behavior is needed, though the superclass's method should still be
224         called.
226     def readKickstart (file):
227         Parse the input file.  This method reads the input file, switches
228         between states, and calls the handlers listed above.  This
229         method should not need to be overridden by any subclass as it
230         defines the kickstart file format.
232     followIncludes:
233         Defaults to True.  Set to False if you don't want %include
234         files to be parsed as well.
236 class KickstartParseError:
237     def __init__ (line):
238         Creates a new KickstartParseError exception object.  The message
239         will include line, which should be the line in the kickstart file
240         that caused a parse error.
242 class KickstartPartData:
243     def __init__ ():
244         Creates a new KickstartPartData object and sets default values
245         on attributes.  Instances of this class should be appended to
246         KickstartData.partList.
248 class KickstartRaidData:
249     def __init__ ():
250         Creates a new KickstartRaidData object and sets default values
251         on attributes.  Instances of this class should be appended to
252         KickstartData.raidList.
254 class KickstartValueError:
255     def __init (val):
256         Creates a new KickstartValueError exception object corresponding
257         to a problem with the provided val.
259 class KickstartVolGroupData:
260     def __init__ ():
261         Creates a new KickstartVolGroupData object and sets default values
262         on attributes.  Instances of this class should be appended to
263         KickstartData.volGroupList.
265 class KickstartWriter:
266     def __init__ (ksdata):
267         Creates a new KickstartWriter object and initializes the order
268         KickstartData options should be printed out in.
270     def write ():
271         Returns a valid kickstart file generated from ksdata as a string
272         that is suitable for writing out to a file.
274 class KSOptionParser:
275     def __init__ (map=[]):
276         Creates a specialized subclass of python's OptionParser making use
277         of the MappableOption, RequiredOption, and DeprecatedOption
278         classes.  This class is used within command handlers and should
279         not need to be subclassed unless extremely complex behavior is
280         required.  The map option is needed if this object will have any
281         MappableOption instances.
283 class MappableOption:
284     def __init__ ():
285         Creates a new Option type that supports a "map" action.  A map
286         action on a given option stores into the destination the value
287         given by:
289                 KSOptionParser.map[key]
291         where key is the option with leading dashes stripped off.
293         This also adds a "map_extend" action.  A map_extend action on
294         a given set of options appends to the destination the value
295         given by:
297                 KSOptionParser.map[key]
299         where key is the option with leading dashes stripped off.
301 class RequiredOption:
302     def __init__ ():
303         Creates a new Option type that supports a "required" option
304         attribute.  Command options with required=1 must be provided or
305         an OptionError exception is raised.
307 class Script:
308     def __init__ (script, interp="/bin/sh", inChroot=False, logfile=None,
309                   errorOnFail=False, type=KS_SCRIPT_PRE):
310         Creates a new Script object and sets the defaults for a %pre
311         script.  inChroot only makes sense for %post scripts.
313     def __repr__ ():
314         Returns a string representation of the script useful for debugging
315         output.
317     def write ():
318         Returns a valid kickstart file script generated from ksdata as a
319         string that is suitable for writing out to a file.  This string
320         includes the script header.