diff --git a/README.md b/README.md
index 3edfbf7..af87806 100644
--- a/README.md
+++ b/README.md
@@ -1,3 +1,199 @@
-# role_modele
+# role_drone_runner_exec
-Modèle
\ No newline at end of file
+Rôle de déploiement d'un runner-exec drone.io.
+
+## Variables
+
+### drone_runner_exec_prerequisites
+
+Liste des paquets pré-requis.
+
+Valeur par défaut: `["curl", "jq"]`
+
+### drone_runner_exec_url
+
+URL pointant vers l'API de github.com fournissant le lien de téléchargement de l'archive.
+
+Valeur par défaut: `https://api.github.com/repos/drone-runners/drone-runner-exec/releases/latest`
+
+### drone_runner_exec_architecture
+
+Nécessaire pour télécharger la bonne archive depuis github.com.
+Les architectures disponibles sont visibles dans [la liste de release du dépôt](https://github.com/drone-runners/drone-runner-exec/releases).
+
+Valeur par défaut: `arm64`
+
+### drone_runner_exec_rpc_proto
+
+Protocole utilisé pour contacter le serveur drone.io.
+Les valeurs peuvent être `http` ou `https`.
+
+Valeur par défaut: aucune
+
+### drone_runner_exec_rpc_host
+
+Adresse IP ou nom d'hôte suivi du numéro de port du serveur drone.io.
+
+Valeur par défaut: aucune
+
+### drone_runner_exec_rpc_secret
+
+Clé utilisée par le serveur drone.io.
+
+Valeur par défaut: aucune
+
+### drone_runner_exec_log_file
+
+Emplacement des journaux.
+
+Valeur par défaut: `/var/log/drone-runner-exec/log.txt`
+
+### drone_runner_exec_log_file_max_size
+
+Taille maximal en mégaoctets d'un journal.
+
+Valeur par défaut: `10`
+
+### drone_runner_exec_log_file_max_age
+
+Nombre de jour où sera conservé un journal.
+
+Valeur par défaut: `7`
+
+### drone_runner_exec_log_file_max_backup
+
+Nombre d'ancien journaux conservés.
+
+Valeur par défaut: `0`
+
+### drone_runner_exec_debug
+
+Activer le mode debug.
+
+Valeur par défaut: `false`
+
+### drone_runner_exec_trace
+
+Activer le mode trace.
+
+Valeur par défaut: `false`
+
+### drone_runner_exec_rpc_dump
+
+Afficher le détail des communication entre le serveur et le runner en activant les paramètre suivants :
+
+ - `DRONE_RPC_DUMP_HTTP`
+ - `DRONE_RPC_DUMP_HTTP_BODY`
+
+Activer cette option génère énormément de ligne en sortie ; à n'activer que sur une très petite période.
+
+Valeur par défaut: `false`
+
+### drone_runner_exec_runner_name
+
+Définir le nom du runner au lieu d'utiliser le nom d'hôte.
+
+Valeur par défaut: aucune
+
+### drone_runner_exec_runner_labels
+
+Définir les étiquettes (tags) pour le runner.
+Cette option sert à cibler les runners depuis les pipelines.
+
+Valeur par défaut: aucune
+
+### drone_runner_exec_ui_username
+
+Activer l'interface web du runner en définissant un nom d'utilisateur pour s'y connecter.
+
+Valeur par défaut: aucune
+
+### drone_runner_exec_ui_password
+
+Activer l'interface web du runner en définissant un mot de passe pour s'y connecter.
+
+Valeur par défaut: aucune
+
+### drone_runner_exec_user: drone_runner
+
+Utilisateur exécutant le runner.
+
+Valeur par défaut: `drone_runner`
+
+### drone_runner_exec_group: drone_runner
+
+Groupe exécutant le runner.
+
+Valeur par défaut: `drone_runner`
+
+### drone_runner_exec_config_base_path
+
+Chemin vers le fichier de configuration du runner.
+
+Valeur par défaut: `/home/{{ drone_runner_exec_user }}/.drone-runner-exec`
+
+## Exemple d'utilisation
+
+### inventory.yml
+
+```yaml
+---
+
+all:
+ hosts:
+ host1.ykn.local:
+```
+
+### group_vars/all.yml
+
+```yaml
+---
+
+drone_runner_exec_architecture: arm64
+drone_runner_exec_rpc_proto: http
+drone_runner_exec_rpc_host: "192.168.1.1:9082"
+drone_runner_exec_rpc_secret: !vault |
+ $ANSIBLE_VAULT;1.1;AES256
+ 31383335306534333462613832646537376232386465643262306134653931383863336133306561
+ 3964303562336532393334343530636161343366656539620a326337376232623163323439303735
+ 39656634356366306361366537663939653336323432646335656230663133393039343638363536
+ 6565336166666261350a343937373733396131623962303237316661666539653432326136306239
+ 3538
+
+drone_runner_api_url: "https://drone.ykn.local/api"
+drone_runner_api_key: !vault |
+ $ANSIBLE_VAULT;1.1;AES256
+ 31383335306534333462613832646537376232386465643262306134653931383863336133306561
+ 3964303562336532393334343530636161343366656539620a326337376232623163323439303735
+ 39656634356366306361366537663939653336323432646335656230663133393039343638363536
+ 6565336166666261350a343937373733396131623962303237316661666539653432326136306239
+ 3538
+drone_runner_api_requests:
+ - path: /repos/ansible/playbook_lxc/secrets
+ name: ANSIBLE_VAULT_PASSWORD
+ data: !vault |
+ $ANSIBLE_VAULT;1.1;AES256
+ 31383335306534333462613832646537376232386465643262306134653931383863336133306561
+ 3964303562336532393334343530636161343366656539620a326337376232623163323439303735
+ 39656634356366306361366537663939653336323432646335656230663133393039343638363536
+ 6565336166666261350a343937373733396131623962303237316661666539653432326136306239
+ 3538
+ pull_request: false
+```
+
+### host_vars/host1.ykn.local.yml
+
+```yaml
+drone_runner_exec_runner_name: "runner-1"
+drone_runner_exec_runner_labels: "runner_name: {{ drone_runner_exec_runner_name }}"
+```
+
+### playbook.yml
+
+```yaml
+---
+
+- hosts: 'all'
+ roles:
+ - name: drone_runner_exec
+```
diff --git a/defaults/main.yml b/defaults/main.yml
new file mode 100644
index 0000000..d338602
--- /dev/null
+++ b/defaults/main.yml
@@ -0,0 +1,33 @@
+---
+# defaults file for drone_runner_exec
+
+drone_runner_exec_prerequisites:
+ - curl
+ - jq
+ - git
+
+drone_runner_exec_url: https://api.github.com/repos/drone-runners/drone-runner-exec/releases/latest
+drone_runner_exec_architecture: arm64
+
+drone_runner_exec_rpc_proto: ""
+drone_runner_exec_rpc_host: ""
+drone_runner_exec_rpc_secret: ""
+
+drone_runner_exec_log_file: /var/log/drone-runner-exec/log.txt
+drone_runner_exec_log_file_max_size: 10
+drone_runner_exec_log_file_max_age: 7
+drone_runner_exec_log_file_max_backup: 0
+
+drone_runner_exec_debug: false
+drone_runner_exec_trace: false
+drone_runner_exec_rpc_dump: false
+
+drone_runner_exec_runner_name: ""
+drone_runner_exec_runner_labels: ""
+
+drone_runner_exec_ui_username: ""
+drone_runner_exec_ui_password: ""
+
+drone_runner_exec_user: drone_runner
+drone_runner_exec_group: drone_runner
+drone_runner_exec_config_base_path: "/home/{{ drone_runner_exec_user }}/.drone-runner-exec"
diff --git a/files/drone-downstream.bash b/files/drone-downstream.bash
new file mode 100644
index 0000000..e9ad841
--- /dev/null
+++ b/files/drone-downstream.bash
@@ -0,0 +1,24 @@
+#!/usr/bin/env bash
+
+# Lancer une pipeline
+request=$(curl --silent --request POST --header "Authorization: Bearer ${DRONE_TOKEN}" ${DRONE_BASE_URL}/api/repos/${DRONE_REPOSITORY_PATH}/builds${DRONE_URL_PARAM} | jq .number)
+
+# Attendre que la pipeline ne soit plus en exécution
+while true; do
+ # Récupérer l'état de la pipeline
+ status=$(curl --silent --request GET --header "Authorization: Bearer ${DRONE_TOKEN}" ${DRONE_BASE_URL}/api/repos/${DRONE_REPOSITORY_PATH}/builds/$request | jq .status)
+
+ case "${status}" in
+ "\"pending\"" | "\"running\"")
+ sleep 5s
+ ;;
+ "\"success\"")
+ echo "${DRONE_REPOSITORY_PATH}: ${status}"
+ exit 0
+ ;;
+ *)
+ echo "${DRONE_REPOSITORY_PATH}: ${status}"
+ exit 1
+ ;;
+ esac
+done
diff --git a/handlers/main.yml b/handlers/main.yml
new file mode 100644
index 0000000..16304e4
--- /dev/null
+++ b/handlers/main.yml
@@ -0,0 +1,10 @@
+---
+# handlers file for drone_runner_exec
+
+- name: Redémarrer drone-runner-exec.service
+ ansible.builtin.systemd:
+ enabled: true
+ daemon_reload: true
+ state: restarted
+ name: drone-runner-exec.service
+ become: true
diff --git a/meta/main.yml b/meta/main.yml
index c58bebf..5c3b184 100644
--- a/meta/main.yml
+++ b/meta/main.yml
@@ -1,7 +1,7 @@
galaxy_info:
namespace: ykn
author: pulsar89.5
- description: Rôle modèle
+ description: Rôle de déploiement d'un runner-exec drone.io
license: GPL-3.0-or-later
@@ -12,4 +12,5 @@ galaxy_info:
versions:
- all
-dependencies: []
+dependencies:
+ - role: users
diff --git a/tasks/configuration.yml b/tasks/configuration.yml
new file mode 100644
index 0000000..188c34b
--- /dev/null
+++ b/tasks/configuration.yml
@@ -0,0 +1,69 @@
+---
+# tasks file for drone_runner_exec
+
+- name: Créer le dossier de configuration
+ ansible.builtin.file:
+ state: directory
+ path: "{{ drone_runner_exec_config_base_path }}"
+ owner: "{{ drone_runner_exec_user }}"
+ group: "{{ drone_runner_exec_user }}"
+ mode: u=rwX,g=rX,o=rX
+ become: true
+
+- name: Créer le dossier de journalisation
+ ansible.builtin.file:
+ state: directory
+ path: /var/log/drone-runner-exec
+ owner: "{{ drone_runner_exec_user }}"
+ group: "{{ drone_runner_exec_user }}"
+ mode: u=rwX,g=rX,o=rX
+ become: true
+
+- name: Configurer le runner
+ ansible.builtin.template:
+ src: config.j2
+ dest: "{{ drone_runner_exec_config_base_path }}/config"
+ owner: "{{ drone_runner_exec_user }}"
+ group: "{{ drone_runner_exec_user }}"
+ mode: u=rwX,g=rX,o=rX
+ become: true
+ notify: Redémarrer drone-runner-exec.service
+
+- name: Récupérer les faits sur les services
+ ansible.builtin.service_facts:
+
+- name: Installer drone-runner.service
+ ansible.builtin.command:
+ cmd: >-
+ /opt/drone-runner-exec/drone-runner-exec service install
+ --config="{{ drone_runner_exec_config_base_path }}/config"
+ when: "'drone-runner-exec.service' not in ansible_facts.services"
+ become: true
+ notify: Redémarrer drone-runner-exec.service
+
+- name: Créer le dossier de surcharge du service
+ ansible.builtin.file:
+ state: directory
+ path: /etc/systemd/system/drone-runner-exec.service.d
+ mode: u=rwX,g=rX,o=rX
+ become: true
+
+- name: Définir l'utilisateur du service
+ ansible.builtin.template:
+ src: override.conf.j2
+ dest: /etc/systemd/system/drone-runner-exec.service.d/override.conf
+ owner: root
+ group: root
+ mode: u=rwX,g=rX,o=rX
+ become: true
+ notify: Redémarrer drone-runner-exec.service
+
+- name: Déployer le script permettant d'exécuter un pipeline depuis une autre
+ ansible.builtin.copy:
+ src: drone-downstream.bash
+ dest: /opt/drone-runner-exec/drone-downstream.bash
+ owner: root
+ group: root
+ mode: u=rwx,g=rx,o=rx
+ become: true
+ diff: false
diff --git a/tasks/installation.yml b/tasks/installation.yml
new file mode 100644
index 0000000..7a60655
--- /dev/null
+++ b/tasks/installation.yml
@@ -0,0 +1,46 @@
+---
+# tasks file for drone_runner_exec
+
+- name: Installer les prérequis
+ ansible.builtin.package:
+ name: "{{ item }}"
+ become: true
+ loop: "{{ drone_runner_exec_prerequisites }}"
+
+- name: Créer le dossier dédié
+ ansible.builtin.file:
+ path: /opt/drone-runner-exec
+ state: directory
+ owner: root
+ group: root
+ mode: u=rwX,g=rX,o=rX
+ become: true
+
+- name: Récupérer le contenu du fichier de version
+ ansible.builtin.uri:
+ url: "{{ drone_runner_exec_url }}"
+ return_content: true
+ follow_redirects: all
+ register: releases
+
+- name: Extraire l'URL du paquet
+ ansible.builtin.set_fact:
+ browser_download_url: >
+ {{
+ releases.json.assets |
+ selectattr('browser_download_url', 'search', 'linux') |
+ selectattr('browser_download_url', 'search', drone_runner_exec_architecture) |
+ map(attribute='browser_download_url')
+ }}
+
+- name: Extraire le runner
+ ansible.builtin.unarchive:
+ src: "{{ browser_download_url | first }}"
+ dest: /opt/drone-runner-exec
+ remote_src: true
+ list_files: true
+ owner: root
+ group: root
+ mode: u=rwX,g=rX,o=rX
+ become: true
+ notify: Redémarrer drone-runner-exec.service
diff --git a/tasks/main.yml b/tasks/main.yml
new file mode 100644
index 0000000..ff2ee68
--- /dev/null
+++ b/tasks/main.yml
@@ -0,0 +1,10 @@
+---
+# tasks file for drone_runner_exec
+
+- name: Importer les tâches d'installation
+ tags: installation
+ ansible.builtin.import_tasks: installation.yml
+
+- name: Importer les tâches de configuration
+ tags: configuration
+ ansible.builtin.import_tasks: configuration.yml
diff --git a/templates/config.j2 b/templates/config.j2
new file mode 100644
index 0000000..45e172a
--- /dev/null
+++ b/templates/config.j2
@@ -0,0 +1,31 @@
+# {{ ansible_managed }}
+
+DRONE_RPC_PROTO={{ drone_runner_exec_rpc_proto }}
+DRONE_RPC_HOST={{ drone_runner_exec_rpc_host }}
+DRONE_RPC_SECRET={{ drone_runner_exec_rpc_secret }}
+
+DRONE_LOG_FILE={{ drone_runner_exec_log_file }}
+DRONE_LOG_FILE_MAX_SIZE={{ drone_runner_exec_log_file_max_size }}
+DRONE_LOG_FILE_MAX_AGE={{ drone_runner_exec_log_file_max_age }}
+DRONE_LOG_FILE_MAX_BACKUPS={{ drone_runner_exec_log_file_max_backup }}
+
+DRONE_DEBUG={{ drone_runner_exec_debug }}
+DRONE_TRACE={{ drone_runner_exec_trace }}
+{% if drone_runner_exec_rpc_dump %}
+DRONE_RPC_DUMP_HTTP=true
+DRONE_RPC_DUMP_HTTP_BODY=true
+{% endif %}
+{% if drone_runner_exec_runner_name | length > 0 %}
+DRONE_RUNNER_NAME={{ drone_runner_exec_runner_name }}
+{% endif %}
+{% if drone_runner_exec_runner_labels | length > 0 %}
+DRONE_RUNNER_LABELS={{ drone_runner_exec_runner_labels }}
+{% endif %}
+{% if
+ drone_runner_exec_ui_username | length > 0
+ and
+ drone_runner_exec_ui_password | length > 0
+%}
+DRONE_UI_USERNAME={{ drone_runner_exec_ui_username }}
+DRONE_UI_PASSWORD={{ drone_runner_exec_ui_password }}
+{% endif %}
diff --git a/templates/override.conf.j2 b/templates/override.conf.j2
new file mode 100644
index 0000000..dae6e81
--- /dev/null
+++ b/templates/override.conf.j2
@@ -0,0 +1,5 @@
+# {{ ansible_managed }}
+
+[Service]
+User={{ drone_runner_exec_user }}
+Group={{ drone_runner_exec_group }}