Various typo fixes in documents Various grammar and language changes for clarification Change-Id: I111bf45c90405a26d09a5254733a055c78b47407
6.6 KiB
Plugin Support
Table of Contents
Our requirements for airshipctl contain two very conflicting concepts. One,
we'd like to assert that airshipctl is a statically linked executable, such
that it can be easily distributed. Two, we'd like to have plugin support. These
requirements can't coincide within the same project under the standard
definition of a plugin. Our solution is to provide a more refined definition of
what a plugin actually is.
Compile-In Plugins
In order to support plugins to an independent binary file, we use the concept
of "compile-in plugins". A "compile-in plugin" is an add-on that is built into
the main application at compile time, as opposed to runtime. This means that
while airshipctl is a standalone application, it also acts as a sort of
library. In fact, taking a deeper look at airshipctl reveals that the base
application is incredibly simple. At its core, airshipctl provides exactly 2
commands: version and help. Take a look at the following snippet to see
what this looks like:
package main
import (
"os"
"opendev.org/airship/airshipctl/cmd"
)
func main() {
rootCmd, _, err := cmd.NewRootCmd(os.Stdout)
if err != nil {
panic(err)
}
rootCmd.Execute()
}
Compiling and running the above gives the following output:
$ ./airshipctl
airshipctl is a unified entrypoint to various airship components
Usage:
airshipctl [command]
Available Commands:
bootstrap Bootstrap ephemeral Kubernetes cluster
completion Generate autocompletions script for the specified shell (bash or zsh)
config Modify airshipctl config files
document manages deployment documents
help Help about any command
kubectl kubectl controls the Kubernetes cluster manager
version Show the version number of airshipctl
Flags:
--airshipconf string Path to file for airshipctl configuration. (default "$HOME/.airship/config")
--debug enable verbose output
-h, --help help for airshipctl
--kubeconfig string Path to kubeconfig associated with airshipctl configuration. (default "$HOME/.airship/kubeconfig")
Additional help topics:
airshipctl cluster Control Kubernetes cluster
Use "airshipctl [command] --help" for more information about a command.
Every other command is treated as a plugin. Changing main to the following
adds the default commands, or "plugins", to the airshipctl tool:
func main() {
rootCmd, settings, err := cmd.NewRootCmd(os.Stdout)
if err != nil {
panic(err)
}
cmd.AddDefaultAirshipCTLCommands(rootCmd, settings)
rootCmd.Execute()
}
Compiling and running now provides the following commands:
Available Commands:
bootstrap Bootstrap ephemeral Kubernetes cluster
completion Generate autocompletions script for the specified shell (bash or zsh)
config Modify airshipctl config files
document manages deployment documents
help Help about any command
kubectl kubectl controls the Kubernetes cluster manager
version Show the version number of airshipctl
------ more commands TBD ------
Downloading and building the main airshipctl project will default to
providing the builtin commands (such as bootstrap), much like the above. A
plugin author wishing to use airshipctl can then use the rootCmd as the
first of a series of building blocks. The following demonstrates the addition
of a new command, hello:
package main
import (
"fmt"
"os"
"opendev.org/airship/airshipctl/cmd"
"github.com/spf13/cobra"
)
func main() {
rootCmd, settings, err := cmd.NewRootCmd(os.Stdout)
if err != nil {
panic(err)
}
cmd.AddDefaultAirshipCTLCommands(rootCmd, settings)
helloCmd := &cobra.Command{
Use: "hello",
Short: "Prints a friendly message to the screen",
Run: func(cmd *cobra.Command, args []string) {
fmt.Println("Hello World!")
},
}
rootCmd.AddCommand(helloCmd)
rootCmd.Execute()
}
Fine Tuning a Build
There are a couple of ways in which a plugin author can fine tune their version
of airshipctl. These manifest as an ability to pick and choose various
plugins (including the defaults), and capabilities for accessing the same
settings as other airshipctl commands.
Command Selection
In the previous section, we introduced the AddDefaultAirshipCTLCommands
function. That command will simply dump all of the builtin commands onto the
root. But a plugin author might not need all of the builtins. To deal with
this, the author can pick and choose specific commands to add to their
airshipctl, much like the following:
package main
import (
"os"
"opendev.org/airship/airshipctl/cmd"
"opendev.org/airship/airshipctl/cmd/bootstrap"
)
func main() {
rootCmd, settings, err := cmd.NewRootCmd(os.Stdout)
if err != nil {
panic(err)
}
rootCmd.AddCommand(bootstrap.NewBootstrapCommand(settings))
rootCmd.Execute()
}
This variant of airshipctl will have the bootstrap command, but will not
have any other builtins.
This can be particularly useful if a plugin author desires to "override" a
specific functionality provided by a builtin command. For example, you might
write your own bootstrap command and use it in place of the builtin.
Accessing airshipctl settings
The airshipctl will contain several settings which may be useful to a plugin
author. The following snippet demonstrates how to use the debug flag,
provided by airshipctl, as well as a custom alt-message flag, provided by
the plugin.
package main
import (
"fmt"
"os"
"opendev.org/airship/airshipctl/cmd"
"opendev.org/airship/airshipctl/pkg/environment"
"github.com/spf13/cobra"
)
type Settings struct {
*environment.AirshipCTLSettings
AltMessage bool
}
func main() {
rootCmd, rootSettings, err := cmd.NewRootCmd(os.Stdout)
if err != nil {
panic(err)
}
settings := Settings{AirshipCTLSettings: rootSettings}
helloCmd := &cobra.Command{
Use: "hello",
Short: "Prints a friendly message to the screen",
Run: func(cmd *cobra.Command, args []string) {
if settings.Debug {
fmt.Println("DEBUG: a debugging message")
}
if settings.AltMessage {
fmt.Println("Goodbye World!")
} else {
fmt.Println("Hello World!")
}
},
}
helloCmd.PersistentFlags().BoolVar(&settings.AltMessage, "alt-message", false, "display an alternate message")
rootCmd.AddCommand(helloCmd)
rootCmd.Execute()
}
The AirshipCTLSettings object can be found
here. Future documentation TBD.