Add support for specifying thin pool profile
[pykickstart.git] / pykickstart / sections.py
blobbc592ff0c2e88d33b50fa43a4f4ff6b69f7e89da
2 # sections.py: Kickstart file sections.
4 # Chris Lumens <clumens@redhat.com>
6 # Copyright 2011-2014 Red Hat, Inc.
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.
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.
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.
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 KickstartParseError, formatErrorMsg
34 from options import KSOptionParser
35 from version import *
37 import gettext
38 _ = lambda x: gettext.ldgettext("pykickstart", x)
40 class Section(object):
41 """The base class for defining kickstart sections. You are free to
42 subclass this as appropriate.
44 Class attributes:
46 allLines -- Does this section require the parser to call handleLine
47 for every line in the section, even blanks and comments?
48 sectionOpen -- The string that denotes the start of this section. You
49 must start your tag with a percent sign.
50 timesSeen -- This attribute is for informational purposes only. It is
51 incremented every time handleHeader is called to keep
52 track of the number of times a section of this type is
53 seen.
54 """
55 allLines = False
56 sectionOpen = ""
57 timesSeen = 0
59 def __init__(self, handler, **kwargs):
60 """Create a new Script instance. At the least, you must pass in an
61 instance of a baseHandler subclass.
63 Valid kwargs:
65 dataObj --
66 """
67 self.handler = handler
69 self.version = self.handler.version
71 self.dataObj = kwargs.get("dataObj", None)
73 def finalize(self):
74 """This method is called when the %end tag for a section is seen. It
75 is not required to be provided.
76 """
77 pass
79 def handleLine(self, line):
80 """This method is called for every line of a section. Take whatever
81 action is appropriate. While this method is not required to be
82 provided, not providing it does not make a whole lot of sense.
84 Arguments:
86 line -- The complete line, with any trailing newline.
87 """
88 pass
90 def handleHeader(self, lineno, args):
91 """This method is called when the opening tag for a section is seen.
92 Not all sections will need this method, though all provided with
93 kickstart include one.
95 Arguments:
97 args -- A list of all strings passed as arguments to the section
98 opening tag.
99 """
100 self.timesSeen += 1
102 @property
103 def seen(self):
104 """This property is given for consistency with KickstartCommand objects
105 only. It simply returns whether timesSeen is non-zero.
107 return self.timesSeen > 0
109 class NullSection(Section):
110 """This defines a section that pykickstart will recognize but do nothing
111 with. If the parser runs across a %section that has no object registered,
112 it will raise an error. Sometimes, you may want to simply ignore those
113 sections instead. This class is useful for that purpose.
115 def __init__(self, *args, **kwargs):
116 """Create a new NullSection instance. You must pass a sectionOpen
117 parameter (including a leading '%') for the section you wish to
118 ignore.
120 Section.__init__(self, *args, **kwargs)
121 self.sectionOpen = kwargs.get("sectionOpen")
123 class ScriptSection(Section):
124 allLines = True
126 def __init__(self, *args, **kwargs):
127 Section.__init__(self, *args, **kwargs)
128 self._script = {}
129 self._resetScript()
131 def _getParser(self):
132 op = KSOptionParser(self.version)
133 op.add_option("--erroronfail", dest="errorOnFail", action="store_true",
134 default=False)
135 op.add_option("--interpreter", dest="interpreter", default="/bin/sh")
136 op.add_option("--log", "--logfile", dest="log")
137 return op
139 def _resetScript(self):
140 self._script = {"interp": "/bin/sh", "log": None, "errorOnFail": False,
141 "lineno": None, "chroot": False, "body": []}
143 def handleLine(self, line):
144 self._script["body"].append(line)
146 def finalize(self):
147 if " ".join(self._script["body"]).strip() == "":
148 return
150 kwargs = {"interp": self._script["interp"],
151 "inChroot": self._script["chroot"],
152 "lineno": self._script["lineno"],
153 "logfile": self._script["log"],
154 "errorOnFail": self._script["errorOnFail"],
155 "type": self._script["type"]}
157 s = self.dataObj (self._script["body"], **kwargs)
158 self._resetScript()
160 if self.handler:
161 self.handler.scripts.append(s)
163 def handleHeader(self, lineno, args):
164 """Process the arguments to a %pre/%post/%traceback header for later
165 setting on a Script instance once the end of the script is found.
166 This method may be overridden in a subclass if necessary.
168 Section.handleHeader(self, lineno, args)
169 op = self._getParser()
171 (opts, extra) = op.parse_args(args=args[1:], lineno=lineno)
173 self._script["interp"] = opts.interpreter
174 self._script["lineno"] = lineno
175 self._script["log"] = opts.log
176 self._script["errorOnFail"] = opts.errorOnFail
177 if hasattr(opts, "nochroot"):
178 self._script["chroot"] = not opts.nochroot
180 class PreScriptSection(ScriptSection):
181 sectionOpen = "%pre"
183 def _resetScript(self):
184 ScriptSection._resetScript(self)
185 self._script["type"] = KS_SCRIPT_PRE
187 class PostScriptSection(ScriptSection):
188 sectionOpen = "%post"
190 def _getParser(self):
191 op = ScriptSection._getParser(self)
192 op.add_option("--nochroot", dest="nochroot", action="store_true",
193 default=False)
194 return op
196 def _resetScript(self):
197 ScriptSection._resetScript(self)
198 self._script["chroot"] = True
199 self._script["type"] = KS_SCRIPT_POST
201 class TracebackScriptSection(ScriptSection):
202 sectionOpen = "%traceback"
204 def _resetScript(self):
205 ScriptSection._resetScript(self)
206 self._script["type"] = KS_SCRIPT_TRACEBACK
208 class PackageSection(Section):
209 sectionOpen = "%packages"
211 def handleLine(self, line):
212 if not self.handler:
213 return
215 (h, s, t) = line.partition('#')
216 line = h.rstrip()
218 self.handler.packages.add([line])
220 def handleHeader(self, lineno, args):
221 """Process the arguments to the %packages header and set attributes
222 on the Version's Packages instance appropriate. This method may be
223 overridden in a subclass if necessary.
225 Section.handleHeader(self, lineno, args)
226 op = KSOptionParser(version=self.version)
227 op.add_option("--excludedocs", dest="excludedocs", action="store_true",
228 default=False)
229 op.add_option("--ignoremissing", dest="ignoremissing",
230 action="store_true", default=False)
231 op.add_option("--nobase", dest="nobase", action="store_true",
232 default=False, deprecated=F18)
233 op.add_option("--nocore", dest="nocore", action="store_true",
234 default=False, introduced=RHEL7)
235 op.add_option("--ignoredeps", dest="resolveDeps", action="store_false",
236 deprecated=FC4, removed=F9)
237 op.add_option("--resolvedeps", dest="resolveDeps", action="store_true",
238 deprecated=FC4, removed=F9)
239 op.add_option("--default", dest="defaultPackages", action="store_true",
240 default=False, introduced=F7)
241 op.add_option("--instLangs", dest="instLangs", type="string",
242 default="", introduced=F9)
243 op.add_option("--multilib", dest="multiLib", action="store_true",
244 default=False, introduced=F18)
246 (opts, extra) = op.parse_args(args=args[1:], lineno=lineno)
248 if opts.defaultPackages and opts.nobase:
249 raise KickstartParseError(formatErrorMsg(lineno, msg=_("--default and --nobase cannot be used together")))
250 elif opts.defaultPackages and opts.nocore:
251 raise KickstartParseError(formatErrorMsg(lineno, msg=_("--default and --nocore cannot be used together")))
253 self.handler.packages.excludeDocs = opts.excludedocs
254 self.handler.packages.addBase = not opts.nobase
255 if opts.ignoremissing:
256 self.handler.packages.handleMissing = KS_MISSING_IGNORE
257 else:
258 self.handler.packages.handleMissing = KS_MISSING_PROMPT
260 if opts.defaultPackages:
261 self.handler.packages.default = True
263 if opts.instLangs:
264 self.handler.packages.instLangs = opts.instLangs
266 self.handler.packages.nocore = opts.nocore
267 self.handler.packages.multiLib = opts.multiLib
268 self.handler.packages.seen = True