Merge "Another method of install tpk." into devel
[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 errors import *
34 from options import KSOptionParser
35 from version import *
36
37 class Section(object):
38     """The base class for defining kickstart sections.  You are free to
39        subclass this as appropriate.
40
41        Class attributes:
42
43        allLines    -- Does this section require the parser to call handleLine
44                       for every line in the section, even blanks and comments?
45        sectionOpen -- The string that denotes the start of this section.  You
46                       must start your tag with a percent sign.
47        timesSeen   -- This attribute is for informational purposes only.  It is
48                       incremented every time handleHeader is called to keep
49                       track of the number of times a section of this type is
50                       seen.
51     """
52     allLines = False
53     sectionOpen = ""
54     timesSeen = 0
55
56     def __init__(self, handler, **kwargs):
57         """Create a new Script instance.  At the least, you must pass in an
58            instance of a baseHandler subclass.
59
60            Valid kwargs:
61
62            dataObj --
63         """
64         self.handler = handler
65
66         self.version = self.handler.version
67
68         self.dataObj = kwargs.get("dataObj", None)
69
70     def finalize(self):
71         """This method is called when the %end tag for a section is seen.  It
72            is not required to be provided.
73         """
74         pass
75
76     def handleLine(self, line):
77         """This method is called for every line of a section.  Take whatever
78            action is appropriate.  While this method is not required to be
79            provided, not providing it does not make a whole lot of sense.
80
81            Arguments:
82
83            line -- The complete line, with any trailing newline.
84         """
85         pass
86
87     def handleHeader(self, lineno, args):
88         """This method is called when the opening tag for a section is seen.
89            Not all sections will need this method, though all provided with
90            kickstart include one.
91
92            Arguments:
93
94            args -- A list of all strings passed as arguments to the section
95                    opening tag.
96         """
97         self.timesSeen += 1
98
99 class NullSection(Section):
100     """This defines a section that pykickstart will recognize but do nothing
101        with.  If the parser runs across a %section that has no object registered,
102        it will raise an error.  Sometimes, you may want to simply ignore those
103        sections instead.  This class is useful for that purpose.
104     """
105     def __init__(self, *args, **kwargs):
106         """Create a new NullSection instance.  You must pass a sectionOpen
107            parameter (including a leading '%') for the section you wish to
108            ignore.
109         """
110         Section.__init__(self, *args, **kwargs)
111         self.sectionOpen = kwargs.get("sectionOpen")
112
113 class ScriptSection(Section):
114     allLines = True
115
116     def __init__(self, *args, **kwargs):
117         Section.__init__(self, *args, **kwargs)
118         self._script = {}
119         self._resetScript()
120
121     def _getParser(self):
122         op = KSOptionParser(self.version)
123         op.add_option("--erroronfail", dest="errorOnFail", action="store_true",
124                       default=False)
125         op.add_option("--interpreter", dest="interpreter", default="/bin/sh")
126         op.add_option("--log", "--logfile", dest="log")
127         return op
128
129     def _resetScript(self):
130         self._script = {"interp": "/bin/sh", "log": None, "errorOnFail": False,
131                         "lineno": None, "chroot": False, "body": []}
132
133     def handleLine(self, line):
134         self._script["body"].append(line)
135
136     def finalize(self):
137         if " ".join(self._script["body"]).strip() == "":
138             return
139
140         kwargs = {"interp": self._script["interp"],
141                   "inChroot": self._script["chroot"],
142                   "lineno": self._script["lineno"],
143                   "logfile": self._script["log"],
144                   "errorOnFail": self._script["errorOnFail"],
145                   "type": self._script["type"]}
146
147         s = self.dataObj (self._script["body"], **kwargs)
148         self._resetScript()
149
150         if self.handler:
151             self.handler.scripts.append(s)
152
153     def handleHeader(self, lineno, args):
154         """Process the arguments to a %pre/%post/%traceback header for later
155            setting on a Script instance once the end of the script is found.
156            This method may be overridden in a subclass if necessary.
157         """
158         Section.handleHeader(self, lineno, args)
159         op = self._getParser()
160
161         (opts, extra) = op.parse_args(args=args[1:], lineno=lineno)
162
163         self._script["interp"] = opts.interpreter
164         self._script["lineno"] = lineno
165         self._script["log"] = opts.log
166         self._script["errorOnFail"] = opts.errorOnFail
167         if hasattr(opts, "nochroot"):
168             self._script["chroot"] = not opts.nochroot
169
170 class PreScriptSection(ScriptSection):
171     sectionOpen = "%pre"
172
173     def _resetScript(self):
174         ScriptSection._resetScript(self)
175         self._script["type"] = KS_SCRIPT_PRE
176
177 class PostScriptSection(ScriptSection):
178     sectionOpen = "%post"
179
180     def _getParser(self):
181         op = ScriptSection._getParser(self)
182         op.add_option("--nochroot", dest="nochroot", action="store_true",
183                       default=False)
184         return op
185
186     def _resetScript(self):
187         ScriptSection._resetScript(self)
188         self._script["chroot"] = True
189         self._script["type"] = KS_SCRIPT_POST
190
191 class TracebackScriptSection(ScriptSection):
192     sectionOpen = "%traceback"
193
194     def _resetScript(self):
195         ScriptSection._resetScript(self)
196         self._script["type"] = KS_SCRIPT_TRACEBACK
197
198 class RunScriptSection(ScriptSection):
199     sectionOpen = "%runscript"
200
201     def _resetScript(self):
202         ScriptSection._resetScript(self)
203         self._script["type"] = KS_SCRIPT_RUN
204
205     def finalize(self):
206         ScriptSection.finalize(self)
207         if self.handler:
208             for s in self.handler.scripts:
209                 if s.type == KS_SCRIPT_UMOUNT:
210                     raise KickstartError("%runscript and %post-umount " \
211                                          "can not be defined together")
212
213 class PostUmountScriptSection(ScriptSection):
214     sectionOpen = "%post-umount"
215
216     def _resetScript(self):
217         ScriptSection._resetScript(self)
218         self._script["type"] = KS_SCRIPT_UMOUNT
219
220     def finalize(self):
221         ScriptSection.finalize(self)
222         if self.handler:
223             for s in self.handler.scripts:
224                 if s.type == KS_SCRIPT_RUN:
225                     raise KickstartError("%runscript and %post-umount " \
226                                          "can not be defined together")
227
228 class PackageSection(Section):
229     sectionOpen = "%packages"
230
231     def handleLine(self, line):
232         if not self.handler:
233             return
234
235         (h, s, t) = line.partition('#')
236         line = h.rstrip()
237         self.handler.packages.add([line])
238
239     def handleHeader(self, lineno, args):
240         """Process the arguments to the %packages header and set attributes
241            on the Version's Packages instance appropriate.  This method may be
242            overridden in a subclass if necessary.
243         """
244         Section.handleHeader(self, lineno, args)
245         op = KSOptionParser(version=self.version)
246         op.add_option("--excludedocs", dest="excludedocs", action="store_true",
247                       default=False)
248         op.add_option("--ignoremissing", dest="ignoremissing",
249                       action="store_true", default=False)
250         op.add_option("--nobase", dest="nobase", action="store_true",
251                       default=False)
252         op.add_option("--ignoredeps", dest="resolveDeps", action="store_false",
253                       deprecated=FC4, removed=F9)
254         op.add_option("--resolvedeps", dest="resolveDeps", action="store_true",
255                       deprecated=FC4, removed=F9)
256         op.add_option("--default", dest="defaultPackages", action="store_true",
257                       default=False, introduced=F7)
258         op.add_option("--instLangs", dest="instLangs", type="string",
259                       default="", introduced=F9)
260
261         (opts, extra) = op.parse_args(args=args[1:], lineno=lineno)
262
263         self.handler.packages.excludeDocs = opts.excludedocs
264         self.handler.packages.addBase = not opts.nobase
265         if opts.ignoremissing:
266             self.handler.packages.handleMissing = KS_MISSING_IGNORE
267         else:
268             self.handler.packages.handleMissing = KS_MISSING_PROMPT
269
270         if opts.defaultPackages:
271             self.handler.packages.default = True
272
273         if opts.instLangs:
274             self.handler.packages.instLangs = opts.instLangs
275
276 class TpkPackageSection(Section):
277     sectionOpen = "%tpk_packages"
278
279     def handleLine(self, line):
280         if not self.handler:
281             return
282
283         (h, s, t) = line.partition('#')
284         line = h.rstrip()
285         self.handler.tpk_packages.add([line])
286
287     def handleHeader(self, lineno, args):
288         """Process the arguments to the %tpk_packages header and set attributes
289            on the Version's TpkPackages instance appropriate.  This method may be
290            overridden in a subclass if necessary.
291         """
292         Section.handleHeader(self, lineno, args)