initial role commit

This commit is contained in:
hiperman
2025-11-28 20:50:50 -05:00
parent be507897df
commit fdd0c909bd
15 changed files with 1655 additions and 2 deletions

79
tasks/backup.yaml Normal file
View File

@@ -0,0 +1,79 @@
---
- name: Backup block
block:
- name: Create backup root directory
ansible.builtin.file:
path: "{{ gitea_root_backup_dir }}"
state: directory
mode: '0755'
owner: admin
group: admin
- name: Create a directory for this backup
ansible.builtin.file:
path: "{{ gitea_root_backup_dir }}/gitea_backup_{{ ansible_date_time.iso8601_basic }}"
state: directory
mode: '0755'
owner: admin
group: admin
register: gitea_dir_backup_task
- name: Store the backup path as a fact
set_fact:
backup_dir: "{{ gitea_dir_backup_task.path }}"
- name: Create directories for the runner backups
ansible.builtin.file:
path: "{{ backup_dir }}/{{ item.data_mount }}"
state: directory
mode: '0755'
owner: admin
group: admin
loop: "{{ gitea_runners }}"
- name: Stop Gitea service and runners
community.docker.docker_compose_v2:
project_src: "{{ gitea_home_path }}"
state: stopped
- name: Backup Gitea data directory
ansible.builtin.copy:
src: "{{ gitea_home_path }}/data"
dest: "{{ backup_dir }}"
remote_src: yes
mode: preserve
- name: Backup each runner's data directory
ansible.builtin.copy:
src: "{{ gitea_home_path }}/{{ item.data_mount }}"
dest: "{{ backup_dir }}/runners/{{ item.name }}"
remote_src: yes
mode: preserve
loop: "{{ gitea_runners }}"
- name: Start the Gitea service and runners
community.docker.docker_compose_v2:
project_src: "{{ gitea_home_path }}"
state: present
- name: Create a tar.gz archive of the backup
community.general.archive:
path: "{{ backup_dir }}/*"
dest: "{{ backup_dir }}.tar.gz"
format: gz
- name: Copy the backups to the controller
ansible.builtin.fetch:
src: "/{{ backup_dir }}.tar.gz"
dest: "{{ gitea_local_backup_dir }}/{{ backup_dir | basename }}.tar.gz"
flat: yes
rescue:
- name: Start the Gitea service and runners as backup failed
community.docker.docker_compose_v2:
project_src: "{{ gitea_home_path }}"
state: present
- name: Print updating error and cancel
ansible.builtin.fail:
msg: "failed to backup gitea"

23
tasks/main.yaml Normal file
View File

@@ -0,0 +1,23 @@
---
- name: Gather installed packages for checks later on
ansible.builtin.package_facts:
manager: "auto"
- name: Deploy optional fail2ban rules
ansible.builtin.include_tasks: setup-fail2ban.yaml
when: gitea_fail2ban_enabled | bool
- name: Install the Gitea compose stack
ansible.builtin.import_tasks: setup-compose.yaml
- name: Restore data from backup
ansible.builtin.include_tasks: restore.yaml
when: gitea_restore_backup | bool
- name: Run handlers
ansible.builtin.meta: flush_handlers
- name: Create or remove Gitea users
ansible.builtin.include_tasks: manage_users.yaml
when: gitea_users | length > 0

58
tasks/manage_users.yaml Normal file
View File

@@ -0,0 +1,58 @@
---
- name: Get list of users
community.docker.docker_container_exec:
container: gitea-gitea-1
command: /bin/bash -c "gitea admin user list"
register: user_list
failed_when: false
changed_when: false
when: gitea_users | length > 0
- name: Extract existing usernames
ansible.builtin.set_fact:
gitea_existing_users: "{{ user_list.stdout_lines[1:] | map('regex_replace', '^\\d+\\s+(\\S+)\\s+.*$', '\\1') | list | default([]) }}"
when:
- gitea_users | length > 0
- user_list.stdout_lines | default([]) | length > 1
- name: Create Gitea users
community.docker.docker_container_exec:
container: gitea-gitea-1
command: >
/bin/bash -c "gitea admin user create
--username {{ user.username }}
--email {{ user.email }}
--password {{ user.password }}
--must-change-password={{ user.must_change_password | default(false) }}
--admin={{ user.admin | default(false) }}"
register: _gitea_user_result
failed_when:
- '"successfully created" not in _gitea_user_result.stdout'
changed_when:
- '"successfully created!" in _gitea_user_result.stdout'
when:
- user.username not in gitea_existing_users | default([]) and user.state | default('present') == 'present'
loop: "{{ gitea_users }}"
loop_control:
label: "user={{ user.username }}"
loop_var: user
# no_log: true # Avoid logging passwords
- name: Remove gitea users
community.docker.docker_container_exec:
container: gitea-gitea-1
command: >
/bin/bash -c "gitea admin user delete
--username {{ user.username }}
--email {{ user.email }}"
register: _gitea_user_del_result
failed_when:
- '"error" in _gitea_user_del_result.stdout'
changed_when: "user.username in gitea_existing_users"
when: "user.username in gitea_existing_users | default([]) and user.state | default('present') == 'absent'"
loop: "{{ gitea_users }}"
loop_control:
label: "user={{ user.username }}"
loop_var: user

87
tasks/restore.yaml Normal file
View File

@@ -0,0 +1,87 @@
---
- name: Select backup file on localhost
delegate_to: localhost
become: no
block:
- name: Find all backup files in the directory
find:
paths: "{{ gitea_local_backup_dir }}"
patterns: "gitea_backup_*.tar.gz"
file_type: file
register: backup_files
- name: Print files
debug:
msg: "files found {{ backup_files }}"
- name: Set gitea_backup_file if not defined or empty
when: gitea_backup_file is not defined or gitea_backup_file == ""
block:
- name: Sort backup files by timestamp in filename and select newest
set_fact:
gitea_backup_file: "{{ backup_files.files | sort(attribute='path') | last | default({}) | json_query('path') }}"
when: backup_files.files | length > 0
- name: Fail if no backup files found
fail:
msg: "No backup files found in {{ gitea_local_backup_dir }}"
when: backup_files.files | length == 0
- name: Display selected backup file
debug:
msg: "Using backup file: {{ gitea_backup_file }}"
- name: Verify backup file exists
stat:
path: "{{ gitea_backup_file }}"
register: final_backup_check
- name: Fail if backup file doesn't exist
fail:
msg: "Backup file does not exist: {{ gitea_backup_file }}"
when: not final_backup_check.stat.exists
- name: Stop Gitea service and runners
community.docker.docker_compose_v2:
project_src: /opt/gitea
state: stopped
- name: Remove existing data directory
file:
path: "{{ gitea_home_path }}/data"
state: absent
- name: Remove existing runner directories
file:
path: "{{ gitea_home_path }}/{{ item.data_mount }}"
state: absent
loop: "{{ gitea_runners }}"
- name: Copy backup file to remote host
copy:
src: "{{ gitea_backup_file }}"
dest: "{{ gitea_home_path }}/{{ gitea_backup_file | basename }}"
mode: preserve
register: copy_result
- name:
- name: Extract backup archive on remote host
unarchive:
src: "{{ gitea_home_path }}/{{ gitea_backup_file | basename }}"
dest: "{{ gitea_home_path }}"
remote_src: yes
register: extract_result
- name: Fix ownership of extracted files
file:
path: "{{ gitea_home_path }}"
owner: admin
group: admin
recurse: yes
- name: Delete backup archive from remote host
file:
path: "{{ gitea_home_path }}/{{ gitea_backup_file | basename }}"
state: absent

74
tasks/setup-compose.yaml Normal file
View File

@@ -0,0 +1,74 @@
---
- name: Set up Docker and Docker compose
ansible.builtin.include_role:
name: geerlingguy.docker
- name: Create directory for Gitea Docker Compose stack
ansible.builtin.file:
path: "{{ gitea_home_path }}"
state: directory
mode: "0755"
- name: Create directory for data
ansible.builtin.file:
path: "{{ gitea_home_path }}/data"
state: directory
mode: "0755"
owner: "admin"
group: "admin"
notify: Deploy Docker Compose stack
- name: Create directory for config
ansible.builtin.file:
path: "{{ gitea_home_path }}/config"
state: directory
mode: "0755"
owner: "admin"
group: "admin"
notify: Deploy Docker Compose stack
- name: Create directory for logs
ansible.builtin.file:
path: "{{ gitea_home_path }}/log"
state: directory
mode: "0755"
owner: "admin"
group: "admin"
notify: Deploy Docker Compose stack
when: gitea_log_mode == 'file'
- name: Get host IP
set_fact:
gitea_host_ip: "{{ ansible_default_ipv4.address }}"
- name: Create data directories for runners
ansible.builtin.file:
path: "{{ gitea_home_path }}/{{ item.data_mount }}"
state: directory
mode: "0755"
owner: "admin"
group: "admin"
loop: "{{ gitea_runners }}"
- name: Create configuration files for each runner
ansible.builtin.template:
src: actions/config.yaml.j2
dest: "{{ gitea_home_path }}/{{ item.config_file_mount }}"
mode: "0755"
owner: "admin"
group: "admin"
loop: "{{ gitea_runners }}"
- name: Create the Compose file based on template
ansible.builtin.template:
src: docker-compose.yaml.j2
dest: "{{ gitea_home_path }}/docker-compose.yaml"
mode: "0755"
notify: Deploy Docker Compose stack
- name: Create the .env file based on template
ansible.builtin.template:
src: env.j2
dest: "{{ gitea_home_path }}/.env"
mode: "0644"
notify: Deploy Docker Compose stack

32
tasks/setup-fail2ban.yaml Normal file
View File

@@ -0,0 +1,32 @@
---
- name: Install fail2ban filter
become: true
ansible.builtin.template:
src: fail2ban/filter.conf.j2
dest: /etc/fail2ban/filter.d/gitea.local
owner: root
group: root
mode: "0444"
notify: "Restart fail2ban"
when: "'fail2ban' in ansible_facts.packages"
- name: Install fail2ban jail for logins over HTTP(S)
become: true
vars:
gitea_fail2ban_filter: gitea
gitea_fail2ban_port: "http,https,{{ gitea_ssh_port }}"
gitea_fail2ban_jail_name: gitea-docker
ansible.builtin.template:
src: fail2ban/jail.conf.j2
dest: /etc/fail2ban/jail.d/gitea.local
owner: root
group: root
mode: "0444"
notify: "Restart fail2ban"
when: "'fail2ban' in ansible_facts.packages"
- name: Warn if fail2ban is not installed
ansible.builtin.fail:
msg: "the package fail2ban is not installed. no fail2ban filters deployed."
when: "'fail2ban' not in ansible_facts.packages"
failed_when: false