From b1d9f73b861dad5b1537e25b2dc3071c0dd3554d Mon Sep 17 00:00:00 2001 From: Johanna Dorothea Reichmann Date: Sun, 30 Jan 2022 15:52:31 +0100 Subject: [PATCH] feat(gitea): add ansible role for deployment in docker containers --- roles/gitea/README.md | 34 ++++++++++++ roles/gitea/defaults/main.yml | 51 +++++++++++++++++ roles/gitea/tasks/main.yml | 100 ++++++++++++++++++++++++++++++++++ roles/gitea/vars/main.yml | 34 ++++++++++++ 4 files changed, 219 insertions(+) create mode 100644 roles/gitea/README.md create mode 100644 roles/gitea/defaults/main.yml create mode 100644 roles/gitea/tasks/main.yml create mode 100644 roles/gitea/vars/main.yml diff --git a/roles/gitea/README.md b/roles/gitea/README.md new file mode 100644 index 0000000..22a0295 --- /dev/null +++ b/roles/gitea/README.md @@ -0,0 +1,34 @@ +# `finallycoffee.services.gitea` ansible role + +## Overview + +This role deploys [gitea](https://gitea.com/) +using its official available docker image, and is able to setup SSH +forwarding from the host to the container (enabling git-over-SSH without +the need for a non-standard SSH port while running an SSH server on the +host aswell). + +### Configuration + +#### Email notifications + +To enable to send emails, you need to set the following variables, demonstrated +here with an SMTP server. A TLS connection is strongly advised, as otherwise, it +can be trival to intercept a login to the mail server and record the authentication +details, enabling anyone to send mail as if they were your gitea instance. + +```yaml +gitea_config_mailer_enabled: true +# Can be `sendmail` or `smtp` +gitea_config_mailer_type: smtp +# Including the port can be used to force secure smtp (SMTPS) +gitea_config_mailer_host: mail.my-domain.tld:465 +gitea_config_mailer_user: gitea +gitea_config_mailer_passwd: very_long_password +gitea_config_mailer_tls: true +gitea_config_mailer_from_addr: "gitea@{{ gitea_domain }}" +# Set `gitea_config_mailer_sendmail_path` when using a sendmail binary +gitea_config_mailer_sendmail_path: /usr/sbin/sendmail +``` + +For more information, see [the gitea docs on email setup](https://docs.gitea.io/en-us/email-setup/). diff --git a/roles/gitea/defaults/main.yml b/roles/gitea/defaults/main.yml new file mode 100644 index 0000000..4be6dec --- /dev/null +++ b/roles/gitea/defaults/main.yml @@ -0,0 +1,51 @@ +--- + +gitea_version: "1.15.6" +gitea_user: git +gitea_base_path: "/opt/gitea" +gitea_data_path: "{{ gitea_base_path }}/data" + +# Set this to the (sub)domain gitea will run at +gitea_domain: ~ + +# container config +gitea_container_name: "git" +gitea_container_image_name: "docker.io/gitea/gitea" +gitea_container_image_tag: "{{ gitea_version }}" +gitea_container_image: "{{ gitea_container_image_name }}:{{ gitea_container_image_tag }}" +gitea_container_networks: [] +gitea_container_purge_networks: ~ +gitea_container_restart_policy: "unless-stopped" +gitea_container_extra_env: {} +gitea_contianer_extra_labels: {} +gitea_container_extra_ports: [] +gitea_container_extra_volumes: [] + +# container defaults +gitea_container_base_volumes: + - "{{ gitea_data_path }}:/data:z" + - "/home/{{ gitea_user }}/.ssh/:/data/git/.ssh:z" + +gitea_container_base_ports: + - "127.0.0.1:{{ git_container_port_webui }}:{{ git_container_port_webui }}" + - "127.0.0.1:{{ git_container_port_ssh }}:{{ git_container_port_ssh }}" + +gitea_container_base_env: + USER_UID: "{{ gitea_user_res.uid | default(gitea_user) }}" + USER_GID: "{{ gitea_user_res.group | default(gitea_user) }}" + +gitea_container_base_labels: + version: "{{ gitea_version }}" + +gitea_config_mailer_enabled: false +gitea_config_mailer_type: ~ +gitea_config_mailer_from_addr: ~ +gitea_config_mailer_host: ~ +gitea_config_mailer_user: ~ +gitea_config_mailer_passwd: ~ +gitea_config_mailer_tls: ~ +gitea_config_mailer_sendmail_path: ~ +gitea_config_metrics_enabled: false + +gitea_config: "{{ gitea_config_base | combine(gitea_extra_config, recursive=True, list_merge='append') }}" +gitea_extra_config: {} diff --git a/roles/gitea/tasks/main.yml b/roles/gitea/tasks/main.yml new file mode 100644 index 0000000..aa60f2e --- /dev/null +++ b/roles/gitea/tasks/main.yml @@ -0,0 +1,100 @@ +--- + +- name: Create gitea user + user: + name: "{{ gitea_user }}" + state: present + system: no + register: gitea_user_res + +- name: Ensure host directories exist + file: + path: "{{ item }}" + owner: "{{ gitea_user_res.uid }}" + group: "{{ gitea_user_res.group }}" + state: directory + loop: + - "{{ gitea_base_path }}" + - "{{ gitea_data_path }}" + +- name: Ensure .ssh folder for gitea user exists + file: + path: "/home/{{ gitea_user }}/.ssh" + state: directory + owner: "{{ gitea_user_res.uid }}" + group: "{{ gitea_user_res.group }}" + mode: 0700 + +- name: Generate SSH keypair for host<>container + community.crypto.openssh_keypair: + path: "/home/{{ gitea_user }}/.ssh/id_ssh_ed25519" + type: ed25519 + state: present + comment: "Gitea:Host2Container" + owner: "{{ gitea_user_res.uid }}" + group: "{{ gitea_user_res.group }}" + mode: 0600 + register: gitea_user_ssh_key + +- name: Create directory to place forwarding script into + file: + path: "/app/gitea" + state: directory + mode: 0770 + owner: "{{ gitea_user_res.uid }}" + group: "{{ gitea_user_res.group }}" + +- name: Create forwarding script + copy: + dest: "/app/gitea/gitea" + owner: "{{ gitea_user_res.uid }}" + group: "{{ gitea_user_res.group }}" + mode: 0700 + content: | + ssh -p {{ gitea_public_ssh_server_port }} -o StrictHostKeyChecking=no {{ gitea_user }}@127.0.0.1 -i /home/{{ gitea_user }}/.ssh/id_ssh_ed25519 "SSH_ORIGINAL_COMMAND=\"$SSH_ORIGINAL_COMMAND\" $0 $@" + +- name: Add host pubkey to git users authorized_keys file + lineinfile: + path: "/home/{{ gitea_user }}/.ssh/authorized_keys" + line: "{{ gitea_user_ssh_key.public_key }} Gitea:Host2Container" + state: present + create: yes + owner: "{{ gitea_user_res.uid }}" + group: "{{ gitea_user_res.group }}" + mode: 0600 + +- name: Ensure gitea container image is present + docker_image: + name: "{{ gitea_container_image }}" + state: present + source: pull + force_source: "{{ gitea_container_image.endswith(':latest') }}" + +- name: Ensure container '{{ gitea_container_name }}' with gitea is running + docker_container: + name: "{{ gitea_container_name }}" + image: "{{ gitea_container_image }}" + env: "{{ gitea_container_env }}" + volumes: "{{ gitea_container_volumes }}" + networks: "{{ gitea_container_networks | default(omit, True) }}" + purge_networks: "{{ gitea_container_purge_networks | default(omit, True) }}" + published_ports: "{{ gitea_container_ports }}" + restart_policy: "{{ gitea_container_restart_policy }}" + state: started + +- name: Ensure given configuration is set in the config file + ini_file: + path: "{{ gitea_data_path }}/gitea/conf/app.ini" + section: "{{ section }}" + option: "{{ option }}" + value: "{{ entry.value }}" + state: "{{ 'present' if (entry.value is not none) else 'absent' }}" + loop: "{{ lookup('ansible.utils.to_paths', gitea_config) | dict2items }}" + loop_control: + loop_var: entry + label: "{{ section | default('/', True) }}->{{ option }}" + vars: + key_split: "{{ entry.key | split('.') }}" + # sections can be named `section_name`.`sub_section`, f.ex.: `repository.upload` + section: "{{ '' if key_split|length == 1 else (key_split[:-1] | join('.')) }}" + option: "{{ key_split | first if key_split|length == 1 else key_split | last }}" diff --git a/roles/gitea/vars/main.yml b/roles/gitea/vars/main.yml new file mode 100644 index 0000000..df08114 --- /dev/null +++ b/roles/gitea/vars/main.yml @@ -0,0 +1,34 @@ +--- + +gitea_container_volumes: "{{ gitea_container_base_volumes + gitea_container_extra_volumes }}" + +gitea_container_labels: "{{ gitea_container_base_labels | combine(gitea_container_extra_labels) }}" + +gitea_container_env: "{{ gitea_container_base_env | combine(gitea_container_extra_env) }}" + +gitea_container_ports: "{{ gitea_container_base_ports + gitea_container_extra_ports }}" + + +gitea_container_port_webui: 3000 +gitea_container_port_ssh: 22 + +gitea_config_base: + RUN_MODE: prod + RUN_USER: "{{ gitea_user }}" + server: + SSH_DOMAIN: "{{ gitea_domain }}" + DOMAIN: "{{ gitea_domain }}" + HTTP_PORT: "{{ gitea_container_port_webui }}" + DISABLE_SSH: false + START_SSH_SERVER: false + mailer: + ENABLED: "{{ gitea_config_mailer_enabled }}" + MAILER_TYP: "{{ gitea_config_mailer_type }}" + HOST: "{{ gitea_config_mailer_host }}" + USER: "{{ gitea_config_mailer_user }}" + PASSWD: "{{ gitea_config_mailer_passwd }}" + IS_TLS_ENABLED: "{{ gitea_config_mailer_tls }}" + FROM: "{{ gitea_config_mailer_from_addr }}" + SENDMAIL_PATH: "{{ gitea_config_mailer_sendmail_path }}" + metrics: + ENABLED: "{{ gitea_config_metrics_enabled }}"