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",
"Rev": "85a41f27a10c"
"Rev": "d5ab0ddd8b73"
},
{
"ImportPath": "k8s.io/apimachinery",
"Rev": "52a338251bb2"
"Rev": "fb45917aae8b"
},
{
"ImportPath": "k8s.io/client-go",
"Rev": "4b7e8bfcc145"
"Rev": "c44f517f891f"
},
{
"ImportPath": "k8s.io/component-base",
"Rev": "616550b070ba"
"Rev": "0d86229a457e"
},
{
"ImportPath": "k8s.io/gengo",
@ -620,7 +620,7 @@
},
{
"ImportPath": "sigs.k8s.io/structured-merge-diff/v3",
"Rev": "0fb62c1057dd"
"Rev": "5e70324e7c1c"
},
{
"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/yaml.v2 v2.2.8
gotest.tools v2.2.0+incompatible // indirect
k8s.io/api v0.0.0-20200207025841-85a41f27a10c
k8s.io/apimachinery v0.0.0-20200207025655-52a338251bb2
k8s.io/client-go v0.0.0-20200208144352-4b7e8bfcc145
k8s.io/component-base v0.0.0-20200207030544-616550b070ba
k8s.io/api v0.0.0-20200209065837-d5ab0ddd8b73
k8s.io/apimachinery v0.0.0-20200209065656-fb45917aae8b
k8s.io/client-go v0.0.0-20200209070100-c44f517f891f
k8s.io/component-base v0.0.0-20200209070609-0d86229a457e
k8s.io/klog v1.0.0
k8s.io/kube-openapi v0.0.0-20200121204235-bf4fb3bd569c
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
)
replace (
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
k8s.io/api => k8s.io/api v0.0.0-20200207025841-85a41f27a10c
k8s.io/apimachinery => k8s.io/apimachinery v0.0.0-20200207025655-52a338251bb2
k8s.io/client-go => k8s.io/client-go v0.0.0-20200208144352-4b7e8bfcc145
k8s.io/component-base => k8s.io/component-base v0.0.0-20200207030544-616550b070ba
k8s.io/api => k8s.io/api v0.0.0-20200209065837-d5ab0ddd8b73
k8s.io/apimachinery => k8s.io/apimachinery v0.0.0-20200209065656-fb45917aae8b
k8s.io/client-go => k8s.io/client-go v0.0.0-20200209070100-c44f517f891f
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-20190106161140-3f1c8253044a/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/apimachinery v0.0.0-20200207025655-52a338251bb2/go.mod h1:4JiEu5qfVX4iOPJG4zxNOGJ0HamEJ5OmJHxtHMChmZo=
k8s.io/client-go v0.0.0-20200208144352-4b7e8bfcc145/go.mod h1:ourVHU91vVd0R4YiJhW1FNlt3K+HtokZ5ImtcAbqVh4=
k8s.io/component-base v0.0.0-20200207030544-616550b070ba/go.mod h1:xqOLjWJL1P+sXGSeMoLVvN0UM/adtUwVUp/mwh5H518=
k8s.io/api v0.0.0-20200209065837-d5ab0ddd8b73/go.mod h1:p/XFTiuxjo+0OlHcql2jDLBO6mxwx4J9xy7Sq9vRtnY=
k8s.io/apimachinery v0.0.0-20200209065656-fb45917aae8b/go.mod h1:5X8oEhnd931nEg6/Nkumo00nT6ZsCLp2h7Xwd7Ym6P4=
k8s.io/client-go v0.0.0-20200209070100-c44f517f891f/go.mod h1:lrXl4vvqm+n6jlzJDxwcfMx2obCLSV1hYD1HuaL7WEc=
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/klog v0.0.0-20181102134211-b9b56d5dfc92/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=
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-20200121225636-0fb62c1057dd h1:RtLwJkS5lCLrbjdIqQdKiwZ6LrlGuLVdIcVhkUfsaIA=
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 h1:xQP7F7Lntt2dtYmg12WPQHObOrAyPHlMWP1JVSa79GM=
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/go.mod h1:UJmg0vDUVViEyp3mgSv9WPwZCDxu4rQW1olrI1uml+o=
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/runtime"
"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/internal"
"k8s.io/kube-openapi/pkg/util/proto"
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"
)
@ -45,9 +51,17 @@ var fakeSchema = prototesting.Fake{
"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 {
if typedValue, ok := in.(*typed.TypedValue); ok {
var err error
out, err = c.converter.Convert(typedValue, c.apiVersion)
return err
}
out = in
return nil
}
@ -71,18 +85,14 @@ type TestFieldManager struct {
}
func NewTestFieldManager(gvk schema.GroupVersionKind) TestFieldManager {
d, err := fakeSchema.OpenAPISchema()
if err != nil {
panic(err)
}
m, err := proto.NewOpenAPIData(d)
if err != nil {
panic(err)
}
m := NewFakeOpenAPIModels()
tc := NewFakeTypeConverter(m)
converter := internal.NewVersionConverter(tc, &fakeObjectConvertor{}, gvk.GroupVersion())
apiVersion := fieldpath.APIVersion(gvk.GroupVersion().String())
f, err := fieldmanager.NewStructuredMergeManager(
m,
&fakeObjectConvertor{},
&fakeObjectConvertor{converter, apiVersion},
&fakeObjectDefaulter{},
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() {
f.liveObj = f.emptyObj.DeepCopyObject()
}
@ -393,16 +423,24 @@ func BenchmarkNewObject(b *testing.B) {
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) {
f := NewTestFieldManager(test.gvk)
newObj := &unstructured.Unstructured{Object: map[string]interface{}{}}
if err := yaml.Unmarshal(test.obj, &newObj.Object); err != nil {
decoder := serializer.NewCodecFactory(scheme).UniversalDecoder(test.gvk.GroupVersion())
newObj, err := runtime.Decode(decoder, test.obj)
if err != nil {
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",
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) {
f := NewTestFieldManager(schema.FromAPIVersionAndKind("v1", "Pod"))
podBytes := getObjectBytes("pod.yaml")

View File

@ -49,11 +49,12 @@ var _ TypeConverter = DeducedTypeConverter{}
// ObjectToTyped converts an object into a TypedValue with a "deduced type".
func (DeducedTypeConverter) ObjectToTyped(obj runtime.Object) (*typed.TypedValue, error) {
u, err := runtime.DefaultUnstructuredConverter.ToUnstructured(obj)
if err != nil {
return nil, err
switch o := obj.(type) {
case *unstructured.Unstructured:
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
@ -80,16 +81,17 @@ func NewTypeConverter(models proto.Models, preserveUnknownFields bool) (TypeConv
}
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()
t := c.parser.Type(gvk)
if t == nil {
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) {