Je voudrais utiliser le module lineinfile ou replace d'Ansible afin d'ajouter le mot splash
à la cmdline dans GRUB.
Cela devrait fonctionner pour tous les exemples suivants:
Exemple 1:
GRUB_CMDLINE_DEFAULT=""
GRUB_CMDLINE_DEFAULT="splash"
Exemple 2:
GRUB_CMDLINE_DEFAULT="quiet"
GRUB_CMDLINE_DEFAULT="quiet splash"
Exemple 3:
GRUB_CMDLINE_DEFAULT="quiet nomodeset"
GRUB_CMDLINE_DEFAULT="quiet nomodeset splash"
Le post Ansible: insérer un seul mot sur une ligne existante dans un fichier expliquait bien comment cela pouvait être fait sans guillemets. Cependant, je ne peux pas lui faire insérer le mot entre les guillemets.
Quelle est l'entrée requise dans le rôle ou le playbook Ansible pour ajouter le mot splash
à la cmdline comme indiqué?
3 Réponses :
Une solution possible est la définition de deux entrées comme suit:
- name: "Checking GRUB cmdline" shell: "grep 'GRUB_CMDLINE_LINUX_DEFAULT=.*splash.*' /etc/default/grub" register: grub_cfg_grep changed_when: false failed_when: false - name: "Configuring GRUB cmdline" replace: path: '/etc/default/grub' regexp: '^GRUB_CMDLINE_LINUX_DEFAULT="((\w.?)*)"$' replace: 'GRUB_CMDLINE_LINUX_DEFAULT="\1 splash"' when: '"splash" not in grub_cfg_grep'
Explication: Nous vérifions d'abord si le mot-clé splash est présent dans la ligne requise à l'aide de grep. Puisque grep donne un code de retour négatif lorsqu'une chaîne n'est pas trouvée, nous failed_when: false
les erreurs en utilisant failed_when: false
. La sortie de grep est enregistrée dans la variable grub_cfg_grep
.
Ensuite, nous lions le module replace à la condition que le mot-clé splash soit dans la sortie standard de grep. L'expression régulière prend l'ancien contenu entre guillemets et ajoute le mot-clé splash derrière.
Remarque: dans le cas d'une chaîne vide avant l'exécution, le résultat lit " splash"
(avec un espace devant) mais c'est toujours une cmdline valide.
La difficulté est cette ligne dans la page du module de remplacement: "C'est à l'utilisateur de maintenir l'idempotence en s'assurant que le même modèle ne correspondrait jamais aux remplacements effectués." https://docs.ansible.com/ansible/latest/modules/replace_module.html#id4 Il est facile d'insérer l'élément mais en fait assez difficile de le rendre idempotent, le fichier cible ne grossit pas à chaque fois que vous exécutez la tâche .
J'ai trouvé un moyen de le faire d'un seul coup avec le module de remplacement. Vous devriez pouvoir adapter cela. Ma tâche vérifie la ligne GRUB_CMDLINE_LINUX_DEFAULT pour "vt.default_red" et insère des codes de couleur si non trouvés.
Ma méthode consistait à copier-coller divers exemples presque là-bas dans le site Web du testeur d'expression régulière et à jouer du violon jusqu'à ce que cela fonctionne. Je ne connais toujours pas le résultat, mais cela a fonctionné dans mes tests sur https://www.regextester.com/ et cela fonctionne dans mon playbook.
Un problème que j'ai eu était que l'implémentation de regex d'Ansible ne prend apparemment pas en charge les conditions, ce qui m'a donné des erreurs étranges pendant un certain temps.
( - open capture group #1 (creates backref #1) (:? - open a non-capturing group (not sure what the question mark is here) (?! - negative lookahead (ie. don't match if the following string comes next) vt\.default_red - the string to look for, literal dot is escaped ) - close negative lookahead .) - match a single char (why?) and close the non-capturing group * - try to match the non-capturing group zero or more times ? - ... lazily (ie. get the smallest possible match) ) - close capture group #1
L'expression régulière correspond à la chaîne littérale ("GRUB_CMDLINE_LINUX_DEFAULT =" et un guillemet double) au début et le guillemet double à la fin. Déconstruire le reste ...
- name: colours | configured grub command replace: path: /etc/default/grub regexp: '^GRUB_CMDLINE_LINUX_DEFAULT="((:?(?!vt\.default_red).)*?)"$' replace: 'GRUB_CMDLINE_LINUX_DEFAULT="\1 vt.default_red=0xee,..."'
Vous pouvez le faire sans sortie shell
, avec 2 modules lineinfiles
.
Dans votre exemple, vous recherchez splash
:
- name: check if splash is configured in the boot command lineinfile: backup: true path: /etc/default/grub regexp: regexp: '^GRUB_CMDLINE_LINUX=".*splash' state: absent check_mode: true register: grub_cmdline_check changed_when: false - name: insert splash if missing lineinfile: backrefs: true path: /etc/default/grub regexp: "^(GRUB_CMDLINE_LINUX=\".*)\"$" line: '\1 splash"' when: grub_cmdline_check.found == 0 notify: update grub
L'astuce consiste à essayer de supprimer la ligne si nous pouvons trouver splash
quelque part, mais en ne vérifiant que check_mode: true
. Si le terme a été trouvé ( found
> 0), nous n'avons pas besoin de mettre à jour la ligne. S'il n'est pas trouvé, cela signifie que nous devons l'insérer. Nous l'ajoutons à la fin avec les backrefs.
Si vous souhaitez inclure des guillemets doubles dans une chaîne, utilisez simplement des guillemets simples à l'extérieur:
'Here is "an example" that contains double qutoes'