Skip to content

Commit

Permalink
tridentctl plugin support (#1697)
Browse files Browse the repository at this point in the history
  • Loading branch information
wgerlach authored Aug 20, 2024
1 parent e4d93bd commit cb5cdb6
Showing 1 changed file with 95 additions and 0 deletions.
95 changes: 95 additions & 0 deletions cli/cmd/plugins.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,95 @@
package cmd

import (
"fmt"
"log"
"os"
"os/exec"
"path/filepath"
"strings"

"github.com/spf13/cobra"
)

const (
tridentctlPrefix = "tridentctl-"
execMask = 0o111
pluginPathEnvVar = "TRIDENTCTL_PLUGIN_PATH"
)

func init() {
// search PATH for all binaries starting with "tridentctl-"
binaries := findBinaries(tridentctlPrefix)

plugins := make([]*cobra.Command, 0, len(binaries))
for _, binary := range binaries {
pluginName := strings.TrimPrefix(filepath.Base(binary), tridentctlPrefix)
pluginCmd := &cobra.Command{
Use: pluginName,
Short: "Run the " + pluginName + " plugin",
GroupID: "plugins",
DisableFlagParsing: true,
Run: func(cmd *cobra.Command, args []string) {
pluginCommand := binary

os.Setenv("TRIDENTCTL_PLUGIN_INVOCATION", "true")

execCmd := exec.Command(pluginCommand, args...)
execCmd.Stdin = os.Stdin
execCmd.Stdout = os.Stdout
execCmd.Stderr = os.Stderr

err := execCmd.Run()
if err != nil {
fmt.Printf("Error executing plugin command: %v\n", err)
}
},
}
plugins = append(plugins, pluginCmd)

}

if len(plugins) == 0 {
return
}

pluginGroup := cobra.Group{
ID: "plugins",
Title: "Plugins",
}

RootCmd.AddGroup(&pluginGroup)
for _, pluginCmd := range plugins {
RootCmd.AddCommand(pluginCmd)
}
}

func findBinaries(prefix string) []string {
var binaries []string
path := os.Getenv(pluginPathEnvVar)
if path == "" {
path = os.Getenv("PATH")
}

for _, dir := range strings.Split(path, ":") {
files, err := filepath.Glob(filepath.Join(dir, prefix+"*"))
if err != nil {
log.Println(err)
continue
}
for _, file := range files {
if isExecutable(file) {
binaries = append(binaries, file)
}
}
}
return binaries
}

func isExecutable(file string) bool {
info, err := os.Stat(file)
if err != nil {
return false
}
return info.Mode().IsRegular() && info.Mode()&execMask != 0
}

0 comments on commit cb5cdb6

Please sign in to comment.