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