¿Es posible modificar un archivo yml a través de un script de shell?

12

Así es como se ve mi docker-compose.yml.

nginx:
  container_name: 'nginx'
  image: 'nginx:1.11'
  restart: 'always'
  ports:
    - '80:80'
    - '443:443'
  volumes:
    - '/opt/nginx/conf.d:/etc/nginx/conf.d:ro'
  links:
    - 'anything'

Ahora necesito agregar algo de contenido a través del script de shell (en un servidor ubuntu). No estoy muy seguro de si es posible en absoluto:

  1. Agregue un nuevo elemento a nginx/links, si no existe
  2. Agregar newthingbloque si no existe un bloque nuevo

El nuevo contenido debería verse así:

nginx:
  container_name: 'nginx'
  image: 'nginx:1.11'
  restart: 'always'
  ports:
    - '80:80'
    - '443:443'
  volumes:
    - '/opt/nginx/conf.d:/etc/nginx/conf.d:ro'
    - '/etc/letsencrypt:/etc/letsencrypt'
  links:
    - 'anything'
    - 'newthing'

newthing:
  container_name: foo
  image: 'newthing:1.2.3'
  restart: always
  hostname: 'example.com'
usuario3142695
fuente
1
Shell le proporciona un lenguaje de script muy potente. Usted puede escribir un script usando sed, awky regular expressionspara actualizar su archivo.
fósil
¿Podría por favor dar un pequeño ejemplo?
user3142695
2
Si bien esto es técnicamente posible usando shell, es mejor que uses un lenguaje que tenga una biblioteca yaml real.
jordanm
Te aconsejaría que revises la ruamel.yamlbiblioteca para Python.
phk
Creo que vale la pena señalar que los enlaces son una característica heredada que se eliminará de Docker en el futuro: docs.docker.com/compose/compose-file/#links
Mikael Kjær

Respuestas:

6

Hay varias bibliotecas de yaml para Perl, Python, etc., si está bien, no lo haga directamente desde un script de shell, sino que use otro idioma.

Otra opción es instalar un procesador yaml de línea de comandos y llamarlo desde su script de shell.

dirkt
fuente
8

Escribí https://github.com/kislyuk/yq , un contenedor alrededor de https://stedolan.github.io/jq/ , para abordar este caso de uso.

tejedor
fuente
¿Se puede actualizar?
weynhamz
1
Sí: yq -y '.newthing=...' input.yml > output.yml. (Si está preguntando por una actualización en el lugar, como sed -i, yq no puede hacerlo por sí mismo todavía, pero puede usar sponge:. yq -y .newthing=... file.yml | sponge file.yml)
weaver
1
@weaver eres mi nuevo héroe
voutasaurus
7

Escribí yaml_cli ( https://github.com/Gallore/yaml_cli ) para hacer exactamente lo que necesita. Está basado en python. Esta sería la sintaxis para su ejemplo:

yaml_cli \
  -f docker-compose.yml \                # read from and save to file
  --list-append \                        # flag to append to lists instead of replacing existing values
  -s nginx:links newthing \              # add a value of type string; here you need --list-append
  -s newthing:container_name foo \       # key 'newthing' is created automatically
  -s newthing:image 'newthing:1.2.3' \   #
  -s newthing:restart always \           #
  -s newthing:hostname 'example.com'     #

Se agradece su opinión sobre yaml_cli.

Andy Werner
fuente
1

Dado que la razón por la que desea hacer esto es modificar un archivo docker-compose, otra alternativa es usar un archivo JSON. Docker-compose ahora admite archivos JSON . El soporte para la manipulación de JSON en la línea de comandos ya es muy bueno (ej: jq )

Vivek Kodira
fuente