/* * Copyright 2024 the KubeSphere Authors. * Please refer to the LICENSE file in the root directory of the project. * https://github.com/kubesphere/kubesphere/blob/master/LICENSE */ package app import ( "context" "errors" "fmt" "net/http" "github.com/google/gops/agent" "github.com/spf13/cobra" utilerrors "k8s.io/apimachinery/pkg/util/errors" cliflag "k8s.io/component-base/cli/flag" "k8s.io/klog/v2" "sigs.k8s.io/controller-runtime/pkg/manager/signals" "kubesphere.io/kubesphere/cmd/ks-apiserver/app/options" "kubesphere.io/kubesphere/pkg/config" "kubesphere.io/kubesphere/pkg/constants" "kubesphere.io/kubesphere/pkg/utils/term" "kubesphere.io/kubesphere/pkg/version" ) func NewAPIServerCommand() *cobra.Command { s := options.NewAPIServerOptions() if conf, err := config.TryLoadFromDisk(); err == nil { s.Merge(conf) } else { klog.Fatalf("Failed to load configuration from disk: %v", err) } cmd := &cobra.Command{ Use: constants.KubeSphereAPIServerName, Long: `The KubeSphere API server validates and configures data for the API objects. The API Server services REST operations and provides the frontend to the cluster's shared state through which all other components interact.`, RunE: func(cmd *cobra.Command, args []string) error { if errs := s.Validate(); len(errs) != 0 { return utilerrors.NewAggregate(errs) } if s.DebugMode { // Add agent to report additional information such as the current stack trace, Go version, memory stats, etc. // Bind to a random port on address 127.0.0.1. if err := agent.Listen(agent.Options{}); err != nil { klog.Fatalln(err) } } return Run(signals.SetupSignalHandler(), s) }, SilenceUsage: true, } fs := cmd.Flags() namedFlagSets := s.Flags() for _, f := range namedFlagSets.FlagSets { fs.AddFlagSet(f) } usageFmt := "Usage:\n %s\n" cols, _, _ := term.TerminalSize(cmd.OutOrStdout()) cmd.SetHelpFunc(func(cmd *cobra.Command, args []string) { _, _ = fmt.Fprintf(cmd.OutOrStdout(), "%s\n\n"+usageFmt, cmd.Long, cmd.UseLine()) cliflag.PrintSections(cmd.OutOrStdout(), namedFlagSets, cols) }) versionCmd := &cobra.Command{ Use: "version", Short: "Print the version of KubeSphere ks-apiserver", Run: func(cmd *cobra.Command, args []string) { cmd.Println(version.Get()) }, } cmd.AddCommand(versionCmd) return cmd } func Run(ctx context.Context, s *options.APIServerOptions) error { apiServer, err := s.NewAPIServer(ctx) if err != nil { return err } if err = apiServer.PrepareRun(ctx.Done()); err != nil { return err } if errors.Is(apiServer.Run(ctx), http.ErrServerClosed) { return nil } return err }