Refactor patch logic to use openapiv3 instead of v2/swagger - #446
Conversation
Codecov Report❌ Patch coverage is
📢 Thoughts on this report? Let us know! |
3c0f6f0 to
f1fb6ac
Compare
bc1b14d to
6a7bfdf
Compare
95a3276 to
8105dfd
Compare
805259a to
7821663
Compare
| name: grpc | ||
| - containerPort: 8080 | ||
| name: http | ||
| # We recommend that you do not configure a liveness probe on a production environment, as this can impact the availability of production databases. |
| # mysql needs ~100mb for startup; this leaves some headroom. | ||
| storage: 500Mi |
There was a problem hiding this comment.
This seems to make the tests more stable
| // The StatefulSet existing says nothing about the database accepting | ||
| // connections. Waiting on a ready replica means a pod that never starts | ||
| // surfaces here, instead of 5 minutes later as a connection refused. | ||
| if statefulSet.Status.ReadyReplicas < 1 { |
There was a problem hiding this comment.
Some extra defensiveness
| corev1.SchemeGroupVersion.WithResource("events"), | ||
| corev1.SchemeGroupVersion.WithResource("persistentvolumeclaims"), |
There was a problem hiding this comment.
Extra debug output that goes into artifacts
| } | ||
| } | ||
|
|
||
| resources, err := f.OpenAPISchema() |
There was a problem hiding this comment.
This was responsible for ~100mb of memory usage
| if err != nil { | ||
| return err | ||
| } | ||
| patchMetaResolver := config.NewV3PatchMetaResolver(openapi3.NewRoot(openAPIV3Client)) |
There was a problem hiding this comment.
We pass this resolver down so that we can fetch the objects as needed
There was a problem hiding this comment.
This file is what does the work of fetching those objects from the k8s API
| // Resolved here, at the only point that needs it, and with the | ||
| // GVK in hand -- which is what lets the v3 resolver fetch a | ||
| // single group-version instead of the whole cluster's schema. | ||
| lookupPatchMeta, err := resolver.LookupPatchMeta(gv.WithKind(*typeMeta.Kind)) |
There was a problem hiding this comment.
And this is where we actually do the lazy fetching
7821663 to
2c1a206
Compare
2c1a206 to
cb33119
Compare
| - "--innodb-use-native-aio=0" | ||
| - "--innodb-flush-method=fsync" |
There was a problem hiding this comment.
This also seems to be salient
There was a problem hiding this comment.
we haven't changed any of this in a long time, i'm unclear on why this is needed now. if the explanation here were true, the tests would never have passed?
There was a problem hiding this comment.
My assumption is that it's highly dependent on what the backing storage is/does, and therefore sensitive to exactly how CI is set up.
| - "--innodb-use-native-aio=0" | ||
| - "--innodb-flush-method=fsync" |
There was a problem hiding this comment.
we haven't changed any of this in a long time, i'm unclear on why this is needed now. if the explanation here were true, the tests would never have passed?
| // AssertDeploymentPatchedFunc asserts that a strategic merge patch actually | ||
| // reached the SpiceDB deployment, rather than merely failing to error. | ||
| // The container check is the primary part of the assertion. | ||
| func AssertDeploymentPatchedFunc(ctx context.Context, namespace string, kclient kubernetes.Interface) func(owner string, labels map[string]string, envName, envValue string) { |
There was a problem hiding this comment.
nit: isn't this really AssertDeploymentEnvVar?
| // failure. The database namespaces matter as much as the per-spec ones: a | ||
| // database that never becomes ready fails specs in BeforeEach, and nothing in | ||
| // the test namespaces explains why. | ||
| var dumpNamespacePrefixes = []string{"test", "postgres-", "mysql-", "cockroachdb-"} |
There was a problem hiding this comment.
| var dumpNamespacePrefixes = []string{"test", "postgres-", "mysql-", "cockroachdb-"} | |
| var dumpNamespacePrefixes = []string{"test", "postgres", "mysql", "cockroachdb"} |
super nit
| name = pod.Name + "-" + container.Name + "-previous.log" | ||
| } | ||
|
|
||
| logs, err := k.CoreV1().Pods(namespace).GetLogs(pod.Name, &corev1.PodLogOptions{ |
There was a problem hiding this comment.
I thought I had written a Ginkgo helper somewhere to tail pod logs we could re-use
There was a problem hiding this comment.
Tail in util_test.go? It seems like it's designed for asserting things about the logs on the side, rather than taking log output and directing it somewhere. I could use it but it's awkward.
| resolver := newTestPatchMetaResolver() | ||
|
|
||
| for _, gvk := range patchedKinds { | ||
| t.Run(gvk.Kind, func(t *testing.T) { |
Alternative to #445
Description
Under the old logic, the controller had to load the entirety of the API's swagger to construct the Strategic Patch Merges. This changes things to use the new OpenAPIv3 APIs provided by k8s, which reduces memory usage significantly, bringing down peak RSS from ~250mb to ~80:
(as measured using the new script)
Changes
patchmetafile that describes a resolver for various GVKs used by the controllerApplyPatchlook up the descriptions of the objects using that resolverTesting
Review. See that tests pass and are sane.