From d0bbb53baf0c75a3be5374d79010dacb6088fb0e Mon Sep 17 00:00:00 2001 From: wangfei Date: Wed, 31 Aug 2022 17:13:29 +0800 Subject: [PATCH 1/6] Optimization: Categorize cmd modules by type --- cmd/sealer/cmd/alpha/cert.go | 5 +- cmd/sealer/cmd/alpha/exec.go | 8 +-- cmd/sealer/cmd/alpha/gen.go | 1 - cmd/sealer/cmd/alpha/upgrade.go | 5 +- cmd/sealer/cmd/{ => cluster}/apply.go | 39 ++++++----- cmd/sealer/cmd/{ => cluster}/check.go | 47 +++++++------ cmd/sealer/cmd/{ => cluster}/delete.go | 97 +++++++++++++------------- cmd/sealer/cmd/{ => cluster}/join.go | 53 +++++++------- cmd/sealer/cmd/{ => cluster}/run.go | 55 ++++++++------- cmd/sealer/cmd/completion.go | 43 ++++++------ cmd/sealer/cmd/{ => image}/build.go | 72 +++++++++---------- cmd/sealer/cmd/{ => image}/gen_doc.go | 6 +- cmd/sealer/cmd/{ => image}/images.go | 37 +++++----- cmd/sealer/cmd/{ => image}/inspect.go | 47 +++++++------ cmd/sealer/cmd/{ => image}/load.go | 37 +++++----- cmd/sealer/cmd/{ => image}/login.go | 42 ++++++----- cmd/sealer/cmd/{ => image}/logout.go | 39 +++++------ cmd/sealer/cmd/{ => image}/pull.go | 41 ++++++----- cmd/sealer/cmd/{ => image}/push.go | 42 ++++++----- cmd/sealer/cmd/{ => image}/rmi.go | 41 ++++++----- cmd/sealer/cmd/{ => image}/save.go | 42 +++++------ cmd/sealer/cmd/image/search.go | 82 ++++++++++++++++++++++ cmd/sealer/cmd/{ => image}/tag.go | 41 ++++++----- cmd/sealer/cmd/root.go | 22 ++++-- cmd/sealer/cmd/search.go | 82 ---------------------- cmd/sealer/cmd/version.go | 42 ++++++----- 26 files changed, 534 insertions(+), 534 deletions(-) rename cmd/sealer/cmd/{ => cluster}/apply.go (64%) rename cmd/sealer/cmd/{ => cluster}/check.go (52%) rename cmd/sealer/cmd/{ => cluster}/delete.go (54%) rename cmd/sealer/cmd/{ => cluster}/join.go (74%) rename cmd/sealer/cmd/{ => cluster}/run.go (79%) rename cmd/sealer/cmd/{ => image}/build.go (88%) rename cmd/sealer/cmd/{ => image}/gen_doc.go (95%) rename cmd/sealer/cmd/{ => image}/images.go (74%) rename cmd/sealer/cmd/{ => image}/inspect.go (63%) rename cmd/sealer/cmd/{ => image}/load.go (67%) rename cmd/sealer/cmd/{ => image}/login.go (75%) rename cmd/sealer/cmd/{ => image}/logout.go (65%) rename cmd/sealer/cmd/{ => image}/pull.go (74%) rename cmd/sealer/cmd/{ => image}/push.go (68%) rename cmd/sealer/cmd/{ => image}/rmi.go (75%) rename cmd/sealer/cmd/{ => image}/save.go (71%) create mode 100644 cmd/sealer/cmd/image/search.go rename cmd/sealer/cmd/{ => image}/tag.go (56%) delete mode 100644 cmd/sealer/cmd/search.go diff --git a/cmd/sealer/cmd/alpha/cert.go b/cmd/sealer/cmd/alpha/cert.go index 5b5cf33038c..5bb2e98c59a 100644 --- a/cmd/sealer/cmd/alpha/cert.go +++ b/cmd/sealer/cmd/alpha/cert.go @@ -27,21 +27,20 @@ import ( "github.com/sealerio/sealer/pkg/clusterfile" ) -var altNames []string - var longCertCmdDescription = `This command will add the new domain or IP address in cert to update cluster API server. sealer has some default domain and IP in the cert process builtin: localhost,outbound IP address and some DNS domain which is strongly related to the apiserver CertSANs configured by kubeadm.yml. You need to restart your API server manually after using sealer alpha cert. Then, you can using cmd "openssl x509 -noout -text -in apiserver.crt" to check the cert details. ` - var exampleForCertCmd = ` The following command will generate new api server cert and key for all control-plane certificates: sealer alpha cert --alt-names 39.105.169.253,sealer.cool ` +var altNames []string + func NewCertCmd() *cobra.Command { certCmd := &cobra.Command{ Use: "cert", diff --git a/cmd/sealer/cmd/alpha/exec.go b/cmd/sealer/cmd/alpha/exec.go index 09f915577db..ab02a979b5e 100644 --- a/cmd/sealer/cmd/alpha/exec.go +++ b/cmd/sealer/cmd/alpha/exec.go @@ -27,12 +27,10 @@ import ( ) var ( - clusterName string - roles []string + clusterName string + roles []string + longExecCmdDescription = `Using sealer builtin ssh client to run shell command on the node filtered by cluster and cluster role. it is convenient for cluster administrator to do quick investigate` ) - -var longExecCmdDescription = `Using sealer builtin ssh client to run shell command on the node filtered by cluster and cluster role. it is convenient for cluster administrator to do quick investigate` - var exampleForExecCmd = ` Exec the default cluster node: sealer alpha exec "cat /etc/hosts" diff --git a/cmd/sealer/cmd/alpha/gen.go b/cmd/sealer/cmd/alpha/gen.go index c7dcc3d1cf3..e6294b73892 100644 --- a/cmd/sealer/cmd/alpha/gen.go +++ b/cmd/sealer/cmd/alpha/gen.go @@ -29,7 +29,6 @@ var exampleForGenCmd = `The following command will generate Clusterfile used by sealer alpha gen --passwd xxxx --image kubernetes:v1.19.8 ` - var longGenCmdDescription = `Sealer will call kubernetes API to get masters and nodes IP info, then generate a Clusterfile. and also pull a ClusterImage which matches the kubernetes version. Then you can use any sealer command to manage the cluster like: diff --git a/cmd/sealer/cmd/alpha/upgrade.go b/cmd/sealer/cmd/alpha/upgrade.go index e546fc109ff..0c50fba2b87 100644 --- a/cmd/sealer/cmd/alpha/upgrade.go +++ b/cmd/sealer/cmd/alpha/upgrade.go @@ -19,15 +19,14 @@ import ( "github.com/spf13/cobra" ) -var upgradeClusterName string - var exampleForUpgradeCmd = `The following command will upgrade the current cluster to kubernetes:v1.19.9 sealer alpha upgrade kubernetes:v1.19.9 ` - var longUpgradeCmdDescription = `Sealer upgrade command will upgrade the current cluster to the specified version with the ClusterImage using kubeadm upgrade ` +var upgradeClusterName string + // NewUpgradeCmd implement the sealer upgrade command func NewUpgradeCmd() *cobra.Command { upgradeCmd := &cobra.Command{ diff --git a/cmd/sealer/cmd/apply.go b/cmd/sealer/cmd/cluster/apply.go similarity index 64% rename from cmd/sealer/cmd/apply.go rename to cmd/sealer/cmd/cluster/apply.go index d4a9e3e59c7..850055f4d24 100644 --- a/cmd/sealer/cmd/apply.go +++ b/cmd/sealer/cmd/cluster/apply.go @@ -12,7 +12,7 @@ // See the License for the specific language governing permissions and // limitations under the License. -package cmd +package cluster import ( "github.com/sealerio/sealer/pkg/runtime/kubernetes" @@ -23,26 +23,27 @@ import ( var clusterFile string -// applyCmd represents the apply command -var applyCmd = &cobra.Command{ - Use: "apply", - Short: "apply a Kubernetes cluster via specified Clusterfile", - Long: `apply command is used to apply a Kubernetes cluster via specified Clusterfile. +var longNewApplyCmdDescription = `apply command is used to apply a Kubernetes cluster via specified Clusterfile. If the Clusterfile is applied first time, Kubernetes cluster will be created. Otherwise, sealer -will apply the diff change of current Clusterfile and the original one.`, - Example: `sealer apply -f Clusterfile`, - Args: cobra.NoArgs, - RunE: func(cmd *cobra.Command, args []string) error { - applier, err := apply.NewApplierFromFile(clusterFile) - if err != nil { - return err - } - return applier.Apply() - }, -} +will apply the diff change of current Clusterfile and the original one.` -func init() { - rootCmd.AddCommand(applyCmd) +// NewApplyCmd applyCmd represents the apply command +func NewApplyCmd() *cobra.Command { + applyCmd := &cobra.Command{ + Use: "apply", + Short: "apply a Kubernetes cluster via specified Clusterfile", + Long: longNewApplyCmdDescription, + Example: `sealer apply -f Clusterfile`, + Args: cobra.NoArgs, + RunE: func(cmd *cobra.Command, args []string) error { + applier, err := apply.NewApplierFromFile(clusterFile) + if err != nil { + return err + } + return applier.Apply() + }, + } applyCmd.Flags().StringVarP(&clusterFile, "Clusterfile", "f", "Clusterfile", "Clusterfile path to apply a Kubernetes cluster") applyCmd.Flags().BoolVar(&kubernetes.ForceDelete, "force", false, "force to delete the specified cluster if set true") + return applyCmd } diff --git a/cmd/sealer/cmd/check.go b/cmd/sealer/cmd/cluster/check.go similarity index 52% rename from cmd/sealer/cmd/check.go rename to cmd/sealer/cmd/cluster/check.go index c7663f1936d..d2582b3f571 100644 --- a/cmd/sealer/cmd/check.go +++ b/cmd/sealer/cmd/cluster/check.go @@ -12,7 +12,7 @@ // See the License for the specific language governing permissions and // limitations under the License. -package cmd +package cluster import ( "fmt" @@ -29,29 +29,30 @@ type CheckArgs struct { var checkArgs *CheckArgs -// pushCmd represents the push command -var checkCmd = &cobra.Command{ - Use: "check", - Short: "check the state of cluster", - Long: `check command is used to check status of the cluster, including node status -, service status and pod status.`, - Example: `sealer check --pre or sealer check --post`, - Args: cobra.NoArgs, - RunE: func(cmd *cobra.Command, args []string) error { - if checkArgs.Pre && checkArgs.Post { - return fmt.Errorf("don't allow to set two flags --pre and --post") - } - list := []checker.Interface{checker.NewNodeChecker(), checker.NewSvcChecker(), checker.NewPodChecker()} - if checkArgs.Pre { - return checker.RunCheckList(list, nil, checker.PhasePre) - } - return checker.RunCheckList(list, nil, checker.PhasePost) - }, -} - -func init() { +var longNewCheckCmdDescription = `check command is used to check status of the cluster, including node status +, service status and pod status.` + +// NewCheckCmd pushCmd represents the push command +func NewCheckCmd() *cobra.Command { + checkCmd := &cobra.Command{ + Use: "check", + Short: "check the state of cluster", + Long: longNewCheckCmdDescription, + Example: `sealer check --pre or sealer check --post`, + Args: cobra.NoArgs, + RunE: func(cmd *cobra.Command, args []string) error { + if checkArgs.Pre && checkArgs.Post { + return fmt.Errorf("don't allow to set two flags --pre and --post") + } + list := []checker.Interface{checker.NewNodeChecker(), checker.NewSvcChecker(), checker.NewPodChecker()} + if checkArgs.Pre { + return checker.RunCheckList(list, nil, checker.PhasePre) + } + return checker.RunCheckList(list, nil, checker.PhasePost) + }, + } checkArgs = &CheckArgs{} - rootCmd.AddCommand(checkCmd) checkCmd.Flags().BoolVar(&checkArgs.Pre, "pre", false, "Check dependencies before cluster creation") checkCmd.Flags().BoolVar(&checkArgs.Post, "post", false, "Check the status of the cluster after it is created") + return checkCmd } diff --git a/cmd/sealer/cmd/delete.go b/cmd/sealer/cmd/cluster/delete.go similarity index 54% rename from cmd/sealer/cmd/delete.go rename to cmd/sealer/cmd/cluster/delete.go index ae2cd1a54ce..b22c1533ca2 100644 --- a/cmd/sealer/cmd/delete.go +++ b/cmd/sealer/cmd/cluster/delete.go @@ -12,7 +12,7 @@ // See the License for the specific language governing permissions and // limitations under the License. -package cmd +package cluster import ( "fmt" @@ -32,14 +32,10 @@ var ( deleteClusterName string ) -// deleteCmd represents the delete command -var deleteCmd = &cobra.Command{ - Use: "delete", - Short: "delete an existing cluster", - Long: `delete command is used to delete part or all of existing cluster. -User can delete cluster by explicitly specifying node IP, Clusterfile, or cluster name.`, - Args: cobra.NoArgs, - Example: ` +var longDeleteCmdDescription = `delete command is used to delete part or all of existing cluster. +User can delete cluster by explicitly specifying node IP, Clusterfile, or cluster name.` + +var exampleForDeleteCmd = ` delete default cluster: sealer delete --masters x.x.x.x --nodes x.x.x.x sealer delete --masters x.x.x.x-x.x.x.y --nodes x.x.x.x-x.x.x.y @@ -47,52 +43,58 @@ delete all: sealer delete --all [--force] sealer delete -f /root/.sealer/mycluster/Clusterfile [--force] sealer delete -c my-cluster [--force] -`, - RunE: func(cmd *cobra.Command, args []string) error { - all, err := cmd.Flags().GetBool("all") - if err != nil { - return err - } - if deleteClusterName == "" && deleteClusterFile == "" { - if !all && deleteArgs.Masters == "" && deleteArgs.Nodes == "" { - return fmt.Errorf("the delete parameter needs to be set") - } - deleteClusterName, err = clusterfile.GetDefaultClusterName() - if err == clusterfile.ErrClusterNotExist { - fmt.Println("Find no exist cluster, skip delete") - return nil - } +` + +// NewDeleteCmd deleteCmd represents the delete command +func NewDeleteCmd() *cobra.Command { + deleteCmd := &cobra.Command{ + Use: "delete", + Short: "delete an existing cluster", + Long: longDeleteCmdDescription, + Args: cobra.NoArgs, + Example: exampleForDeleteCmd, + RunE: func(cmd *cobra.Command, args []string) error { + all, err := cmd.Flags().GetBool("all") if err != nil { return err } - deleteClusterFile = common.GetClusterWorkClusterfile(deleteClusterName) - } else if deleteClusterName != "" && deleteClusterFile != "" { - tmpClusterfile := common.GetClusterWorkClusterfile(deleteClusterName) - if tmpClusterfile != deleteClusterFile { - return fmt.Errorf("arguments error:%s and %s refer to different clusters", deleteClusterFile, tmpClusterfile) + if deleteClusterName == "" && deleteClusterFile == "" { + if !all && deleteArgs.Masters == "" && deleteArgs.Nodes == "" { + return fmt.Errorf("the delete parameter needs to be set") + } + deleteClusterName, err = clusterfile.GetDefaultClusterName() + if err == clusterfile.ErrClusterNotExist { + fmt.Println("Find no exist cluster, skip delete") + return nil + } + if err != nil { + return err + } + deleteClusterFile = common.GetClusterWorkClusterfile(deleteClusterName) + } else if deleteClusterName != "" && deleteClusterFile != "" { + tmpClusterfile := common.GetClusterWorkClusterfile(deleteClusterName) + if tmpClusterfile != deleteClusterFile { + return fmt.Errorf("arguments error:%s and %s refer to different clusters", deleteClusterFile, tmpClusterfile) + } + } else if deleteClusterFile == "" { + deleteClusterFile = common.GetClusterWorkClusterfile(deleteClusterName) + } + if deleteArgs.Nodes != "" || deleteArgs.Masters != "" { + applier, err := apply.NewScaleApplierFromArgs(deleteClusterFile, deleteArgs, common.DeleteSubCmd) + if err != nil { + return err + } + return applier.Apply() } - } else if deleteClusterFile == "" { - deleteClusterFile = common.GetClusterWorkClusterfile(deleteClusterName) - } - if deleteArgs.Nodes != "" || deleteArgs.Masters != "" { - applier, err := apply.NewScaleApplierFromArgs(deleteClusterFile, deleteArgs, common.DeleteSubCmd) + + applier, err := apply.NewApplierFromFile(deleteClusterFile) if err != nil { return err } - return applier.Apply() - } - - applier, err := apply.NewApplierFromFile(deleteClusterFile) - if err != nil { - return err - } - return applier.Delete() - }, -} - -func init() { + return applier.Delete() + }, + } deleteArgs = &apply.Args{} - rootCmd.AddCommand(deleteCmd) deleteCmd.Flags().StringVarP(&deleteArgs.Masters, "masters", "m", "", "reduce Count or IPList to masters") deleteCmd.Flags().StringVarP(&deleteArgs.Nodes, "nodes", "n", "", "reduce Count or IPList to nodes") deleteCmd.Flags().StringVarP(&deleteClusterFile, "Clusterfile", "f", "", "delete a kubernetes cluster with Clusterfile Annotations") @@ -100,4 +102,5 @@ func init() { deleteCmd.Flags().StringSliceVarP(&deleteArgs.CustomEnv, "env", "e", []string{}, "set custom environment variables") deleteCmd.Flags().BoolVar(&kubernetes.ForceDelete, "force", false, "We also can input an --force flag to delete cluster by force") deleteCmd.Flags().BoolP("all", "a", false, "this flags is for delete nodes, if this is true, empty all node ip") + return deleteCmd } diff --git a/cmd/sealer/cmd/join.go b/cmd/sealer/cmd/cluster/join.go similarity index 74% rename from cmd/sealer/cmd/join.go rename to cmd/sealer/cmd/cluster/join.go index 91762cc5a52..c5ad9dc30d7 100644 --- a/cmd/sealer/cmd/join.go +++ b/cmd/sealer/cmd/cluster/join.go @@ -12,7 +12,7 @@ // See the License for the specific language governing permissions and // limitations under the License. -package cmd +package cluster import ( "github.com/spf13/cobra" @@ -25,46 +25,45 @@ import ( var clusterName string var joinArgs *apply.Args -var joinCmd = &cobra.Command{ - Use: "join", - Short: "join new master or worker node to specified cluster", - // TODO: add long description. - Long: "", - Args: cobra.NoArgs, - Example: ` +var exampleForJoinCmd = ` join default cluster: sealer join --masters x.x.x.x --nodes x.x.x.x sealer join --masters x.x.x.x-x.x.x.y --nodes x.x.x.x-x.x.x.y -`, - RunE: func(cmd *cobra.Command, args []string) error { - if clusterName == "" { - cn, err := clusterfile.GetDefaultClusterName() +` + +func NewJoinCmd() *cobra.Command { + joinCmd := &cobra.Command{ + Use: "join", + Short: "join new master or worker node to specified cluster", + // TODO: add long description. + Long: "", + Args: cobra.NoArgs, + Example: exampleForJoinCmd, + RunE: func(cmd *cobra.Command, args []string) error { + if clusterName == "" { + cn, err := clusterfile.GetDefaultClusterName() + if err != nil { + return err + } + clusterName = cn + } + path := common.GetClusterWorkClusterfile(clusterName) + applier, err := apply.NewScaleApplierFromArgs(path, joinArgs, common.JoinSubCmd) if err != nil { return err } - clusterName = cn - } - path := common.GetClusterWorkClusterfile(clusterName) - applier, err := apply.NewScaleApplierFromArgs(path, joinArgs, common.JoinSubCmd) - if err != nil { - return err - } - return applier.Apply() - }, -} - -func init() { + return applier.Apply() + }, + } joinArgs = &apply.Args{} - rootCmd.AddCommand(joinCmd) - joinCmd.Flags().StringVarP(&joinArgs.User, "user", "u", "root", "set baremetal server username") joinCmd.Flags().StringVarP(&joinArgs.Password, "passwd", "p", "", "set cloud provider or baremetal server password") joinCmd.Flags().Uint16Var(&joinArgs.Port, "port", 22, "set the sshd service port number for the server (default port: 22)") joinCmd.Flags().StringVar(&joinArgs.Pk, "pk", common.GetHomeDir()+"/.ssh/id_rsa", "set baremetal server private key") joinCmd.Flags().StringVar(&joinArgs.PkPassword, "pk-passwd", "", "set baremetal server private key password") joinCmd.Flags().StringSliceVarP(&joinArgs.CustomEnv, "env", "e", []string{}, "set custom environment variables") - joinCmd.Flags().StringVarP(&joinArgs.Masters, "masters", "m", "", "set Count or IPList to masters") joinCmd.Flags().StringVarP(&joinArgs.Nodes, "nodes", "n", "", "set Count or IPList to nodes") joinCmd.Flags().StringVarP(&clusterName, "cluster-name", "c", "", "specify the name of cluster") + return joinCmd } diff --git a/cmd/sealer/cmd/run.go b/cmd/sealer/cmd/cluster/run.go similarity index 79% rename from cmd/sealer/cmd/run.go rename to cmd/sealer/cmd/cluster/run.go index 839da756a9a..3aa76653e55 100644 --- a/cmd/sealer/cmd/run.go +++ b/cmd/sealer/cmd/cluster/run.go @@ -12,7 +12,7 @@ // See the License for the specific language governing permissions and // limitations under the License. -package cmd +package cluster import ( "os" @@ -30,11 +30,7 @@ import ( var runArgs *apply.Args -var runCmd = &cobra.Command{ - Use: "run", - Short: "start to run a cluster from a ClusterImage", - Long: `sealer run registry.cn-qingdao.aliyuncs.com/sealer-io/kubernetes:v1.19.8 --masters [arg] --nodes [arg]`, - Example: ` +var exampleForRunCmd = ` create cluster to your bare metal server, appoint the iplist: sealer run kubernetes:v1.19.8 --masters 192.168.0.2,192.168.0.3,192.168.0.4 \ --nodes 192.168.0.5,192.168.0.6,192.168.0.7 --passwd xxx @@ -51,31 +47,35 @@ specify server SSH port : create a cluster with custom environment variables: sealer run -e DashBoardPort=8443 mydashboard:latest --masters 192.168.0.2,192.168.0.3,192.168.0.4 \ --nodes 192.168.0.5,192.168.0.6,192.168.0.7 --passwd xxx -`, - Args: cobra.ExactArgs(1), - RunE: func(cmd *cobra.Command, args []string) error { - // set local ip address as master0 default ip if user input is empty. - // this is convenient to execute `sealer run` without set many arguments. - // Example looks like "sealer run kubernetes:v1.19.8" - if runArgs.Masters == "" { - ip, err := net.GetLocalDefaultIP() +` + +func NewRunCmd() *cobra.Command { + runCmd := &cobra.Command{ + Use: "run", + Short: "start to run a cluster from a ClusterImage", + Long: `sealer run registry.cn-qingdao.aliyuncs.com/sealer-io/kubernetes:v1.19.8 --masters [arg] --nodes [arg]`, + Example: exampleForRunCmd, + Args: cobra.ExactArgs(1), + RunE: func(cmd *cobra.Command, args []string) error { + // set local ip address as master0 default ip if user input is empty. + // this is convenient to execute `sealer run` without set many arguments. + // Example looks like "sealer run kubernetes:v1.19.8" + if runArgs.Masters == "" { + ip, err := net.GetLocalDefaultIP() + if err != nil { + return err + } + runArgs.Masters = ip + } + + applier, err := apply.NewApplierFromArgs(args[0], runArgs) if err != nil { return err } - runArgs.Masters = ip - } - - applier, err := apply.NewApplierFromArgs(args[0], runArgs) - if err != nil { - return err - } - return applier.Apply() - }, -} - -func init() { + return applier.Apply() + }, + } runArgs = &apply.Args{} - rootCmd.AddCommand(runCmd) runCmd.Flags().StringVarP(&runArgs.Provider, "provider", "", "", "set infra provider, example `ALI_CLOUD`, the local server need ignore this") runCmd.Flags().StringVarP(&runArgs.Masters, "masters", "m", "", "set count or IPList to masters") runCmd.Flags().StringVarP(&runArgs.Nodes, "nodes", "n", "", "set count or IPList to nodes") @@ -94,4 +94,5 @@ func init() { logrus.Errorf("provide completion for provider flag, err: %v", err) os.Exit(1) } + return runCmd } diff --git a/cmd/sealer/cmd/completion.go b/cmd/sealer/cmd/completion.go index af0bd1c5b1c..34bb1163586 100644 --- a/cmd/sealer/cmd/completion.go +++ b/cmd/sealer/cmd/completion.go @@ -23,11 +23,7 @@ import ( "github.com/sirupsen/logrus" ) -// completionCmd represents the completion command -var completionCmd = &cobra.Command{ - Use: "completion", - Short: "generate autocompletion script for bash", - Long: `Generate the autocompletion script for sealer for the bash shell. +var longCompletionCmdDescription = `Generate the autocompletion script for sealer for the bash shell. To load completions in your current shell session: source <(sealer completion bash) @@ -37,21 +33,26 @@ To load completions for every new session, execute once: - Linux : ## If bash-completion is not installed on Linux, please install the 'bash-completion' package sealer completion bash > /etc/bash_completion.d/sealer - `, - DisableFlagsInUseLine: true, - ValidArgs: []string{"bash"}, - Args: cobra.ExactValidArgs(1), - Run: func(cmd *cobra.Command, args []string) { - switch args[0] { - case "bash": - if err := cmd.Root().GenBashCompletion(common.StdOut); err != nil { - logrus.Errorf("failed to use bash completion, %v", err) - os.Exit(1) + ` + +// NewCompletionCmd completionCmd represents the completion command +func NewCompletionCmd() *cobra.Command { + completionCmd := &cobra.Command{ + Use: "completion", + Short: "generate autocompletion script for bash", + Long: longCompletionCmdDescription, + DisableFlagsInUseLine: true, + ValidArgs: []string{"bash"}, + Args: cobra.ExactValidArgs(1), + Run: func(cmd *cobra.Command, args []string) { + switch args[0] { + case "bash": + if err := cmd.Root().GenBashCompletion(common.StdOut); err != nil { + logrus.Errorf("failed to use bash completion, %v", err) + os.Exit(1) + } } - } - }, -} - -func init() { - rootCmd.AddCommand(completionCmd) + }, + } + return completionCmd } diff --git a/cmd/sealer/cmd/build.go b/cmd/sealer/cmd/image/build.go similarity index 88% rename from cmd/sealer/cmd/build.go rename to cmd/sealer/cmd/image/build.go index 5b83f8cb709..c64797d3f2c 100644 --- a/cmd/sealer/cmd/build.go +++ b/cmd/sealer/cmd/image/build.go @@ -12,7 +12,7 @@ // See the License for the specific language governing permissions and // limitations under the License. -package cmd +package image import ( "fmt" @@ -45,15 +45,11 @@ type BuildFlag struct { var buildFlags = bc.BuildOptions{} -// buildCmd represents the build command -var buildCmd = &cobra.Command{ - Use: "build [flags] PATH", - Short: "build a ClusterImage from a Kubefile", - Long: `build command is used to generate a ClusterImage from specified Kubefile. +var longNewBuildCmdDescription = `build command is used to generate a ClusterImage from specified Kubefile. It organizes the specified Kubefile and input building context, and builds -a brand new ClusterImage.`, - Args: cobra.MaximumNArgs(1), - Example: `the current path is the context path, default build type is lite and use build cache +a brand new ClusterImage.` + +var exampleNewBuildCmd = `the current path is the context path, default build type is lite and use build cache build: sealer build -f Kubefile -t my-kubernetes:1.19.8 . @@ -66,11 +62,38 @@ build without base: build with args: sealer build -f Kubefile -t my-kubernetes:1.19.8 --build-arg MY_ARG=abc,PASSWORD=Sealer123 . -`, - RunE: func(cmd *cobra.Command, args []string) error { - buildFlags.ContextDir = args[0] - return buildSealerImage() - }, +` + +// NewBuildCmd buildCmd represents the build command +func NewBuildCmd() *cobra.Command { + buildCmd := &cobra.Command{ + Use: "build [flags] PATH", + Short: "build a ClusterImage from a Kubefile", + Long: longNewBuildCmdDescription, + Args: cobra.MaximumNArgs(1), + Example: exampleNewBuildCmd, + RunE: func(cmd *cobra.Command, args []string) error { + buildFlags.ContextDir = args[0] + return buildSealerImage() + }, + } + buildCmd.Flags().StringVarP(&buildFlags.Kubefile, "file", "f", "Kubefile", "Kubefile filepath") + buildCmd.Flags().StringVar(&buildFlags.Platform, "platform", parse.DefaultPlatform(), "set the target platform, like linux/amd64 or linux/amd64/v7") + buildCmd.Flags().StringVar(&buildFlags.PullPolicy, "pull", "", "pull policy. Allow for --pull, --pull=true, --pull=false, --pull=never, --pull=always") + buildCmd.Flags().StringVar(&buildFlags.Authfile, "authfile", pkgauth.GetDefaultAuthFilePath(), "path of the authentication file.") + buildCmd.Flags().BoolVar(&buildFlags.NoCache, "no-cache", false, "do not use existing cached images for building. Build from the start with a new set of cached layers.") + buildCmd.Flags().BoolVar(&buildFlags.Base, "base", true, "build with base image, default value is true.") + buildCmd.Flags().StringSliceVarP(&buildFlags.Tags, "tag", "t", []string{}, "specify a name for ClusterImage") + buildCmd.Flags().StringSliceVar(&buildFlags.BuildArgs, "build-arg", []string{}, "set custom build args") + buildCmd.Flags().StringSliceVar(&buildFlags.Annotations, "annotation", []string{}, "add annotations for image. Format like --annotation key=[value]") + buildCmd.Flags().StringSliceVar(&buildFlags.Labels, "label", []string{getSealerLabel()}, "add labels for image. Format like --label key=[value]") + requiredFlags := []string{"tag"} + for _, flag := range requiredFlags { + if err := buildCmd.MarkFlagRequired(flag); err != nil { + logrus.Fatal(err) + } + } + return buildCmd } func buildSealerImage() error { @@ -155,27 +178,6 @@ func buildSealerImage() error { return nil } -func init() { - buildCmd.Flags().StringVarP(&buildFlags.Kubefile, "file", "f", "Kubefile", "Kubefile filepath") - buildCmd.Flags().StringVar(&buildFlags.Platform, "platform", parse.DefaultPlatform(), "set the target platform, like linux/amd64 or linux/amd64/v7") - buildCmd.Flags().StringVar(&buildFlags.PullPolicy, "pull", "", "pull policy. Allow for --pull, --pull=true, --pull=false, --pull=never, --pull=always") - buildCmd.Flags().StringVar(&buildFlags.Authfile, "authfile", pkgauth.GetDefaultAuthFilePath(), "path of the authentication file.") - buildCmd.Flags().BoolVar(&buildFlags.NoCache, "no-cache", false, "do not use existing cached images for building. Build from the start with a new set of cached layers.") - buildCmd.Flags().BoolVar(&buildFlags.Base, "base", true, "build with base image, default value is true.") - buildCmd.Flags().StringSliceVarP(&buildFlags.Tags, "tag", "t", []string{}, "specify a name for ClusterImage") - buildCmd.Flags().StringSliceVar(&buildFlags.BuildArgs, "build-arg", []string{}, "set custom build args") - buildCmd.Flags().StringSliceVar(&buildFlags.Annotations, "annotation", []string{}, "add annotations for image. Format like --annotation key=[value]") - buildCmd.Flags().StringSliceVar(&buildFlags.Labels, "label", []string{getSealerLabel()}, "add labels for image. Format like --label key=[value]") - - requiredFlags := []string{"tag"} - for _, flag := range requiredFlags { - if err := buildCmd.MarkFlagRequired(flag); err != nil { - logrus.Fatal(err) - } - } - rootCmd.AddCommand(buildCmd) -} - func getSealerLabel() string { return "io.sealer.version=" + version.Get().GitVersion } diff --git a/cmd/sealer/cmd/gen_doc.go b/cmd/sealer/cmd/image/gen_doc.go similarity index 95% rename from cmd/sealer/cmd/gen_doc.go rename to cmd/sealer/cmd/image/gen_doc.go index edda9409646..3d1a6090b5d 100644 --- a/cmd/sealer/cmd/gen_doc.go +++ b/cmd/sealer/cmd/image/gen_doc.go @@ -12,7 +12,7 @@ // See the License for the specific language governing permissions and // limitations under the License. -package cmd +package image import ( "fmt" @@ -30,7 +30,7 @@ type GenDocCommand struct { path string } -func init() { +func NewGenDocCommand() *cobra.Command { genDocCommand := &GenDocCommand{} genDocCommand.cmd = &cobra.Command{ Use: "gen-doc", @@ -43,7 +43,7 @@ func init() { }, } genDocCommand.addFlags() - rootCmd.AddCommand(genDocCommand.cmd) + return genDocCommand.cmd } // addFlags adds flags for specific command. diff --git a/cmd/sealer/cmd/images.go b/cmd/sealer/cmd/image/images.go similarity index 74% rename from cmd/sealer/cmd/images.go rename to cmd/sealer/cmd/image/images.go index ce4be2d4cd7..419162ab241 100644 --- a/cmd/sealer/cmd/images.go +++ b/cmd/sealer/cmd/image/images.go @@ -12,7 +12,7 @@ // See the License for the specific language governing permissions and // limitations under the License. -package cmd +package image import ( "github.com/sealerio/sealer/pkg/define/options" @@ -22,23 +22,22 @@ import ( var imagesOpts *options.ImagesOptions -var listCmd = &cobra.Command{ - Use: "images", - Short: "list all ClusterImages on the local node", - // TODO: add long description. - Long: "", - Args: cobra.NoArgs, - Example: `sealer images`, - RunE: func(cmd *cobra.Command, args []string) error { - engine, err := imageengine.NewImageEngine(options.EngineGlobalConfigurations{}) - if err != nil { - return err - } - return engine.Images(imagesOpts) - }, -} - -func init() { +func NewListCmd() *cobra.Command { + listCmd := &cobra.Command{ + Use: "images", + Short: "list all ClusterImages on the local node", + // TODO: add long description. + Long: "", + Args: cobra.NoArgs, + Example: `sealer images`, + RunE: func(cmd *cobra.Command, args []string) error { + engine, err := imageengine.NewImageEngine(options.EngineGlobalConfigurations{}) + if err != nil { + return err + } + return engine.Images(imagesOpts) + }, + } imagesOpts = &options.ImagesOptions{} flags := listCmd.Flags() flags.BoolVarP(&imagesOpts.All, "all", "a", false, "show all images, including intermediate images from a build") @@ -49,5 +48,5 @@ func init() { flags.BoolVarP(&imagesOpts.Quiet, "quiet", "q", false, "display only image IDs") flags.BoolVarP(&imagesOpts.History, "history", "", false, "display the image name history") - rootCmd.AddCommand(listCmd) + return listCmd } diff --git a/cmd/sealer/cmd/inspect.go b/cmd/sealer/cmd/image/inspect.go similarity index 63% rename from cmd/sealer/cmd/inspect.go rename to cmd/sealer/cmd/image/inspect.go index d0bacfaa201..6bd222a004a 100644 --- a/cmd/sealer/cmd/inspect.go +++ b/cmd/sealer/cmd/image/inspect.go @@ -12,7 +12,7 @@ // See the License for the specific language governing permissions and // limitations under the License. -package cmd +package image import ( "github.com/sealerio/sealer/pkg/define/options" @@ -22,33 +22,34 @@ import ( var inspectOpts *options.InspectOptions -// inspectCmd represents the inspect command -var inspectCmd = &cobra.Command{ - Use: "inspect", - Short: "print the image information or Clusterfile", - Example: `sealer inspect {imageName or imageID} +var exampleForInspectCmd = `sealer inspect {imageName or imageID} sealer inspect --format '{{.OCIv1.Config.Env}}' {imageName or imageID} -`, - Args: cobra.ExactArgs(1), - RunE: func(cmd *cobra.Command, args []string) error { - engine, err := imageengine.NewImageEngine(options.EngineGlobalConfigurations{}) - if err != nil { - return err - } +` - inspectOpts.ImageNameOrID = args[0] - err = engine.Inspect(inspectOpts) - if err != nil { - return err - } - return nil - }, -} +// NewInspectCmd inspectCmd represents the inspect command +func NewInspectCmd() *cobra.Command { + inspectCmd := &cobra.Command{ + Use: "inspect", + Short: "print the image information or Clusterfile", + Example: exampleForInspectCmd, + Args: cobra.ExactArgs(1), + RunE: func(cmd *cobra.Command, args []string) error { + engine, err := imageengine.NewImageEngine(options.EngineGlobalConfigurations{}) + if err != nil { + return err + } -func init() { + inspectOpts.ImageNameOrID = args[0] + err = engine.Inspect(inspectOpts) + if err != nil { + return err + } + return nil + }, + } inspectOpts = &options.InspectOptions{} flags := inspectCmd.Flags() flags.StringVarP(&inspectOpts.Format, "format", "f", "", "use `format` as a Go template to format the output") flags.StringVarP(&inspectOpts.InspectType, "type", "t", "image", "look at the item of the specified `type` (container or image) and name") - rootCmd.AddCommand(inspectCmd) + return inspectCmd } diff --git a/cmd/sealer/cmd/load.go b/cmd/sealer/cmd/image/load.go similarity index 67% rename from cmd/sealer/cmd/load.go rename to cmd/sealer/cmd/image/load.go index fa52f89ef15..6271bfa9089 100644 --- a/cmd/sealer/cmd/load.go +++ b/cmd/sealer/cmd/image/load.go @@ -12,7 +12,7 @@ // See the License for the specific language governing permissions and // limitations under the License. -package cmd +package image import ( "os" @@ -26,23 +26,22 @@ import ( var loadOpts *options.LoadOptions -// loadCmd represents the load command -var loadCmd = &cobra.Command{ - Use: "load", - Short: "load a ClusterImage from a tar file", - Long: `Load a ClusterImage from a tar archive`, - Example: `sealer load -i kubernetes.tar`, - Args: cobra.NoArgs, - RunE: func(cmd *cobra.Command, args []string) error { - engine, err := imageengine.NewImageEngine(options.EngineGlobalConfigurations{}) - if err != nil { - return err - } - return engine.Load(loadOpts) - }, -} - -func init() { +// NewLoadCmd loadCmd represents the load command +func NewLoadCmd() *cobra.Command { + loadCmd := &cobra.Command{ + Use: "load", + Short: "load a ClusterImage from a tar file", + Long: `Load a ClusterImage from a tar archive`, + Example: `sealer load -i kubernetes.tar`, + Args: cobra.NoArgs, + RunE: func(cmd *cobra.Command, args []string) error { + engine, err := imageengine.NewImageEngine(options.EngineGlobalConfigurations{}) + if err != nil { + return err + } + return engine.Load(loadOpts) + }, + } loadOpts = &options.LoadOptions{} flags := loadCmd.Flags() flags.StringVarP(&loadOpts.Input, "input", "i", "", "Load image from file") @@ -51,5 +50,5 @@ func init() { logrus.Errorf("failed to init flag: %v", err) os.Exit(1) } - rootCmd.AddCommand(loadCmd) + return loadCmd } diff --git a/cmd/sealer/cmd/login.go b/cmd/sealer/cmd/image/login.go similarity index 75% rename from cmd/sealer/cmd/login.go rename to cmd/sealer/cmd/image/login.go index 15bbd971c19..34492e4a4ce 100644 --- a/cmd/sealer/cmd/login.go +++ b/cmd/sealer/cmd/image/login.go @@ -12,7 +12,7 @@ // See the License for the specific language governing permissions and // limitations under the License. -package cmd +package image import ( "os" @@ -26,32 +26,29 @@ import ( var loginConfig *options.LoginOptions -var loginCmd = &cobra.Command{ - Use: "login", - Short: "login image registry", - // TODO: add long description. - Long: "", - Example: `sealer login registry.cn-qingdao.aliyuncs.com -u [username] -p [password]`, - Args: cobra.ExactArgs(1), - RunE: func(cmd *cobra.Command, args []string) error { - adaptor, err := imageengine.NewImageEngine(options.EngineGlobalConfigurations{}) - if err != nil { - return err - } - loginConfig.Domain = args[0] - - return adaptor.Login(loginConfig) - }, -} - -func init() { +func NewLoginCmd() *cobra.Command { + loginCmd := &cobra.Command{ + Use: "login", + Short: "login image registry", + // TODO: add long description. + Long: "", + Example: `sealer login registry.cn-qingdao.aliyuncs.com -u [username] -p [password]`, + Args: cobra.ExactArgs(1), + RunE: func(cmd *cobra.Command, args []string) error { + adaptor, err := imageengine.NewImageEngine(options.EngineGlobalConfigurations{}) + if err != nil { + return err + } + loginConfig.Domain = args[0] + + return adaptor.Login(loginConfig) + }, + } loginConfig = &options.LoginOptions{} - rootCmd.AddCommand(loginCmd) loginCmd.Flags().StringVarP(&loginConfig.Username, "username", "u", "", "user name for login registry") loginCmd.Flags().StringVarP(&loginConfig.Password, "passwd", "p", "", "password for login registry") loginCmd.Flags().StringVar(&loginConfig.AuthFile, "authfile", auth.GetDefaultAuthFilePath(), "path to store auth file after login. It will be $HOME/.sealer/auth.json by default.") loginCmd.Flags().BoolVar(&loginConfig.TLSVerify, "tls-verify", true, "require HTTPS and verify certificates when accessing the registry. TLS verification cannot be used when talking to an insecure registry.") - if err := loginCmd.MarkFlagRequired("username"); err != nil { logrus.Errorf("failed to init flag: %v", err) os.Exit(1) @@ -60,4 +57,5 @@ func init() { logrus.Errorf("failed to init flag: %v", err) os.Exit(1) } + return loginCmd } diff --git a/cmd/sealer/cmd/logout.go b/cmd/sealer/cmd/image/logout.go similarity index 65% rename from cmd/sealer/cmd/logout.go rename to cmd/sealer/cmd/image/logout.go index 3b2d5807172..b7c7754de28 100644 --- a/cmd/sealer/cmd/logout.go +++ b/cmd/sealer/cmd/image/logout.go @@ -12,7 +12,7 @@ // See the License for the specific language governing permissions and // limitations under the License. -package cmd +package image import ( "github.com/sealerio/sealer/pkg/auth" @@ -23,26 +23,25 @@ import ( var logoutConfig *options.LogoutOptions -var logoutCmd = &cobra.Command{ - Use: "logout", - Short: "logout from image registry", - // TODO: add long description. - Long: "", - Example: `sealer logout registry.cn-qingdao.aliyuncs.com`, - Args: cobra.ExactArgs(1), - RunE: func(cmd *cobra.Command, args []string) error { - adaptor, err := imageengine.NewImageEngine(options.EngineGlobalConfigurations{}) - if err != nil { - return err - } - logoutConfig.Domain = args[0] +func NewLogoutCmd() *cobra.Command { + logoutCmd := &cobra.Command{ + Use: "logout", + Short: "logout from image registry", + // TODO: add long description. + Long: "", + Example: `sealer logout registry.cn-qingdao.aliyuncs.com`, + Args: cobra.ExactArgs(1), + RunE: func(cmd *cobra.Command, args []string) error { + adaptor, err := imageengine.NewImageEngine(options.EngineGlobalConfigurations{}) + if err != nil { + return err + } + logoutConfig.Domain = args[0] - return adaptor.Logout(logoutConfig) - }, -} - -func init() { + return adaptor.Logout(logoutConfig) + }, + } logoutConfig = &options.LogoutOptions{} - rootCmd.AddCommand(logoutCmd) logoutCmd.Flags().StringVar(&logoutConfig.Authfile, "authfile", auth.GetDefaultAuthFilePath(), "path to store auth file after login. It will be $HOME/.sealer/auth.json by default.") + return logoutCmd } diff --git a/cmd/sealer/cmd/pull.go b/cmd/sealer/cmd/image/pull.go similarity index 74% rename from cmd/sealer/cmd/pull.go rename to cmd/sealer/cmd/image/pull.go index 3c1fa435c99..2554e314c66 100644 --- a/cmd/sealer/cmd/pull.go +++ b/cmd/sealer/cmd/image/pull.go @@ -12,7 +12,7 @@ // See the License for the specific language governing permissions and // limitations under the License. -package cmd +package image import ( "github.com/containers/buildah/pkg/parse" @@ -24,32 +24,31 @@ import ( var pullOpts *options.PullOptions -// pullCmd represents the pull command -var pullCmd = &cobra.Command{ - Use: "pull", - Short: "pull ClusterImage from a registry to local", - Example: `sealer pull registry.cn-qingdao.aliyuncs.com/sealer-io/kubernetes:v1.19.8 +var exampleForPullCmd = `sealer pull registry.cn-qingdao.aliyuncs.com/sealer-io/kubernetes:v1.19.8 sealer pull registry.cn-qingdao.aliyuncs.com/sealer-io/kubernetes:v1.19.8 --platform linux/amd64 -`, - Args: cobra.ExactArgs(1), - RunE: func(cmd *cobra.Command, args []string) error { - engine, err := imageengine.NewImageEngine(options.EngineGlobalConfigurations{}) - if err != nil { - return err - } - pullOpts.Image = args[0] - return engine.Pull(pullOpts) - }, -} +` -func init() { +// NewPullCmd pullCmd represents the pull command +func NewPullCmd() *cobra.Command { + pullCmd := &cobra.Command{ + Use: "pull", + Short: "pull ClusterImage from a registry to local", + Example: exampleForPullCmd, + Args: cobra.ExactArgs(1), + RunE: func(cmd *cobra.Command, args []string) error { + engine, err := imageengine.NewImageEngine(options.EngineGlobalConfigurations{}) + if err != nil { + return err + } + pullOpts.Image = args[0] + return engine.Pull(pullOpts) + }, + } pullOpts = &options.PullOptions{} - pullCmd.Flags().StringVar(&pullOpts.Platform, "platform", parse.DefaultPlatform(), "prefer OS/ARCH instead of the current operating system and architecture for choosing images") pullCmd.Flags().StringVar(&pullOpts.Authfile, "authfile", pkgauth.GetDefaultAuthFilePath(), "path of the authentication file. Use REGISTRY_AUTH_FILE environment variable to override") pullCmd.Flags().BoolVar(&pullOpts.TLSVerify, "tls-verify", true, "require HTTPS and verify certificates when accessing the registry. TLS verification cannot be used when talking to an insecure registry.") pullCmd.Flags().StringVar(&pullOpts.PullPolicy, "policy", "missing", "missing, always, or never.") pullCmd.Flags().BoolVarP(&pullOpts.Quiet, "quiet", "q", false, "don't output progress information when pulling images") - - rootCmd.AddCommand(pullCmd) + return pullCmd } diff --git a/cmd/sealer/cmd/push.go b/cmd/sealer/cmd/image/push.go similarity index 68% rename from cmd/sealer/cmd/push.go rename to cmd/sealer/cmd/image/push.go index 7c47b6a51c1..895386d68f6 100644 --- a/cmd/sealer/cmd/push.go +++ b/cmd/sealer/cmd/image/push.go @@ -12,7 +12,7 @@ // See the License for the specific language governing permissions and // limitations under the License. -package cmd +package image import ( "github.com/sealerio/sealer/pkg/auth" @@ -23,30 +23,28 @@ import ( var pushOpts *options.PushOptions -// pushCmd represents the push command -var pushCmd = &cobra.Command{ - Use: "push", - Short: "push ClusterImage to remote registry", - // TODO: add long description. - Long: "", - Example: `sealer push registry.cn-qingdao.aliyuncs.com/sealer-io/my-kubernetes-cluster-with-dashboard:latest`, - Args: cobra.ExactArgs(1), - RunE: func(cmd *cobra.Command, args []string) error { - adaptor, err := imageengine.NewImageEngine(options.EngineGlobalConfigurations{}) - if err != nil { - return err - } - pushOpts.Image = args[0] - return adaptor.Push(pushOpts) - }, -} - -func init() { +// NewPushCmd pushCmd represents the push command +func NewPushCmd() *cobra.Command { + pushCmd := &cobra.Command{ + Use: "push", + Short: "push ClusterImage to remote registry", + // TODO: add long description. + Long: "", + Example: `sealer push registry.cn-qingdao.aliyuncs.com/sealer-io/my-kubernetes-cluster-with-dashboard:latest`, + Args: cobra.ExactArgs(1), + RunE: func(cmd *cobra.Command, args []string) error { + adaptor, err := imageengine.NewImageEngine(options.EngineGlobalConfigurations{}) + if err != nil { + return err + } + pushOpts.Image = args[0] + return adaptor.Push(pushOpts) + }, + } pushOpts = &options.PushOptions{} - pushCmd.Flags().StringVar(&pushOpts.Authfile, "authfile", auth.GetDefaultAuthFilePath(), "path to store auth file after login. Accessing registry with this auth.") // tls-verify is not working currently pushCmd.Flags().BoolVar(&pushOpts.TLSVerify, "tls-verify", true, "require HTTPS and verify certificates when accessing the registry. TLS verification cannot be used when talking to an insecure registry. (not work currently)") pushCmd.Flags().BoolVarP(&pushOpts.Quiet, "quiet", "q", false, "don't output progress information when pushing images") - rootCmd.AddCommand(pushCmd) + return pushCmd } diff --git a/cmd/sealer/cmd/rmi.go b/cmd/sealer/cmd/image/rmi.go similarity index 75% rename from cmd/sealer/cmd/rmi.go rename to cmd/sealer/cmd/image/rmi.go index 08c8a4fac3c..994da65ef90 100644 --- a/cmd/sealer/cmd/rmi.go +++ b/cmd/sealer/cmd/image/rmi.go @@ -12,7 +12,7 @@ // See the License for the specific language governing permissions and // limitations under the License. -package cmd +package image import ( "github.com/sealerio/sealer/pkg/define/options" @@ -22,17 +22,25 @@ import ( var removeOpts *options.RemoveImageOptions -// rmiCmd represents the rmi command -var rmiCmd = &cobra.Command{ - Use: "rmi", - Short: "remove local images by name", - // TODO: add long description. - Long: "", - Example: `sealer rmi registry.cn-qingdao.aliyuncs.com/sealer-io/kubernetes:v1.19.8`, - Args: cobra.MinimumNArgs(1), - RunE: func(cmd *cobra.Command, args []string) error { - return runRemove(args) - }, +// NewRmiCmd rmiCmd represents the rmi command +func NewRmiCmd() *cobra.Command { + rmiCmd := &cobra.Command{ + Use: "rmi", + Short: "remove local images by name", + // TODO: add long description. + Long: "", + Example: `sealer rmi registry.cn-qingdao.aliyuncs.com/sealer-io/kubernetes:v1.19.8`, + Args: cobra.MinimumNArgs(1), + RunE: func(cmd *cobra.Command, args []string) error { + return runRemove(args) + }, + } + removeOpts = &options.RemoveImageOptions{} + flags := rmiCmd.Flags() + flags.BoolVarP(&removeOpts.All, "all", "a", false, "remove all images") + flags.BoolVarP(&removeOpts.Prune, "prune", "p", false, "prune dangling images") + flags.BoolVarP(&removeOpts.Force, "force", "f", false, "force removal of the image and any containers using the image") + return rmiCmd } func runRemove(images []string) error { @@ -44,12 +52,3 @@ func runRemove(images []string) error { return engine.RemoveImage(removeOpts) } - -func init() { - removeOpts = &options.RemoveImageOptions{} - flags := rmiCmd.Flags() - flags.BoolVarP(&removeOpts.All, "all", "a", false, "remove all images") - flags.BoolVarP(&removeOpts.Prune, "prune", "p", false, "prune dangling images") - flags.BoolVarP(&removeOpts.Force, "force", "f", false, "force removal of the image and any containers using the image") - rootCmd.AddCommand(rmiCmd) -} diff --git a/cmd/sealer/cmd/save.go b/cmd/sealer/cmd/image/save.go similarity index 71% rename from cmd/sealer/cmd/save.go rename to cmd/sealer/cmd/image/save.go index 9b12fc87ec2..7a6ff63c7e0 100644 --- a/cmd/sealer/cmd/save.go +++ b/cmd/sealer/cmd/image/save.go @@ -12,7 +12,7 @@ // See the License for the specific language governing permissions and // limitations under the License. -package cmd +package image import ( "github.com/sealerio/sealer/pkg/define/options" @@ -27,38 +27,38 @@ import ( var saveOpts *options.SaveOptions -// saveCmd represents the save command -var saveCmd = &cobra.Command{ - Use: "save", - Short: "save ClusterImage to a tar file", - Long: `sealer save -o [output file name] [image name]`, - Example: ` +var exampleForSaveCmd = ` save kubernetes:v1.19.8 image to kubernetes.tar file: -sealer save -o kubernetes.tar kubernetes:v1.19.8`, - Args: cobra.ExactArgs(1), - RunE: func(cmd *cobra.Command, args []string) error { - engine, err := imageengine.NewImageEngine(options.EngineGlobalConfigurations{}) - if err != nil { - return err - } - saveOpts.ImageNameOrID = args[0] - return engine.Save(saveOpts) - }, -} +sealer save -o kubernetes.tar kubernetes:v1.19.8` -func init() { +// NewSaveCmd saveCmd represents the save command +func NewSaveCmd() *cobra.Command { + saveCmd := &cobra.Command{ + Use: "save", + Short: "save ClusterImage to a tar file", + Long: `sealer save -o [output file name] [image name]`, + Example: exampleForSaveCmd, + Args: cobra.ExactArgs(1), + RunE: func(cmd *cobra.Command, args []string) error { + engine, err := imageengine.NewImageEngine(options.EngineGlobalConfigurations{}) + if err != nil { + return err + } + saveOpts.ImageNameOrID = args[0] + return engine.Save(saveOpts) + }, + } saveOpts = &options.SaveOptions{} flags := saveCmd.Flags() flags.StringVar(&saveOpts.Format, "format", buildah.V2s2Archive, "Save image to oci-archive, oci-dir (directory with oci manifest type), docker-archive, docker-dir (directory with v2s2 manifest type)") flags.StringVarP(&saveOpts.Output, "output", "o", "", "Write image to a specified file") flags.BoolVarP(&saveOpts.Quiet, "quiet", "q", false, "Suppress the output") flags.BoolVar(&saveOpts.Compress, "compress", false, "Compress tarball image layers when saving to a directory using the 'dir' transport. (default is same compression type as source)") - if err := saveCmd.MarkFlagRequired("output"); err != nil { logrus.Errorf("failed to init flag: %v", err) os.Exit(1) } - rootCmd.AddCommand(saveCmd) + return saveCmd } diff --git a/cmd/sealer/cmd/image/search.go b/cmd/sealer/cmd/image/search.go new file mode 100644 index 00000000000..27eda046678 --- /dev/null +++ b/cmd/sealer/cmd/image/search.go @@ -0,0 +1,82 @@ +// Copyright © 2021 Alibaba Group Holding Ltd. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package image + +import ( + "context" + "fmt" + + "github.com/sealerio/sealer/common" + "github.com/sealerio/sealer/pkg/image/reference" + save2 "github.com/sealerio/sealer/pkg/image/save" + + reference2 "github.com/distribution/distribution/v3/reference" + "github.com/olekukonko/tablewriter" + "github.com/spf13/cobra" +) + +const ( + imageName = "IMAGE NAME" +) + +var exampleForSearchCmd = `sealer search // ... +## default imageDomain: 'registry.cn-qingdao.aliyuncs.com', default imageRepo: 'sealer-io' +ex.: + sealer search kubernetes seadent/rootfs docker.io/library/hello-world +` + +// NewSearchCmd searchCmd represents the search command +func NewSearchCmd() *cobra.Command { + searchCmd := &cobra.Command{ + Use: "search", + Short: "search ClusterImage in default registry", + // TODO: add long description. + Long: "", + Example: exampleForSearchCmd, + Args: cobra.MinimumNArgs(1), + RunE: func(cmd *cobra.Command, args []string) error { + table := tablewriter.NewWriter(common.StdOut) + table.SetHeader([]string{imageName, "version"}) + for _, imgName := range args { + named, err := reference.ParseToNamed(imgName) + if err != nil { + return err + } + ns, err := save2.NewProxyRegistry(context.Background(), "", named.Domain()) + if err != nil { + return err + } + rNamed, err := reference2.WithName(named.Repo()) + if err != nil { + return fmt.Errorf("failed to get repository name: %v", err) + } + repo, err := ns.Repository(context.Background(), rNamed) + if err != nil { + return err + } + tags, err := repo.Tags(context.Background()).All(context.Background()) + if err != nil { + return err + } + for _, tag := range tags { + table.Append([]string{named.String(), tag}) + } + } + table.Render() + return nil + }, + } + return searchCmd +} diff --git a/cmd/sealer/cmd/tag.go b/cmd/sealer/cmd/image/tag.go similarity index 56% rename from cmd/sealer/cmd/tag.go rename to cmd/sealer/cmd/image/tag.go index 6adff90b496..cfda2f2a291 100644 --- a/cmd/sealer/cmd/tag.go +++ b/cmd/sealer/cmd/image/tag.go @@ -12,7 +12,7 @@ // See the License for the specific language governing permissions and // limitations under the License. -package cmd +package image import ( "github.com/sealerio/sealer/pkg/define/options" @@ -20,25 +20,24 @@ import ( "github.com/spf13/cobra" ) -var tagCmd = &cobra.Command{ - Use: "tag", - Short: "create one or more tags for local ClusterImage", - Example: `sealer tag kubernetes:v1.19.8 firstName secondName`, - Args: cobra.MinimumNArgs(2), - RunE: func(cmd *cobra.Command, args []string) error { - tagOpts := options.TagOptions{ - ImageNameOrID: args[0], - Tags: args[1:], - } +func NewTagCmd() *cobra.Command { + tagCmd := &cobra.Command{ + Use: "tag", + Short: "create one or more tags for local ClusterImage", + Example: `sealer tag kubernetes:v1.19.8 firstName secondName`, + Args: cobra.MinimumNArgs(2), + RunE: func(cmd *cobra.Command, args []string) error { + tagOpts := options.TagOptions{ + ImageNameOrID: args[0], + Tags: args[1:], + } - engine, err := imageengine.NewImageEngine(options.EngineGlobalConfigurations{}) - if err != nil { - return err - } - return engine.Tag(&tagOpts) - }, -} - -func init() { - rootCmd.AddCommand(tagCmd) + engine, err := imageengine.NewImageEngine(options.EngineGlobalConfigurations{}) + if err != nil { + return err + } + return engine.Tag(&tagOpts) + }, + } + return tagCmd } diff --git a/cmd/sealer/cmd/root.go b/cmd/sealer/cmd/root.go index 8f9404eaa7e..2c922e77a95 100644 --- a/cmd/sealer/cmd/root.go +++ b/cmd/sealer/cmd/root.go @@ -19,6 +19,9 @@ import ( "os" "path/filepath" + "github.com/sealerio/sealer/cmd/sealer/cmd/cluster" + "github.com/sealerio/sealer/cmd/sealer/cmd/image" + "github.com/sealerio/sealer/cmd/sealer/cmd/alpha" "github.com/sealerio/sealer/pkg/logger" @@ -48,6 +51,11 @@ const ( colorModeAlways = "always" ) +var longRootCmdDescription = `sealer is a tool to seal application's all dependencies and Kubernetes +into ClusterImage by Kubefile, distribute this application anywhere via ClusterImage, +and run it within any cluster with Clusterfile in one command. +` + var supportedColorModes = []string{ colorModeNever, colorModeAlways, @@ -55,12 +63,9 @@ var supportedColorModes = []string{ // rootCmd represents the base command when called without any subcommands var rootCmd = &cobra.Command{ - Use: "sealer", - Short: "A tool to build, share and run any distributed applications.", - Long: `sealer is a tool to seal application's all dependencies and Kubernetes -into ClusterImage by Kubefile, distribute this application anywhere via ClusterImage, -and run it within any cluster with Clusterfile in one command. -`, + Use: "sealer", + Short: "A tool to build, share and run any distributed applications.", + Long: longRootCmdDescription, SilenceUsage: true, SilenceErrors: true, } @@ -77,7 +82,10 @@ func Execute() { func init() { cobra.OnInitialize(initConfig) - rootCmd.AddCommand(alpha.NewCmdAlpha()) + rootCmd.AddCommand(alpha.NewCmdAlpha(), image.NewCmdImage(), NewCompletionCmd(), NewVersionCmd(), + cluster.NewApplyCmd(), cluster.NewCheckCmd(), cluster.NewDeleteCmd(), cluster.NewJoinCmd(), cluster.NewRunCmd(), + image.NewBuildCmd(), image.NewGenDocCommand(), image.NewListCmd(), image.NewInspectCmd(), image.NewLoadCmd(), image.NewLoginCmd(), + image.NewLogoutCmd(), image.NewPullCmd(), image.NewPushCmd(), image.NewRmiCmd(), image.NewSaveCmd(), image.NewSearchCmd(), image.NewTagCmd()) rootCmd.PersistentFlags().StringVar(&rootOpt.cfgFile, "config", "", "config file of sealer tool (default is $HOME/.sealer.json)") rootCmd.PersistentFlags().BoolVarP(&rootOpt.debugModeOn, "debug", "d", false, "turn on debug mode") diff --git a/cmd/sealer/cmd/search.go b/cmd/sealer/cmd/search.go deleted file mode 100644 index f08d8b552b1..00000000000 --- a/cmd/sealer/cmd/search.go +++ /dev/null @@ -1,82 +0,0 @@ -// Copyright © 2021 Alibaba Group Holding Ltd. -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -package cmd - -import ( - "context" - "fmt" - - "github.com/sealerio/sealer/common" - "github.com/sealerio/sealer/pkg/image/reference" - save2 "github.com/sealerio/sealer/pkg/image/save" - - reference2 "github.com/distribution/distribution/v3/reference" - "github.com/olekukonko/tablewriter" - "github.com/spf13/cobra" -) - -const ( - imageName = "IMAGE NAME" -) - -// searchCmd represents the search command -var searchCmd = &cobra.Command{ - Use: "search", - Short: "search ClusterImage in default registry", - // TODO: add long description. - Long: "", - Example: `sealer search // ... -## default imageDomain: 'registry.cn-qingdao.aliyuncs.com', default imageRepo: 'sealer-io' -ex.: - sealer search kubernetes seadent/rootfs docker.io/library/hello-world -`, - Args: cobra.MinimumNArgs(1), - RunE: func(cmd *cobra.Command, args []string) error { - - table := tablewriter.NewWriter(common.StdOut) - table.SetHeader([]string{imageName, "version"}) - for _, imgName := range args { - named, err := reference.ParseToNamed(imgName) - if err != nil { - return err - } - ns, err := save2.NewProxyRegistry(context.Background(), "", named.Domain()) - if err != nil { - return err - } - rNamed, err := reference2.WithName(named.Repo()) - if err != nil { - return fmt.Errorf("failed to get repository name: %v", err) - } - repo, err := ns.Repository(context.Background(), rNamed) - if err != nil { - return err - } - tags, err := repo.Tags(context.Background()).All(context.Background()) - if err != nil { - return err - } - for _, tag := range tags { - table.Append([]string{named.String(), tag}) - } - } - table.Render() - return nil - }, -} - -func init() { - rootCmd.AddCommand(searchCmd) -} diff --git a/cmd/sealer/cmd/version.go b/cmd/sealer/cmd/version.go index 97271f059d4..d22c8701657 100644 --- a/cmd/sealer/cmd/version.go +++ b/cmd/sealer/cmd/version.go @@ -25,27 +25,25 @@ import ( var shortPrint bool -var versionCmd = &cobra.Command{ - Use: "version", - Short: "show sealer and related versions", - Args: cobra.NoArgs, - Example: `sealer version`, - RunE: func(cmd *cobra.Command, args []string) error { - marshalled, err := json.Marshal(version.Get()) - if err != nil { - return err - } - if shortPrint { - fmt.Println(version.Get().String()) - } else { - fmt.Println(string(marshalled)) - } - return nil - - }, -} - -func init() { - rootCmd.AddCommand(versionCmd) +func NewVersionCmd() *cobra.Command { + versionCmd := &cobra.Command{ + Use: "version", + Short: "show sealer and related versions", + Args: cobra.NoArgs, + Example: `sealer version`, + RunE: func(cmd *cobra.Command, args []string) error { + marshalled, err := json.Marshal(version.Get()) + if err != nil { + return err + } + if shortPrint { + fmt.Println(version.Get().String()) + } else { + fmt.Println(string(marshalled)) + } + return nil + }, + } versionCmd.Flags().BoolVar(&shortPrint, "short", false, "if true, print sealer's own version number.") + return versionCmd } From 56bda0fb026afcb5b37d03bf9adcdb4fed7d7196 Mon Sep 17 00:00:00 2001 From: wangfei Date: Thu, 1 Sep 2022 10:26:24 +0800 Subject: [PATCH 2/6] Delete undefined functions --- cmd/sealer/cmd/root.go | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/cmd/sealer/cmd/root.go b/cmd/sealer/cmd/root.go index 2c922e77a95..b982bb65db2 100644 --- a/cmd/sealer/cmd/root.go +++ b/cmd/sealer/cmd/root.go @@ -82,11 +82,10 @@ func Execute() { func init() { cobra.OnInitialize(initConfig) - rootCmd.AddCommand(alpha.NewCmdAlpha(), image.NewCmdImage(), NewCompletionCmd(), NewVersionCmd(), + rootCmd.AddCommand(alpha.NewCmdAlpha(), NewCompletionCmd(), NewVersionCmd(), cluster.NewApplyCmd(), cluster.NewCheckCmd(), cluster.NewDeleteCmd(), cluster.NewJoinCmd(), cluster.NewRunCmd(), image.NewBuildCmd(), image.NewGenDocCommand(), image.NewListCmd(), image.NewInspectCmd(), image.NewLoadCmd(), image.NewLoginCmd(), image.NewLogoutCmd(), image.NewPullCmd(), image.NewPushCmd(), image.NewRmiCmd(), image.NewSaveCmd(), image.NewSearchCmd(), image.NewTagCmd()) - rootCmd.PersistentFlags().StringVar(&rootOpt.cfgFile, "config", "", "config file of sealer tool (default is $HOME/.sealer.json)") rootCmd.PersistentFlags().BoolVarP(&rootOpt.debugModeOn, "debug", "d", false, "turn on debug mode") rootCmd.PersistentFlags().BoolVarP(&rootCmd.SilenceUsage, "quiet", "q", false, "silence the usage when fail") From 895d897867194ebffc7d0adb514d9cf473f372e9 Mon Sep 17 00:00:00 2001 From: wangfei Date: Thu, 1 Sep 2022 10:49:11 +0800 Subject: [PATCH 3/6] Add cluster and image methods --- cmd/sealer/cmd/cluster/cluster.go | 27 ++++++++++++++++++++++++ cmd/sealer/cmd/image/image.go | 35 +++++++++++++++++++++++++++++++ cmd/sealer/cmd/root.go | 5 +---- 3 files changed, 63 insertions(+), 4 deletions(-) create mode 100644 cmd/sealer/cmd/cluster/cluster.go create mode 100644 cmd/sealer/cmd/image/image.go diff --git a/cmd/sealer/cmd/cluster/cluster.go b/cmd/sealer/cmd/cluster/cluster.go new file mode 100644 index 00000000000..e922fbfe371 --- /dev/null +++ b/cmd/sealer/cmd/cluster/cluster.go @@ -0,0 +1,27 @@ +// Copyright © 2021 Alibaba Group Holding Ltd. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package cluster + +import "github.com/spf13/cobra" + +func NewCmdCluster() *cobra.Command { + cmd := &cobra.Command{} + cmd.AddCommand(NewApplyCmd()) + cmd.AddCommand(NewCheckCmd()) + cmd.AddCommand(NewDeleteCmd()) + cmd.AddCommand(NewJoinCmd()) + cmd.AddCommand(NewRunCmd()) + return cmd +} diff --git a/cmd/sealer/cmd/image/image.go b/cmd/sealer/cmd/image/image.go new file mode 100644 index 00000000000..ed7cc48492f --- /dev/null +++ b/cmd/sealer/cmd/image/image.go @@ -0,0 +1,35 @@ +// Copyright © 2021 Alibaba Group Holding Ltd. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package image + +import "github.com/spf13/cobra" + +func NewCmdImage() *cobra.Command { + cmd := &cobra.Command{} + cmd.AddCommand(NewBuildCmd()) + cmd.AddCommand(NewGenDocCommand()) + cmd.AddCommand(NewListCmd()) + cmd.AddCommand(NewInspectCmd()) + cmd.AddCommand(NewLoadCmd()) + cmd.AddCommand(NewLoginCmd()) + cmd.AddCommand(NewLogoutCmd()) + cmd.AddCommand(NewPullCmd()) + cmd.AddCommand(NewPushCmd()) + cmd.AddCommand(NewRmiCmd()) + cmd.AddCommand(NewSaveCmd()) + cmd.AddCommand(NewSearchCmd()) + cmd.AddCommand(NewTagCmd()) + return cmd +} diff --git a/cmd/sealer/cmd/root.go b/cmd/sealer/cmd/root.go index b982bb65db2..b76f338cf3a 100644 --- a/cmd/sealer/cmd/root.go +++ b/cmd/sealer/cmd/root.go @@ -82,10 +82,7 @@ func Execute() { func init() { cobra.OnInitialize(initConfig) - rootCmd.AddCommand(alpha.NewCmdAlpha(), NewCompletionCmd(), NewVersionCmd(), - cluster.NewApplyCmd(), cluster.NewCheckCmd(), cluster.NewDeleteCmd(), cluster.NewJoinCmd(), cluster.NewRunCmd(), - image.NewBuildCmd(), image.NewGenDocCommand(), image.NewListCmd(), image.NewInspectCmd(), image.NewLoadCmd(), image.NewLoginCmd(), - image.NewLogoutCmd(), image.NewPullCmd(), image.NewPushCmd(), image.NewRmiCmd(), image.NewSaveCmd(), image.NewSearchCmd(), image.NewTagCmd()) + rootCmd.AddCommand(alpha.NewCmdAlpha(), cluster.NewCmdCluster(), image.NewCmdImage(), NewCompletionCmd(), NewVersionCmd()) rootCmd.PersistentFlags().StringVar(&rootOpt.cfgFile, "config", "", "config file of sealer tool (default is $HOME/.sealer.json)") rootCmd.PersistentFlags().BoolVarP(&rootOpt.debugModeOn, "debug", "d", false, "turn on debug mode") rootCmd.PersistentFlags().BoolVarP(&rootCmd.SilenceUsage, "quiet", "q", false, "silence the usage when fail") From 2ef9e30e842dddb05d4b43e877c6547fa4997d68 Mon Sep 17 00:00:00 2001 From: wangfei Date: Fri, 2 Sep 2022 10:55:33 +0800 Subject: [PATCH 4/6] Modify the cmd return method --- cmd/sealer/cmd/cluster/cluster.go | 12 ++++-------- cmd/sealer/cmd/{image => }/gen_doc.go | 2 +- cmd/sealer/cmd/image/image.go | 25 ++++++++----------------- cmd/sealer/cmd/root.go | 5 ++++- 4 files changed, 17 insertions(+), 27 deletions(-) rename cmd/sealer/cmd/{image => }/gen_doc.go (99%) diff --git a/cmd/sealer/cmd/cluster/cluster.go b/cmd/sealer/cmd/cluster/cluster.go index e922fbfe371..8b36d5c7439 100644 --- a/cmd/sealer/cmd/cluster/cluster.go +++ b/cmd/sealer/cmd/cluster/cluster.go @@ -16,12 +16,8 @@ package cluster import "github.com/spf13/cobra" -func NewCmdCluster() *cobra.Command { - cmd := &cobra.Command{} - cmd.AddCommand(NewApplyCmd()) - cmd.AddCommand(NewCheckCmd()) - cmd.AddCommand(NewDeleteCmd()) - cmd.AddCommand(NewJoinCmd()) - cmd.AddCommand(NewRunCmd()) - return cmd +func NewClusterCommands() []*cobra.Command { + var clusterCommands []*cobra.Command + clusterCommands = append(clusterCommands, NewApplyCmd(), NewCheckCmd(), NewDeleteCmd(), NewJoinCmd(), NewRunCmd()) + return clusterCommands } diff --git a/cmd/sealer/cmd/image/gen_doc.go b/cmd/sealer/cmd/gen_doc.go similarity index 99% rename from cmd/sealer/cmd/image/gen_doc.go rename to cmd/sealer/cmd/gen_doc.go index 3d1a6090b5d..b7be5b52580 100644 --- a/cmd/sealer/cmd/image/gen_doc.go +++ b/cmd/sealer/cmd/gen_doc.go @@ -12,7 +12,7 @@ // See the License for the specific language governing permissions and // limitations under the License. -package image +package cmd import ( "fmt" diff --git a/cmd/sealer/cmd/image/image.go b/cmd/sealer/cmd/image/image.go index ed7cc48492f..2d4679e522b 100644 --- a/cmd/sealer/cmd/image/image.go +++ b/cmd/sealer/cmd/image/image.go @@ -14,22 +14,13 @@ package image -import "github.com/spf13/cobra" +import ( + "github.com/spf13/cobra" +) -func NewCmdImage() *cobra.Command { - cmd := &cobra.Command{} - cmd.AddCommand(NewBuildCmd()) - cmd.AddCommand(NewGenDocCommand()) - cmd.AddCommand(NewListCmd()) - cmd.AddCommand(NewInspectCmd()) - cmd.AddCommand(NewLoadCmd()) - cmd.AddCommand(NewLoginCmd()) - cmd.AddCommand(NewLogoutCmd()) - cmd.AddCommand(NewPullCmd()) - cmd.AddCommand(NewPushCmd()) - cmd.AddCommand(NewRmiCmd()) - cmd.AddCommand(NewSaveCmd()) - cmd.AddCommand(NewSearchCmd()) - cmd.AddCommand(NewTagCmd()) - return cmd +func NewImageCommands() []*cobra.Command { + var imageCommands []*cobra.Command + imageCommands = append(imageCommands, NewBuildCmd(), NewListCmd(), NewInspectCmd(), NewLoadCmd(), + NewLoadCmd(), NewLoginCmd(), NewLogoutCmd(), NewPullCmd(), NewPushCmd(), NewRmiCmd(), NewSaveCmd(), NewSearchCmd(), NewTagCmd()) + return imageCommands } diff --git a/cmd/sealer/cmd/root.go b/cmd/sealer/cmd/root.go index b76f338cf3a..6e8d4f78cd8 100644 --- a/cmd/sealer/cmd/root.go +++ b/cmd/sealer/cmd/root.go @@ -82,7 +82,10 @@ func Execute() { func init() { cobra.OnInitialize(initConfig) - rootCmd.AddCommand(alpha.NewCmdAlpha(), cluster.NewCmdCluster(), image.NewCmdImage(), NewCompletionCmd(), NewVersionCmd()) + rootCmd.AddCommand(alpha.NewCmdAlpha(), NewCompletionCmd(), NewVersionCmd(), NewGenDocCommand()) + rootCmd.AddCommand(cluster.NewClusterCommands()...) + rootCmd.AddCommand(image.NewImageCommands()...) + rootCmd.PersistentFlags().StringVar(&rootOpt.cfgFile, "config", "", "config file of sealer tool (default is $HOME/.sealer.json)") rootCmd.PersistentFlags().BoolVarP(&rootOpt.debugModeOn, "debug", "d", false, "turn on debug mode") rootCmd.PersistentFlags().BoolVarP(&rootCmd.SilenceUsage, "quiet", "q", false, "silence the usage when fail") From 30480c6b24de2407105c704951389ee93ddf727f Mon Sep 17 00:00:00 2001 From: wangfei Date: Fri, 2 Sep 2022 14:58:30 +0800 Subject: [PATCH 5/6] Modify check example --- cmd/sealer/cmd/cluster/check.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cmd/sealer/cmd/cluster/check.go b/cmd/sealer/cmd/cluster/check.go index d2582b3f571..73f69c4420b 100644 --- a/cmd/sealer/cmd/cluster/check.go +++ b/cmd/sealer/cmd/cluster/check.go @@ -38,7 +38,7 @@ func NewCheckCmd() *cobra.Command { Use: "check", Short: "check the state of cluster", Long: longNewCheckCmdDescription, - Example: `sealer check --pre or sealer check --post`, + Example: `sealer check --pre \n sealer check --post`, Args: cobra.NoArgs, RunE: func(cmd *cobra.Command, args []string) error { if checkArgs.Pre && checkArgs.Post { From c82f90961e5f243eab2e056371901475a9f527fd Mon Sep 17 00:00:00 2001 From: wangfei Date: Fri, 2 Sep 2022 15:17:45 +0800 Subject: [PATCH 6/6] Modify check example --- cmd/sealer/cmd/cluster/check.go | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/cmd/sealer/cmd/cluster/check.go b/cmd/sealer/cmd/cluster/check.go index 73f69c4420b..86c7094f25c 100644 --- a/cmd/sealer/cmd/cluster/check.go +++ b/cmd/sealer/cmd/cluster/check.go @@ -35,11 +35,12 @@ var longNewCheckCmdDescription = `check command is used to check status of the c // NewCheckCmd pushCmd represents the push command func NewCheckCmd() *cobra.Command { checkCmd := &cobra.Command{ - Use: "check", - Short: "check the state of cluster", - Long: longNewCheckCmdDescription, - Example: `sealer check --pre \n sealer check --post`, - Args: cobra.NoArgs, + Use: "check", + Short: "check the state of cluster", + Long: longNewCheckCmdDescription, + Example: `sealer check --pre + sealer check --post`, + Args: cobra.NoArgs, RunE: func(cmd *cobra.Command, args []string) error { if checkArgs.Pre && checkArgs.Post { return fmt.Errorf("don't allow to set two flags --pre and --post")