New version.
[pykickstart.git] / pykickstart / commands / logvol.py
blobf8d571a09c0b606845d62b93ed7fcf0f592a37d9
2 # Chris Lumens <clumens@redhat.com>
4 # Copyright 2005, 2006, 2007, 2008, 2012 Red Hat, Inc.
6 # This copyrighted material is made available to anyone wishing to use, modify,
7 # copy, or redistribute it subject to the terms and conditions of the GNU
8 # General Public License v.2. This program is distributed in the hope that it
9 # will be useful, but WITHOUT ANY WARRANTY expressed or implied, including the
10 # implied warranties of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
11 # See the GNU General Public License for more details.
13 # You should have received a copy of the GNU General Public License along with
14 # this program; if not, write to the Free Software Foundation, Inc., 51
15 # Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. Any Red Hat
16 # trademarks that are incorporated in the source code or documentation are not
17 # subject to the GNU General Public License and may only be used or replicated
18 # with the express permission of Red Hat, Inc.
20 from pykickstart.base import BaseData, KickstartCommand
21 from pykickstart.errors import KickstartParseError, KickstartValueError, formatErrorMsg
22 from pykickstart.options import KSOptionParser
24 import gettext
25 import warnings
26 _ = lambda x: gettext.ldgettext("pykickstart", x)
28 class FC3_LogVolData(BaseData):
29 removedKeywords = BaseData.removedKeywords
30 removedAttrs = BaseData.removedAttrs
32 def __init__(self, *args, **kwargs):
33 BaseData.__init__(self, *args, **kwargs)
34 self.fstype = kwargs.get("fstype", "")
35 self.grow = kwargs.get("grow", False)
36 self.maxSizeMB = kwargs.get("maxSizeMB", 0)
37 self.name = kwargs.get("name", "")
38 self.format = kwargs.get("format", True)
39 self.percent = kwargs.get("percent", 0)
40 self.recommended = kwargs.get("recommended", False)
41 self.size = kwargs.get("size", None)
42 self.preexist = kwargs.get("preexist", False)
43 self.vgname = kwargs.get("vgname", "")
44 self.mountpoint = kwargs.get("mountpoint", "")
46 def __eq__(self, y):
47 if not y:
48 return False
50 return self.vgname == y.vgname and self.name == y.name
52 def __ne__(self, y):
53 return not self == y
55 def _getArgsAsStr(self):
56 retval = ""
58 if self.fstype != "":
59 retval += " --fstype=\"%s\"" % self.fstype
60 if self.grow:
61 retval += " --grow"
62 if self.maxSizeMB > 0:
63 retval += " --maxsize=%d" % self.maxSizeMB
64 if not self.format:
65 retval += " --noformat"
66 if self.percent > 0:
67 retval += " --percent=%d" % self.percent
68 if self.recommended:
69 retval += " --recommended"
70 if self.size > 0:
71 retval += " --size=%d" % self.size
72 if self.preexist:
73 retval += " --useexisting"
75 return retval
77 def __str__(self):
78 retval = BaseData.__str__(self)
79 retval += "logvol %s %s --name=%s --vgname=%s\n" % (self.mountpoint, self._getArgsAsStr(), self.name, self.vgname)
80 return retval
82 class FC4_LogVolData(FC3_LogVolData):
83 removedKeywords = FC3_LogVolData.removedKeywords
84 removedAttrs = FC3_LogVolData.removedAttrs
86 def __init__(self, *args, **kwargs):
87 FC3_LogVolData.__init__(self, *args, **kwargs)
88 self.bytesPerInode = kwargs.get("bytesPerInode", 4096)
89 self.fsopts = kwargs.get("fsopts", "")
91 def _getArgsAsStr(self):
92 retval = FC3_LogVolData._getArgsAsStr(self)
94 if hasattr(self, "bytesPerInode") and self.bytesPerInode != 0:
95 retval += " --bytes-per-inode=%d" % self.bytesPerInode
96 if self.fsopts != "":
97 retval += " --fsoptions=\"%s\"" % self.fsopts
99 return retval
101 class RHEL5_LogVolData(FC4_LogVolData):
102 removedKeywords = FC4_LogVolData.removedKeywords
103 removedAttrs = FC4_LogVolData.removedAttrs
105 def __init__(self, *args, **kwargs):
106 FC4_LogVolData.__init__(self, *args, **kwargs)
107 self.encrypted = kwargs.get("encrypted", False)
108 self.passphrase = kwargs.get("passphrase", "")
110 def _getArgsAsStr(self):
111 retval = FC4_LogVolData._getArgsAsStr(self)
113 if self.encrypted:
114 retval += " --encrypted"
116 if self.passphrase != "":
117 retval += " --passphrase=\"%s\"" % self.passphrase
119 return retval
121 class F9_LogVolData(FC4_LogVolData):
122 removedKeywords = FC4_LogVolData.removedKeywords + ["bytesPerInode"]
123 removedAttrs = FC4_LogVolData.removedAttrs + ["bytesPerInode"]
125 def __init__(self, *args, **kwargs):
126 FC4_LogVolData.__init__(self, *args, **kwargs)
127 self.deleteRemovedAttrs()
129 self.fsopts = kwargs.get("fsopts", "")
130 self.fsprofile = kwargs.get("fsprofile", "")
131 self.encrypted = kwargs.get("encrypted", False)
132 self.passphrase = kwargs.get("passphrase", "")
134 def _getArgsAsStr(self):
135 retval = FC4_LogVolData._getArgsAsStr(self)
137 if self.fsprofile != "":
138 retval += " --fsprofile=\"%s\"" % self.fsprofile
139 if self.encrypted:
140 retval += " --encrypted"
142 if self.passphrase != "":
143 retval += " --passphrase=\"%s\"" % self.passphrase
145 return retval
147 class F12_LogVolData(F9_LogVolData):
148 removedKeywords = F9_LogVolData.removedKeywords
149 removedAttrs = F9_LogVolData.removedAttrs
151 def __init__(self, *args, **kwargs):
152 F9_LogVolData.__init__(self, *args, **kwargs)
153 self.deleteRemovedAttrs()
155 self.escrowcert = kwargs.get("escrowcert", "")
156 self.backuppassphrase = kwargs.get("backuppassphrase", False)
158 def _getArgsAsStr(self):
159 retval = F9_LogVolData._getArgsAsStr(self)
161 if self.encrypted and self.escrowcert != "":
162 retval += " --escrowcert=\"%s\"" % self.escrowcert
164 if self.backuppassphrase:
165 retval += " --backuppassphrase"
167 return retval
169 class RHEL6_LogVolData(F12_LogVolData):
170 removedKeywords = F12_LogVolData.removedKeywords
171 removedAttrs = F12_LogVolData.removedAttrs
173 def __init__(self, *args, **kwargs):
174 F12_LogVolData.__init__(self, *args, **kwargs)
176 self.cipher = kwargs.get("cipher", "")
177 self.hibernation = kwargs.get("hibernation", False)
179 def _getArgsAsStr(self):
180 retval = F12_LogVolData._getArgsAsStr(self)
182 if self.encrypted and self.cipher:
183 retval += " --cipher=\"%s\"" % self.cipher
184 if self.hibernation:
185 retval += " --hibernation"
187 return retval
189 F14_LogVolData = F12_LogVolData
191 class F15_LogVolData(F14_LogVolData):
192 removedKeywords = F14_LogVolData.removedKeywords
193 removedAttrs = F14_LogVolData.removedAttrs
195 def __init__(self, *args, **kwargs):
196 F14_LogVolData.__init__(self, *args, **kwargs)
197 self.label = kwargs.get("label", "")
199 def _getArgsAsStr(self):
200 retval = F14_LogVolData._getArgsAsStr(self)
202 if self.label != "":
203 retval += " --label=\"%s\"" % self.label
205 return retval
207 class F17_LogVolData(F15_LogVolData):
208 def __init__(self, *args, **kwargs):
209 F15_LogVolData.__init__(self, *args, **kwargs)
210 self.resize = kwargs.get("resize", False)
212 def _getArgsAsStr(self):
213 retval = F15_LogVolData._getArgsAsStr(self)
214 if self.resize:
215 retval += " --resize"
217 return retval
219 class F18_LogVolData(F17_LogVolData):
220 def __init__(self, *args, **kwargs):
221 F17_LogVolData.__init__(self, *args, **kwargs)
222 self.hibernation = kwargs.get("hibernation", False)
223 self.cipher = kwargs.get("cipher", "")
225 def _getArgsAsStr(self):
226 retval = F17_LogVolData._getArgsAsStr(self)
228 if self.hibernation:
229 retval += " --hibernation"
231 if self.encrypted and self.cipher:
232 retval += " --cipher=\"%s\"" % self.cipher
234 return retval
236 class F20_LogVolData(F18_LogVolData):
237 def __init__(self, *args, **kwargs):
238 F18_LogVolData.__init__(self, *args, **kwargs)
239 self.thin_pool = kwargs.get("thin_pool", False)
240 self.thin_volume = kwargs.get("thin_volume", False)
241 self.pool_name = kwargs.get("pool_name", "")
243 # these are only for thin pools
244 self.chunk_size = kwargs.get("chunk_size", None) # kilobytes
245 self.metadata_size = kwargs.get("metadata_size", None) # megabytes
247 def _getArgsAsStr(self):
248 retval = F18_LogVolData._getArgsAsStr(self)
250 if self.thin_pool:
251 retval += " --thinpool"
253 if self.metadata_size:
254 retval += " --metadatasize=%d" % self.metadata_size
256 if self.chunk_size:
257 retval += " --chunksize=%d" % self.chunk_size
259 if self.thin_volume:
260 retval += " --thin --poolname=%s" % self.pool_name
262 return retval
264 class FC3_LogVol(KickstartCommand):
265 removedKeywords = KickstartCommand.removedKeywords
266 removedAttrs = KickstartCommand.removedAttrs
268 def __init__(self, writePriority=133, *args, **kwargs):
269 KickstartCommand.__init__(self, writePriority, *args, **kwargs)
270 self.op = self._getParser()
272 self.lvList = kwargs.get("lvList", [])
274 def __str__(self):
275 retval = ""
277 for part in self.lvList:
278 retval += part.__str__()
280 return retval
282 def _getParser(self):
283 def lv_cb (option, opt_str, value, parser):
284 parser.values.format = False
285 parser.values.preexist = True
287 op = KSOptionParser()
288 op.add_option("--fstype", dest="fstype")
289 op.add_option("--grow", dest="grow", action="store_true",
290 default=False)
291 op.add_option("--maxsize", dest="maxSizeMB", action="store", type="int",
292 nargs=1)
293 op.add_option("--name", dest="name", required=1)
294 op.add_option("--noformat", action="callback", callback=lv_cb,
295 dest="format", default=True, nargs=0)
296 op.add_option("--percent", dest="percent", action="store", type="int",
297 nargs=1)
298 op.add_option("--recommended", dest="recommended", action="store_true",
299 default=False)
300 op.add_option("--size", dest="size", action="store", type="int",
301 nargs=1)
302 op.add_option("--useexisting", dest="preexist", action="store_true",
303 default=False)
304 op.add_option("--vgname", dest="vgname", required=1)
305 return op
307 def parse(self, args):
308 (opts, extra) = self.op.parse_args(args=args, lineno=self.lineno)
310 if len(extra) == 0:
311 raise KickstartValueError(formatErrorMsg(self.lineno, msg=_("Mount point required for %s") % "logvol"))
313 lvd = self.handler.LogVolData()
314 self._setToObj(self.op, opts, lvd)
315 lvd.lineno = self.lineno
316 lvd.mountpoint=extra[0]
318 # Check for duplicates in the data list.
319 if lvd in self.dataList():
320 warnings.warn(_("A logical volume with the name %s has already been defined in volume group %s.") % (lvd.name, lvd.vgname))
322 return lvd
324 def dataList(self):
325 return self.lvList
327 class FC4_LogVol(FC3_LogVol):
328 removedKeywords = FC3_LogVol.removedKeywords
329 removedAttrs = FC3_LogVol.removedAttrs
331 def _getParser(self):
332 op = FC3_LogVol._getParser(self)
333 op.add_option("--bytes-per-inode", dest="bytesPerInode", action="store",
334 type="int", nargs=1)
335 op.add_option("--fsoptions", dest="fsopts")
336 return op
338 class RHEL5_LogVol(FC4_LogVol):
339 removedKeywords = FC4_LogVol.removedKeywords
340 removedAttrs = FC4_LogVol.removedAttrs
342 def _getParser(self):
343 op = FC4_LogVol._getParser(self)
344 op.add_option("--encrypted", action="store_true", default=False)
345 op.add_option("--passphrase")
346 return op
348 class F9_LogVol(FC4_LogVol):
349 removedKeywords = FC4_LogVol.removedKeywords
350 removedAttrs = FC4_LogVol.removedAttrs
352 def _getParser(self):
353 op = FC4_LogVol._getParser(self)
354 op.add_option("--bytes-per-inode", deprecated=1)
355 op.add_option("--fsprofile", dest="fsprofile", action="store",
356 type="string", nargs=1)
357 op.add_option("--encrypted", action="store_true", default=False)
358 op.add_option("--passphrase")
359 return op
361 class F12_LogVol(F9_LogVol):
362 removedKeywords = F9_LogVol.removedKeywords
363 removedAttrs = F9_LogVol.removedAttrs
365 def _getParser(self):
366 op = F9_LogVol._getParser(self)
367 op.add_option("--escrowcert")
368 op.add_option("--backuppassphrase", action="store_true", default=False)
369 return op
371 class RHEL6_LogVol(F12_LogVol):
372 removedKeywords = F12_LogVol.removedKeywords
373 removedAttrs = F12_LogVol.removedAttrs
375 def _getParser(self):
376 op = F12_LogVol._getParser(self)
377 op.add_option("--cipher")
378 op.add_option("--hibernation", dest="hibernation", action="store_true",
379 default=False)
381 return op
383 def parse(self, args):
384 # call the overriden method
385 retval = F12_LogVol.parse(self, args)
386 # the logvol command can't be used together with the autopart command
387 # due to the hard to debug behavior their combination introduces
388 if self.handler.autopart.seen:
389 errorMsg = _("The logvol and autopart commands can't be used at the same time")
390 raise KickstartParseError(formatErrorMsg(self.lineno, msg=errorMsg))
391 return retval
393 class F14_LogVol(F12_LogVol):
394 removedKeywords = F12_LogVol.removedKeywords
395 removedAttrs = F12_LogVol.removedAttrs
397 def _getParser(self):
398 op = F12_LogVol._getParser(self)
399 op.remove_option("--bytes-per-inode")
400 return op
402 class F15_LogVol(F14_LogVol):
403 removedKeywords = F14_LogVol.removedKeywords
404 removedAttrs = F14_LogVol.removedAttrs
406 def _getParser(self):
407 op = F14_LogVol._getParser(self)
408 op.add_option("--label")
409 return op
411 class F17_LogVol(F15_LogVol):
412 def _getParser(self):
413 op = F15_LogVol._getParser(self)
414 op.add_option("--resize", action="store_true", default=False)
415 return op
417 def parse(self, args):
418 retval = F15_LogVol.parse(self, args)
420 if retval.resize and not retval.preexist:
421 raise KickstartParseError(formatErrorMsg(self.lineno, msg=_("--resize can only be used in conjunction with --useexisting")))
423 if retval.resize and not retval.size:
424 raise KickstartParseError(formatErrorMsg(self.lineno, msg=_("--resize requires --size to indicate new size")))
426 return retval
428 class F18_LogVol(F17_LogVol):
429 def _getParser(self):
430 op = F17_LogVol._getParser(self)
431 op.add_option("--hibernation", action="store_true", default=False)
432 op.add_option("--cipher")
433 return op
435 class F20_LogVol(F18_LogVol):
436 def _getParser(self):
437 op = F18_LogVol._getParser(self)
438 op.add_option("--thinpool", action="store_true", dest="thin_pool",
439 default=False)
440 op.add_option("--thin", action="store_true", dest="thin_volume",
441 default=False)
442 op.add_option("--poolname", dest="pool_name")
443 op.add_option("--chunksize", type="int", dest="chunk_size")
444 op.add_option("--metadatasize", type="int", dest="metadata_size")
445 return op
447 def parse(self, args):
448 retval = F18_LogVol.parse(self, args)
450 if retval.thin_volume and retval.thin_pool:
451 err = formatErrorMsg(self.lineno,
452 msg=_("--thin and --thinpool cannot both be "
453 "specified for the same logvol"))
454 raise KickstartParseError(err)
456 if retval.thin_volume and not retval.pool_name:
457 err = formatErrorMsg(self.lineno,
458 msg=_("--thin requires --poolname to specify "
459 "pool name"))
460 raise KickstartParseError(err)
462 if (retval.chunk_size or retval.metadata_size) and \
463 not retval.thin_pool:
464 err = formatErrorMsg(self.lineno,
465 msg=_("--chunksize and --metadatasize are "
466 "for thin pools only"))
467 raise KickstartParseError(err)
469 # the logvol command can't be used together with the autopart command
470 # due to the hard to debug behavior their combination introduces
471 if self.handler.autopart.seen:
472 errorMsg = _("The logvol and autopart commands can't be used at the same time")
473 raise KickstartParseError(formatErrorMsg(self.lineno, msg=errorMsg))
475 return retval