0

I have a yaml file called original.yml with the following contents:

version: '2'
services:
  vendor-app:
    image: vendor/vendor-app@sha256:f9db328fe5eed87f89cc0390a91c65eb92351fedda8a0c833b30c9147bd7ba07
    logging:
      driver: json-file
      options:
        max-size: "50m"
        max-file: "2"
    volumes:
    - /my_vol
    labels:
      io.rancher.container.pull_image: always
      com.vendor-app.builder.version: "3bc55d00c"
      com.vendor-app.built: "Mon, 01 Jan 2021 19:32:24 -0000"

  myservice:
    image: myregistry/myservice
    logging:
      driver: json-file
      options:
        max-size: "50m"
        max-file: "2"
    volumes:
    - /my_vol2
    labels:
      io.rancher.container.pull_image: always

I have another yaml file, I will call it vendor.yml that I get from vendor periodically, with the following content:

version: '2'
services:
  vendor-app:
    image: vendor/vendor-app@sha256:ba065e9a04478fc17fd5b61b8c558616b7e9acba105668ef786f084545c32778
    logging:
      driver: json-file
      options:
        max-size: "50m"
        max-file: "20"
    volumes:
    - /my_vol
    labels:
      com.vendor-app.builder.version: "7766jjc"
      com.vendor-app.built: "Fri, 14 Dec 2018 20:50:35 -0000"

I would like to replace image in original.yml from image in vendor.yml, and merge labels from vendor.yml with the existing labels in original.yml. Basically the end result should be the following :

services:
  vendor-app:
    image: vendor/vendor-app@sha256:ba065e9a04478fc17fd5b61b8c558616b7e9acba105668ef786f084545c32778
    logging:
      driver: json-file
      options:
        max-size: "50m"
        max-file: "2"
    volumes:
    - /my_vol
    labels:
      io.rancher.container.pull_image: always
      com.vendor-app.builder.version: "7766jjc"
      com.vendor-app.built: "Fri, 14 Dec 2018 20:50:35 -0000"

  myservice:
    image: myregistry/myservice
    logging:
      driver: json-file
      options:
        max-size: "50m"
        max-file: "2"
    volumes:
    - /my_vol2
    labels:
      io.rancher.container.pull_image: always

I almost reached my goal by doing this :

Map merge(Map... maps) {
  Map result = [:]
  maps.each { map ->
    map.each { k, v ->
      result[k] = result[k] instanceof Map ? merge(result[k], v) : v
      }
    }
   result
  }


def latest_yml = readYaml file:"vendor.yml"
def current_yml = readYaml file:"original.yml"
def new_yml = readYaml file:"original.yml"

current_yml.services['vendor-app'].image = latest_yml.services['vendor'].image
current_yml.services['vendor-app'].labels =  latest_yml.services['vendor-app'].labels
writeYaml file:"beforemerge.yml", data: current_yml

println "merge(new_yml, current_yml): " + merge(new_yml, current_yml)
writeYaml file:"aftermerge.yml", data: merge(new_yml, current_yml)

Almost, because this is what I get in aftermerge.yml:

services:
  vendor-app:
    image: vendor/vendor-app@sha256:ba065e9a04478fc17fd5b61b8c558616b7e9acba105668ef786f084545c32778
    logging:
      driver: json-file
      options:
        max-size: 50m
        max-file: '2'
    volumes:
    - /my_vol
    labels:
      io.rancher.container.pull_image: always
      com.vendor-app.builder.version: 7766jjc
      com.vendor-app.built: Fri, 14 Dec 2018 20:50:35 -0000
  myservice:
    image: myregistry/myservice
    logging:
      driver: json-file
      options:
        max-size: 50m
        max-file: '2'
    volumes:
    - /my_vol2
    labels:
      io.rancher.container.pull_image: always

As you can see, it has messed up the formatting somewhat...the double quotes from com.vendor-app.built and com.vendor-app.builder.version have disappeared and this obviously will cause havoc when I use the updated yaml file (the examples here are redacted versions of docker-compose.yml). The quoting around max-size and max-file are also changed to singles quotes only for max-file ?? Weird...

Why is it doing this and how can I make the logic preserve the quoting? Is there a better way of doing this? Really all I want to do is get the values from image and labels from vendor.yml and use them to update the same values in original.yml (in the case of labels, appending onto the current value in original.yml as well as updating).

Any help would be appreciated, thanks.

JaneD
  • 109
  • 2
  • 11
  • _this obviously will cause havoc_ -- why? https://stackoverflow.com/questions/19109912/yaml-do-i-need-quotes-for-strings-in-yaml#:~:text=In%20general%2C%20you%20don't%20need%20quotes.,%25%20%2C%20%40%20%2C%20%5C%20). – tim_yates Jun 03 '21 at 14:10
  • @tim_yates thanks for that. I would love to not used quotes if I can get away with it - however I cant control the format of the yaml file I get from the vendor and these contain quotes. My problem is that groovy yaml removes these quotes and as you said obviously will cause issues. – JaneD Jun 04 '21 at 01:00

0 Answers0