-
Notifications
You must be signed in to change notification settings - Fork 362
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Optimize: move experimental cmd to alpha stage #1577
Changes from 2 commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,36 @@ | ||
// 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 alpha | ||
|
||
import ( | ||
"github.com/spf13/cobra" | ||
) | ||
|
||
// NewCmdAlpha returns "sealer alpha" command. | ||
func NewCmdAlpha() *cobra.Command { | ||
cmd := &cobra.Command{ | ||
Use: "alpha", | ||
Short: "Sealer experimental sub-commands", | ||
} | ||
|
||
cmd.AddCommand(NewPruneCmd()) | ||
cmd.AddCommand(NewDebugCmd()) | ||
cmd.AddCommand(NewExecCmd()) | ||
cmd.AddCommand(NewMergeCmd()) | ||
cmd.AddCommand(NewUpgradeCmd()) | ||
cmd.AddCommand(NewGenCmd()) | ||
cmd.AddCommand(NewCertCmd()) | ||
return cmd | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,73 @@ | ||
// 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 alpha | ||
|
||
import ( | ||
"fmt" | ||
|
||
"github.com/spf13/cobra" | ||
|
||
"github.com/sealerio/sealer/common" | ||
"github.com/sealerio/sealer/pkg/clusterfile" | ||
"github.com/sealerio/sealer/pkg/runtime" | ||
) | ||
|
||
var altNames []string | ||
|
||
var longCertCmdDescription = `Add domain or ip in certs: you had better backup old certs first. this command will update cluster API server cert, you need to restart your API server manually after using sealer cert. then, you can using cmd "openssl x509 -noout -text -in apiserver.crt" to check the cert details. | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Please make sure that first word of every sentence should be uppercase. It is minor mistake. But I think we should pay more attention to this minor cases. |
||
` | ||
|
||
var exampleForCertCmd = ` | ||
The following command will generate keys and CSRs for all control-plane certificates and kubeconfig files: | ||
|
||
sealer alpha cert --alt-names 39.105.169.253,sealer.cool | ||
` | ||
|
||
// NewCertCmd returns the sealer cert Cobra command | ||
func NewCertCmd() *cobra.Command { | ||
certCmd := &cobra.Command{ | ||
Use: "cert", | ||
Short: "Update Kubernetes API server's cert", | ||
Args: cobra.NoArgs, | ||
Long: longCertCmdDescription, | ||
Example: exampleForCertCmd, | ||
RunE: func(cmd *cobra.Command, args []string) error { | ||
if len(altNames) == 0 { | ||
return fmt.Errorf("ip address or DNS domain needed for cert Subject Alternative Names") | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. s/ip/IP/g, IP is a reserved word. While I think quite lot of people use ip, which is lowercase. And lowercase is incorrect. |
||
} | ||
|
||
cluster, err := clusterfile.GetDefaultCluster() | ||
if err != nil { | ||
return fmt.Errorf("failed to get default cluster: %v", err) | ||
} | ||
|
||
clusterFile, err := clusterfile.NewClusterFile(cluster.GetAnnotationsByKey(common.ClusterfileName)) | ||
if err != nil { | ||
return err | ||
} | ||
|
||
r, err := runtime.NewDefaultRuntime(cluster, clusterFile.GetKubeadmConfig()) | ||
if err != nil { | ||
return fmt.Errorf("failed to get default runtime: %v", err) | ||
} | ||
|
||
return r.UpdateCert(altNames) | ||
}, | ||
} | ||
|
||
certCmd.Flags().StringSliceVar(&altNames, "alt-names", []string{}, "add domain or ip in certs, sealer.cool or 10.103.97.2") | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Do we have a default domain name? If we have, we should add it explicitly in the flag description. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. yes, we have a default domain in the cert process builtin, i will add it explicitly in the flag description. |
||
|
||
return certCmd | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,158 @@ | ||
// 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 alpha | ||
|
||
import ( | ||
"fmt" | ||
|
||
"github.com/sealerio/sealer/common" | ||
"github.com/spf13/cobra" | ||
|
||
"github.com/sealerio/sealer/pkg/debug" | ||
) | ||
|
||
// NewDebugCmd returns the sealer debug Cobra command | ||
func NewDebugCmd() *cobra.Command { | ||
var debugOptions = debug.NewDebugOptions() | ||
|
||
var debugCommand = &cobra.Command{ | ||
Use: "debug", | ||
Short: "Create debugging sessions for pods and nodes", | ||
// TODO: add long description. | ||
Long: "", | ||
} | ||
|
||
debugCommand.AddCommand(newDebugCleanCMD()) | ||
debugCommand.AddCommand(newDebugShowImageCMD()) | ||
debugCommand.AddCommand(newDebugPodCommand(debugOptions)) | ||
debugCommand.AddCommand(newDebugNodeCommand(debugOptions)) | ||
|
||
debugCommand.PersistentFlags().StringVar(&debugOptions.Image, "image", debugOptions.Image, "Container image to use for debug container.") | ||
debugCommand.PersistentFlags().StringVar(&debugOptions.DebugContainerName, "name", debugOptions.DebugContainerName, "Container name to use for debug container.") | ||
debugCommand.PersistentFlags().StringVar(&debugOptions.PullPolicy, "image-pull-policy", "IfNotPresent", "Container image pull policy, default policy is IfNotPresent.") | ||
debugCommand.PersistentFlags().StringSliceVar(&debugOptions.CheckList, "check-list", debugOptions.CheckList, "Check items, such as network, volume.") | ||
debugCommand.PersistentFlags().StringVarP(&debugOptions.Namespace, "namespace", "n", "default", "Namespace of Pod.") | ||
debugCommand.PersistentFlags().BoolVarP(&debugOptions.Interactive, "stdin", "i", debugOptions.Interactive, "Keep stdin open on the container, even if nothing is attached.") | ||
debugCommand.PersistentFlags().BoolVarP(&debugOptions.TTY, "tty", "t", debugOptions.TTY, "Allocate a TTY for the debugging container.") | ||
debugCommand.PersistentFlags().StringToStringP("env", "e", nil, "Environment variables to set in the container.") | ||
|
||
return debugCommand | ||
} | ||
|
||
func newDebugCleanCMD() *cobra.Command { | ||
cleanCmd := &cobra.Command{ | ||
Use: "clean", | ||
Short: "Clean the debug container od pod", | ||
Args: cobra.ExactArgs(1), | ||
RunE: func(cmd *cobra.Command, args []string) error { | ||
cleaner := debug.NewDebugCleaner() | ||
cleaner.AdminKubeConfigPath = common.KubeAdminConf | ||
|
||
if err := cleaner.CompleteAndVerifyOptions(args); err != nil { | ||
return err | ||
} | ||
if err := cleaner.Run(); err != nil { | ||
return err | ||
} | ||
|
||
return nil | ||
}, | ||
} | ||
|
||
return cleanCmd | ||
} | ||
|
||
func newDebugShowImageCMD() *cobra.Command { | ||
showCmd := &cobra.Command{ | ||
Use: "show-images", | ||
Short: "List default images", | ||
Args: cobra.NoArgs, | ||
RunE: func(cmd *cobra.Command, args []string) error { | ||
manager := debug.NewDebugImagesManager() | ||
manager.RegistryURL = debug.DefaultSealerRegistryURL | ||
|
||
if err := manager.ShowDefaultImages(); err != nil { | ||
return err | ||
} | ||
return nil | ||
}, | ||
} | ||
|
||
return showCmd | ||
} | ||
|
||
func newDebugPodCommand(options *debug.DebuggerOptions) *cobra.Command { | ||
cmd := &cobra.Command{ | ||
Use: "pod", | ||
Short: "Debug pod or container", | ||
Args: cobra.MinimumNArgs(1), | ||
RunE: func(cmd *cobra.Command, args []string) error { | ||
debugger := debug.NewDebugger(options) | ||
debugger.AdminKubeConfigPath = common.KubeAdminConf | ||
debugger.Type = debug.TypeDebugPod | ||
debugger.Motd = debug.SealerDebugMotd | ||
|
||
imager := debug.NewDebugImagesManager() | ||
|
||
if err := debugger.CompleteAndVerifyOptions(cmd, args, imager); err != nil { | ||
return err | ||
} | ||
str, err := debugger.Run() | ||
if err != nil { | ||
return err | ||
} | ||
if len(str) != 0 { | ||
fmt.Println("The debug ID:", str) | ||
} | ||
|
||
return nil | ||
}, | ||
} | ||
|
||
cmd.Flags().StringVarP(&options.TargetContainer, "container", "c", "", "The container to be debugged.") | ||
|
||
return cmd | ||
} | ||
|
||
func newDebugNodeCommand(options *debug.DebuggerOptions) *cobra.Command { | ||
cmd := &cobra.Command{ | ||
Use: "node", | ||
Short: "Debug node", | ||
Args: cobra.MinimumNArgs(1), | ||
RunE: func(cmd *cobra.Command, args []string) error { | ||
debugger := debug.NewDebugger(options) | ||
debugger.AdminKubeConfigPath = common.KubeAdminConf | ||
debugger.Type = debug.TypeDebugNode | ||
debugger.Motd = debug.SealerDebugMotd | ||
|
||
imager := debug.NewDebugImagesManager() | ||
|
||
if err := debugger.CompleteAndVerifyOptions(cmd, args, imager); err != nil { | ||
return err | ||
} | ||
str, err := debugger.Run() | ||
if err != nil { | ||
return err | ||
} | ||
if len(str) != 0 { | ||
fmt.Println("The debug ID:", str) | ||
} | ||
|
||
return nil | ||
}, | ||
} | ||
|
||
return cmd | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,102 @@ | ||
// 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 alpha | ||
|
||
import ( | ||
"fmt" | ||
"net" | ||
|
||
"github.com/sealerio/sealer/common" | ||
"github.com/sealerio/sealer/pkg/clusterfile" | ||
"github.com/sealerio/sealer/pkg/exec" | ||
v2 "github.com/sealerio/sealer/types/api/v2" | ||
|
||
"github.com/spf13/cobra" | ||
) | ||
|
||
var ( | ||
clusterName string | ||
roles []string | ||
) | ||
|
||
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" | ||
|
||
specify the cluster name: | ||
sealer alpha exec -c my-cluster "cat /etc/hosts" | ||
|
||
using role label to filter node and run exec cmd: | ||
sealer alpha exec -c my-cluster -r master,slave,node1 "cat /etc/hosts" | ||
` | ||
|
||
// NewExecCmd implement the sealer exec command | ||
func NewExecCmd() *cobra.Command { | ||
execCmd := &cobra.Command{ | ||
Use: "exec", | ||
Short: "Exec a shell command or script on a specified node", | ||
Long: longExecCmdDescription, | ||
Example: exampleForExecCmd, | ||
Args: cobra.ExactArgs(1), | ||
RunE: execActionFunc, | ||
} | ||
|
||
execCmd.Flags().StringVarP(&clusterName, "cluster-name", "c", "", "specify the name of cluster") | ||
execCmd.Flags().StringSliceVarP(&roles, "roles", "r", []string{}, "set role label to filter node") | ||
|
||
return execCmd | ||
} | ||
|
||
func execActionFunc(cmd *cobra.Command, args []string) error { | ||
var ipList []net.IP | ||
|
||
cluster, err := GetCurrentClusterByName(clusterName) | ||
if err != nil { | ||
return err | ||
} | ||
|
||
if len(roles) == 0 { | ||
ipList = append(cluster.GetMasterIPList(), cluster.GetNodeIPList()...) | ||
} else { | ||
for _, role := range roles { | ||
ipList = append(ipList, cluster.GetIPSByRole(role)...) | ||
} | ||
if len(ipList) == 0 { | ||
return fmt.Errorf("failed to get target ipList by roles label %s", roles) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. should add the detailed failure reason:
|
||
} | ||
} | ||
|
||
execCmd := exec.NewExecCmd(cluster, ipList) | ||
return execCmd.RunCmd(args[0]) | ||
} | ||
|
||
func GetCurrentClusterByName(name string) (*v2.Cluster, error) { | ||
var err error | ||
if name == "" { | ||
name, err = clusterfile.GetDefaultClusterName() | ||
if err != nil { | ||
return nil, fmt.Errorf("failed to get default cluster name from home dir: %v", err) | ||
} | ||
} | ||
|
||
cluster, err := clusterfile.GetClusterFromFile(common.GetClusterWorkClusterfile(name)) | ||
if err != nil { | ||
return nil, err | ||
} | ||
|
||
return cluster, nil | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Please add a long field to add more description of
sealer alpha
command. This is very useful for end users. Thanks. And do not make sealer uppercase. sealer is a reserved word, then it has no uppercase mode, just like etcd. sealer and etcd both have a lowercase first letter.There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
alpha
command has sub command which has their own long description. i am ok with adding long description onalpha
command, but seems like there is very little to describe.There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
😄, we should explain to help end-users to understand what is alpha command for. Please take the following paragraph into consideration.
alpha command of sealer is used to provide functionality incubation from immature to mature. Each function will experience a growing procedure. Alpha command policy calls on end users to experience alpha functionality as early as possible, and actively feedback the experience results to sealer community, and finally cooperate to promote function from incubation to graduation. Please file an issue at https://github.com/sealerio/sealer/issues when you have any feedback on alpha commands.