#!/usr/bin/python
#
# anaconda: The Red Hat Linux Installation program
#
# Copyright (C) 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007
# Red Hat, Inc. All rights reserved.
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see .
#
# Author(s): Brent Fox
# Mike Fulbright
# Jakub Jelinek
# Jeremy Katz
# Chris Lumens
# Paul Nasrat
# Erik Troan
# Matt Wilson
#
import os, time, string
import iutil
import isys
from tempfile import mkstemp
import logging
log = logging.getLogger("anaconda")
stdoutLog = logging.getLogger("anaconda.stdout")
import gettext
_ = lambda x: gettext.ldgettext("anaconda", x)
class Anaconda(object):
def __init__(self):
import desktop, dispatch, firewall, security
import system_config_keyboard.keyboard as keyboard
from flags import flags
self._backend = None
self._bootloader = None
self.canReIPL = False
self.desktop = desktop.Desktop()
self.dir = None
self.dispatch = dispatch.Dispatcher(self)
self.displayMode = None
self.extraModules = []
self.firewall = firewall.Firewall()
self.id = None
self._instClass = None
self._instLanguage = None
self._intf = None
self.isHeadless = False
self.keyboard = keyboard.Keyboard()
self.ksdata = None
self.mediaDevice = None
self.methodstr = None
self._network = None
self._platform = None
self.proxy = None
self.proxyUsername = None
self.proxyPassword = None
self.reIPLMessage = None
self.rescue = False
self.rescue_mount = True
self.rootParts = None
self.rootPath = "/mnt/sysimage"
self.security = security.Security()
self.simpleFilter = not iutil.isS390()
self.stage2 = None
self._storage = None
self._timezone = None
self.updateSrc = None
self.upgrade = flags.cmdline.has_key("preupgrade")
self.upgradeRoot = None
self.upgradeSwapInfo = None
self._users = None
self.mehConfig = None
# *sigh* we still need to be able to write this out
self.xdriver = None
@property
def backend(self):
if not self._backend:
b = self.instClass.getBackend()
self._backend = apply(b, (self, ))
return self._backend
@property
def bootloader(self):
if not self._bootloader:
import booty
self._bootloader = booty.getBootloader(self)
return self._bootloader
@property
def firstboot(self):
from pykickstart.constants import FIRSTBOOT_SKIP, FIRSTBOOT_DEFAULT
if self.ksdata:
return self.ksdata.firstboot.firstboot
elif iutil.isS390():
return FIRSTBOOT_SKIP
else:
return FIRSTBOOT_DEFAULT
@property
def instClass(self):
if not self._instClass:
from installclass import DefaultInstall
self._instClass = DefaultInstall()
return self._instClass
@property
def instLanguage(self):
if not self._instLanguage:
import language
self._instLanguage = language.Language(self.displayMode)
return self._instLanguage
def _getInterface(self):
return self._intf
def _setInterface(self, v):
# "lambda cannot contain assignment"
self._intf = v
def _delInterface(self):
del self._intf
intf = property(_getInterface, _setInterface, _delInterface)
@property
def network(self):
if not self._network:
import network
self._network = network.Network()
return self._network
@property
def platform(self):
if not self._platform:
from pyanaconda import platform
self._platform = platform.getPlatform(self)
return self._platform
@property
def protected(self):
import stat
if os.path.exists("/dev/live") and \
stat.S_ISBLK(os.stat("/dev/live")[stat.ST_MODE]):
return [os.readlink("/dev/live")]
elif self.methodstr and self.methodstr.startswith("hd:"):
method = self.methodstr[3:]
return [method.split(":", 3)[0]]
else:
return []
@property
def users(self):
if not self._users:
import users
self._users = users.Users(self)
return self._users
@property
def storage(self):
if not self._storage:
import storage
self._storage = storage.Storage(self)
return self._storage
@property
def timezone(self):
if not self._timezone:
import timezone
self._timezone = timezone.Timezone()
self._timezone.setTimezoneInfo(self.instLanguage.getDefaultTimeZone(self.rootPath))
return self._timezone
def dumpState(self):
from meh.dump import ReverseExceptionDump
from inspect import stack as _stack
# Skip the frames for dumpState and the signal handler.
stack = _stack()[2:]
stack.reverse()
exn = ReverseExceptionDump((None, None, stack), self.mehConfig)
(fd, filename) = mkstemp("", "anaconda-tb-", "/tmp")
fo = os.fdopen(fd, "w")
exn.write(self, fo)
def initInterface(self):
if self._intf:
raise RuntimeError, "Second attempt to initialize the InstallInterface"
# setup links required by graphical mode if installing and verify display mode
if self.displayMode == 'g':
stdoutLog.info (_("Starting graphical installation."))
try:
from gui import InstallInterface
except Exception, e:
from flags import flags
stdoutLog.error("Exception starting GUI installer: %s" %(e,))
# if we're not going to really go into GUI mode, we need to get
# back to vc1 where the text install is going to pop up.
if not flags.livecdInstall:
isys.vtActivate (1)
stdoutLog.warning("GUI installer startup failed, falling back to text mode.")
self.displayMode = 't'
if 'DISPLAY' in os.environ.keys():
del os.environ['DISPLAY']
time.sleep(2)
if self.displayMode == 't':
from text import InstallInterface
if not os.environ.has_key("LANG"):
os.environ["LANG"] = "en_US.UTF-8"
if self.displayMode == 'c':
from cmdline import InstallInterface
self._intf = InstallInterface()
return self._intf
def writeXdriver(self, root = None):
# this should go away at some point, but until it does, we
# need to keep it around.
if self.xdriver is None:
return
if root is None:
root = self.rootPath
if not os.path.isdir("%s/etc/X11" %(root,)):
os.makedirs("%s/etc/X11" %(root,), mode=0755)
f = open("%s/etc/X11/xorg.conf" %(root,), 'w')
f.write('Section "Device"\n\tIdentifier "Videocard0"\n\tDriver "%s"\nEndSection\n' % self.xdriver)
f.close()
def setMethodstr(self, methodstr):
if methodstr.startswith("cdrom://"):
(device, tree) = string.split(methodstr[8:], ":", 1)
if not tree.startswith("/"):
tree = "/%s" %(tree,)
if device.startswith("/dev/"):
device = device[5:]
self.mediaDevice = device
self.methodstr = "cdrom://%s" % tree
else:
self.methodstr = methodstr
def requiresNetworkInstall(self):
fail = False
numNetDevs = isys.getNetworkDeviceCount()
if self.methodstr is not None:
if (self.methodstr.startswith("http") or \
self.methodstr.startswith("ftp://") or \
self.methodstr.startswith("nfs:")) and \
numNetDevs == 0:
fail = True
elif self.stage2 is not None:
if self.stage2.startswith("cdrom://") and \
not os.path.isdir("/mnt/stage2/Packages") and \
numNetDevs == 0:
fail = True
if fail:
log.error("network install required, but no network devices available")
return fail
def write(self):
self.writeXdriver()
self.instLanguage.write(self.rootPath)
self.timezone.write(self.rootPath)
self.network.write()
self.network.copyConfigToPath(instPath=self.rootPath)
self.network.disableNMForStorageDevices(self,
instPath=self.rootPath)
self.desktop.write(self.rootPath)
self.users.write(self.rootPath)
self.security.write(self.rootPath)
self.firewall.write(self.rootPath)
if self.ksdata:
for svc in self.ksdata.services.disabled:
iutil.execWithRedirect("/sbin/chkconfig",
[svc, "off"],
stdout="/dev/tty5", stderr="/dev/tty5",
root=self.rootPath)
for svc in self.ksdata.services.enabled:
iutil.execWithRedirect("/sbin/chkconfig",
[svc, "on"],
stdout="/dev/tty5", stderr="/dev/tty5",
root=self.rootPath)
def writeKS(self, filename):
import urllib
from pykickstart.version import versionToString, DEVEL
f = open(filename, "w")
f.write("# Kickstart file automatically generated by anaconda.\n\n")
f.write("#version=%s\n" % versionToString(DEVEL))
if self.upgrade:
f.write("upgrade\n")
else:
f.write("install\n")
m = None
if self.methodstr:
m = self.methodstr
elif self.stage2:
m = self.stage2
if m:
if m.startswith("cdrom:"):
f.write("cdrom\n")
elif m.startswith("hd:"):
if m.count(":") == 3:
(part, fs, dir) = string.split(m[3:], ":")
else:
(part, dir) = string.split(m[3:], ":")
f.write("harddrive --partition=%s --dir=%s\n" % (part, dir))
elif m.startswith("nfs:"):
if m.count(":") == 3:
(opts, server, dir) = string.split(m[4:], ":")
f.write("nfs --server=%s --opts=%s --dir=%s\n" % (server, opts, dir))
else:
(server, dir) = string.split(m[4:], ":")
f.write("nfs --server=%s --dir=%s\n" % (server, dir))
elif m.startswith("ftp://") or m.startswith("http"):
f.write("url --url=%s\n" % urllib.unquote(m))
# Some kickstart commands do not correspond to any anaconda UI
# component. If this is a kickstart install, we need to make sure
# the information from the input file ends up in the output file.
if self.ksdata:
f.write(self.ksdata.user.__str__())
f.write(self.ksdata.services.__str__())
f.write(self.ksdata.reboot.__str__())
self.instLanguage.writeKS(f)
if not self.isHeadless:
self.keyboard.writeKS(f)
self.network.writeKS(f)
self.timezone.writeKS(f)
self.users.writeKS(f)
self.security.writeKS(f)
self.firewall.writeKS(f)
self.storage.writeKS(f)
self.bootloader.writeKS(f)
if self.backend:
self.backend.writeKS(f)
self.backend.writePackagesKS(f, self)
# Also write out any scripts from the input ksfile.
if self.ksdata:
for s in self.ksdata.scripts:
f.write(s.__str__())
# make it so only root can read, could have password
os.chmod(filename, 0600)