2011-01-18 09:24:57 +00:00
|
|
|
#
|
|
|
|
# text.py - text mode frontend to anaconda
|
|
|
|
#
|
|
|
|
# Copyright (C) 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006 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 <http://www.gnu.org/licenses/>.
|
|
|
|
#
|
|
|
|
# Author(s): Erik Troan <ewt@redhat.com>
|
|
|
|
# Matt Wilson <msw@redhat.com>
|
|
|
|
#
|
|
|
|
|
|
|
|
from snack import *
|
|
|
|
import sys
|
|
|
|
import os
|
|
|
|
import isys
|
|
|
|
import iutil
|
|
|
|
import time
|
2013-01-23 17:28:19 +00:00
|
|
|
import traceback
|
2011-01-18 09:24:57 +00:00
|
|
|
import signal
|
|
|
|
import parted
|
|
|
|
import product
|
|
|
|
import string
|
|
|
|
from flags import flags
|
2013-01-23 17:28:19 +00:00
|
|
|
from textw.constants_text import *
|
2011-01-18 09:24:57 +00:00
|
|
|
from constants import *
|
2013-01-23 17:28:19 +00:00
|
|
|
from network import hasActiveNetDev, getDevices
|
2011-01-18 09:24:57 +00:00
|
|
|
from installinterfacebase import InstallInterfaceBase
|
2013-01-23 17:28:19 +00:00
|
|
|
import imp
|
|
|
|
import textw
|
2011-01-18 09:24:57 +00:00
|
|
|
|
|
|
|
import gettext
|
|
|
|
_ = lambda x: gettext.ldgettext("anaconda", x)
|
|
|
|
P_ = lambda x, y, z: gettext.ldngettext("anaconda", x, y, z)
|
|
|
|
|
|
|
|
import logging
|
|
|
|
log = logging.getLogger("anaconda")
|
|
|
|
|
|
|
|
stepToClasses = {
|
|
|
|
"language" : ("language_text", "LanguageWindow"),
|
|
|
|
"keyboard" : ("keyboard_text", "KeyboardWindow"),
|
|
|
|
"parttype" : ("partition_text", "PartitionTypeWindow"),
|
|
|
|
"upgrademigratefs" : ("upgrade_text", "UpgradeMigrateFSWindow"),
|
2013-01-23 17:28:19 +00:00
|
|
|
"findinstall" : ("upgrade_text", "UpgradeExamineWindow"),
|
2011-01-18 09:24:57 +00:00
|
|
|
"upgbootloader": ("upgrade_bootloader_text", "UpgradeBootloaderWindow"),
|
2013-01-23 17:28:19 +00:00
|
|
|
"network" : ("network_text", "HostnameWindow"),
|
2011-01-18 09:24:57 +00:00
|
|
|
"timezone" : ("timezone_text", "TimezoneWindow"),
|
|
|
|
"accounts" : ("userauth_text", "RootPasswordWindow"),
|
|
|
|
"tasksel": ("task_text", "TaskWindow"),
|
|
|
|
"install" : ("progress_text", "setupForInstall"),
|
|
|
|
"complete" : ("complete_text", "FinishedWindow"),
|
2013-01-23 17:28:19 +00:00
|
|
|
"bootloader" : ("zipl_text", ( "ZiplWindow"))
|
2011-01-18 09:24:57 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
class InstallWindow:
|
|
|
|
def __call__ (self, screen):
|
|
|
|
raise RuntimeError, "Unimplemented screen"
|
|
|
|
|
|
|
|
class WaitWindow:
|
|
|
|
def pop(self):
|
|
|
|
self.screen.popWindow()
|
|
|
|
self.screen.refresh()
|
|
|
|
|
|
|
|
def refresh(self):
|
|
|
|
pass
|
|
|
|
|
|
|
|
def __init__(self, screen, title, text):
|
|
|
|
self.screen = screen
|
|
|
|
width = 40
|
|
|
|
if (len(text) < width): width = len(text)
|
|
|
|
|
|
|
|
t = TextboxReflowed(width, text)
|
|
|
|
|
|
|
|
g = GridForm(self.screen, title, 1, 1)
|
|
|
|
g.add(t, 0, 0)
|
|
|
|
g.draw()
|
|
|
|
self.screen.refresh()
|
|
|
|
|
|
|
|
class OkCancelWindow:
|
|
|
|
def getrc(self):
|
|
|
|
return self.rc
|
|
|
|
|
|
|
|
def __init__(self, screen, title, text):
|
|
|
|
rc = ButtonChoiceWindow(screen, title, text,
|
|
|
|
buttons=[TEXT_OK_BUTTON, _("Cancel")])
|
|
|
|
if rc == string.lower(_("Cancel")):
|
|
|
|
self.rc = 1
|
|
|
|
else:
|
|
|
|
self.rc = 0
|
|
|
|
|
|
|
|
class ProgressWindow:
|
|
|
|
def pop(self):
|
|
|
|
self.screen.popWindow()
|
|
|
|
self.screen.refresh()
|
|
|
|
del self.scale
|
|
|
|
self.scale = None
|
|
|
|
|
|
|
|
def pulse(self):
|
|
|
|
pass
|
|
|
|
|
|
|
|
def set(self, amount):
|
|
|
|
self.scale.set(int(float(amount) * self.multiplier))
|
|
|
|
self.screen.refresh()
|
|
|
|
|
|
|
|
def refresh(self):
|
|
|
|
pass
|
|
|
|
|
|
|
|
def __init__(self, screen, title, text, total, updpct = 0.05, pulse = False):
|
|
|
|
self.multiplier = 1
|
|
|
|
if total == 1.0:
|
|
|
|
self.multiplier = 100
|
|
|
|
self.screen = screen
|
|
|
|
width = 55
|
|
|
|
if (len(text) > width): width = len(text)
|
|
|
|
|
|
|
|
t = TextboxReflowed(width, text)
|
|
|
|
|
|
|
|
g = GridForm(self.screen, title, 1, 2)
|
|
|
|
g.add(t, 0, 0, (0, 0, 0, 1), anchorLeft=1)
|
|
|
|
|
|
|
|
self.scale = Scale(int(width), int(float(total) * self.multiplier))
|
|
|
|
if not pulse:
|
|
|
|
g.add(self.scale, 0, 1)
|
|
|
|
|
|
|
|
g.draw()
|
|
|
|
self.screen.refresh()
|
|
|
|
|
|
|
|
class LuksPassphraseWindow:
|
|
|
|
def __init__(self, screen, passphrase = "", preexist = False):
|
|
|
|
self.screen = screen
|
|
|
|
self.passphrase = passphrase
|
|
|
|
self.minLength = 8
|
|
|
|
self.preexist = preexist
|
|
|
|
self.txt = _("Choose a passphrase for the encrypted devices. You "
|
|
|
|
"will be prompted for this passphrase during system boot.")
|
|
|
|
self.rc = None
|
|
|
|
|
|
|
|
def run(self):
|
|
|
|
toplevel = GridForm(self.screen, _("Passphrase for encrypted device"),
|
|
|
|
1, 5)
|
|
|
|
|
|
|
|
txt = TextboxReflowed(65, self.txt)
|
|
|
|
toplevel.add(txt, 0, 0)
|
|
|
|
|
|
|
|
passphraseentry = Entry(60, password = 1)
|
|
|
|
toplevel.add(passphraseentry, 0, 1, (0,0,0,1))
|
|
|
|
|
|
|
|
confirmentry = Entry(60, password = 1)
|
|
|
|
toplevel.add(confirmentry, 0, 2, (0,0,0,1))
|
|
|
|
|
|
|
|
if self.preexist:
|
|
|
|
globalcheckbox = Checkbox(_("Also add this passphrase to all existing encrypted devices"), isOn = True)
|
|
|
|
toplevel.add(globalcheckbox, 0, 3)
|
|
|
|
|
|
|
|
buttons = ButtonBar(self.screen, [TEXT_OK_BUTTON, TEXT_CANCEL_BUTTON])
|
|
|
|
toplevel.add(buttons, 0, 4, growx=1)
|
|
|
|
|
|
|
|
passphraseentry.set(self.passphrase)
|
|
|
|
confirmentry.set(self.passphrase)
|
|
|
|
|
|
|
|
while True:
|
|
|
|
rc = toplevel.run()
|
|
|
|
res = buttons.buttonPressed(rc)
|
|
|
|
|
|
|
|
passphrase = None
|
|
|
|
if res == TEXT_OK_CHECK or rc == "F12":
|
|
|
|
passphrase = passphraseentry.value()
|
|
|
|
confirm = confirmentry.value()
|
|
|
|
|
|
|
|
if passphrase != confirm:
|
|
|
|
ButtonChoiceWindow(self.screen,
|
|
|
|
_("Error with passphrase"),
|
|
|
|
_("The passphrases you entered were "
|
|
|
|
"different. Please try again."),
|
|
|
|
buttons=[TEXT_OK_BUTTON])
|
|
|
|
passphraseentry.set("")
|
|
|
|
confirmentry.set("")
|
|
|
|
continue
|
|
|
|
|
|
|
|
if len(passphrase) < self.minLength:
|
|
|
|
ButtonChoiceWindow(self.screen,
|
|
|
|
_("Error with passphrase"),
|
|
|
|
P_("The passphrase must be at least "
|
|
|
|
"%d character long.",
|
|
|
|
"The passphrase must be at least "
|
|
|
|
"%d characters long.",
|
|
|
|
self.minLength)
|
|
|
|
% (self.minLength,),
|
|
|
|
buttons=[TEXT_OK_BUTTON])
|
|
|
|
passphraseentry.set("")
|
|
|
|
confirmentry.set("")
|
|
|
|
continue
|
|
|
|
else:
|
|
|
|
passphrase = self.passphrase
|
|
|
|
passphraseentry.set(self.passphrase)
|
|
|
|
confirmentry.set(self.passphrase)
|
|
|
|
|
|
|
|
retrofit = False
|
|
|
|
if self.preexist:
|
|
|
|
retrofit = globalcheckbox.selected()
|
|
|
|
self.rc = passphrase
|
|
|
|
return (self.rc, retrofit)
|
|
|
|
|
|
|
|
def pop(self):
|
|
|
|
self.screen.popWindow()
|
|
|
|
|
|
|
|
class PassphraseEntryWindow:
|
|
|
|
def __init__(self, screen, device):
|
|
|
|
self.screen = screen
|
|
|
|
self.txt = _("Device %s is encrypted. In order to "
|
|
|
|
"access the device's contents during "
|
|
|
|
"installation you must enter the device's "
|
|
|
|
"passphrase below.") % (device,)
|
|
|
|
self.rc = None
|
|
|
|
|
|
|
|
def run(self):
|
2013-01-23 17:28:19 +00:00
|
|
|
toplevel = GridForm(self.screen, _("Passphrase"), 1, 3)
|
2011-01-18 09:24:57 +00:00
|
|
|
|
|
|
|
txt = TextboxReflowed(65, self.txt)
|
|
|
|
toplevel.add(txt, 0, 0)
|
|
|
|
|
|
|
|
passphraseentry = Entry(60, password = 1)
|
|
|
|
toplevel.add(passphraseentry, 0, 1, (0,0,0,1))
|
|
|
|
|
|
|
|
buttons = ButtonBar(self.screen, [TEXT_OK_BUTTON, TEXT_CANCEL_BUTTON])
|
2013-01-23 17:28:19 +00:00
|
|
|
toplevel.add(buttons, 0, 2, growx=1)
|
2011-01-18 09:24:57 +00:00
|
|
|
|
|
|
|
rc = toplevel.run()
|
|
|
|
res = buttons.buttonPressed(rc)
|
|
|
|
|
|
|
|
passphrase = None
|
2013-01-23 17:28:19 +00:00
|
|
|
if res == TEXT_OK_CHECK or rc == "F12":
|
2011-01-18 09:24:57 +00:00
|
|
|
passphrase = passphraseentry.value().strip()
|
|
|
|
|
2013-01-23 17:28:19 +00:00
|
|
|
self.rc = passphrase
|
2011-01-18 09:24:57 +00:00
|
|
|
return self.rc
|
|
|
|
|
|
|
|
def pop(self):
|
|
|
|
self.screen.popWindow()
|
|
|
|
|
|
|
|
class InstallInterface(InstallInterfaceBase):
|
|
|
|
def progressWindow(self, title, text, total, updpct = 0.05, pulse = False):
|
|
|
|
return ProgressWindow(self.screen, title, text, total, updpct, pulse)
|
|
|
|
|
2013-01-23 17:28:19 +00:00
|
|
|
def reinitializeWindow(self, title, path, size, description):
|
|
|
|
grid = GridForm(self.screen, title, 1, 3)
|
|
|
|
text = TEXT_REINITIALIZE % {"description": description, "size": size, "devicePath": path}
|
|
|
|
grid.add(TextboxReflowed(70, text), 0, 0)
|
|
|
|
|
|
|
|
all_devices_cb = Checkbox(TEXT_REINITIALIZE_ALL, isOn=False)
|
|
|
|
grid.add(all_devices_cb, 0, 1, padding=(0, 1, 0, 0))
|
|
|
|
|
|
|
|
buttons = [(_("Yes, discard any data"), "yes"),
|
|
|
|
(_("No, keep any data"), "no")]
|
|
|
|
grid.buttons = ButtonBar(self.screen, buttons)
|
|
|
|
grid.add(grid.buttons, 0, 2, padding=(0, 1, 0, 0))
|
|
|
|
|
|
|
|
result = grid.run()
|
|
|
|
button_check = grid.buttons.buttonPressed(result)
|
|
|
|
self.screen.popWindow()
|
|
|
|
rc = 2 if button_check == "yes" else 0
|
|
|
|
if all_devices_cb.selected():
|
|
|
|
rc += 1
|
|
|
|
return rc
|
|
|
|
|
2011-01-18 09:24:57 +00:00
|
|
|
def setInstallProgressClass(self, c):
|
|
|
|
self.instProgress = c
|
|
|
|
|
|
|
|
def exitWindow(self, title, text):
|
|
|
|
return self.messageWindow(title, text, type="custom",
|
|
|
|
custom_buttons=[_("Exit installer")])
|
|
|
|
|
|
|
|
def messageWindow(self, title, text, type="ok", default = None,
|
|
|
|
custom_icon=None, custom_buttons=[]):
|
2013-01-23 17:28:19 +00:00
|
|
|
text = str(text)
|
2011-01-18 09:24:57 +00:00
|
|
|
if type == "ok":
|
|
|
|
ButtonChoiceWindow(self.screen, title, text,
|
|
|
|
buttons=[TEXT_OK_BUTTON])
|
|
|
|
elif type == "yesno":
|
|
|
|
if default and default == "no":
|
|
|
|
btnlist = [TEXT_NO_BUTTON, TEXT_YES_BUTTON]
|
|
|
|
else:
|
|
|
|
btnlist = [TEXT_YES_BUTTON, TEXT_NO_BUTTON]
|
|
|
|
rc = ButtonChoiceWindow(self.screen, title, text,
|
|
|
|
buttons=btnlist)
|
|
|
|
if rc == "yes":
|
|
|
|
return 1
|
|
|
|
else:
|
|
|
|
return 0
|
|
|
|
elif type == "custom":
|
|
|
|
tmpbut = []
|
|
|
|
for but in custom_buttons:
|
|
|
|
tmpbut.append(string.replace(but,"_",""))
|
|
|
|
|
|
|
|
rc = ButtonChoiceWindow(self.screen, title, text, width=60,
|
|
|
|
buttons=tmpbut)
|
|
|
|
|
|
|
|
idx = 0
|
|
|
|
for b in tmpbut:
|
|
|
|
if string.lower(b) == rc:
|
|
|
|
return idx
|
|
|
|
idx = idx + 1
|
|
|
|
return 0
|
|
|
|
else:
|
|
|
|
return OkCancelWindow(self.screen, title, text)
|
|
|
|
|
|
|
|
def detailedMessageWindow(self, title, text, longText=None, type="ok",
|
|
|
|
default=None, custom_icon=None,
|
2013-01-23 17:28:19 +00:00
|
|
|
custom_buttons=[], expanded=False):
|
2011-01-18 09:24:57 +00:00
|
|
|
t = TextboxReflowed(60, text, maxHeight=8)
|
2013-01-23 17:28:19 +00:00
|
|
|
|
|
|
|
# if it is a string, just print it as it is (#674322)
|
|
|
|
if isinstance(longText, basestring):
|
|
|
|
lt = Textbox(60, 6, longText, scroll=1, wrap=1)
|
|
|
|
# if the argument is anything else we have to join it together (#654074)
|
|
|
|
else:
|
|
|
|
lt = Textbox(60, 6, "\n".join(longText), scroll=1, wrap=1)
|
|
|
|
|
2011-01-18 09:24:57 +00:00
|
|
|
g = GridFormHelp(self.screen, title, help, 1, 3)
|
|
|
|
g.add(t, 0, 0)
|
|
|
|
g.add(lt, 0, 1, padding = (0, 1, 0, 1))
|
|
|
|
|
|
|
|
if type == "ok":
|
|
|
|
bb = ButtonBar(self.screen, [TEXT_OK_BUTTON])
|
|
|
|
g.add(bb, 0, 2, growx = 1)
|
|
|
|
return bb.buttonPressed(g.runOnce(None, None))
|
|
|
|
elif type == "yesno":
|
|
|
|
if default and default == "no":
|
|
|
|
buttons = [TEXT_NO_BUTTON, TEXT_YES_BUTTON]
|
|
|
|
else:
|
|
|
|
buttons = [TEXT_YES_BUTTON, TEXT_NO_BUTTON]
|
|
|
|
|
|
|
|
bb = ButtonBar(self.screen, buttons)
|
|
|
|
g.add(bb, 0, 2, growx = 1)
|
|
|
|
rc = bb.buttonPressed(g.runOnce(None, None))
|
|
|
|
|
|
|
|
if rc == "yes":
|
|
|
|
return 1
|
|
|
|
else:
|
|
|
|
return 0
|
|
|
|
elif type == "custom":
|
|
|
|
buttons = []
|
|
|
|
idx = 0
|
|
|
|
|
|
|
|
for button in custom_buttons:
|
|
|
|
buttons.append(string.replace(button, "_", ""))
|
|
|
|
|
|
|
|
bb = ButtonBar(self.screen, buttons)
|
|
|
|
g.add(bb, 0, 2, growx = 1)
|
|
|
|
rc = bb.buttonPressed(g.runOnce(None, None))
|
|
|
|
|
|
|
|
for b in buttons:
|
|
|
|
if string.lower(b) == rc:
|
|
|
|
return idx
|
|
|
|
idx += 1
|
|
|
|
|
|
|
|
return 0
|
|
|
|
else:
|
|
|
|
return self.messageWindow(title, text, type, default, custom_icon,
|
|
|
|
custom_buttons)
|
|
|
|
|
|
|
|
def editRepoWindow(self, repoObj):
|
|
|
|
self.messageWindow(_("Error"),
|
|
|
|
_("Repository editing is not available in text mode."))
|
|
|
|
|
|
|
|
def getLuksPassphrase(self, passphrase = "", preexist = False):
|
|
|
|
w = LuksPassphraseWindow(self.screen, passphrase = passphrase,
|
|
|
|
preexist = preexist)
|
|
|
|
rc = w.run()
|
|
|
|
w.pop()
|
|
|
|
return rc
|
|
|
|
|
|
|
|
def passphraseEntryWindow(self, device):
|
|
|
|
w = PassphraseEntryWindow(self.screen, device)
|
2013-01-23 17:28:19 +00:00
|
|
|
passphrase = w.run()
|
2011-01-18 09:24:57 +00:00
|
|
|
w.pop()
|
2013-01-23 17:28:19 +00:00
|
|
|
return passphrase
|
2011-01-18 09:24:57 +00:00
|
|
|
|
|
|
|
def enableNetwork(self):
|
2013-01-23 17:28:19 +00:00
|
|
|
if len(getDevices) == 0:
|
2011-01-18 09:24:57 +00:00
|
|
|
return False
|
2013-01-23 17:28:19 +00:00
|
|
|
from textw.netconfig_text import NetworkConfiguratorText
|
2011-01-18 09:24:57 +00:00
|
|
|
w = NetworkConfiguratorText(self.screen, self.anaconda)
|
|
|
|
ret = w.run()
|
|
|
|
return ret != INSTALL_BACK
|
|
|
|
|
|
|
|
def kickstartErrorWindow(self, text):
|
|
|
|
s = _("The following error was found while parsing the "
|
|
|
|
"kickstart configuration file:\n\n%s") %(text,)
|
|
|
|
self.messageWindow(_("Error Parsing Kickstart Config"),
|
|
|
|
s,
|
|
|
|
type = "custom",
|
|
|
|
custom_buttons = [("_Reboot")],
|
|
|
|
custom_icon="error")
|
|
|
|
|
|
|
|
def mainExceptionWindow(self, shortText, longTextFile):
|
|
|
|
from meh.ui.text import MainExceptionWindow
|
|
|
|
log.critical(shortText)
|
|
|
|
exnWin = MainExceptionWindow(shortText, longTextFile, screen=self.screen)
|
|
|
|
return exnWin
|
|
|
|
|
2013-01-23 17:28:19 +00:00
|
|
|
def saveExceptionWindow(self, accountManager, signature, *args, **kwargs):
|
2011-01-18 09:24:57 +00:00
|
|
|
from meh.ui.text import SaveExceptionWindow
|
2013-01-23 17:28:19 +00:00
|
|
|
import urlgrabber
|
|
|
|
|
|
|
|
if not hasActiveNetDev():
|
|
|
|
if self.messageWindow(_("Warning"),
|
|
|
|
_("You do not have an active network connection. This is "
|
|
|
|
"required by some exception saving methods. Would you "
|
|
|
|
"like to configure your network now?"),
|
|
|
|
type = "yesno"):
|
|
|
|
|
|
|
|
if not self.enableNetwork():
|
|
|
|
self.messageWindow(_("No Network Available"),
|
|
|
|
_("Remote exception saving methods will not work."))
|
|
|
|
else:
|
|
|
|
urlgrabber.grabber.reset_curl_obj()
|
|
|
|
|
|
|
|
win = SaveExceptionWindow (accountManager, signature, screen=self.screen,
|
2011-01-18 09:24:57 +00:00
|
|
|
*args, **kwargs)
|
2013-01-23 17:28:19 +00:00
|
|
|
win.run()
|
2011-01-18 09:24:57 +00:00
|
|
|
|
|
|
|
def waitWindow(self, title, text):
|
|
|
|
return WaitWindow(self.screen, title, text)
|
|
|
|
|
|
|
|
def beep(self):
|
|
|
|
# no-op. could call newtBell() if it was bound
|
|
|
|
pass
|
|
|
|
|
|
|
|
def drawFrame(self):
|
|
|
|
self.screen.drawRootText (0, 0, self.screen.width * " ")
|
|
|
|
if productArch:
|
|
|
|
self.screen.drawRootText (0, 0, _("Welcome to %(productName)s for %(productArch)s") % {'productName': productName, 'productArch': productArch})
|
|
|
|
else:
|
|
|
|
self.screen.drawRootText (0, 0, _("Welcome to %s") % productName)
|
|
|
|
|
|
|
|
self.screen.pushHelpLine(_(" <Tab>/<Alt-Tab> between elements | <Space> selects | <F12> next screen"))
|
|
|
|
|
|
|
|
def setScreen(self, screen):
|
|
|
|
self.screen = screen
|
|
|
|
|
|
|
|
def shutdown(self):
|
|
|
|
self.screen.finish()
|
|
|
|
self.screen = None
|
|
|
|
|
|
|
|
def suspend(self):
|
|
|
|
self.screen.suspend()
|
|
|
|
|
|
|
|
def resume(self):
|
|
|
|
self.screen.resume()
|
|
|
|
|
|
|
|
def __init__(self):
|
|
|
|
InstallInterfaceBase.__init__(self)
|
|
|
|
signal.signal(signal.SIGINT, signal.SIG_IGN)
|
|
|
|
signal.signal(signal.SIGTSTP, signal.SIG_IGN)
|
|
|
|
self.screen = SnackScreen()
|
|
|
|
self.instProgress = None
|
|
|
|
|
|
|
|
def __del__(self):
|
|
|
|
if self.screen:
|
|
|
|
self.screen.finish()
|
|
|
|
|
|
|
|
def isRealConsole(self):
|
|
|
|
"""Returns True if this is a _real_ console that can do things, False
|
|
|
|
for non-real consoles such as serial, i/p virtual consoles or xen."""
|
|
|
|
if flags.serial or flags.virtpconsole:
|
|
|
|
return False
|
|
|
|
if isys.isPseudoTTY(0):
|
|
|
|
return False
|
|
|
|
if isys.isVioConsole():
|
|
|
|
return False
|
|
|
|
return True
|
|
|
|
|
|
|
|
def run(self, anaconda):
|
|
|
|
self.anaconda = anaconda
|
|
|
|
|
|
|
|
if not self.isRealConsole():
|
|
|
|
self.screen.suspendCallback(spawnShell, self.screen)
|
|
|
|
|
|
|
|
# drop into the python debugger on ctrl-z if we're running in test mode
|
|
|
|
if flags.debug:
|
|
|
|
self.screen.suspendCallback(debugSelf, self.screen)
|
|
|
|
|
|
|
|
# draw the frame after setting up the fallback
|
|
|
|
self.drawFrame()
|
2013-01-23 17:28:19 +00:00
|
|
|
# and now descend into the dispatcher
|
|
|
|
self.anaconda.dispatch.dispatch()
|
|
|
|
|
|
|
|
def display_step(self, step):
|
|
|
|
(file, className) = stepToClasses[step]
|
|
|
|
while True:
|
|
|
|
try:
|
|
|
|
found = imp.find_module(file, textw.__path__)
|
|
|
|
moduleName = 'pyanaconda.textw.%s' % file
|
|
|
|
loaded = imp.load_module(moduleName, *found)
|
|
|
|
nextWindow = loaded.__dict__[className]
|
|
|
|
break
|
|
|
|
except ImportError as e:
|
|
|
|
log.error("loading interface component %s" % className)
|
|
|
|
log.error(traceback.format_exc())
|
|
|
|
rc = ButtonChoiceWindow(self.screen, _("Error!"),
|
|
|
|
_("An error occurred when attempting "
|
|
|
|
"to load an installer interface "
|
|
|
|
"component.\n\nclassName = %s")
|
|
|
|
% className,
|
|
|
|
buttons=[_("Exit"), _("Retry")])
|
|
|
|
|
|
|
|
if rc == string.lower(_("Exit")):
|
|
|
|
sys.exit(0)
|
|
|
|
win = nextWindow()
|
2011-01-18 09:24:57 +00:00
|
|
|
|
2013-01-23 17:28:19 +00:00
|
|
|
while True:
|
|
|
|
rc = win(self.screen, self.anaconda)
|
|
|
|
if rc == INSTALL_OK:
|
|
|
|
return DISPATCH_FORWARD
|
|
|
|
elif rc == INSTALL_NOOP:
|
|
|
|
return DISPATCH_DEFAULT
|
|
|
|
elif rc == INSTALL_BACK:
|
|
|
|
if self.anaconda.dispatch.can_go_back():
|
|
|
|
return DISPATCH_BACK
|
|
|
|
else:
|
2011-01-18 09:24:57 +00:00
|
|
|
ButtonChoiceWindow(self.screen, _("Cancelled"),
|
|
|
|
_("I can't go to the previous step "
|
|
|
|
"from here. You will have to try "
|
|
|
|
"again."),
|
|
|
|
buttons=[_("OK")])
|
2013-01-23 17:28:19 +00:00
|
|
|
# keep displaying the same dialog until the user gives us
|
|
|
|
# a better answer
|
|
|
|
continue
|
2011-01-18 09:24:57 +00:00
|
|
|
|
2013-01-23 17:28:19 +00:00
|
|
|
def unsupported_steps(self):
|
|
|
|
l = ["cleardiskssel", "filtertype", "filter", "group-selection",
|
|
|
|
"partition"]
|
|
|
|
if not iutil.isS390():
|
|
|
|
l.append("bootloader")
|
|
|
|
return l
|
2011-01-18 09:24:57 +00:00
|
|
|
|
|
|
|
def killSelf(screen):
|
|
|
|
screen.finish()
|
|
|
|
os._exit(0)
|
|
|
|
|
|
|
|
def debugSelf(screen):
|
|
|
|
screen.suspend()
|
|
|
|
import pdb
|
|
|
|
try:
|
|
|
|
pdb.set_trace()
|
|
|
|
except:
|
|
|
|
sys.exit(-1)
|
|
|
|
screen.resume()
|
|
|
|
|
|
|
|
def spawnShell(screen):
|
|
|
|
screen.suspend()
|
|
|
|
print("\n\nType <exit> to return to the install program.\n")
|
|
|
|
if os.path.exists("/bin/sh"):
|
|
|
|
iutil.execConsole()
|
|
|
|
else:
|
|
|
|
print("Unable to find /bin/sh to execute! Not starting shell")
|
|
|
|
time.sleep(5)
|
|
|
|
screen.resume()
|