É possível modificar um arquivo yml via shell script?

12

É assim que meu docker-compose.yml se parece.

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'

Agora eu preciso adicionar algum conteúdo via shell script (em um servidor ubuntu). Não tenho certeza se é possível:

  1. Adicione novo elemento a nginx/links, se ele não existir
  2. Anexar newthingbloco se não houver nenhum bloco novo

O novo conteúdo deve ficar assim:

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'
user3142695
fonte
1
O Shell fornece uma linguagem de script muito poderosa. Você pode facilmente escrever um script usando sed, awke regular expressionspara atualizar o arquivo.
fossil
Poderia, por favor, dar um pequeno exemplo?
precisa saber é o seguinte
2
Embora isso seja tecnicamente possível usando o shell, é melhor usar um idioma que tenha uma biblioteca yaml real.
Jordanm 20/01
Aconselho você a verificar a ruamel.yamlbiblioteca do Python.
Phd #
Eu acho que é importante notar que as ligações é um recurso legado que será removido da janela de encaixe no futuro: docs.docker.com/compose/compose-file/#links
Mikael Kjær

Respostas:

6

Existem várias bibliotecas yaml para Perl, Python, etc.

Outra opção é instalar um processador yaml da linha de comando e chamá-lo a partir do seu shell script.

dirkt
fonte
8

Eu escrevi https://github.com/kislyuk/yq , um wrapper em https://stedolan.github.io/jq/ , para abordar esse caso de uso.

tecelão
fonte
Pode fazer atualização?
weynhamz
1
Sim: yq -y '.newthing=...' input.yml > output.yml. (Se você está perguntando sobre uma atualização no local, como sed -i, yq não pode fazê-lo por si só ainda, mas você pode usar sponge: yq -y .newthing=... file.yml | sponge file.yml.)
tecelão
1
@weaver você é meu novo herói
voutasaurus 08/01
7

Eu escrevi yaml_cli ( https://github.com/Gallore/yaml_cli ) para fazer exatamente o que você precisa. É baseado em python. Essa seria a sintaxe do seu exemplo:

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'     #

O feedback sobre yaml_cli é apreciado.

Andy Werner
fonte
1

Como o motivo para fazer isso é modificar um arquivo de composição de encaixe, outra alternativa é usar um arquivo JSON. O Docker-compose agora suporta arquivos JSON . O suporte à manipulação de JSONs na linha de comando já é muito bom (ex: jq )

Vivek Kodira
fonte