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]["bootloader"] = micboot.Mic_Bootloader
104 commandMap[using_version]["part"] = partition.Mic_Partition
105 commandMap[using_version]["partition"] = partition.Mic_Partition
106 commandMap[using_version]["installerfw_plugins"] = installerfw.Mic_installerfw
107 dataMap[using_version]["RepoData"] = micrepo.Mic_RepoData
108 dataMap[using_version]["PartData"] = partition.Mic_PartData
109 superclass = ksversion.returnClassForVersion(version=using_version)
111 class KSHandlers(superclass):
113 superclass.__init__(self, mapping=commandMap[using_version])
114 self.prepackages = ksparser.Packages()
115 self.attachment = ksparser.Packages()
117 ks = ksparser.KickstartParser(KSHandlers(), errorsAreFatal=False)
118 ks.registerSection(PrepackageSection(ks.handler))
119 ks.registerSection(AttachmentSection(ks.handler))
122 ks.readKickstart(path)
123 except (kserrors.KickstartParseError, kserrors.KickstartError), err:
124 if msger.ask("Errors occured on kickstart file, skip and continue?"):
125 msger.warning("%s" % err)
128 raise errors.KsError("%s" % err)
132 class KickstartConfig(object):
133 """A base class for applying kickstart configurations to a system."""
134 def __init__(self, instroot):
135 self.instroot = instroot
137 def path(self, subpath):
138 return self.instroot + subpath
140 def _check_sysconfig(self):
141 if not os.path.exists(self.path("/etc/sysconfig")):
142 fs.makedirs(self.path("/etc/sysconfig"))
145 os.chroot(self.instroot)
148 def call(self, args):
149 if not os.path.exists("%s/%s" %(self.instroot, args[0])):
150 raise errors.KsError("Can't find %s in chroot" % args[0])
151 subprocess.call(args, preexec_fn = self.chroot)
156 class LanguageConfig(KickstartConfig):
157 """A class to apply a kickstart language configuration to a system."""
159 def apply(self, kslang):
160 self._check_sysconfig()
162 f = open(self.path("/etc/sysconfig/i18n"), "w+")
163 f.write("LANG=\"" + kslang.lang + "\"\n")
166 f = open(self.path("/etc/locale.conf"), "w+")
167 f.write("LANG=\"" + kslang.lang + "\"\n")
170 #cp ks lang setting to other file, then can access the file in %post section
171 fs.makedirs(self.path("/etc/config"))
172 f = open(self.path("/etc/config/mic_language"), "w+")
173 f.write("LANG=\"" + kslang.lang + "\"\n")
176 class KeyboardConfig(KickstartConfig):
177 """A class to apply a kickstart keyboard configuration to a system."""
179 def apply(self, kskeyboard):
182 # should this impact the X keyboard config too?
183 # or do we want to make X be able to do this mapping?
185 #k = rhpl.keyboard.Keyboard()
186 #if kskeyboard.keyboard:
187 # k.set(kskeyboard.keyboard)
188 #k.write(self.instroot)
191 class TimezoneConfig(KickstartConfig):
192 """A class to apply a kickstart timezone configuration to a system."""
194 def apply(self, kstimezone):
195 self._check_sysconfig()
196 tz = kstimezone.timezone or "America/New_York"
197 utc = str(kstimezone.isUtc)
199 f = open(self.path("/etc/sysconfig/clock"), "w+")
200 f.write("ZONE=\"" + tz + "\"\n")
201 f.write("UTC=" + utc + "\n")
203 if not os.path.exists("/opt/etc"):
204 fs.makedirs("/opt/etc")
205 tz_source = "/usr/share/zoneinfo/%s" % (tz)
206 tz_midst = "/opt/etc/localtime"
207 tz_dest = "/etc/localtime"
209 lncmd = fs.find_binary_inchroot('ln', self.instroot)
211 self.call([lncmd, "-s", tz_source, tz_midst])
212 self.call([lncmd, "-s", tz_midst, tz_dest])
214 lncmd = fs.find_binary_path('ln')
215 subprocess.call([lncmd, "-s",
216 self.path(tz_source),
217 self.path(tz_midst)])
218 subprocess.call([lncmd, "-s",
221 except (IOError, OSError), (errno, msg):
222 raise errors.KsError("Timezone setting error: %s" % msg)
224 class AuthConfig(KickstartConfig):
225 """A class to apply a kickstart authconfig configuration to a system."""
227 def apply(self, ksauthconfig):
228 auth = ksauthconfig.authconfig or "--useshadow --enablemd5"
229 args = ["/usr/share/authconfig/authconfig.py", "--update", "--nostart"]
230 self.call(args + auth.split())
232 class FirewallConfig(KickstartConfig):
233 """A class to apply a kickstart firewall configuration to a system."""
235 def apply(self, ksfirewall):
237 # FIXME: should handle the rest of the options
239 if not os.path.exists(self.path("/usr/sbin/lokkit")):
241 if ksfirewall.enabled:
244 status = "--disabled"
246 self.call(["/usr/sbin/lokkit",
247 "-f", "--quiet", "--nostart", status])
249 class RootPasswordConfig(KickstartConfig):
250 """A class to apply a kickstart root password configuration to a system."""
252 self.call(["/usr/bin/passwd", "-d", "root"])
254 def set_encrypted(self, password):
255 self.call(["/usr/sbin/usermod", "-p", password, "root"])
257 def set_unencrypted(self, password):
258 for p in ("/bin/echo", "/usr/sbin/chpasswd"):
259 if not os.path.exists("%s/%s" %(self.instroot, p)):
260 raise errors.KsError("Unable to set unencrypted password due "
263 p1 = subprocess.Popen(["/bin/echo", "root:%s" %password],
264 stdout = subprocess.PIPE,
265 preexec_fn = self.chroot)
266 p2 = subprocess.Popen(["/usr/sbin/chpasswd", "-m"],
268 stdout = subprocess.PIPE,
269 preexec_fn = self.chroot)
273 def apply(self, ksrootpw):
274 if ksrootpw.isCrypted:
275 self.set_encrypted(ksrootpw.password)
276 elif ksrootpw.password != "":
277 self.set_unencrypted(ksrootpw.password)
281 class UserConfig(KickstartConfig):
282 def set_empty_passwd(self, user):
283 self.call(["/usr/bin/passwd", "-d", user])
285 def set_encrypted_passwd(self, user, password):
286 self.call(["/usr/sbin/usermod", "-p", "%s" % password, user])
288 def set_unencrypted_passwd(self, user, password):
289 for p in ("/bin/echo", "/usr/sbin/chpasswd"):
290 if not os.path.exists("%s/%s" %(self.instroot, p)):
291 raise errors.KsError("Unable to set unencrypted password due "
294 p1 = subprocess.Popen(["/bin/echo", "%s:%s" %(user, password)],
295 stdout = subprocess.PIPE,
296 preexec_fn = self.chroot)
297 p2 = subprocess.Popen(["/usr/sbin/chpasswd", "-m"],
299 stdout = subprocess.PIPE,
300 preexec_fn = self.chroot)
303 def addUser(self, userconfig):
304 args = [ "/usr/sbin/useradd" ]
305 if userconfig.groups:
306 args += [ "--groups", string.join(userconfig.groups, ",") ]
309 args += [ "-d", "/home/%s" % userconfig.name ]
310 args.append(userconfig.name)
312 dev_null = os.open("/dev/null", os.O_WRONLY)
313 msger.debug('adding user with %s' % args)
314 subprocess.call(args,
317 preexec_fn = self.chroot)
320 msger.warning('Cannot add user using "useradd"')
322 if userconfig.password not in (None, ""):
323 if userconfig.isCrypted:
324 self.set_encrypted_passwd(userconfig.name,
327 self.set_unencrypted_passwd(userconfig.name,
330 self.set_empty_passwd(userconfig.name)
332 raise errors.KsError("Invalid kickstart command: %s" \
333 % userconfig.__str__())
336 def apply(self, user):
337 for userconfig in user.userList:
338 self.addUser(userconfig)
340 class ServicesConfig(KickstartConfig):
341 """A class to apply a kickstart services configuration to a system."""
343 def apply(self, ksservices):
344 if not os.path.exists(self.path("/sbin/chkconfig")):
346 for s in ksservices.enabled:
347 self.call(["/sbin/chkconfig", s, "on"])
348 for s in ksservices.disabled:
349 self.call(["/sbin/chkconfig", s, "off"])
351 class XConfig(KickstartConfig):
352 """A class to apply a kickstart X configuration to a system."""
354 def apply(self, ksxconfig):
355 if ksxconfig.startX and os.path.exists(self.path("/etc/inittab")):
356 f = open(self.path("/etc/inittab"), "rw+")
358 buf = buf.replace("id:3:initdefault", "id:5:initdefault")
362 if ksxconfig.defaultdesktop:
363 self._check_sysconfig()
364 f = open(self.path("/etc/sysconfig/desktop"), "w")
365 f.write("DESKTOP="+ksxconfig.defaultdesktop+"\n")
368 class DesktopConfig(KickstartConfig):
369 """A class to apply a kickstart desktop configuration to a system."""
371 def apply(self, ksdesktop):
372 if ksdesktop.defaultdesktop:
373 self._check_sysconfig()
374 f = open(self.path("/etc/sysconfig/desktop"), "w")
375 f.write("DESKTOP="+ksdesktop.defaultdesktop+"\n")
377 if os.path.exists(self.path("/etc/gdm/custom.conf")):
378 f = open(self.path("/etc/skel/.dmrc"), "w")
379 f.write("[Desktop]\n")
380 f.write("Session="+ksdesktop.defaultdesktop.lower()+"\n")
382 if ksdesktop.session:
383 if os.path.exists(self.path("/etc/sysconfig/uxlaunch")):
384 f = open(self.path("/etc/sysconfig/uxlaunch"), "a+")
385 f.write("session="+ksdesktop.session.lower()+"\n")
387 if ksdesktop.autologinuser:
388 self._check_sysconfig()
389 f = open(self.path("/etc/sysconfig/desktop"), "a+")
390 f.write("AUTOLOGIN_USER=" + ksdesktop.autologinuser + "\n")
392 if os.path.exists(self.path("/etc/gdm/custom.conf")):
393 f = open(self.path("/etc/gdm/custom.conf"), "w")
394 f.write("[daemon]\n")
395 f.write("AutomaticLoginEnable=true\n")
396 f.write("AutomaticLogin=" + ksdesktop.autologinuser + "\n")
399 class MoblinRepoConfig(KickstartConfig):
400 """A class to apply a kickstart desktop configuration to a system."""
401 def __create_repo_section(self, repo, type, fd):
404 reposuffix = {"base":"", "debuginfo":"-debuginfo", "source":"-source"}
405 reponame = repo.name + reposuffix[type]
408 baseurl = repo.baseurl
410 mirrorlist = repo.mirrorlist
412 elif type == "debuginfo":
414 if repo.baseurl.endswith("/"):
415 baseurl = os.path.dirname(os.path.dirname(repo.baseurl))
417 baseurl = os.path.dirname(repo.baseurl)
421 variant = repo.mirrorlist[repo.mirrorlist.find("$"):]
422 mirrorlist = repo.mirrorlist[0:repo.mirrorlist.find("$")]
423 mirrorlist += "debug" + "-" + variant
425 elif type == "source":
427 if repo.baseurl.endswith("/"):
428 baseurl = os.path.dirname(
430 os.path.dirname(repo.baseurl)))
432 baseurl = os.path.dirname(os.path.dirname(repo.baseurl))
436 variant = repo.mirrorlist[repo.mirrorlist.find("$"):]
437 mirrorlist = repo.mirrorlist[0:repo.mirrorlist.find("$")]
438 mirrorlist += "source" + "-" + variant
440 fd.write("[" + reponame + "]\n")
441 fd.write("name=" + reponame + "\n")
442 fd.write("failovermethod=priority\n")
444 auth_url = re.compile(AUTH_URL_PTN)
445 m = auth_url.match(baseurl)
447 baseurl = "%s://%s" % (m.group('scheme'), m.group('url'))
448 fd.write("baseurl=" + baseurl + "\n")
450 fd.write("mirrorlist=" + mirrorlist + "\n")
451 """ Skip saving proxy settings """
453 # fd.write("proxy=" + repo.proxy + "\n")
454 #if repo.proxy_username:
455 # fd.write("proxy_username=" + repo.proxy_username + "\n")
456 #if repo.proxy_password:
457 # fd.write("proxy_password=" + repo.proxy_password + "\n")
459 fd.write("gpgkey=" + repo.gpgkey + "\n")
460 fd.write("gpgcheck=1\n")
462 fd.write("gpgcheck=0\n")
463 if type == "source" or type == "debuginfo" or repo.disable:
464 fd.write("enabled=0\n")
466 fd.write("enabled=1\n")
469 def __create_repo_file(self, repo, repodir):
470 fs.makedirs(self.path(repodir))
471 f = open(self.path(repodir + "/" + repo.name + ".repo"), "w")
472 self.__create_repo_section(repo, "base", f)
474 self.__create_repo_section(repo, "debuginfo", f)
476 self.__create_repo_section(repo, "source", f)
480 def apply(self, ksrepo, repodata, repourl):
481 for repo in ksrepo.repoList:
482 if repo.name in repourl:
483 repo.baseurl = repourl[repo.name]
485 #self.__create_repo_file(repo, "/etc/yum.repos.d")
486 self.__create_repo_file(repo, "/etc/zypp/repos.d")
487 """ Import repo gpg keys """
489 for repo in repodata:
492 "--root=%s" % self.instroot,
496 class RPMMacroConfig(KickstartConfig):
497 """A class to apply the specified rpm macros to the filesystem"""
502 if not os.path.exists(self.path("/etc/rpm")):
503 os.mkdir(self.path("/etc/rpm"))
504 f = open(self.path("/etc/rpm/macros.imgcreate"), "w+")
506 f.write("%_excludedocs 1\n")
507 f.write("%__file_context_path %{nil}\n")
508 if inst_langs(ks) != None:
509 f.write("%_install_langs ")
510 f.write(inst_langs(ks))
514 class NetworkConfig(KickstartConfig):
515 """A class to apply a kickstart network configuration to a system."""
516 def write_ifcfg(self, network):
517 p = self.path("/etc/sysconfig/network-scripts/ifcfg-" + network.device)
522 f.write("DEVICE=%s\n" % network.device)
523 f.write("BOOTPROTO=%s\n" % network.bootProto)
525 if network.bootProto.lower() == "static":
527 f.write("IPADDR=%s\n" % network.ip)
529 f.write("NETMASK=%s\n" % network.netmask)
532 f.write("ONBOOT=on\n")
534 f.write("ONBOOT=off\n")
537 f.write("ESSID=%s\n" % network.essid)
540 if network.ethtool.find("autoneg") == -1:
541 network.ethtool = "autoneg off " + network.ethtool
542 f.write("ETHTOOL_OPTS=%s\n" % network.ethtool)
544 if network.bootProto.lower() == "dhcp":
546 f.write("DHCP_HOSTNAME=%s\n" % network.hostname)
547 if network.dhcpclass:
548 f.write("DHCP_CLASSID=%s\n" % network.dhcpclass)
551 f.write("MTU=%s\n" % network.mtu)
555 def write_wepkey(self, network):
556 if not network.wepkey:
559 p = self.path("/etc/sysconfig/network-scripts/keys-" + network.device)
562 f.write("KEY=%s\n" % network.wepkey)
565 def write_sysconfig(self, useipv6, hostname, gateway):
566 path = self.path("/etc/sysconfig/network")
570 f.write("NETWORKING=yes\n")
573 f.write("NETWORKING_IPV6=yes\n")
575 f.write("NETWORKING_IPV6=no\n")
578 f.write("HOSTNAME=%s\n" % hostname)
580 f.write("HOSTNAME=localhost.localdomain\n")
583 f.write("GATEWAY=%s\n" % gateway)
587 def write_hosts(self, hostname):
589 if hostname and hostname != "localhost.localdomain":
590 localline += hostname + " "
591 l = hostname.split(".")
593 localline += l[0] + " "
594 localline += "localhost.localdomain localhost"
596 path = self.path("/etc/hosts")
599 f.write("127.0.0.1\t\t%s\n" % localline)
600 f.write("::1\t\tlocalhost6.localdomain6 localhost6\n")
603 def write_resolv(self, nodns, nameservers):
604 if nodns or not nameservers:
607 path = self.path("/etc/resolv.conf")
611 for ns in (nameservers):
613 f.write("nameserver %s\n" % ns)
618 def apply(self, ksnet):
619 fs.makedirs(self.path("/etc/sysconfig/network-scripts"))
627 for network in ksnet.network:
628 if not network.device:
629 raise errors.KsError("No --device specified with "
630 "network kickstart command")
632 if (network.onboot and network.bootProto.lower() != "dhcp" and
633 not (network.ip and network.netmask)):
634 raise errors.KsError("No IP address and/or netmask "
635 "specified with static "
636 "configuration for '%s'" %
639 self.write_ifcfg(network)
640 self.write_wepkey(network)
648 hostname = network.hostname
650 gateway = network.gateway
652 if network.nameserver:
653 nameservers = network.nameserver.split(",")
655 self.write_sysconfig(useipv6, hostname, gateway)
656 self.write_hosts(hostname)
657 self.write_resolv(nodns, nameservers)
659 def use_installerfw(ks, feature):
660 """ Check if the installer framework has to be used for a feature
663 features = ks.handler.installerfw.features
665 if feature in features or "all" in features:
669 def get_image_size(ks, default = None):
671 for p in ks.handler.partition.partitions:
672 if p.mountpoint == "/" and p.size:
675 return int(__size) * 1024L * 1024L
679 def get_image_fstype(ks, default = None):
680 for p in ks.handler.partition.partitions:
681 if p.mountpoint == "/" and p.fstype:
685 def get_image_fsopts(ks, default = None):
686 for p in ks.handler.partition.partitions:
687 if p.mountpoint == "/" and p.fsopts:
693 if isinstance(ks.handler.device, kscommands.device.FC3_Device):
694 devices.append(ks.handler.device)
696 devices.extend(ks.handler.device.deviceList)
699 for device in devices:
700 if not device.moduleName:
702 modules.extend(device.moduleName.split(":"))
706 def get_timeout(ks, default = None):
707 if not hasattr(ks.handler.bootloader, "timeout"):
709 if ks.handler.bootloader.timeout is None:
711 return int(ks.handler.bootloader.timeout)
713 def get_kernel_args(ks, default = "ro rd.live.image"):
714 if not hasattr(ks.handler.bootloader, "appendLine"):
716 if ks.handler.bootloader.appendLine is None:
718 return "%s %s" %(default, ks.handler.bootloader.appendLine)
720 def get_menu_args(ks, default = ""):
721 if not hasattr(ks.handler.bootloader, "menus"):
723 if ks.handler.bootloader.menus in (None, ""):
725 return "%s" % ks.handler.bootloader.menus
727 def get_default_kernel(ks, default = None):
728 if not hasattr(ks.handler.bootloader, "default"):
730 if not ks.handler.bootloader.default:
732 return ks.handler.bootloader.default
734 RepoType = collections.namedtuple("Repo",
735 "name, baseurl, mirrorlist, includepkgs, excludepkgs, proxy, \
736 proxy_username, proxy_password, debuginfo, \
737 source, gpgkey, disable, ssl_verify, nocache, \
740 def Repo(name, baseurl, mirrorlist=None, includepkgs=[], excludepkgs=[], proxy=None,
741 proxy_username=None, proxy_password=None, debuginfo=None,
742 source=None, gpgkey=None, disable=None, ssl_verify=None,
743 nocache=False, cost=None, priority=None):
744 return RepoType(name, baseurl, mirrorlist, includepkgs, excludepkgs, proxy,
745 proxy_username, proxy_password, debuginfo,
746 source, gpgkey, disable, ssl_verify, nocache,
750 def get_repos(ks, repo_urls=None, ignore_ksrepo=False):
752 for repodata in ks.handler.repo.repoList:
754 for field in RepoType._fields:
755 if hasattr(repodata, field) and getattr(repodata, field):
756 repo[field] = getattr(repodata, field)
758 if hasattr(repodata, 'baseurl') and getattr(repodata, 'baseurl'):
759 repo['baseurl'] = SafeURL(getattr(repodata, 'baseurl'),
760 getattr(repodata, 'user', None),
761 getattr(repodata, 'passwd', None))
764 repos[repo['name']] = Repo(**repo)
769 for name, repo in repo_urls.items():
770 if 'baseurl' in repo:
771 repo['baseurl'] = SafeURL(repo.get('baseurl'),
772 repo.get('user', None),
773 repo.get('passwd', None))
774 repos[name] = Repo(**repo)
776 return repos.values()
778 def convert_method_to_repo(ks):
780 ks.handler.repo.methodToRepo()
781 except (AttributeError, kserrors.KickstartError):
784 def get_attachment(ks, required=()):
785 return ks.handler.attachment.packageList + list(required)
787 def get_pre_packages(ks, required=()):
788 return ks.handler.prepackages.packageList + list(required)
790 def get_packages(ks, required=()):
791 return ks.handler.packages.packageList + list(required)
793 def get_groups(ks, required=()):
794 return ks.handler.packages.groupList + list(required)
796 def get_excluded(ks, required=()):
797 return ks.handler.packages.excludedList + list(required)
799 def get_partitions(ks):
800 return ks.handler.partition.partitions
802 def ignore_missing(ks):
803 return ks.handler.packages.handleMissing == ksconstants.KS_MISSING_IGNORE
805 def exclude_docs(ks):
806 return ks.handler.packages.excludeDocs
809 if hasattr(ks.handler.packages, "instLange"):
810 return ks.handler.packages.instLange
811 elif hasattr(ks.handler.packages, "instLangs"):
812 return ks.handler.packages.instLangs
815 def get_post_scripts(ks):
817 for s in ks.handler.scripts:
818 if s.type != ksparser.KS_SCRIPT_POST:
823 def get_sign_scripts(ks):
825 for s in ks.handler.scripts:
826 if s.type != ksparser.KS_SCRIPT_RUN:
830 def add_repo(ks, repostr):
831 args = repostr.split()
832 repoobj = ks.handler.repo.parse(args[1:])
833 if repoobj and repoobj not in ks.handler.repo.repoList:
834 ks.handler.repo.repoList.append(repoobj)
836 def remove_all_repos(ks):
837 while len(ks.handler.repo.repoList) != 0:
838 del ks.handler.repo.repoList[0]
840 def remove_duplicate_repos(ks):
844 if len(ks.handler.repo.repoList) < 2:
846 if i >= len(ks.handler.repo.repoList) - 1:
848 name = ks.handler.repo.repoList[i].name
849 baseurl = ks.handler.repo.repoList[i].baseurl
850 if j < len(ks.handler.repo.repoList):
851 if (ks.handler.repo.repoList[j].name == name or \
852 ks.handler.repo.repoList[j].baseurl == baseurl):
853 del ks.handler.repo.repoList[j]
856 if j >= len(ks.handler.repo.repoList):
863 def resolve_groups(creatoropts, repometadata):
865 if 'zypp' == creatoropts['pkgmgr']:
867 ks = creatoropts['ks']
869 for repo in repometadata:
870 """ Mustn't replace group with package list if repo is ready for the
871 corresponding package manager.
874 if iszypp and repo["patterns"]:
876 if not iszypp and repo["comps"]:
879 # But we also must handle such cases, use zypp but repo only has comps,
880 # use yum but repo only has patterns, use zypp but use_comps is true,
881 # use yum but use_comps is false.
883 if iszypp and repo["comps"]:
884 groupfile = repo["comps"]
885 get_pkglist_handler = misc.get_pkglist_in_comps
886 if not iszypp and repo["patterns"]:
887 groupfile = repo["patterns"]
888 get_pkglist_handler = misc.get_pkglist_in_patterns
893 if i >= len(ks.handler.packages.groupList):
895 pkglist = get_pkglist_handler(
896 ks.handler.packages.groupList[i].name,
899 del ks.handler.packages.groupList[i]
901 if pkg not in ks.handler.packages.packageList:
902 ks.handler.packages.packageList.append(pkg)