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'
user3142695
la source
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.

dirkt
la source
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.

tisserand
la source
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.

Andy Werner
la source
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 )

Vivek Kodira
la source