-
Notifications
You must be signed in to change notification settings - Fork 2k
[K8s] Do env-variable expansion on the uninterpreted Config files #974
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[K8s] Do env-variable expansion on the uninterpreted Config files #974
Conversation
|
This is an excellent example of why the Compose file YAML should not be used as part of the API. The API should have its own types and the client should translate the compose file representation into the API types (just like with swarm mode). That way updates to the Compose file on the client don't unexpected break the API. |
|
@dnephin agreed. That is also why we did that for v1beta2 :) |
16442b4 to
270b9eb
Compare
| return errors.Errorf("Please specify only one compose file (with --compose-file).") | ||
| } | ||
|
|
||
| // due to env var expansion logic (and the need to conserve the same compose version as original file) |
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.
the need to conserve the same compose version as original file
Do we need that ?
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.
At the beginning, I wanted to just override the original composefile version with the latest supported by the cli (in order to align the "long-formats" generating by marshalling composetypes.Config with the version it is supported in), but after a bit of thinking I found that it was a bad idea: if in a future version of the CLI we introduce a new compose schema version, we will generate composefiles that the server-side can't understand if not updated (and we don't want to break compatibility with Docker EE for example).
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.
@simonferquel this is only for v1beta1 api (compose controller) right ? we know which version we support on that release of the controller, so really, we could, for this case only, decide of a version and never update it (until we drop support for v1beta1 👼 ). It's a special case anyway so let's make the "fix" the simplest.
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.
I don't think keeping an old config structure and implementing conversion from latest to this reference version is simpler than just doing the variable expansion on non-interpreted config files (this PR basically just expose exiting code to the kubernetes subpackage)
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.
I don't think keeping an old config structure and implementing conversion from latest to this reference version is simpler than just doing the variable expansion on non-interpreted config files (this PR basically just expose exiting code to the kubernetes subpackage)
Not sure I get that one. We don't keep an old structure anywhere.
As is, we do interpolation twice and use a different "config" between what is sent (just the map serialized) and what's used later (to wait for it to be ready, etc..). This breaks behavior now or maybe more in the future. As an example, this mean we don't call LoadService anymore (for the composefile we send), and thus we won't parse the envfile and update the environment for the service(s) — this is something we do as of now — same for resolveVolumePaths (although it's kinda broken #966).
With that PR, what will be the behavior for v1beta2 implemented in #899 ?
The v1beta1 api version support composefile from 3.0 to 3.x in the first version of the compose controller right ?
// data/config_schema_v3.0.json
// data/config_schema_v3.1.json
// data/config_schema_v3.2.json
// data/config_schema_v3.3.json
// data/config_schema_v3.4.jsonSo here are my thoughs:
- Even with newer version of the controller, we should make the assumption that the
v1beta1api endpoint does not support composefile version higher (to make sure we don't have some weird behavior, like having different behavior between toov1beta1endpoint served by different controller version). - That means we can/should know for sure in the CLI, which version of the composefile format we can and cannot send to the
v1beta1endpoint. Aslong format for describing ports has been introduced in 3.2, we know for a fact thatv1beta1supports that too. That means, we can/should send the compose file to thev1beta1asversion: "3.4"all the time if necessary (or at least3.2if it's lower than that). - If we need to "customize" the way the structure is marshalled back to a
yamlfor a specific version (from the current one to "3.x"), then it should be on the struct itself.
👍 on this. I think the CLI can error out if a Compose file with greater version than v1beta1 supports is used. |
|
Ok, so we would have to be very careful anytime the composetypes.Config (or any of its nested struct) is updated, that we don't replace constructs from v3.5 with a different representation (e.g. that we only add fields). (v3.5 is the latest format supported in ee) |
270b9eb to
5aff96f
Compare
|
Done that. Also added a v3.5 schema validation of the resulting composefile after marshalling the composetypes.Config |
|
@vdemeester does it fit you ? |
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.
LGTM 🐯
(honestly I would have prefered "3.4" because it's what 0.1.x version of controller supports)
|
0.1.x only shipped with a private beta of Docker for Mac, we don't want to support it any way (and docker for desktop ships its own version of the docker CLI aligned with the engine/kubernetes integration anyway) |
Right, but the image is there and public (I think ?) so it "could" still be used. I know we don't support it (as of Docker inc.), but if the there is no need to use 3.5 over 3.4 for |
| metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" | ||
| ) | ||
|
|
||
| const v1beta1MaxComposeVersion = "3.5" |
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.
Can we move this constant to the apiv1beta1 package? It should be the package responsibility to know which compose version it can handle.
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.
And maybe we should add one also for v1beta2, and generalize the process?
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.
@silvin-lubecki we don't need one for v1beta2 as we send a struct that is not the composefile, this it has nothing to do with the composefile version
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.
Good point 😅
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.
But I think my first comment is still valid.
| return nil, err | ||
| } | ||
| if err = schema.Validate(resparsedConfig, v1beta1MaxComposeVersion); err != nil { | ||
| return nil, errors.Wrapf(err, "the generated compose yaml file is invalid with v%s", v1beta1MaxComposeVersion) |
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.
Remove "generated" in the message? I don't know if it will be a useful information for the user?
| }, | ||
| Spec: apiv1beta1.StackSpec{ | ||
| ComposeFile: `version: "3.1" | ||
| ComposeFile: `version: "3.5" |
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.
Add a test with a compose file which fails with a 3.6 version?
|
@silvin-lubecki I've moved the const declaration and added a test for v3.6 files |
|
ping @simonferquel this needs a rebase |
Signed-off-by: Simon Ferquel <simon.ferquel@docker.com>
8ae6e4d to
f766aff
Compare
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.
LGTM, thanks!
|
I think all comments were addressed, so merging |

Formed in 2009, the Archive Team (not to be confused with the archive.org Archive-It Team) is a rogue archivist collective dedicated to saving copies of rapidly dying or deleted websites for the sake of history and digital heritage. The group is 100% composed of volunteers and interested parties, and has expanded into a large amount of related projects for saving online and digital history.

This fix an issue where composefiles like
get translated into
The problem here is that the long format for describing ports has been
introduced in 3.2 and so, the generated compose file is invalid.
I thought first about just always use latest version information to
override the output composefile version, but that would just make the
problem worse once we introduce a new compose file schema in the CLI
that is not supported on the server side.
This PR makes it possible to interpolate the compose files without
converting them into composetypes.Config (but only work on the loaded
config file format:
map[string]interface{}. This way, we don't expandshort representations into long ones, and don't risk breaking original
compose files.