Dans mon livre de jeu Ansible, je dois modifier les autorisations sur un grand nombre de fichiers, mais quelques sous-répertoires ont besoin d'autorisations de lecture-écriture, alors que la plupart ont besoin de lecture seule. Suite à une autre suggestion de superuser, j'ai cette solution :
- name: A few directories need group-write permissions
file:
path: "{{item}}"
mode: "u+rwX,g+rwX,o+rX,o-w"
recurse: True
with_items:
- /opt/myapp/path1/excludeddir1
- /opt/myapp/path1/excludeddir2
- /opt/myapp/path2/excludeddir1
- /opt/myapp/path2/excludeddir2
- name: For performance, set a lot of directories directly
file:
path: "{{item}}"
mode: "u+rwX,go+rX,go-w"
recurse: True
with_items:
- /opt/myapp/path1/readonlydir1
- /opt/myapp/path1/readonlydir2
#############################################
# This step generates a very large list
- name: Find all files in my directory
find:
paths:
- "/opt/myapp/path1"
- "/opt/myapp/path2"
recurse: True
file_type: any
follow: False
register: filestochange
#############################################
# This step is painfully slow
- name: Clear group-write permissions where needed
file:
path: "{{ item.path }}"
mode: "u+rwX,go+rX,go-w"
follow: False
when:
- not item.islnk
- "'/opt/myapp/path1/excludeddir1' not in item.path"
- "'/opt/myapp/path1/excludeddir2' not in item.path"
- "'/opt/myapp/path2/excludeddir1' not in item.path"
- "'/opt/myapp/path2/excludeddir2' not in item.path"
- "'/opt/myapp/path1/readonlydir1' not in item.path
- "'/opt/myapp/path1/readonlydir2' not in item.path
loop: "{{ filestochange.files }}"
loop_control:
label: "{{ item.path }}"
Les sous-répertoires concernés comptent au total environ 100 000 fichiers.
Le code ci-dessus fonctionne, mais il est, sans surprise, terriblement lent. L'implémentation originale, essentiellement naïve, a fonctionné pendant deux jours d'affilée.
Ma première optimisation a été de définir les autorisations pour quelques sous-répertoires qui n'ont pas besoin d'exceptions, et de les ignorer plus tard dans la boucle. Cela a aidé dans une certaine mesure ; le temps est maintenant réduit à une heure ou deux.
En guise d'optimisation suivante, j'aimerais supprimer ces mêmes entrées de la liste que le module find génère avant même de l'introduire dans la boucle, mais je n'ai pas trouvé de moyen de le faire.
Le module de fichiers possède un attribut d'exclusion, mais il semble ne correspondre qu'aux noms de fichiers, et non aux noms de répertoires.
Je cherche donc un moyen de supprimer les éléments d'une liste qui correspondent à certains modèles de caractères génériques.
Bien entendu, je suis également ouvert à toute autre suggestion visant à optimiser davantage ce système.
Remarque : cette mise en œuvre naïve ne fonctionne PAS car elle réinitialiserait, puis définirait, les autorisations.
- name: Set everything to G read-only
file:
path: "{{item}}"
mode: "u+rwX,go+rX,go-w"
recurse: True
with_items:
- /opt/myapp/path1
- /opt/myapp/path2
- name: A few directories need group-write permissions
file:
path: "{{item}}"
mode: "u+rwX,g+wrX,o+rX,o-w"
recurse: True
with_items:
- /opt/myapp/path1/excludeddir1
- /opt/myapp/path1/excludeddir2
- /opt/myapp/path2/excludeddir1
- /opt/myapp/path2/excludeddir2