-
Notifications
You must be signed in to change notification settings - Fork 1.1k
Conversation
return execKubeyaml(in, args) | ||
} | ||
|
||
func execKubeyaml(in []byte, args []string) ([]byte, error) { |
This comment was marked as abuse.
This comment was marked as abuse.
Sorry, something went wrong.
This comment was marked as abuse.
This comment was marked as abuse.
Sorry, something went wrong.
return execKubeyaml(in, args) | ||
} | ||
|
||
func execKubeyaml(in []byte, args []string) ([]byte, error) { |
This comment was marked as abuse.
This comment was marked as abuse.
Sorry, something went wrong.
This comment was marked as abuse.
This comment was marked as abuse.
Sorry, something went wrong.
This comment was marked as abuse.
This comment was marked as abuse.
Sorry, something went wrong.
This comment was marked as abuse.
This comment was marked as abuse.
Sorry, something went wrong.
This comment was marked as abuse.
This comment was marked as abuse.
Sorry, something went wrong.
This comment was marked as abuse.
This comment was marked as abuse.
Sorry, something went wrong.
This comment was marked as abuse.
This comment was marked as abuse.
Sorry, something went wrong.
This comment was marked as abuse.
This comment was marked as abuse.
Sorry, something went wrong.
This comment was marked as abuse.
This comment was marked as abuse.
Sorry, something went wrong.
IRL conversation: we could give kubeyaml a server mode, since it only needs to answer simple questions and doesn't need a sophisticated API or anything. That would let us run it as a sidecar, rather than an initContainer, removing some of the ickiness with |
Though this would make testing a bit harder. |
Should unit tests depend on kubeyaml at all, whether it's via We could:
|
Just noticed a problem. When we're updating then container-specific tag filters, we parse the configs. But while
|
docker/Dockerfile.flux
Outdated
@@ -18,6 +18,10 @@ WORKDIR /home/flux | |||
ENTRYPOINT [ "/sbin/tini", "--", "fluxd" ] | |||
RUN apk add --no-cache openssh ca-certificates tini 'git>=2.3.0' | |||
|
|||
# Get the kubeyaml binary (files) and put them on the path | |||
COPY --from=quay.io/squaremo/kubeyaml:0.1.0 /usr/lib/kubeyaml /usr/lib/kubeyaml/ |
This comment was marked as abuse.
This comment was marked as abuse.
Sorry, something went wrong.
This comment was marked as abuse.
This comment was marked as abuse.
Sorry, something went wrong.
This comment was marked as abuse.
This comment was marked as abuse.
Sorry, something went wrong.
This wipes out a bunch of regexp-(ab)using code, in favour of using a self-contained binary from an image, which is expected to be on the `$PATH`. For the tests, we have to have a `kubectl` in the `$PATH`. A small shell script shim suffices. To make the binary available in a pod, the kubeyaml image can be called as an initContainer, copying the files to a shared volume.
While kubeyaml does a good job of preserving comments and mostly a good job or preserving whitespace, it does end up reindenting blocks, and requoting string literals. Since these are still meaning-preserving changes, remove them from consideration by cooking the test cases a little.
It's not enough to be able to update images in a List resource, we must be able to recognise them in the first place. The Go YAML parser makes this a little tricky, because it doesn't give you access to the bytes (like `UnmarshalJSON` does), so if we want typed resources, we have to parse them generically and marshal them back out to bytes.
kubeyaml (now) supports updating annotations as well as images, with the same round-tripping properties. One wrinkle in the test code is that it relies on maps being sorted lexicographically when interpolated into templates. However, kubeyaml keeps the order in which things were added. Rather than add a lot of complication in the comparison of expected v. actual result, I have made the order explicit by using slices instead of maps. We can get rid of some duplication by using the resources package to parse manifests and thereby get policies.
To be able to use kubeyaml from within a pod, fluxd must have access to the binaries. We can simply build the files into the image using a multistage Dockerfile, and make sure they are on the `$PATH`. I took the opportunity to factor out the code that executes `kubeyaml`.
- We have many fewer requirements of YAMLs now - While we're documenting limitations: kubeyaml 0.2.1 preserves quotes, and thereby produces fewer spurious diffs, so update to that version rather than having to mention it
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Great work. Nicely organised PR too ✨
@@ -149,7 +149,6 @@ spec: | |||
metadata: | |||
labels: | |||
name: fluxy | |||
version: master-a000001 |
This comment was marked as abuse.
This comment was marked as abuse.
Sorry, something went wrong.
This comment was marked as abuse.
This comment was marked as abuse.
Sorry, something went wrong.
@@ -194,7 +193,6 @@ spec: | |||
metadata: | |||
labels: | |||
name: fluxy | |||
version: "1234567" |
This comment was marked as abuse.
This comment was marked as abuse.
Sorry, something went wrong.
return execKubeyaml(in, args) | ||
} | ||
|
||
func execKubeyaml(in []byte, args []string) ([]byte, error) { |
This comment was marked as abuse.
This comment was marked as abuse.
Sorry, something went wrong.
squaremo/kubeyaml
uses a round-tripping YAML parser, so can do a more reliable job at updating YAMLs. By using that, we can divest fluxd of lots of regexp use, and gain the ability to support List and multidoc YAMLs almost for free.We still have to get the
kubeyaml
executable files available to fluxd. The kubeyaml image happens to be (* I made it) based on alpine, so the binary will run in fluxd's container. In principle, we could just base fluxd on the kubeyaml file, but this is the wrong way around for them to compose. Instead, I use an implicit multistage Dockerfile to copy the files from the kubeyaml image.Because kubeyaml parses then serialises whole files, it will tend to reformat things. Once this is merged, we will see a few commits that have incidental changes, like reindented list items, or occasional changes in quoting.
There are a few corner cases* where this mangles a file because of bugs in the underlying YAML parser. Happily, we now verify that updates are correct (thanks to #1081), so releases that hit those bugs will fail rather than committing garbage. (*way fewer than in the regexp-based code! to be clear)
I have left the change of
[]byte
toio.Reader
at Sam's suggestion for another PR. Likewise, porting to a more general yamling library (i.e., py-yamler or something very close), so that we can do this incrementally -- kubeyaml is good enough for us to take this step.