From 83f8d042254338c114da73655226af03722d3a77 Mon Sep 17 00:00:00 2001 From: sqshq Date: Sun, 23 Jun 2019 00:08:24 -0400 Subject: [PATCH] added interactive shell multistep-init --- README.md | 6 ++++++ config/component.go | 13 +++++++------ config/validator.go | 26 ++++++++++++++++++++++++-- data/int_pty.go | 12 ++++++++++-- data/int_shell.go | 12 ++++++++++-- data/item.go | 16 +++++++++++++--- 6 files changed, 70 insertions(+), 15 deletions(-) diff --git a/README.md b/README.md index f6883fc..89e3aad 100644 --- a/README.md +++ b/README.md @@ -388,7 +388,11 @@ textboxes: ### JMX + +
Java application uptime + Prerequisite: download [jmxterm jar file](https://docs.cyclopsgroup.org/jmxterm) + ```yml textboxes: - title: Java application uptime @@ -399,3 +403,5 @@ textboxes: sample: get Uptime transform: echo $sample | tr -dc '0-9' | awk '{printf "%.1f min", $1/1000/60}' ``` + +
\ No newline at end of file diff --git a/config/component.go b/config/component.go index 6215443..42897bb 100644 --- a/config/component.go +++ b/config/component.go @@ -103,12 +103,13 @@ type LegendConfig struct { } type Item struct { - Label *string `yaml:"label,omitempty"` - Color *ui.Color `yaml:"color,omitempty"` - Pty *bool `yaml:"pty,omitempty"` - InitScript *string `yaml:"init,omitempty"` - SampleScript *string `yaml:"sample"` - TransformScript *string `yaml:"transform,omitempty"` + Label *string `yaml:"label,omitempty"` + Color *ui.Color `yaml:"color,omitempty"` + Pty *bool `yaml:"pty,omitempty"` + InitScript *string `yaml:"init,omitempty"` + MultiStepInitScript *[]string `yaml:"multistep-init,omitempty"` + SampleScript *string `yaml:"sample"` + TransformScript *string `yaml:"transform,omitempty"` } type Location struct { diff --git a/config/validator.go b/config/validator.go index 4f31b38..5e775de 100644 --- a/config/validator.go +++ b/config/validator.go @@ -12,31 +12,53 @@ func (c *Config) validate() { for _, c := range c.RunCharts { components = append(components, c.ComponentConfig) validateLabelsUniqueness(c.Title, c.Items) + validateItemsScripts(c.Title, c.Items) } for _, c := range c.BarCharts { components = append(components, c.ComponentConfig) validateLabelsUniqueness(c.Title, c.Items) + validateItemsScripts(c.Title, c.Items) } for _, c := range c.SparkLines { components = append(components, c.ComponentConfig) + validateItemScripts(c.Title, c.Item) } for _, c := range c.Gauges { 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 { components = append(components, c.ComponentConfig) + validateItemScripts(c.Title, c.Item) } for _, c := range c.TextBoxes { components = append(components, c.ComponentConfig) + validateItemScripts(c.Title, c.Item) } 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) { labels := make(map[string]bool) - for _, c := range items { - label := *c.Label + for _, i := range items { + label := *i.Label if _, contains := labels[label]; contains { console.Exit(fmt.Sprintf("Config validation error: item labels should be unique. Please rename '%s' in '%s'", label, title)) } diff --git a/data/int_pty.go b/data/int_pty.go index 644cf10..5585c3f 100644 --- a/data/int_pty.go +++ b/data/int_pty.go @@ -13,7 +13,7 @@ import ( ) const ( - startupTimeout = 100 * time.Millisecond + startupTimeout = 200 * time.Millisecond minAwaitTimeout = 100 * time.Millisecond maxAwaitTimeout = 1 * time.Second ) @@ -33,7 +33,7 @@ type PtyInteractiveShell struct { 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) file, err := pty.Start(cmd) @@ -61,6 +61,14 @@ func (s *PtyInteractiveShell) init() error { 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 } diff --git a/data/int_shell.go b/data/int_shell.go index ce539f8..86d934c 100644 --- a/data/int_shell.go +++ b/data/int_shell.go @@ -23,7 +23,7 @@ type BasicInteractiveShell struct { 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) cmd.Wait() @@ -65,12 +65,20 @@ func (s *BasicInteractiveShell) init() error { 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 } 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 { s.errCount++ if s.errCount > errorThreshold { diff --git a/data/item.go b/data/item.go index 25f1e32..d692cf0 100644 --- a/data/item.go +++ b/data/item.go @@ -12,8 +12,8 @@ const errorThreshold = 10 type Item struct { label string + initScripts []string sampleScript string - initScript *string transformScript *string color *ui.Color rateMs int @@ -30,7 +30,7 @@ func NewItems(cfgs []config.Item, rateMs int) []*Item { item := &Item{ label: *i.Label, sampleScript: *i.SampleScript, - initScript: i.InitScript, + initScripts: getInitScripts(i), transformScript: i.TransformScript, color: i.Color, rateMs: rateMs, @@ -43,7 +43,7 @@ func NewItems(cfgs []config.Item, rateMs int) []*Item { 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) if err != nil { return "", err @@ -99,3 +99,13 @@ func enrichEnvVariables(cmd *exec.Cmd, variables []string) { 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{} + } +}