Use cobra for cli.

Signed-off-by: Lantao Liu <lantaol@google.com>
This commit is contained in:
Lantao Liu
2017-10-24 20:28:22 +00:00
parent 698f0ea2ae
commit 7977970e04
15 changed files with 3433 additions and 47 deletions

View File

@@ -17,12 +17,13 @@ limitations under the License.
package main
import (
"flag"
"os"
"github.com/docker/docker/pkg/reexec"
"github.com/golang/glog"
"github.com/opencontainers/selinux/go-selinux"
"github.com/spf13/pflag"
"github.com/spf13/cobra"
"k8s.io/kubernetes/pkg/util/interrupt"
"github.com/kubernetes-incubator/cri-containerd/cmd/cri-containerd/options"
@@ -30,40 +31,69 @@ import (
"github.com/kubernetes-incubator/cri-containerd/pkg/version"
)
// Add \u200B to avoid the space trimming.
const desc = "\u200B" + ` _ __ _ __
__________(_) _________ ____ / /_____ _(_)____ ___ _________/ /
/ ___/ ___/ /______/ ___/ __ \/ __ \/ __/ __ ` + "`" + `/ // __ \/ _ \/ ___/ __ /
/ /__/ / / //_____/ /__/ /_/ / / / / /_/ /_/ / // / / / __/ / / /_/ /
\___/_/ /_/ \___/\____/_/ /_/\__/\__,_/_//_/ /_/\___/_/ \__,_/
A containerd based Kubernetes CRI implementation.
`
var cmd = &cobra.Command{
Use: "cri-containerd",
Short: "A containerd based Kubernetes CRI implementation.",
Long: desc,
}
// Add golang flags as persistent flags.
func init() {
cmd.PersistentFlags().AddGoFlagSet(flag.CommandLine)
}
func main() {
if reexec.Init() {
return
}
o := options.NewCRIContainerdOptions()
o.AddFlags(pflag.CommandLine)
if err := o.InitFlags(pflag.CommandLine); err != nil {
glog.Exitf("Failed to init CRI containerd flags: %v", err)
o.AddFlags(cmd.Flags())
cmd.Run = func(cmd *cobra.Command, args []string) {
if err := o.InitFlags(cmd.Flags()); err != nil {
glog.Exitf("Failed to init CRI containerd flags: %v", err)
}
// TODO(random-liu): Turn to subcommand.
glog.V(0).Infof("Run cri-containerd %+v", o)
if o.PrintVersion {
version.PrintVersion()
os.Exit(0)
}
if o.PrintDefaultConfig {
o.PrintDefaultTomlConfig()
os.Exit(0)
}
validateConfig(o)
glog.V(2).Infof("Run cri-containerd grpc server on socket %q", o.SocketPath)
s, err := server.NewCRIContainerdService(o.Config)
if err != nil {
glog.Exitf("Failed to create CRI containerd service: %v", err)
}
// Use interrupt handler to make sure the server is stopped properly.
// Pass in non-empty final function to avoid os.Exit(1). We expect `Run`
// to return itself.
h := interrupt.New(func(os.Signal) {}, s.Stop)
if err := h.Run(func() error { return s.Run() }); err != nil {
glog.Exitf("Failed to run cri-containerd grpc server: %v", err)
}
}
glog.V(0).Infof("Run cri-containerd %+v", o)
if o.PrintVersion {
version.PrintVersion()
os.Exit(0)
}
if o.PrintDefaultConfig {
o.PrintDefaultTomlConfig()
os.Exit(0)
}
validateConfig(o)
glog.V(2).Infof("Run cri-containerd grpc server on socket %q", o.SocketPath)
s, err := server.NewCRIContainerdService(o.Config)
if err != nil {
glog.Exitf("Failed to create CRI containerd service: %v", err)
}
// Use interrupt handler to make sure the server to be stopped properly.
// Pass in non-empty final function to avoid os.Exit(1). We expect `Run`
// to return itself.
h := interrupt.New(func(os.Signal) {}, s.Stop)
if err := h.Run(func() error { return s.Run() }); err != nil {
glog.Exitf("Failed to run cri-containerd grpc server: %v", err)
if err := cmd.Execute(); err != nil {
glog.Exitf("Failed to execute cri-containerd: %v", err)
}
}

View File

@@ -17,7 +17,6 @@ limitations under the License.
package options
import (
"flag"
"fmt"
"os"
@@ -26,8 +25,12 @@ import (
"github.com/spf13/pflag"
)
// configFilePathArgName is the path to the config file.
const configFilePathArgName = "config"
const (
// configFilePathArgName is the path to the config file.
configFilePathArgName = "config"
// defaultConfigFilePath is the default config file path.
defaultConfigFilePath = "/etc/cri-containerd/config.toml"
)
// ContainerdConfig contains config related to containerd
type ContainerdConfig struct {
@@ -90,8 +93,8 @@ type Config struct {
type CRIContainerdOptions struct {
// Config contains cri-containerd toml config
Config
// Path to the TOML config file
ConfigFilePath string
// Path to the TOML config file.
ConfigFilePath string `toml:"-"`
// PrintVersion indicates to print version information of cri-containerd.
PrintVersion bool
// PrintDefaultConfig indicates to print default toml config of cri-containerd.
@@ -106,7 +109,7 @@ func NewCRIContainerdOptions() *CRIContainerdOptions {
// AddFlags adds cri-containerd command line options to pflag.
func (c *CRIContainerdOptions) AddFlags(fs *pflag.FlagSet) {
fs.StringVar(&c.ConfigFilePath, configFilePathArgName,
"/etc/cri-containerd/config.toml", "Path to the config file.")
defaultConfigFilePath, "Path to the config file.")
fs.StringVar(&c.SocketPath, "socket-path",
"/var/run/cri-containerd.sock", "Path to the socket which cri-containerd serves on.")
fs.StringVar(&c.RootDir, "root-dir",
@@ -149,19 +152,11 @@ func (c *CRIContainerdOptions) AddFlags(fs *pflag.FlagSet) {
-999, "Adjust the cri-containerd's oom score.")
}
// InitFlags must be called after adding all cli options flags are defined and
// before flags are accessed by the program. Ths fuction adds flag.CommandLine
// (the default set of command-line flags, parsed from os.Args) and then calls
// pflag.Parse().
// InitFlags load configurations from config file, and then overwrite with flags.
// This function must be called inside `Run`, at that time flags should have been
// parsed once.
// precedence: commandline > configfile > default
func (c *CRIContainerdOptions) InitFlags(fs *pflag.FlagSet) error {
fs.AddGoFlagSet(flag.CommandLine)
commandline := os.Args[1:]
if err := fs.Parse(commandline); err != nil {
return err
}
// Load default config file if none provided
if _, err := toml.DecodeFile(c.ConfigFilePath, &c.Config); err != nil {
// the absence of default config file is normal case.
@@ -179,7 +174,7 @@ func (c *CRIContainerdOptions) InitFlags(fs *pflag.FlagSet) error {
// But the priority of the toml config value is higher than the default value,
// Without a way to insert the toml config value between the default value and the command line value.
// We parse twice one for default value, one for commandline value.
return fs.Parse(commandline)
return fs.Parse(os.Args[1:])
}
// PrintDefaultTomlConfig print default toml config of cri-containerd.