Skip to content

Commit

Permalink
Capture run time of plugins; Allow overriding default log values via env
Browse files Browse the repository at this point in the history
  • Loading branch information
Abhijith Dadaga Arkakeerthy committed Nov 1, 2024
1 parent 7b87f98 commit f8b1e66
Show file tree
Hide file tree
Showing 13 changed files with 286 additions and 177 deletions.
56 changes: 43 additions & 13 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -399,19 +399,49 @@ $
```
```yaml
$ cat a.yaml
type: preupgrade
# cat a.yaml
name: preupgrade
description: ""
requiredby: []
requires: []
execstart: ""
plugins:
- description: Checking for "D" settings...
name: D/d.preupgrade
execstart: $PM_LIBRARY/D/preupgrade.sh
requiredby:
- A/a.preupgrade
requires: []
status: Failed
stdouterr: "Running preupgrade.sh (path: sample/library//D/preupgrade.sh) with
status(1)...\nDisplaying Plugin Manager (PM) Config file path: \nFail(1)\n"
- name: A/a.preupgrade
description: Checking for "A" settings
requiredby: []
requires:
- D/d.preupgrade
execstart: /bin/echo "Checking A..."
plugins: []
library: ""
runtime:
starttime: 2024-10-28T18:21:17.289968946-05:00
endtime: 2024-10-28T18:21:17.337773824-05:00
duration: 47.804888ms
status: Skipped
stdouterr: []
- name: D/d.preupgrade
description: Checking for "D" settings...
requiredby: []
requires: []
execstart: $PM_LIBRARY/D/preupgrade.sh
plugins: []
library: ""
runtime:
starttime: 2024-10-28T18:21:17.220368224-05:00
endtime: 2024-10-28T18:21:17.289945583-05:00
duration: 69.577293ms
status: Failed
stdouterr:
- 'Running preupgrade.sh (path: sample/library//D/preupgrade.sh) with status(1)...'
- 'Displaying Plugin Manager (PM) Config file path: '
- Fail(1)
library: ""
runtime:
starttime: 2024-10-28T18:21:17.185365352-05:00
endtime: 2024-10-28T18:21:17.337805574-05:00
duration: 152.440222ms
status: Failed
stdouterr: 'Running preupgrade plugins: Failed'
$
stdouterr:
- 'Running preupgrade plugins: Failed'
```
29 changes: 11 additions & 18 deletions cmd/pm/integ_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ import (
"testing"

"github.com/VeritasOS/plugin-manager/config"
"github.com/VeritasOS/plugin-manager/types/status"
logger "github.com/VeritasOS/plugin-manager/utils/log"

yaml "gopkg.in/yaml.v3"
Expand All @@ -30,14 +31,6 @@ type Config struct {
}
}

// Status of plugin execution used for displaying to user on console.
const (
dStatusFail = "Failed"
dStatusOk = "Succeeded"
dStatusSkip = "Skipped"
dStatusStart = "Starting"
)

func saveConfig(newConfig Config, configFile string) error {
logger.Info.Println("Entering saveConfig")
defer logger.Info.Println("Exiting saveConfig")
Expand Down Expand Up @@ -144,11 +137,11 @@ func integTest(t *testing.T, pmBinary, tDir string) {
pluginType: "preupgrade",
},
want: []string{
"Checking for \"D\" settings...: " + dStatusStart,
"Checking for \"D\" settings...: " + dStatusOk,
"Checking for \"A\" settings: " + dStatusStart,
"Checking for \"A\" settings: " + dStatusOk,
"Running preupgrade plugins: " + dStatusOk,
"Checking for \"D\" settings...: " + status.Start,
"Checking for \"D\" settings...: " + status.Ok,
"Checking for \"A\" settings: " + status.Start,
"Checking for \"A\" settings: " + status.Ok,
"Running preupgrade plugins: " + status.Ok,
},
wantErr: false,
},
Expand All @@ -159,11 +152,11 @@ func integTest(t *testing.T, pmBinary, tDir string) {
testPluginExitStatus: 1,
},
want: []string{
"Checking for \"D\" settings...: " + dStatusStart,
"Checking for \"D\" settings...: " + dStatusFail,
"Checking for \"A\" settings: " + dStatusStart,
"Checking for \"A\" settings: " + dStatusSkip,
"Running preupgrade plugins: " + dStatusFail,
"Checking for \"D\" settings...: " + status.Start,
"Checking for \"D\" settings...: " + status.Fail,
"Checking for \"A\" settings: " + status.Start,
"Checking for \"A\" settings: " + status.Skip,
"Running preupgrade plugins: " + status.Fail,
"",
},
wantErr: true,
Expand Down
10 changes: 10 additions & 0 deletions config/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -92,6 +92,16 @@ func Load() error {
logger.Debug.Printf("config file: %s", myConfigFile)
var err error
myConfig, err = readConfigFile(myConfigFile)
// Set default values when it's not specified in config file.
if myConfig.PluginManager.LogDir == "" {
myConfig.PluginManager.LogDir = logger.DefaultLogDir
}
if myConfig.PluginManager.LogFile == "" {
myConfig.PluginManager.LogFile = logger.DefaultLogFile
}
if myConfig.PluginManager.LogLevel == "" {
myConfig.PluginManager.LogLevel = logger.DefaultLogLevel
}
logger.Debug.Printf("Plugin Manager Config: %+v", myConfig)
return err
}
Expand Down
13 changes: 12 additions & 1 deletion config/config_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -85,7 +85,18 @@ func Test_Load(t *testing.T) {
args: args{
EnvConfFile: "non-existing/pm.config.yaml",
},
want: Config{},
want: Config{
PluginManager: struct {
Library string "yaml:\"library\""
LogDir string "yaml:\"log dir\""
LogFile string "yaml:\"log file\""
LogLevel string "yaml:\"log level\""
}{
LogDir: logger.DefaultLogDir,
LogFile: logger.DefaultLogFile,
LogLevel: logger.DefaultLogLevel,
},
},
},
}

Expand Down
68 changes: 33 additions & 35 deletions graph.go → graph/graph.go
Original file line number Diff line number Diff line change
@@ -1,18 +1,19 @@
// Copyright (c) 2024 Veritas Technologies LLC. All rights reserved. IP63-2828-7171-04-15-9

// Package pm graph is used for generating the graph image.
package pm
// Package graph is used for generating the graph image.
package graph

import (
"os"
"path/filepath"
"sort"
"strconv"
"strings"
"sync"
"time"

"github.com/VeritasOS/plugin-manager/config"
"github.com/VeritasOS/plugin-manager/types"
"github.com/VeritasOS/plugin-manager/types/status"
logger "github.com/VeritasOS/plugin-manager/utils/log"
osutils "github.com/VeritasOS/plugin-manager/utils/os"
)
Expand All @@ -32,7 +33,14 @@ type graph struct {
var g graph
var dotCmdPresent = true

func initGraphConfig(imgNamePrefix string) {
// Plugin is of type types.Plugin
type Plugin = types.Plugin

// Plugins is of type types.Plugins
type Plugins = types.Plugins

// InitGraphConfig initliazes output file names.
func InitGraphConfig(imgNamePrefix string) {
// Initialization should be done only once.
if g.fileNoExt == "" {
// Remove imgNamePrefix if it's end with ".log"
Expand All @@ -41,39 +49,28 @@ func initGraphConfig(imgNamePrefix string) {
}
}

func getImagePath() string {
// GetImagePath gets the path of the image file.
func GetImagePath() string {
return config.GetPMLogDir() + g.fileNoExt + ".svg"
}

func getDotFilePath() string {
// GetDotFilePath gets the path of the dot file.
func GetDotFilePath() string {
return config.GetPMLogDir() + g.fileNoExt + ".dot"
}

// initGraph initliazes the graph data structure and invokes generateGraph.
func initGraph(pluginType string, pluginsInfo Plugins) error {
initGraphConfig(config.GetPMLogFile())
// InitGraph initliazes the graph data structure and invokes generateGraph.
func InitGraph(pluginType string, pluginsInfo Plugins) error {
InitGraphConfig(config.GetPMLogFile())

// DOT guide: https://graphviz.gitlab.io/_pages/pdf/dotguide.pdf

// INFO: Sort the plugins so that list of dependencies generated
// (used by documentation) doesn't change.
// NOTE: If not sorted, then even without addition of any new plugin,
// the dependency file generated will keep changing and appears in
// git staged list.
orderedPluginsList := []string{}
pluginsIdx := map[string]int{}
for pIdx, p := range pluginsInfo {
orderedPluginsList = append(orderedPluginsList, p.Name)
pluginsIdx[p.Name] = pIdx
}
sort.Strings(orderedPluginsList)
for _, pName := range orderedPluginsList {
pIdx := pluginsIdx[pName]
pFileString := "\"" + pName + "\""
pFileString := "\"" + p.Name + "\""
absLogPath, _ := filepath.Abs(config.GetPMLogDir())
absLibraryPath, _ := filepath.Abs(config.GetPluginsLibrary())
relPath, _ := filepath.Rel(absLogPath, absLibraryPath)
pURL := "\"" + filepath.FromSlash(relPath+string(os.PathSeparator)+pName) + "\""
pURL := "\"" + filepath.FromSlash(relPath+string(os.PathSeparator)+p.Name) + "\""
rows := []string{}
rowsInterface, ok := g.subgraph.Load(pluginType)
if ok {
Expand All @@ -82,10 +79,10 @@ func initGraph(pluginType string, pluginsInfo Plugins) error {
rows = append(rows, pFileString+" [label=\""+
strings.Replace(pluginsInfo[pIdx].Description, "\"", `\"`, -1)+
"\",style=filled,fillcolor=lightgrey,URL="+pURL+"]")
rows = append(rows, "\""+pName+"\"")
rows = append(rows, "\""+p.Name+"\"")
rbyLen := len(pluginsInfo[pIdx].RequiredBy)
if rbyLen != 0 {
graphRow := "\"" + pName + "\" -> "
graphRow := "\"" + p.Name + "\" -> "
for rby := range pluginsInfo[pIdx].RequiredBy {
graphRow += "\"" + pluginsInfo[pIdx].RequiredBy[rby] + "\""
if rby != rbyLen-1 {
Expand All @@ -103,7 +100,7 @@ func initGraph(pluginType string, pluginsInfo Plugins) error {
graphRow += ", "
}
}
graphRow += " -> \"" + pName + "\""
graphRow += " -> \"" + p.Name + "\""
rows = append(rows, graphRow)
}
g.subgraph.Store(pluginType, rows)
Expand All @@ -115,8 +112,8 @@ func initGraph(pluginType string, pluginsInfo Plugins) error {
// generateGraph generates an input `.dot` file based on the fileNoExt name,
// and then generates an `.svg` image output file as fileNoExt.svg.
func generateGraph() error {
dotFile := getDotFilePath()
svgFile := getImagePath()
dotFile := GetDotFilePath()
svgFile := GetImagePath()

fhDigraph, openerr := osutils.OsOpenFile(dotFile, os.O_RDWR|os.O_CREATE|os.O_TRUNC, 0666)
if openerr != nil {
Expand Down Expand Up @@ -168,20 +165,21 @@ func generateGraph() error {
}

// getStatusColor returns the color for a given result status.
func getStatusColor(status string) string {
func getStatusColor(myStatus string) string {
// Node color
ncolor := "blue" // dStatusStart by default
if status == dStatusFail {
ncolor := "blue" // status.Start by default
if myStatus == status.Fail {
ncolor = "red"
} else if status == dStatusOk {
} else if myStatus == status.Ok {
ncolor = "green"
} else if status == dStatusSkip {
} else if myStatus == status.Skip {
ncolor = "yellow"
}
return ncolor
}

func updateGraph(subgraphName, plugin, status, url string) error {
// UpdateGraph updates the plugin node with the status and url.
func UpdateGraph(subgraphName, plugin, status, url string) error {
ncolor := getStatusColor(status)
gContents := []string{}
gContentsInterface, ok := g.subgraph.Load(subgraphName)
Expand Down
24 changes: 13 additions & 11 deletions graph_test.go → graph/graph_test.go
Original file line number Diff line number Diff line change
@@ -1,11 +1,13 @@
// Copyright (c) 2024 Veritas Technologies LLC. All rights reserved. IP63-2828-7171-04-15-9
package pm
package graph

import (
"os"
"reflect"
"sort"
"testing"

"github.com/VeritasOS/plugin-manager/types/status"
)

func Test_getStatusColor(t *testing.T) {
Expand All @@ -24,22 +26,22 @@ func Test_getStatusColor(t *testing.T) {
}{
{
name: "Start",
args: args{status: dStatusStart},
args: args{status: status.Start},
want: "blue",
},
{
name: "Ok/Pass",
args: args{status: dStatusOk},
args: args{status: status.Ok},
want: "green",
},
{
name: "Fail",
args: args{status: dStatusFail},
args: args{status: status.Fail},
want: "red",
},
{
name: "Skip",
args: args{status: dStatusSkip},
args: args{status: status.Skip},
want: "yellow",
},
}
Expand All @@ -52,7 +54,7 @@ func Test_getStatusColor(t *testing.T) {
}
}

func Test_updateGraph(t *testing.T) {
func Test_UpdateGraph(t *testing.T) {
if os.Getenv("INTEGRATION_TEST") == "RUNNING" {
t.Skip("Not applicable while running integration tests.")
return
Expand All @@ -77,7 +79,7 @@ func Test_updateGraph(t *testing.T) {
name: "Append a row",
args: args{
plugin: "A/a.test",
status: dStatusOk,
status: status.Ok,
url: "url/A/a.test",
},
wantErr: false,
Expand All @@ -88,10 +90,10 @@ func Test_updateGraph(t *testing.T) {
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
if err := updateGraph(getPluginType(tt.args.plugin), tt.args.plugin, tt.args.status, tt.args.url); (err != nil) != tt.wantErr {
if err := UpdateGraph("test", tt.args.plugin, tt.args.status, tt.args.url); (err != nil) != tt.wantErr {
t.Errorf("updateGraph() error = %v, wantErr %v", err, tt.wantErr)
}
rowsInterface, _ := g.subgraph.Load(getPluginType(tt.args.plugin))
rowsInterface, _ := g.subgraph.Load("test")
rows := rowsInterface.([]string)
if !reflect.DeepEqual(rows, tt.wants.rows) {
t.Errorf("updateGraph() g.rows = %v, wants.rows %v", rows, tt.wants.rows)
Expand All @@ -100,7 +102,7 @@ func Test_updateGraph(t *testing.T) {
}
}

func Test_initGraph(t *testing.T) {
func Test_InitGraph(t *testing.T) {
type args struct {
pluginType string
pluginsInfo Plugins
Expand Down Expand Up @@ -200,7 +202,7 @@ func Test_initGraph(t *testing.T) {

for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
if err := initGraph(tt.args.pluginType, tt.args.pluginsInfo); (err != nil) != tt.wantErr {
if err := InitGraph(tt.args.pluginType, tt.args.pluginsInfo); (err != nil) != tt.wantErr {
t.Errorf("initGraph() error = %v, wantErr %v", err, tt.wantErr)
}
rowsI, _ := g.subgraph.Load(tt.args.pluginType)
Expand Down
Loading

0 comments on commit f8b1e66

Please sign in to comment.