summaryrefslogtreecommitdiffstats
path: root/scripts/lib/mic/kickstart/__init__.py
diff options
context:
space:
mode:
Diffstat (limited to 'scripts/lib/mic/kickstart/__init__.py')
-rw-r--r--scripts/lib/mic/kickstart/__init__.py892
1 files changed, 892 insertions, 0 deletions
diff --git a/scripts/lib/mic/kickstart/__init__.py b/scripts/lib/mic/kickstart/__init__.py
new file mode 100644
index 0000000000..f9a53343d1
--- /dev/null
+++ b/scripts/lib/mic/kickstart/__init__.py
@@ -0,0 +1,892 @@
1#!/usr/bin/python -tt
2#
3# Copyright (c) 2007 Red Hat, Inc.
4# Copyright (c) 2009, 2010, 2011 Intel, Inc.
5#
6# This program is free software; you can redistribute it and/or modify it
7# under the terms of the GNU General Public License as published by the Free
8# Software Foundation; version 2 of the License
9#
10# This program is distributed in the hope that it will be useful, but
11# WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
12# or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
13# for more details.
14#
15# You should have received a copy of the GNU General Public License along
16# with this program; if not, write to the Free Software Foundation, Inc., 59
17# Temple Place - Suite 330, Boston, MA 02111-1307, USA.
18
19import os, sys, re
20import shutil
21import subprocess
22import string
23
24import pykickstart.sections as kssections
25import pykickstart.commands as kscommands
26import pykickstart.constants as ksconstants
27import pykickstart.errors as kserrors
28import pykickstart.parser as ksparser
29import pykickstart.version as ksversion
30from pykickstart.handlers.control import commandMap
31from pykickstart.handlers.control import dataMap
32
33from mic import msger
34from mic.utils import errors, misc, runner, fs_related as fs
35from custom_commands import desktop, micrepo, micboot, partition, installerfw
36
37
38AUTH_URL_PTN = r"(?P<scheme>.*)://(?P<username>.*)(:?P<password>.*)?@(?P<url>.*)"
39
40
41class PrepackageSection(kssections.Section):
42 sectionOpen = "%prepackages"
43
44 def handleLine(self, line):
45 if not self.handler:
46 return
47
48 (h, s, t) = line.partition('#')
49 line = h.rstrip()
50
51 self.handler.prepackages.add([line])
52
53 def handleHeader(self, lineno, args):
54 kssections.Section.handleHeader(self, lineno, args)
55
56class AttachmentSection(kssections.Section):
57 sectionOpen = "%attachment"
58
59 def handleLine(self, line):
60 if not self.handler:
61 return
62
63 (h, s, t) = line.partition('#')
64 line = h.rstrip()
65
66 self.handler.attachment.add([line])
67
68 def handleHeader(self, lineno, args):
69 kssections.Section.handleHeader(self, lineno, args)
70
71def apply_wrapper(func):
72 def wrapper(*kargs, **kwargs):
73 try:
74 func(*kargs, **kwargs)
75 except (OSError, IOError, errors.KsError), err:
76 cfgcls = kargs[0].__class__.__name__
77 if msger.ask("Failed to apply %s, skip and continue?" % cfgcls):
78 msger.warning("%s" % err)
79 pass
80 else:
81 # just throw out the exception
82 raise
83 return wrapper
84
85def read_kickstart(path):
86 """Parse a kickstart file and return a KickstartParser instance.
87
88 This is a simple utility function which takes a path to a kickstart file,
89 parses it and returns a pykickstart KickstartParser instance which can
90 be then passed to an ImageCreator constructor.
91
92 If an error occurs, a CreatorError exception is thrown.
93 """
94
95 #version = ksversion.makeVersion()
96 #ks = ksparser.KickstartParser(version)
97
98 using_version = ksversion.DEVEL
99 commandMap[using_version]["desktop"] = desktop.Mic_Desktop
100 commandMap[using_version]["repo"] = micrepo.Mic_Repo
101 commandMap[using_version]["bootloader"] = micboot.Mic_Bootloader
102 commandMap[using_version]["part"] = partition.Mic_Partition
103 commandMap[using_version]["partition"] = partition.Mic_Partition
104 commandMap[using_version]["installerfw"] = installerfw.Mic_installerfw
105 dataMap[using_version]["RepoData"] = micrepo.Mic_RepoData
106 dataMap[using_version]["PartData"] = partition.Mic_PartData
107 superclass = ksversion.returnClassForVersion(version=using_version)
108
109 class KSHandlers(superclass):
110 def __init__(self):
111 superclass.__init__(self, mapping=commandMap[using_version])
112 self.prepackages = ksparser.Packages()
113 self.attachment = ksparser.Packages()
114
115 ks = ksparser.KickstartParser(KSHandlers(), errorsAreFatal=False)
116 ks.registerSection(PrepackageSection(ks.handler))
117 ks.registerSection(AttachmentSection(ks.handler))
118
119 try:
120 ks.readKickstart(path)
121 except (kserrors.KickstartParseError, kserrors.KickstartError), err:
122 if msger.ask("Errors occured on kickstart file, skip and continue?"):
123 msger.warning("%s" % err)
124 pass
125 else:
126 raise errors.KsError("%s" % err)
127
128 return ks
129
130class KickstartConfig(object):
131 """A base class for applying kickstart configurations to a system."""
132 def __init__(self, instroot):
133 self.instroot = instroot
134
135 def path(self, subpath):
136 return self.instroot + subpath
137
138 def _check_sysconfig(self):
139 if not os.path.exists(self.path("/etc/sysconfig")):
140 fs.makedirs(self.path("/etc/sysconfig"))
141
142 def chroot(self):
143 os.chroot(self.instroot)
144 os.chdir("/")
145
146 def call(self, args):
147 if not os.path.exists("%s/%s" %(self.instroot, args[0])):
148 raise errors.KsError("Can't find %s in chroot" % args[0])
149 subprocess.call(args, preexec_fn = self.chroot)
150
151 def apply(self):
152 pass
153
154class LanguageConfig(KickstartConfig):
155 """A class to apply a kickstart language configuration to a system."""
156 @apply_wrapper
157 def apply(self, kslang):
158 self._check_sysconfig()
159 if kslang.lang:
160 f = open(self.path("/etc/sysconfig/i18n"), "w+")
161 f.write("LANG=\"" + kslang.lang + "\"\n")
162 f.close()
163
164class KeyboardConfig(KickstartConfig):
165 """A class to apply a kickstart keyboard configuration to a system."""
166 @apply_wrapper
167 def apply(self, kskeyboard):
168 #
169 # FIXME:
170 # should this impact the X keyboard config too?
171 # or do we want to make X be able to do this mapping?
172 #
173 #k = rhpl.keyboard.Keyboard()
174 #if kskeyboard.keyboard:
175 # k.set(kskeyboard.keyboard)
176 #k.write(self.instroot)
177 pass
178
179class TimezoneConfig(KickstartConfig):
180 """A class to apply a kickstart timezone configuration to a system."""
181 @apply_wrapper
182 def apply(self, kstimezone):
183 self._check_sysconfig()
184 tz = kstimezone.timezone or "America/New_York"
185 utc = str(kstimezone.isUtc)
186
187 f = open(self.path("/etc/sysconfig/clock"), "w+")
188 f.write("ZONE=\"" + tz + "\"\n")
189 f.write("UTC=" + utc + "\n")
190 f.close()
191 tz_source = "/usr/share/zoneinfo/%s" % (tz)
192 tz_dest = "/etc/localtime"
193 try:
194 cpcmd = fs.find_binary_inchroot('cp', self.instroot)
195 if cpcmd:
196 self.call([cpcmd, "-f", tz_source, tz_dest])
197 else:
198 cpcmd = fs.find_binary_path('cp')
199 subprocess.call([cpcmd, "-f",
200 self.path(tz_source),
201 self.path(tz_dest)])
202 except (IOError, OSError), (errno, msg):
203 raise errors.KsError("Timezone setting error: %s" % msg)
204
205class AuthConfig(KickstartConfig):
206 """A class to apply a kickstart authconfig configuration to a system."""
207 @apply_wrapper
208 def apply(self, ksauthconfig):
209 auth = ksauthconfig.authconfig or "--useshadow --enablemd5"
210 args = ["/usr/share/authconfig/authconfig.py", "--update", "--nostart"]
211 self.call(args + auth.split())
212
213class FirewallConfig(KickstartConfig):
214 """A class to apply a kickstart firewall configuration to a system."""
215 @apply_wrapper
216 def apply(self, ksfirewall):
217 #
218 # FIXME: should handle the rest of the options
219 #
220 if not os.path.exists(self.path("/usr/sbin/lokkit")):
221 return
222 if ksfirewall.enabled:
223 status = "--enabled"
224 else:
225 status = "--disabled"
226
227 self.call(["/usr/sbin/lokkit",
228 "-f", "--quiet", "--nostart", status])
229
230class RootPasswordConfig(KickstartConfig):
231 """A class to apply a kickstart root password configuration to a system."""
232 def unset(self):
233 self.call(["/usr/bin/passwd", "-d", "root"])
234
235 def set_encrypted(self, password):
236 self.call(["/usr/sbin/usermod", "-p", password, "root"])
237
238 def set_unencrypted(self, password):
239 for p in ("/bin/echo", "/usr/sbin/chpasswd"):
240 if not os.path.exists("%s/%s" %(self.instroot, p)):
241 raise errors.KsError("Unable to set unencrypted password due "
242 "to lack of %s" % p)
243
244 p1 = subprocess.Popen(["/bin/echo", "root:%s" %password],
245 stdout = subprocess.PIPE,
246 preexec_fn = self.chroot)
247 p2 = subprocess.Popen(["/usr/sbin/chpasswd", "-m"],
248 stdin = p1.stdout,
249 stdout = subprocess.PIPE,
250 preexec_fn = self.chroot)
251 p2.communicate()
252
253 @apply_wrapper
254 def apply(self, ksrootpw):
255 if ksrootpw.isCrypted:
256 self.set_encrypted(ksrootpw.password)
257 elif ksrootpw.password != "":
258 self.set_unencrypted(ksrootpw.password)
259 else:
260 self.unset()
261
262class UserConfig(KickstartConfig):
263 def set_empty_passwd(self, user):
264 self.call(["/usr/bin/passwd", "-d", user])
265
266 def set_encrypted_passwd(self, user, password):
267 self.call(["/usr/sbin/usermod", "-p", "%s" % password, user])
268
269 def set_unencrypted_passwd(self, user, password):
270 for p in ("/bin/echo", "/usr/sbin/chpasswd"):
271 if not os.path.exists("%s/%s" %(self.instroot, p)):
272 raise errors.KsError("Unable to set unencrypted password due "
273 "to lack of %s" % p)
274
275 p1 = subprocess.Popen(["/bin/echo", "%s:%s" %(user, password)],
276 stdout = subprocess.PIPE,
277 preexec_fn = self.chroot)
278 p2 = subprocess.Popen(["/usr/sbin/chpasswd", "-m"],
279 stdin = p1.stdout,
280 stdout = subprocess.PIPE,
281 preexec_fn = self.chroot)
282 p2.communicate()
283
284 def addUser(self, userconfig):
285 args = [ "/usr/sbin/useradd" ]
286 if userconfig.groups:
287 args += [ "--groups", string.join(userconfig.groups, ",") ]
288 if userconfig.name:
289 args += [ "-m"]
290 args += [ "-d", "/home/%s" % userconfig.name ]
291 args.append(userconfig.name)
292 try:
293 dev_null = os.open("/dev/null", os.O_WRONLY)
294 msger.debug('adding user with %s' % args)
295 subprocess.call(args,
296 stdout = dev_null,
297 stderr = dev_null,
298 preexec_fn = self.chroot)
299 os.close(dev_null)
300 except:
301 msger.warning('Cannot add user using "useradd"')
302
303 if userconfig.password not in (None, ""):
304 if userconfig.isCrypted:
305 self.set_encrypted_passwd(userconfig.name,
306 userconfig.password)
307 else:
308 self.set_unencrypted_passwd(userconfig.name,
309 userconfig.password)
310 else:
311 self.set_empty_passwd(userconfig.name)
312 else:
313 raise errors.KsError("Invalid kickstart command: %s" \
314 % userconfig.__str__())
315
316 @apply_wrapper
317 def apply(self, user):
318 for userconfig in user.userList:
319 self.addUser(userconfig)
320
321class ServicesConfig(KickstartConfig):
322 """A class to apply a kickstart services configuration to a system."""
323 @apply_wrapper
324 def apply(self, ksservices):
325 if not os.path.exists(self.path("/sbin/chkconfig")):
326 return
327 for s in ksservices.enabled:
328 self.call(["/sbin/chkconfig", s, "on"])
329 for s in ksservices.disabled:
330 self.call(["/sbin/chkconfig", s, "off"])
331
332class XConfig(KickstartConfig):
333 """A class to apply a kickstart X configuration to a system."""
334 @apply_wrapper
335 def apply(self, ksxconfig):
336 if ksxconfig.startX and os.path.exists(self.path("/etc/inittab")):
337 f = open(self.path("/etc/inittab"), "rw+")
338 buf = f.read()
339 buf = buf.replace("id:3:initdefault", "id:5:initdefault")
340 f.seek(0)
341 f.write(buf)
342 f.close()
343 if ksxconfig.defaultdesktop:
344 self._check_sysconfig()
345 f = open(self.path("/etc/sysconfig/desktop"), "w")
346 f.write("DESKTOP="+ksxconfig.defaultdesktop+"\n")
347 f.close()
348
349class DesktopConfig(KickstartConfig):
350 """A class to apply a kickstart desktop configuration to a system."""
351 @apply_wrapper
352 def apply(self, ksdesktop):
353 if ksdesktop.defaultdesktop:
354 self._check_sysconfig()
355 f = open(self.path("/etc/sysconfig/desktop"), "w")
356 f.write("DESKTOP="+ksdesktop.defaultdesktop+"\n")
357 f.close()
358 if os.path.exists(self.path("/etc/gdm/custom.conf")):
359 f = open(self.path("/etc/skel/.dmrc"), "w")
360 f.write("[Desktop]\n")
361 f.write("Session="+ksdesktop.defaultdesktop.lower()+"\n")
362 f.close()
363 if ksdesktop.session:
364 if os.path.exists(self.path("/etc/sysconfig/uxlaunch")):
365 f = open(self.path("/etc/sysconfig/uxlaunch"), "a+")
366 f.write("session="+ksdesktop.session.lower()+"\n")
367 f.close()
368 if ksdesktop.autologinuser:
369 self._check_sysconfig()
370 f = open(self.path("/etc/sysconfig/desktop"), "a+")
371 f.write("AUTOLOGIN_USER=" + ksdesktop.autologinuser + "\n")
372 f.close()
373 if os.path.exists(self.path("/etc/gdm/custom.conf")):
374 f = open(self.path("/etc/gdm/custom.conf"), "w")
375 f.write("[daemon]\n")
376 f.write("AutomaticLoginEnable=true\n")
377 f.write("AutomaticLogin=" + ksdesktop.autologinuser + "\n")
378 f.close()
379
380class MoblinRepoConfig(KickstartConfig):
381 """A class to apply a kickstart desktop configuration to a system."""
382 def __create_repo_section(self, repo, type, fd):
383 baseurl = None
384 mirrorlist = None
385 reposuffix = {"base":"", "debuginfo":"-debuginfo", "source":"-source"}
386 reponame = repo.name + reposuffix[type]
387 if type == "base":
388 if repo.baseurl:
389 baseurl = repo.baseurl
390 if repo.mirrorlist:
391 mirrorlist = repo.mirrorlist
392
393 elif type == "debuginfo":
394 if repo.baseurl:
395 if repo.baseurl.endswith("/"):
396 baseurl = os.path.dirname(os.path.dirname(repo.baseurl))
397 else:
398 baseurl = os.path.dirname(repo.baseurl)
399 baseurl += "/debug"
400
401 if repo.mirrorlist:
402 variant = repo.mirrorlist[repo.mirrorlist.find("$"):]
403 mirrorlist = repo.mirrorlist[0:repo.mirrorlist.find("$")]
404 mirrorlist += "debug" + "-" + variant
405
406 elif type == "source":
407 if repo.baseurl:
408 if repo.baseurl.endswith("/"):
409 baseurl = os.path.dirname(
410 os.path.dirname(
411 os.path.dirname(repo.baseurl)))
412 else:
413 baseurl = os.path.dirname(os.path.dirname(repo.baseurl))
414 baseurl += "/source"
415
416 if repo.mirrorlist:
417 variant = repo.mirrorlist[repo.mirrorlist.find("$"):]
418 mirrorlist = repo.mirrorlist[0:repo.mirrorlist.find("$")]
419 mirrorlist += "source" + "-" + variant
420
421 fd.write("[" + reponame + "]\n")
422 fd.write("name=" + reponame + "\n")
423 fd.write("failovermethod=priority\n")
424 if baseurl:
425 auth_url = re.compile(AUTH_URL_PTN)
426 m = auth_url.match(baseurl)
427 if m:
428 baseurl = "%s://%s" % (m.group('scheme'), m.group('url'))
429 fd.write("baseurl=" + baseurl + "\n")
430 if mirrorlist:
431 fd.write("mirrorlist=" + mirrorlist + "\n")
432 """ Skip saving proxy settings """
433 #if repo.proxy:
434 # fd.write("proxy=" + repo.proxy + "\n")
435 #if repo.proxy_username:
436 # fd.write("proxy_username=" + repo.proxy_username + "\n")
437 #if repo.proxy_password:
438 # fd.write("proxy_password=" + repo.proxy_password + "\n")
439 if repo.gpgkey:
440 fd.write("gpgkey=" + repo.gpgkey + "\n")
441 fd.write("gpgcheck=1\n")
442 else:
443 fd.write("gpgcheck=0\n")
444 if type == "source" or type == "debuginfo" or repo.disable:
445 fd.write("enabled=0\n")
446 else:
447 fd.write("enabled=1\n")
448 fd.write("\n")
449
450 def __create_repo_file(self, repo, repodir):
451 fs.makedirs(self.path(repodir))
452 f = open(self.path(repodir + "/" + repo.name + ".repo"), "w")
453 self.__create_repo_section(repo, "base", f)
454 if repo.debuginfo:
455 self.__create_repo_section(repo, "debuginfo", f)
456 if repo.source:
457 self.__create_repo_section(repo, "source", f)
458 f.close()
459
460 @apply_wrapper
461 def apply(self, ksrepo, repodata, repourl):
462 for repo in ksrepo.repoList:
463 if repo.name in repourl:
464 repo.baseurl = repourl[repo.name]
465 if repo.save:
466 #self.__create_repo_file(repo, "/etc/yum.repos.d")
467 self.__create_repo_file(repo, "/etc/zypp/repos.d")
468 """ Import repo gpg keys """
469 if repodata:
470 for repo in repodata:
471 if repo['repokey']:
472 runner.quiet(['rpm',
473 "--root=%s" % self.instroot,
474 "--import",
475 repo['repokey']])
476
477class RPMMacroConfig(KickstartConfig):
478 """A class to apply the specified rpm macros to the filesystem"""
479 @apply_wrapper
480 def apply(self, ks):
481 if not ks:
482 return
483 if not os.path.exists(self.path("/etc/rpm")):
484 os.mkdir(self.path("/etc/rpm"))
485 f = open(self.path("/etc/rpm/macros.imgcreate"), "w+")
486 if exclude_docs(ks):
487 f.write("%_excludedocs 1\n")
488 f.write("%__file_context_path %{nil}\n")
489 if inst_langs(ks) != None:
490 f.write("%_install_langs ")
491 f.write(inst_langs(ks))
492 f.write("\n")
493 f.close()
494
495class NetworkConfig(KickstartConfig):
496 """A class to apply a kickstart network configuration to a system."""
497 def write_ifcfg(self, network):
498 p = self.path("/etc/sysconfig/network-scripts/ifcfg-" + network.device)
499
500 f = file(p, "w+")
501 os.chmod(p, 0644)
502
503 f.write("DEVICE=%s\n" % network.device)
504 f.write("BOOTPROTO=%s\n" % network.bootProto)
505
506 if network.bootProto.lower() == "static":
507 if network.ip:
508 f.write("IPADDR=%s\n" % network.ip)
509 if network.netmask:
510 f.write("NETMASK=%s\n" % network.netmask)
511
512 if network.onboot:
513 f.write("ONBOOT=on\n")
514 else:
515 f.write("ONBOOT=off\n")
516
517 if network.essid:
518 f.write("ESSID=%s\n" % network.essid)
519
520 if network.ethtool:
521 if network.ethtool.find("autoneg") == -1:
522 network.ethtool = "autoneg off " + network.ethtool
523 f.write("ETHTOOL_OPTS=%s\n" % network.ethtool)
524
525 if network.bootProto.lower() == "dhcp":
526 if network.hostname:
527 f.write("DHCP_HOSTNAME=%s\n" % network.hostname)
528 if network.dhcpclass:
529 f.write("DHCP_CLASSID=%s\n" % network.dhcpclass)
530
531 if network.mtu:
532 f.write("MTU=%s\n" % network.mtu)
533
534 f.close()
535
536 def write_wepkey(self, network):
537 if not network.wepkey:
538 return
539
540 p = self.path("/etc/sysconfig/network-scripts/keys-" + network.device)
541 f = file(p, "w+")
542 os.chmod(p, 0600)
543 f.write("KEY=%s\n" % network.wepkey)
544 f.close()
545
546 def write_sysconfig(self, useipv6, hostname, gateway):
547 path = self.path("/etc/sysconfig/network")
548 f = file(path, "w+")
549 os.chmod(path, 0644)
550
551 f.write("NETWORKING=yes\n")
552
553 if useipv6:
554 f.write("NETWORKING_IPV6=yes\n")
555 else:
556 f.write("NETWORKING_IPV6=no\n")
557
558 if hostname:
559 f.write("HOSTNAME=%s\n" % hostname)
560 else:
561 f.write("HOSTNAME=localhost.localdomain\n")
562
563 if gateway:
564 f.write("GATEWAY=%s\n" % gateway)
565
566 f.close()
567
568 def write_hosts(self, hostname):
569 localline = ""
570 if hostname and hostname != "localhost.localdomain":
571 localline += hostname + " "
572 l = hostname.split(".")
573 if len(l) > 1:
574 localline += l[0] + " "
575 localline += "localhost.localdomain localhost"
576
577 path = self.path("/etc/hosts")
578 f = file(path, "w+")
579 os.chmod(path, 0644)
580 f.write("127.0.0.1\t\t%s\n" % localline)
581 f.write("::1\t\tlocalhost6.localdomain6 localhost6\n")
582 f.close()
583
584 def write_resolv(self, nodns, nameservers):
585 if nodns or not nameservers:
586 return
587
588 path = self.path("/etc/resolv.conf")
589 f = file(path, "w+")
590 os.chmod(path, 0644)
591
592 for ns in (nameservers):
593 if ns:
594 f.write("nameserver %s\n" % ns)
595
596 f.close()
597
598 @apply_wrapper
599 def apply(self, ksnet):
600 fs.makedirs(self.path("/etc/sysconfig/network-scripts"))
601
602 useipv6 = False
603 nodns = False
604 hostname = None
605 gateway = None
606 nameservers = None
607
608 for network in ksnet.network:
609 if not network.device:
610 raise errors.KsError("No --device specified with "
611 "network kickstart command")
612
613 if (network.onboot and network.bootProto.lower() != "dhcp" and
614 not (network.ip and network.netmask)):
615 raise errors.KsError("No IP address and/or netmask "
616 "specified with static "
617 "configuration for '%s'" %
618 network.device)
619
620 self.write_ifcfg(network)
621 self.write_wepkey(network)
622
623 if network.ipv6:
624 useipv6 = True
625 if network.nodns:
626 nodns = True
627
628 if network.hostname:
629 hostname = network.hostname
630 if network.gateway:
631 gateway = network.gateway
632
633 if network.nameserver:
634 nameservers = network.nameserver.split(",")
635
636 self.write_sysconfig(useipv6, hostname, gateway)
637 self.write_hosts(hostname)
638 self.write_resolv(nodns, nameservers)
639
640def use_installerfw(ks, feature):
641 """ Check if the installer framework has to be used for a feature
642 "feature". """
643
644 features = ks.handler.installerfw.features
645 if features:
646 if feature in features or "all" in features:
647 return True
648 return False
649
650def get_image_size(ks, default = None):
651 __size = 0
652 for p in ks.handler.partition.partitions:
653 if p.mountpoint == "/" and p.size:
654 __size = p.size
655 if __size > 0:
656 return int(__size) * 1024L * 1024L
657 else:
658 return default
659
660def get_image_fstype(ks, default = None):
661 for p in ks.handler.partition.partitions:
662 if p.mountpoint == "/" and p.fstype:
663 return p.fstype
664 return default
665
666def get_image_fsopts(ks, default = None):
667 for p in ks.handler.partition.partitions:
668 if p.mountpoint == "/" and p.fsopts:
669 return p.fsopts
670 return default
671
672def get_modules(ks):
673 devices = []
674 if isinstance(ks.handler.device, kscommands.device.FC3_Device):
675 devices.append(ks.handler.device)
676 else:
677 devices.extend(ks.handler.device.deviceList)
678
679 modules = []
680 for device in devices:
681 if not device.moduleName:
682 continue
683 modules.extend(device.moduleName.split(":"))
684
685 return modules
686
687def get_timeout(ks, default = None):
688 if not hasattr(ks.handler.bootloader, "timeout"):
689 return default
690 if ks.handler.bootloader.timeout is None:
691 return default
692 return int(ks.handler.bootloader.timeout)
693
694def get_kernel_args(ks, default = "ro rd.live.image"):
695 if not hasattr(ks.handler.bootloader, "appendLine"):
696 return default
697 if ks.handler.bootloader.appendLine is None:
698 return default
699 return "%s %s" %(default, ks.handler.bootloader.appendLine)
700
701def get_menu_args(ks, default = ""):
702 if not hasattr(ks.handler.bootloader, "menus"):
703 return default
704 if ks.handler.bootloader.menus in (None, ""):
705 return default
706 return "%s" % ks.handler.bootloader.menus
707
708def get_default_kernel(ks, default = None):
709 if not hasattr(ks.handler.bootloader, "default"):
710 return default
711 if not ks.handler.bootloader.default:
712 return default
713 return ks.handler.bootloader.default
714
715def get_repos(ks, repo_urls=None):
716 repos = {}
717 for repo in ks.handler.repo.repoList:
718 inc = []
719 if hasattr(repo, "includepkgs"):
720 inc.extend(repo.includepkgs)
721
722 exc = []
723 if hasattr(repo, "excludepkgs"):
724 exc.extend(repo.excludepkgs)
725
726 baseurl = repo.baseurl
727 mirrorlist = repo.mirrorlist
728
729 if repo_urls and repo.name in repo_urls:
730 baseurl = repo_urls[repo.name]
731 mirrorlist = None
732
733 if repos.has_key(repo.name):
734 msger.warning("Overriding already specified repo %s" %(repo.name,))
735
736 proxy = None
737 if hasattr(repo, "proxy"):
738 proxy = repo.proxy
739 proxy_username = None
740 if hasattr(repo, "proxy_username"):
741 proxy_username = repo.proxy_username
742 proxy_password = None
743 if hasattr(repo, "proxy_password"):
744 proxy_password = repo.proxy_password
745 if hasattr(repo, "debuginfo"):
746 debuginfo = repo.debuginfo
747 if hasattr(repo, "source"):
748 source = repo.source
749 if hasattr(repo, "gpgkey"):
750 gpgkey = repo.gpgkey
751 if hasattr(repo, "disable"):
752 disable = repo.disable
753 ssl_verify = True
754 if hasattr(repo, "ssl_verify"):
755 ssl_verify = repo.ssl_verify == "yes"
756 nocache = False
757 if hasattr(repo, "nocache"):
758 nocache = repo.nocache
759 cost = None
760 if hasattr(repo, "cost"):
761 cost = repo.cost
762 priority = None
763 if hasattr(repo, "priority"):
764 priority = repo.priority
765
766 repos[repo.name] = (repo.name, baseurl, mirrorlist, inc, exc,
767 proxy, proxy_username, proxy_password, debuginfo,
768 source, gpgkey, disable, ssl_verify, nocache,
769 cost, priority)
770
771 return repos.values()
772
773def convert_method_to_repo(ks):
774 try:
775 ks.handler.repo.methodToRepo()
776 except (AttributeError, kserrors.KickstartError):
777 pass
778
779def get_attachment(ks, required=()):
780 return ks.handler.attachment.packageList + list(required)
781
782def get_pre_packages(ks, required=()):
783 return ks.handler.prepackages.packageList + list(required)
784
785def get_packages(ks, required=()):
786 return ks.handler.packages.packageList + list(required)
787
788def get_groups(ks, required=()):
789 return ks.handler.packages.groupList + list(required)
790
791def get_excluded(ks, required=()):
792 return ks.handler.packages.excludedList + list(required)
793
794def get_partitions(ks):
795 return ks.handler.partition.partitions
796
797def ignore_missing(ks):
798 return ks.handler.packages.handleMissing == ksconstants.KS_MISSING_IGNORE
799
800def exclude_docs(ks):
801 return ks.handler.packages.excludeDocs
802
803def inst_langs(ks):
804 if hasattr(ks.handler.packages, "instLange"):
805 return ks.handler.packages.instLange
806 elif hasattr(ks.handler.packages, "instLangs"):
807 return ks.handler.packages.instLangs
808 return ""
809
810def get_post_scripts(ks):
811 scripts = []
812 for s in ks.handler.scripts:
813 if s.type != ksparser.KS_SCRIPT_POST:
814 continue
815 scripts.append(s)
816 return scripts
817
818def add_repo(ks, repostr):
819 args = repostr.split()
820 repoobj = ks.handler.repo.parse(args[1:])
821 if repoobj and repoobj not in ks.handler.repo.repoList:
822 ks.handler.repo.repoList.append(repoobj)
823
824def remove_all_repos(ks):
825 while len(ks.handler.repo.repoList) != 0:
826 del ks.handler.repo.repoList[0]
827
828def remove_duplicate_repos(ks):
829 i = 0
830 j = i + 1
831 while True:
832 if len(ks.handler.repo.repoList) < 2:
833 break
834 if i >= len(ks.handler.repo.repoList) - 1:
835 break
836 name = ks.handler.repo.repoList[i].name
837 baseurl = ks.handler.repo.repoList[i].baseurl
838 if j < len(ks.handler.repo.repoList):
839 if (ks.handler.repo.repoList[j].name == name or \
840 ks.handler.repo.repoList[j].baseurl == baseurl):
841 del ks.handler.repo.repoList[j]
842 else:
843 j += 1
844 if j >= len(ks.handler.repo.repoList):
845 i += 1
846 j = i + 1
847 else:
848 i += 1
849 j = i + 1
850
851def resolve_groups(creatoropts, repometadata):
852 iszypp = False
853 if 'zypp' == creatoropts['pkgmgr']:
854 iszypp = True
855 ks = creatoropts['ks']
856
857 for repo in repometadata:
858 """ Mustn't replace group with package list if repo is ready for the
859 corresponding package manager.
860 """
861
862 if iszypp and repo["patterns"]:
863 continue
864 if not iszypp and repo["comps"]:
865 continue
866
867 # But we also must handle such cases, use zypp but repo only has comps,
868 # use yum but repo only has patterns, use zypp but use_comps is true,
869 # use yum but use_comps is false.
870 groupfile = None
871 if iszypp and repo["comps"]:
872 groupfile = repo["comps"]
873 get_pkglist_handler = misc.get_pkglist_in_comps
874 if not iszypp and repo["patterns"]:
875 groupfile = repo["patterns"]
876 get_pkglist_handler = misc.get_pkglist_in_patterns
877
878 if groupfile:
879 i = 0
880 while True:
881 if i >= len(ks.handler.packages.groupList):
882 break
883 pkglist = get_pkglist_handler(
884 ks.handler.packages.groupList[i].name,
885 groupfile)
886 if pkglist:
887 del ks.handler.packages.groupList[i]
888 for pkg in pkglist:
889 if pkg not in ks.handler.packages.packageList:
890 ks.handler.packages.packageList.append(pkg)
891 else:
892 i = i + 1