diff --git a/tools/agent_tui/app.go b/tools/agent_tui/app.go index 263762f..a6382d5 100644 --- a/tools/agent_tui/app.go +++ b/tools/agent_tui/app.go @@ -1,6 +1,9 @@ package agent_tui import ( + "fmt" + "log" + "github.com/openshift/agent-installer-utils/tools/agent_tui/checks" "github.com/openshift/agent-installer-utils/tools/agent_tui/dialogs" "github.com/openshift/agent-installer-utils/tools/agent_tui/ui" @@ -8,21 +11,53 @@ import ( ) func App(app *tview.Application, config checks.Config) { + + if err := prepareConfig(&config); err != nil { + log.Fatal(err) + } + var appUI *ui.UI if app == nil { app = tview.NewApplication() } - appUI = ui.NewUI(app, config) - controller := ui.NewController(appUI) - engine := checks.NewEngine(controller.GetChan(), config) controller.Init(engine.Size()) engine.Init() - if err := app.Run(); err != nil { dialogs.PanicDialog(app, err) } } + +func prepareConfig(config *checks.Config) error { + // Set hostname + hostname, err := checks.ParseHostnameFromURL(config.ReleaseImageURL) + if err != nil { + log.Fatal(err) + } + config.ReleaseImageHostname = hostname + + // Set scheme + schemeHostnamePort, err := checks.ParseSchemeHostnamePortFromURL(config.ReleaseImageURL, "https://") + if err != nil { + log.Fatalf("Error creating ://: from releaseImageURL: %s\n", config.ReleaseImageURL) + } + config.ReleaseImageSchemeHostnamePort = schemeHostnamePort + + // Set skipped checks + skippedPingUrls := []string{ + "quay.io", + "registry.ci.openshift.org", + } + + config.SkippedChecks = map[string]string{} + for _, s := range skippedPingUrls { + if s == hostname { + config.SkippedChecks[checks.CheckTypeReleaseImageHostPing] = fmt.Sprintf("%s does not respond to ping, ping skipped", hostname) + } + } + + return nil +} diff --git a/tools/agent_tui/app_test.go b/tools/agent_tui/app_test.go index 8789e8a..ad78d8c 100644 --- a/tools/agent_tui/app_test.go +++ b/tools/agent_tui/app_test.go @@ -37,7 +37,7 @@ func TestChecksPage(t *testing.T) { appConfig.ReleaseImageURL, "✓ podman pull release image", "✓ nslookup quay.io", - "✓ quay.io does not respond to ping, ping skipped") + "? quay.io does not respond to ping, ping skipped") }, }, { diff --git a/tools/agent_tui/checks/engine.go b/tools/agent_tui/checks/engine.go index debd3c0..033b355 100644 --- a/tools/agent_tui/checks/engine.go +++ b/tools/agent_tui/checks/engine.go @@ -21,6 +21,10 @@ const ( type Config struct { ReleaseImageURL string LogPath string + + SkippedChecks map[string]string + ReleaseImageHostname string + ReleaseImageSchemeHostnamePort string } // ChecksEngine is the model part, and is composed by a number @@ -63,7 +67,7 @@ func (e *Engine) createCheckResult(f checkFunction, checkType string) CheckResul return result } -func (e *Engine) newRegistryImagePullCheck(releaseImageURL string) *Check { +func (e *Engine) newRegistryImagePullCheck(config Config) *Check { ctype := CheckTypeReleaseImagePull return &Check{ Type: ctype, @@ -71,7 +75,7 @@ func (e *Engine) newRegistryImagePullCheck(releaseImageURL string) *Check { Run: func(c chan CheckResult, freq time.Duration) { for { checkFunction := func() ([]byte, error) { - return exec.Command("podman", "pull", releaseImageURL).CombinedOutput() + return exec.Command("podman", "pull", config.ReleaseImageURL).CombinedOutput() } c <- e.createCheckResult(checkFunction, ctype) time.Sleep(freq) @@ -80,7 +84,7 @@ func (e *Engine) newRegistryImagePullCheck(releaseImageURL string) *Check { } } -func (e *Engine) newReleaseImageHostDNSCheck(hostname string) *Check { +func (e *Engine) newReleaseImageHostDNSCheck(config Config) *Check { ctype := CheckTypeReleaseImageHostDNS return &Check{ Type: ctype, @@ -88,7 +92,7 @@ func (e *Engine) newReleaseImageHostDNSCheck(hostname string) *Check { Run: func(c chan CheckResult, freq time.Duration) { for { checkFunction := func() ([]byte, error) { - return exec.Command("nslookup", hostname).CombinedOutput() + return exec.Command("nslookup", config.ReleaseImageHostname).CombinedOutput() } c <- e.createCheckResult(checkFunction, ctype) time.Sleep(freq) @@ -97,23 +101,15 @@ func (e *Engine) newReleaseImageHostDNSCheck(hostname string) *Check { } } -func (e *Engine) newReleaseImageHostPingCheck(hostname string) *Check { +func (e *Engine) newReleaseImageHostPingCheck(config Config) *Check { ctype := CheckTypeReleaseImageHostPing return &Check{ Type: ctype, Freq: 5 * time.Second, Run: func(c chan CheckResult, freq time.Duration) { for { - var checkFunction func() ([]byte, error) - if hostname == "quay.io" { - // quay.io does not respond to ping - checkFunction = func() ([]byte, error) { - return nil, nil - } - } else { - checkFunction = func() ([]byte, error) { - return exec.Command("ping", "-c", "4", hostname).CombinedOutput() - } + checkFunction := func() ([]byte, error) { + return exec.Command("ping", "-c", "4", config.ReleaseImageHostname).CombinedOutput() } c <- e.createCheckResult(checkFunction, ctype) time.Sleep(freq) @@ -125,7 +121,8 @@ func (e *Engine) newReleaseImageHostPingCheck(hostname string) *Check { // This check verifies whether there is a http server response // when schemeHostnamePort is queried. This does not check // if the release image exists. -func (e *Engine) newReleaseImageHttpCheck(schemeHostnamePort string) *Check { +func (e *Engine) newReleaseImageHttpCheck(config Config) *Check { + ctype := CheckTypeReleaseImageHttp return &Check{ Type: ctype, @@ -133,7 +130,7 @@ func (e *Engine) newReleaseImageHttpCheck(schemeHostnamePort string) *Check { Run: func(c chan CheckResult, freq time.Duration) { for { checkFunction := func() ([]byte, error) { - resp, err := http.Get(schemeHostnamePort) + resp, err := http.Get(config.ReleaseImageSchemeHostnamePort) if err != nil { return []byte(err.Error()), err } else { @@ -164,27 +161,24 @@ func NewEngine(c chan CheckResult, config Config) *Engine { logger.Infof("Release Image URL: %s", config.ReleaseImageURL) - hostname, err := ParseHostnameFromURL(config.ReleaseImageURL) - if err != nil { - logger.Fatalf("Error parsing hostname from releaseImageURL: %s\n", config.ReleaseImageURL) - } - - schemeHostnamePort, err := ParseSchemeHostnamePortFromURL(config.ReleaseImageURL, "https://") - if err != nil { - logger.Fatalf("Error creating ://: from releaseImageURL: %s\n", config.ReleaseImageURL) - } - e := &Engine{ checks: checks, channel: c, logger: logger, } - e.checks = append(e.checks, - e.newRegistryImagePullCheck(config.ReleaseImageURL), - e.newReleaseImageHostDNSCheck(hostname), - e.newReleaseImageHostPingCheck(hostname), - e.newReleaseImageHttpCheck(schemeHostnamePort)) + for _, c := range []*Check{ + e.newRegistryImagePullCheck(config), + e.newReleaseImageHostDNSCheck(config), + e.newReleaseImageHostPingCheck(config), + e.newReleaseImageHttpCheck(config), + } { + if reason, skipped := config.SkippedChecks[c.Type]; skipped { + logger.Infof(reason) + continue + } + e.checks = append(e.checks, c) + } return e } diff --git a/tools/agent_tui/ui/check_page.go b/tools/agent_tui/ui/check_page.go index 7d7d4bf..33041ba 100644 --- a/tools/agent_tui/ui/check_page.go +++ b/tools/agent_tui/ui/check_page.go @@ -2,10 +2,10 @@ package ui import ( "fmt" + "strings" "github.com/gdamore/tcell/v2" "github.com/openshift/agent-installer-utils/tools/agent_tui/checks" - "github.com/openshift/agent-installer-utils/tools/agent_tui/dialogs" "github.com/openshift/agent-installer-utils/tools/agent_tui/newt" "github.com/rivo/tview" ) @@ -59,6 +59,22 @@ func (u *UI) appendToDetails(newLines string) { u.details.SetText(current + newLines) } +func (u *UI) setCheckWidget(row int, checkType string, desc string, config checks.Config) { + u.markCheckUnknown(row, 0) + + if skipReason, skipped := config.SkippedChecks[checkType]; skipped { + u.setCheckDescription(row, 1, skipReason) + return + } + + checkDesc := desc + if strings.Contains(desc, "%s") { + checkDesc = fmt.Sprintf(desc, config.ReleaseImageHostname) + } + u.setCheckDescription(row, 1, checkDesc) + +} + func (u *UI) createCheckPage(config checks.Config) { u.envVars = tview.NewTextView() u.envVars.SetBorder(true) @@ -69,29 +85,17 @@ func (u *UI) createCheckPage(config checks.Config) { u.envVars.SetText("\n" + config.ReleaseImageURL) u.envVars.SetTextColor(newt.ColorBlack) - releaseImageHostName, err := checks.ParseHostnameFromURL(config.ReleaseImageURL) - if err != nil { - dialogs.PanicDialog(u.app, err) - } - u.checks = tview.NewTable() u.checks.SetBorder(true) u.checks.SetTitle(" Checks ") u.checks.SetBorderColor(newt.ColorBlack) u.checks.SetBackgroundColor(newt.ColorGray) u.checks.SetTitleColor(newt.ColorBlack) - u.markCheckUnknown(0, 0) - u.setCheckDescription(0, 1, "podman pull release image") - u.markCheckUnknown(1, 0) - u.setCheckDescription(1, 1, "nslookup "+releaseImageHostName) - u.markCheckUnknown(2, 0) - if releaseImageHostName == "quay.io" { - u.setCheckDescription(2, 1, "quay.io does not respond to ping, ping skipped") - } else { - u.setCheckDescription(2, 1, "ping "+releaseImageHostName) - } - u.markCheckUnknown(3, 0) - u.setCheckDescription(3, 1, releaseImageHostName+" responds to http GET") + + u.setCheckWidget(0, checks.CheckTypeReleaseImagePull, "podman pull release image", config) + u.setCheckWidget(1, checks.CheckTypeReleaseImageHostDNS, "nslookup %s", config) + u.setCheckWidget(2, checks.CheckTypeReleaseImageHostPing, "ping %s", config) + u.setCheckWidget(3, checks.CheckTypeReleaseImageHttp, "%s responds to http GET", config) u.details = tview.NewTextView() u.details.SetBorder(true)