3 # Copyright (c) 2007 Red Hat, Inc.
4 # Copyright (c) 2009, 2010, 2011 Intel, Inc.
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
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
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.
25 import pykickstart.sections as kssections
26 import pykickstart.commands as kscommands
27 import pykickstart.constants as ksconstants
28 import pykickstart.errors as kserrors
29 import pykickstart.parser as ksparser
30 import pykickstart.version as ksversion
31 from pykickstart.handlers.control import commandMap
32 from pykickstart.handlers.control import dataMap
35 from mic.utils import errors, misc, runner, fs_related as fs
36 from custom_commands import desktop, micrepo, micboot, partition, installerfw
37 from mic.utils.safeurl import SafeURL
40 AUTH_URL_PTN = r"(?P<scheme>.*)://(?P<username>.*)(:?P<password>.*)?@(?P<url>.*)"
43 class PrepackageSection(kssections.Section):
44 sectionOpen = "%prepackages"
46 def handleLine(self, line):
50 (h, s, t) = line.partition('#')
53 self.handler.prepackages.add([line])
55 def handleHeader(self, lineno, args):
56 kssections.Section.handleHeader(self, lineno, args)
58 class AttachmentSection(kssections.Section):
59 sectionOpen = "%attachment"
61 def handleLine(self, line):
65 (h, s, t) = line.partition('#')
68 self.handler.attachment.add([line])
70 def handleHeader(self, lineno, args):
71 kssections.Section.handleHeader(self, lineno, args)
73 def apply_wrapper(func):
74 def wrapper(*kargs, **kwargs):
76 func(*kargs, **kwargs)
77 except (OSError, IOError, errors.KsError), err:
78 cfgcls = kargs[0].__class__.__name__
79 if msger.ask("Failed to apply %s, skip and continue?" % cfgcls):
80 msger.warning("%s" % err)
83 # just throw out the exception
87 def read_kickstart(path):
88 """Parse a kickstart file and return a KickstartParser instance.
90 This is a simple utility function which takes a path to a kickstart file,
91 parses it and returns a pykickstart KickstartParser instance which can
92 be then passed to an ImageCreator constructor.
94 If an error occurs, a CreatorError exception is thrown.
97 #version = ksversion.makeVersion()
98 #ks = ksparser.KickstartParser(version)
100 using_version = ksversion.DEVEL
101 commandMap[using_version]["desktop"] = desktop.Mic_Desktop
102 commandMap[using_version]["repo"] = micrepo.Mic_Repo
103 commandMap[using_version]["tpk_repo"] = micrepo.Mic_Tpk_Repo
104 commandMap[using_version]["bootloader"] = micboot.Mic_Bootloader
105 commandMap[using_version]["part"] = partition.Mic_Partition
106 commandMap[using_version]["partition"] = partition.Mic_Partition
107 commandMap[using_version]["installerfw_plugins"] = installerfw.Mic_installerfw
108 dataMap[using_version]["RepoData"] = micrepo.Mic_RepoData
109 dataMap[using_version]["Tpk_RepoData"] = micrepo.Mic_Tpk_RepoData
110 dataMap[using_version]["PartData"] = partition.Mic_PartData
111 superclass = ksversion.returnClassForVersion(version=using_version)
113 class KSHandlers(superclass):
115 superclass.__init__(self, mapping=commandMap[using_version])
116 self.prepackages = ksparser.Packages()
117 self.attachment = ksparser.Packages()
119 ks = ksparser.KickstartParser(KSHandlers(), errorsAreFatal=False)
120 ks.registerSection(PrepackageSection(ks.handler))
121 ks.registerSection(AttachmentSection(ks.handler))
124 ks.readKickstart(path)
125 except (kserrors.KickstartParseError, kserrors.KickstartError), err:
126 if msger.ask("Errors occured on kickstart file, skip and continue?"):
127 msger.warning("%s" % err)
130 raise errors.KsError("%s" % err)
134 class KickstartConfig(object):
135 """A base class for applying kickstart configurations to a system."""
136 def __init__(self, instroot):
137 self.instroot = instroot
139 def path(self, subpath):
140 return self.instroot + subpath
142 def _check_sysconfig(self):
143 if not os.path.exists(self.path("/etc/sysconfig")):
144 fs.makedirs(self.path("/etc/sysconfig"))
147 os.chroot(self.instroot)
150 def call(self, args):
151 if not os.path.exists("%s/%s" %(self.instroot, args[0])):
152 raise errors.KsError("Can't find %s in chroot" % args[0])
153 subprocess.call(args, preexec_fn = self.chroot)
158 class LanguageConfig(KickstartConfig):
159 """A class to apply a kickstart language configuration to a system."""
161 def apply(self, kslang):
162 self._check_sysconfig()
164 f = open(self.path("/etc/sysconfig/i18n"), "w+")
165 f.write("LANG=\"" + kslang.lang + "\"\n")
168 f = open(self.path("/etc/locale.conf"), "w+")
169 f.write("LANG=\"" + kslang.lang + "\"\n")
172 #cp ks lang setting to other file, then can access the file in %post section
173 fs.makedirs(self.path("/etc/config"))
174 f = open(self.path("/etc/config/mic_language"), "w+")
175 f.write("LANG=\"" + kslang.lang + "\"\n")
178 class KeyboardConfig(KickstartConfig):
179 """A class to apply a kickstart keyboard configuration to a system."""
181 def apply(self, kskeyboard):
184 # should this impact the X keyboard config too?
185 # or do we want to make X be able to do this mapping?
187 #k = rhpl.keyboard.Keyboard()
188 #if kskeyboard.keyboard:
189 # k.set(kskeyboard.keyboard)
190 #k.write(self.instroot)
193 class TimezoneConfig(KickstartConfig):
194 """A class to apply a kickstart timezone configuration to a system."""
196 def apply(self, kstimezone):
197 self._check_sysconfig()
198 tz = kstimezone.timezone or "America/New_York"
199 utc = str(kstimezone.isUtc)
201 f = open(self.path("/etc/sysconfig/clock"), "w+")
202 f.write("ZONE=\"" + tz + "\"\n")
203 f.write("UTC=" + utc + "\n")
205 if not os.path.exists("/opt/etc"):
206 fs.makedirs("/opt/etc")
207 tz_source = "/usr/share/zoneinfo/%s" % (tz)
208 tz_midst = "/opt/etc/localtime"
209 tz_dest = "/etc/localtime"
211 lncmd = fs.find_binary_inchroot('ln', self.instroot)
213 self.call([lncmd, "-s", tz_source, tz_midst])
214 self.call([lncmd, "-s", tz_midst, tz_dest])
216 lncmd = fs.find_binary_path('ln')
217 subprocess.call([lncmd, "-s",
218 self.path(tz_source),
219 self.path(tz_midst)])
220 subprocess.call([lncmd, "-s",
223 except (IOError, OSError), (errno, msg):
224 raise errors.KsError("Timezone setting error: %s" % msg)
226 class AuthConfig(KickstartConfig):
227 """A class to apply a kickstart authconfig configuration to a system."""
229 def apply(self, ksauthconfig):
230 auth = ksauthconfig.authconfig or "--useshadow --enablemd5"
231 args = ["/usr/share/authconfig/authconfig.py", "--update", "--nostart"]
232 self.call(args + auth.split())
234 class FirewallConfig(KickstartConfig):
235 """A class to apply a kickstart firewall configuration to a system."""
237 def apply(self, ksfirewall):
239 # FIXME: should handle the rest of the options
241 if not os.path.exists(self.path("/usr/sbin/lokkit")):
243 if ksfirewall.enabled:
246 status = "--disabled"
248 self.call(["/usr/sbin/lokkit",
249 "-f", "--quiet", "--nostart", status])
251 class RootPasswordConfig(KickstartConfig):
252 """A class to apply a kickstart root password configuration to a system."""
254 self.call(["/usr/bin/passwd", "-d", "root"])
256 def set_encrypted(self, password):
257 self.call(["/usr/sbin/usermod", "-p", password, "root"])
259 def set_unencrypted(self, password):
260 for p in ("/bin/echo", "/usr/sbin/chpasswd"):
261 if not os.path.exists("%s/%s" %(self.instroot, p)):
262 raise errors.KsError("Unable to set unencrypted password due "
265 p1 = subprocess.Popen(["/bin/echo", "root:%s" %password],
266 stdout = subprocess.PIPE,
267 preexec_fn = self.chroot)
268 p2 = subprocess.Popen(["/usr/sbin/chpasswd", "-m"],
270 stdout = subprocess.PIPE,
271 preexec_fn = self.chroot)
275 def apply(self, ksrootpw):
276 if ksrootpw.isCrypted:
277 self.set_encrypted(ksrootpw.password)
278 elif ksrootpw.password != "":
279 self.set_unencrypted(ksrootpw.password)
283 class UserConfig(KickstartConfig):
284 def set_empty_passwd(self, user):
285 self.call(["/usr/bin/passwd", "-d", user])
287 def set_encrypted_passwd(self, user, password):
288 self.call(["/usr/sbin/usermod", "-p", "%s" % password, user])
290 def set_unencrypted_passwd(self, user, password):
291 for p in ("/bin/echo", "/usr/sbin/chpasswd"):
292 if not os.path.exists("%s/%s" %(self.instroot, p)):
293 raise errors.KsError("Unable to set unencrypted password due "
296 p1 = subprocess.Popen(["/bin/echo", "%s:%s" %(user, password)],
297 stdout = subprocess.PIPE,
298 preexec_fn = self.chroot)
299 p2 = subprocess.Popen(["/usr/sbin/chpasswd", "-m"],
301 stdout = subprocess.PIPE,
302 preexec_fn = self.chroot)
305 def addUser(self, userconfig):
306 args = [ "/usr/sbin/useradd" ]
307 if userconfig.groups:
308 args += [ "--groups", string.join(userconfig.groups, ",") ]
311 args += [ "-d", "/home/%s" % userconfig.name ]
312 args.append(userconfig.name)
314 dev_null = os.open("/dev/null", os.O_WRONLY)
315 msger.debug('adding user with %s' % args)
316 subprocess.call(args,
319 preexec_fn = self.chroot)
322 msger.warning('Cannot add user using "useradd"')
324 if userconfig.password not in (None, ""):
325 if userconfig.isCrypted:
326 self.set_encrypted_passwd(userconfig.name,
329 self.set_unencrypted_passwd(userconfig.name,
332 self.set_empty_passwd(userconfig.name)
334 raise errors.KsError("Invalid kickstart command: %s" \
335 % userconfig.__str__())
338 def apply(self, user):
339 for userconfig in user.userList:
340 self.addUser(userconfig)
342 class ServicesConfig(KickstartConfig):
343 """A class to apply a kickstart services configuration to a system."""
345 def apply(self, ksservices):
346 if not os.path.exists(self.path("/sbin/chkconfig")):
348 for s in ksservices.enabled:
349 self.call(["/sbin/chkconfig", s, "on"])
350 for s in ksservices.disabled:
351 self.call(["/sbin/chkconfig", s, "off"])
353 class XConfig(KickstartConfig):
354 """A class to apply a kickstart X configuration to a system."""
356 def apply(self, ksxconfig):
357 if ksxconfig.startX and os.path.exists(self.path("/etc/inittab")):
358 f = open(self.path("/etc/inittab"), "rw+")
360 buf = buf.replace("id:3:initdefault", "id:5:initdefault")
364 if ksxconfig.defaultdesktop:
365 self._check_sysconfig()
366 f = open(self.path("/etc/sysconfig/desktop"), "w")
367 f.write("DESKTOP="+ksxconfig.defaultdesktop+"\n")
370 class DesktopConfig(KickstartConfig):
371 """A class to apply a kickstart desktop configuration to a system."""
373 def apply(self, ksdesktop):
374 if ksdesktop.defaultdesktop:
375 self._check_sysconfig()
376 f = open(self.path("/etc/sysconfig/desktop"), "w")
377 f.write("DESKTOP="+ksdesktop.defaultdesktop+"\n")
379 if os.path.exists(self.path("/etc/gdm/custom.conf")):
380 f = open(self.path("/etc/skel/.dmrc"), "w")
381 f.write("[Desktop]\n")
382 f.write("Session="+ksdesktop.defaultdesktop.lower()+"\n")
384 if ksdesktop.session:
385 if os.path.exists(self.path("/etc/sysconfig/uxlaunch")):
386 f = open(self.path("/etc/sysconfig/uxlaunch"), "a+")
387 f.write("session="+ksdesktop.session.lower()+"\n")
389 if ksdesktop.autologinuser:
390 self._check_sysconfig()
391 f = open(self.path("/etc/sysconfig/desktop"), "a+")
392 f.write("AUTOLOGIN_USER=" + ksdesktop.autologinuser + "\n")
394 if os.path.exists(self.path("/etc/gdm/custom.conf")):
395 f = open(self.path("/etc/gdm/custom.conf"), "w")
396 f.write("[daemon]\n")
397 f.write("AutomaticLoginEnable=true\n")
398 f.write("AutomaticLogin=" + ksdesktop.autologinuser + "\n")
401 class MoblinRepoConfig(KickstartConfig):
402 """A class to apply a kickstart desktop configuration to a system."""
403 def __create_repo_section(self, repo, type, fd):
406 reposuffix = {"base":"", "debuginfo":"-debuginfo", "source":"-source"}
407 reponame = repo.name + reposuffix[type]
410 baseurl = repo.baseurl
412 mirrorlist = repo.mirrorlist
414 elif type == "debuginfo":
416 if repo.baseurl.endswith("/"):
417 baseurl = os.path.dirname(os.path.dirname(repo.baseurl))
419 baseurl = os.path.dirname(repo.baseurl)
423 variant = repo.mirrorlist[repo.mirrorlist.find("$"):]
424 mirrorlist = repo.mirrorlist[0:repo.mirrorlist.find("$")]
425 mirrorlist += "debug" + "-" + variant
427 elif type == "source":
429 if repo.baseurl.endswith("/"):
430 baseurl = os.path.dirname(
432 os.path.dirname(repo.baseurl)))
434 baseurl = os.path.dirname(os.path.dirname(repo.baseurl))
438 variant = repo.mirrorlist[repo.mirrorlist.find("$"):]
439 mirrorlist = repo.mirrorlist[0:repo.mirrorlist.find("$")]
440 mirrorlist += "source" + "-" + variant
442 fd.write("[" + reponame + "]\n")
443 fd.write("name=" + reponame + "\n")
444 fd.write("failovermethod=priority\n")
446 auth_url = re.compile(AUTH_URL_PTN)
447 m = auth_url.match(baseurl)
449 baseurl = "%s://%s" % (m.group('scheme'), m.group('url'))
450 fd.write("baseurl=" + baseurl + "\n")
452 fd.write("mirrorlist=" + mirrorlist + "\n")
453 """ Skip saving proxy settings """
455 # fd.write("proxy=" + repo.proxy + "\n")
456 #if repo.proxy_username:
457 # fd.write("proxy_username=" + repo.proxy_username + "\n")
458 #if repo.proxy_password:
459 # fd.write("proxy_password=" + repo.proxy_password + "\n")
461 fd.write("gpgkey=" + repo.gpgkey + "\n")
462 fd.write("gpgcheck=1\n")
464 fd.write("gpgcheck=0\n")
465 if type == "source" or type == "debuginfo" or repo.disable:
466 fd.write("enabled=0\n")
468 fd.write("enabled=1\n")
471 def __create_repo_file(self, repo, repodir):
472 fs.makedirs(self.path(repodir))
473 f = open(self.path(repodir + "/" + repo.name + ".repo"), "w")
474 self.__create_repo_section(repo, "base", f)
476 self.__create_repo_section(repo, "debuginfo", f)
478 self.__create_repo_section(repo, "source", f)
482 def apply(self, ksrepo, repodata, repourl):
483 for repo in ksrepo.repoList:
484 if repo.name in repourl:
485 repo.baseurl = repourl[repo.name]
487 #self.__create_repo_file(repo, "/etc/yum.repos.d")
488 self.__create_repo_file(repo, "/etc/zypp/repos.d")
489 """ Import repo gpg keys """
491 for repo in repodata:
494 "--root=%s" % self.instroot,
498 class RPMMacroConfig(KickstartConfig):
499 """A class to apply the specified rpm macros to the filesystem"""
504 if not os.path.exists(self.path("/etc/rpm")):
505 os.mkdir(self.path("/etc/rpm"))
506 f = open(self.path("/etc/rpm/macros.imgcreate"), "w+")
508 f.write("%_excludedocs 1\n")
509 f.write("%__file_context_path %{nil}\n")
510 if inst_langs(ks) != None:
511 f.write("%_install_langs ")
512 f.write(inst_langs(ks))
516 class NetworkConfig(KickstartConfig):
517 """A class to apply a kickstart network configuration to a system."""
518 def write_ifcfg(self, network):
519 p = self.path("/etc/sysconfig/network-scripts/ifcfg-" + network.device)
524 f.write("DEVICE=%s\n" % network.device)
525 f.write("BOOTPROTO=%s\n" % network.bootProto)
527 if network.bootProto.lower() == "static":
529 f.write("IPADDR=%s\n" % network.ip)
531 f.write("NETMASK=%s\n" % network.netmask)
534 f.write("ONBOOT=on\n")
536 f.write("ONBOOT=off\n")
539 f.write("ESSID=%s\n" % network.essid)
542 if network.ethtool.find("autoneg") == -1:
543 network.ethtool = "autoneg off " + network.ethtool
544 f.write("ETHTOOL_OPTS=%s\n" % network.ethtool)
546 if network.bootProto.lower() == "dhcp":
548 f.write("DHCP_HOSTNAME=%s\n" % network.hostname)
549 if network.dhcpclass:
550 f.write("DHCP_CLASSID=%s\n" % network.dhcpclass)
553 f.write("MTU=%s\n" % network.mtu)
557 def write_wepkey(self, network):
558 if not network.wepkey:
561 p = self.path("/etc/sysconfig/network-scripts/keys-" + network.device)
564 f.write("KEY=%s\n" % network.wepkey)
567 def write_sysconfig(self, useipv6, hostname, gateway):
568 path = self.path("/etc/sysconfig/network")
572 f.write("NETWORKING=yes\n")
575 f.write("NETWORKING_IPV6=yes\n")
577 f.write("NETWORKING_IPV6=no\n")
580 f.write("HOSTNAME=%s\n" % hostname)
582 f.write("HOSTNAME=localhost.localdomain\n")
585 f.write("GATEWAY=%s\n" % gateway)
589 def write_hosts(self, hostname):
591 if hostname and hostname != "localhost.localdomain":
592 localline += hostname + " "
593 l = hostname.split(".")
595 localline += l[0] + " "
596 localline += "localhost.localdomain localhost"
598 path = self.path("/etc/hosts")
601 f.write("127.0.0.1\t\t%s\n" % localline)
602 f.write("::1\t\tlocalhost6.localdomain6 localhost6\n")
605 def write_resolv(self, nodns, nameservers):
606 if nodns or not nameservers:
609 path = self.path("/etc/resolv.conf")
613 for ns in (nameservers):
615 f.write("nameserver %s\n" % ns)
620 def apply(self, ksnet):
621 fs.makedirs(self.path("/etc/sysconfig/network-scripts"))
629 for network in ksnet.network:
630 if not network.device:
631 raise errors.KsError("No --device specified with "
632 "network kickstart command")
634 if (network.onboot and network.bootProto.lower() != "dhcp" and
635 not (network.ip and network.netmask)):
636 raise errors.KsError("No IP address and/or netmask "
637 "specified with static "
638 "configuration for '%s'" %
641 self.write_ifcfg(network)
642 self.write_wepkey(network)
650 hostname = network.hostname
652 gateway = network.gateway
654 if network.nameserver:
655 nameservers = network.nameserver.split(",")
657 self.write_sysconfig(useipv6, hostname, gateway)
658 self.write_hosts(hostname)
659 self.write_resolv(nodns, nameservers)
661 def use_installerfw(ks, feature):
662 """ Check if the installer framework has to be used for a feature
665 features = ks.handler.installerfw.features
667 if feature in features or "all" in features:
671 def get_image_size(ks, default = None):
673 for p in ks.handler.partition.partitions:
674 if p.mountpoint == "/" and p.size:
677 return int(__size) * 1024L * 1024L
681 def get_image_fstype(ks, default = None):
682 for p in ks.handler.partition.partitions:
683 if p.mountpoint == "/" and p.fstype:
687 def get_image_fsopts(ks, default = None):
688 for p in ks.handler.partition.partitions:
689 if p.mountpoint == "/" and p.fsopts:
695 if isinstance(ks.handler.device, kscommands.device.FC3_Device):
696 devices.append(ks.handler.device)
698 devices.extend(ks.handler.device.deviceList)
701 for device in devices:
702 if not device.moduleName:
704 modules.extend(device.moduleName.split(":"))
708 def get_timeout(ks, default = None):
709 if not hasattr(ks.handler.bootloader, "timeout"):
711 if ks.handler.bootloader.timeout is None:
713 return int(ks.handler.bootloader.timeout)
715 def get_kernel_args(ks, default = "ro rd.live.image"):
716 if not hasattr(ks.handler.bootloader, "appendLine"):
718 if ks.handler.bootloader.appendLine is None:
720 return "%s %s" %(default, ks.handler.bootloader.appendLine)
722 def get_menu_args(ks, default = ""):
723 if not hasattr(ks.handler.bootloader, "menus"):
725 if ks.handler.bootloader.menus in (None, ""):
727 return "%s" % ks.handler.bootloader.menus
729 def get_default_kernel(ks, default = None):
730 if not hasattr(ks.handler.bootloader, "default"):
732 if not ks.handler.bootloader.default:
734 return ks.handler.bootloader.default
736 RepoType = collections.namedtuple("Repo",
737 "name, baseurl, mirrorlist, includepkgs, excludepkgs, proxy, \
738 proxy_username, proxy_password, debuginfo, \
739 source, gpgkey, disable, ssl_verify, nocache, \
742 def Repo(name, baseurl, mirrorlist=None, includepkgs=[], excludepkgs=[], proxy=None,
743 proxy_username=None, proxy_password=None, debuginfo=None,
744 source=None, gpgkey=None, disable=None, ssl_verify=None,
745 nocache=False, cost=None, priority=None):
746 return RepoType(name, baseurl, mirrorlist, includepkgs, excludepkgs, proxy,
747 proxy_username, proxy_password, debuginfo,
748 source, gpgkey, disable, ssl_verify, nocache,
752 def get_repos(ks, repo_urls=None, ignore_ksrepo=False):
754 for repodata in ks.handler.repo.repoList:
756 for field in RepoType._fields:
757 if hasattr(repodata, field) and getattr(repodata, field):
758 repo[field] = getattr(repodata, field)
760 if hasattr(repodata, 'baseurl') and getattr(repodata, 'baseurl'):
761 repo['baseurl'] = SafeURL(getattr(repodata, 'baseurl'),
762 getattr(repodata, 'user', None),
763 getattr(repodata, 'passwd', None))
766 repos[repo['name']] = Repo(**repo)
771 for name, repo in repo_urls.items():
772 if 'baseurl' in repo:
773 repo['baseurl'] = SafeURL(repo.get('baseurl'),
774 repo.get('user', None),
775 repo.get('passwd', None))
776 repos[name] = Repo(**repo)
777 return repos.values()
779 TpkRepoType = collections.namedtuple("TpkRepo",
780 "name, baseurl,proxy,proxy_username,proxy_password,ssl_verify")
782 def TpkRepo(name, baseurl, proxy=None,proxy_username=None, proxy_password=None,ssl_verify=None):
783 return TpkRepoType(name, baseurl,proxy,proxy_username,proxy_password,ssl_verify)
786 def get_tpkrepos(ks):
788 for tpkrepodata in ks.handler.tpk_repo.tpkRepoList:
790 for field in TpkRepoType._fields:
791 if hasattr(tpkrepodata, field) and getattr(tpkrepodata, field):
792 tpkrepo[field] = getattr(tpkrepodata, field)
794 if hasattr(tpkrepodata, 'baseurl') and getattr(tpkrepodata, 'baseurl'):
795 tpkrepo['baseurl'] = SafeURL(getattr(tpkrepodata, 'baseurl'),getattr(tpkrepodata, 'user',None),getattr(tpkrepodata, 'passwd',None))
797 if 'name' in tpkrepo:
798 tpkrepos[tpkrepo['name']] = TpkRepo(**tpkrepo)
800 return tpkrepos.values()
803 def convert_method_to_repo(ks):
805 ks.handler.repo.methodToRepo()
806 except (AttributeError, kserrors.KickstartError):
809 def get_attachment(ks, required=()):
810 return ks.handler.attachment.packageList + list(required)
812 def get_pre_packages(ks, required=()):
813 return ks.handler.prepackages.packageList + list(required)
815 def get_packages(ks, required=()):
816 return ks.handler.packages.packageList + list(required)
818 def get_tpkpackages(ks):
819 return ks.handler.tpk_packages.tpk_packageList
821 def get_groups(ks, required=()):
822 return ks.handler.packages.groupList + list(required)
824 def get_excluded(ks, required=()):
825 return ks.handler.packages.excludedList + list(required)
827 def get_partitions(ks):
828 return ks.handler.partition.partitions
830 def ignore_missing(ks):
831 return ks.handler.packages.handleMissing == ksconstants.KS_MISSING_IGNORE
833 def exclude_docs(ks):
834 return ks.handler.packages.excludeDocs
837 if hasattr(ks.handler.packages, "instLange"):
838 return ks.handler.packages.instLange
839 elif hasattr(ks.handler.packages, "instLangs"):
840 return ks.handler.packages.instLangs
843 def get_post_scripts(ks):
845 for s in ks.handler.scripts:
846 if s.type != ksparser.KS_SCRIPT_POST:
851 def get_sign_scripts(ks):
853 for s in ks.handler.scripts:
854 if s.type != ksparser.KS_SCRIPT_RUN:
858 def add_repo(ks, repostr):
859 args = repostr.split()
860 repoobj = ks.handler.repo.parse(args[1:])
861 if repoobj and repoobj not in ks.handler.repo.repoList:
862 ks.handler.repo.repoList.append(repoobj)
864 def remove_all_repos(ks):
865 while len(ks.handler.repo.repoList) != 0:
866 del ks.handler.repo.repoList[0]
868 def remove_duplicate_repos(ks):
872 if len(ks.handler.repo.repoList) < 2:
874 if i >= len(ks.handler.repo.repoList) - 1:
876 name = ks.handler.repo.repoList[i].name
877 baseurl = ks.handler.repo.repoList[i].baseurl
878 if j < len(ks.handler.repo.repoList):
879 if (ks.handler.repo.repoList[j].name == name or \
880 ks.handler.repo.repoList[j].baseurl == baseurl):
881 del ks.handler.repo.repoList[j]
884 if j >= len(ks.handler.repo.repoList):
891 def resolve_groups(creatoropts, repometadata):
893 if 'zypp' == creatoropts['pkgmgr']:
895 ks = creatoropts['ks']
897 for repo in repometadata:
898 """ Mustn't replace group with package list if repo is ready for the
899 corresponding package manager.
902 if iszypp and repo["patterns"]:
904 if not iszypp and repo["comps"]:
907 # But we also must handle such cases, use zypp but repo only has comps,
908 # use yum but repo only has patterns, use zypp but use_comps is true,
909 # use yum but use_comps is false.
911 if iszypp and repo["comps"]:
912 groupfile = repo["comps"]
913 get_pkglist_handler = misc.get_pkglist_in_comps
914 if not iszypp and repo["patterns"]:
915 groupfile = repo["patterns"]
916 get_pkglist_handler = misc.get_pkglist_in_patterns
921 if i >= len(ks.handler.packages.groupList):
923 pkglist = get_pkglist_handler(
924 ks.handler.packages.groupList[i].name,
927 del ks.handler.packages.groupList[i]
929 if pkg not in ks.handler.packages.packageList:
930 ks.handler.packages.packageList.append(pkg)