[node-patches] Change in ovirt-node[master]: [DRAFT] ui: Installer
fabiand at fedoraproject.org
fabiand at fedoraproject.org
Tue Jan 15 20:05:41 UTC 2013
Fabian Deutsch has uploaded a new change for review.
Change subject: [DRAFT] ui: Installer
......................................................................
[DRAFT] ui: Installer
Change-Id: I0c81e0e85ff35ee073dd5e47df9f53da0a8f7738
Signed-off-by: Fabian Deutsch <fabiand at fedoraproject.org>
---
M scripts/tui/src/ovirt/node/installer/boot_device_page.py
M scripts/tui/src/ovirt/node/installer/installation_device_page.py
M scripts/tui/src/ovirt/node/installer/keyboard_page.py
M scripts/tui/src/ovirt/node/installer/password_page.py
M scripts/tui/src/ovirt/node/installer/progress_page.py
M scripts/tui/src/ovirt/node/installer/welcome_page.py
6 files changed, 209 insertions(+), 88 deletions(-)
git pull ssh://gerrit.ovirt.org:29418/ovirt-node refs/changes/66/11066/1
diff --git a/scripts/tui/src/ovirt/node/installer/boot_device_page.py b/scripts/tui/src/ovirt/node/installer/boot_device_page.py
index 3c83212..64a951c 100644
--- a/scripts/tui/src/ovirt/node/installer/boot_device_page.py
+++ b/scripts/tui/src/ovirt/node/installer/boot_device_page.py
@@ -22,12 +22,11 @@
"""
Boot device selection page of the installer
"""
-from ovirt.node import plugins, ui, utils
+from ovirt.node import plugins, ui, utils, valid
class Plugin(plugins.NodePlugin):
- _model = None
- _elements = None
+ _model = {}
def name(self):
return "Boot Device"
@@ -36,58 +35,85 @@
return 30
def model(self):
- return self._model or {}
+ self._model.update({"boot.device": ""})
+ devices = self._device_list()
+ if devices:
+ first_dev = devices[0][0]
+ self._model["label.details"] = first_dev
+ self._model["boot.device"] = first_dev
+ return self._model
def validators(self):
- return {}
+ return {"boot.device": lambda v: None if v else "No device given"
+ }
def ui_content(self):
page_title = "Please select the disk to use for booting %s" % \
self.application.product.PRODUCT_SHORT
- ws = [ui.Header("header[0]", page_title),
- ui.Table("boot.device", "", " %6s %11s %5s" %
- ("Location", "Device Name", "Size"),
- self._device_list()),
- DeviceDetails("label.details", "(No device)")
- ]
+ devices = self._device_list()
+
+ ws = [ui.Header("header[0]", page_title)]
+
+ if devices:
+ ws += [ui.Table("boot.device", "", " %6s %11s %5s" %
+ ("Location", "Device Name", "Size"), devices),
+ DeviceDetails("label.details", "(No device)")
+ ]
+ else:
+ ws += [ui.Label("boot.no_device",
+ "No Valid Boot Devices Detected")]
self.widgets.add(ws)
page = ui.Page("boot", ws)
- page.buttons = [ui.Button("button.quit", "Quit"),
+ page.buttons = [ui.QuitButton("button.quit", "Quit"),
ui.Button("button.back", "Back"),
- ui.Button("button.next", "Continue")]
+ ui.SaveButton("button.next", "Continue")]
return page
def _device_list(self):
- devices = utils.storage.Devices(fake=True)
+ do_fake = False
+ if self.application.args.dry:
+ do_fake = True
+ devices = utils.storage.Devices(fake=do_fake)
all_devices = devices.get_all().items()
- return [(name, " %6s %11s %5s GB" % (d.bus, d.name, d.size))
- for name, d in all_devices]
+ return sorted([(name, " %6s %11s %5s GB" % (d.bus, d.name, d.size))
+ for name, d in all_devices], key=lambda t: t[0])
def on_change(self, changes):
- if "button.next" in changes:
- self._elements["label.details"].set_device(changes["button.next"])
+ if changes.contains_any(["boot.device"]):
+ self._model.update(changes)
+ self.widgets["label.details"].set_device(changes["boot.device"])
def on_merge(self, effective_changes):
changes = self.pending_changes(False)
if changes.contains_any(["button.next", "boot.device"]):
- self.transaction = "a"
self.application.ui.navigate.to_next_plugin()
+ elif changes.contains_any(["button.back"]):
+ self.application.ui.navigate.to_previous_plugin()
class DeviceDetails(ui.Label):
- def set_device(self, device):
+ def set_device(self, device_name):
devices = utils.storage.Devices(fake=True)
all_devices = devices.get_all()
- if not all_devices:
- pass
- """lines = [("Disk Details",),
- ("Device", ""),
- ("Model", ""),
- ("Bus Type", ""),
- ("Serial", ""),
- ("Size", ""),
- ("Description", ""),
- ]"""
- self.set_text("%s" % device)
+ device = all_devices[device_name]
+
+ lines = [("Device", device.name),
+ ("Model", device.model),
+ ("Bus Type", device.bus),
+ ("Serial", device.serial),
+ ("Size (GB)", device.size),
+ ("Description", device.desc),
+ ]
+
+ width = max([len(o[0]) for o in lines])
+ txt = "Disk Details\n"
+ txt += "\n".join(["%s: %s" % (("{:%d}" % width).format(a), b)
+ for a, b in lines])
+ self.text(txt)
+
+ def value(self, value=None):
+ if value:
+ self.set_device(value)
+ return value
diff --git a/scripts/tui/src/ovirt/node/installer/installation_device_page.py b/scripts/tui/src/ovirt/node/installer/installation_device_page.py
index edd3fec..a0e586c 100644
--- a/scripts/tui/src/ovirt/node/installer/installation_device_page.py
+++ b/scripts/tui/src/ovirt/node/installer/installation_device_page.py
@@ -27,8 +27,7 @@
class Plugin(plugins.NodePlugin):
- _model = None
- _elements = None
+ _model = {}
def name(self):
return "Data Device"
@@ -37,7 +36,13 @@
return 40
def model(self):
- return self._model or {}
+ self._model.update({"installation.device": ""})
+ devices = self._device_list()
+ if devices:
+ first_dev = devices[0][0]
+ self._model["label.details"] = first_dev
+ self._model["installation.device"] = first_dev
+ return self._model
def validators(self):
return {}
@@ -46,32 +51,45 @@
page_title = "Please select the disk(s) to use for installation " \
"of %s" % self.application.product.PRODUCT_SHORT
- ws = [ui.Header("header[0]", page_title),
- ui.Table("installation.device", "", " %6s %11s %5s" %
- ("Location", "Device Name", "Size"),
- self._device_list()),
- DeviceDetails("label.details", "(No device)")
- ]
+ devices = self._device_list()
- self.widgets.add(ws)
+ ws = [ui.Header("header[0]", page_title)]
+
+ if devices:
+ ws += [ui.Table("installation.device", "", " %6s %11s %5s" %
+ ("Location", "Device Name", "Size"), devices),
+ DeviceDetails("label.details", "(No device)")
+ ]
+ else:
+ ws += [ui.Label("installation.no_device",
+ "No Valid Install Devices Detected")]
+
page = ui.Page("device", ws)
- page.buttons = [ui.Button("button.quit", "Quit"),
+ page.buttons = [ui.QuitButton("button.quit", "Quit"),
ui.Button("button.back", "Back"),
- ui.Button("button.next", "Continue")]
+ ui.SaveButton("button.next", "Continue")]
+
+ self.widgets.add(page)
return page
def _device_list(self):
- devices = utils.storage.Devices(fake=True)
+ do_fake = False
+ if self.application.args.dry:
+ do_fake = True
+ devices = utils.storage.Devices(fake=do_fake)
all_devices = devices.get_all().items()
- return [(name, " %6s %11s %5s GB" % (d.bus, d.name, d.size))
- for name, d in all_devices]
+ return sorted([(name, " %6s %11s %5s GB" % (d.bus, d.name, d.size))
+ for name, d in all_devices], key=lambda t: t[0])
def on_change(self, changes):
- if "button.next" in changes:
- self._elements["label.details"].set_device(changes["button.next"])
+ if changes.contains_any(["installation.device"]):
+ self._model.update(changes)
+ w = self.widgets["label.details"]
+ w.set_device(changes["installation.device"])
def on_merge(self, effective_changes):
changes = self.pending_changes(False)
if changes.contains_any(["installation.device", "button.next"]):
- self.transaction = "a"
self.application.ui.navigate.to_next_plugin()
+ elif changes.contains_any(["button.back"]):
+ self.application.ui.navigate.to_previous_plugin()
diff --git a/scripts/tui/src/ovirt/node/installer/keyboard_page.py b/scripts/tui/src/ovirt/node/installer/keyboard_page.py
index 557c823..6bf9697 100644
--- a/scripts/tui/src/ovirt/node/installer/keyboard_page.py
+++ b/scripts/tui/src/ovirt/node/installer/keyboard_page.py
@@ -27,7 +27,6 @@
class Plugin(plugins.NodePlugin):
_model = {}
- _elements = None
def name(self):
return "Keyboard"
@@ -36,21 +35,24 @@
return 20
def model(self):
- return self._model or {}
+ return self._model
def validators(self):
return {}
def ui_content(self):
kbd = utils.Keyboard()
+ c = kbd.get_current()
+ self.logger.debug("Current layout: %s" % c)
ws = [ui.Header("header[0]", "Keyboard Layout Selection"),
ui.Table("keyboard.layout", "Available Keyboard Layouts",
- "", kbd.available_layouts()),
+ "", kbd.available_layouts(), c),
+ ui.Label("label[0]", "(Hit return to select a layout)")
]
self.widgets.add(ws)
page = ui.Page("keyboard", ws)
- page.buttons = [ui.Button("button.quit", "Quit"),
- ui.Button("button.next", "Continue")]
+ page.buttons = [ui.QuitButton("button.quit", "Quit"),
+ ui.SaveButton("button.next", "Continue")]
return page
def on_change(self, changes):
@@ -60,5 +62,8 @@
def on_merge(self, effective_changes):
changes = self.pending_changes(False)
if changes.contains_any(["keyboard.layout", "button.next"]):
- self.transaction = "a"
+ # Apply kbd layout directly so it takes affect on the password page
+ kbd = utils.Keyboard()
+ self.dry_or(lambda: kbd.set_layout(changes["keyboard.layout"]))
+
self.application.ui.navigate.to_next_plugin()
diff --git a/scripts/tui/src/ovirt/node/installer/password_page.py b/scripts/tui/src/ovirt/node/installer/password_page.py
index 30327a2..4c0edad 100644
--- a/scripts/tui/src/ovirt/node/installer/password_page.py
+++ b/scripts/tui/src/ovirt/node/installer/password_page.py
@@ -18,16 +18,16 @@
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
# MA 02110-1301, USA. A copy of the GNU General Public License is
# also available at http://www.gnu.org/copyleft/gpl.html.
+from ovirt.node import plugins, ui, valid
+from ovirt.node.plugins import Validator
"""
Password page of the installer
"""
-from ovirt.node import plugins, ui
class Plugin(plugins.NodePlugin):
- _model = None
- _elements = None
+ _model = {}
def name(self):
return "Console Password"
@@ -39,7 +39,10 @@
return self._model or {}
def validators(self):
- return {}
+ return {"root.password_confirmation":
+ Validator.SameAsIn(self, "root.password", "Password") | \
+ valid.Empty()
+ }
def ui_content(self):
ws = [ui.Header("header[0]",
@@ -51,16 +54,18 @@
]
self.widgets.add(ws)
page = ui.Page("password", ws)
- page.buttons = [ui.Button("button.quit", "Quit"),
+ page.buttons = [ui.QuitButton("button.quit", "Quit"),
ui.Button("button.back", "Back"),
- ui.Button("button.next", "Install")]
+ ui.SaveButton("button.next", "Install")]
return page
def on_change(self, changes):
- pass
+ if changes.contains_any(["root.password_confirmation"]):
+ self._model.update(changes)
def on_merge(self, effective_changes):
changes = self.pending_changes(False)
if changes.contains_any(["root.password_confirmation", "button.next"]):
- self.transaction = "a"
self.application.ui.navigate.to_next_plugin()
+ elif changes.contains_any(["button.back"]):
+ self.application.ui.navigate.to_previous_plugin()
diff --git a/scripts/tui/src/ovirt/node/installer/progress_page.py b/scripts/tui/src/ovirt/node/installer/progress_page.py
index c2dfab7..134ce2f 100644
--- a/scripts/tui/src/ovirt/node/installer/progress_page.py
+++ b/scripts/tui/src/ovirt/node/installer/progress_page.py
@@ -19,6 +19,7 @@
# MA 02110-1301, USA. A copy of the GNU General Public License is
# also available at http://www.gnu.org/copyleft/gpl.html.
from ovirt.node import plugins, ui, utils
+from ovirt.node.config import defaults
import threading
import time
@@ -29,8 +30,6 @@
class Plugin(plugins.NodePlugin):
- _model = None
- _elements = None
_worker = None
def __init__(self, application):
@@ -44,7 +43,7 @@
return 60
def model(self):
- return self._model or {}
+ return {}
def validators(self):
return {}
@@ -83,8 +82,8 @@
time.sleep(0.3) # Give the UI some time to build
transaction = self.__build_transaction()
- progressbar = self.progress_plugin._elements["progressbar"]
- log = self.progress_plugin._elements["log"]
+ progressbar = self.progress_plugin.widgets["progressbar"]
+ log = self.progress_plugin.widgets["log"]
log_lines = []
txlen = len(transaction)
@@ -104,27 +103,39 @@
log.text("EXECPTION: %s" % e)
def __build_transaction(self):
- self.__update_defaults_from_models()
-
tx = utils.Transaction("Installation")
+ app = self.progress_plugin.application
+ tx.append(self.UpdateDefaultsFromModels(app))
tx.append(self.PartitionAndFormat())
tx.append(self.SetPassword("the-password"))
tx.append(self.InstallBootloader())
+ tx.append(self.SetKeyboardLayout("da-layout"))
return tx
- def __update_defaults_from_models(self):
- config = {}
- app = self.progress_plugin.application
- for pname, plugin in app.plugins().items():
- self.logger.debug("Config for %s" % (pname))
- try:
- model = plugin.model()
- config.update(model)
- self.logger.debug("Merged config: %s" % (model))
- except NotImplementedError:
- self.logger.debug("Merged no config.")
+ class UpdateDefaultsFromModels(utils.Transaction.Element):
+ title = "Write configuration file"
+
+ def __init__(self, application):
+ super(InstallerThread.UpdateDefaultsFromModels, self).__init__()
+ self.application = application
+
+ def prepare(self):
+ config = {}
+ for pname, plugin in self.application.plugins().items():
+ self.logger.debug("Config for page %s" % (pname))
+ try:
+ model = plugin.model()
+ config.update(model)
+ self.logger.debug("Merged config: %s" % (model))
+ except NotImplementedError:
+ self.logger.debug("Merged no config.")
+ self.logger.debug("Final config: %s" % config)
+
+ def commit(self):
+ model = defaults.Storage()
+ raise NotImplementedError
class PartitionAndFormat(utils.Transaction.Element):
title = "Partitioning and Creating File Systems"
@@ -158,3 +169,14 @@
boot_setup = install.ovirt_boot_setup()
if not boot_setup:
raise RuntimeError("Failed to set install bootloader")
+
+ class SetKeyboardLayout(utils.Transaction.Element):
+ title = "Setting keyboard layout to '{kbd_layout}'"
+
+ def __init__(self, kbd_layout):
+ super(InstallerThread.SetKeyboardLayout, self).__init__()
+ self.kbd_layout = kbd_layout
+ self.title = self.title.format(kbd_layout=kbd_layout)
+
+ def commit(self):
+ utils.Keyboard().set_layout(self.kbd_layout)
diff --git a/scripts/tui/src/ovirt/node/installer/welcome_page.py b/scripts/tui/src/ovirt/node/installer/welcome_page.py
index 26aaffa..7533402 100644
--- a/scripts/tui/src/ovirt/node/installer/welcome_page.py
+++ b/scripts/tui/src/ovirt/node/installer/welcome_page.py
@@ -18,6 +18,9 @@
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
# MA 02110-1301, USA. A copy of the GNU General Public License is
# also available at http://www.gnu.org/copyleft/gpl.html.
+from ovirt.node import plugins, ui, utils
+from ovirt.node.utils import virt, system
+import os
"""
Welcome page of the installer
@@ -29,14 +32,12 @@
NOTE: Each page stores the information in the config page
NOTE II: Or shall we build the transactions per page?
"""
-from ovirt.node import plugins, ui
class Plugin(plugins.NodePlugin):
"""The welcome page plugin
"""
_model = {}
- _elements = None
def name(self):
return "Welcome"
@@ -51,12 +52,13 @@
return {}
def ui_content(self):
- ws = [ui.Button("button.install", "Install %s" %
- str(self.application.product)),
- ]
+ ws = [ui.Header("header[0]", "Installation")]
+ ws += [self.___installation_option()]
+ ws += [ui.Divider("divider[0]")]
+ ws += self.__additional_infos()
self.widgets.add(ws)
page = ui.Page("welcome", ws)
- page.buttons = [ui.Button("button.quit", "Quit")]
+ page.buttons = [ui.QuitButton("button.quit", "Quit")]
return page
def on_change(self, changes):
@@ -64,5 +66,48 @@
def on_merge(self, effective_changes):
if "button.install" in effective_changes:
- self.transaction = "a"
self.application.ui.navigate.to_next_plugin()
+
+ def ___installation_option(self):
+ if self.application.args.dry:
+ return ui.Button("button.install", "Install Hypervisor (dry)")
+
+ media = utils.system.InstallationMedia()
+ installed = utils.system.InstalledMedia()
+
+ has_hostvg = os.path.exists("/dev/HostVG")
+ has_root = os.path.exists("/dev/disk/by-label/ROOT")
+
+ if has_hostvg and has_root:
+ return ui.Label("Major version upgrades are unsupported, " +
+ "uninstall existing version first")
+
+ if has_hostvg:
+ try:
+ if media > installed:
+ return ui.Button("button.upgrade",
+ "Upgrade %s to %s" % (media, installed))
+ elif media < installed:
+ return ui.Button("button.downgrade",
+ "Downgrade %s to %s" % (media,
+ installed))
+ return ui.Button("button.reinstall",
+ "Reinstall %s" % installed)
+ except:
+ self.logger.error("Unable to get version numbers for " +
+ "upgrade, invalid installation or media")
+ return ui.Label("Invalid installation, please reboot from " +
+ "media and choose Reinstall")
+
+ return ui.Button("button.install", "Install Hypervisor %s" % media)
+
+ def __additional_infos(self):
+ ws = []
+ ws.append(ui.Label("welcome.virt", "Info: %s" %
+ virt.hardware_status()))
+ if system.is_efi():
+ ws.append(ui.Label("welcome.efi",
+ "Info: Machine is booted in EFI mode"))
+ if self.application.args.dry:
+ ws.append(ui.Label("dry", "Info: DRY MODE"))
+ return ws
--
To view, visit http://gerrit.ovirt.org/11066
To unsubscribe, visit http://gerrit.ovirt.org/settings
Gerrit-MessageType: newchange
Gerrit-Change-Id: I0c81e0e85ff35ee073dd5e47df9f53da0a8f7738
Gerrit-PatchSet: 1
Gerrit-Project: ovirt-node
Gerrit-Branch: master
Gerrit-Owner: Fabian Deutsch <fabiand at fedoraproject.org>
More information about the node-patches
mailing list