diff --git a/cmd/root.go b/cmd/root.go index 8bf404de..e80156a0 100644 --- a/cmd/root.go +++ b/cmd/root.go @@ -60,6 +60,17 @@ k3d is a wrapper CLI that helps you to easily create k3s clusters inside docker. Nodes of a k3d cluster are docker containers running a k3s image. All Nodes of a k3d cluster are part of the same docker network.`, Run: func(cmd *cobra.Command, args []string) { + if len(args) > 1 { + parts := args[1:] + + // Check if it's a built-in command, else try to execute it as a plugin + if _, _, err := cmd.Find(parts); err != nil { + if err := util.HandlePlugin(parts); err != nil { + log.Errorf("Failed to execute plugin '%+v'", parts) + log.Fatalln(err) + } + } + } if flags.version { printVersion() } else { diff --git a/cmd/util/plugins.go b/cmd/util/plugins.go new file mode 100644 index 00000000..b32bab9c --- /dev/null +++ b/cmd/util/plugins.go @@ -0,0 +1,76 @@ +/* +Copyright © 2020 The k3d Author(s) + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. +*/ +package util + +import ( + "fmt" + "os" + "os/exec" + "strings" +) + +func HandlePlugin(args []string) error { + argsPrefix := []string{} + + for _, arg := range args { + if strings.HasPrefix(arg, "-") { + continue // drop flags + } + argsPrefix = append(argsPrefix, strings.ReplaceAll(arg, "-", "_")) // plugin executables assumed to have underscores + } + + execPath := "" + + for len(argsPrefix) > 0 { + path, found := FindPlugin(strings.Join(argsPrefix, "-")) + + if !found { + argsPrefix = argsPrefix[:len(argsPrefix)-1] // drop last element + continue + } + + execPath = path + break + } + + if execPath == "" { + return nil + } + + return ExecPlugin(execPath, args[len(argsPrefix):], os.Environ()) + +} + +// FindPlugin tries to find the plugin executable on the filesystem +func FindPlugin(name string) (string, bool) { + path, err := exec.LookPath(fmt.Sprintf("%s-%s", k3d.DefaultObjectNamePrefix, name)) + if err == nil && len(path) > 0 { + return path, true + } + return "", false +} + +// ExecPlugin executes a found plugin +func ExecPlugin(path string, args []string, env []string) error { + + return nil +}