2020-04-27 13:09:58 -04:00
package executor
import (
"context"
"net/http"
2020-05-05 18:02:16 -04:00
"os"
"path/filepath"
2021-11-12 00:03:15 -05:00
"strconv"
"strings"
2025-09-12 17:10:21 -04:00
"sync"
2021-11-12 00:03:15 -05:00
"time"
2020-04-27 13:09:58 -04:00
2022-03-02 18:47:27 -05:00
"github.com/k3s-io/k3s/pkg/cli/cmds"
daemonconfig "github.com/k3s-io/k3s/pkg/daemons/config"
2021-11-12 00:03:15 -05:00
yaml2 "gopkg.in/yaml.v2"
2020-04-27 13:09:58 -04:00
"k8s.io/apiserver/pkg/authentication/authenticator"
2021-11-12 00:03:15 -05:00
"sigs.k8s.io/yaml"
2020-04-27 13:09:58 -04:00
)
2020-05-05 18:02:16 -04:00
var (
executor Executor
)
2025-11-07 03:10:21 -05:00
// TestFunc is the signature of a function that returns nil error when the component is ready.
// The enableMaintenance flag enables attempts to perform corrective maintenance during the test process.
type TestFunc func ( ctx context . Context , enableMaintenance bool ) error
2025-03-14 18:24:49 -04:00
2020-04-27 13:09:58 -04:00
type Executor interface {
2021-05-11 15:50:08 -04:00
Bootstrap ( ctx context . Context , nodeConfig * daemonconfig . Node , cfg cmds . Agent ) error
2021-09-13 18:20:03 -04:00
Kubelet ( ctx context . Context , args [ ] string ) error
KubeProxy ( ctx context . Context , args [ ] string ) error
2021-10-12 02:13:10 -04:00
APIServerHandlers ( ctx context . Context ) ( authenticator . Request , http . Handler , error )
2025-03-14 18:24:49 -04:00
APIServer ( ctx context . Context , args [ ] string ) error
2025-03-05 03:35:58 -05:00
Scheduler ( ctx context . Context , nodeReady <- chan struct { } , args [ ] string ) error
ControllerManager ( ctx context . Context , args [ ] string ) error
2020-05-05 18:02:16 -04:00
CurrentETCDOptions ( ) ( InitialOptions , error )
2025-09-12 17:10:21 -04:00
ETCD ( ctx context . Context , wg * sync . WaitGroup , args * ETCDConfig , extraArgs [ ] string , test TestFunc ) error
2021-09-13 18:20:03 -04:00
CloudControllerManager ( ctx context . Context , ccmRBACReady <- chan struct { } , args [ ] string ) error
2024-01-08 17:38:36 -05:00
Containerd ( ctx context . Context , node * daemonconfig . Node ) error
Docker ( ctx context . Context , node * daemonconfig . Node ) error
2025-03-06 03:39:32 -05:00
CRI ( ctx context . Context , node * daemonconfig . Node ) error
2025-11-25 14:26:54 -05:00
CNI ( ctx context . Context , wg * sync . WaitGroup , node * daemonconfig . Node ) error
2025-03-05 03:35:58 -05:00
APIServerReadyChan ( ) <- chan struct { }
2025-03-14 18:24:49 -04:00
ETCDReadyChan ( ) <- chan struct { }
2025-03-06 03:39:32 -05:00
CRIReadyChan ( ) <- chan struct { }
2025-09-12 17:10:21 -04:00
IsSelfHosted ( ) bool
2020-04-27 13:09:58 -04:00
}
2025-04-11 13:51:10 -04:00
type ETCDSocketOpts struct {
ReuseAddress bool ` json:"reuse-address,omitempty" `
ReusePort bool ` json:"reuse-port,omitempty" `
}
2020-05-05 18:02:16 -04:00
type ETCDConfig struct {
2024-02-02 16:10:05 -05:00
InitialOptions ` json:",inline" `
2025-04-11 13:51:10 -04:00
Name string ` json:"name,omitempty" `
ListenClientURLs string ` json:"listen-client-urls,omitempty" `
ListenClientHTTPURLs string ` json:"listen-client-http-urls,omitempty" `
ListenMetricsURLs string ` json:"listen-metrics-urls,omitempty" `
ListenPeerURLs string ` json:"listen-peer-urls,omitempty" `
AdvertiseClientURLs string ` json:"advertise-client-urls,omitempty" `
DataDir string ` json:"data-dir,omitempty" `
SnapshotCount int ` json:"snapshot-count,omitempty" `
ServerTrust ServerTrust ` json:"client-transport-security" `
PeerTrust PeerTrust ` json:"peer-transport-security" `
ForceNewCluster bool ` json:"force-new-cluster,omitempty" `
HeartbeatInterval int ` json:"heartbeat-interval" `
ElectionTimeout int ` json:"election-timeout" `
Logger string ` json:"logger" `
LogOutputs [ ] string ` json:"log-outputs" `
SocketOpts ETCDSocketOpts ` json:"socket-options" `
2024-02-02 16:10:05 -05:00
ExperimentalInitialCorruptCheck bool ` json:"experimental-initial-corrupt-check" `
ExperimentalWatchProgressNotifyInterval time . Duration ` json:"experimental-watch-progress-notify-interval" `
2020-05-05 18:02:16 -04:00
}
type ServerTrust struct {
CertFile string ` json:"cert-file" `
KeyFile string ` json:"key-file" `
ClientCertAuth bool ` json:"client-cert-auth" `
TrustedCAFile string ` json:"trusted-ca-file" `
}
type PeerTrust struct {
CertFile string ` json:"cert-file" `
KeyFile string ` json:"key-file" `
ClientCertAuth bool ` json:"client-cert-auth" `
TrustedCAFile string ` json:"trusted-ca-file" `
}
type InitialOptions struct {
AdvertisePeerURL string ` json:"initial-advertise-peer-urls,omitempty" `
Cluster string ` json:"initial-cluster,omitempty" `
State string ` json:"initial-cluster-state,omitempty" `
}
2021-11-12 00:03:15 -05:00
func ( e ETCDConfig ) ToConfigFile ( extraArgs [ ] string ) ( string , error ) {
2020-05-05 18:02:16 -04:00
confFile := filepath . Join ( e . DataDir , "config" )
bytes , err := yaml . Marshal ( & e )
if err != nil {
return "" , err
}
2021-11-12 00:03:15 -05:00
if len ( extraArgs ) > 0 {
var s map [ string ] interface { }
if err := yaml2 . Unmarshal ( bytes , & s ) ; err != nil {
return "" , err
}
for _ , v := range extraArgs {
extraArg := strings . SplitN ( v , "=" , 2 )
// Depending on the argV, we have different types to handle.
// Source: https://github.com/etcd-io/etcd/blob/44b8ae145b505811775f5af915dd19198d556d55/server/config/config.go#L36-L190 and https://etcd.io/docs/v3.5/op-guide/configuration/#configuration-file
if len ( extraArg ) == 2 {
key := strings . TrimLeft ( extraArg [ 0 ] , "-" )
lowerKey := strings . ToLower ( key )
var stringArr [ ] string
if i , err := strconv . Atoi ( extraArg [ 1 ] ) ; err == nil {
s [ key ] = i
} else if time , err := time . ParseDuration ( extraArg [ 1 ] ) ; err == nil && ( strings . Contains ( lowerKey , "time" ) || strings . Contains ( lowerKey , "duration" ) || strings . Contains ( lowerKey , "interval" ) || strings . Contains ( lowerKey , "retention" ) ) {
// auto-compaction-retention is either a time.Duration or int, depending on version. If it is an int, it will be caught above.
s [ key ] = time
} else if err := yaml . Unmarshal ( [ ] byte ( extraArg [ 1 ] ) , & stringArr ) ; err == nil {
s [ key ] = stringArr
} else {
switch strings . ToLower ( extraArg [ 1 ] ) {
case "true" :
s [ key ] = true
case "false" :
s [ key ] = false
default :
s [ key ] = extraArg [ 1 ]
}
}
}
}
bytes , err = yaml2 . Marshal ( & s )
if err != nil {
return "" , err
}
}
2020-05-05 18:02:16 -04:00
if err := os . MkdirAll ( e . DataDir , 0700 ) ; err != nil {
return "" , err
}
2022-10-07 20:36:57 -04:00
return confFile , os . WriteFile ( confFile , bytes , 0600 )
2020-05-05 18:02:16 -04:00
}
2020-04-27 13:09:58 -04:00
func Set ( driver Executor ) {
executor = driver
}
2021-05-11 15:50:08 -04:00
func Bootstrap ( ctx context . Context , nodeConfig * daemonconfig . Node , cfg cmds . Agent ) error {
return executor . Bootstrap ( ctx , nodeConfig , cfg )
}
2021-09-13 18:20:03 -04:00
func Kubelet ( ctx context . Context , args [ ] string ) error {
return executor . Kubelet ( ctx , args )
2020-04-27 13:09:58 -04:00
}
2021-09-13 18:20:03 -04:00
func KubeProxy ( ctx context . Context , args [ ] string ) error {
return executor . KubeProxy ( ctx , args )
2020-04-27 13:09:58 -04:00
}
2021-10-12 02:13:10 -04:00
func APIServerHandlers ( ctx context . Context ) ( authenticator . Request , http . Handler , error ) {
return executor . APIServerHandlers ( ctx )
}
2025-03-14 18:24:49 -04:00
func APIServer ( ctx context . Context , args [ ] string ) error {
return executor . APIServer ( ctx , args )
2020-04-27 13:09:58 -04:00
}
2025-03-05 03:35:58 -05:00
func Scheduler ( ctx context . Context , nodeReady <- chan struct { } , args [ ] string ) error {
return executor . Scheduler ( ctx , nodeReady , args )
2020-04-27 13:09:58 -04:00
}
2025-03-05 03:35:58 -05:00
func ControllerManager ( ctx context . Context , args [ ] string ) error {
return executor . ControllerManager ( ctx , args )
2020-04-27 13:09:58 -04:00
}
2020-05-05 18:02:16 -04:00
func CurrentETCDOptions ( ) ( InitialOptions , error ) {
return executor . CurrentETCDOptions ( )
}
2025-09-12 17:10:21 -04:00
func ETCD ( ctx context . Context , wg * sync . WaitGroup , args * ETCDConfig , extraArgs [ ] string , test TestFunc ) error {
return executor . ETCD ( ctx , wg , args , extraArgs , test )
2020-05-05 18:02:16 -04:00
}
2021-06-29 10:28:38 -04:00
2021-09-13 18:20:03 -04:00
func CloudControllerManager ( ctx context . Context , ccmRBACReady <- chan struct { } , args [ ] string ) error {
return executor . CloudControllerManager ( ctx , ccmRBACReady , args )
2021-06-29 10:28:38 -04:00
}
2024-01-08 17:38:36 -05:00
func Containerd ( ctx context . Context , config * daemonconfig . Node ) error {
return executor . Containerd ( ctx , config )
}
func Docker ( ctx context . Context , config * daemonconfig . Node ) error {
return executor . Docker ( ctx , config )
}
2025-03-05 03:35:58 -05:00
2025-03-06 03:39:32 -05:00
func CRI ( ctx context . Context , config * daemonconfig . Node ) error {
return executor . CRI ( ctx , config )
}
2025-11-25 14:26:54 -05:00
func CNI ( ctx context . Context , wg * sync . WaitGroup , config * daemonconfig . Node ) error {
return executor . CNI ( ctx , wg , config )
}
2025-03-05 03:35:58 -05:00
func APIServerReadyChan ( ) <- chan struct { } {
return executor . APIServerReadyChan ( )
}
2025-03-06 03:39:32 -05:00
2025-03-14 18:24:49 -04:00
func ETCDReadyChan ( ) <- chan struct { } {
return executor . ETCDReadyChan ( )
}
2025-03-06 03:39:32 -05:00
func CRIReadyChan ( ) <- chan struct { } {
return executor . CRIReadyChan ( )
}
2025-09-12 17:10:21 -04:00
func IsSelfHosted ( ) bool {
return executor . IsSelfHosted ( )
}
func CloseIfNilErr ( err error , ch chan struct { } ) error {
if err == nil {
close ( ch )
}
return err
}