kubeadm: make the active timeouts structure accessible from anywhere

Currently, timeouts are only accessible if a kubeadm runtime.Object{}
like InitConfiguration is passed around.

Any time a config is loaded or defaulted, store the Timeouts
structure in a thread-safe way in the main kubeadm API package
with SetActiveTimeouts(). Optionally, a deep-copy can be
performed before calling SetActiveTimeouts(). Make this struct
accessible with GetActiveTimeouts(). Ensure these functions
are thread safe.

On init() make sure the struct is defaulted, so that unit
tests can work with these values.
This commit is contained in:
Lubomir I. Ivanov 2023-12-31 20:09:03 +02:00
parent ea0fa41445
commit d9e48705ff
5 changed files with 72 additions and 13 deletions

View File

@ -17,6 +17,7 @@ limitations under the License.
package kubeadm
import (
"sync"
"time"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
@ -33,3 +34,26 @@ func SetDefaultTimeouts(t **Timeouts) {
Discovery: &metav1.Duration{Duration: 5 * time.Minute},
}
}
var (
activeTimeouts *Timeouts = nil
timeoutMutex = &sync.RWMutex{}
)
func init() {
SetDefaultTimeouts(&activeTimeouts)
}
// GetActiveTimeouts gets the active timeouts structure.
func GetActiveTimeouts() *Timeouts {
timeoutMutex.RLock()
defer timeoutMutex.RUnlock()
return activeTimeouts
}
// SetActiveTimeouts sets the active timeouts structure.
func SetActiveTimeouts(timeouts *Timeouts) {
timeoutMutex.Lock()
activeTimeouts = timeouts.DeepCopy()
timeoutMutex.Unlock()
}

View File

@ -384,6 +384,19 @@ func isKubeadmPrereleaseVersion(versionInfo *apimachineryversion.Info, k8sVersio
return false
}
// prepareStaticVariables takes a given config and stores values from it in variables
// that can be used from multiple packages.
func prepareStaticVariables(config any) {
switch c := config.(type) {
case *kubeadmapi.InitConfiguration:
kubeadmapi.SetActiveTimeouts(c.Timeouts.DeepCopy())
case *kubeadmapi.JoinConfiguration:
kubeadmapi.SetActiveTimeouts(c.Timeouts.DeepCopy())
case *kubeadmapi.ResetConfiguration:
kubeadmapi.SetActiveTimeouts(c.Timeouts.DeepCopy())
}
}
// migrateMutator can be used to mutate a slice of configuration objects.
// The mutation is applied in-place and no copies are made.
type migrateMutator struct {

View File

@ -229,7 +229,7 @@ func DefaultedStaticInitConfiguration() (*kubeadmapi.InitConfiguration, error) {
}
// DefaultedInitConfiguration takes a versioned init config (often populated by flags), defaults it and converts it into internal InitConfiguration
func DefaultedInitConfiguration(versionedInitCfg *kubeadmapiv1.InitConfiguration, versionedClusterCfg *kubeadmapiv1.ClusterConfiguration, skipCRIDetect bool) (*kubeadmapi.InitConfiguration, error) {
func DefaultedInitConfiguration(versionedInitCfg *kubeadmapiv1.InitConfiguration, versionedClusterCfg *kubeadmapiv1.ClusterConfiguration, opts LoadOrDefaultConfigurationOptions) (*kubeadmapi.InitConfiguration, error) {
internalcfg := &kubeadmapi.InitConfiguration{}
// Takes passed flags into account; the defaulting is executed once again enforcing assignment of
@ -245,7 +245,7 @@ func DefaultedInitConfiguration(versionedInitCfg *kubeadmapiv1.InitConfiguration
}
// Applies dynamic defaults to settings not provided with flags
if err := SetInitDynamicDefaults(internalcfg, skipCRIDetect); err != nil {
if err := SetInitDynamicDefaults(internalcfg, opts.SkipCRIDetect); err != nil {
return nil, err
}
// Validates cfg (flags/configs + defaults + dynamic defaults)
@ -273,13 +273,20 @@ func LoadInitConfigurationFromFile(cfgPath string, opts LoadOrDefaultConfigurati
// Right thereafter, the configuration is defaulted again with dynamic values (like IP addresses of a machine, etc)
// Lastly, the internal config is validated and returned.
func LoadOrDefaultInitConfiguration(cfgPath string, versionedInitCfg *kubeadmapiv1.InitConfiguration, versionedClusterCfg *kubeadmapiv1.ClusterConfiguration, opts LoadOrDefaultConfigurationOptions) (*kubeadmapi.InitConfiguration, error) {
var (
config *kubeadmapi.InitConfiguration
err error
)
if cfgPath != "" {
// Loads configuration from config file, if provided
// Nb. --config overrides command line flags
return LoadInitConfigurationFromFile(cfgPath, opts)
config, err = LoadInitConfigurationFromFile(cfgPath, opts)
} else {
config, err = DefaultedInitConfiguration(versionedInitCfg, versionedClusterCfg, opts)
}
return DefaultedInitConfiguration(versionedInitCfg, versionedClusterCfg, opts.SkipCRIDetect)
if err == nil {
prepareStaticVariables(config)
}
return config, err
}
// BytesToInitConfiguration converts a byte slice to an internal, defaulted and validated InitConfiguration object.

View File

@ -62,13 +62,20 @@ func SetJoinControlPlaneDefaults(cfg *kubeadmapi.JoinControlPlane) error {
// Right thereafter, the configuration is defaulted again with dynamic values (like IP addresses of a machine, etc)
// Lastly, the internal config is validated and returned.
func LoadOrDefaultJoinConfiguration(cfgPath string, defaultversionedcfg *kubeadmapiv1.JoinConfiguration, opts LoadOrDefaultConfigurationOptions) (*kubeadmapi.JoinConfiguration, error) {
var (
config *kubeadmapi.JoinConfiguration
err error
)
if cfgPath != "" {
// Loads configuration from config file, if provided
// Nb. --config overrides command line flags, TODO: fix this
return LoadJoinConfigurationFromFile(cfgPath, opts)
config, err = LoadJoinConfigurationFromFile(cfgPath, opts)
} else {
config, err = DefaultedJoinConfiguration(defaultversionedcfg, opts)
}
return DefaultedJoinConfiguration(defaultversionedcfg, opts)
if err == nil {
prepareStaticVariables(config)
}
return config, err
}
// LoadJoinConfigurationFromFile loads versioned JoinConfiguration from file, converts it to internal, defaults and validates it

View File

@ -66,12 +66,20 @@ func SetResetDynamicDefaults(cfg *kubeadmapi.ResetConfiguration, skipCRIDetect b
// Right thereafter, the configuration is defaulted again with dynamic values
// Lastly, the internal config is validated and returned.
func LoadOrDefaultResetConfiguration(cfgPath string, defaultversionedcfg *kubeadmapiv1.ResetConfiguration, opts LoadOrDefaultConfigurationOptions) (*kubeadmapi.ResetConfiguration, error) {
var (
config *kubeadmapi.ResetConfiguration
err error
)
if cfgPath != "" {
// Loads configuration from config file, if provided
return LoadResetConfigurationFromFile(cfgPath, opts)
config, err = LoadResetConfigurationFromFile(cfgPath, opts)
} else {
config, err = DefaultedResetConfiguration(defaultversionedcfg, opts)
}
return DefaultedResetConfiguration(defaultversionedcfg, opts)
if err == nil {
prepareStaticVariables(config)
}
return config, err
}
// LoadResetConfigurationFromFile loads versioned ResetConfiguration from file, converts it to internal, defaults and validates it