A la hora de usar Ansible en SmartOS una molestia constante es
que, a veces, al volver a ejecutar un script Ansible, nos dice
que realiza de nuevo las acciones pkgin (instalación de paquetes
PkgSrc) o bien salta una excepción Python. Esto no ocurre
siempre, pero sí ocurre con frecuencia.
Me explico: Las acciones Ansible se diseñan para que sean
idempotentes. Es decir, que lanzar una acción que ya se ha
realizado en el pasado debe marcar la acción como "ya realizada",
en vez de realizarla de nuevo. En el caso concreto de las acciones
pkgin, si le pedimos que instale un paquete que ya está
instalado, debería decirnos que ya está hecho y no, en cambio,
decirnos que ha realizado la acción de nuevo o fallar sin motivo.
Es decir, el resultado de la acción debería ser ok y no
changed o, peor aún, que salte una excepción.
En pocas palabras, cuando ejecutamos un script Ansible dos
veces, la segunda vez debería darnos ok en todas las acciones
porque no ha tenido que hacer nada.
Pero Ansible no lo hace así en el caso de acciones pkgin siempre.
A veces lo hace y a veces no, por motivos desconocidos. Y cuando
no lo hace, puede saltar una excepción Python.
Cuando ocurre así, si lanzamos de nuevo el script Ansible
termina correctamente... casi siempre.
Molesto con la situación, estudio el código fuente de Ansible,
que está escrito en Python. Me encuentro lo siguiente, entre
otras cosas, en
ansible_collections/community/general/plugins/modules/pkgin.py:
if rc == 0:
if re.search('^nothing to do.\n$', out):
module.exit_json(changed=False, msg="nothing left to upgrade")
else:
module.fail_json(msg="could not %s packages" % cmd, stdout=out, stderr=err)
Aquí se está buscando que el comando pkgin de SmartOS
devuelva la cadena "nothing to do.", tal cual. El problema
es que pkgin, al menos en las versiones modernas de SmartOS,
termina con esa cadena cuando no tiene nada que hacer, pero puede
ir precedida por bastante más texto y eso el código de Ansible no
lo contempla.
Leer más…