Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
43 changes: 39 additions & 4 deletions tools/agent_tui/app.go
Original file line number Diff line number Diff line change
@@ -1,28 +1,63 @@
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"
"github.com/rivo/tview"
)

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 <scheme>://<hostname>:<port> 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
}
2 changes: 1 addition & 1 deletion tools/agent_tui/app_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -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")
},
},
{
Expand Down
58 changes: 26 additions & 32 deletions tools/agent_tui/checks/engine.go
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -63,15 +67,15 @@ 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,
Freq: 5 * time.Second,
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)
Expand All @@ -80,15 +84,15 @@ 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,
Freq: 5 * time.Second,
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)
Expand All @@ -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)
Expand All @@ -125,15 +121,16 @@ 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,
Freq: 5 * time.Second,
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 {
Expand Down Expand Up @@ -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 <scheme>://<hostname>:<port> 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
}
Expand Down
40 changes: 22 additions & 18 deletions tools/agent_tui/ui/check_page.go
Original file line number Diff line number Diff line change
Expand Up @@ -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"
)
Expand Down Expand Up @@ -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)
Expand All @@ -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)
Expand Down