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.