mirror of
https://github.com/fscotto/infra.git
synced 2026-10-03 13:29:58 +00:00
160 lines
6.1 KiB
YAML
160 lines
6.1 KiB
YAML
---
|
|
- name: Prepare the isolated rootless Atlas Gitea target
|
|
tags: [atlas, gitea]
|
|
when: atlas_manage_gitea | bool
|
|
block:
|
|
- name: Require the existing Atlas application-data dataset
|
|
ansible.builtin.assert:
|
|
that:
|
|
- atlas_manage_storage | bool
|
|
- atlas_gitea_dataset == atlas_zfs_pool ~ '/services/data/gitea'
|
|
- atlas_gitea_mountpoint == atlas_app_data_mountpoint ~ '/gitea'
|
|
- atlas_gitea_username == atlas_admin_username
|
|
- atlas_gitea_group == atlas_admin_group
|
|
- atlas_gitea_uid | int == atlas_admin_uid | int
|
|
- atlas_gitea_gid | int == atlas_admin_gid | int
|
|
- atlas_gitea_container_uid | int == 1000
|
|
- atlas_gitea_container_gid | int == 1000
|
|
- atlas_gitea_staging_bind_address == '127.0.0.1'
|
|
- not (atlas_gitea_production_enabled | bool) or atlas_manage_firewall | bool
|
|
- not (atlas_gitea_production_enabled | bool) or atlas_gitea_bind_address == ansible_host
|
|
fail_msg: >-
|
|
Rootless Gitea requires Atlas storage, the admin user manager, the
|
|
dedicated dataset, and loopback-only staging ports.
|
|
|
|
- name: Inspect the final-restore marker before production activation
|
|
ansible.builtin.stat:
|
|
path: "{{ atlas_gitea_mountpoint }}/.final-sha256"
|
|
register: atlas_gitea_final_marker
|
|
when: atlas_gitea_production_enabled | bool
|
|
|
|
- name: Refuse production activation without the final consistent restore
|
|
ansible.builtin.assert:
|
|
that:
|
|
- atlas_gitea_final_marker.stat.isreg | default(false)
|
|
fail_msg: Restore the final stopped-source Gitea export before enabling production.
|
|
when: atlas_gitea_production_enabled | bool
|
|
|
|
- name: Verify the production Gitea dataset belongs to admin
|
|
ansible.builtin.stat:
|
|
path: "{{ atlas_gitea_mountpoint }}"
|
|
register: atlas_gitea_dataset_owner
|
|
when: atlas_gitea_production_enabled | bool
|
|
|
|
- name: Refuse to overlap the legacy host-account service
|
|
ansible.builtin.assert:
|
|
that:
|
|
- atlas_gitea_dataset_owner.stat.uid | int == atlas_admin_uid | int
|
|
- atlas_gitea_dataset_owner.stat.gid | int == atlas_admin_gid | int
|
|
fail_msg: >-
|
|
Run the explicit Gitea owner migration before enabling the admin
|
|
Quadlet; never chown an active legacy service in a normal run.
|
|
when: atlas_gitea_production_enabled | bool
|
|
|
|
- name: Remove the retired account's parent-dataset traverse ACL
|
|
ansible.posix.acl:
|
|
path: "{{ item }}"
|
|
etype: user
|
|
entity: "{{ atlas_gitea_legacy_username }}"
|
|
state: absent
|
|
loop:
|
|
- "{{ atlas_services_mountpoint }}"
|
|
- "{{ atlas_app_data_mountpoint }}"
|
|
when: atlas_gitea_production_enabled | bool
|
|
|
|
- name: Enable POSIX ACLs only on the service-namespace parents
|
|
community.general.zfs:
|
|
name: "{{ item }}"
|
|
state: present
|
|
extra_zfs_properties:
|
|
acltype: posix
|
|
loop:
|
|
- "{{ atlas_zfs_pool }}/{{ atlas_zfs_dataset_services }}"
|
|
- "{{ atlas_zfs_pool }}/{{ atlas_zfs_dataset_app_data }}"
|
|
|
|
- name: Create the dedicated Gitea ZFS dataset
|
|
community.general.zfs:
|
|
name: "{{ atlas_gitea_dataset }}"
|
|
state: present
|
|
extra_zfs_properties:
|
|
compression: zstd
|
|
mountpoint: "{{ atlas_gitea_mountpoint }}"
|
|
|
|
- name: Restrict the Gitea dataset and create rootless volume paths
|
|
ansible.builtin.file:
|
|
path: "{{ item }}"
|
|
state: directory
|
|
owner: "{{ atlas_gitea_username }}"
|
|
group: "{{ atlas_gitea_group }}"
|
|
mode: "0700"
|
|
loop:
|
|
- "{{ atlas_gitea_mountpoint }}"
|
|
- "{{ atlas_gitea_mountpoint }}/data"
|
|
- "{{ atlas_gitea_mountpoint }}/config"
|
|
- "{{ atlas_gitea_home }}/.config"
|
|
- "{{ atlas_gitea_home }}/.config/containers"
|
|
- "{{ atlas_gitea_quadlet_dir }}"
|
|
|
|
- name: Ensure lingering for the admin rootless account
|
|
ansible.builtin.command:
|
|
argv:
|
|
- loginctl
|
|
- enable-linger
|
|
- "{{ atlas_gitea_username }}"
|
|
creates: "/var/lib/systemd/linger/{{ atlas_gitea_username }}"
|
|
|
|
- name: Start the admin rootless user manager
|
|
ansible.builtin.systemd:
|
|
name: "user@{{ atlas_gitea_uid }}.service"
|
|
state: started
|
|
when: not ansible_check_mode
|
|
|
|
- name: Prepare the admin-owned Gitea image
|
|
ansible.builtin.import_tasks: gitea_image.yml
|
|
|
|
- name: Render the rootless Gitea Quadlet
|
|
ansible.builtin.template:
|
|
src: atlas-gitea.container.j2
|
|
dest: "{{ atlas_gitea_quadlet_dir }}/atlas-gitea.container"
|
|
owner: "{{ atlas_gitea_username }}"
|
|
group: "{{ atlas_gitea_group }}"
|
|
mode: "0644"
|
|
|
|
- name: Permit only Aegis to reach production Gitea HTTP and SSH
|
|
ansible.posix.firewalld:
|
|
rich_rule: >-
|
|
rule family="ipv4" source address="{{ atlas_aegis_ip }}"
|
|
port port="{{ item }}" protocol="tcp" accept
|
|
zone: "{{ atlas_firewalld_zone }}"
|
|
state: "{{ 'enabled' if atlas_gitea_production_enabled | bool else 'disabled' }}"
|
|
permanent: true
|
|
immediate: true
|
|
loop:
|
|
- "{{ atlas_gitea_http_port }}"
|
|
- "{{ atlas_gitea_ssh_port }}"
|
|
when: atlas_manage_firewall | bool
|
|
|
|
- name: Reload the rootless Gitea user manager without starting Gitea
|
|
become_user: "{{ atlas_gitea_username }}"
|
|
ansible.builtin.systemd:
|
|
scope: user
|
|
daemon_reload: true
|
|
environment:
|
|
XDG_RUNTIME_DIR: "/run/user/{{ atlas_gitea_uid }}"
|
|
DBUS_SESSION_BUS_ADDRESS: "unix:path=/run/user/{{ atlas_gitea_uid }}/bus"
|
|
when: not ansible_check_mode
|
|
|
|
- name: Start and enable the rootless Gitea user Quadlet after final restore
|
|
become_user: "{{ atlas_gitea_username }}"
|
|
ansible.builtin.systemd:
|
|
name: atlas-gitea.service
|
|
scope: user
|
|
state: started
|
|
enabled: true
|
|
environment:
|
|
XDG_RUNTIME_DIR: "/run/user/{{ atlas_gitea_uid }}"
|
|
DBUS_SESSION_BUS_ADDRESS: "unix:path=/run/user/{{ atlas_gitea_uid }}/bus"
|
|
when:
|
|
- atlas_gitea_production_enabled | bool
|
|
- not ansible_check_mode
|