Added some ctl boilerplate

This commit is contained in:
2026-03-27 18:34:53 +08:00
parent bf85462e34
commit 87aa1d4b0b
30 changed files with 1813 additions and 19 deletions

View File

@@ -0,0 +1,51 @@
package agent
import (
"context"
"fmt"
"time"
monov1alpha1 "undecided.project/monok8s/pkg/apis/monok8s/v1alpha1"
"undecided.project/monok8s/pkg/kube"
"github.com/spf13/cobra"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/runtime/schema"
"k8s.io/cli-runtime/pkg/genericclioptions"
"k8s.io/klog/v2"
)
func NewCmdAgent(flags *genericclioptions.ConfigFlags) *cobra.Command {
var namespace string
cmd := &cobra.Command{
Use: "agent",
Short: "Watch OSUpgrade resources and do nothing for now",
RunE: func(cmd *cobra.Command, _ []string) error {
clients, err := kube.NewClients(flags)
if err != nil {
return err
}
gvr := schema.GroupVersionResource{Group: monov1alpha1.Group, Version: monov1alpha1.Version, Resource: "osupgrades"}
ctx := cmd.Context()
for {
list, err := clients.Dynamic.Resource(gvr).Namespace(namespace).List(ctx, metav1.ListOptions{})
if err != nil {
return err
}
klog.InfoS("agent tick", "namespace", namespace, "items", len(list.Items))
for _, item := range list.Items {
klog.InfoS("observed osupgrade", "name", item.GetName(), "resourceVersion", item.GetResourceVersion())
}
select {
case <-ctx.Done():
return ctx.Err()
case <-time.After(15 * time.Second):
}
}
},
}
cmd.Flags().StringVar(&namespace, "namespace", "kube-system", "namespace to watch")
return cmd
}
var _ = context.Background
var _ = fmt.Sprintf

View File

@@ -0,0 +1,54 @@
package apply
import (
"context"
"fmt"
"undecided.project/monok8s/pkg/crds"
"undecided.project/monok8s/pkg/kube"
"github.com/spf13/cobra"
apiextensionsv1 "k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1"
apierrors "k8s.io/apimachinery/pkg/api/errors"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/cli-runtime/pkg/genericclioptions"
"k8s.io/klog/v2"
)
func NewCmdApply(flags *genericclioptions.ConfigFlags) *cobra.Command {
cmd := &cobra.Command{Use: "apply", Short: "Apply MonoK8s resources"}
cmd.AddCommand(newCmdApplyCRDs(flags))
return cmd
}
func newCmdApplyCRDs(flags *genericclioptions.ConfigFlags) *cobra.Command {
return &cobra.Command{
Use: "crds",
Short: "Register the MonoKSConfig and OSUpgrade CRDs",
RunE: func(cmd *cobra.Command, _ []string) error {
clients, err := kube.NewClients(flags)
if err != nil {
return err
}
ctx := context.Background()
for _, wanted := range crds.Definitions() {
_, err := clients.APIExtensions.ApiextensionsV1().CustomResourceDefinitions().Create(ctx, wanted, metav1.CreateOptions{})
if apierrors.IsAlreadyExists(err) {
current, getErr := clients.APIExtensions.ApiextensionsV1().CustomResourceDefinitions().Get(ctx, wanted.Name, metav1.GetOptions{})
if getErr != nil {
return getErr
}
wanted.ResourceVersion = current.ResourceVersion
_, err = clients.APIExtensions.ApiextensionsV1().CustomResourceDefinitions().Update(ctx, wanted, metav1.UpdateOptions{})
}
if err != nil {
return err
}
klog.InfoS("crd applied", "name", wanted.Name)
}
_, _ = fmt.Fprintln(cmd.OutOrStdout(), "CRDs applied")
return nil
},
}
}
var _ *apiextensionsv1.CustomResourceDefinition

View File

@@ -0,0 +1,30 @@
package checkconfig
import (
"fmt"
"undecided.project/monok8s/pkg/config"
"github.com/spf13/cobra"
)
func NewCmdCheckConfig() *cobra.Command {
var configPath string
cmd := &cobra.Command{
Use: "checkconfig",
Short: "Validate a MonoKSConfig",
RunE: func(cmd *cobra.Command, _ []string) error {
path, err := (config.Loader{}).ResolvePath(configPath)
if err != nil {
return err
}
cfg, err := (config.Loader{}).Load(path)
if err != nil {
return err
}
fmt.Fprintf(cmd.OutOrStdout(), "OK: %s (%s / %s)\n", path, cfg.Spec.NodeName, cfg.Spec.KubernetesVersion)
return nil
},
}
cmd.Flags().StringVarP(&configPath, "config", "c", "", "path to MonoKSConfig yaml")
return cmd
}

View File

@@ -0,0 +1,31 @@
package create
import (
"fmt"
"undecided.project/monok8s/pkg/templates"
"github.com/spf13/cobra"
)
func NewCmdCreate() *cobra.Command {
cmd := &cobra.Command{Use: "create", Short: "Create starter resources"}
cmd.AddCommand(
&cobra.Command{
Use: "config",
Short: "Print a MonoKSConfig template",
RunE: func(cmd *cobra.Command, _ []string) error {
_, err := fmt.Fprint(cmd.OutOrStdout(), templates.MonoKSConfigYAML)
return err
},
},
&cobra.Command{
Use: "osupgrade",
Short: "Print an OSUpgrade template",
RunE: func(cmd *cobra.Command, _ []string) error {
_, err := fmt.Fprint(cmd.OutOrStdout(), templates.OSUpgradeYAML)
return err
},
},
)
return cmd
}

View File

@@ -0,0 +1,34 @@
package initcmd
import (
"context"
"undecided.project/monok8s/pkg/bootstrap"
"undecided.project/monok8s/pkg/config"
"github.com/spf13/cobra"
"k8s.io/cli-runtime/pkg/genericclioptions"
"k8s.io/klog/v2"
)
func NewCmdInit(_ *genericclioptions.ConfigFlags) *cobra.Command {
var configPath string
cmd := &cobra.Command{
Use: "init",
Short: "Equivalent of apply-node-config + bootstrap-cluster",
RunE: func(cmd *cobra.Command, _ []string) error {
path, err := (config.Loader{}).ResolvePath(configPath)
if err != nil {
return err
}
cfg, err := (config.Loader{}).Load(path)
if err != nil {
return err
}
klog.InfoS("starting init", "config", path, "node", cfg.Spec.NodeName)
return bootstrap.NewRunner(cfg).Init(cmd.Context())
},
}
cmd.Flags().StringVarP(&configPath, "config", "c", "", "path to MonoKSConfig yaml")
_ = context.Background()
return cmd
}

View File

@@ -0,0 +1,30 @@
package internal
import (
"undecided.project/monok8s/pkg/bootstrap"
"undecided.project/monok8s/pkg/config"
"github.com/spf13/cobra"
)
func NewCmdInternal() *cobra.Command {
var configPath string
cmd := &cobra.Command{Use: "internal", Hidden: true}
cmd.AddCommand(&cobra.Command{
Use: "run-step STEP",
Short: "Run one internal step for testing",
Args: cobra.ExactArgs(1),
RunE: func(cmd *cobra.Command, args []string) error {
path, err := (config.Loader{}).ResolvePath(configPath)
if err != nil {
return err
}
cfg, err := (config.Loader{}).Load(path)
if err != nil {
return err
}
return bootstrap.NewRunner(cfg).RunNamedStep(cmd.Context(), args[0])
},
})
cmd.PersistentFlags().StringVarP(&configPath, "config", "c", "", "path to MonoKSConfig yaml")
return cmd
}

View File

@@ -0,0 +1,41 @@
package root
import (
"flag"
agentcmd "undecided.project/monok8s/pkg/cmd/agent"
applycmd "undecided.project/monok8s/pkg/cmd/apply"
checkconfigcmd "undecided.project/monok8s/pkg/cmd/checkconfig"
createcmd "undecided.project/monok8s/pkg/cmd/create"
initcmd "undecided.project/monok8s/pkg/cmd/initcmd"
internalcmd "undecided.project/monok8s/pkg/cmd/internal"
"github.com/spf13/cobra"
"k8s.io/cli-runtime/pkg/genericclioptions"
"k8s.io/klog/v2"
)
func NewRootCmd() *cobra.Command {
flags := genericclioptions.NewConfigFlags(true)
cmd := &cobra.Command{
Use: "ctl",
Short: "MonoK8s control tool",
SilenceUsage: true,
SilenceErrors: true,
PersistentPreRun: func(*cobra.Command, []string) {
klog.InitFlags(nil)
_ = flag.Set("logtostderr", "true")
},
}
flags.AddFlags(cmd.PersistentFlags())
cmd.AddCommand(
initcmd.NewCmdInit(flags),
checkconfigcmd.NewCmdCheckConfig(),
createcmd.NewCmdCreate(),
applycmd.NewCmdApply(flags),
agentcmd.NewCmdAgent(flags),
internalcmd.NewCmdInternal(),
)
return cmd
}