diff --git a/ansible/devops.yaml b/ansible/devops.yaml index 03fde7c..d26f6ea 100644 --- a/ansible/devops.yaml +++ b/ansible/devops.yaml @@ -4,9 +4,14 @@ roles: - server-setup - name: Set up drone - hosts: servers + hosts: ci become: true become_method: ansible.builtin.sudo remote_user: "{{ ssh_user }}" roles: - drone +- name: Set up Gitea + hosts: git + remote_user: "{{ ssh_user }}" + roles: + - gitea diff --git a/ansible/inventories/hetzner.example b/ansible/inventories/devops.example similarity index 66% rename from ansible/inventories/hetzner.example rename to ansible/inventories/devops.example index 174fbc1..a0bb609 100644 --- a/ansible/inventories/hetzner.example +++ b/ansible/inventories/devops.example @@ -1,4 +1,7 @@ localhost ansible_connection=local ansible_python_interpreter=/usr/bin/python3 -[servers] -alias ansible_host=IPorDomain ansible_python_interpreter=python3 \ No newline at end of file +[ci] +alias ansible_host=IPorDomain ansible_python_interpreter=python3 + +[git] +user.uber.space ansible_python_interpreter=/usr/bin/python \ No newline at end of file diff --git a/ansible/inventories/group_vars/servers/servers_vars.yaml.example b/ansible/inventories/group_vars/ci/ci_vars.yaml.example similarity index 100% rename from ansible/inventories/group_vars/servers/servers_vars.yaml.example rename to ansible/inventories/group_vars/ci/ci_vars.yaml.example diff --git a/ansible/roles/drone/defaults/main.yaml b/ansible/roles/drone/defaults/main.yaml index 50e0c30..edb6f8b 100644 --- a/ansible/roles/drone/defaults/main.yaml +++ b/ansible/roles/drone/defaults/main.yaml @@ -1,2 +1,5 @@ --- drone_max_procs: 1 +drone_registration_closed: true +drone_server_version: 2.18.0 +drone_runner_version: 1.8.3 diff --git a/ansible/roles/drone/tasks/drone.yml b/ansible/roles/drone/tasks/drone.yml index 7160a8c..6c2eeb2 100644 --- a/ansible/roles/drone/tasks/drone.yml +++ b/ansible/roles/drone/tasks/drone.yml @@ -5,12 +5,12 @@ path: /etc/drone owner: root group: root - mode: "644" + mode: "755" - name: Create shared secret ansible.builtin.command: cmd: openssl rand -hex 16 register: drone_rpc_secret - changed_when: true + changed_when: false - name: Copy docker compose file for drone ansible.builtin.template: src: etc/drone/docker-compose.yml.j2 diff --git a/ansible/roles/drone/templates/etc/drone/docker-compose.yml.j2 b/ansible/roles/drone/templates/etc/drone/docker-compose.yml.j2 index 2742d5e..39a5fe8 100644 --- a/ansible/roles/drone/templates/etc/drone/docker-compose.yml.j2 +++ b/ansible/roles/drone/templates/etc/drone/docker-compose.yml.j2 @@ -2,7 +2,7 @@ version: '2' services: drone-server: - image: drone/drone:latest + image: "drone/drone:{{ drone_server_version }}" ports: - "8000:80" @@ -21,10 +21,11 @@ services: - DRONE_GITEA_CLIENT_ID={{ gitea_client_id }} - DRONE_GITEA_CLIENT_SECRET={{ gitea_client_secret }} - DOCKER_MAX_PROCS={{ drone_max_procs }} + - DRONE_REGISTRATION_CLOSED={{ drone_registration_closed }} - LC_ALL=C.UTF-8 - LANG=C.UTF-8 drone-runner: - image: drone/drone-runner-docker:latest + image: "drone/drone-runner-docker:{{ drone_runner_version }}" ports: - "3000:3000" diff --git a/ansible/roles/gitea/defaults/main.yaml b/ansible/roles/gitea/defaults/main.yaml new file mode 100644 index 0000000..87985bc --- /dev/null +++ b/ansible/roles/gitea/defaults/main.yaml @@ -0,0 +1,2 @@ +--- +gitea_version: 1.20.2 diff --git a/ansible/roles/gitea/tasks/backend.yaml b/ansible/roles/gitea/tasks/backend.yaml new file mode 100644 index 0000000..77beb56 --- /dev/null +++ b/ansible/roles/gitea/tasks/backend.yaml @@ -0,0 +1,9 @@ +--- +- name: Get backend list + ansible.builtin.command: uberspace web backend list + register: backends + changed_when: false +- name: Add backend + when: backends.stdout.find(gitea_backend) == -1 + ansible.builtin.command: uberspace web backend set / --http --port {{ gitea_port }} + changed_when: true diff --git a/ansible/roles/gitea/tasks/domains.yaml b/ansible/roles/gitea/tasks/domains.yaml new file mode 100644 index 0000000..ec83f1b --- /dev/null +++ b/ansible/roles/gitea/tasks/domains.yaml @@ -0,0 +1,16 @@ +--- +- name: List domains + ansible.builtin.command: uberspace web domain list + changed_when: false + register: domains +- name: Set up domain + when: domains.stdout.find(gitea_domain) == -1 + block: + - name: Add domain + ansible.builtin.command: uberspace web domain add {{ gitea_domain }} + register: new_domain + changed_when: true + - name: Print out important information + changed_when: false + ansible.builtin.debug: + msg: "{{ new_domain.stdout }}" diff --git a/ansible/roles/gitea/tasks/gitea.yaml b/ansible/roles/gitea/tasks/gitea.yaml new file mode 100644 index 0000000..a2081c6 --- /dev/null +++ b/ansible/roles/gitea/tasks/gitea.yaml @@ -0,0 +1,130 @@ +--- +- name: Create directory + ansible.builtin.file: + state: directory + path: /home/{{ ssh_user }}/gitea + owner: "{{ ssh_user }}" + group: "{{ ssh_user }}" + mode: "755" +- name: Check if service exists + ansible.builtin.stat: + path: /home/{{ ssh_user }}/etc/services.d/gitea.ini.j2 + register: service +- name: Shutdown Gitea + community.general.supervisorctl: + name: gitea + state: stopped + when: service.stat.exists +- name: Download Gitea + ansible.builtin.get_url: + url: https://dl.gitea.com/gitea/{{ gitea_version }}/gitea-{{ gitea_version }}-linux-{{ host_architecture }} + dest: /home/{{ ssh_user }}/gitea/gitea + owner: "{{ ssh_user }}" + group: "{{ ssh_user }}" + mode: "744" +- name: Create config directory + ansible.builtin.file: + state: directory + path: /home/{{ ssh_user }}/gitea/custom/conf + owner: "{{ ssh_user }}" + group: "{{ ssh_user }}" + mode: "755" +- name: Create data directory + ansible.builtin.file: + state: directory + path: /home/{{ ssh_user }}/gitea/data + owner: "{{ ssh_user }}" + group: "{{ ssh_user }}" + mode: "755" +- name: Check if config file exists + ansible.builtin.stat: + path: /home/{{ ssh_user }}/gitea/custom/conf/app.ini + register: config_file +- name: Read existing secret + register: existing_secret_key + when: config_file.stat.exists + changed_when: false + ansible.builtin.command: + chdir: /home/{{ ssh_user }}/gitea/custom/conf + argv: + - bash + - -c + - grep -e ^SECRET_KEY app.ini | cut -f 3 -d ' ' +- name: Read existing internal token + register: existing_internal_token + when: config_file.stat.exists + changed_when: false + ansible.builtin.command: + chdir: /home/{{ ssh_user }}/gitea/custom/conf + argv: + - bash + - -c + - grep -e ^INTERNAL_TOKEN app.ini | cut -f 3 -d ' ' +- name: Read existing JWT secret + register: existing_jwt_secret + when: config_file.stat.exists + changed_when: false + ansible.builtin.command: + chdir: /home/{{ ssh_user }}/gitea/custom/conf + argv: + - bash + - -c + - grep -e ^JWT_SECRET app.ini | cut -f 3 -d ' ' +- name: Read existing LFS JWT secret + register: existing_lfs_jwt_secret + when: config_file.stat.exists + changed_when: false + ansible.builtin.command: + chdir: /home/{{ ssh_user }}/gitea/custom/conf + argv: + - bash + - -c + - grep -e ^LFS_JWT_SECRET app.ini | cut -f 3 -d ' ' +- name: Create secret + ansible.builtin.command: /home/{{ ssh_user }}/gitea/gitea generate secret SECRET_KEY + register: secret_key + when: not config_file.stat.exists + changed_when: false +- name: Create internal token + ansible.builtin.command: /home/{{ ssh_user }}/gitea/gitea generate secret INTERNAL_TOKEN + register: internal_token + when: not config_file.stat.exists + changed_when: false +- name: Create LFS JWT secret + ansible.builtin.command: /home/{{ ssh_user }}/gitea/gitea generate secret LFS_JWT_SECRET + register: lfs_jwt_secret + when: not config_file.stat.exists + changed_when: false +- name: Create JWT secret + ansible.builtin.command: /home/{{ ssh_user }}/gitea/gitea generate secret JWT_SECRET + register: jwt_secret + when: not config_file.stat.exists + changed_when: false +- name: Create configuration + ansible.builtin.template: + src: gitea/custom/conf/app.ini.j2 + dest: /home/{{ ssh_user }}/gitea/custom/conf/app.ini + owner: "{{ ssh_user }}" + group: "{{ ssh_user }}" + mode: "600" +- name: Migrate database + ansible.builtin.command: /home/{{ ssh_user }}/gitea/gitea migrate + changed_when: true +- name: Create service directory + ansible.builtin.file: + state: directory + path: /home/{{ ssh_user }}/etc/services.d + owner: "{{ ssh_user }}" + group: "{{ ssh_user }}" + mode: "755" +- name: Create Gitea service + ansible.builtin.template: + src: etc/services.d/gitea.ini.j2 + dest: /home/{{ ssh_user }}/etc/services.d/gitea.ini + owner: "{{ ssh_user }}" + group: "{{ ssh_user }}" + mode: "644" +- name: Start Gitea + community.general.supervisorctl: + state: started + name: gitea diff --git a/ansible/roles/gitea/tasks/main.yaml b/ansible/roles/gitea/tasks/main.yaml new file mode 100644 index 0000000..118cb0f --- /dev/null +++ b/ansible/roles/gitea/tasks/main.yaml @@ -0,0 +1,7 @@ +--- +- name: Set up backend + ansible.builtin.import_tasks: backend.yaml +- name: Set up domains + ansible.builtin.import_tasks: domains.yaml +- name: Set up Gitea + ansible.builtin.import_tasks: gitea.yaml diff --git a/ansible/roles/gitea/templates/etc/services.d/gitea.ini.j2 b/ansible/roles/gitea/templates/etc/services.d/gitea.ini.j2 new file mode 100644 index 0000000..794fdb6 --- /dev/null +++ b/ansible/roles/gitea/templates/etc/services.d/gitea.ini.j2 @@ -0,0 +1,5 @@ +[program:gitea] +directory=%(ENV_HOME)s/gitea +command=%(ENV_HOME)s/gitea/gitea web +startsecs=30 +autorestart=yes diff --git a/ansible/roles/gitea/templates/gitea/custom/conf/app.ini.j2 b/ansible/roles/gitea/templates/gitea/custom/conf/app.ini.j2 new file mode 100644 index 0000000..85e7e20 --- /dev/null +++ b/ansible/roles/gitea/templates/gitea/custom/conf/app.ini.j2 @@ -0,0 +1,106 @@ +APP_NAME = {{ gitea_name }} +RUN_USER = {{ ssh_user }} +RUN_MODE = prod +WORK_PATH = /home/{{ ssh_user }}/gitea + +[server] +HTTP_PORT = {{ gitea_port }} +DOMAIN = {{ gitea_domain }} +ROOT_URL = https://%(DOMAIN)s/ +LOCAL_ROOT_URL = http://localhost:{{ gitea_port }}/ +SSH_DOMAIN = {{ gitea_domain }} +DISABLE_SSH = false +LFS_START_SERVER = true ; Enables Git LFS support +{% if 'stdout' in lfs_jwt_secret %} +LFS_JWT_SECRET = {{ lfs_jwt_secret.stdout }} +{% elif 'stdout' in existing_lfs_jwt_secret %} +LFS_JWT_SECRET = {{ existing_lfs_jwt_secret.stdout }} +{% endif %} +OFFLINE_MODE = false ; privacy option. + +[lfs] +PATH = /home/{{ ssh_user }}/gitea/data/lfs + +[database] +DB_TYPE = mysql +HOST = 127.0.0.1:3306 +NAME = {{ ssh_user }}_gitea +USER = {{ ssh_user }} +PASSWD = {{ mysql_password }} +SSL_MODE = disable +PATH = data/gitea.db + +[security] +INSTALL_LOCK = true +{% if 'stdout' in secret_key %} +SECRET_KEY = {{ secret_key.stdout }} ; the before generated security key +{% elif 'stdout' in existing_secret_key %} +SECRET_KEY = {{ existing_secret_key.stdout }} ; the before generated security key +{% endif %} +{% if 'stdout' in internal_token %} +INTERNAL_TOKEN = {{ internal_token.stdout }} +{% elif 'stdout' in existing_internal_token %} +INTERNAL_TOKEN = {{ existing_internal_token.stdout }} +{% endif %} + +[service] +DISABLE_REGISTRATION = true +REGISTER_EMAIL_CONFIRM = false +SHOW_REGISTRATION_BUTTON = false +ENABLE_NOTIFY_MAIL = false +ENABLE_CAPTCHA = false +DISABLE_REGISTRATION = true ; security option, only admins can create new users. +REQUIRE_SIGNIN_VIEW = false +DEFAULT_ORG_VISIBILITY = private ; [public, limited, private] +DEFAULT_KEEP_EMAIL_PRIVATE = false +DEFAULT_ALLOW_CREATE_ORGANIZATION = true +DEFAULT_ENABLE_TIMETRACKING = true +NO_REPLY_ADDRESS = noreply.{{ gitea_domain }} + +[service.explore] +REQUIRE_SIGNIN_VIEW = true + +[mailer] +ENABLED = true +SMTP_ADDR = {{ gitea_mail_domain }} +SMTP_PORT = 587 +FROM = gitea@{{ gitea_domain }} +USER = {{ ssh_user }}@uber.space +PASSWD = {{ gitea_mail_password }} + +[repository] +ROOT = /home/{{ ssh_user }}/gitea-repositories + +[picture] +DISABLE_GRAVATAR = false +ENABLE_FEDERATED_AVATAR = true + +[openid] +ENABLE_OPENID_SIGNIN = true +ENABLE_OPENID_SIGNUP = false + +[session] +PROVIDER = file +PROVIDER_CONFIG = data/sessions + +[log] +MODE = file +LEVEL = Info +ROOT_PATH = /home/{{ ssh_user }}/logs/gitea + +[cron.delete_repo_archives] +ENABLED = true +SCHEDULE = @every 24h + +[oauth2] +{% if 'stdout' in jwt_secret %} +JWT_SECRET = {{ jwt_secret.stdout }} +{% elif 'stdout' in existing_jwt_secret %} +JWT_SECRET = {{ existing_jwt_secret.stdout }} +{% endif %} + +[git] +VERBOSE_PUSH = false + +[other] +SHOW_FOOTER_VERSION = false ; hide version number from strangers - you can still see it in the admin panel at /admin diff --git a/ansible/site.yaml b/ansible/site.yaml index 5c62693..88a231c 100644 --- a/ansible/site.yaml +++ b/ansible/site.yaml @@ -1,2 +1,2 @@ --- -- include: devops.yaml \ No newline at end of file +- include: devops.yaml