Open pradeepto opened 7 years ago
I don't like any of them. We want the tool to be user friendly and json-like
syntax is not going to do the job. Yeah, yaml
can be fragile, but still the best choice IMO.
Yaml might be best option for use, but I don't want to dismiss other formats without doing some research and gathering some pros and cons.
@kadel feel free to do so :)
Jsonnet syntax isn't that terrible
{
version: "0.1-dev",
services: [
{
name: "helloworld",
containers: [{
image: "tomaskral/nonroot-nginx",
ports: [{
port: "8080:80",
type: "external",
}]
}]
}]
}
And you'll gain immediatly templating/lint/variables without doing it internally. which is a great to share and reuse opencompose packages
{
version: "0.1-dev",
variables:: {
image: "tomaskral/nonroot-nginx"
}
services: [
{
name: "helloworld",
containers: [{
image: $.variables.image,
labels: ["service-version": $.version],
ports: [{
port: "8080:80",
type: "external",
}]
}]
}]
}
@ant31 True that. It is not terrible.
But what do you think will happen when the file grows a bit more? Those {,[ s are already getting me worried. As discussed with you, we see the power jsonnet has but I am worried about the readability of jsonnet based examples. But I am not still ruling it out.
I really need to be convinced before we move to jsonnet or anything else. Would you have other suggestions as well?
Just found out about https://github.com/vstakhov/libucl @ant31 @kadel @surajssd @containscafeine From it's readme :
Each UCL object can be serialized to one of the three supported formats: JSON - canonic json notation (with spaces indented structure); Compacted JSON - compact json notation (without spaces or newlines); Configuration - nginx like notation; YAML - yaml inlined notation.
Have a look.
Speaking of the transformation your are doing in the Go-code, they can all be done on the jsonnet side. IMO it would be awesome: configuration part would embed it's own library and let opencompose evolve freely and quickly without retro-compat issues. currently the flow is:
yaml-conf -> opencompose(transformation) -> kubernetes-resources -> opencompose/kubectl(management part)
Moving/embedding the transformation to the configuration is going to be a big win. You'll be able to reuse other jsonnet libraries and as said configuration becomes autonomous and users can extend easily and write new API that match better their usecase.
It depend on how the jsonnet library is created. It can be very light changes from current open-compose yaml syntax:
local opencompose = import opencompose.v1.jsonnet
opencompose.generate({
version: "0.1-dev",
services: [
{
name: "helloworld",
containers: [{
image: "tomaskral/nonroot-nginx",
ports: [{
port: "8080:80",
type: "external",
}]
}]
}]
})
The above example could generate all kubernetes resources without using the go client at all: the configuration embed what it needs:
jsonnet-conf -> kubernetes-resources -> opencompose/kubectl(management-part)
I already see several tickets like
Need secret
, Need imagePullPolicy
etc...
In one/two years, if the project continue I think that the whole opencompose api will not be simple anymore OR too limited from what Kubernetes offers.
I believe to be successful, opencompose should expose the full kubernetes power. Jsonnet would allow you to do it without mitigated your goal of having a Higher Level and extremely easy API to use.
example:
The user wants to add hostNetwork: true
but opencompose does't have constructor/api for it
local opencompose = import opencompose.v1.jsonnet
local resources = opencompose.generate({
version: "0.1-dev",
services: [
{
name: "helloworld",
containers: [{
image: "tomaskral/nonroot-nginx",
ports: [{
port: "8080:80",
type: "external",
}]
}]
}]
});
resources+: {
deployment+: {spec: {template: {spec: {hostNetwork: true}}}}
}
(Yes, it looks more complex, but it is only for advances usage when opencompose isn't offering abstraction)
The great thing here, is that we can also reuse existing efforts to abstract lower level API (like https://github.com/heptio/kube.libsonnet):
local kube = import "kube.libsonnet"
resources+: {deployment+: kube.DeploySpec.hostNework(true)}
Those {,[ s are already getting me worried
On the other hand I've seen so many people complaining about indentation from Yaml :) I can't count how many time I indented with the wrong key.
Jsonnet provide stackstrace and can be nicely integrated with IDE. So yes on first glance it's less attractive but in practice it is very convenient and easy to use.
# Missing templating variable
$ jsonnet wordpress/no-storage.jsonnet
RUNTIME ERROR: Field does not exist: badvar
no-storage.jsonnet:29:30-56 thunk <b>
# Missing a comma
$ jsonnet no-storage.jsonnet
STATIC ERROR: no-storage.jsonnet:31:8-26: Expected a comma before next array element.
Jsonnet is really powerful and has a tun of benefits. But I see one big problem with it:
If I'm ordinary web developer doing NodeJS or Ruby on Rails whole day and I see Jsonnet syntax I would probably be much more confused and scared from how complicated it looks then from looking at regular Kubernetes primitives :-(
If I'm ordinary web developer doing NodeJS
Json based configurations are pretty present: e.g package.json (http://browsenpm.org/package.json).
With all the above implemented (which are good) and I'm sure more will come, user will only switch from: looking in kubernetes doc to know how to do XXX in Kubernetes primitives, to opencompose documentation.
eg: this isn't obvious:
mounts:
- volumeName: db
mountPath: /app/store
volumeSubPath: foo/bar
readOnly: true
IMO there is no useless fields in the Kubernetes API, my concern is that overtime you'll going to rewrite the complete API. Probably in a more mnemonic and succinct way but still large and complex to learn.
On the other hand I completely understand your comments about Jsonnet/non-yaml and you're maybe right about them.
If I'm ordinary web developer doing NodeJS Json based configurations are pretty present: e.g package.json (http://browsenpm.org/package.json).
OK, I shouldn't have use NodeJS as example :smile:
IMO there is no useless fields in the Kubernetes API, my concern is that overtime you'll going to rewrite the complete API. Probably in a more mnemonic and succinct way but still large and complex to learn.
yep :unamused:, you are completely right. Those are valid concerns and this is the biggest risk with our current approach. If we end up rewriting everything from API we failed big time. Even I'm not convinced that this is best way to do it, right now we just don't have anything better :-(
I'm afraid that just adding templating in form of Jsonnet on top of Kubernetes primitives is not going to make it easier to write. I would even say that opposite is true :disappointed: But don't have any data to prove it, that is just my feeling
adding templating in form of Jsonnet on top of Kubernetes primitives is not going to make it easier to write
I did a small 'working' poc to show a concrete example, I tried to reuse more-or-less opencompose syntax: https://gist.github.com/ant31/882b642e8f6c29123919d92eca993590
that looks interesting 👍
can you share lib/opencompose.libsonnet
?
@kadel source: https://github.com/ant31/opencompose-jsonnet (it's like ~1 hour work so it's messy)
$ jsonnet cookieapp-opencompose.jsonnet
@kadel @ant31 @tnozicka @pradeepto
This is a really good and long discussion on how they decided what format to use for the dep
tool for Golang.
In the end they chose TOML over YAML and other formats.
Although their use-case was different (it was originally debating about comments in yaml/json), it gradually turned into a good analysis of all the different formats.
Besides, if we pick YAML it's still a superset of JSON so we'll get that too, regardless what the user chooses to write.
How about HCL? jsonnet?