¿Se puede desarchivar Ansible para escribir tiempos de modificación de carpetas estáticas?

8 minutos de lectura

avatar de usuario
la mitad

Estoy escribiendo un proceso de compilación para una instalación de WordPress usando Ansible. No tiene un sistema de compilación a nivel de aplicación en este momento, y elegí Ansible para que pueda integrarse limpiamente con los scripts de compilación del servidor, de modo que pueda abrir un servidor en funcionamiento con solo tocar un botón.

La mayoría de mis complementos de WordPress se están instalando con el unarchive característica, que apunta a compilaciones de complementos versionados en el servidor de instalación oficial de wordpress.org. Encontré un problema con solo uno de estos, que es que siempre se marca como “cambiado” a pesar de que los archivos son exactamente iguales.

Habiendo examinado el estado de ls -Rl antes y después, noté que este complemento (WordPress HTTPS) es el único que usa subdirectorios internos, y con cada descompresión, el tiempo de modificación de las carpetas se acelera.

Puede ser útil saber que este es un script de construcción de proyecto, con un connection de local. Supongo que eso significa que SSH no se está utilizando.

Aquí hay un fragmento de mi libro de jugadas:

- name: Install the W3 Total Cache plugin
  unarchive: >
    src=https://downloads.wordpress.org/plugin/w3-total-cache.0.9.4.1.zip
    dest=wp-content/plugins
    copy=no

- name: Install the WP DB Manager plugin
  unarchive: >
    src=https://downloads.wordpress.org/plugin/wp-dbmanager.2.78.1.zip
    dest=wp-content/plugins
    copy=no

# @todo Since this has internal sub-folders, need to work out
# how to preserve timestamps of the original folders rather than
# re-writing them, which forces Ansible to record a change of
# server state.
- name: Install the WordPress HTTPS plugin
  unarchive: >
    src=https://downloads.wordpress.org/plugin/wordpress-https.3.3.6.zip
    dest=wp-content/plugins
    copy=no

Una forma ingeniosa de arreglar esto es usar ls -R antes y después, usando opciones para incluir tamaños de archivo pero no marcas de tiempo, y luego md5sum esa salida. Luego podría marcarlo como cambiado si hay un cambio en la suma de verificación. Funcionaría pero no es muy elegante (y me gustaría hacer eso para todos los complementos, por consistencia).

Otro enfoque es abandonar la tarea si ya existe un archivo de complemento, pero eso causaría problemas cuando actualice el número de versión del complemento a la última copia.

Por lo tanto, idealmente, estoy buscando un interruptor para presentar a unarchive decir que quiero los tiempos de modificación de la carpeta del archivo zip, no del tiempo de ejecución del libro de jugadas. ¿Es posible?


Actualización: un comentarista preguntó si el contenido del archivo podría haber cambiado de alguna manera. Para determinar si lo han hecho, escribí este script, que crea una suma de verificación para (1) todos los contenidos de los archivos y (2) todas las marcas de tiempo de archivos/directorios:

#!/bin/bash

# Save pwd and then change dir to root location
STARTDIR=`pwd`
cd `dirname $0`/../..

# Clear collation file
echo > /tmp/wp-checksum

# List all files recursively
find wp-content/plugins/wordpress-https/ -type f | while read file
do
    #echo $file
    cat $file >> /tmp/wp-checksum
done

# Get checksum of file contents
sha1sum /tmp/wp-checksum

# Get checksum of file sizes
ls -Rl wp-content/plugins/wordpress-https/ | sha1sum

# Go back to original dir
cd $STARTDIR

Ejecuté esto como parte de mi libro de jugadas (ejecutándolo de forma aislada usando etiquetas) y recibí esto:

PLAY [Set this playbook to run locally] ****************************************

TASK [setup] *******************************************************************
ok: [localhost]

TASK [jonblog : Run checksum command] ******************************************
changed: [localhost]

TASK [jonblog : debug] *********************************************************
ok: [localhost] => {
    "checksum_before.stdout_lines": [
        "374fadc4df1578f78fd60b1be6758477c2c533fa  /tmp/wp-checksum", 
        "10d66f7bdbbdd3af531d1b11a3db3059a5868838  -"
    ]
}

TASK [jonblog : Install the WordPress HTTPS plugin] ***************
changed: [localhost]

TASK [jonblog : Run checksum command] ******************************************
changed: [localhost]

TASK [jonblog : debug] *********************************************************
ok: [localhost] => {
    "checksum_after.stdout_lines": [
        "374fadc4df1578f78fd60b1be6758477c2c533fa  /tmp/wp-checksum", 
        "719c9da94b525e723b1abe188ee9f5bbaf121f3f  -"
    ]
}

PLAY RECAP *********************************************************************
localhost                  : ok=6    changed=3    unreachable=0    failed=0   

Las líneas de depuración reflejan el hash de suma de verificación del contenido de los archivos (esto es idéntico) y luego el hash de suma de verificación de ls -Rl de la estructura del archivo (esto ha cambiado). Esto está de acuerdo con mi manual anterior que encuentra que las sumas de verificación del directorio están cambiando.

Entonces, ¿qué puedo hacer a continuación para rastrear por qué los tiempos de modificación de la carpeta marcan incorrectamente esta operación como modificada?

  • ¿Está absolutamente seguro de que el contenido es el mismo cada vez? ¿Qué sucede si md5sum todo y luego ejecuta su juego y verifica nuevamente? Me sorprendería mucho si Ansible sobrescribe un archivo con el mismo contenido, pero puede haber un error en alguna parte. Lo primero que me viene a la mente es que la instalación de WP está modificando uno de esos archivos después de haberlo copiado.

    – ydaetskcoR

    6 de junio de 2016 a las 7:00

  • Gracias @ydaetskcoR. Estoy bastante seguro, sí, aunque no había pensado en etiquetar este comando y ejecutarlo solo, así que lo haré a continuación. Creo que el contenido del archivo es completamente idéntico en cada ejecución, pero es posible que haya algo más jugando con el directorio. Sin embargo, no será WP: no estoy ejecutando ningún código de instalación PHP de WP como parte de este libro de jugadas.

    – mitad

    6 de junio de 2016 a las 7:28

  • @ydaetskcoR: Hice la investigación que sugirió y descubrí que los archivos son de hecho idénticos en bytes, solo las marcas de tiempo de la carpeta están cambiando. ¿Alguna idea nueva? Mientras tanto, usaré mi secuencia de comandos de suma de verificación como una medida de cambio, lo que me hará idempotente por ahora, pero sería bueno hacerlo correctamente (o informar un error al equipo central de Ansible).

    – mitad

    22 de junio de 2016 a las 9:40

  • No obtengo mucho en el camino de las picaduras de mi recompensa… ¿vale la pena presentarlo como un error? Resolví el problema usando mi secuencia de comandos de suma de verificación, por lo que el problema se evitó para mí y puede permanecer así, pero sería bueno solucionarlo para otros.

    – mitad

    26 de junio de 2016 a las 11:28

En lugar de sobrescribir todos los archivos cada vez y encontrar una manera de mantener la misma fecha y hora de modificación, es posible que desee utilizar el creates opción de la unarchive módulo.

Como quizás ya sepa, esto le dice a Ansible que se creará un archivo/carpeta específico como resultado de la tarea. Por lo tanto, la próxima vez que la tarea no ejecutarse de nuevo si ese archivo/carpeta ya existe.

Ver http://docs.ansible.com/ansible/unarchive_module.html#options

  • Sí, pensé en eso, lo siento, no aclaré un poco mi penúltimo párrafo, pero a eso me refería. El problema con este enfoque, como yo lo veo, es cuando tropiezo wordpress-https.3.3.6.zip a wordpress-https.3.3.7.zip debido a una nueva versión, la tarea afirmará haber tenido éxito en una instalación existente cuando en realidad no ha hecho nada.

    – mitad

    5 de junio de 2016 a las 21:15

  • Sin embargo, otra forma en que podría hacerlo es usar una carpeta temporal para ensamblar la aplicación y eliminar todo en el plugins carpeta. Todas estas tareas podrían marcarse como changed_when: Falsey luego yo synchronize en su lugar, lo que produce una salida cambiada/sin cambios.

    – mitad

    5 de junio de 2016 a las 21:18


  • Ah, no, eso tampoco funcionará: ¡cambiar las marcas de tiempo de la carpeta nuevamente! Bah… Entonces, gracias por la sugerencia anterior, pero ¿tienes más ideas? :-)

    – mitad

    5 de junio de 2016 a las 21:19


avatar de usuario
la mitad

Mi solución es modificar el script de suma de comprobación y convertirlo en una característica permanente del proceso de Ansible. Se siente un poco complicado hacer mi propia suma de verificación, cuando Ansible debería hacerlo por mí, pero funciona.

Serán bienvenidas nuevas respuestas que expliquen que estoy haciendo algo mal, o que una nueva versión de Ansible solucione el problema.

Si tengo un momento, plantearé esto como un posible error con el equipo de Ansible. Sin embargo, a veces me pregunto acerca de la relación esfuerzo/recompensa al generar errores en un rastreador ocupado: ya tengo un elemento pendiente, ha estado esperando un tiempo y también he optado por solucionarlo.

Actualización (18 meses después)

Este sistema de compilación de Ansible nunca llegó a funcionar. Sentía que siempre estaba trabajando en torno a algo. Recientemente, cuando decidí que necesitaba mover mi blog a otro servidor, finalmente lo dockericé. Esto tomó varias semanas (ya que hay una cantidad sorprendente de cosas en las que pensar en una instalación real de WordPress), pero en general encontré el proceso mucho más agradable que usar herramientas de orquestación.

¿Ha sido útil esta solución?