mirror of
https://github.com/clearlinux/clr-installer.git
synced 2026-09-05 13:11:28 +00:00
Directly after TUI init, run the system check and report if there are any failures, and force application exit. Signed-off-by: Brian J Lovin <brian.j.lovin@intel.com>
200 lines
5.1 KiB
Go
200 lines
5.1 KiB
Go
// Copyright © 2019 Intel Corporation
|
|
//
|
|
// SPDX-License-Identifier: GPL-3.0-only
|
|
|
|
package tui
|
|
|
|
import (
|
|
"github.com/clearlinux/clr-installer/args"
|
|
"github.com/clearlinux/clr-installer/cmd"
|
|
"github.com/clearlinux/clr-installer/log"
|
|
"github.com/clearlinux/clr-installer/model"
|
|
"github.com/clearlinux/clr-installer/syscheck"
|
|
"github.com/clearlinux/clr-installer/utils"
|
|
|
|
"github.com/VladimirMarkelov/clui"
|
|
"github.com/nsf/termbox-go"
|
|
)
|
|
|
|
// Tui is the main tui data struct and holds data about the higher level data for this
|
|
// front end, it also implements the Frontend interface
|
|
type Tui struct {
|
|
pages []Page
|
|
currPage Page
|
|
prevPage Page
|
|
model *model.SystemInstall
|
|
options args.Args
|
|
rootDir string
|
|
paniced chan error
|
|
installReboot bool
|
|
}
|
|
|
|
var (
|
|
// errorLabelBg is a custom theme element, it has the error label background color definition
|
|
errorLabelBg termbox.Attribute
|
|
|
|
// errorLabelFg is a custom theme element, it has the error label foreground color definition
|
|
errorLabelFg termbox.Attribute
|
|
)
|
|
|
|
// New creates a new Tui frontend instance
|
|
func New() *Tui {
|
|
return &Tui{pages: []Page{}}
|
|
}
|
|
|
|
// MustRun is part of the Frontend interface implementation and tells the core that this
|
|
// frontend wants/must run.
|
|
func (tui *Tui) MustRun(args *args.Args) bool {
|
|
return true
|
|
}
|
|
|
|
// Run is part of the Frontend interface implementation and is the tui frontend main entry point
|
|
func (tui *Tui) Run(md *model.SystemInstall, rootDir string, options args.Args) (bool, error) {
|
|
// First disable console messages
|
|
err := cmd.RunAndLog("dmesg", "--console-off")
|
|
if err != nil {
|
|
log.Warning("Failed to disable dmesg on console: %v", err)
|
|
}
|
|
// Defer enabling console messages
|
|
defer func() {
|
|
err := cmd.RunAndLog("dmesg", "--console-on")
|
|
if err != nil {
|
|
log.Warning("Failed to enable dmesg on console: %v", err)
|
|
}
|
|
}()
|
|
|
|
clui.InitLibrary()
|
|
defer clui.DeinitLibrary()
|
|
|
|
tui.model = md
|
|
tui.options = options
|
|
themeDir, err := utils.LookupThemeDir()
|
|
if err != nil {
|
|
return false, err
|
|
}
|
|
|
|
// When using the Interactive Installer we always want to copy network
|
|
// configurations to the target system
|
|
tui.model.CopyNetwork = options.CopyNetwork
|
|
|
|
clui.SetThemePath(themeDir)
|
|
|
|
if !clui.SetCurrentTheme("clr-installer") {
|
|
panic("Could not change theme")
|
|
}
|
|
|
|
errorLabelBg = clui.RealColor(clui.ColorDefault, "ErrorLabel", "Back")
|
|
errorLabelFg = clui.RealColor(clui.ColorDefault, "ErrorLabel", "Text")
|
|
|
|
tui.rootDir = rootDir
|
|
tui.paniced = make(chan error, 1)
|
|
|
|
menus := []struct {
|
|
desc string
|
|
fc func(*Tui) (Page, error)
|
|
}{
|
|
{"timezone", newTimezonePage},
|
|
{"language", newLanguagePage},
|
|
{"keyboard", newKeyboardPage},
|
|
{"media config", newMediaConfigPage},
|
|
{"disk config", newDiskConfigPage},
|
|
{"disk partition", newDiskPartitionPage},
|
|
{"network", newNetworkPage},
|
|
{"proxy", newProxyPage},
|
|
{"network validate", newNetworkValidatePage},
|
|
{"network interface", newNetworkInterfacePage},
|
|
{"main menu", newMenuPage},
|
|
{"bundle selection", newBundlePage},
|
|
{"add manager", newUserManagerPage},
|
|
{"add user", newUseraddPage},
|
|
{"telemetry enabling", newTelemetryPage},
|
|
{"kernel cmdline", newKernelCMDLine},
|
|
{"kernel selection", newKernelPage},
|
|
{"install", newInstallPage},
|
|
{"swupd mirror", newSwupdMirrorPage},
|
|
{"hostname", newHostnamePage},
|
|
{"autoupdate", newAutoUpdatePage},
|
|
{"save config", newSaveConfigPage},
|
|
}
|
|
|
|
for _, menu := range menus {
|
|
var page Page
|
|
|
|
if page, err = menu.fc(tui); err != nil {
|
|
return false, err
|
|
}
|
|
|
|
tui.pages = append(tui.pages, page)
|
|
}
|
|
|
|
tui.gotoPage(TuiPageMenu, tui.currPage)
|
|
|
|
var paniced error
|
|
|
|
go func() {
|
|
if paniced = <-tui.paniced; paniced != nil {
|
|
clui.Stop()
|
|
log.ErrorError(paniced)
|
|
}
|
|
}()
|
|
|
|
// Run system check, if fail report error and exit
|
|
if retErr := syscheck.RunSystemCheck(true); retErr != nil {
|
|
msg := "System failed to pass pre-install checks." + "\n" +
|
|
retErr.Error() + "\n\n" +
|
|
"The application will now exit."
|
|
|
|
if dialog, err := CreateWarningDialogBox(msg); err == nil {
|
|
dialog.OnClose(func() {
|
|
clui.Stop()
|
|
log.ErrorError(retErr)
|
|
})
|
|
} else {
|
|
log.Warning("Failed to create warning dialog: %s", err)
|
|
}
|
|
}
|
|
|
|
clui.MainLoop()
|
|
|
|
if paniced != nil {
|
|
if errLog := md.Telemetry.LogRecord("tuipanic", 3, paniced.Error()); errLog != nil {
|
|
log.Error("Failed to log Telemetry fail record: %s", "tuipanic")
|
|
}
|
|
log.RequestCrashInfo()
|
|
return false, paniced
|
|
}
|
|
|
|
return tui.installReboot, nil
|
|
}
|
|
|
|
func (tui *Tui) gotoPage(id int, currPage Page) {
|
|
if tui.currPage != nil && !isPopUpPage(id) {
|
|
if tui.currPage.GetWindow() != nil {
|
|
tui.currPage.GetWindow().SetVisible(false)
|
|
tui.currPage.DeActivate()
|
|
|
|
// TODO clui is not hiding cursor when we hide/destroy an edit widget
|
|
termbox.HideCursor()
|
|
}
|
|
}
|
|
|
|
tui.currPage = tui.getPage(id)
|
|
tui.prevPage = currPage
|
|
|
|
tui.currPage.Activate()
|
|
if !isPopUpPage(id) {
|
|
tui.currPage.GetWindow().SetVisible(true)
|
|
clui.ActivateControl(tui.currPage.GetWindow(), tui.currPage.GetActivated())
|
|
}
|
|
}
|
|
|
|
func (tui *Tui) getPage(page int) Page {
|
|
for _, curr := range tui.pages {
|
|
if curr.GetID() == page {
|
|
return curr
|
|
}
|
|
}
|
|
|
|
return nil
|
|
}
|