/[smeserver]/cdrom.image/sme9/updates/text.py
ViewVC logotype

Annotation of /cdrom.image/sme9/updates/text.py

Parent Directory Parent Directory | Revision Log Revision Log | View Revision Graph Revision Graph


Revision 1.1 - (hide annotations) (download) (as text)
Mon Oct 28 23:02:23 2013 UTC (11 years ago) by charliebrady
Branch: MAIN
Content type: text/x-python
Remove "Re-initialize" option for unpartitioned drives. [SME: 7933]

1 charliebrady 1.1 #
2     # text.py - text mode frontend to anaconda
3     #
4     # Copyright (C) 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006 Red Hat, Inc.
5     # All rights reserved.
6     #
7     # This program is free software; you can redistribute it and/or modify
8     # it under the terms of the GNU General Public License as published by
9     # the Free Software Foundation; either version 2 of the License, or
10     # (at your option) any later version.
11     #
12     # This program is distributed in the hope that it will be useful,
13     # but WITHOUT ANY WARRANTY; without even the implied warranty of
14     # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15     # GNU General Public License for more details.
16     #
17     # You should have received a copy of the GNU General Public License
18     # along with this program. If not, see <http://www.gnu.org/licenses/>.
19     #
20     # Author(s): Erik Troan <ewt@redhat.com>
21     # Matt Wilson <msw@redhat.com>
22     #
23    
24     from snack import *
25     import sys
26     import os
27     import isys
28     import iutil
29     import time
30     import signal
31     import parted
32     import product
33     import string
34     from language import expandLangs
35     from flags import flags
36     from constants_text import *
37     from constants import *
38     import network
39     from installinterfacebase import InstallInterfaceBase
40     import imputil
41    
42     import gettext
43     _ = lambda x: gettext.ldgettext("anaconda", x)
44     P_ = lambda x, y, z: gettext.ldngettext("anaconda", x, y, z)
45    
46     import logging
47     log = logging.getLogger("anaconda")
48    
49     stepToClasses = {
50     "language" : ("language_text", "LanguageWindow"),
51     "keyboard" : ("keyboard_text", "KeyboardWindow"),
52     "welcome" : ("welcome_text", "WelcomeWindow"),
53     "parttype" : ("partition_text", "PartitionTypeWindow"),
54     "addswap" : ("upgrade_text", "UpgradeSwapWindow"),
55     "upgrademigratefs" : ("upgrade_text", "UpgradeMigrateFSWindow"),
56     "zfcpconfig": ("zfcp_text", ("ZFCPWindow")),
57     "findinstall" : ("upgrade_text", ("UpgradeExamineWindow")),
58     "upgbootloader": ("upgrade_bootloader_text", "UpgradeBootloaderWindow"),
59     "network" : ("network_text", ("HostnameWindow")),
60     "timezone" : ("timezone_text", "TimezoneWindow"),
61     "accounts" : ("userauth_text", "RootPasswordWindow"),
62     "tasksel": ("task_text", "TaskWindow"),
63     "install" : ("progress_text", "setupForInstall"),
64     "complete" : ("complete_text", "FinishedWindow"),
65     }
66    
67     if iutil.isS390():
68     stepToClasses["bootloader"] = ("zipl_text", ( "ZiplWindow"))
69    
70     class InstallWindow:
71     def __call__ (self, screen):
72     raise RuntimeError, "Unimplemented screen"
73    
74     class WaitWindow:
75     def pop(self):
76     self.screen.popWindow()
77     self.screen.refresh()
78    
79     def refresh(self):
80     pass
81    
82     def __init__(self, screen, title, text):
83     self.screen = screen
84     width = 40
85     if (len(text) < width): width = len(text)
86    
87     t = TextboxReflowed(width, text)
88    
89     g = GridForm(self.screen, title, 1, 1)
90     g.add(t, 0, 0)
91     g.draw()
92     self.screen.refresh()
93    
94     class OkCancelWindow:
95     def getrc(self):
96     return self.rc
97    
98     def __init__(self, screen, title, text):
99     rc = ButtonChoiceWindow(screen, title, text,
100     buttons=[TEXT_OK_BUTTON, _("Cancel")])
101     if rc == string.lower(_("Cancel")):
102     self.rc = 1
103     else:
104     self.rc = 0
105    
106     class ProgressWindow:
107     def pop(self):
108     self.screen.popWindow()
109     self.screen.refresh()
110     del self.scale
111     self.scale = None
112    
113     def pulse(self):
114     pass
115    
116     def set(self, amount):
117     self.scale.set(int(float(amount) * self.multiplier))
118     self.screen.refresh()
119    
120     def refresh(self):
121     pass
122    
123     def __init__(self, screen, title, text, total, updpct = 0.05, pulse = False):
124     self.multiplier = 1
125     if total == 1.0:
126     self.multiplier = 100
127     self.screen = screen
128     width = 55
129     if (len(text) > width): width = len(text)
130    
131     t = TextboxReflowed(width, text)
132    
133     g = GridForm(self.screen, title, 1, 2)
134     g.add(t, 0, 0, (0, 0, 0, 1), anchorLeft=1)
135    
136     self.scale = Scale(int(width), int(float(total) * self.multiplier))
137     if not pulse:
138     g.add(self.scale, 0, 1)
139    
140     g.draw()
141     self.screen.refresh()
142    
143     class LuksPassphraseWindow:
144     def __init__(self, screen, passphrase = "", preexist = False):
145     self.screen = screen
146     self.passphrase = passphrase
147     self.minLength = 8
148     self.preexist = preexist
149     self.txt = _("Choose a passphrase for the encrypted devices. You "
150     "will be prompted for this passphrase during system boot.")
151     self.rc = None
152    
153     def run(self):
154     toplevel = GridForm(self.screen, _("Passphrase for encrypted device"),
155     1, 5)
156    
157     txt = TextboxReflowed(65, self.txt)
158     toplevel.add(txt, 0, 0)
159    
160     passphraseentry = Entry(60, password = 1)
161     toplevel.add(passphraseentry, 0, 1, (0,0,0,1))
162    
163     confirmentry = Entry(60, password = 1)
164     toplevel.add(confirmentry, 0, 2, (0,0,0,1))
165    
166     if self.preexist:
167     globalcheckbox = Checkbox(_("Also add this passphrase to all existing encrypted devices"), isOn = True)
168     toplevel.add(globalcheckbox, 0, 3)
169    
170     buttons = ButtonBar(self.screen, [TEXT_OK_BUTTON, TEXT_CANCEL_BUTTON])
171     toplevel.add(buttons, 0, 4, growx=1)
172    
173     passphraseentry.set(self.passphrase)
174     confirmentry.set(self.passphrase)
175    
176     while True:
177     rc = toplevel.run()
178     res = buttons.buttonPressed(rc)
179    
180     passphrase = None
181     if res == TEXT_OK_CHECK or rc == "F12":
182     passphrase = passphraseentry.value()
183     confirm = confirmentry.value()
184    
185     if passphrase != confirm:
186     ButtonChoiceWindow(self.screen,
187     _("Error with passphrase"),
188     _("The passphrases you entered were "
189     "different. Please try again."),
190     buttons=[TEXT_OK_BUTTON])
191     passphraseentry.set("")
192     confirmentry.set("")
193     continue
194    
195     if len(passphrase) < self.minLength:
196     ButtonChoiceWindow(self.screen,
197     _("Error with passphrase"),
198     P_("The passphrase must be at least "
199     "%d character long.",
200     "The passphrase must be at least "
201     "%d characters long.",
202     self.minLength)
203     % (self.minLength,),
204     buttons=[TEXT_OK_BUTTON])
205     passphraseentry.set("")
206     confirmentry.set("")
207     continue
208     else:
209     passphrase = self.passphrase
210     passphraseentry.set(self.passphrase)
211     confirmentry.set(self.passphrase)
212    
213     retrofit = False
214     if self.preexist:
215     retrofit = globalcheckbox.selected()
216     self.rc = passphrase
217     return (self.rc, retrofit)
218    
219     def pop(self):
220     self.screen.popWindow()
221    
222     class PassphraseEntryWindow:
223     def __init__(self, screen, device):
224     self.screen = screen
225     self.txt = _("Device %s is encrypted. In order to "
226     "access the device's contents during "
227     "installation you must enter the device's "
228     "passphrase below.") % (device,)
229     self.rc = None
230    
231     def run(self):
232     toplevel = GridForm(self.screen, _("Passphrase"), 1, 4)
233    
234     txt = TextboxReflowed(65, self.txt)
235     toplevel.add(txt, 0, 0)
236    
237     passphraseentry = Entry(60, password = 1)
238     toplevel.add(passphraseentry, 0, 1, (0,0,0,1))
239    
240     globalcheckbox = Checkbox(_("This is a global passphrase"))
241     toplevel.add(globalcheckbox, 0, 2)
242    
243     buttons = ButtonBar(self.screen, [TEXT_OK_BUTTON, TEXT_CANCEL_BUTTON])
244     toplevel.add(buttons, 0, 3, growx=1)
245    
246     rc = toplevel.run()
247     res = buttons.buttonPressed(rc)
248    
249     passphrase = None
250     isglobal = False
251     if res == TEXT_OK_CHECK or rc == "F12":
252     passphrase = passphraseentry.value().strip()
253     isglobal = globalcheckbox.selected()
254    
255     self.rc = (passphrase, isglobal)
256     return self.rc
257    
258     def pop(self):
259     self.screen.popWindow()
260    
261     class InstallInterface(InstallInterfaceBase):
262     def progressWindow(self, title, text, total, updpct = 0.05, pulse = False):
263     return ProgressWindow(self.screen, title, text, total, updpct, pulse)
264    
265     def exitWindow(self, title, text):
266     return self.messageWindow(title, text, type="custom",
267     custom_buttons=[_("Exit installer")])
268    
269     def messageWindow(self, title, text, type="ok", default = None,
270     custom_icon=None, custom_buttons=[]):
271     text = str(text)
272     if type == "ok":
273     ButtonChoiceWindow(self.screen, title, text,
274     buttons=[TEXT_OK_BUTTON])
275     elif type == "yesno":
276     if default and default == "no":
277     btnlist = [TEXT_NO_BUTTON, TEXT_YES_BUTTON]
278     else:
279     btnlist = [TEXT_YES_BUTTON, TEXT_NO_BUTTON]
280     rc = ButtonChoiceWindow(self.screen, title, text,
281     buttons=btnlist)
282     if rc == "yes":
283     return 1
284     else:
285     return 0
286     elif type == "custom":
287     tmpbut = []
288     for but in custom_buttons:
289     tmpbut.append(string.replace(but,"_",""))
290    
291     rc = ButtonChoiceWindow(self.screen, title, text, width=60,
292     buttons=tmpbut)
293    
294     idx = 0
295     for b in tmpbut:
296     if string.lower(b) == rc:
297     return idx
298     idx = idx + 1
299     return 0
300     else:
301     return OkCancelWindow(self.screen, title, text)
302    
303     def detailedMessageWindow(self, title, text, longText=None, type="ok",
304     default=None, custom_icon=None,
305     custom_buttons=[], expanded=False):
306     t = TextboxReflowed(60, text, maxHeight=8)
307    
308     # if it is a string, just print it as it is (#674322)
309     if isinstance(longText, basestring):
310     lt = Textbox(60, 6, longText, scroll=1, wrap=1)
311     # if the argument is anything else we have to join it together (#654074)
312     else:
313     lt = Textbox(60, 6, "\n".join(longText), scroll=1, wrap=1)
314    
315     g = GridFormHelp(self.screen, title, help, 1, 3)
316     g.add(t, 0, 0)
317     g.add(lt, 0, 1, padding = (0, 1, 0, 1))
318    
319     if type == "ok":
320     bb = ButtonBar(self.screen, [TEXT_OK_BUTTON])
321     g.add(bb, 0, 2, growx = 1)
322     return bb.buttonPressed(g.runOnce(None, None))
323     elif type == "yesno":
324     if default and default == "no":
325     buttons = [TEXT_NO_BUTTON, TEXT_YES_BUTTON]
326     else:
327     buttons = [TEXT_YES_BUTTON, TEXT_NO_BUTTON]
328    
329     bb = ButtonBar(self.screen, buttons)
330     g.add(bb, 0, 2, growx = 1)
331     rc = bb.buttonPressed(g.runOnce(None, None))
332    
333     if rc == "yes":
334     return 1
335     else:
336     return 0
337     elif type == "custom":
338     buttons = []
339     idx = 0
340    
341     for button in custom_buttons:
342     buttons.append(string.replace(button, "_", ""))
343    
344     bb = ButtonBar(self.screen, buttons)
345     g.add(bb, 0, 2, growx = 1)
346     rc = bb.buttonPressed(g.runOnce(None, None))
347    
348     for b in buttons:
349     if string.lower(b) == rc:
350     return idx
351     idx += 1
352    
353     return 0
354     else:
355     return self.messageWindow(title, text, type, default, custom_icon,
356     custom_buttons)
357    
358     def createRepoWindow(self):
359     self.messageWindow(_("Error"),
360     _("Repository editing is not available in text mode."))
361    
362     def editRepoWindow(self, repoObj):
363     self.messageWindow(_("Error"),
364     _("Repository editing is not available in text mode."))
365    
366     def entryWindow(self, title, text, prompt, entrylength = None):
367     (res, value) = EntryWindow(self.screen, title, text, [prompt])
368     if res == "cancel":
369     return None
370     r = value[0]
371     r.strip()
372     return r
373    
374     def getLuksPassphrase(self, passphrase = "", preexist = False):
375     w = LuksPassphraseWindow(self.screen, passphrase = passphrase,
376     preexist = preexist)
377     rc = w.run()
378     w.pop()
379     return rc
380    
381     def passphraseEntryWindow(self, device):
382     w = PassphraseEntryWindow(self.screen, device)
383     (passphrase, isglobal) = w.run()
384     w.pop()
385     return (passphrase, isglobal)
386    
387     def enableNetwork(self):
388     if len(self.anaconda.id.network.netdevices) == 0:
389     return False
390     from netconfig_text import NetworkConfiguratorText
391     w = NetworkConfiguratorText(self.screen, self.anaconda)
392     ret = w.run()
393     return ret != INSTALL_BACK
394    
395     def kickstartErrorWindow(self, text):
396     s = _("The following error was found while parsing the "
397     "kickstart configuration file:\n\n%s") %(text,)
398     self.messageWindow(_("Error Parsing Kickstart Config"),
399     s,
400     type = "custom",
401     custom_buttons = [("_Reboot")],
402     custom_icon="error")
403    
404     def mainExceptionWindow(self, shortText, longTextFile):
405     from meh.ui.text import MainExceptionWindow
406     log.critical(shortText)
407     exnWin = MainExceptionWindow(shortText, longTextFile, screen=self.screen)
408     return exnWin
409    
410     def saveExceptionWindow(self, accountManager, signature, *args, **kwargs):
411     from meh.ui.text import SaveExceptionWindow
412     network.saveExceptionEnableNetwork(self)
413     win = SaveExceptionWindow (accountManager, signature, screen=self.screen,
414     *args, **kwargs)
415     win.run()
416    
417     def waitWindow(self, title, text):
418     return WaitWindow(self.screen, title, text)
419    
420     def beep(self):
421     # no-op. could call newtBell() if it was bound
422     pass
423    
424     def drawFrame(self):
425     self.screen.drawRootText (0, 0, self.screen.width * " ")
426     if productArch:
427     self.screen.drawRootText (0, 0, _("Welcome to %(productName)s for %(productArch)s") % {'productName': productName, 'productArch': productArch})
428     else:
429     self.screen.drawRootText (0, 0, _("Welcome to %s") % productName)
430    
431     self.screen.pushHelpLine(_(" <Tab>/<Alt-Tab> between elements | <Space> selects | <F12> next screen"))
432    
433     def setScreen(self, screen):
434     self.screen = screen
435    
436     def shutdown(self):
437     self.screen.finish()
438     self.screen = None
439    
440     def suspend(self):
441     self.screen.suspend()
442    
443     def resume(self):
444     self.screen.resume()
445    
446     def __init__(self):
447     InstallInterfaceBase.__init__(self)
448     signal.signal(signal.SIGINT, signal.SIG_IGN)
449     signal.signal(signal.SIGTSTP, signal.SIG_IGN)
450     self.screen = SnackScreen()
451     self._inconsistentLVMAnswers = {}
452    
453     def __del__(self):
454     if self.screen:
455     self.screen.finish()
456    
457     def isRealConsole(self):
458     """Returns True if this is a _real_ console that can do things, False
459     for non-real consoles such as serial, i/p virtual consoles or xen."""
460     if flags.serial or flags.virtpconsole:
461     return False
462     if isys.isPseudoTTY(0):
463     return False
464     if isys.isVioConsole():
465     return False
466     return True
467    
468     def resetInitializeDiskQuestion(self):
469     pass
470    
471     def questionInitializeDisk(self, path, description, size, details=""):
472     if not path:
473     return False
474     return True
475    
476     def resetReinitInconsistentLVMQuestion(self):
477     self._inconsistentLVMAnswers = {}
478    
479     def questionReinitInconsistentLVM(self, pv_names=None, lv_name=None, vg_name=None):
480    
481     retVal = False # The less destructive default
482     allSet = frozenset(["all"])
483    
484     if not pv_names or (lv_name is None and vg_name is None):
485     return retVal
486    
487     # We are caching answers so that we don't ask for ignoring
488     # in each storage.reset() again (note that reinitialization is
489     # done right after confirmation in dialog, not as a planned
490     # action).
491     key = frozenset(pv_names)
492     if key in self._inconsistentLVMAnswers:
493     log.info("UI not asking about disk initialization, "
494     "using cached answer: %s" % self._inconsistentLVMAnswers[key])
495     return self._inconsistentLVMAnswers[key]
496     elif allSet in self._inconsistentLVMAnswers:
497     log.info("UI not asking about disk initialization, "
498     "using cached answer: %s" % self._inconsistentLVMAnswers[allSet])
499     return self._inconsistentLVMAnswers[allSet]
500    
501     if vg_name is not None:
502     message = "Volume Group %s" % vg_name
503     elif lv_name is not None:
504     message = "Logical Volume %s" % lv_name
505    
506     na = {'msg': message, 'pvs': ", ".join(pv_names)}
507     rc = self.messageWindow(_("Warning"),
508     _("Error processing LVM.\n"
509     "There is inconsistent LVM data on %(msg)s. You can "
510     "reinitialize all related PVs (%(pvs)s) which will erase "
511     "the LVM metadata, or ignore which will preserve the "
512     "contents. This action may also be applied to all other "
513     "PVs with inconsistent metadata.") % na,
514     type="custom",
515     custom_buttons = [ _("_Ignore"),
516     _("Ignore _all"),
517     _("_Re-initialize"),
518     _("Re-ini_tialize all") ],
519     custom_icon="question")
520     if rc == 0:
521     retVal = False
522     elif rc == 1:
523     key = allSet
524     retVal = False
525     elif rc == 2:
526     retVal = True
527     elif rc == 3:
528     key = allSet
529     retVal = True
530    
531     self._inconsistentLVMAnswers[key] = retVal
532     return retVal
533    
534     def run(self, anaconda):
535     self.anaconda = anaconda
536     instLang = anaconda.id.instLanguage
537    
538     if instLang.getFontFile(instLang.instLang) == "none":
539     if not anaconda.isKickstart:
540     ButtonChoiceWindow(self.screen, "Language Unavailable",
541     "%s display is unavailable in text mode. "
542     "The installation will continue in "
543     "English." % (instLang.instLang,),
544     buttons=[TEXT_OK_BUTTON])
545    
546     if not self.isRealConsole():
547     self.screen.suspendCallback(spawnShell, self.screen)
548    
549     # drop into the python debugger on ctrl-z if we're running in test mode
550     if flags.debug:
551     self.screen.suspendCallback(debugSelf, self.screen)
552    
553     self.instLanguage = anaconda.id.instLanguage
554    
555     # draw the frame after setting up the fallback
556     self.drawFrame()
557    
558     lastrc = INSTALL_OK
559     (step, instance) = anaconda.dispatch.currentStep()
560     while step:
561     (file, classNames) = stepToClasses[step]
562    
563     if type(classNames) != type(()):
564     classNames = (classNames,)
565    
566     if lastrc == INSTALL_OK:
567     step = 0
568     else:
569     step = len(classNames) - 1
570    
571     while step >= 0 and step < len(classNames):
572     # reget the args. they could change (especially direction)
573     (foo, args) = anaconda.dispatch.currentStep()
574     nextWindow = None
575    
576     while 1:
577     try:
578     found = imputil.imp.find_module(file)
579     loaded = imputil.imp.load_module(classNames[step],
580     found[0], found[1],
581     found[2])
582     nextWindow = loaded.__dict__[classNames[step]]
583     break
584     except ImportError, e:
585     rc = ButtonChoiceWindow(self.screen, _("Error!"),
586     _("An error occurred when attempting "
587     "to load an installer interface "
588     "component.\n\nclassName = %s")
589     % (classNames[step],),
590     buttons=[_("Exit"), _("Retry")])
591    
592     if rc == string.lower(_("Exit")):
593     sys.exit(0)
594    
595     win = nextWindow()
596    
597     #log.info("TUI running step %s (class %s, file %s)" %
598     #(step, file, classNames))
599    
600     rc = win(self.screen, instance)
601    
602     if rc == INSTALL_NOOP:
603     rc = lastrc
604    
605     if rc == INSTALL_BACK:
606     step = step - 1
607     anaconda.dispatch.dir = DISPATCH_BACK
608     elif rc == INSTALL_OK:
609     step = step + 1
610     anaconda.dispatch.dir = DISPATCH_FORWARD
611    
612     lastrc = rc
613    
614     if step == -1:
615     if not anaconda.dispatch.canGoBack():
616     ButtonChoiceWindow(self.screen, _("Cancelled"),
617     _("I can't go to the previous step "
618     "from here. You will have to try "
619     "again."),
620     buttons=[_("OK")])
621     anaconda.dispatch.gotoPrev()
622     else:
623     anaconda.dispatch.gotoNext()
624    
625     (step, args) = anaconda.dispatch.currentStep()
626    
627     self.screen.finish()
628    
629     def setSteps(self, anaconda):
630     anaconda.dispatch.skipStep("filtertype", permanent=1)
631     anaconda.dispatch.skipStep("filter", permanent=1)
632     anaconda.dispatch.skipStep("cleardiskssel", permanent=1)
633     anaconda.dispatch.skipStep("group-selection", permanent=1)
634    
635     def killSelf(screen):
636     screen.finish()
637     os._exit(0)
638    
639     def debugSelf(screen):
640     screen.suspend()
641     import pdb
642     try:
643     pdb.set_trace()
644     except:
645     sys.exit(-1)
646     screen.resume()
647    
648     def spawnShell(screen):
649     screen.suspend()
650     print("\n\nType <exit> to return to the install program.\n")
651     if os.path.exists("/bin/sh"):
652     iutil.execConsole()
653     else:
654     print("Unable to find /bin/sh to execute! Not starting shell")
655     time.sleep(5)
656     screen.resume()

admin@koozali.org
ViewVC Help
Powered by ViewVC 1.2.1 RSS 2.0 feed