dockerdocker-composejsonnet

How to use Jsonnet to create Docker Compose File with Alias


In am using jsonnet to create docker compose file. I am at just initial stages, and I need an alias &image because I will reuse this in other section later.

function(spec, service) {
  version: spec.version.compose_version,
  services: {
    [service + '-primary']: {
      image: '&image ' + spec.registry + '/' + service  ':' + spec.version
    }
  }
}

But this will output

"services":
  "ourproduct-primary":
    "image": "&image mycompany.com/ourproduct:${VERSION:-master}"
"version": "3.9"

I think this is not valid as &image and the link are both enclosed in same double quotes, I don't know how to solve.

Also is there a way to remove the double quotes? So it would look like this?

version: '3.9'

services:
  ourproduct-primary:
    image: &image mycompany.com/ourproduct:${VERSION:-master}

I am using manifestYamlDoc

function(spec){
  ['compose.%s.yaml' % service]: std.manifestYamlDoc(services[service](spec, service))
  for service in spec.services
}

Solution

  • As surely already found, std.manifestYamlDoc() doesn't have a flag to unquote values (as it does have quote_keys=false), but even other ad-hoc tools like yq will find the &, take it verbatim, then quote it (see output#1 below).

    I think the only solution is to post-replace some arbitrary string very late in the CLI invocation:

    src: foo.libsonnet

    // foo.libsonnet
    function(spec, service) {
      services: {
        [service + '-primary']: {
          image: 'YAML_ALIASimage ' + spec.registry + '/' + service + ':' + spec.version,
        },
      },
    }
    

    src: foo.jsonnet

    // foo.jsonnet
    local libfoo = import 'foo.libsonnet';
    
    std.manifestYamlDoc(
      { version: '3.9' }
      + libfoo({ registry: 'docker.io/bar', version: '${VERSION:-master}' }, 'baz')
    )
    

    output#1

    Note that yq even quotes it:

    $ jsonnet -S foo.jsonnet  | sed 's/YAML_ALIAS/\&/' | yq -y .
    services:
      baz-primary:
        image: '&image docker.io/bar/baz:${VERSION:-master}'
    version: '3.9'
    

    output#2

    Late post-processing ftw (same as output#1 but changed piping order):

    jsonnet -S foo.jsonnet  | yq -y . | sed 's/YAML_ALIAS/\&/'
    services:
      baz-primary:
        image: &image docker.io/bar/baz:${VERSION:-master}
    version: '3.9'