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 }}