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.