tower - Solo verifica si una línea está presente en un archivo(ansible)
ansible tutorial (5)
En ansible, necesito verificar si una línea particular está presente en un archivo o no. Básicamente, necesito convertir el siguiente comando en una tarea ansible. Mi objetivo es solo comprobar.
grep -Fxq "127.0.0.1" /tmp/my.conf
Con la solución aceptada, aunque ignore los errores, seguirá obteniendo un error de rojo feo en la primera tarea si no hay coincidencia:
TASK: [Check whether /tmp/my.conf contains "127.0.0.1"] ***********************
failed: [localhost] => {"changed": false, "cmd": "grep -Fxq "127.0.0.1" /tmp/my.conf", "delta": "0:00:00.018709", "end": "2015-09-27 17:46:18.252024", "rc": 1, "start": "2015-09-27 17:46:18.233315", "stdout_lines": [], "warnings": []}
...ignoring
Si desea una salida menos detallada, puede usar awk
lugar de grep
. awk
no devolverá un error en una no coincidencia, lo que significa que la primera tarea de verificación a continuación no generará un error, independientemente de una coincidencia o no coincidencia:
- name: Check whether /tmp/my.conf contains "127.0.0.1"
command: awk /^127.0.0.1$/ /tmp/my.conf
register: checkmyconf
changed_when: False
- name: Greet the world if /tmp/my.conf contains "127.0.0.1"
debug: msg="Hello, world!"
when: checkmyconf.stdout | match("127.0.0.1")
Observe que mi segunda tarea usa el filtro de coincidencia, ya que awk devuelve la cadena coincidente si encuentra una coincidencia.
La alternativa anterior producirá la siguiente salida, independientemente de si la tarea de verificación tiene una coincidencia o no:
TASK: [Check whether /tmp/my.conf contains "127.0.0.1"] ***********************
ok: [localhost]
En mi humilde opinión, este es un mejor enfoque, ya que no ignorará otros errores en su primera tarea (por ejemplo, si el archivo especificado no existía).
Otra forma es usar el "módulo de reemplazo" y luego el "módulo de archivos de línea".
El algo se cierra al que se usa cuando desea cambiar los valores de dos variables.
- Primero, use "reemplazar módulo" para detectar si la línea que está buscando está aquí y cámbiela por otra cosa. (Como la misma línea + algo al final).
- Entonces, si "reemplazar" es verdadero, significa que su línea está aquí, entonces reemplace la nueva línea con una particularidad, con la nueva línea mirando.
- De lo contrario, la línea que está buscando no está aquí.
Ejemplo:
# Vars
- name: Set parameters
set_fact:
newline : "hello, i love ansible"
lineSearched : "hello"
lineModified : "hello you"
# Tasks
- name: Try to replace the line
replace:
dest : /dir/file
replace : ''{{ lineModified }} ''
regexp : ''{{ lineSearched }}$''
backup : yes
register : checkIfLineIsHere
- name: Line is here, change it
lineinfile:
state : present
dest : /dir/file
line : ''{{ newline }}''
regexp : ''{{ lineModified }}$''
when: checkIfLineIsHere.changed
- Si el archivo contiene "hola", se convertirá en "hola" y luego "hola, me encanta ansible" al final.
- Si el contenido del archivo no contiene "hola", el archivo no se modifica.
Con la misma idea, puedes hacer algo si el lineSearched está aquí:
# Vars
- name: Set parameters
set_fact:
newline : "hello, i love ansible"
lineSearched : "hello"
lineModified : "hello you"
# Tasks
- name: Try to replace the line
replace:
dest : /dir/file
replace : ''{{ lineModified }} ''
regexp : ''{{ lineSearched }}$''
backup : yes
register : checkIfLineIsHere
# If the line is here, I want to add something.
- name: If line is here, do something
lineinfile:
state : present
dest : /dir/file
line : ''{{ newline }}''
regexp : ''''
insertafter: EOF
when: checkIfLineIsHere.changed
# But I still want this line in the file, Then restore it
- name: Restore the searched line.
lineinfile:
state : present
dest : /dir/file
line : ''{{ lineSearched }}''
regexp : ''{{ lineModified }}$''
when: checkIfLineIsHere.changed
- Si el archivo contiene "hola", la línea seguirá conteniendo "hola" y "hola, me encanta ansible" al final.
- Si el contenido del archivo no contiene "hola", el archivo no se modifica.
Usa check_mode, register y failed_when en concierto. Esto falla la tarea si el módulo de línea de archivos realizaría algún cambio en el archivo que se está comprobando. Check_mode asegura que nada cambiará, aunque de lo contrario lo haría.
- name: "Ensure /tmp/my.conf contains ''127.0.0.1''"
lineinfile:
path: /tmp/my.conf
line: "127.0.0.1"
state: present
check_mode: yes
register: contents_would_have
failed_when: (contents_would_have | changed) or (contents_would_have | failed)
Use el comando ansible lineinfile, pero este comando actualizará el archivo con la línea si no existe.
- lineinfile: dest=/tmp/my.conf line=''127.0.0.1'' state=present
- name: Check whether /tmp/my.conf contains "127.0.0.1"
command: grep -Fxq "127.0.0.1" /tmp/my.conf
register: checkmyconf
check_mode: no
ignore_errors: yes
changed_when: no
- name: Greet the world if /tmp/my.conf contains "127.0.0.1"
debug: msg="Hello, world!"
when: checkmyconf.rc == 0
Actualización 2017-08-28: Las versiones anteriores de Ansible deben usar always_run: yes
lugar de check_mode: no
.