44df856b8dc05cfd6a7bcfaf3cd4da0e612cba62
[tools/mic.git] / mic / 3rdparty / pykickstart / sections.py
1 #
2 # sections.py:  Kickstart file sections.
3 #
4 # Chris Lumens <clumens@redhat.com>
5 #
6 # Copyright 2011 Red Hat, Inc.
7 #
8 # This copyrighted material is made available to anyone wishing to use, modify,
9 # copy, or redistribute it subject to the terms and conditions of the GNU
10 # General Public License v.2.  This program is distributed in the hope that it
11 # will be useful, but WITHOUT ANY WARRANTY expressed or implied, including the
12 # implied warranties of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
13 # See the GNU General Public License for more details.
14 #
15 # You should have received a copy of the GNU General Public License along with
16 # this program; if not, write to the Free Software Foundation, Inc., 51
17 # Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.  Any Red Hat
18 # trademarks that are incorporated in the source code or documentation are not
19 # subject to the GNU General Public License and may only be used or replicated
20 # with the express permission of Red Hat, Inc. 
21 #
22 """
23 This module exports the classes that define a section of a kickstart file.  A
24 section is a chunk of the file starting with a %tag and ending with a %end.
25 Examples of sections include %packages, %pre, and %post.
26
27 You may use this module to define your own custom sections which will be
28 treated just the same as a predefined one by the kickstart parser.  All that
29 is necessary is to create a new subclass of Section and call
30 parser.registerSection with an instance of your new class.
31 """
32 from constants import *
33 from options import KSOptionParser
34 from version import *
35
36 class Section(object):
37     """The base class for defining kickstart sections.  You are free to
38        subclass this as appropriate.
39
40        Class attributes:
41
42        allLines    -- Does this section require the parser to call handleLine
43                       for every line in the section, even blanks and comments?
44        sectionOpen -- The string that denotes the start of this section.  You
45                       must start your tag with a percent sign.
46        timesSeen   -- This attribute is for informational purposes only.  It is
47                       incremented every time handleHeader is called to keep
48                       track of the number of times a section of this type is
49                       seen.
50     """
51     allLines = False
52     sectionOpen = ""
53     timesSeen = 0
54
55     def __init__(self, handler, **kwargs):
56         """Create a new Script instance.  At the least, you must pass in an
57            instance of a baseHandler subclass.
58
59            Valid kwargs:
60
61            dataObj --
62         """
63         self.handler = handler
64
65         self.version = self.handler.version
66
67         self.dataObj = kwargs.get("dataObj", None)
68
69     def finalize(self):
70         """This method is called when the %end tag for a section is seen.  It
71            is not required to be provided.
72         """
73         pass
74
75     def handleLine(self, line):
76         """This method is called for every line of a section.  Take whatever
77            action is appropriate.  While this method is not required to be
78            provided, not providing it does not make a whole lot of sense.
79
80            Arguments:
81
82            line -- The complete line, with any trailing newline.
83         """
84         pass
85
86     def handleHeader(self, lineno, args):
87         """This method is called when the opening tag for a section is seen.
88            Not all sections will need this method, though all provided with
89            kickstart include one.
90
91            Arguments:
92
93            args -- A list of all strings passed as arguments to the section
94                    opening tag.
95         """
96         self.timesSeen += 1
97
98 class NullSection(Section):
99     """This defines a section that pykickstart will recognize but do nothing
100        with.  If the parser runs across a %section that has no object registered,
101        it will raise an error.  Sometimes, you may want to simply ignore those
102        sections instead.  This class is useful for that purpose.
103     """
104     def __init__(self, *args, **kwargs):
105         """Create a new NullSection instance.  You must pass a sectionOpen
106            parameter (including a leading '%') for the section you wish to
107            ignore.
108         """
109         Section.__init__(self, *args, **kwargs)
110         self.sectionOpen = kwargs.get("sectionOpen")
111
112 class ScriptSection(Section):
113     allLines = True
114
115     def __init__(self, *args, **kwargs):
116         Section.__init__(self, *args, **kwargs)
117         self._script = {}
118         self._resetScript()
119
120     def _getParser(self):
121         op = KSOptionParser(self.version)
122         op.add_option("--erroronfail", dest="errorOnFail", action="store_true",
123                       default=False)
124         op.add_option("--interpreter", dest="interpreter", default="/bin/sh")
125         op.add_option("--log", "--logfile", dest="log")
126         return op
127
128     def _resetScript(self):
129         self._script = {"interp": "/bin/sh", "log": None, "errorOnFail": False,
130                         "lineno": None, "chroot": False, "body": []}
131
132     def handleLine(self, line):
133         self._script["body"].append(line)
134
135     def finalize(self):
136         if " ".join(self._script["body"]).strip() == "":
137             return
138
139         kwargs = {"interp": self._script["interp"],
140                   "inChroot": self._script["chroot"],
141                   "lineno": self._script["lineno"],
142                   "logfile": self._script["log"],
143                   "errorOnFail": self._script["errorOnFail"],
144                   "type": self._script["type"]}
145
146         s = self.dataObj (self._script["body"], **kwargs)
147         self._resetScript()
148
149         if self.handler:
150             self.handler.scripts.append(s)
151
152     def handleHeader(self, lineno, args):
153         """Process the arguments to a %pre/%post/%traceback header for later
154            setting on a Script instance once the end of the script is found.
155            This method may be overridden in a subclass if necessary.
156         """
157         Section.handleHeader(self, lineno, args)
158         op = self._getParser()
159
160         (opts, extra) = op.parse_args(args=args[1:], lineno=lineno)
161
162         self._script["interp"] = opts.interpreter
163         self._script["lineno"] = lineno
164         self._script["log"] = opts.log
165         self._script["errorOnFail"] = opts.errorOnFail
166         if hasattr(opts, "nochroot"):
167             self._script["chroot"] = not opts.nochroot
168
169 class PreScriptSection(ScriptSection):
170     sectionOpen = "%pre"
171
172     def _resetScript(self):
173         ScriptSection._resetScript(self)
174         self._script["type"] = KS_SCRIPT_PRE
175
176 class PostScriptSection(ScriptSection):
177     sectionOpen = "%post"
178
179     def _getParser(self):
180         op = ScriptSection._getParser(self)
181         op.add_option("--nochroot", dest="nochroot", action="store_true",
182                       default=False)
183         return op
184
185     def _resetScript(self):
186         ScriptSection._resetScript(self)
187         self._script["chroot"] = True
188         self._script["type"] = KS_SCRIPT_POST
189
190 class TracebackScriptSection(ScriptSection):
191     sectionOpen = "%traceback"
192
193     def _resetScript(self):
194         ScriptSection._resetScript(self)
195         self._script["type"] = KS_SCRIPT_TRACEBACK
196
197 class PackageSection(Section):
198     sectionOpen = "%packages"
199
200     def handleLine(self, line):
201         if not self.handler:
202             return
203
204         (h, s, t) = line.partition('#')
205         line = h.rstrip()
206
207         self.handler.packages.add([line])
208
209     def handleHeader(self, lineno, args):
210         """Process the arguments to the %packages header and set attributes
211            on the Version's Packages instance appropriate.  This method may be
212            overridden in a subclass if necessary.
213         """
214         Section.handleHeader(self, lineno, args)
215         op = KSOptionParser(version=self.version)
216         op.add_option("--excludedocs", dest="excludedocs", action="store_true",
217                       default=False)
218         op.add_option("--ignoremissing", dest="ignoremissing",
219                       action="store_true", default=False)
220         op.add_option("--nobase", dest="nobase", action="store_true",
221                       default=False)
222         op.add_option("--ignoredeps", dest="resolveDeps", action="store_false",
223                       deprecated=FC4, removed=F9)
224         op.add_option("--resolvedeps", dest="resolveDeps", action="store_true",
225                       deprecated=FC4, removed=F9)
226         op.add_option("--default", dest="defaultPackages", action="store_true",
227                       default=False, introduced=F7)
228         op.add_option("--instLangs", dest="instLangs", type="string",
229                       default="", introduced=F9)
230
231         (opts, extra) = op.parse_args(args=args[1:], lineno=lineno)
232
233         self.handler.packages.excludeDocs = opts.excludedocs
234         self.handler.packages.addBase = not opts.nobase
235         if opts.ignoremissing:
236             self.handler.packages.handleMissing = KS_MISSING_IGNORE
237         else:
238             self.handler.packages.handleMissing = KS_MISSING_PROMPT
239
240         if opts.defaultPackages:
241             self.handler.packages.default = True
242
243         if opts.instLangs:
244             self.handler.packages.instLangs = opts.instLangs