#!/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 # # This toplevel file is a little messy at the moment... import atexit, sys, os, re, time, subprocess from tempfile import mkstemp # keep up with process ID of the window manager if we start it wm_pid = None def exitHandler(anaconda, exitCode=None): from pyanaconda import isys from pyanaconda.flags import flags if exitCode: anaconda.intf.shutdown() if "nokill" in flags.cmdline: isys.vtActivate(1) print "anaconda halting due to nokill flag." print "The system will be rebooted when you press Ctrl-Alt-Delete." while True: time.sleep(10000) if image_count: anaconda.storage.umountFilesystems(ignoreErrors=True, swapoff=False) devicetree = anaconda.storage.devicetree devicetree.teardownAll() for name in devicetree.diskImages: device = devicetree.getDeviceByName(name) for loop in device.parents: loop.controllable = True device.deactivate(recursive=True) if anaconda.ksdata and not flags.imageInstall: from pykickstart.constants import KS_SHUTDOWN, KS_WAIT, KS_REBOOT from pyanaconda.iutil import dracut_eject if anaconda.ksdata.reboot.eject: for drive in anaconda.storage.devicetree.devices: if drive.type != "cdrom": continue dracut_eject(drive.path) if anaconda.ksdata.reboot.action == KS_SHUTDOWN: os.system("systemctl --force --no-wall poweroff") elif anaconda.ksdata.reboot.action == KS_WAIT: os.system("systemctl --force --no-wall halt") else: # reboot action is KS_REBOOT or None os.system("systemctl --force --no-wall reboot") elif not flags.imageInstall: os.system("systemctl --force --no-wall reboot") def startMetacityWM(): childpid = os.fork() if not childpid: # after this point the method should never return (or throw an exception # outside) try: args = ['--display', ':1', '--sm-disable'] iutil.execWithRedirect('metacity', args, stdout='/dev/null', stderr='/dev/null') except BaseException as e: # catch all possible exceptions log.error("Problems running the window manager: %s" % str(e)) sys.exit(1) log.info("The window manager has terminated.") sys.exit(0) return childpid def startAuditDaemon(): childpid = os.fork() if not childpid: cmd = '/sbin/auditd' try: os.execl(cmd, cmd) except OSError as e: log.error("Error running the audit daemon: %s" % str(e)) sys.exit(0) # auditd will turn into a daemon so catch the immediate child pid now: os.waitpid(childpid, 0) # function to handle X startup special issues for anaconda def doStartupX11Actions(): global wm_pid # pid of the anaconda fork where the window manager is running setupGraphicalLinks() # now start up the window manager wm_pid = startMetacityWM() log.info("Starting window manager, pid %s." % (wm_pid,)) def set_x_resolution(runres): # cant do this if no window manager is running because otherwise when we # open and close an X connection in the xutils calls the X server will exit # since this is the first X connection (if no window manager is running) if runres and opts.display_mode == 'g' and not flags.usevnc and wm_pid : try: log.info("Setting the screen resolution to: %s.", runres) iutil.execWithRedirect("xrandr", ["-d", ":1", "-s", runres], stdout="/dev/tty5", stderr="/dev/tty5") except RuntimeError as e: log.error("The X resolution not set") iutil.execWithRedirect("xrandr", ["-d", ":1", "-q"], stdout="/dev/tty5", stderr="/dev/tty5") def setupPythonUpdates(): from distutils.sysconfig import get_python_lib if not os.path.exists("/tmp/updates"): return for pkg in os.listdir("/tmp/updates"): d = "/tmp/updates/%s" % pkg if not os.path.isdir(d): continue # See if the package exists in /usr/lib{64,}/python/?.?/site-packages. # If it does, we can set it up as an update. If not, the pkg is # likely a completely new directory and should not be looked at. dest = "%s/%s" % (get_python_lib(), pkg) if not os.access(dest, os.R_OK): dest = "%s/%s" % (get_python_lib(1), pkg) if not os.access(dest, os.R_OK): continue # Symlink over everything that's in the python libdir but not in # the updates directory. symlink_updates(dest, d) import glob import shutil for rule in glob.glob("/tmp/updates/*.rules"): target = "/etc/udev/rules.d/" + rule.split('/')[-1] shutil.copyfile(rule, target) def symlink_updates(dest_dir, update_dir): contents = os.listdir(update_dir) for f in os.listdir(dest_dir): dest_path = os.path.join(dest_dir, f) update_path = os.path.join(update_dir, f) if f in contents: # recurse into directories, there might be files missing in updates if os.path.isdir(dest_path) and os.path.isdir(update_path): symlink_updates(dest_path, update_path) else: if f.endswith(".pyc") or f.endswith(".pyo"): continue os.symlink(dest_path, update_path) def getAnacondaVersion(): # Using _isys here so we don't drag in the logging stuff, which is always # complicated. from pyanaconda import _isys return _isys.getAnacondaVersion() def parseOptions(argv = None): from pyanaconda.anaconda_optparse import AnacondaOptionParser op = AnacondaOptionParser(version="%prog " + getAnacondaVersion(), bootarg_prefix="inst.", require_prefix=False) # Interface op.add_option("-C", "--cmdline", dest="display_mode", action="store_const", const="c", default="g") op.add_option("-G", "--graphical", dest="display_mode", action="store_const", const="g") op.add_option("-T", "--text", dest="display_mode", action="store_const", const="t") op.add_option("-S", "--script", dest="display_mode", action="store_const", const="s") # Network op.add_option("--noipv4", action="store_true", default=False) op.add_option("--noipv6", action="store_true", default=False) op.add_option("--proxy") op.add_option("--proxyAuth") # Method of operation op.add_option("--autostep", action="store_true", default=False) op.add_option("-d", "--debug", dest="debug", action="store_true", default=False) op.add_option("--ks", dest="ksfile", action="store_const", const="/run/install/ks.cfg") op.add_option("--kickstart", dest="ksfile") op.add_option("--rescue", dest="rescue", action="store_true", default=False) op.add_option("--targetarch", "rpmarch", dest="targetArch", type="string") op.add_option("-m", "--method", dest="method", default=None) op.add_option("--repo", dest="method", default=None) op.add_option("--stage2", dest="stage2", default=None) op.add_option("--noverifyssl", action="store_true", default=False) op.add_option("--liveinst", action="store_true", default=False) # Display op.add_option("--headless", dest="isHeadless", action="store_true", default=False) op.add_option("--nofb") op.add_option("--resolution", dest="runres", default=None) op.add_option("--serial", action="store_true", default=False) op.add_option("--usefbx", dest="xdriver", action="store_const", const="fbdev") op.add_option("--virtpconsole") op.add_option("--vnc", action="store_true", default=False) op.add_option("--vncconnect") op.add_option("--vncpassword", default="") op.add_option("--xdriver", dest="xdriver", action="store", type="string", default=None) # Language op.add_option("--keymap") op.add_option("--kbdtype") op.add_option("--lang") # Obvious op.add_option("--loglevel") op.add_option("--syslog") op.add_option("--noselinux", dest="selinux", action="store_false", default=True) op.add_option("--selinux", action="store_true") op.add_option("--nompath", dest="mpath", action="store_false", default=True) op.add_option("--mpath", action="store_true") op.add_option("--nodmraid", dest="dmraid", action="store_false", default=True) op.add_option("--dmraid", action="store_true") op.add_option("--noibft", dest="ibft", action="store_false", default=True) op.add_option("--ibft", action="store_true") op.add_option("--noiscsi", dest="iscsi", action="store_false", default=False) op.add_option("--iscsi", action="store_true") # Miscellaneous op.add_option("--module", action="append", default=[]) op.add_option("--nomount", dest="rescue_nomount", action="store_true", default=False) op.add_option("--updates", dest="updateSrc", action="store", type="string") op.add_option("--dlabel", action="store_true", default=False) op.add_option("--image", action="append", dest="images", default=[]) op.add_option("--memcheck", action="store_true", default=True) op.add_option("--no-memcheck", action="store_false", dest="memcheck") (opts, args) = op.parse_args(argv) return (opts, args, op.deprecated_bootargs) def setupPythonPath(): sys.path.append('/usr/share/system-config-date') def setupEnvironment(): # Silly GNOME stuff if os.environ.has_key('HOME') and not os.environ.has_key("XAUTHORITY"): os.environ['XAUTHORITY'] = os.environ['HOME'] + '/.Xauthority' os.environ['HOME'] = '/tmp' os.environ['LC_NUMERIC'] = 'C' os.environ["GCONF_GLOBAL_LOCKS"] = "1" # In theory, this gets rid of our LVM file descriptor warnings os.environ["LVM_SUPPRESS_FD_WARNINGS"] = "1" # make sure we have /sbin and /usr/sbin in our path os.environ["PATH"] += ":/sbin:/usr/sbin" # we can't let the LD_PRELOAD hang around because it will leak into # rpm %post and the like. ick :/ if os.environ.has_key("LD_PRELOAD"): del os.environ["LD_PRELOAD"] os.environ["GLADEPATH"] = "/tmp/updates/:/tmp/updates/data/ui/:ui/:/usr/share/anaconda/ui/:/usr/share/python-meh/" os.environ["PIXMAPPATH"] = "/tmp/updates/pixmaps/:/tmp/updates/:/tmp/product/pixmaps/:/tmp/product/:pixmaps/:/usr/share/anaconda/pixmaps/:/usr/share/pixmaps/:/usr/share/anaconda/:/usr/share/python-meh/:/usr/share/icons/Fedora/48x48/apps/" def setupLoggingFromOpts(opts): if opts.loglevel and anaconda_log.logLevelMap.has_key(opts.loglevel): level = anaconda_log.logLevelMap[opts.loglevel] anaconda_log.logger.tty_loglevel = level anaconda_log.setHandlersLevel(log, level) storage_log = logging.getLogger("storage") anaconda_log.setHandlersLevel(storage_log, level) if opts.syslog: anaconda_log.logger.remote_syslog = opts.syslog # ftp installs pass the password via a file in /tmp so # ps doesn't show it def expandFTPMethod(str): ret = None try: filename = str[1:] ret = open(filename, "r").readline() ret = ret[:len(ret) - 1] os.unlink(filename) return ret except: return None def runVNC(vncS): vncS.startServer() child = os.fork() if child == 0: for p in ('/tmp/updates/pyrc.py', \ '/usr/share/anaconda/pyrc.py'): if os.access(p, os.R_OK|os.X_OK): os.environ['PYTHONSTARTUP'] = p break while True: # Not having a virtual terminal or otherwise free console # are the only places we /really/ need a shell on tty1, # and everywhere else this just gets in the way of pdb. But we # don't want to return, because that'll return try to start X # a second time. if iutil.isConsoleOnVirtualTerminal() or iutil.isS390(): time.sleep(10000) else: print _("Press for a shell") sys.stdin.readline() iutil.execConsole() def gtk_warning(title, reason): import gtk dialog = gtk.MessageDialog(type = gtk.MESSAGE_ERROR, buttons = gtk.BUTTONS_CLOSE, message_format=reason) dialog.set_title(title) dialog.run() dialog.destroy() def check_memory(anaconda, opts, display_mode=None): reason_strict = _("%s requires %s MB of memory to install, but you only have " "%s MB on this machine.\n") reason_graphical = _("The %s graphical installer requires %s MB of memory, but " "you only have %s MB.") reboot_extra = _('\n' 'Press to reboot your system.\n') livecd_title = _("Not enough RAM") livecd_extra =_(" Try the text mode installer by running:\n\n" "'/usr/bin/liveinst -T'\n\n from a root " "terminal.") nolivecd_extra = _(" Starting text mode.") if not display_mode: display_mode = anaconda.displayMode reason = reason_strict total_ram = int(isys.total_memory() / 1024) needed_ram = int(isys.MIN_RAM / 1024) graphical_ram = needed_ram + int(isys.GUI_INSTALL_EXTRA_RAM / 1024) log.info("check_memory(): total:%s, needed:%s, graphical:%s" % \ (total_ram, needed_ram, graphical_ram)) if not opts.memcheck: log.warning("CHECK_MEMORY DISABLED") return if needed_ram > total_ram: from snack import SnackScreen, ButtonChoiceWindow if opts.liveinst: stdoutLog.warning(reason % (product.productName, needed_ram, total_ram)) gtk_warning(livecd_title, reason % (product.productName, needed_ram, total_ram)) else: reason += reboot_extra screen = SnackScreen() ButtonChoiceWindow(screen, _('Fatal Error'), reason % (product.productName, needed_ram, total_ram), buttons = (_("OK"),)) screen.finish() sys.exit(1) # override display mode if machine cannot nicely run X if display_mode not in ('t', 'c', 's') and not flags.usevnc: needed_ram = graphical_ram reason = reason_graphical if needed_ram > total_ram: if opts.liveinst: reason += livecd_extra stdoutLog.warning(reason % (product.productName, needed_ram, total_ram)) title = livecd_title gtk_warning(title, reason % (product.productName, needed_ram, total_ram)) sys.exit(1) else: reason += nolivecd_extra stdoutLog.warning(reason % (product.productName, needed_ram, total_ram)) anaconda.displayMode = 't' time.sleep(2) def setupGraphicalLinks(): for i in ( "imrc", "im_palette.pal", "gtk-2.0", "pango", "fonts", "fb.modes"): try: if os.path.exists("/mnt/runtime/etc/%s" %(i,)): os.symlink ("../mnt/runtime/etc/" + i, "/etc/" + i) except: pass def startDebugger(signum, frame): import epdb epdb.serve(skip=1) def setupDisplay(anaconda, opts): graphical_failed = 0 vncS = vnc.VncServer() # The vnc Server object. vncS.anaconda = anaconda anaconda.displayMode = opts.display_mode anaconda.isHeadless = opts.isHeadless if opts.vnc: flags.usevnc = 1 anaconda.displayMode = 'g' vncS.password = opts.vncpassword # Only consider vncconnect when vnc is a param if opts.vncconnect: cargs = string.split(opts.vncconnect, ":") vncS.vncconnecthost = cargs[0] if len(cargs) > 1 and len(cargs[1]) > 0: if len(cargs[1]) > 0: vncS.vncconnectport = cargs[1] if opts.serial: flags.serial = True if opts.virtpconsole: flags.virtpconsole = opts.virtpconsole if opts.xdriver: anaconda.xdriver = opts.xdriver anaconda.writeXdriver(root="/") if anaconda.rescue: anaconda.displayMode = 'r' else: if anaconda.ksdata: if anaconda.ksdata.vnc.enabled: flags.usevnc = 1 anaconda.displayMode = 'g' if vncS.password == "": vncS.password = anaconda.ksdata.vnc.password if vncS.vncconnecthost == "": vncS.vncconnecthost = anaconda.ksdata.vnc.host if vncS.vncconnectport == "": vncS.vncconnectport = anaconda.ksdata.vnc.port flags.vncquestion = False # disable VNC over text question when not enough memory is available if iutil.memInstalled() < isys.MIN_GUI_RAM: flags.vncquestion = False if os.environ.has_key('DISPLAY'): flags.preexisting_x11 = True if anaconda.displayMode == 't' and flags.vncquestion: #we prefer vnc over text mode, so ask about that title = _("Would you like to use VNC?") message = _("Text mode provides a limited set of installation " "options. It does not allow you to specify your " "own partitioning layout or package selections. " "Would you like to use VNC mode instead?") ret = vnc.askVncWindow(title, message) if ret != -1: anaconda.displayMode = 'g' flags.usevnc = 1 if ret is not None: vncS.password = ret log.info("Display mode = %s" % anaconda.displayMode) check_memory(anaconda, opts) # # now determine if we're going to run in GUI or TUI mode # # if no X server, we have to use text mode if anaconda.displayMode == 'g' and not flags.livecdInstall \ and not iutil.isS390() \ and not os.access("/usr/bin/Xorg", os.X_OK): stdoutLog.warning(_("Graphical installation is not available. " "Starting text mode.")) time.sleep(2) anaconda.displayMode = 't' # s390/iSeries checks if anaconda.isHeadless and anaconda.displayMode == "g" and not \ (flags.preexisting_x11 or flags.usevnc): stdoutLog.warning(_("DISPLAY variable not set. Starting text mode.")) anaconda.displayMode = 't' graphical_failed = 1 time.sleep(2) # if DISPLAY not set either vnc server failed to start or we're not # running on a redirected X display, so start local X server if anaconda.displayMode == 'g' and not flags.preexisting_x11 and \ not flags.usevnc: # The following code depends on no SIGCHLD being delivered, # possibly only except the one from a failing X.org. Thus # make sure before entering this section that all the other # children of anaconda have terminated or were forked into # an orphan (which won't deliver a SIGCHLD to mess up the # fragile signaling below). start X with its USR1 handler # set to ignore. this will make it send us SIGUSR1 if it # succeeds. if it fails, catch SIGCHLD and bomb out. def sigchld_handler(num, frame): raise OSError(0, "SIGCHLD caught when trying to start the X server.") def sigusr1_handler(num, frame): log.debug("X server has signalled a successful start.") def preexec_fn(): signal.signal(signal.SIGUSR1, signal.SIG_IGN) old_sigusr1 = signal.signal(signal.SIGUSR1, sigusr1_handler) old_sigchld = signal.signal(signal.SIGCHLD, sigchld_handler) xout = open("/dev/tty5", "w") try: proc = subprocess.Popen(["Xorg", "-br", "-logfile", "/tmp/X.log", ":1", "vt6", "-s", "1440", "-ac", "-nolisten", "tcp", "-dpi", "96", "-noreset"], close_fds=True, stdout=xout, stderr=xout, preexec_fn=preexec_fn) signal.pause() os.environ["DISPLAY"] = ":1" doStartupX11Actions() except (OSError, RuntimeError): stdoutLog.warning("X startup failed, falling back to text mode") anaconda.displayMode = 't' graphical_failed = 1 time.sleep(2) finally: signal.signal(signal.SIGUSR1, old_sigusr1) signal.signal(signal.SIGCHLD, old_sigchld) set_x_resolution(opts.runres) if anaconda.displayMode == 't' and graphical_failed and \ not anaconda.ksdata: ret = vnc.askVncWindow() if ret != -1: anaconda.displayMode = 'g' flags.usevnc = 1 if ret is not None: vncS.password = ret # if they want us to use VNC do that now if anaconda.displayMode == 'g' and flags.usevnc: runVNC(vncS) doStartupX11Actions() # with X running we can initialize the UI interface anaconda.initInterface() anaconda.instClass.configure(anaconda) if __name__ == "__main__": setupPythonPath() # Allow a file to be loaded as early as possible try: import updates_disk_hook except ImportError: pass # this handles setting up updates for pypackages to minimize the set needed setupPythonUpdates() # do this early so we can set flags before initializing logging (opts, args, depr) = parseOptions() from pyanaconda.flags import flags if opts.images: flags.imageInstall = True # Set up logging as early as possible. import logging from pyanaconda import anaconda_log anaconda_log.init() log = logging.getLogger("anaconda") stdoutLog = logging.getLogger("anaconda.stdout") if os.geteuid() != 0: stdoutLog.error("anaconda must be run as root.") sys.exit(0) log.info("%s %s" % (sys.argv[0], getAnacondaVersion())) for arg in depr: stdoutLog.warn("Boot argument '%s' is deprecated. " "In the future, use 'inst.%s'.", arg, arg) # pull this in to get product name and versioning from pyanaconda import product from pyanaconda.constants import ROOT_PATH, DEFAULT_LANG from pyanaconda import isys isys.initLog() import signal, string, time from pyanaconda import iutil from pyanaconda import vnc from pyanaconda import kickstart # Write out the default locale before anything imports locale (#731356) deflang, defcode = DEFAULT_LANG.split('.') iutil.execWithRedirect("localedef", ["-i", deflang, "-f", defcode, DEFAULT_LANG]) import gettext _ = lambda x: gettext.ldgettext("anaconda", x) from pyanaconda import Anaconda anaconda = Anaconda() iutil.setup_translations(gettext) # reset python's default SIGINT handler signal.signal(signal.SIGINT, signal.SIG_DFL) signal.signal(signal.SIGSEGV, isys.handleSegv) setupEnvironment() # make sure we have /var/log soon, some programs fail to start without it iutil.mkdirChain("/var/log") pidfile = open("/var/run/anaconda.pid", "w") pidfile.write("%s\n" % (os.getpid(),)) del pidfile # add our own additional signal handlers signal.signal(signal.SIGHUP, startDebugger) anaconda.opts = opts # check memory, just the text mode for now: check_memory(anaconda, opts, 't') # Now that we've got arguments, do some extra processing. setupLoggingFromOpts(opts) # Default is to prompt to mount the installed system. anaconda.rescue_mount = not opts.rescue_nomount if opts.dlabel: #autodetected driverdisc in use flags.dlabel = True if opts.noipv4: flags.useIPv4 = False if opts.noipv6: flags.useIPv6 = False if opts.proxy: anaconda.proxy = opts.proxy if opts.proxyAuth: filename = opts.proxyAuth ret = open(filename, "r").readlines() os.unlink(filename) anaconda.proxyUsername = ret[0].rstrip() if len(ret) == 2: anaconda.proxyPassword = ret[1].rstrip() if opts.updateSrc: anaconda.updateSrc = opts.updateSrc if opts.method: if opts.method[0] == '@': opts.method = expandFTPMethod(opts.method) anaconda.setMethodstr(opts.method) else: anaconda.methodstr = None if opts.stage2: if opts.stage2[0] == '@': opts.stage2 = expandFTPMethod(opts.stage2) anaconda.stage2 = opts.stage2 if opts.noverifyssl: flags.noverifyssl = True if opts.liveinst: flags.livecdInstall = True if opts.module: for mod in opts.module: (path, name) = string.split(mod, ":") anaconda.extraModules.append((path, name)) if opts.ibft: flags.ibft = 1 if opts.iscsi: flags.iscsi = 1 if opts.targetArch: flags.targetarch = opts.targetArch # set flags flags.dmraid = opts.dmraid flags.mpath = opts.mpath flags.selinux = opts.selinux if not flags.livecdInstall and not flags.imageInstall: startAuditDaemon() # setup links required for all install types for i in ( "services", "protocols", "nsswitch.conf", "joe", "selinux", "mke2fs.conf" ): try: if os.path.exists("/mnt/runtime/etc/" + i): os.symlink ("../mnt/runtime/etc/" + i, "/etc/" + i) except: pass if opts.debug: flags.debug = True if opts.rescue: anaconda.rescue = True log.info("anaconda called with cmdline = %s" %(sys.argv,)) log.info("Default encoding = %s " % sys.getdefaultencoding()) os.system("udevadm control --env=ANACONDA=1") # parse (not execute) kickstart now, the ks commands can affect things like # UI interface type or enabling rescue mode if opts.ksfile: kickstart.preScriptPass(anaconda, opts.ksfile) anaconda.ksdata = kickstart.parseKickstart(anaconda, opts.ksfile) if anaconda.ksdata.rescue.rescue: anaconda.rescue = True # Setup the storage config options from the kickstart file anaconda.storage.config.zeroMbr = anaconda.ksdata.zerombr.zerombr anaconda.storage.config.ignoreDiskInteractive = anaconda.ksdata.ignoredisk.interactive anaconda.storage.config.ignoredDisks = anaconda.ksdata.ignoredisk.ignoredisk anaconda.storage.config.exclusiveDisks = anaconda.ksdata.ignoredisk.onlyuse if anaconda.ksdata.clearpart.type is not None: anaconda.storage.config.clearPartType = anaconda.ksdata.clearpart.type anaconda.storage.config.clearPartDisks = anaconda.ksdata.clearpart.drives if anaconda.ksdata.clearpart.initAll: anaconda.storage.config.reinitializeDisks = anaconda.ksdata.clearpart.initAll # now start the interface setupDisplay(anaconda, opts) # setting the install steps requires interface to be running if opts.ksfile: kickstart.setSteps(anaconda) else: anaconda.instClass.setSteps(anaconda) if anaconda.rescue: anaconda.dispatch.request_steps("rescue") image_count = 0 for image in opts.images: image_spec = image.rsplit(":", 1) path = image_spec[0] if len(image_spec) == 2 and image_spec[1].strip(): name = image_spec[1].strip() else: name = os.path.splitext(os.path.basename(path))[0] if "/" in name or name in anaconda.storage.config.diskImages.keys(): name = "diskimg%d" % image_count log.info("naming disk image '%s' '%s'" % (path, name)) anaconda.storage.config.diskImages[name] = path image_count += 1 flags.imageInstall = True if image_count: anaconda.storage.setupDiskImages() anaconda.dispatch.skip_steps("filtertype") anaconda.simpleFilter = True # comment out the next line to make exceptions non-fatal from pyanaconda.exception import initExceptionHandling anaconda.mehConfig = initExceptionHandling(anaconda) # add our own additional signal handlers signal.signal(signal.SIGUSR2, lambda signum, frame: anaconda.dumpState()) if opts.lang: # this is lame, but make things match what we expect (#443408) opts.lang = opts.lang.replace(".utf8", ".UTF-8") anaconda.dispatch.skip_steps("language") anaconda.instLanguage.instLang = opts.lang anaconda.instLanguage.buildLocale() anaconda.instLanguage.systemLang = opts.lang anaconda.timezone.setTimezoneInfo(anaconda.instLanguage.getDefaultTimeZone()) if opts.keymap: anaconda.dispatch.skip_steps("keyboard") anaconda.keyboard.set(opts.keymap) anaconda.keyboard.activate() # set up the headless case if anaconda.isHeadless: anaconda.dispatch.skip_steps("keyboard") atexit.register(exitHandler, anaconda) try: anaconda.dispatch.run() except SystemExit as code: exitHandler(anaconda, code) except RuntimeError as errtxt: if anaconda.displayMode == 'c': print errtxt while True: time.sleep(10000) raise # vim:tw=78:ts=4:et:sw=4