Matches ctl version to upstream
This commit is contained in:
1
.gitignore
vendored
1
.gitignore
vendored
@@ -1,4 +1,5 @@
|
|||||||
clitools/bin
|
clitools/bin
|
||||||
packages/
|
packages/
|
||||||
out/
|
out/
|
||||||
|
*_gen.go
|
||||||
*.swp
|
*.swp
|
||||||
|
|||||||
@@ -11,5 +11,3 @@ rc-update add fancontrol boot
|
|||||||
rc-update add loopback boot
|
rc-update add loopback boot
|
||||||
rc-update add hostname boot
|
rc-update add hostname boot
|
||||||
rc-update add localmount boot
|
rc-update add localmount boot
|
||||||
rc-update add apply-node-config default
|
|
||||||
rc-update add bootstrap-cluster default
|
|
||||||
|
|||||||
28
clitools/README
Normal file
28
clitools/README
Normal file
@@ -0,0 +1,28 @@
|
|||||||
|
## For development workflow
|
||||||
|
|
||||||
|
Run this on device
|
||||||
|
```bash
|
||||||
|
while true; do nc -l -p 1234 -e sh; done
|
||||||
|
```
|
||||||
|
|
||||||
|
Run this script on the dev machine
|
||||||
|
```bash
|
||||||
|
#!/bin/bash
|
||||||
|
make build
|
||||||
|
|
||||||
|
SIZE=$(wc -c < ./bin/ctl-linux-aarch64-dev)
|
||||||
|
|
||||||
|
(
|
||||||
|
echo 'base64 -d > /var/ctl <<'"'"'EOF'"'"''
|
||||||
|
pv -s "$SIZE" < ./bin/ctl-linux-aarch64-dev | base64
|
||||||
|
echo 'EOF'
|
||||||
|
echo 'chmod +x /var/ctl'
|
||||||
|
echo '/var/ctl create config > /var/abc.yaml'
|
||||||
|
echo "/var/ctl internal run-step $1 -c /var/abc.yaml 2>&1"
|
||||||
|
) | nc 10.0.0.10 1234
|
||||||
|
```
|
||||||
|
|
||||||
|
And use it like this
|
||||||
|
```bash
|
||||||
|
./send.sh start_crio
|
||||||
|
```
|
||||||
@@ -1,11 +1,22 @@
|
|||||||
VERSION ?= dev
|
VERSION ?= dev
|
||||||
|
|
||||||
|
KUBE_VERSION=v1.35.1
|
||||||
|
|
||||||
BIN_DIR := bin
|
BIN_DIR := bin
|
||||||
|
|
||||||
build:
|
BUILDINFO_FILE := pkg/buildinfo/buildinfo_gen.go
|
||||||
|
|
||||||
|
$(BUILDINFO_FILE):
|
||||||
|
echo 'package buildinfo' > $@
|
||||||
|
echo '' >> $@
|
||||||
|
echo 'const DefaultKubernetesVersion = "$(KUBE_VERSION)"' >> $@
|
||||||
|
|
||||||
|
build: $(BUILDINFO_FILE)
|
||||||
mkdir -p $(BIN_DIR)
|
mkdir -p $(BIN_DIR)
|
||||||
GOOS=linux GOARCH=arm64 go build -o $(BIN_DIR)/ctl-linux-aarch64-$(VERSION) ./cmd/ctl/
|
GOOS=linux GOARCH=arm64 go build -o $(BIN_DIR)/ctl-linux-aarch64-$(VERSION) ./cmd/ctl/
|
||||||
# go build -o $(BIN_DIR)/ctl-$(VERSION) ./cmd/ctl
|
|
||||||
|
build-local:
|
||||||
|
go build -o $(BIN_DIR)/ctl-$(VERSION) ./cmd/ctl
|
||||||
|
|
||||||
run:
|
run:
|
||||||
go run ./cmd/ctl
|
go run ./cmd/ctl
|
||||||
|
|||||||
@@ -21,7 +21,7 @@ type MonoKSConfig struct {
|
|||||||
metav1.TypeMeta `json:",inline" yaml:",inline"`
|
metav1.TypeMeta `json:",inline" yaml:",inline"`
|
||||||
metav1.ObjectMeta `json:"metadata,omitempty" yaml:"metadata,omitempty"`
|
metav1.ObjectMeta `json:"metadata,omitempty" yaml:"metadata,omitempty"`
|
||||||
Spec MonoKSConfigSpec `json:"spec,omitempty" yaml:"spec,omitempty"`
|
Spec MonoKSConfigSpec `json:"spec,omitempty" yaml:"spec,omitempty"`
|
||||||
Status MonoKSConfigStatus `json:"status,omitempty" yaml:"status,omitempty"`
|
Status *MonoKSConfigStatus `json:"status,omitempty" yaml:"status,omitempty"`
|
||||||
}
|
}
|
||||||
|
|
||||||
type MonoKSConfigList struct {
|
type MonoKSConfigList struct {
|
||||||
@@ -35,13 +35,13 @@ type MonoKSConfigSpec struct {
|
|||||||
NodeName string `json:"nodeName,omitempty" yaml:"nodeName,omitempty"`
|
NodeName string `json:"nodeName,omitempty" yaml:"nodeName,omitempty"`
|
||||||
ClusterName string `json:"clusterName,omitempty" yaml:"clusterName,omitempty"`
|
ClusterName string `json:"clusterName,omitempty" yaml:"clusterName,omitempty"`
|
||||||
ClusterDomain string `json:"clusterDomain,omitempty" yaml:"clusterDomain,omitempty"`
|
ClusterDomain string `json:"clusterDomain,omitempty" yaml:"clusterDomain,omitempty"`
|
||||||
|
ClusterRole string `json:"clusterRole,omitempty" yaml:"clusterRole,omitempty"`
|
||||||
|
InitControlPlane bool `json:"initControlPlane,omitempty" yaml:"initControlPlane,omitempty"`
|
||||||
PodSubnet string `json:"podSubnet,omitempty" yaml:"podSubnet,omitempty"`
|
PodSubnet string `json:"podSubnet,omitempty" yaml:"podSubnet,omitempty"`
|
||||||
ServiceSubnet string `json:"serviceSubnet,omitempty" yaml:"serviceSubnet,omitempty"`
|
ServiceSubnet string `json:"serviceSubnet,omitempty" yaml:"serviceSubnet,omitempty"`
|
||||||
APIServerAdvertiseAddress string `json:"apiServerAdvertiseAddress,omitempty" yaml:"apiServerAdvertiseAddress,omitempty"`
|
APIServerAdvertiseAddress string `json:"apiServerAdvertiseAddress,omitempty" yaml:"apiServerAdvertiseAddress,omitempty"`
|
||||||
APIServerEndpoint string `json:"apiServerEndpoint,omitempty" yaml:"apiServerEndpoint,omitempty"`
|
APIServerEndpoint string `json:"apiServerEndpoint,omitempty" yaml:"apiServerEndpoint,omitempty"`
|
||||||
ContainerRuntimeEndpoint string `json:"containerRuntimeEndpoint,omitempty" yaml:"containerRuntimeEndpoint,omitempty"`
|
ContainerRuntimeEndpoint string `json:"containerRuntimeEndpoint,omitempty" yaml:"containerRuntimeEndpoint,omitempty"`
|
||||||
BootstrapMode string `json:"bootstrapMode,omitempty" yaml:"bootstrapMode,omitempty"`
|
|
||||||
JoinKind string `json:"joinKind,omitempty" yaml:"joinKind,omitempty"`
|
|
||||||
BootstrapToken string `json:"bootstrapToken,omitempty" yaml:"bootstrapToken,omitempty"`
|
BootstrapToken string `json:"bootstrapToken,omitempty" yaml:"bootstrapToken,omitempty"`
|
||||||
DiscoveryTokenCACertHash string `json:"discoveryTokenCACertHash,omitempty" yaml:"discoveryTokenCACertHash,omitempty"`
|
DiscoveryTokenCACertHash string `json:"discoveryTokenCACertHash,omitempty" yaml:"discoveryTokenCACertHash,omitempty"`
|
||||||
ControlPlaneCertKey string `json:"controlPlaneCertKey,omitempty" yaml:"controlPlaneCertKey,omitempty"`
|
ControlPlaneCertKey string `json:"controlPlaneCertKey,omitempty" yaml:"controlPlaneCertKey,omitempty"`
|
||||||
@@ -75,7 +75,7 @@ type OSUpgrade struct {
|
|||||||
metav1.TypeMeta `json:",inline" yaml:",inline"`
|
metav1.TypeMeta `json:",inline" yaml:",inline"`
|
||||||
metav1.ObjectMeta `json:"metadata,omitempty" yaml:"metadata,omitempty"`
|
metav1.ObjectMeta `json:"metadata,omitempty" yaml:"metadata,omitempty"`
|
||||||
Spec OSUpgradeSpec `json:"spec,omitempty" yaml:"spec,omitempty"`
|
Spec OSUpgradeSpec `json:"spec,omitempty" yaml:"spec,omitempty"`
|
||||||
Status OSUpgradeStatus `json:"status,omitempty" yaml:"status,omitempty"`
|
Status *OSUpgradeStatus `json:"status,omitempty" yaml:"status,omitempty"`
|
||||||
}
|
}
|
||||||
|
|
||||||
type OSUpgradeList struct {
|
type OSUpgradeList struct {
|
||||||
|
|||||||
@@ -12,6 +12,7 @@ type Registry struct {
|
|||||||
|
|
||||||
func NewRegistry(ctx *node.NodeContext) *Registry {
|
func NewRegistry(ctx *node.NodeContext) *Registry {
|
||||||
netCfg := node.NetworkConfig{
|
netCfg := node.NetworkConfig{
|
||||||
|
Hostname: ctx.Config.Spec.Network.Hostname,
|
||||||
MgmtIface: ctx.Config.Spec.Network.ManagementIface,
|
MgmtIface: ctx.Config.Spec.Network.ManagementIface,
|
||||||
MgmtAddress: ctx.Config.Spec.Network.ManagementCIDR,
|
MgmtAddress: ctx.Config.Spec.Network.ManagementCIDR,
|
||||||
MgmtGateway: ctx.Config.Spec.Network.ManagementGW,
|
MgmtGateway: ctx.Config.Spec.Network.ManagementGW,
|
||||||
@@ -21,13 +22,10 @@ func NewRegistry(ctx *node.NodeContext) *Registry {
|
|||||||
|
|
||||||
return &Registry{
|
return &Registry{
|
||||||
steps: map[string]node.Step{
|
steps: map[string]node.Step{
|
||||||
"check_prereqs": node.CheckPrereqs,
|
|
||||||
"validate_network_requirements": node.ValidateNetworkRequirements,
|
"validate_network_requirements": node.ValidateNetworkRequirements,
|
||||||
"install_cni_if_requested": node.InstallCNIIfRequested,
|
"configure_default_cni": node.ConfigureDefaultCNI,
|
||||||
"start_crio": node.StartCRIO,
|
"start_crio": node.StartCRIO,
|
||||||
"check_crio_running": node.CheckCRIORunning,
|
|
||||||
"wait_for_existing_cluster_if_needed": node.WaitForExistingClusterIfNeeded,
|
"wait_for_existing_cluster_if_needed": node.WaitForExistingClusterIfNeeded,
|
||||||
"decide_bootstrap_action": node.DecideBootstrapAction,
|
|
||||||
"check_required_images": node.CheckRequiredImages,
|
"check_required_images": node.CheckRequiredImages,
|
||||||
"generate_kubeadm_config": node.GenerateKubeadmConfig,
|
"generate_kubeadm_config": node.GenerateKubeadmConfig,
|
||||||
"run_kubeadm_init": node.RunKubeadmInit,
|
"run_kubeadm_init": node.RunKubeadmInit,
|
||||||
@@ -35,6 +33,7 @@ func NewRegistry(ctx *node.NodeContext) *Registry {
|
|||||||
"apply_local_node_metadata_if_possible": node.ApplyLocalNodeMetadataIfPossible,
|
"apply_local_node_metadata_if_possible": node.ApplyLocalNodeMetadataIfPossible,
|
||||||
"allow_single_node_scheduling": node.AllowSingleNodeScheduling,
|
"allow_single_node_scheduling": node.AllowSingleNodeScheduling,
|
||||||
"ensure_ip_forward": node.EnsureIPForward,
|
"ensure_ip_forward": node.EnsureIPForward,
|
||||||
|
"configure_hostname": node.ConfigureHostname(netCfg),
|
||||||
"configure_mgmt_interface": node.ConfigureMgmtInterface(netCfg),
|
"configure_mgmt_interface": node.ConfigureMgmtInterface(netCfg),
|
||||||
"configure_dns": node.ConfigureDNS(netCfg),
|
"configure_dns": node.ConfigureDNS(netCfg),
|
||||||
"set_hostname_if_needed": node.SetHostnameIfNeeded,
|
"set_hostname_if_needed": node.SetHostnameIfNeeded,
|
||||||
|
|||||||
@@ -17,7 +17,7 @@ func NewRunner(cfg *monov1alpha1.MonoKSConfig) *Runner {
|
|||||||
runnerCfg := system.RunnerConfig{}
|
runnerCfg := system.RunnerConfig{}
|
||||||
nctx := &node.NodeContext{
|
nctx := &node.NodeContext{
|
||||||
Config: cfg,
|
Config: cfg,
|
||||||
System: system.NewRunner(runnerCfg),
|
SystemRunner: system.NewRunner(runnerCfg),
|
||||||
}
|
}
|
||||||
return &Runner{
|
return &Runner{
|
||||||
NodeCtx: nctx,
|
NodeCtx: nctx,
|
||||||
@@ -27,11 +27,13 @@ func NewRunner(cfg *monov1alpha1.MonoKSConfig) *Runner {
|
|||||||
|
|
||||||
func (r *Runner) Init(ctx context.Context) error {
|
func (r *Runner) Init(ctx context.Context) error {
|
||||||
for _, name := range []string{
|
for _, name := range []string{
|
||||||
"check_prereqs",
|
"configure_hostname",
|
||||||
|
"configure_dns",
|
||||||
|
"configure_mgmt_interface",
|
||||||
"validate_network_requirements",
|
"validate_network_requirements",
|
||||||
"install_cni_if_requested",
|
"configure_default_cni",
|
||||||
"start_crio",
|
"start_crio",
|
||||||
"check_crio_running",
|
"check_container_images",
|
||||||
"wait_for_existing_cluster_if_needed",
|
"wait_for_existing_cluster_if_needed",
|
||||||
"decide_bootstrap_action",
|
"decide_bootstrap_action",
|
||||||
"check_required_images",
|
"check_required_images",
|
||||||
|
|||||||
1
clitools/pkg/buildinfo/README
Normal file
1
clitools/pkg/buildinfo/README
Normal file
@@ -0,0 +1 @@
|
|||||||
|
Use `make build` to generate the files. Do not modify.
|
||||||
@@ -2,9 +2,9 @@ package create
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
|
|
||||||
"undecided.project/monok8s/pkg/templates"
|
|
||||||
"github.com/spf13/cobra"
|
"github.com/spf13/cobra"
|
||||||
|
|
||||||
|
render "undecided.project/monok8s/pkg/render"
|
||||||
)
|
)
|
||||||
|
|
||||||
func NewCmdCreate() *cobra.Command {
|
func NewCmdCreate() *cobra.Command {
|
||||||
@@ -14,7 +14,11 @@ func NewCmdCreate() *cobra.Command {
|
|||||||
Use: "config",
|
Use: "config",
|
||||||
Short: "Print a MonoKSConfig template",
|
Short: "Print a MonoKSConfig template",
|
||||||
RunE: func(cmd *cobra.Command, _ []string) error {
|
RunE: func(cmd *cobra.Command, _ []string) error {
|
||||||
_, err := fmt.Fprint(cmd.OutOrStdout(), templates.MonoKSConfigYAML)
|
out, err := render.RenderMonoKSConfig()
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
_, err = fmt.Fprint(cmd.OutOrStdout(), out)
|
||||||
return err
|
return err
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
@@ -22,7 +26,11 @@ func NewCmdCreate() *cobra.Command {
|
|||||||
Use: "osupgrade",
|
Use: "osupgrade",
|
||||||
Short: "Print an OSUpgrade template",
|
Short: "Print an OSUpgrade template",
|
||||||
RunE: func(cmd *cobra.Command, _ []string) error {
|
RunE: func(cmd *cobra.Command, _ []string) error {
|
||||||
_, err := fmt.Fprint(cmd.OutOrStdout(), templates.OSUpgradeYAML)
|
out, err := render.RenderOSUpgrade()
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
_, err = fmt.Fprint(cmd.OutOrStdout(), out)
|
||||||
return err
|
return err
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -3,15 +3,16 @@ package root
|
|||||||
import (
|
import (
|
||||||
"flag"
|
"flag"
|
||||||
|
|
||||||
|
"github.com/spf13/cobra"
|
||||||
|
"k8s.io/cli-runtime/pkg/genericclioptions"
|
||||||
|
"k8s.io/klog/v2"
|
||||||
agentcmd "undecided.project/monok8s/pkg/cmd/agent"
|
agentcmd "undecided.project/monok8s/pkg/cmd/agent"
|
||||||
applycmd "undecided.project/monok8s/pkg/cmd/apply"
|
applycmd "undecided.project/monok8s/pkg/cmd/apply"
|
||||||
checkconfigcmd "undecided.project/monok8s/pkg/cmd/checkconfig"
|
checkconfigcmd "undecided.project/monok8s/pkg/cmd/checkconfig"
|
||||||
createcmd "undecided.project/monok8s/pkg/cmd/create"
|
createcmd "undecided.project/monok8s/pkg/cmd/create"
|
||||||
initcmd "undecided.project/monok8s/pkg/cmd/initcmd"
|
initcmd "undecided.project/monok8s/pkg/cmd/initcmd"
|
||||||
internalcmd "undecided.project/monok8s/pkg/cmd/internal"
|
internalcmd "undecided.project/monok8s/pkg/cmd/internal"
|
||||||
"github.com/spf13/cobra"
|
versioncmd "undecided.project/monok8s/pkg/cmd/version"
|
||||||
"k8s.io/cli-runtime/pkg/genericclioptions"
|
|
||||||
"k8s.io/klog/v2"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
func NewRootCmd() *cobra.Command {
|
func NewRootCmd() *cobra.Command {
|
||||||
@@ -30,6 +31,7 @@ func NewRootCmd() *cobra.Command {
|
|||||||
|
|
||||||
flags.AddFlags(cmd.PersistentFlags())
|
flags.AddFlags(cmd.PersistentFlags())
|
||||||
cmd.AddCommand(
|
cmd.AddCommand(
|
||||||
|
versioncmd.NewCmdVersion(),
|
||||||
initcmd.NewCmdInit(flags),
|
initcmd.NewCmdInit(flags),
|
||||||
checkconfigcmd.NewCmdCheckConfig(),
|
checkconfigcmd.NewCmdCheckConfig(),
|
||||||
createcmd.NewCmdCreate(),
|
createcmd.NewCmdCreate(),
|
||||||
|
|||||||
22
clitools/pkg/cmd/version/version.go
Normal file
22
clitools/pkg/cmd/version/version.go
Normal file
@@ -0,0 +1,22 @@
|
|||||||
|
package apply
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
|
||||||
|
"github.com/spf13/cobra"
|
||||||
|
|
||||||
|
buildInfo "undecided.project/monok8s/pkg/buildinfo"
|
||||||
|
)
|
||||||
|
|
||||||
|
func NewCmdVersion() *cobra.Command {
|
||||||
|
cmd := &cobra.Command{
|
||||||
|
Use: "version",
|
||||||
|
Short: "Print the version information",
|
||||||
|
RunE: func(cmd *cobra.Command, _ []string) error {
|
||||||
|
|
||||||
|
_, err := fmt.Fprintln(cmd.OutOrStdout(), buildInfo.Version)
|
||||||
|
return err
|
||||||
|
},
|
||||||
|
}
|
||||||
|
return cmd
|
||||||
|
}
|
||||||
@@ -6,8 +6,8 @@ import (
|
|||||||
"os"
|
"os"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
monov1alpha1 "undecided.project/monok8s/pkg/apis/monok8s/v1alpha1"
|
|
||||||
"gopkg.in/yaml.v3"
|
"gopkg.in/yaml.v3"
|
||||||
|
monov1alpha1 "undecided.project/monok8s/pkg/apis/monok8s/v1alpha1"
|
||||||
)
|
)
|
||||||
|
|
||||||
const EnvVar = "MONOKSCONFIG"
|
const EnvVar = "MONOKSCONFIG"
|
||||||
@@ -62,11 +62,8 @@ func ApplyDefaults(cfg *monov1alpha1.MonoKSConfig) {
|
|||||||
if cfg.Spec.ContainerRuntimeEndpoint == "" {
|
if cfg.Spec.ContainerRuntimeEndpoint == "" {
|
||||||
cfg.Spec.ContainerRuntimeEndpoint = "unix:///var/run/crio/crio.sock"
|
cfg.Spec.ContainerRuntimeEndpoint = "unix:///var/run/crio/crio.sock"
|
||||||
}
|
}
|
||||||
if cfg.Spec.BootstrapMode == "" {
|
if cfg.Spec.ClusterRole == "" {
|
||||||
cfg.Spec.BootstrapMode = "init"
|
cfg.Spec.ClusterRole = "control-plane"
|
||||||
}
|
|
||||||
if cfg.Spec.JoinKind == "" {
|
|
||||||
cfg.Spec.JoinKind = "worker"
|
|
||||||
}
|
}
|
||||||
if cfg.Spec.CNIPlugin == "" {
|
if cfg.Spec.CNIPlugin == "" {
|
||||||
cfg.Spec.CNIPlugin = "none"
|
cfg.Spec.CNIPlugin = "none"
|
||||||
@@ -102,31 +99,27 @@ func Validate(cfg *monov1alpha1.MonoKSConfig) error {
|
|||||||
if !strings.Contains(cfg.Spec.Network.ManagementCIDR, "/") {
|
if !strings.Contains(cfg.Spec.Network.ManagementCIDR, "/") {
|
||||||
problems = append(problems, "spec.network.managementCIDR must include a CIDR prefix")
|
problems = append(problems, "spec.network.managementCIDR must include a CIDR prefix")
|
||||||
}
|
}
|
||||||
if cfg.Spec.BootstrapMode != "init" && cfg.Spec.BootstrapMode != "join" {
|
if cfg.Spec.ClusterRole != "control-plane" && cfg.Spec.ClusterRole != "worker" {
|
||||||
problems = append(problems, "spec.bootstrapMode must be init or join")
|
problems = append(problems, "spec.clusterRole can either be control-plane or worker")
|
||||||
}
|
|
||||||
if cfg.Spec.JoinKind != "worker" && cfg.Spec.JoinKind != "control-plane" {
|
|
||||||
problems = append(problems, "spec.joinKind must be worker or control-plane")
|
|
||||||
}
|
}
|
||||||
for _, ns := range cfg.Spec.Network.DNSNameservers {
|
for _, ns := range cfg.Spec.Network.DNSNameservers {
|
||||||
if ns == "10.96.0.10" {
|
if ns == "10.96.0.10" {
|
||||||
problems = append(problems, "spec.network.dnsNameservers must not include cluster DNS service IP 10.96.0.10")
|
problems = append(problems, "spec.network.dnsNameservers must not include cluster DNS service IP 10.96.0.10")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if cfg.Spec.BootstrapMode == "join" {
|
if cfg.Spec.ClusterRole == "worker" {
|
||||||
if cfg.Spec.APIServerEndpoint == "" {
|
if cfg.Spec.APIServerEndpoint == "" {
|
||||||
problems = append(problems, "spec.apiServerEndpoint is required for join mode")
|
problems = append(problems, "spec.apiServerEndpoint is required to join a cluster")
|
||||||
}
|
}
|
||||||
if cfg.Spec.BootstrapToken == "" {
|
if cfg.Spec.BootstrapToken == "" {
|
||||||
problems = append(problems, "spec.bootstrapToken is required for join mode")
|
problems = append(problems, "spec.bootstrapToken is required to join a cluster")
|
||||||
}
|
}
|
||||||
if cfg.Spec.DiscoveryTokenCACertHash == "" {
|
if cfg.Spec.DiscoveryTokenCACertHash == "" {
|
||||||
problems = append(problems, "spec.discoveryTokenCACertHash is required for join mode")
|
problems = append(problems, "spec.discoveryTokenCACertHash is required to join a cluster")
|
||||||
}
|
}
|
||||||
if cfg.Spec.JoinKind == "control-plane" && cfg.Spec.ControlPlaneCertKey == "" {
|
} else if !cfg.Spec.InitControlPlane && cfg.Spec.ControlPlaneCertKey == "" {
|
||||||
problems = append(problems, "spec.controlPlaneCertKey is required for control-plane join")
|
problems = append(problems, "spec.controlPlaneCertKey is required for control-plane join")
|
||||||
}
|
}
|
||||||
}
|
|
||||||
if len(problems) > 0 {
|
if len(problems) > 0 {
|
||||||
return errors.New(strings.Join(problems, "; "))
|
return errors.New(strings.Join(problems, "; "))
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -9,7 +9,7 @@ import (
|
|||||||
|
|
||||||
type NodeContext struct {
|
type NodeContext struct {
|
||||||
Config *monov1alpha1.MonoKSConfig
|
Config *monov1alpha1.MonoKSConfig
|
||||||
System *system.Runner
|
SystemRunner *system.Runner
|
||||||
}
|
}
|
||||||
|
|
||||||
type Step func(context.Context, *NodeContext) error
|
type Step func(context.Context, *NodeContext) error
|
||||||
|
|||||||
@@ -2,21 +2,61 @@ package node
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
|
"fmt"
|
||||||
|
"os"
|
||||||
|
"strings"
|
||||||
|
|
||||||
"k8s.io/klog/v2"
|
"k8s.io/klog/v2"
|
||||||
|
system "undecided.project/monok8s/pkg/system"
|
||||||
)
|
)
|
||||||
|
|
||||||
func InstallCNIIfRequested(context.Context, *NodeContext) error {
|
func ConfigureDefaultCNI(ctx context.Context, n *NodeContext) error {
|
||||||
klog.Info("install_cni_if_requested: TODO implement bridge/none CNI toggling")
|
_ = ctx
|
||||||
|
|
||||||
|
const (
|
||||||
|
cniDir = "/etc/cni/net.d"
|
||||||
|
enabledPath = cniDir + "/10-crio-bridge.conflist"
|
||||||
|
disabledPath = cniDir + "/10-crio-bridge.conflist.disabled"
|
||||||
|
)
|
||||||
|
|
||||||
|
plugin := strings.TrimSpace(n.Config.Spec.CNIPlugin)
|
||||||
|
|
||||||
|
switch plugin {
|
||||||
|
case "none":
|
||||||
|
// Fail hard if we cannot ensure the default bridge CNI is disabled.
|
||||||
|
if _, err := os.Stat(enabledPath); err == nil {
|
||||||
|
if err := os.Rename(enabledPath, disabledPath); err != nil {
|
||||||
|
return fmt.Errorf("disable default CRI-O bridge CNI: %w", err)
|
||||||
|
}
|
||||||
|
} else if !os.IsNotExist(err) {
|
||||||
|
return fmt.Errorf("stat %s: %w", enabledPath, err)
|
||||||
|
}
|
||||||
|
|
||||||
|
klog.Infof("Default CRI-O bridge CNI disabled")
|
||||||
|
return nil
|
||||||
|
|
||||||
|
case "bridge":
|
||||||
|
fallthrough
|
||||||
|
case "default":
|
||||||
|
// Fail soft. User can still install or provide their own CNI.
|
||||||
|
if _, err := os.Stat(disabledPath); err == nil {
|
||||||
|
if err := os.Rename(disabledPath, enabledPath); err != nil {
|
||||||
|
klog.Warningf("failed enabling default CRI-O bridge CNI: %v", err)
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
} else if !os.IsNotExist(err) {
|
||||||
|
klog.Warningf("failed stating %s while enabling default CRI-O bridge CNI: %v", disabledPath, err)
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
klog.Infof("Default CRI-O bridge CNI enabled")
|
||||||
|
return nil
|
||||||
|
|
||||||
|
}
|
||||||
|
klog.Infof("unsupported CNIPlugin: %q", plugin)
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func StartCRIO(context.Context, *NodeContext) error {
|
func StartCRIO(ctx context.Context, n *NodeContext) error {
|
||||||
klog.Info("start_crio: TODO implement rc-service crio start")
|
return system.EnsureServiceRunning(ctx, n.SystemRunner, "crio")
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func CheckCRIORunning(context.Context, *NodeContext) error {
|
|
||||||
klog.Info("check_crio_running: TODO implement crictl readiness checks")
|
|
||||||
return nil
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2,6 +2,8 @@ package node
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
|
"fmt"
|
||||||
|
"strings"
|
||||||
|
|
||||||
"k8s.io/klog/v2"
|
"k8s.io/klog/v2"
|
||||||
)
|
)
|
||||||
@@ -10,8 +12,57 @@ func WaitForExistingClusterIfNeeded(context.Context, *NodeContext) error {
|
|||||||
klog.Info("wait_for_existing_cluster_if_needed: TODO implement kubelet/admin.conf waits")
|
klog.Info("wait_for_existing_cluster_if_needed: TODO implement kubelet/admin.conf waits")
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
func CheckRequiredImages(context.Context, *NodeContext) error {
|
|
||||||
klog.Info("check_required_images: TODO implement kubeadm image list + crictl image presence")
|
func CheckRequiredImages(ctx context.Context, n *NodeContext) error {
|
||||||
|
if n.Config.Spec.SkipImageCheck {
|
||||||
|
klog.Infof("skipping image check (skipImageCheck=true)")
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
k8sVersion := strings.TrimSpace(n.Config.Spec.KubernetesVersion)
|
||||||
|
if k8sVersion == "" {
|
||||||
|
return fmt.Errorf("kubernetesVersion is required")
|
||||||
|
}
|
||||||
|
|
||||||
|
klog.Infof("checking required Kubernetes images for %s...", k8sVersion)
|
||||||
|
|
||||||
|
result, err := n.SystemRunner.Run(ctx,
|
||||||
|
"kubeadm", "config", "images", "list",
|
||||||
|
"--kubernetes-version", k8sVersion,
|
||||||
|
)
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Errorf("list required Kubernetes images for %s: %w", k8sVersion, err)
|
||||||
|
}
|
||||||
|
|
||||||
|
var missing []string
|
||||||
|
for _, img := range strings.Fields(result.Stdout) {
|
||||||
|
if err := checkImagePresent(ctx, n, img); err != nil {
|
||||||
|
klog.Errorf("MISSING image: %s", img)
|
||||||
|
missing = append(missing, img)
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
klog.Infof("found image: %s", img)
|
||||||
|
}
|
||||||
|
|
||||||
|
if len(missing) > 0 {
|
||||||
|
return fmt.Errorf("preload the Kubernetes images before bootstrapping; missing: %s", strings.Join(missing, ", "))
|
||||||
|
}
|
||||||
|
|
||||||
|
klog.Infof("all required images are present")
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func checkImagePresent(ctx context.Context, n *NodeContext, image string) error {
|
||||||
|
image = strings.TrimSpace(image)
|
||||||
|
if image == "" {
|
||||||
|
return fmt.Errorf("image is required")
|
||||||
|
}
|
||||||
|
|
||||||
|
// crictl inspecti exits non-zero when the image is absent.
|
||||||
|
_, err := n.SystemRunner.Run(ctx, "crictl", "inspecti", image)
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Errorf("image %q not present: %w", image, err)
|
||||||
|
}
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
func GenerateKubeadmConfig(context.Context, *NodeContext) error {
|
func GenerateKubeadmConfig(context.Context, *NodeContext) error {
|
||||||
|
|||||||
@@ -12,6 +12,7 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
type NetworkConfig struct {
|
type NetworkConfig struct {
|
||||||
|
Hostname string
|
||||||
MgmtIface string
|
MgmtIface string
|
||||||
MgmtAddress string
|
MgmtAddress string
|
||||||
MgmtGateway string
|
MgmtGateway string
|
||||||
@@ -48,11 +49,11 @@ func ConfigureMgmtInterface(cfg NetworkConfig) Step {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if _, err := nctx.System.Run(ctx, "ip", "link", "show", "dev", cfg.MgmtIface); err != nil {
|
if _, err := nctx.SystemRunner.Run(ctx, "ip", "link", "show", "dev", cfg.MgmtIface); err != nil {
|
||||||
return fmt.Errorf("interface not found: %s: %w", cfg.MgmtIface, err)
|
return fmt.Errorf("interface not found: %s: %w", cfg.MgmtIface, err)
|
||||||
}
|
}
|
||||||
|
|
||||||
if _, err := nctx.System.Run(ctx, "ip", "link", "set", "dev", cfg.MgmtIface, "up"); err != nil {
|
if _, err := nctx.SystemRunner.Run(ctx, "ip", "link", "set", "dev", cfg.MgmtIface, "up"); err != nil {
|
||||||
return fmt.Errorf("failed to bring up interface %s: %w", cfg.MgmtIface, err)
|
return fmt.Errorf("failed to bring up interface %s: %w", cfg.MgmtIface, err)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -64,13 +65,13 @@ func ConfigureMgmtInterface(cfg NetworkConfig) Step {
|
|||||||
if hasAddr {
|
if hasAddr {
|
||||||
klog.Infof("address already present on %s: %s", cfg.MgmtIface, wantCIDR)
|
klog.Infof("address already present on %s: %s", cfg.MgmtIface, wantCIDR)
|
||||||
} else {
|
} else {
|
||||||
if _, err := nctx.System.Run(ctx, "ip", "addr", "add", wantCIDR, "dev", cfg.MgmtIface); err != nil {
|
if _, err := nctx.SystemRunner.Run(ctx, "ip", "addr", "add", wantCIDR, "dev", cfg.MgmtIface); err != nil {
|
||||||
return fmt.Errorf("failed assigning %s to %s: %w", wantCIDR, cfg.MgmtIface, err)
|
return fmt.Errorf("failed assigning %s to %s: %w", wantCIDR, cfg.MgmtIface, err)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if gw := strings.TrimSpace(cfg.MgmtGateway); gw != "" {
|
if gw := strings.TrimSpace(cfg.MgmtGateway); gw != "" {
|
||||||
if _, err := nctx.System.Run(ctx, "ip", "route", "replace", "default", "via", gw, "dev", cfg.MgmtIface); err != nil {
|
if _, err := nctx.SystemRunner.Run(ctx, "ip", "route", "replace", "default", "via", gw, "dev", cfg.MgmtIface); err != nil {
|
||||||
return fmt.Errorf("failed setting default route via %s dev %s: %w", gw, cfg.MgmtIface, err)
|
return fmt.Errorf("failed setting default route via %s dev %s: %w", gw, cfg.MgmtIface, err)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -85,7 +86,44 @@ func maskSize(m net.IPMask) int {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func EnsureIPForward(ctx context.Context, n *NodeContext) error {
|
func EnsureIPForward(ctx context.Context, n *NodeContext) error {
|
||||||
return system.EnsureSysctl(ctx, n.System, "net.ipv4.ip_forward", "1")
|
return system.EnsureSysctl(ctx, n.SystemRunner, "net.ipv4.ip_forward", "1")
|
||||||
|
}
|
||||||
|
|
||||||
|
func ConfigureHostname(cfg NetworkConfig) Step {
|
||||||
|
return func(context.Context, *NodeContext) error {
|
||||||
|
want := strings.TrimSpace(cfg.Hostname)
|
||||||
|
if want == "" {
|
||||||
|
return fmt.Errorf("hostname is required")
|
||||||
|
}
|
||||||
|
|
||||||
|
current, err := os.Hostname()
|
||||||
|
if err != nil {
|
||||||
|
current = ""
|
||||||
|
}
|
||||||
|
|
||||||
|
if current == want {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
if err := system.SetHostname(want); err != nil {
|
||||||
|
return fmt.Errorf("set hostname to %q: %w", want, err)
|
||||||
|
}
|
||||||
|
|
||||||
|
if err := os.WriteFile("/etc/hostname", []byte(want+"\n"), 0o644); err != nil {
|
||||||
|
return fmt.Errorf("write /etc/hostname: %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
current, err = os.Hostname()
|
||||||
|
if err != nil {
|
||||||
|
current = ""
|
||||||
|
}
|
||||||
|
|
||||||
|
if current != want {
|
||||||
|
return fmt.Errorf("Unable to set hostname: %q", want)
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func ConfigureDNS(cfg NetworkConfig) Step {
|
func ConfigureDNS(cfg NetworkConfig) Step {
|
||||||
@@ -159,7 +197,7 @@ func ConfigureDNS(cfg NetworkConfig) Step {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func interfaceHasIPv4(ctx context.Context, nctx *NodeContext, iface, wantIP string) (bool, error) {
|
func interfaceHasIPv4(ctx context.Context, nctx *NodeContext, iface, wantIP string) (bool, error) {
|
||||||
res, err := nctx.System.Run(ctx, "ip", "-o", "-4", "addr", "show", "dev", iface)
|
res, err := nctx.SystemRunner.Run(ctx, "ip", "-o", "-4", "addr", "show", "dev", iface)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return false, err
|
return false, err
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2,17 +2,107 @@ package node
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
|
"fmt"
|
||||||
|
"net"
|
||||||
|
"strings"
|
||||||
|
"time"
|
||||||
|
|
||||||
"k8s.io/klog/v2"
|
"k8s.io/klog/v2"
|
||||||
)
|
)
|
||||||
|
|
||||||
func CheckPrereqs(context.Context, *NodeContext) error {
|
func ValidateNetworkRequirements(ctx context.Context, nct *NodeContext) error {
|
||||||
klog.Info("check_prereqs: TODO implement command discovery and runtime validation")
|
requireLocalIP := func(wantedIP string) error {
|
||||||
return nil
|
wantedIP = strings.TrimSpace(wantedIP)
|
||||||
}
|
if wantedIP == "" {
|
||||||
|
return fmt.Errorf("API server advertise address is required")
|
||||||
|
}
|
||||||
|
|
||||||
|
ip := net.ParseIP(wantedIP)
|
||||||
|
if ip == nil {
|
||||||
|
return fmt.Errorf("invalid API server advertise address %q", wantedIP)
|
||||||
|
}
|
||||||
|
|
||||||
|
ifaces, err := net.Interfaces()
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Errorf("list interfaces: %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, iface := range ifaces {
|
||||||
|
addrs, err := iface.Addrs()
|
||||||
|
if err != nil {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
for _, addr := range addrs {
|
||||||
|
var got net.IP
|
||||||
|
switch v := addr.(type) {
|
||||||
|
case *net.IPNet:
|
||||||
|
got = v.IP
|
||||||
|
case *net.IPAddr:
|
||||||
|
got = v.IP
|
||||||
|
}
|
||||||
|
if got != nil && got.Equal(ip) {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return fmt.Errorf("required local IP is not present on any interface: %s", wantedIP)
|
||||||
|
}
|
||||||
|
|
||||||
|
checkAPIServerReachable := func(endpoint string) error {
|
||||||
|
endpoint = strings.TrimSpace(endpoint)
|
||||||
|
if endpoint == "" {
|
||||||
|
return fmt.Errorf("API server endpoint is required")
|
||||||
|
}
|
||||||
|
|
||||||
|
host, port, err := net.SplitHostPort(endpoint)
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Errorf("invalid API server endpoint %q: %w", endpoint, err)
|
||||||
|
}
|
||||||
|
if strings.TrimSpace(host) == "" || strings.TrimSpace(port) == "" {
|
||||||
|
return fmt.Errorf("invalid API server endpoint %q", endpoint)
|
||||||
|
}
|
||||||
|
|
||||||
|
klog.Infof("checking API server reachability: %s:%s", host, port)
|
||||||
|
|
||||||
|
var lastErr error
|
||||||
|
for i := 0; i < 20; i++ {
|
||||||
|
d := net.Dialer{Timeout: 1 * time.Second}
|
||||||
|
conn, err := d.DialContext(ctx, "tcp", endpoint)
|
||||||
|
if err == nil {
|
||||||
|
_ = conn.Close()
|
||||||
|
klog.Infof("API server is reachable")
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
lastErr = err
|
||||||
|
|
||||||
|
select {
|
||||||
|
case <-ctx.Done():
|
||||||
|
return ctx.Err()
|
||||||
|
case <-time.After(1 * time.Second):
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return fmt.Errorf("cannot reach API server at %s: %w", endpoint, lastErr)
|
||||||
|
}
|
||||||
|
|
||||||
|
cfg := nct.Config.Spec
|
||||||
|
switch strings.TrimSpace(cfg.ClusterRole) {
|
||||||
|
case "control-plane":
|
||||||
|
if err := requireLocalIP(cfg.APIServerAdvertiseAddress); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
case "worker":
|
||||||
|
if err := requireLocalIP(cfg.APIServerAdvertiseAddress); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
if err := checkAPIServerReachable(cfg.APIServerEndpoint); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
default:
|
||||||
|
return fmt.Errorf("Incorrect ClusterRole: %s", cfg.ClusterRole)
|
||||||
|
}
|
||||||
|
|
||||||
func ValidateNetworkRequirements(context.Context, *NodeContext) error {
|
|
||||||
klog.Info("validate_network_requirements: TODO implement local IP and API reachability checks")
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -20,8 +110,3 @@ func CheckUpgradePrereqs(context.Context, *NodeContext) error {
|
|||||||
klog.Info("check_upgrade_prereqs: TODO implement kubeadm version / skew checks")
|
klog.Info("check_upgrade_prereqs: TODO implement kubeadm version / skew checks")
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func DecideBootstrapAction(_ context.Context, nctx *NodeContext) error {
|
|
||||||
klog.InfoS("decide_bootstrap_action", "bootstrapMode", nctx.Config.Spec.BootstrapMode, "joinKind", nctx.Config.Spec.JoinKind)
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|||||||
55
clitools/pkg/render/monoks.go
Normal file
55
clitools/pkg/render/monoks.go
Normal file
@@ -0,0 +1,55 @@
|
|||||||
|
package templates
|
||||||
|
|
||||||
|
import (
|
||||||
|
"bytes"
|
||||||
|
|
||||||
|
"k8s.io/apimachinery/pkg/runtime"
|
||||||
|
"k8s.io/apimachinery/pkg/runtime/serializer/json"
|
||||||
|
|
||||||
|
"undecided.project/monok8s/pkg/scheme"
|
||||||
|
tmpl "undecided.project/monok8s/pkg/templates"
|
||||||
|
)
|
||||||
|
|
||||||
|
func RenderMonoKSConfig() (string, error) {
|
||||||
|
cfg := tmpl.DefaultMonoKSConfig()
|
||||||
|
|
||||||
|
s := runtime.NewScheme()
|
||||||
|
if err := scheme.AddToScheme(s); err != nil {
|
||||||
|
return "", err
|
||||||
|
}
|
||||||
|
|
||||||
|
serializer := json.NewYAMLSerializer(
|
||||||
|
json.DefaultMetaFactory,
|
||||||
|
s,
|
||||||
|
s,
|
||||||
|
)
|
||||||
|
|
||||||
|
var buf bytes.Buffer
|
||||||
|
if err := serializer.Encode(&cfg, &buf); err != nil {
|
||||||
|
return "", err
|
||||||
|
}
|
||||||
|
|
||||||
|
return buf.String(), nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func RenderOSUpgrade() (string, error) {
|
||||||
|
cfg := tmpl.DefaultOSUpgrade()
|
||||||
|
|
||||||
|
s := runtime.NewScheme()
|
||||||
|
if err := scheme.AddToScheme(s); err != nil {
|
||||||
|
return "", err
|
||||||
|
}
|
||||||
|
|
||||||
|
serializer := json.NewYAMLSerializer(
|
||||||
|
json.DefaultMetaFactory,
|
||||||
|
s,
|
||||||
|
s,
|
||||||
|
)
|
||||||
|
|
||||||
|
var buf bytes.Buffer
|
||||||
|
if err := serializer.Encode(&cfg, &buf); err != nil {
|
||||||
|
return "", err
|
||||||
|
}
|
||||||
|
|
||||||
|
return buf.String(), nil
|
||||||
|
}
|
||||||
27
clitools/pkg/scheme/v1alpha1.go
Normal file
27
clitools/pkg/scheme/v1alpha1.go
Normal file
@@ -0,0 +1,27 @@
|
|||||||
|
package scheme
|
||||||
|
|
||||||
|
import (
|
||||||
|
"k8s.io/apimachinery/pkg/runtime"
|
||||||
|
"k8s.io/apimachinery/pkg/runtime/schema"
|
||||||
|
|
||||||
|
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||||
|
types "undecided.project/monok8s/pkg/apis/monok8s/v1alpha1"
|
||||||
|
)
|
||||||
|
|
||||||
|
var (
|
||||||
|
GroupVersion = schema.GroupVersion{
|
||||||
|
Group: "monok8s.io",
|
||||||
|
Version: "v1alpha1",
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
|
func AddToScheme(s *runtime.Scheme) error {
|
||||||
|
s.AddKnownTypes(GroupVersion,
|
||||||
|
&types.MonoKSConfig{},
|
||||||
|
)
|
||||||
|
|
||||||
|
// Required for meta stuff
|
||||||
|
metav1.AddToGroupVersion(s, GroupVersion)
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
@@ -5,15 +5,19 @@ import (
|
|||||||
"fmt"
|
"fmt"
|
||||||
"os"
|
"os"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
|
"k8s.io/klog/v2"
|
||||||
)
|
)
|
||||||
|
|
||||||
const DefaultSecond = 1_000_000_000
|
const DefaultSecond = 1_000_000_000
|
||||||
|
|
||||||
func EnsureServiceRunning(ctx context.Context, r *Runner, svc string) error {
|
func EnsureServiceRunning(ctx context.Context, r *Runner, svc string) error {
|
||||||
|
|
||||||
if _, err := r.Run(ctx, " rc-service", svc, "status"); err == nil {
|
if _, err := r.Run(ctx, " rc-service", svc, "status"); err == nil {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
klog.Infof("Starting service: %q", svc)
|
||||||
_, err := r.RunRetry(ctx, RetryOptions{
|
_, err := r.RunRetry(ctx, RetryOptions{
|
||||||
Attempts: 3,
|
Attempts: 3,
|
||||||
Delay: 2 * DefaultSecond,
|
Delay: 2 * DefaultSecond,
|
||||||
|
|||||||
12
clitools/pkg/system/hostname_linux.go
Normal file
12
clitools/pkg/system/hostname_linux.go
Normal file
@@ -0,0 +1,12 @@
|
|||||||
|
//go:build linux
|
||||||
|
|
||||||
|
package system
|
||||||
|
|
||||||
|
import "golang.org/x/sys/unix"
|
||||||
|
|
||||||
|
func SetHostname(hostname string) error {
|
||||||
|
if hostname == "" {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
return unix.Sethostname([]byte(hostname))
|
||||||
|
}
|
||||||
8
clitools/pkg/system/hostname_stub.go
Normal file
8
clitools/pkg/system/hostname_stub.go
Normal file
@@ -0,0 +1,8 @@
|
|||||||
|
//go:build !linux
|
||||||
|
|
||||||
|
package system
|
||||||
|
|
||||||
|
func SetHostname(hostname string) error {
|
||||||
|
// intentionally a no-op
|
||||||
|
return nil
|
||||||
|
}
|
||||||
@@ -1,54 +1,93 @@
|
|||||||
package templates
|
package templates
|
||||||
|
|
||||||
const MonoKSConfigYAML = `apiVersion: monok8s.io/v1alpha1
|
import (
|
||||||
kind: MonoKSConfig
|
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||||
metadata:
|
types "undecided.project/monok8s/pkg/apis/monok8s/v1alpha1"
|
||||||
name: example
|
buildinfo "undecided.project/monok8s/pkg/buildinfo"
|
||||||
namespace: kube-system
|
)
|
||||||
spec:
|
|
||||||
kubernetesVersion: v1.35.3
|
|
||||||
nodeName: monok8s-master-1
|
|
||||||
clusterName: monok8s
|
|
||||||
clusterDomain: cluster.local
|
|
||||||
podSubnet: 10.244.0.0/16
|
|
||||||
serviceSubnet: 10.96.0.0/12
|
|
||||||
apiServerAdvertiseAddress: 10.0.0.10
|
|
||||||
apiServerEndpoint: 10.0.0.10:6443
|
|
||||||
containerRuntimeEndpoint: unix:///var/run/crio/crio.sock
|
|
||||||
bootstrapMode: init
|
|
||||||
joinKind: worker
|
|
||||||
cniPlugin: none
|
|
||||||
allowSchedulingOnControlPlane: true
|
|
||||||
skipImageCheck: false
|
|
||||||
kubeProxyNodePortAddresses:
|
|
||||||
- primary
|
|
||||||
subjectAltNames:
|
|
||||||
- 10.0.0.10
|
|
||||||
nodeLabels:
|
|
||||||
node-role.kubernetes.io/control-plane: ""
|
|
||||||
nodeAnnotations: {}
|
|
||||||
network:
|
|
||||||
hostname: monok8s-master-1
|
|
||||||
managementIface: eth0
|
|
||||||
managementCIDR: 10.0.0.10/24
|
|
||||||
managementGateway: 10.0.0.1
|
|
||||||
dnsNameservers:
|
|
||||||
- 1.1.1.1
|
|
||||||
- 8.8.8.8
|
|
||||||
dnsSearchDomains:
|
|
||||||
- lan
|
|
||||||
`
|
|
||||||
|
|
||||||
const OSUpgradeYAML = `apiVersion: monok8s.io/v1alpha1
|
func DefaultMonoKSConfig() types.MonoKSConfig {
|
||||||
kind: OSUpgrade
|
return types.MonoKSConfig{
|
||||||
metadata:
|
TypeMeta: metav1.TypeMeta{
|
||||||
name: example
|
APIVersion: "monok8s.io/v1alpha1",
|
||||||
namespace: kube-system
|
Kind: "MonoKSConfig",
|
||||||
spec:
|
},
|
||||||
version: v0.0.1
|
ObjectMeta: metav1.ObjectMeta{
|
||||||
imageURL: https://example.invalid/images/monok8s-v0.0.1.img.zst
|
Name: "example",
|
||||||
targetPartition: B
|
Namespace: "kube-system",
|
||||||
nodeSelector:
|
},
|
||||||
- monok8s-master-1
|
Spec: types.MonoKSConfigSpec{
|
||||||
force: false
|
KubernetesVersion: buildinfo.Version,
|
||||||
`
|
NodeName: "monok8s-master-1",
|
||||||
|
|
||||||
|
ClusterRole: "control-plane",
|
||||||
|
InitControlPlane: true,
|
||||||
|
|
||||||
|
ClusterName: "monok8s",
|
||||||
|
ClusterDomain: "cluster.local",
|
||||||
|
|
||||||
|
PodSubnet: "10.244.0.0/16",
|
||||||
|
ServiceSubnet: "10.96.0.0/12",
|
||||||
|
|
||||||
|
APIServerAdvertiseAddress: "10.0.0.10",
|
||||||
|
APIServerEndpoint: "10.0.0.10:6443",
|
||||||
|
|
||||||
|
ContainerRuntimeEndpoint: "unix:///var/run/crio/crio.sock",
|
||||||
|
|
||||||
|
CNIPlugin: "default",
|
||||||
|
|
||||||
|
AllowSchedulingOnControlPlane: true,
|
||||||
|
SkipImageCheck: false,
|
||||||
|
|
||||||
|
KubeProxyNodePortAddresses: []string{
|
||||||
|
"primary",
|
||||||
|
},
|
||||||
|
|
||||||
|
SubjectAltNames: []string{
|
||||||
|
"10.0.0.10",
|
||||||
|
},
|
||||||
|
|
||||||
|
NodeLabels: map[string]string{
|
||||||
|
"node-role.kubernetes.io/control-plane": "",
|
||||||
|
},
|
||||||
|
|
||||||
|
NodeAnnotations: map[string]string{},
|
||||||
|
|
||||||
|
Network: types.NetworkSpec{
|
||||||
|
Hostname: "monok8s-master-1",
|
||||||
|
ManagementIface: "eth0",
|
||||||
|
ManagementCIDR: "10.0.0.10/24",
|
||||||
|
ManagementGW: "10.0.0.1",
|
||||||
|
DNSNameservers: []string{
|
||||||
|
"1.1.1.1",
|
||||||
|
"8.8.8.8",
|
||||||
|
},
|
||||||
|
DNSSearchDomains: []string{
|
||||||
|
"lan",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func DefaultOSUpgrade() types.OSUpgrade {
|
||||||
|
return types.OSUpgrade{
|
||||||
|
TypeMeta: metav1.TypeMeta{
|
||||||
|
APIVersion: "monok8s.io/v1alpha1",
|
||||||
|
Kind: "OSUpgrade",
|
||||||
|
},
|
||||||
|
ObjectMeta: metav1.ObjectMeta{
|
||||||
|
Name: "example",
|
||||||
|
Namespace: "kube-system",
|
||||||
|
},
|
||||||
|
Spec: types.OSUpgradeSpec{
|
||||||
|
Version: "v0.0.1",
|
||||||
|
ImageURL: "https://example.invalid/images/monok8s-v0.0.1.img.zst",
|
||||||
|
TargetPartition: "B",
|
||||||
|
NodeSelector: []string{
|
||||||
|
"monok8s-master-1",
|
||||||
|
},
|
||||||
|
Force: false,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
@@ -3,9 +3,11 @@ ARG DOCKER_IMAGE_ROOT=monok8s
|
|||||||
|
|
||||||
FROM --platform=$BUILDPLATFORM ${DOCKER_IMAGE_ROOT}/build-base:${TAG} AS build-base
|
FROM --platform=$BUILDPLATFORM ${DOCKER_IMAGE_ROOT}/build-base:${TAG} AS build-base
|
||||||
|
|
||||||
|
ARG TAG
|
||||||
ARG ALPINE_ARCH
|
ARG ALPINE_ARCH
|
||||||
ARG ALPINE_VER
|
ARG ALPINE_VER
|
||||||
ARG CRIO_VERSION
|
ARG CRIO_VERSION
|
||||||
|
ARG KUBE_VERSION
|
||||||
ARG DEVICE_TREE_TARGET
|
ARG DEVICE_TREE_TARGET
|
||||||
|
|
||||||
RUN mkdir -p "/out/rootfs"
|
RUN mkdir -p "/out/rootfs"
|
||||||
@@ -20,7 +22,10 @@ COPY out/Image.gz ./
|
|||||||
RUN tar -xf alpine.tar.gz -C "/out/rootfs"
|
RUN tar -xf alpine.tar.gz -C "/out/rootfs"
|
||||||
|
|
||||||
RUN mkdir -p /out/rootfs/usr/local/bin/
|
RUN mkdir -p /out/rootfs/usr/local/bin/
|
||||||
COPY packages/kubernetes/* /out/rootfs/usr/local/bin/
|
COPY packages/kubernetes/kubelet-${KUBE_VERSION} /out/rootfs/usr/local/bin/kubelet
|
||||||
|
COPY packages/kubernetes/kubeadm-${KUBE_VERSION} /out/rootfs/usr/local/bin/kubeadm
|
||||||
|
COPY packages/kubernetes/kubectl-${KUBE_VERSION} /out/rootfs/usr/local/bin/kubectl
|
||||||
|
COPY clitools/bin/ctl-linux-${ALPINE_ARCH}-${TAG} /out/rootfs/usr/local/bin/ctl
|
||||||
RUN chmod +x /out/rootfs/usr/local/bin/*
|
RUN chmod +x /out/rootfs/usr/local/bin/*
|
||||||
|
|
||||||
COPY alpine/rootfs-extra ./rootfs-extra
|
COPY alpine/rootfs-extra ./rootfs-extra
|
||||||
|
|||||||
29
makefile
29
makefile
@@ -13,9 +13,9 @@ NXP_TAR := $(PACKAGES_DIR)/$(NXP_VERSION).tar.gz
|
|||||||
CRIO_TAR := $(PACKAGES_DIR)/$(CRIO_VERSION).tar.gz
|
CRIO_TAR := $(PACKAGES_DIR)/$(CRIO_VERSION).tar.gz
|
||||||
|
|
||||||
# Kubernetes components
|
# Kubernetes components
|
||||||
KUBELET_BIN := $(PACKAGES_DIR)/kubernetes/kubelet
|
KUBELET_BIN := $(PACKAGES_DIR)/kubernetes/kubelet-$(KUBE_VERSION)
|
||||||
KUBEADM_BIN := $(PACKAGES_DIR)/kubernetes/kubeadm
|
KUBEADM_BIN := $(PACKAGES_DIR)/kubernetes/kubeadm-$(KUBE_VERSION)
|
||||||
KUBECTL_BIN := $(PACKAGES_DIR)/kubernetes/kubectl
|
KUBECTL_BIN := $(PACKAGES_DIR)/kubernetes/kubectl-$(KUBE_VERSION)
|
||||||
|
|
||||||
CONFIGS_DIR := configs
|
CONFIGS_DIR := configs
|
||||||
SCRIPTS_DIR := scripts
|
SCRIPTS_DIR := scripts
|
||||||
@@ -31,6 +31,7 @@ RELEASE_IMAGE := $(OUT_DIR)/monok8s-$(TAG).img.gz
|
|||||||
KERNEL_IMAGE := $(OUT_DIR)/Image.gz
|
KERNEL_IMAGE := $(OUT_DIR)/Image.gz
|
||||||
|
|
||||||
BUILD_BASE_STAMP := $(OUT_DIR)/.build-base-$(TAG).stamp
|
BUILD_BASE_STAMP := $(OUT_DIR)/.build-base-$(TAG).stamp
|
||||||
|
CLITOOLS_BIN := bin/ctl-linux-$(ARCH)-$(TAG)
|
||||||
|
|
||||||
ALPINE_SERIES := $(word 1,$(subst ., ,$(ALPINE_VER))).$(word 2,$(subst ., ,$(ALPINE_VER)))
|
ALPINE_SERIES := $(word 1,$(subst ., ,$(ALPINE_VER))).$(word 2,$(subst ., ,$(ALPINE_VER)))
|
||||||
|
|
||||||
@@ -46,6 +47,8 @@ ALPINE_SRCS := $(shell find alpine -type f 2>/dev/null)
|
|||||||
INITRAMFS_SRCS := $(shell find initramfs -type f 2>/dev/null)
|
INITRAMFS_SRCS := $(shell find initramfs -type f 2>/dev/null)
|
||||||
KERNEL_SRCS := $(shell find kernel-build -type f 2>/dev/null)
|
KERNEL_SRCS := $(shell find kernel-build -type f 2>/dev/null)
|
||||||
|
|
||||||
|
CLITOOLS_SRCS := $(shell find clitools -type f 2>/dev/null)
|
||||||
|
|
||||||
BUILD_BASE_DEPS := \
|
BUILD_BASE_DEPS := \
|
||||||
docker/build-base.Dockerfile \
|
docker/build-base.Dockerfile \
|
||||||
build.env \
|
build.env \
|
||||||
@@ -77,11 +80,15 @@ ITB_DEPS := \
|
|||||||
build.env \
|
build.env \
|
||||||
makefile
|
makefile
|
||||||
|
|
||||||
|
CLITOOLS := \
|
||||||
|
$(CLITOOLS_SRCS)
|
||||||
|
|
||||||
RELEASE_DEPS := \
|
RELEASE_DEPS := \
|
||||||
$(BUILD_BASE_STAMP) \
|
$(BUILD_BASE_STAMP) \
|
||||||
$(BUILD_INFO_FILE) \
|
$(BUILD_INFO_FILE) \
|
||||||
$(BOARD_ITB) \
|
$(BOARD_ITB) \
|
||||||
$(ALPINE_TAR) \
|
$(ALPINE_TAR) \
|
||||||
|
$(CLITOOLS_BIN) \
|
||||||
$(CRIO_TAR) \
|
$(CRIO_TAR) \
|
||||||
$(KUBELET_BIN) \
|
$(KUBELET_BIN) \
|
||||||
$(KUBEADM_BIN) \
|
$(KUBEADM_BIN) \
|
||||||
@@ -91,12 +98,6 @@ RELEASE_DEPS := \
|
|||||||
build.env \
|
build.env \
|
||||||
makefile
|
makefile
|
||||||
|
|
||||||
CLITOOLS := \
|
|
||||||
clitools/pkg \
|
|
||||||
clitools/cmd \
|
|
||||||
clitools/go.mod \
|
|
||||||
clitools/go.sum
|
|
||||||
|
|
||||||
# ---- Directory creation ------------------------------------------------------
|
# ---- Directory creation ------------------------------------------------------
|
||||||
|
|
||||||
$(PACKAGES_DIR):
|
$(PACKAGES_DIR):
|
||||||
@@ -174,6 +175,9 @@ $(INITRAMFS): $(INITRAMFS_DEPS) | $(OUT_DIR)
|
|||||||
--output type=local,dest=./$(OUT_DIR) .
|
--output type=local,dest=./$(OUT_DIR) .
|
||||||
test -f $@
|
test -f $@
|
||||||
|
|
||||||
|
$(CLITOOLS_BIN): $(CLITOOLS_SRCS)
|
||||||
|
$(MAKE) -C clitools
|
||||||
|
|
||||||
$(BOARD_ITB): $(ITB_DEPS) | $(OUT_DIR)
|
$(BOARD_ITB): $(ITB_DEPS) | $(OUT_DIR)
|
||||||
docker build \
|
docker build \
|
||||||
-f docker/itb.Dockerfile \
|
-f docker/itb.Dockerfile \
|
||||||
@@ -191,6 +195,7 @@ $(RELEASE_IMAGE): $(RELEASE_DEPS) | $(OUT_DIR)
|
|||||||
--build-arg TAG=$(TAG) \
|
--build-arg TAG=$(TAG) \
|
||||||
--build-arg ALPINE_ARCH=$(ALPINE_ARCH) \
|
--build-arg ALPINE_ARCH=$(ALPINE_ARCH) \
|
||||||
--build-arg ALPINE_VER=$(ALPINE_VER) \
|
--build-arg ALPINE_VER=$(ALPINE_VER) \
|
||||||
|
--build-arg KUBE_VERSION=$(KUBE_VERSION) \
|
||||||
--build-arg CRIO_VERSION=$(CRIO_VERSION) \
|
--build-arg CRIO_VERSION=$(CRIO_VERSION) \
|
||||||
--build-arg DEVICE_TREE_TARGET=$(DEVICE_TREE_TARGET) \
|
--build-arg DEVICE_TREE_TARGET=$(DEVICE_TREE_TARGET) \
|
||||||
-t $(DOCKER_IMAGE_ROOT)/buildenv-alpine:$(TAG) .
|
-t $(DOCKER_IMAGE_ROOT)/buildenv-alpine:$(TAG) .
|
||||||
@@ -263,9 +268,7 @@ kernel: $(KERNEL_IMAGE)
|
|||||||
initramfs: $(INITRAMFS)
|
initramfs: $(INITRAMFS)
|
||||||
itb: $(BOARD_ITB)
|
itb: $(BOARD_ITB)
|
||||||
build-base: $(BUILD_BASE_STAMP)
|
build-base: $(BUILD_BASE_STAMP)
|
||||||
|
clitools: $(CLITOOLS_BIN)
|
||||||
clitools: $(CLITOOLS)
|
|
||||||
$(MAKE) -C clitools
|
|
||||||
|
|
||||||
clean:
|
clean:
|
||||||
rm -f \
|
rm -f \
|
||||||
@@ -274,7 +277,7 @@ clean:
|
|||||||
$(INITRAMFS) \
|
$(INITRAMFS) \
|
||||||
$(BOARD_ITB) \
|
$(BOARD_ITB) \
|
||||||
$(RELEASE_IMAGE) \
|
$(RELEASE_IMAGE) \
|
||||||
$(CLITOOLS)
|
$(CLITOOLS_BIN)
|
||||||
|
|
||||||
distclean: clean
|
distclean: clean
|
||||||
rm -rf $(OUT_DIR)
|
rm -rf $(OUT_DIR)
|
||||||
|
|||||||
Reference in New Issue
Block a user