mirror of
https://github.com/k3s-io/kubernetes.git
synced 2025-07-30 15:05:27 +00:00
Updated ContextData and PluginContext with Clone methods.
This is necessary to be able to clone PluginContext during preemption.
This commit is contained in:
parent
26cc580e65
commit
641317bdde
@ -37,6 +37,17 @@ func (mc CommunicatingPlugin) Name() string {
|
||||
return Name
|
||||
}
|
||||
|
||||
type contextData struct {
|
||||
data string
|
||||
}
|
||||
|
||||
func (f *contextData) Clone() framework.ContextData {
|
||||
copy := &contextData{
|
||||
data: f.data,
|
||||
}
|
||||
return copy
|
||||
}
|
||||
|
||||
// Reserve is the functions invoked by the framework at "reserve" extension point.
|
||||
func (mc CommunicatingPlugin) Reserve(pc *framework.PluginContext, pod *v1.Pod, nodeName string) *framework.Status {
|
||||
if pod == nil {
|
||||
@ -44,7 +55,7 @@ func (mc CommunicatingPlugin) Reserve(pc *framework.PluginContext, pod *v1.Pod,
|
||||
}
|
||||
if pod.Name == "my-test-pod" {
|
||||
pc.Lock()
|
||||
pc.Write(framework.ContextKey(pod.Name), "never bind")
|
||||
pc.Write(framework.ContextKey(pod.Name), &contextData{data: "never bind"})
|
||||
pc.Unlock()
|
||||
}
|
||||
return nil
|
||||
@ -57,8 +68,10 @@ func (mc CommunicatingPlugin) PreBind(pc *framework.PluginContext, pod *v1.Pod,
|
||||
}
|
||||
pc.RLock()
|
||||
defer pc.RUnlock()
|
||||
if v, e := pc.Read(framework.ContextKey(pod.Name)); e == nil && v == "never bind" {
|
||||
return framework.NewStatus(framework.Unschedulable, "pod is not permitted")
|
||||
if v, e := pc.Read(framework.ContextKey(pod.Name)); e == nil {
|
||||
if value, ok := v.(*contextData); ok && value.data == "never bind" {
|
||||
return framework.NewStatus(framework.Unschedulable, "pod is not permitted")
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
@ -43,6 +43,7 @@ filegroup(
|
||||
go_test(
|
||||
name = "go_default_test",
|
||||
srcs = [
|
||||
"context_test.go",
|
||||
"framework_test.go",
|
||||
"interface_test.go",
|
||||
"registry_test.go",
|
||||
|
@ -27,7 +27,12 @@ const (
|
||||
)
|
||||
|
||||
// ContextData is a generic type for arbitrary data stored in PluginContext.
|
||||
type ContextData interface{}
|
||||
type ContextData interface {
|
||||
// Clone is an interface to make a copy of ContextData. For performance reasons,
|
||||
// clone should make shallow copies for members (e.g., slices or maps) that are not
|
||||
// impacted by PreFilter's optional AddPod/RemovePod methods.
|
||||
Clone() ContextData
|
||||
}
|
||||
|
||||
// ContextKey is the type of keys stored in PluginContext.
|
||||
type ContextKey string
|
||||
@ -48,6 +53,15 @@ func NewPluginContext() *PluginContext {
|
||||
}
|
||||
}
|
||||
|
||||
// Clone creates a copy of PluginContext and returns its pointer.
|
||||
func (c *PluginContext) Clone() *PluginContext {
|
||||
copy := NewPluginContext()
|
||||
for k, v := range c.storage {
|
||||
copy.Write(k, v.Clone())
|
||||
}
|
||||
return copy
|
||||
}
|
||||
|
||||
// Read retrieves data with the given "key" from PluginContext. If the key is not
|
||||
// present an error is returned.
|
||||
// This function is not thread safe. In multi-threaded code, lock should be
|
||||
|
66
pkg/scheduler/framework/v1alpha1/context_test.go
Normal file
66
pkg/scheduler/framework/v1alpha1/context_test.go
Normal file
@ -0,0 +1,66 @@
|
||||
/*
|
||||
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 v1alpha1
|
||||
|
||||
import (
|
||||
"testing"
|
||||
)
|
||||
|
||||
type fakeData struct {
|
||||
data string
|
||||
}
|
||||
|
||||
func (f *fakeData) Clone() ContextData {
|
||||
copy := &fakeData{
|
||||
data: f.data,
|
||||
}
|
||||
return copy
|
||||
}
|
||||
|
||||
func TestPluginContextClone(t *testing.T) {
|
||||
var key ContextKey = "key"
|
||||
data1 := "value1"
|
||||
data2 := "value2"
|
||||
|
||||
pc := NewPluginContext()
|
||||
originalValue := &fakeData{
|
||||
data: data1,
|
||||
}
|
||||
pc.Write(key, originalValue)
|
||||
pcCopy := pc.Clone()
|
||||
|
||||
valueCopy, err := pcCopy.Read(key)
|
||||
if err != nil {
|
||||
t.Errorf("failed to read copied value: %v", err)
|
||||
}
|
||||
if v, ok := valueCopy.(*fakeData); ok && v.data != data1 {
|
||||
t.Errorf("clone failed, got %q, expected %q", v.data, data1)
|
||||
}
|
||||
|
||||
originalValue.data = data2
|
||||
original, err := pc.Read(key)
|
||||
if err != nil {
|
||||
t.Errorf("failed to read original value: %v", err)
|
||||
}
|
||||
if v, ok := original.(*fakeData); ok && v.data != data2 {
|
||||
t.Errorf("original value should change, got %q, expected %q", v.data, data2)
|
||||
}
|
||||
|
||||
if v, ok := valueCopy.(*fakeData); ok && v.data != data1 {
|
||||
t.Errorf("cloned copy should not change, got %q, expected %q", v.data, data1)
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue
Block a user