rebase: update K8s packages to v0.32.1

Update K8s packages in go.mod to v0.32.1

Signed-off-by: Praveen M <m.praveen@ibm.com>
This commit is contained in:
Praveen M
2025-01-16 09:41:46 +05:30
committed by mergify[bot]
parent 5aef21ea4e
commit 7eb99fc6c9
2442 changed files with 273386 additions and 47788 deletions

View File

@ -0,0 +1,144 @@
/*
Copyright 2019 The Kubernetes Authors.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
/*
Package cache implements data structures used by the kubelet plugin manager to
keep track of registered plugins.
*/
package cache
import (
"fmt"
"sync"
"time"
"k8s.io/apimachinery/pkg/types"
"k8s.io/klog/v2"
)
// ActualStateOfWorld defines a set of thread-safe operations for the kubelet
// plugin manager's actual state of the world cache.
// This cache contains a map of socket file path to plugin information of
// all plugins attached to this node.
type ActualStateOfWorld interface {
// GetRegisteredPlugins generates and returns a list of plugins
// that are successfully registered plugins in the current actual state of world.
GetRegisteredPlugins() []PluginInfo
// AddPlugin add the given plugin in the cache.
// An error will be returned if socketPath of the PluginInfo object is empty.
// Note that this is different from desired world cache's AddOrUpdatePlugin
// because for the actual state of world cache, there won't be a scenario where
// we need to update an existing plugin if the timestamps don't match. This is
// because the plugin should have been unregistered in the reconciler and therefore
// removed from the actual state of world cache first before adding it back into
// the actual state of world cache again with the new timestamp
AddPlugin(pluginInfo PluginInfo) error
// RemovePlugin deletes the plugin with the given socket path from the actual
// state of world.
// If a plugin does not exist with the given socket path, this is a no-op.
RemovePlugin(socketPath string)
// PluginExistsWithCorrectTimestamp checks if the given plugin exists in the current actual
// state of world cache with the correct timestamp.
// Deprecated: please use `PluginExistsWithCorrectUUID` instead as it provides a better
// cross-platform support
PluginExistsWithCorrectTimestamp(pluginInfo PluginInfo) bool
// PluginExistsWithCorrectUUID checks if the given plugin exists in the current actual
// state of world cache with the correct UUID
PluginExistsWithCorrectUUID(pluginInfo PluginInfo) bool
}
// NewActualStateOfWorld returns a new instance of ActualStateOfWorld
func NewActualStateOfWorld() ActualStateOfWorld {
return &actualStateOfWorld{
socketFileToInfo: make(map[string]PluginInfo),
}
}
type actualStateOfWorld struct {
// socketFileToInfo is a map containing the set of successfully registered plugins
// The keys are plugin socket file paths. The values are PluginInfo objects
socketFileToInfo map[string]PluginInfo
sync.RWMutex
}
var _ ActualStateOfWorld = &actualStateOfWorld{}
// PluginInfo holds information of a plugin
type PluginInfo struct {
SocketPath string
Timestamp time.Time
UUID types.UID
Handler PluginHandler
Name string
}
func (asw *actualStateOfWorld) AddPlugin(pluginInfo PluginInfo) error {
asw.Lock()
defer asw.Unlock()
if pluginInfo.SocketPath == "" {
return fmt.Errorf("socket path is empty")
}
if _, ok := asw.socketFileToInfo[pluginInfo.SocketPath]; ok {
klog.V(2).InfoS("Plugin exists in actual state cache", "path", pluginInfo.SocketPath)
}
asw.socketFileToInfo[pluginInfo.SocketPath] = pluginInfo
return nil
}
func (asw *actualStateOfWorld) RemovePlugin(socketPath string) {
asw.Lock()
defer asw.Unlock()
delete(asw.socketFileToInfo, socketPath)
}
func (asw *actualStateOfWorld) GetRegisteredPlugins() []PluginInfo {
asw.RLock()
defer asw.RUnlock()
currentPlugins := []PluginInfo{}
for _, pluginInfo := range asw.socketFileToInfo {
currentPlugins = append(currentPlugins, pluginInfo)
}
return currentPlugins
}
func (asw *actualStateOfWorld) PluginExistsWithCorrectTimestamp(pluginInfo PluginInfo) bool {
asw.RLock()
defer asw.RUnlock()
// We need to check both if the socket file path exists, and the timestamp
// matches the given plugin (from the desired state cache) timestamp
actualStatePlugin, exists := asw.socketFileToInfo[pluginInfo.SocketPath]
return exists && (actualStatePlugin.Timestamp == pluginInfo.Timestamp)
}
func (asw *actualStateOfWorld) PluginExistsWithCorrectUUID(pluginInfo PluginInfo) bool {
asw.RLock()
defer asw.RUnlock()
// We need to check both if the socket file path exists, and the UUID
// matches the given plugin (from the desired state cache) UUID
actualStatePlugin, exists := asw.socketFileToInfo[pluginInfo.SocketPath]
return exists && (actualStatePlugin.UUID == pluginInfo.UUID)
}

View File

@ -0,0 +1,172 @@
/*
Copyright 2019 The Kubernetes Authors.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
/*
Package cache implements data structures used by the kubelet plugin manager to
keep track of registered plugins.
*/
package cache
import (
"errors"
"fmt"
"sync"
"time"
"k8s.io/apimachinery/pkg/util/uuid"
"k8s.io/klog/v2"
)
// DesiredStateOfWorld defines a set of thread-safe operations for the kubelet
// plugin manager's desired state of the world cache.
// This cache contains a map of socket file path to plugin information of
// all plugins attached to this node.
type DesiredStateOfWorld interface {
// AddOrUpdatePlugin add the given plugin in the cache if it doesn't already exist.
// If it does exist in the cache, then the timestamp of the PluginInfo object in the cache will be updated.
// An error will be returned if socketPath is empty.
AddOrUpdatePlugin(socketPath string) error
// RemovePlugin deletes the plugin with the given socket path from the desired
// state of world.
// If a plugin does not exist with the given socket path, this is a no-op.
RemovePlugin(socketPath string)
// GetPluginsToRegister generates and returns a list of plugins
// in the current desired state of world.
GetPluginsToRegister() []PluginInfo
// PluginExists checks if the given socket path exists in the current desired
// state of world cache
PluginExists(socketPath string) bool
}
// NewDesiredStateOfWorld returns a new instance of DesiredStateOfWorld.
func NewDesiredStateOfWorld() DesiredStateOfWorld {
return &desiredStateOfWorld{
socketFileToInfo: make(map[string]PluginInfo),
}
}
type desiredStateOfWorld struct {
// socketFileToInfo is a map containing the set of successfully registered plugins
// The keys are plugin socket file paths. The values are PluginInfo objects
socketFileToInfo map[string]PluginInfo
sync.RWMutex
}
var _ DesiredStateOfWorld = &desiredStateOfWorld{}
// Generate a detailed error msg for logs
func generatePluginMsgDetailed(prefixMsg, suffixMsg, socketPath, details string) (detailedMsg string) {
return fmt.Sprintf("%v for plugin at %q %v %v", prefixMsg, socketPath, details, suffixMsg)
}
// Generate a simplified error msg for events and a detailed error msg for logs
func generatePluginMsg(prefixMsg, suffixMsg, socketPath, details string) (simpleMsg, detailedMsg string) {
simpleMsg = fmt.Sprintf("%v for plugin at %q %v", prefixMsg, socketPath, suffixMsg)
return simpleMsg, generatePluginMsgDetailed(prefixMsg, suffixMsg, socketPath, details)
}
// GenerateMsgDetailed returns detailed msgs for plugins to register
// that can be used in logs.
// The msg format follows the pattern "<prefixMsg> <plugin details> <suffixMsg>"
func (plugin *PluginInfo) GenerateMsgDetailed(prefixMsg, suffixMsg string) (detailedMsg string) {
detailedStr := fmt.Sprintf("(plugin details: %v)", plugin)
return generatePluginMsgDetailed(prefixMsg, suffixMsg, plugin.SocketPath, detailedStr)
}
// GenerateMsg returns simple and detailed msgs for plugins to register
// that is user friendly and a detailed msg that can be used in logs.
// The msg format follows the pattern "<prefixMsg> <plugin details> <suffixMsg>".
func (plugin *PluginInfo) GenerateMsg(prefixMsg, suffixMsg string) (simpleMsg, detailedMsg string) {
detailedStr := fmt.Sprintf("(plugin details: %v)", plugin)
return generatePluginMsg(prefixMsg, suffixMsg, plugin.SocketPath, detailedStr)
}
// GenerateErrorDetailed returns detailed errors for plugins to register
// that can be used in logs.
// The msg format follows the pattern "<prefixMsg> <plugin details>: <err> ",
func (plugin *PluginInfo) GenerateErrorDetailed(prefixMsg string, err error) (detailedErr error) {
return errors.New(plugin.GenerateMsgDetailed(prefixMsg, errSuffix(err)))
}
// GenerateError returns simple and detailed errors for plugins to register
// that is user friendly and a detailed error that can be used in logs.
// The msg format follows the pattern "<prefixMsg> <plugin details>: <err> ".
func (plugin *PluginInfo) GenerateError(prefixMsg string, err error) (simpleErr, detailedErr error) {
simpleMsg, detailedMsg := plugin.GenerateMsg(prefixMsg, errSuffix(err))
return errors.New(simpleMsg), errors.New(detailedMsg)
}
// Generates an error string with the format ": <err>" if err exists
func errSuffix(err error) string {
errStr := ""
if err != nil {
errStr = fmt.Sprintf(": %v", err)
}
return errStr
}
func (dsw *desiredStateOfWorld) AddOrUpdatePlugin(socketPath string) error {
dsw.Lock()
defer dsw.Unlock()
if socketPath == "" {
return fmt.Errorf("socket path is empty")
}
if _, ok := dsw.socketFileToInfo[socketPath]; ok {
klog.V(2).InfoS("Plugin exists in desired state cache, timestamp will be updated", "path", socketPath)
}
// Update the PluginInfo object.
// Note that we only update the timestamp and UUID in the desired state of world, not the actual state of world
// because in the reconciler, we need to check if the plugin in the actual state of world is the same
// version as the plugin in the desired state of world
dsw.socketFileToInfo[socketPath] = PluginInfo{
SocketPath: socketPath,
Timestamp: time.Now(),
UUID: uuid.NewUUID(),
}
return nil
}
func (dsw *desiredStateOfWorld) RemovePlugin(socketPath string) {
dsw.Lock()
defer dsw.Unlock()
delete(dsw.socketFileToInfo, socketPath)
}
func (dsw *desiredStateOfWorld) GetPluginsToRegister() []PluginInfo {
dsw.RLock()
defer dsw.RUnlock()
pluginsToRegister := []PluginInfo{}
for _, pluginInfo := range dsw.socketFileToInfo {
pluginsToRegister = append(pluginsToRegister, pluginInfo)
}
return pluginsToRegister
}
func (dsw *desiredStateOfWorld) PluginExists(socketPath string) bool {
dsw.RLock()
defer dsw.RUnlock()
_, exists := dsw.socketFileToInfo[socketPath]
return exists
}

View File

@ -0,0 +1,60 @@
/*
Copyright 2019 The Kubernetes Authors.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package cache
import "time"
// PluginHandler is an interface a client of the pluginwatcher API needs to implement in
// order to consume plugins
// The PluginHandler follows the simple following state machine:
//
// +--------------------------------------+
// | ReRegistration |
// | Socket created with same plugin name |
// | |
// | |
// Socket Created v + Socket Deleted
// +------------------> Validate +---------------------------> Register +------------------> DeRegister
// + + +
// | | |
// | Error | Error |
// | | |
// v v v
// Out Out Out
//
// The pluginwatcher module follows strictly and sequentially this state machine for each *plugin name*.
// e.g: If you are Registering a plugin foo, you cannot get a DeRegister call for plugin foo
// until the Register("foo") call returns. Nor will you get a Validate("foo", "Different endpoint", ...)
// call until the Register("foo") call returns.
//
// ReRegistration: Socket created with same plugin name, usually for a plugin update
// e.g: plugin with name foo registers at foo.com/foo-1.9.7 later a plugin with name foo
// registers at foo.com/foo-1.9.9
//
// DeRegistration: When ReRegistration happens only the deletion of the new socket will trigger a DeRegister call
type PluginHandler interface {
// Validate returns an error if the information provided by
// the potential plugin is erroneous (unsupported version, ...)
ValidatePlugin(pluginName string, endpoint string, versions []string) error
// RegisterPlugin is called so that the plugin can be registered by any
// plugin consumer
// Error encountered here can still be Notified to the plugin.
RegisterPlugin(pluginName, endpoint string, versions []string, pluginClientTimeout *time.Duration) error
// DeRegisterPlugin is called once the pluginwatcher observes that the socket has
// been deleted.
DeRegisterPlugin(pluginName string)
}