-
Notifications
You must be signed in to change notification settings - Fork 362
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Optimize: move experimental cmd to alpha stage (#1577)
* optimize:move cmd to alpha * move cmd to alpha * update reviews * update reviews
- Loading branch information
1 parent
a9919aa
commit 08df4e0
Showing
20 changed files
with
614 additions
and
548 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,41 @@ | ||
// 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" | ||
) | ||
|
||
var longAlphaCmdDescription = `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.` | ||
|
||
// NewCmdAlpha returns "sealer alpha" command. | ||
func NewCmdAlpha() *cobra.Command { | ||
cmd := &cobra.Command{ | ||
Use: "alpha", | ||
Short: "sealer experimental sub-commands", | ||
Long: longAlphaCmdDescription, | ||
} | ||
|
||
cmd.AddCommand(NewPruneCmd()) | ||
cmd.AddCommand(NewDebugCmd()) | ||
cmd.AddCommand(NewExecCmd()) | ||
cmd.AddCommand(NewMergeCmd()) | ||
cmd.AddCommand(NewUpgradeCmd()) | ||
cmd.AddCommand(NewGenCmd()) | ||
cmd.AddCommand(NewCertCmd()) | ||
return cmd | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,77 @@ | ||
// 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 = `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 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") | ||
} | ||
|
||
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 DNS domain or IP in certs, if it is already in the cert subject alternative names list, nothing will be changed") | ||
|
||
return certCmd | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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 | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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: no IP gotten by role(%s)", roles) | ||
} | ||
} | ||
|
||
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 | ||
} |
Oops, something went wrong.