Merge pull request #87908 from jpbetz/enable-smd-reflector

Bump to latest SMD to pick up performance optimizations

Kubernetes-commit: 86fcb30e5391a5494c8d83586f0911772a6949aa
This commit is contained in:
Kubernetes Publisher 2020-02-08 18:11:52 -08:00
commit 1c0edf621c
5 changed files with 229 additions and 43 deletions

10
Godeps/Godeps.json generated
View File

@ -588,19 +588,19 @@
}, },
{ {
"ImportPath": "k8s.io/api", "ImportPath": "k8s.io/api",
"Rev": "85a41f27a10c" "Rev": "d5ab0ddd8b73"
}, },
{ {
"ImportPath": "k8s.io/apimachinery", "ImportPath": "k8s.io/apimachinery",
"Rev": "52a338251bb2" "Rev": "fb45917aae8b"
}, },
{ {
"ImportPath": "k8s.io/client-go", "ImportPath": "k8s.io/client-go",
"Rev": "4b7e8bfcc145" "Rev": "c44f517f891f"
}, },
{ {
"ImportPath": "k8s.io/component-base", "ImportPath": "k8s.io/component-base",
"Rev": "616550b070ba" "Rev": "0d86229a457e"
}, },
{ {
"ImportPath": "k8s.io/gengo", "ImportPath": "k8s.io/gengo",
@ -620,7 +620,7 @@
}, },
{ {
"ImportPath": "sigs.k8s.io/structured-merge-diff/v3", "ImportPath": "sigs.k8s.io/structured-merge-diff/v3",
"Rev": "0fb62c1057dd" "Rev": "5e70324e7c1c"
}, },
{ {
"ImportPath": "sigs.k8s.io/yaml", "ImportPath": "sigs.k8s.io/yaml",

18
go.mod
View File

@ -44,22 +44,22 @@ require (
gopkg.in/square/go-jose.v2 v2.2.2 gopkg.in/square/go-jose.v2 v2.2.2
gopkg.in/yaml.v2 v2.2.8 gopkg.in/yaml.v2 v2.2.8
gotest.tools v2.2.0+incompatible // indirect gotest.tools v2.2.0+incompatible // indirect
k8s.io/api v0.0.0-20200207025841-85a41f27a10c k8s.io/api v0.0.0-20200209065837-d5ab0ddd8b73
k8s.io/apimachinery v0.0.0-20200207025655-52a338251bb2 k8s.io/apimachinery v0.0.0-20200209065656-fb45917aae8b
k8s.io/client-go v0.0.0-20200208144352-4b7e8bfcc145 k8s.io/client-go v0.0.0-20200209070100-c44f517f891f
k8s.io/component-base v0.0.0-20200207030544-616550b070ba k8s.io/component-base v0.0.0-20200209070609-0d86229a457e
k8s.io/klog v1.0.0 k8s.io/klog v1.0.0
k8s.io/kube-openapi v0.0.0-20200121204235-bf4fb3bd569c k8s.io/kube-openapi v0.0.0-20200121204235-bf4fb3bd569c
k8s.io/utils v0.0.0-20191217005138-9e5e9d854fcc k8s.io/utils v0.0.0-20191217005138-9e5e9d854fcc
sigs.k8s.io/structured-merge-diff/v3 v3.0.0-20200121225636-0fb62c1057dd sigs.k8s.io/structured-merge-diff/v3 v3.0.0-20200207200219-5e70324e7c1c
sigs.k8s.io/yaml v1.2.0 sigs.k8s.io/yaml v1.2.0
) )
replace ( replace (
golang.org/x/sys => golang.org/x/sys v0.0.0-20190813064441-fde4db37ae7a // pinned to release-branch.go1.13 golang.org/x/sys => golang.org/x/sys v0.0.0-20190813064441-fde4db37ae7a // pinned to release-branch.go1.13
golang.org/x/tools => golang.org/x/tools v0.0.0-20190821162956-65e3620a7ae7 // pinned to release-branch.go1.13 golang.org/x/tools => golang.org/x/tools v0.0.0-20190821162956-65e3620a7ae7 // pinned to release-branch.go1.13
k8s.io/api => k8s.io/api v0.0.0-20200207025841-85a41f27a10c k8s.io/api => k8s.io/api v0.0.0-20200209065837-d5ab0ddd8b73
k8s.io/apimachinery => k8s.io/apimachinery v0.0.0-20200207025655-52a338251bb2 k8s.io/apimachinery => k8s.io/apimachinery v0.0.0-20200209065656-fb45917aae8b
k8s.io/client-go => k8s.io/client-go v0.0.0-20200208144352-4b7e8bfcc145 k8s.io/client-go => k8s.io/client-go v0.0.0-20200209070100-c44f517f891f
k8s.io/component-base => k8s.io/component-base v0.0.0-20200207030544-616550b070ba k8s.io/component-base => k8s.io/component-base v0.0.0-20200209070609-0d86229a457e
) )

12
go.sum
View File

@ -361,10 +361,10 @@ gotest.tools v2.2.0+incompatible/go.mod h1:DsYFclhRJ6vuDpmuTbkuFWG+y2sxOXAzmJt81
honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
honnef.co/go/tools v0.0.0-20190106161140-3f1c8253044a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= honnef.co/go/tools v0.0.0-20190106161140-3f1c8253044a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
honnef.co/go/tools v0.0.0-20190523083050-ea95bdfd59fc/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= honnef.co/go/tools v0.0.0-20190523083050-ea95bdfd59fc/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
k8s.io/api v0.0.0-20200207025841-85a41f27a10c/go.mod h1:SA5EjO7X3UBpRgCFnqrgyCg0rXvBmN8QpNZ4Bvmv9js= k8s.io/api v0.0.0-20200209065837-d5ab0ddd8b73/go.mod h1:p/XFTiuxjo+0OlHcql2jDLBO6mxwx4J9xy7Sq9vRtnY=
k8s.io/apimachinery v0.0.0-20200207025655-52a338251bb2/go.mod h1:4JiEu5qfVX4iOPJG4zxNOGJ0HamEJ5OmJHxtHMChmZo= k8s.io/apimachinery v0.0.0-20200209065656-fb45917aae8b/go.mod h1:5X8oEhnd931nEg6/Nkumo00nT6ZsCLp2h7Xwd7Ym6P4=
k8s.io/client-go v0.0.0-20200208144352-4b7e8bfcc145/go.mod h1:ourVHU91vVd0R4YiJhW1FNlt3K+HtokZ5ImtcAbqVh4= k8s.io/client-go v0.0.0-20200209070100-c44f517f891f/go.mod h1:lrXl4vvqm+n6jlzJDxwcfMx2obCLSV1hYD1HuaL7WEc=
k8s.io/component-base v0.0.0-20200207030544-616550b070ba/go.mod h1:xqOLjWJL1P+sXGSeMoLVvN0UM/adtUwVUp/mwh5H518= k8s.io/component-base v0.0.0-20200209070609-0d86229a457e/go.mod h1:9W3ADuxIg84JdjKHNl3fh3XfShf7mxOdoPJHuCabJ/o=
k8s.io/gengo v0.0.0-20190128074634-0689ccc1d7d6/go.mod h1:ezvh/TsK7cY6rbqRK0oQQ8IAqLxYwwyPxAX1Pzy0ii0= k8s.io/gengo v0.0.0-20190128074634-0689ccc1d7d6/go.mod h1:ezvh/TsK7cY6rbqRK0oQQ8IAqLxYwwyPxAX1Pzy0ii0=
k8s.io/klog v0.0.0-20181102134211-b9b56d5dfc92/go.mod h1:Gq+BEi5rUBO/HRz0bTSXDUcqjScdoY3a9IHpCEIOOfk= k8s.io/klog v0.0.0-20181102134211-b9b56d5dfc92/go.mod h1:Gq+BEi5rUBO/HRz0bTSXDUcqjScdoY3a9IHpCEIOOfk=
k8s.io/klog v0.3.0/go.mod h1:Gq+BEi5rUBO/HRz0bTSXDUcqjScdoY3a9IHpCEIOOfk= k8s.io/klog v0.3.0/go.mod h1:Gq+BEi5rUBO/HRz0bTSXDUcqjScdoY3a9IHpCEIOOfk=
@ -376,8 +376,8 @@ k8s.io/utils v0.0.0-20191217005138-9e5e9d854fcc h1:MUttqhwRgupMiA5ps5F3d2/NLkU8E
k8s.io/utils v0.0.0-20191217005138-9e5e9d854fcc/go.mod h1:sZAwmy6armz5eXlNoLmJcl4F1QuKu7sr+mFQ0byX7Ew= k8s.io/utils v0.0.0-20191217005138-9e5e9d854fcc/go.mod h1:sZAwmy6armz5eXlNoLmJcl4F1QuKu7sr+mFQ0byX7Ew=
sigs.k8s.io/structured-merge-diff/v3 v3.0.0-20200116222232-67a7b8c61874 h1:0KsuGbLhWdIxv5DA1OnbFz5hI/Co9kuxMfMUa5YsAHY= sigs.k8s.io/structured-merge-diff/v3 v3.0.0-20200116222232-67a7b8c61874 h1:0KsuGbLhWdIxv5DA1OnbFz5hI/Co9kuxMfMUa5YsAHY=
sigs.k8s.io/structured-merge-diff/v3 v3.0.0-20200116222232-67a7b8c61874/go.mod h1:PlARxl6Hbt/+BC80dRLi1qAmnMqwqDg62YvvVkZjemw= sigs.k8s.io/structured-merge-diff/v3 v3.0.0-20200116222232-67a7b8c61874/go.mod h1:PlARxl6Hbt/+BC80dRLi1qAmnMqwqDg62YvvVkZjemw=
sigs.k8s.io/structured-merge-diff/v3 v3.0.0-20200121225636-0fb62c1057dd h1:RtLwJkS5lCLrbjdIqQdKiwZ6LrlGuLVdIcVhkUfsaIA= sigs.k8s.io/structured-merge-diff/v3 v3.0.0-20200207200219-5e70324e7c1c h1:xQP7F7Lntt2dtYmg12WPQHObOrAyPHlMWP1JVSa79GM=
sigs.k8s.io/structured-merge-diff/v3 v3.0.0-20200121225636-0fb62c1057dd/go.mod h1:PlARxl6Hbt/+BC80dRLi1qAmnMqwqDg62YvvVkZjemw= sigs.k8s.io/structured-merge-diff/v3 v3.0.0-20200207200219-5e70324e7c1c/go.mod h1:PlARxl6Hbt/+BC80dRLi1qAmnMqwqDg62YvvVkZjemw=
sigs.k8s.io/yaml v1.1.0 h1:4A07+ZFc2wgJwo8YNlQpr1rVlgUDlxXHhPJciaPY5gs= sigs.k8s.io/yaml v1.1.0 h1:4A07+ZFc2wgJwo8YNlQpr1rVlgUDlxXHhPJciaPY5gs=
sigs.k8s.io/yaml v1.1.0/go.mod h1:UJmg0vDUVViEyp3mgSv9WPwZCDxu4rQW1olrI1uml+o= sigs.k8s.io/yaml v1.1.0/go.mod h1:UJmg0vDUVViEyp3mgSv9WPwZCDxu4rQW1olrI1uml+o=
sigs.k8s.io/yaml v1.2.0 h1:kr/MCeFWJWTwyaHoR9c8EjH9OumOmoF9YGiZd7lFm/Q= sigs.k8s.io/yaml v1.2.0 h1:kr/MCeFWJWTwyaHoR9c8EjH9OumOmoF9YGiZd7lFm/Q=

View File

@ -33,9 +33,15 @@ import (
"k8s.io/apimachinery/pkg/apis/meta/v1/unstructured" "k8s.io/apimachinery/pkg/apis/meta/v1/unstructured"
"k8s.io/apimachinery/pkg/runtime" "k8s.io/apimachinery/pkg/runtime"
"k8s.io/apimachinery/pkg/runtime/schema" "k8s.io/apimachinery/pkg/runtime/schema"
"k8s.io/apimachinery/pkg/runtime/serializer"
"k8s.io/apiserver/pkg/endpoints/handlers/fieldmanager" "k8s.io/apiserver/pkg/endpoints/handlers/fieldmanager"
"k8s.io/apiserver/pkg/endpoints/handlers/fieldmanager/internal"
"k8s.io/kube-openapi/pkg/util/proto" "k8s.io/kube-openapi/pkg/util/proto"
prototesting "k8s.io/kube-openapi/pkg/util/proto/testing" prototesting "k8s.io/kube-openapi/pkg/util/proto/testing"
"sigs.k8s.io/structured-merge-diff/v3/fieldpath"
"sigs.k8s.io/structured-merge-diff/v3/merge"
"sigs.k8s.io/structured-merge-diff/v3/typed"
"sigs.k8s.io/yaml" "sigs.k8s.io/yaml"
) )
@ -45,9 +51,17 @@ var fakeSchema = prototesting.Fake{
"api", "openapi-spec", "swagger.json"), "api", "openapi-spec", "swagger.json"),
} }
type fakeObjectConvertor struct{} type fakeObjectConvertor struct {
converter merge.Converter
apiVersion fieldpath.APIVersion
}
func (c *fakeObjectConvertor) Convert(in, out, context interface{}) error { func (c *fakeObjectConvertor) Convert(in, out, context interface{}) error {
if typedValue, ok := in.(*typed.TypedValue); ok {
var err error
out, err = c.converter.Convert(typedValue, c.apiVersion)
return err
}
out = in out = in
return nil return nil
} }
@ -71,18 +85,14 @@ type TestFieldManager struct {
} }
func NewTestFieldManager(gvk schema.GroupVersionKind) TestFieldManager { func NewTestFieldManager(gvk schema.GroupVersionKind) TestFieldManager {
d, err := fakeSchema.OpenAPISchema() m := NewFakeOpenAPIModels()
if err != nil { tc := NewFakeTypeConverter(m)
panic(err)
}
m, err := proto.NewOpenAPIData(d)
if err != nil {
panic(err)
}
converter := internal.NewVersionConverter(tc, &fakeObjectConvertor{}, gvk.GroupVersion())
apiVersion := fieldpath.APIVersion(gvk.GroupVersion().String())
f, err := fieldmanager.NewStructuredMergeManager( f, err := fieldmanager.NewStructuredMergeManager(
m, m,
&fakeObjectConvertor{}, &fakeObjectConvertor{converter, apiVersion},
&fakeObjectDefaulter{}, &fakeObjectDefaulter{},
gvk.GroupVersion(), gvk.GroupVersion(),
gvk.GroupVersion(), gvk.GroupVersion(),
@ -102,6 +112,26 @@ func NewTestFieldManager(gvk schema.GroupVersionKind) TestFieldManager {
} }
} }
func NewFakeTypeConverter(m proto.Models) internal.TypeConverter {
tc, err := internal.NewTypeConverter(m, false)
if err != nil {
panic(fmt.Sprintf("Failed to build TypeConverter: %v", err))
}
return tc
}
func NewFakeOpenAPIModels() proto.Models {
d, err := fakeSchema.OpenAPISchema()
if err != nil {
panic(err)
}
m, err := proto.NewOpenAPIData(d)
if err != nil {
panic(err)
}
return m
}
func (f *TestFieldManager) Reset() { func (f *TestFieldManager) Reset() {
f.liveObj = f.emptyObj.DeepCopyObject() f.liveObj = f.emptyObj.DeepCopyObject()
} }
@ -393,16 +423,24 @@ func BenchmarkNewObject(b *testing.B) {
obj: getObjectBytes("endpoints.yaml"), obj: getObjectBytes("endpoints.yaml"),
}, },
} }
scheme := runtime.NewScheme()
if err := corev1.AddToScheme(scheme); err != nil {
b.Fatalf("Failed to add to scheme: %v", err)
}
for _, test := range tests { for _, test := range tests {
b.Run(test.gvk.Kind, func(b *testing.B) { b.Run(test.gvk.Kind, func(b *testing.B) {
f := NewTestFieldManager(test.gvk) f := NewTestFieldManager(test.gvk)
newObj := &unstructured.Unstructured{Object: map[string]interface{}{}} decoder := serializer.NewCodecFactory(scheme).UniversalDecoder(test.gvk.GroupVersion())
if err := yaml.Unmarshal(test.obj, &newObj.Object); err != nil { newObj, err := runtime.Decode(decoder, test.obj)
if err != nil {
b.Fatalf("Failed to parse yaml object: %v", err) b.Fatalf("Failed to parse yaml object: %v", err)
} }
newObj.SetManagedFields([]metav1.ManagedFieldsEntry{ objMeta, err := meta.Accessor(newObj)
if err != nil {
b.Fatalf("Failed to get object meta: %v", err)
}
objMeta.SetManagedFields([]metav1.ManagedFieldsEntry{
{ {
Manager: "default", Manager: "default",
Operation: "Update", Operation: "Update",
@ -463,6 +501,152 @@ func BenchmarkNewObject(b *testing.B) {
} }
} }
func toUnstructured(b *testing.B, o runtime.Object) *unstructured.Unstructured {
u, err := runtime.DefaultUnstructuredConverter.ToUnstructured(o)
if err != nil {
b.Fatalf("Failed to unmarshal to json: %v", err)
}
return &unstructured.Unstructured{Object: u}
}
func BenchmarkConvertObjectToTyped(b *testing.B) {
tests := []struct {
gvk schema.GroupVersionKind
obj []byte
}{
{
gvk: schema.FromAPIVersionAndKind("v1", "Pod"),
obj: getObjectBytes("pod.yaml"),
},
{
gvk: schema.FromAPIVersionAndKind("v1", "Node"),
obj: getObjectBytes("node.yaml"),
},
{
gvk: schema.FromAPIVersionAndKind("v1", "Endpoints"),
obj: getObjectBytes("endpoints.yaml"),
},
}
scheme := runtime.NewScheme()
if err := corev1.AddToScheme(scheme); err != nil {
b.Fatalf("Failed to add to scheme: %v", err)
}
for _, test := range tests {
b.Run(test.gvk.Kind, func(b *testing.B) {
decoder := serializer.NewCodecFactory(scheme).UniversalDecoder(test.gvk.GroupVersion())
m := NewFakeOpenAPIModels()
typeConverter := NewFakeTypeConverter(m)
structured, err := runtime.Decode(decoder, test.obj)
if err != nil {
b.Fatalf("Failed to parse yaml object: %v", err)
}
b.Run("structured", func(b *testing.B) {
b.ReportAllocs()
b.RunParallel(func(pb *testing.PB) {
for pb.Next() {
_, err := typeConverter.ObjectToTyped(structured)
if err != nil {
b.Errorf("Error in ObjectToTyped: %v", err)
}
}
})
})
unstructured := toUnstructured(b, structured)
b.Run("unstructured", func(b *testing.B) {
b.ReportAllocs()
b.RunParallel(func(pb *testing.PB) {
for pb.Next() {
_, err := typeConverter.ObjectToTyped(unstructured)
if err != nil {
b.Errorf("Error in ObjectToTyped: %v", err)
}
}
})
})
})
}
}
func BenchmarkCompare(b *testing.B) {
tests := []struct {
gvk schema.GroupVersionKind
obj []byte
}{
{
gvk: schema.FromAPIVersionAndKind("v1", "Pod"),
obj: getObjectBytes("pod.yaml"),
},
{
gvk: schema.FromAPIVersionAndKind("v1", "Node"),
obj: getObjectBytes("node.yaml"),
},
{
gvk: schema.FromAPIVersionAndKind("v1", "Endpoints"),
obj: getObjectBytes("endpoints.yaml"),
},
}
scheme := runtime.NewScheme()
if err := corev1.AddToScheme(scheme); err != nil {
b.Fatalf("Failed to add to scheme: %v", err)
}
for _, test := range tests {
b.Run(test.gvk.Kind, func(b *testing.B) {
decoder := serializer.NewCodecFactory(scheme).UniversalDecoder(test.gvk.GroupVersion())
m := NewFakeOpenAPIModels()
typeConverter := NewFakeTypeConverter(m)
structured, err := runtime.Decode(decoder, test.obj)
if err != nil {
b.Fatal(err)
}
tv1, err := typeConverter.ObjectToTyped(structured)
if err != nil {
b.Errorf("Error in ObjectToTyped: %v", err)
}
tv2, err := typeConverter.ObjectToTyped(structured)
if err != nil {
b.Errorf("Error in ObjectToTyped: %v", err)
}
b.Run("structured", func(b *testing.B) {
b.ReportAllocs()
for n := 0; n < b.N; n++ {
_, err = tv1.Compare(tv2)
if err != nil {
b.Errorf("Error in ObjectToTyped: %v", err)
}
}
})
unstructured := toUnstructured(b, structured)
utv1, err := typeConverter.ObjectToTyped(unstructured)
if err != nil {
b.Errorf("Error in ObjectToTyped: %v", err)
}
utv2, err := typeConverter.ObjectToTyped(unstructured)
if err != nil {
b.Errorf("Error in ObjectToTyped: %v", err)
}
b.Run("unstructured", func(b *testing.B) {
b.ReportAllocs()
b.RunParallel(func(pb *testing.PB) {
for pb.Next() {
_, err = utv1.Compare(utv2)
if err != nil {
b.Errorf("Error in ObjectToTyped: %v", err)
}
}
})
})
})
}
}
func BenchmarkRepeatedUpdate(b *testing.B) { func BenchmarkRepeatedUpdate(b *testing.B) {
f := NewTestFieldManager(schema.FromAPIVersionAndKind("v1", "Pod")) f := NewTestFieldManager(schema.FromAPIVersionAndKind("v1", "Pod"))
podBytes := getObjectBytes("pod.yaml") podBytes := getObjectBytes("pod.yaml")

View File

@ -49,11 +49,12 @@ var _ TypeConverter = DeducedTypeConverter{}
// ObjectToTyped converts an object into a TypedValue with a "deduced type". // ObjectToTyped converts an object into a TypedValue with a "deduced type".
func (DeducedTypeConverter) ObjectToTyped(obj runtime.Object) (*typed.TypedValue, error) { func (DeducedTypeConverter) ObjectToTyped(obj runtime.Object) (*typed.TypedValue, error) {
u, err := runtime.DefaultUnstructuredConverter.ToUnstructured(obj) switch o := obj.(type) {
if err != nil { case *unstructured.Unstructured:
return nil, err return typed.DeducedParseableType.FromUnstructured(o.UnstructuredContent())
default:
return typed.DeducedParseableType.FromStructured(obj)
} }
return typed.DeducedParseableType.FromUnstructured(u)
} }
// TypedToObject transforms the typed value into a runtime.Object. That // TypedToObject transforms the typed value into a runtime.Object. That
@ -80,16 +81,17 @@ func NewTypeConverter(models proto.Models, preserveUnknownFields bool) (TypeConv
} }
func (c *typeConverter) ObjectToTyped(obj runtime.Object) (*typed.TypedValue, error) { func (c *typeConverter) ObjectToTyped(obj runtime.Object) (*typed.TypedValue, error) {
u, err := runtime.DefaultUnstructuredConverter.ToUnstructured(obj)
if err != nil {
return nil, err
}
gvk := obj.GetObjectKind().GroupVersionKind() gvk := obj.GetObjectKind().GroupVersionKind()
t := c.parser.Type(gvk) t := c.parser.Type(gvk)
if t == nil { if t == nil {
return nil, newNoCorrespondingTypeError(gvk) return nil, newNoCorrespondingTypeError(gvk)
} }
return t.FromUnstructured(u) switch o := obj.(type) {
case *unstructured.Unstructured:
return t.FromUnstructured(o.UnstructuredContent())
default:
return t.FromStructured(obj)
}
} }
func (c *typeConverter) TypedToObject(value *typed.TypedValue) (runtime.Object, error) { func (c *typeConverter) TypedToObject(value *typed.TypedValue) (runtime.Object, error) {