added interactive shell multistep-init

This commit is contained in:
sqshq 2019-06-23 00:08:24 -04:00
parent e78971482f
commit 83f8d04225
6 changed files with 70 additions and 15 deletions

View File

@ -388,7 +388,11 @@ textboxes:
</details> </details>
### JMX ### JMX
<details><summary>Java application uptime</summary>
Prerequisite: download [jmxterm jar file](https://docs.cyclopsgroup.org/jmxterm) Prerequisite: download [jmxterm jar file](https://docs.cyclopsgroup.org/jmxterm)
```yml ```yml
textboxes: textboxes:
- title: Java application uptime - title: Java application uptime
@ -399,3 +403,5 @@ textboxes:
sample: get Uptime sample: get Uptime
transform: echo $sample | tr -dc '0-9' | awk '{printf "%.1f min", $1/1000/60}' transform: echo $sample | tr -dc '0-9' | awk '{printf "%.1f min", $1/1000/60}'
``` ```
</details>

View File

@ -103,12 +103,13 @@ type LegendConfig struct {
} }
type Item struct { type Item struct {
Label *string `yaml:"label,omitempty"` Label *string `yaml:"label,omitempty"`
Color *ui.Color `yaml:"color,omitempty"` Color *ui.Color `yaml:"color,omitempty"`
Pty *bool `yaml:"pty,omitempty"` Pty *bool `yaml:"pty,omitempty"`
InitScript *string `yaml:"init,omitempty"` InitScript *string `yaml:"init,omitempty"`
SampleScript *string `yaml:"sample"` MultiStepInitScript *[]string `yaml:"multistep-init,omitempty"`
TransformScript *string `yaml:"transform,omitempty"` SampleScript *string `yaml:"sample"`
TransformScript *string `yaml:"transform,omitempty"`
} }
type Location struct { type Location struct {

View File

@ -12,31 +12,53 @@ func (c *Config) validate() {
for _, c := range c.RunCharts { for _, c := range c.RunCharts {
components = append(components, c.ComponentConfig) components = append(components, c.ComponentConfig)
validateLabelsUniqueness(c.Title, c.Items) validateLabelsUniqueness(c.Title, c.Items)
validateItemsScripts(c.Title, c.Items)
} }
for _, c := range c.BarCharts { for _, c := range c.BarCharts {
components = append(components, c.ComponentConfig) components = append(components, c.ComponentConfig)
validateLabelsUniqueness(c.Title, c.Items) validateLabelsUniqueness(c.Title, c.Items)
validateItemsScripts(c.Title, c.Items)
} }
for _, c := range c.SparkLines { for _, c := range c.SparkLines {
components = append(components, c.ComponentConfig) components = append(components, c.ComponentConfig)
validateItemScripts(c.Title, c.Item)
} }
for _, c := range c.Gauges { for _, c := range c.Gauges {
components = append(components, c.ComponentConfig) components = append(components, c.ComponentConfig)
validateItemScripts(c.Title, c.Min)
validateItemScripts(c.Title, c.Max)
validateItemScripts(c.Title, c.Cur)
} }
for _, c := range c.AsciiBoxes { for _, c := range c.AsciiBoxes {
components = append(components, c.ComponentConfig) components = append(components, c.ComponentConfig)
validateItemScripts(c.Title, c.Item)
} }
for _, c := range c.TextBoxes { for _, c := range c.TextBoxes {
components = append(components, c.ComponentConfig) components = append(components, c.ComponentConfig)
validateItemScripts(c.Title, c.Item)
} }
validateTitlesUniqueness(components) validateTitlesUniqueness(components)
} }
func validateItemsScripts(title string, items []Item) {
for _, i := range items {
if i.InitScript != nil && i.MultiStepInitScript != nil {
validateItemScripts(title, i)
}
}
}
func validateItemScripts(title string, i Item) {
if i.InitScript != nil && i.MultiStepInitScript != nil {
console.Exit(fmt.Sprintf("Config validation error: both init and multistep-init scripts are not allowed in '%s'", title))
}
}
func validateLabelsUniqueness(title string, items []Item) { func validateLabelsUniqueness(title string, items []Item) {
labels := make(map[string]bool) labels := make(map[string]bool)
for _, c := range items { for _, i := range items {
label := *c.Label label := *i.Label
if _, contains := labels[label]; contains { if _, contains := labels[label]; contains {
console.Exit(fmt.Sprintf("Config validation error: item labels should be unique. Please rename '%s' in '%s'", label, title)) console.Exit(fmt.Sprintf("Config validation error: item labels should be unique. Please rename '%s' in '%s'", label, title))
} }

View File

@ -13,7 +13,7 @@ import (
) )
const ( const (
startupTimeout = 100 * time.Millisecond startupTimeout = 200 * time.Millisecond
minAwaitTimeout = 100 * time.Millisecond minAwaitTimeout = 100 * time.Millisecond
maxAwaitTimeout = 1 * time.Second maxAwaitTimeout = 1 * time.Second
) )
@ -33,7 +33,7 @@ type PtyInteractiveShell struct {
func (s *PtyInteractiveShell) init() error { func (s *PtyInteractiveShell) init() error {
cmd := exec.Command("sh", "-c", *s.item.initScript) cmd := exec.Command("sh", "-c", s.item.initScripts[0])
enrichEnvVariables(cmd, s.variables) enrichEnvVariables(cmd, s.variables)
file, err := pty.Start(cmd) file, err := pty.Start(cmd)
@ -61,6 +61,14 @@ func (s *PtyInteractiveShell) init() error {
time.Sleep(startupTimeout) time.Sleep(startupTimeout)
for i := 1; i < len(s.item.initScripts); i++ {
_, err = io.WriteString(s.file, fmt.Sprintf(" %s\n", s.item.initScripts[i]))
if err != nil {
return err
}
time.Sleep(startupTimeout) // TODO wait until cmd complete
}
return nil return nil
} }

View File

@ -23,7 +23,7 @@ type BasicInteractiveShell struct {
func (s *BasicInteractiveShell) init() error { func (s *BasicInteractiveShell) init() error {
cmd := exec.Command("sh", "-c", *s.item.initScript) cmd := exec.Command("sh", "-c", s.item.initScripts[0])
enrichEnvVariables(cmd, s.variables) enrichEnvVariables(cmd, s.variables)
cmd.Wait() cmd.Wait()
@ -65,12 +65,20 @@ func (s *BasicInteractiveShell) init() error {
return err return err
} }
for i := 1; i < len(s.item.initScripts); i++ {
_, err := io.WriteString(s.stdin, fmt.Sprintf(" %s\n", s.item.initScripts[i]))
if err != nil {
return err
}
time.Sleep(startupTimeout) // TODO wait until cmd complete
}
return nil return nil
} }
func (s *BasicInteractiveShell) execute() (string, error) { func (s *BasicInteractiveShell) execute() (string, error) {
_, err := io.WriteString(s.stdin, s.item.sampleScript+"\n") _, err := io.WriteString(s.stdin, fmt.Sprintf(" %s\n", s.item.sampleScript))
if err != nil { if err != nil {
s.errCount++ s.errCount++
if s.errCount > errorThreshold { if s.errCount > errorThreshold {

View File

@ -12,8 +12,8 @@ const errorThreshold = 10
type Item struct { type Item struct {
label string label string
initScripts []string
sampleScript string sampleScript string
initScript *string
transformScript *string transformScript *string
color *ui.Color color *ui.Color
rateMs int rateMs int
@ -30,7 +30,7 @@ func NewItems(cfgs []config.Item, rateMs int) []*Item {
item := &Item{ item := &Item{
label: *i.Label, label: *i.Label,
sampleScript: *i.SampleScript, sampleScript: *i.SampleScript,
initScript: i.InitScript, initScripts: getInitScripts(i),
transformScript: i.TransformScript, transformScript: i.TransformScript,
color: i.Color, color: i.Color,
rateMs: rateMs, rateMs: rateMs,
@ -43,7 +43,7 @@ func NewItems(cfgs []config.Item, rateMs int) []*Item {
func (i *Item) nextValue(variables []string) (string, error) { func (i *Item) nextValue(variables []string) (string, error) {
if i.initScript != nil && i.basicShell == nil && i.ptyShell == nil { if len(i.initScripts) > 0 && i.basicShell == nil && i.ptyShell == nil {
err := i.initInteractiveShell(variables) err := i.initInteractiveShell(variables)
if err != nil { if err != nil {
return "", err return "", err
@ -99,3 +99,13 @@ func enrichEnvVariables(cmd *exec.Cmd, variables []string) {
cmd.Env = append(cmd.Env, variable) cmd.Env = append(cmd.Env, variable)
} }
} }
func getInitScripts(item config.Item) []string {
if item.MultiStepInitScript != nil {
return *item.MultiStepInitScript
} else if item.InitScript != nil {
return []string{*item.InitScript}
} else {
return []string{}
}
}