La mejor forma de clonar un repository de git cuando se autentica mediante el reenvío de keys ssh

Prerrequisitos:

  • La authentication de host y git ocurre a través de la key ssh
  • El reenvío de keys ssh está habilitado
  • Cada usuario de nuestro equipo utiliza una count de usuario dedicada; no es posible iniciar session a través de una count de usuario sin cabeza.

Ahora queremos implementar una aplicación desde un repository git. Esto debería ser simple pero no lo es.

- name: Clone app repo git: repo: githost:org/repo.git dest: /some/location version: HEAD force: yes ssh_opts: -o StrictHostKeyChecking=no notify: - Restart app 

githost es una input en nuestro .ssh / config

Esta tarea anterior funciona. Pero el repository es (por supuesto) clonado como el usuario que ejecutó el libro de jugadas. Lo que necesitamos en cambio es:

  • Todos los files deben ser propiedad de un usuario sin cabeza, llamémoslo zaphod
  • Solo zaphod puede leer los files. Estamos hablando de 0600/0700 permissions.

La siguiente tarea no funcionará, porque al usar become perderemos la key ssh reenviada y, por lo tanto, la authentication de git fallará:

 - name: Clone app repo git: repo: githost:org/repo.git dest: /some/location version: HEAD force: yes ssh_opts: -o StrictHostKeyChecking=no notify: - Restart app become: yes become_user: zaphod 

La siguiente variación llamaría primero a un controller que cambia la propiedad del pago antes de (re) iniciar la aplicación:

 - name: Clone app repo git: repo: githost:org/repo.git dest: /some/location version: HEAD force: yes ssh_opts: -o StrictHostKeyChecking=no notify: - Fix ownership - Restart app 

Esto funciona una vez Pero si ejecuta el libro de jugadas por segunda vez, la tarea de git falla porque el usuario que ejecuta la jugada no tiene permissions para modificar el clon.

Tenemos una solución muy fea:

  • Clonar en / tmp / foo
  • Corregir la propiedad de / tmp / foo
  • rm -rf /some/location
  • mv /tmp/foo /some/location
  • Finalmente (re) iniciar la aplicación

El problema con esto es que esto:

  • Dispara un reinicio cada vez que se ejecuta el libro de jugadas
  • El resumen de Ansible muestra 5 tareas modificadas, aunque no pasó nada, excepto el reinicio que no era necesario en primer lugar

Soy un poco exigente aquí, pero solo quiero cambiar los estados si algo realmente cambia, entonces en un mundo perfecto ni siquiera la tarea de git tendría un estado cambiado. Y para esto no veo una solución. Porque requerimos que los files clonados solo sean accesibles por zaphod , pero el propio zaphod no puede clonar el repository. Entonces tiene que haber alguna manipulación de alguna forma que resulte en cambios.

¿Alguna sugerencia de cómo se puede mejorar esto de una manera limpia? No quiero agregar otras 20 tareas revolviendo con copys temporales, cambiando permissions temporalmente, comparando files manualmente y así sucesivamente …

Por supuesto, un module escrito a medida podría tratar con todo esto, pero estoy más interesado en algo que no lleva 2 días en desarrollo y testings de batalla. 😉

Parece que estás intentando implementar una aplicación / página web simplemente clonando el repository que contiene lo que necesitas en lugar de tener que poder enviar los cambios al repository desde ese server.

Si ese es el caso, entonces podría salirse con la suya con una tarea local para convertir el repository en un tarball o algo así y luego usar unarchive para copyr el file resultante al equipo de destino y descomprimirlo. unarchive le permitirá configurar los permissions y la propiedad.

Entonces tu juego podría verse más o less así:

 - name: locally clone repo git: repo: githost:org/repo.git dest: /some/tmp/location version: HEAD force: yes delegate_to: localhost changed_when: false # - name: archive app repo command: git archive --format zip --output /path/to/archive master chdir: /some/tmp/location delegate_to: localhost changed_when: false - name: unarchive app repo unarchive: src: /path/to/archive dest: /some/location owner: zaphod mode: 0700 creates: /some/location notify: - Restart app