|
1 | 1 | # Structured Merge and Diff
|
2 | 2 |
|
3 |
| -This repo contains code for implementing the Kubernetes "apply" operation. |
| 3 | +This repo contains code which implements the Kubernetes "apply" operation. |
4 | 4 |
|
5 |
| -It also contains test vectors for testing an implementation of apply. |
| 5 | +## What is the apply operation? |
| 6 | + |
| 7 | +We model resources in a control plane as having multiple "managers". Each |
| 8 | +manager is typically trying to manage only one aspect of a resource. The goal is |
| 9 | +to make it easy for disparate managers to make the changes they need without |
| 10 | +messing up the things that other managers are doing. In this system, both humans |
| 11 | +and machines (aka "controllers") act as managers. |
| 12 | + |
| 13 | +To do this, we explicitly track (using the fieldset data structure) which fields |
| 14 | +each manager is currently managing. |
| 15 | + |
| 16 | +Now, there are two basic mechanisms by which one modifies an object. |
| 17 | + |
| 18 | +PUT/PATCH: This is a write command that says: "Make the object look EXACTLY like |
| 19 | +X". |
| 20 | + |
| 21 | +APPLY: This is a write command that says: "The fields I manage should now look |
| 22 | +exactly like this (but I don't care about other fields)". |
| 23 | + |
| 24 | +For PUT/PATCH, we deduce which fields will be managed based on what is changing. |
| 25 | +For APPLY, the user is explicitly stating which fields they wish to manage (and |
| 26 | +therefore requesting deletion of any fields that they used to manage but stop |
| 27 | +mentioning). |
| 28 | + |
| 29 | +Any time a manager begins managing some new field, that field is removed from |
| 30 | +all other managers. If the manager is using the APPLY command, we call these |
| 31 | +conflicts, and will not proceed unless the user passes the "force" option. This |
| 32 | +prevents accidentally setting fields which some other entity is managing. |
| 33 | + |
| 34 | +PUT/PATCH always "force". They are mostly used by automated systems, which won't |
| 35 | +do anything productive with a new error type. |
| 36 | + |
| 37 | +## Components |
| 38 | + |
| 39 | +The operation has a few building blocks: |
| 40 | + |
| 41 | +* We define a targeted schema type in the schema package. (As a consequence of |
| 42 | + being well-targeted, it's much simpler than e.g. OpenAPI.) |
| 43 | +* We define a "field set" data structure, in the fieldpath package. A field path |
| 44 | + locates a field in an object, generally a "leaf" field for our purposes. A |
| 45 | + field set is a group of such paths. They can be stored efficiently in what |
| 46 | + amounts to a Trie. |
| 47 | +* We define a "value" type which stores an arbitrary object. |
| 48 | +* We define a "typed" package which combines "value" and "schema". Now we can |
| 49 | + validate that an object conforms to a schema, or compare two objects. |
| 50 | +* We define a "merge" package which uses all of the above concepts to implement |
| 51 | + the "apply" operation. |
| 52 | +* We will extensively test this. |
6 | 53 |
|
7 | 54 | ## Community, discussion, contribution, and support
|
8 | 55 |
|
|
0 commit comments