diff --git a/README.md b/README.md index 7dbd6ba1..6febfdc9 100644 --- a/README.md +++ b/README.md @@ -69,6 +69,9 @@ wander_addr: http://localhost:4646 # required: nomad token wander_token: nomad_token +# optional (default 2): update interval for jobs and allocations data. Disable by setting to -1 +wander_update_seconds: 1 + # only relevant for `wander serve` - the host of the machine serving the ssh app wander_host: localhost diff --git a/cmd/root.go b/cmd/root.go index 677785e5..05a3a6b1 100644 --- a/cmd/root.go +++ b/cmd/root.go @@ -29,10 +29,10 @@ var ( cliLong: "token", config: "wander_token", } - pollSecondsArg = arg{ - cliShort: "p", - cliLong: "poll", - config: "wander_poll_seconds", + updateSecondsArg = arg{ + cliShort: "u", + cliLong: "update", + config: "wander_update_seconds", } description = `wander is a terminal application for Nomad by HashiCorp. It is used to @@ -65,8 +65,8 @@ func init() { viper.BindPFlag(tokenArg.cliLong, rootCmd.PersistentFlags().Lookup(tokenArg.config)) rootCmd.PersistentFlags().StringP(addrArg.cliLong, addrArg.cliShort, "", "nomad address, e.g. http://localhost:4646") viper.BindPFlag(addrArg.cliLong, rootCmd.PersistentFlags().Lookup(addrArg.config)) - rootCmd.PersistentFlags().StringP(pollSecondsArg.cliLong, pollSecondsArg.cliShort, "", "number of seconds between page updates") - viper.BindPFlag(pollSecondsArg.cliLong, rootCmd.PersistentFlags().Lookup(pollSecondsArg.config)) + rootCmd.PersistentFlags().StringP(updateSecondsArg.cliLong, updateSecondsArg.cliShort, "", "number of seconds between page updates") + viper.BindPFlag(updateSecondsArg.cliLong, rootCmd.PersistentFlags().Lookup(updateSecondsArg.config)) // serve serveCmd.PersistentFlags().StringP(hostArg.cliLong, hostArg.cliShort, "", "host for wander ssh server") @@ -102,8 +102,8 @@ func initConfig() { func mainEntrypoint(cmd *cobra.Command, args []string) { nomadAddr := retrieveAssertExists(cmd, addrArg.cliLong, addrArg.config) nomadToken := retrieveAssertExists(cmd, tokenArg.cliLong, tokenArg.config) - pollSeconds := retrievePollSeconds(cmd) - program := tea.NewProgram(initialModel(nomadAddr, nomadToken, pollSeconds), tea.WithAltScreen()) + updateSeconds := retrieveUpdateSeconds(cmd) + program := tea.NewProgram(initialModel(nomadAddr, nomadToken, updateSeconds), tea.WithAltScreen()) dev.Debug("~STARTING UP~") if err := program.Start(); err != nil { diff --git a/cmd/serve.go b/cmd/serve.go index a1e35532..1c1bc5c4 100644 --- a/cmd/serve.go +++ b/cmd/serve.go @@ -80,11 +80,11 @@ func generateTeaHandler(cmd *cobra.Command) func(ssh.Session) (tea.Model, []tea. return func(s ssh.Session) (tea.Model, []tea.ProgramOption) { nomadAddr := retrieveAssertExists(cmd, addrArg.cliLong, addrArg.config) nomadToken := retrieveAssertExists(cmd, tokenArg.cliLong, tokenArg.config) - pollSeconds := retrievePollSeconds(cmd) + updateSeconds := retrieveUpdateSeconds(cmd) // optionally override token - MUST run with `-t` flag to force pty, e.g. ssh -p 20000 localhost -t if sshCommands := s.Command(); len(sshCommands) == 1 { nomadToken = strings.TrimSpace(sshCommands[0]) } - return initialModel(nomadAddr, nomadToken, pollSeconds), []tea.ProgramOption{tea.WithAltScreen()} + return initialModel(nomadAddr, nomadToken, updateSeconds), []tea.ProgramOption{tea.WithAltScreen()} } } diff --git a/cmd/util.go b/cmd/util.go index b767828d..4a19da30 100644 --- a/cmd/util.go +++ b/cmd/util.go @@ -48,14 +48,14 @@ func retrieveWithDefault(cmd *cobra.Command, short, long, defaultVal string) str return val } -func retrievePollSeconds(cmd *cobra.Command) int { - pollSecondsString := retrieveWithDefault(cmd, pollSecondsArg.cliLong, pollSecondsArg.config, constants.DefaultPollSeconds) - pollSeconds, err := strconv.Atoi(pollSecondsString) +func retrieveUpdateSeconds(cmd *cobra.Command) int { + updateSecondsString := retrieveWithDefault(cmd, updateSecondsArg.cliLong, updateSecondsArg.config, constants.DefaultUpdateSeconds) + updateSeconds, err := strconv.Atoi(updateSecondsString) if err != nil { - fmt.Println(fmt.Errorf("poll value %s cannot be converted to an integer", pollSecondsString)) + fmt.Println(fmt.Errorf("update value %s cannot be converted to an integer", updateSecondsString)) os.Exit(1) } - return pollSeconds + return updateSeconds } // CustomLoggingMiddleware provides basic connection logging. Connects are logged with the @@ -75,8 +75,8 @@ func CustomLoggingMiddleware() wish.Middleware { } } -func initialModel(addr, token string, pollSeconds int) app.Model { - return app.InitialModel(Version, CommitSHA, addr, token, pollSeconds) +func initialModel(addr, token string, updateSeconds int) app.Model { + return app.InitialModel(Version, CommitSHA, addr, token, updateSeconds) } func getVersion() string { diff --git a/internal/tui/components/app/app.go b/internal/tui/components/app/app.go index 9794ecdd..7edecafc 100644 --- a/internal/tui/components/app/app.go +++ b/internal/tui/components/app/app.go @@ -40,24 +40,24 @@ type Model struct { webSocketConnected bool lastCommandFinished struct{ stdOut, stdErr bool } - pollInterval time.Duration + updateInterval time.Duration width, height int initialized bool err error } -func InitialModel(version, sha, url, token string, pollSeconds int) Model { +func InitialModel(version, sha, url, token string, updateSeconds int) Model { firstPage := nomad.JobsPage initialHeader := header.New(constants.LogoString, url, getVersionString(version, sha), nomad.GetPageKeyHelp(firstPage, false, false, false, false, false, false)) - pollInterval := time.Second * time.Duration(pollSeconds) + updateInterval := time.Second * time.Duration(updateSeconds) return Model{ - nomadUrl: url, - nomadToken: token, - header: initialHeader, - currentPage: firstPage, - pollInterval: pollInterval, + nomadUrl: url, + nomadToken: token, + header: initialHeader, + currentPage: firstPage, + updateInterval: updateInterval, } } @@ -149,7 +149,7 @@ func (m Model) Update(msg tea.Msg) (tea.Model, tea.Cmd) { } case key.Matches(msg, keymap.KeyMap.Reload): - if m.currentPage.Reloads() { + if m.currentPage.DoesReload() { m.getCurrentPageModel().SetLoading(true) return m, m.getCurrentPageCmd() } @@ -243,10 +243,10 @@ func (m Model) Update(msg tea.Msg) (tea.Model, tea.Cmd) { case nomad.ExecPage: m.getCurrentPageModel().SetInputPrefix("Enter command: ") } - cmds = append(cmds, nomad.PollPageDataWithDelay(m.currentPage, m.pollInterval)) + cmds = append(cmds, nomad.UpdatePageDataWithDelay(m.currentPage, m.updateInterval)) } - case nomad.PollPageDataMsg: + case nomad.UpdatePageDataMsg: if msg.Page == m.currentPage { cmds = append(cmds, m.getCurrentPageCmd()) } @@ -350,7 +350,7 @@ func (m *Model) setPage(page nomad.Page) { m.getCurrentPageModel().HideToast() m.currentPage = page m.getCurrentPageModel().SetFilterPrefix(m.getFilterPrefix(page)) - if page.Loads() { + if page.DoesLoad() { m.getCurrentPageModel().SetLoading(true) } else { m.getCurrentPageModel().SetLoading(false) diff --git a/internal/tui/constants/constants.go b/internal/tui/constants/constants.go index 0d2acdcf..26288823 100644 --- a/internal/tui/constants/constants.go +++ b/internal/tui/constants/constants.go @@ -20,7 +20,7 @@ const ExecWebSocketClosed = "> connection closed <" const ExecWebSocketHeartbeatDuration = time.Second * 10 -const DefaultPollSeconds = "2" +const DefaultUpdateSeconds = "2" const TablePadding = " " diff --git a/internal/tui/nomad/pages.go b/internal/tui/nomad/pages.go index ed3358b8..dd67834b 100644 --- a/internal/tui/nomad/pages.go +++ b/internal/tui/nomad/pages.go @@ -26,7 +26,7 @@ const ( LoglinePage ) -func (p Page) Loads() bool { +func (p Page) DoesLoad() bool { noLoadPages := []Page{LoglinePage} for _, noLoadPage := range noLoadPages { if noLoadPage == p { @@ -36,7 +36,7 @@ func (p Page) Loads() bool { return true } -func (p Page) Reloads() bool { +func (p Page) DoesReload() bool { noReloadPages := []Page{LoglinePage, ExecPage} for _, noReloadPage := range noReloadPages { if noReloadPage == p { @@ -46,16 +46,16 @@ func (p Page) Reloads() bool { return true } -func (p Page) polls() bool { - noPollPages := []Page{ +func (p Page) doesUpdate() bool { + noUpdatePages := []Page{ LoglinePage, // doesn't load ExecPage, // doesn't reload LogsPage, // currently makes scrolling impossible - solve in https://github.com/robinovitch61/wander/issues/1 JobSpecPage, // would require changes to make scrolling possible AllocSpecPage, // would require changes to make scrolling possible } - for _, noPollPage := range noPollPages { - if noPollPage == p { + for _, noUpdatePage := range noUpdatePages { + if noUpdatePage == p { return false } } @@ -145,11 +145,11 @@ type PageLoadedMsg struct { AllPageData []page.Row } -type PollPageDataMsg struct{ Page Page } +type UpdatePageDataMsg struct{ Page Page } -func PollPageDataWithDelay(p Page, d time.Duration) tea.Cmd { - if p.polls() && d > 0 { - return tea.Tick(d, func(t time.Time) tea.Msg { return PollPageDataMsg{p} }) +func UpdatePageDataWithDelay(p Page, d time.Duration) tea.Cmd { + if p.doesUpdate() && d > 0 { + return tea.Tick(d, func(t time.Time) tea.Msg { return UpdatePageDataMsg{p} }) } return nil } @@ -170,7 +170,7 @@ func changeKeyHelp(k *key.Binding, h string) { func GetPageKeyHelp(currentPage Page, filterFocused, filterApplied, saving, enteringInput, inPty, webSocketConnected bool) string { firstRow := []key.Binding{keymap.KeyMap.Exit} - if currentPage.Reloads() && !saving && !filterFocused { + if currentPage.DoesReload() && !saving && !filterFocused { firstRow = append(firstRow, keymap.KeyMap.Reload) }