什么是cobra
Go语言中,我们可以使用cobra很方便的进行命令行工具的开发,Cobra提供了自己的程序,该程序将创建您的应用程序并添加所需的任何命令。cobra项目地址:https://github.com/spf13/cobra
Cobra广泛应用在CLI(命令行界面)
CLI根据软件工程的基本原理进行工作,接受输入,对其进行处理并给出输出。目前很多云原生工具都使用cobra,生成好用的二进制包,例如kuberneteus,etcd,istio,helm,kubeadm 等等, 目前使用cobra的项目:https://github.com/spf13/cobra/blob/v1.1.3/projects_using_cobra.md
Cobra命令、参数和标识符
Commands 表示执行动作
Args 就是执行参数
Flags 是这些动作的标识符
例如:kubeadm --help 可以看到可以执行的Commands 和Flags
Usage:
kubeadm [command]
Available Commands:
alpha Kubeadm experimental sub-commands
completion Output shell completion code for the specified shell (bash or zsh).
config Manage configuration for a kubeadm cluster persisted in a ConfigMap in the cluster.
help Help about any command
init Run this command in order to set up the Kubernetes control plane.
join Run this on any machine you wish to join an existing cluster
reset Run this to revert any changes made to this host by 'kubeadm init' or 'kubeadm join'.
token Manage bootstrap tokens.
upgrade Upgrade your cluster smoothly to a newer version with this command.
version Print the version of kubeadm
Flags:
-h, --help help for kubeadm
--log-file string If non-empty, use this log file
--rootfs string [EXPERIMENTAL] The path to the 'real' host root filesystem.
--skip-headers If true, avoid header prefixes in the log messages
-v, --v Level number for the log level verbosity
Use "kubeadm [command] --help" for more information about a command.
如果Commands是token,执行:kubeadm token --help,我们看到了kubeadm token增加了执行参数,以及执行的动作,还有动作的flags
Usage:
kubeadm token [flags]
kubeadm token [command]
Available Commands:
create Create bootstrap tokens on the server.
delete Delete bootstrap tokens on the server.
generate Generate and print a bootstrap token, but do not create it on the server.
list List bootstrap tokens on the server.
Flags:
--dry-run Whether to enable dry-run mode or not
-h, --help help for token
--kubeconfig string The kubeconfig file to use when talking to the cluster. If the flag is not set, a set of standard locations can be searched for an existing kubeconfig file. (default "/etc/kubernetes/admin.conf")
Global Flags:
--log-file string If non-empty, use this log file
--rootfs string [EXPERIMENTAL] The path to the 'real' host root filesystem.
--skip-headers If true, avoid header prefixes in the log messages
-v, --v Level number for the log level verbosity
Use "kubeadm token [command] --help" for more information about a command.
安装cobra
本机启动docker后,运行容器并进入,设置代理,下载cobra包,现在默认最高版本是1.3.0
docker run -itd --rm --name golang golang:1.16.3-alpine3.13
docker exec -it golang sh
export GOPROXY=https://goproxy.cn
go get -u -v github.com/spf13/cobra/cobra
go get会调用两个命令,第一个是下载git clone源码包,第二步是使用go install来编译,并放到gopath的/pkg目录下,我们来看看有没有这个二进制文件?
/go # go env | grep -i gopath
GOPATH="/go"
/go # ls -l /go/bin/cobra
-rwxr-xr-x 1 root root 8472493 Jan 10 13:33 /go/bin/cobra
/go # date
Mon Jan 10 13:38:35 UTC 2022
/go # which cobra
/go/bin/cobra
/go # find / -name cobra
/go/bin/cobra
/go/pkg/mod/cache/download/github.com/spf13/cobra
/go/pkg/mod/github.com/spf13/cobra@v1.3.0/cobra
/go # cobra --help
Cobra is a CLI library for Go that empowers applications.
This application is a tool to generate the needed files
to quickly create a Cobra application.
Usage:
cobra [command]
Available Commands:
add Add a command to a Cobra Application
completion Generate the autocompletion script for the specified shell
help Help about any command
init Initialize a Cobra Application
Flags:
-a, --author string author name for copyright attribution (default "YOUR NAME")
--config string config file (default is $HOME/.cobra.yaml)
-h, --help help for cobra
-l, --license string name of license for the project
--viper use Viper for configuration
Use "cobra [command] --help" for more information about a command.
cobra安装成功后,先使用使用cobra init 命令来初始化 CLI 应用的脚手架,注意:老版本的cobra库需要--pkg-name参数来进行初始化模块名称,例如:cobra init --pkg-name Testapp
/go # mkdir Cobra && cd Cobra
/go/Cobra # go mod init Testapp
go: creating new go.mod: module Testapp
/go/Cobra # cobra init
Your Cobra application is ready at
/go/Cobra
/go/Cobra # ls -l
total 88
-rw-r--r-- 1 root root 0 Jan 10 13:44 LICENSE
drwxr-x--x 2 root root 4096 Jan 10 13:44 cmd
-rw-r--r-- 1 root root 75 Jan 10 13:44 go.mod
-rw-r--r-- 1 root root 75705 Jan 10 13:44 go.sum
-rw-r--r-- 1 root root 118 Jan 10 13:44 main.go
查看cobra代码和执行流程
main.go是CLI应用的入口,在main.go里调用了cmd/root.go下面的Execute函数:
/go/Cobra # cat main.go
/*
Copyright © 2022 NAME HERE <EMAIL ADDRESS>
*/
package main
import "Testapp/cmd"
import "fmt"
func main() {
fmt.Println("exec in main") //这行是我单独增加的,看执行顺序
cmd.Execute()
}
然后进入cmd/root.go依次使用的函数执行顺序是:
1. init最先执行,init 函数是 Golang 中初始化包的时候第一个调用的函数
2. 然后执行main函数
3. 最后执行rootCmd.Execute()函数,root(根)命令是CLI工具的最基本的命令,比如go get XXX,其中go就是跟命令,而get就是go这个根命令的子命令,而在root.go中就直接使用了cobra命令来初始化rootCmd结构,CLI中的其他所有命令都将是Testapp这个根命令的子命令了
/go/Cobra # cat cmd/root.go
/*
Copyright © 2022 NAME HERE <EMAIL ADDRESS>
*/
package cmd
import (
"os"
"fmt"
"github.com/spf13/cobra"
)
// rootCmd represents the base command when called without any subcommands
var rootCmd = &cobra.Command{
Use: "Testapp",
Short: "A brief description of your application",
Long: `A longer description that spans multiple lines and likely contains
examples and usage of using your application. For example:
Cobra is a CLI library for Go that empowers applications.
This application is a tool to generate the needed files
to quickly create a Cobra application.`,
// Uncomment the following line if your bare application
// has an action associated with it:
Run: func(cmd *cobra.Command, args []string) {
fmt.Println("exec Execute") }, //这行是我单独增加的,看执行顺序
}
// Execute adds all child commands to the root command and sets flags appropriately.
// This is called by main.main(). It only needs to happen once to the rootCmd.
func Execute() {
err := rootCmd.Execute()
if err != nil {
os.Exit(1)
}
}
func init() {
fmt.Println("exec init") //这行是我单独增加的,看执行顺序
// Here you will define your flags and configuration settings.
// Cobra supports persistent flags, which, if defined here,
// will be global for your application.
// rootCmd.PersistentFlags().StringVar(&cfgFile, "config", "", "config file (default is $HOME/.Testapp.yaml)")
// Cobra also supports local flags, which will only run
// when this action is called directly.
rootCmd.Flags().BoolP("toggle", "t", false, "Help message for toggle")
}
/go/Cobra # go run main.go
exec init
exec in main
exec Execute