Est-il possible de modifier un fichier yml via un script shell?


12

Voici à quoi ressemble mon 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'

Maintenant, je dois ajouter du contenu via un script shell (sur un serveur Ubuntu). Je ne sais pas trop si c'est possible du tout:

  1. Ajouter un nouvel élément à nginx/links, s'il n'est pas existant
  2. Ajouter un newthingbloc si aucun nouveau bloc n'est existant

Le nouveau contenu devrait ressembler à ceci:

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'

1
Shell vous fournit un langage de script très puissant. Vous pouvez facilement écrire un script en utilisant sed, awket regular expressionsde mettre à jour votre dossier.
fossile

Pourriez-vous s'il vous plaît fournir un petit exemple?
user3142695

2
Bien que cela soit techniquement possible en utilisant le shell, il vaut mieux utiliser un langage qui possède une véritable bibliothèque yaml.
jordanm

Je vous conseille de consulter la ruamel.yamlbibliothèque de Python.
phk

Je pense qu'il vaut la peine de noter que les liens sont une fonctionnalité héritée qui sera supprimée de docker à l'avenir: docs.docker.com/compose/compose-file/#links
Mikael Kjær

Réponses:


6

Il existe un certain nombre de bibliothèques yaml pour Perl, Python, etc. si vous ne pouvez pas le faire directement à partir d'un script shell, mais utilisez un autre langage.

Une autre option consiste à installer un processeur yaml en ligne de commande et à l'appeler à partir de votre script shell.


8

J'ai écrit https://github.com/kislyuk/yq , un wrapper autour de https://stedolan.github.io/jq/ , pour résoudre ce cas d'utilisation.


Peut-il faire la mise à jour?
weynhamz

1
Oui: yq -y '.newthing=...' input.yml > output.yml. (Si vous demandez une mise à jour en place, comme sed -i, YQ ne peut le faire par lui - même encore, mais vous pouvez utiliser sponge: yq -y .newthing=... file.yml | sponge file.yml.)
tisserand

1
@weaver tu es mon nouveau héros
voutasaurus

7

J'ai écrit yaml_cli ( https://github.com/Gallore/yaml_cli ) pour faire exactement ce dont vous avez besoin. Il est basé sur python. Ce serait la syntaxe de votre exemple:

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

Les commentaires sur yaml_cli sont appréciés.


1

Étant donné que la raison pour laquelle vous souhaitez le faire est de modifier un fichier de composition de docker, une autre alternative consiste à utiliser un fichier JSON. Docker-compose prend désormais en charge les fichiers JSON . La prise en charge de la manipulation en ligne de commande des JSON est déjà très bonne (ex: jq )

En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.