---
# file: roles/incus/tasks/main.yml

- name: "/etc/apt/sources.list.d/zabbly.sources"
  ansible.builtin.deb822_repository:
    name: zabbly
    types: deb
    uris: "https://pkgs.zabbly.com/incus/{{ incus_repository }}"
    suites: "{{ ansible_distribution_release }}"
    components: main
    architectures: amd64
    signed_by: https://pkgs.zabbly.com/key.asc
  register: incus_repository_out
  tags: incus

- name: "apt pin incus version"
  ansible.builtin.copy:
    content: |
      Package: incus*
      Pin: version {{ incus_version_epoch }}:{{ incus_version }}*
      Pin-Priority: 999
    dest: "/etc/apt/preferences.d/incus"
  register: incus_pin_out
  when: incus_version is defined
  tags: incus

- name: "apt update"
  ansible.builtin.apt:
    update_cache: true
  when: incus_repository_out.changed or incus_pin_out.changed
  tags: incus

- name: "install needed packages: bridge-utils and ifenslave for the network, jq/curl for monitoring and apparmor for security"
  ansible.builtin.apt:
    name:
      - bridge-utils
      - ifenslave
      - apparmor
      - curl
  tags: incus

- name: "install incus (and upgrade if incus_version is defined and incus_update_now)"
  ansible.builtin.apt:
    name:
      - incus
    state: "{{ 'latest' if incus_version is defined and incus_update_now else 'present' }}"
  tags: incus

- name: "/etc/sysctl.conf tunable that should alway be set"
  ansible.posix.sysctl:
    name: "{{ item['name'] }}"
    value: "{{ item['value'] }}"
  loop:
    - { 'name': 'fs.aio-max-nr', 'value': '524288' }
    - { 'name': 'fs.inotify.max_queued_events', 'value': '1048576' }
    - { 'name': 'fs.inotify.max_user_instances', 'value': '1048576' }
    - { 'name': 'fs.inotify.max_user_watches', 'value': '1048576' }
    - { 'name': 'kernel.dmesg_restrict', 'value': '1' }
    - { 'name': 'kernel.keys.maxbytes', 'value': '2000000' }
    - { 'name': 'kernel.keys.maxkeys', 'value': '2000' }
    - { 'name': 'vm.max_map_count', 'value': '262144' }
    - { 'name': 'net.core.bpf_jit_limit', 'value': '1000000000' }
    - { 'name': 'net.ipv4.neigh.default.gc_thresh3', 'value': '8192' }
    - { 'name': 'net.ipv6.neigh.default.gc_thresh3', 'value': '8192' }
  tags:
    - incus
    - sysctl

- name: "incus dataset"
  community.general.zfs:
    name: "{{ incus_zfs_root_dataset }}"
    state: present
    extra_zfs_properties:
      mountpoint: legacy
  when: incus_zfs_backend
  tags: incus

- name: "set default incus_ip"
  ansible.builtin.set_fact:
    incus_ip: "[::]"
  when: incus_ip is not defined
  tags: incus

- name: "dump current admin init"
  ansible.builtin.command: "/usr/bin/incus admin init --dump"
  register: incus_admin_init_dump
  changed_when: false
  check_mode: false
  tags: incus

- name: "display current incus configuration"
  ansible.builtin.debug:
    var: incus_admin_init_dump.stdout
    verbosity: 1
  tags: incus

- name: "set configuration if first standalone install"
  ansible.builtin.shell: 'echo "{{ incus_standalone_init_yaml }}" | /usr/bin/incus admin init --preseed'
  when:
    - incus_admin_init_dump.stdout == incus_yaml_unconfigured
    - incus_cluster_name is not defined
  tags: incus

- name: "install cluster"
  ansible.builtin.import_tasks: cluster.yml
  when: incus_cluster_name is defined
  tags: incus

- name: "incus profiles"
  ansible.builtin.import_tasks: profiles.yml
  when: incus_cluster_name is not defined
  tags:
    - incus
    - incus_profiles

- name: "administration scripts"
  ansible.builtin.import_tasks: scripts.yml
  tags:
    - incus
    - incus_scripts

- name: "handle /etc/subuid"
  ansible.builtin.lineinfile:
    path: "/etc/subuid"
    line: "root:{{ item }}:1"
  loop: "{{ incus_subuid_list }}"
  when: incus_subuid_list is defined
  tags: incus

- name: "handle /etc/subgid"
  ansible.builtin.lineinfile:
    path: "/etc/subgid"
    line: "root:{{ item }}:1"
  loop: "{{ incus_subgid_list }}"
  when: incus_subgid_list is defined
  tags: incus

- name: "get and set https_address"
  ansible.builtin.include_tasks:
    file: get_and_set.yml
    apply:
      tags:
        - incus
  loop:
    - { section: config, key: "core.https_address", value: "{{ incus_ip }}:8443" }
  tags: incus

- name: "get and set core.bgp_*"
  ansible.builtin.include_tasks:
    file: get_and_set.yml
    apply:
      tags:
        - incus
  loop:
    - { section: config, key: "core.bgp_address", value: "{{ incus_ip }}:179" }
    - { section: config, key: "core.bgp_asn", value: "{{ incus_bgp_asn }}" }
    - { section: config, key: "core.bgp_routerid", value: "{{ incus_ip }}" }
  when: incus_bgp_asn is defined
  tags: incus

- name: "incus trust configuration via openssl certificates"
  ansible.builtin.import_tasks: trust.yml
  when:
    - incus_trust_list is defined
    - incus_cluster_name is not defined or (incus_cluster_name is defined and ansible_hostname == incus_cluster_main_name)
  tags:
    - incus
    - incus_trust

- name: "cosinfo"
  ansible.builtin.import_tasks: cosinfo.yml
  tags:
    - incus
    - cosinfo
