---
# Copyright 2018, Rackspace US, Inc.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
#     http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

- name: Run apt install block
  block:
    - name: Run the apt package pinning role
      ansible.builtin.include_role:
        name: apt_package_pinning
      vars:
        apt_package_pinning_file_name: "docker.pref"
        apt_package_pinning_priority: 999
        apt_pinned_packages:
          - package: "docker-ce"
            version: "{{ zun_docker_package_version }}"
            priority: 1000
          - package: "docker-ce-cli"
            version: "{{ zun_docker_package_version }}"
            priority: 1000
          - package: "containerd.io"
            version: "{{ zun_containerd_package_version }}"
            priority: 1000

    - name: Validate repo config is deb822 format
      vars:
        _repo_check: "{{ zun_docker_repo | selectattr('repo', 'defined') | map(attribute='repo') }}"
      ansible.builtin.assert:
        that: _repo_check | length == 0
        fail_msg: "The following repository definitions must be updated to deb822 format {{ _repo_check }}"

    # NOTE(jrosser) remove this task for the 2025.2 release
    - name: Clean up legacy repository config not in deb822 format
      ansible.builtin.file:
        path: "/etc/apt/sources.list.d/docker-ce.list"
        state: absent
      register: _cleanup_apt_repositories

    - name: Ensure python3-debian package is available
      ansible.builtin.apt:
        name: python3-debian

    - name: Manage apt repositories
      ansible.builtin.deb822_repository:
        allow_downgrade_to_insecure: "{{ item.allow_downgrade_to_insecure | default(omit) }}"
        allow_insecure: "{{ item.allow_insecure | default(omit) }}"
        allow_weak: "{{ item.allow_weak | default(omit) }}"
        architectures: "{{ item.architectures | default(omit) }}"
        by_hash: "{{ item.by_hash | default(omit) }}"
        check_date: "{{ item.check_date | default(omit) }}"
        check_valid_until: "{{ item.check_valid_until | default(omit) }}"
        components: "{{ item.components | default(omit) }}"
        date_max_future: "{{ item.date_max_future | default(omit) }}"
        enabled: "{{ item.enabled | default(omit) }}"
        inrelease_path: "{{ item.inrelease_path | default(omit) }}"
        languages: "{{ item.languages | default(omit) }}"
        mode: "{{ item.mode | default(omit) }}"
        name: "{{ item.name }}"
        pdiffs: "{{ item.pdiffs | default(omit) }}"
        signed_by: "{{ item.signed_by | default(omit) }}"
        state: "{{ item.state | default(omit) }}"
        suites: "{{ item.suites | default(omit) }}"
        targets: "{{ item.targets | default(omit) }}"
        trusted: "{{ item.trusted | default(omit) }}"
        types: "{{ item.types | default(omit) }}"
        uris: "{{ item.uris | default(omit) }}"
      with_items: "{{ zun_docker_repo }}"
      register: add_nv_repos

    - name: Update Apt cache
      ansible.builtin.apt:
        update_cache: true
      when: (add_nv_repos is changed) or (_cleanup_apt_repositories is changed)
      register: update_apt_cache
      until: update_apt_cache is success
      retries: 5
      delay: 2

  when:
    - "ansible_facts['pkg_mgr'] == 'apt'"

- name: Add docker repo
  ansible.builtin.yum_repository:
    name: "{{ item.name }}"
    description: "{{ item.description }}"
    baseurl: "{{ item.repo }}"
    gpgkey: "{{ item.gpgkey | default(omit) }}"
    gpgcheck: true
    enabled: true
    priority: 25
  register: add_docker_repos
  until: add_docker_repos is success
  retries: 5
  delay: 2
  with_items: "{{ zun_docker_repo }}"
  when:
    - ansible_facts['pkg_mgr'] == 'dnf'

- name: Enable module_hotfixes
  ansible.builtin.lineinfile:
    dest: "/etc/yum.repos.d/{{ item.name }}.repo"
    line: "module_hotfixes=1"
    regexp: "^module_hotfixes"
    insertafter: "^enabled"
  with_items: "{{ zun_docker_repo }}"
  when:
    - ansible_facts['os_family'] | lower == 'redhat'

- name: Install compute distro packages
  ansible.builtin.package:
    name: "{{ zun_distro_compute_packages }}"
    state: "{{ zun_package_state }}"
    update_cache: "{{ (ansible_facts['pkg_mgr'] == 'apt') | ternary('yes', omit) }}"
    cache_valid_time: "{{ (ansible_facts['pkg_mgr'] == 'apt') | ternary(cache_timeout, omit) }}"
    enablerepo: "{{ (ansible_facts['pkg_mgr'] == 'dnf') | ternary('extras', omit) }}"

- name: Install and configure katacontainers
  when: zun_kata_enabled | bool
  block:
    - name: Download kata package
      ansible.builtin.get_url:
        url: "{{ zun_kata_package_source }}"
        dest: "/opt/{{ zun_kata_package_source | basename }}"
        mode: "0440"
        checksum: "{{ zun_kata_package_checksum }}"
      register: _kata_downloaded

    - name: Unpack package
      ansible.builtin.unarchive:
        src: "/opt/{{ zun_kata_package_source | basename }}"
        dest: /opt/
        remote_src: true
        owner: root
        group: root
        extra_opts:
          - --strip-components=2
      when: _kata_downloaded is changed
      notify:
        - Restart containerd

    - name: Symlink kata binaries to PATH
      ansible.builtin.file:
        src: "{{ item.src }}"
        dest: "{{ item.dest }}"
        state: link
      with_items:
        - src: /opt/kata/bin/containerd-shim-kata-v2
          dest: /usr/local/bin/containerd-shim-kata-v2
        - src: /opt/kata/bin/kata-collect-data.sh
          dest: /usr/local/bin/kata-collect-data.sh
        - src: /opt/kata/bin/kata-runtime
          dest: /usr/local/bin/kata-runtime

    - name: Ensure the containerd config directory exists
      ansible.builtin.file:
        path: "/etc/containerd"
        state: "directory"
        owner: "root"
        group: "root"
        mode: "0755"

    - name: Configure containerd
      ansible.builtin.template:
        src: "config.toml.j2"
        dest: "/etc/containerd/config.toml"
        mode: "0644"
        owner: "root"
        group: "root"
      notify:
        - Restart containerd

- name: Ensure the Docker config directory exists
  ansible.builtin.file:
    path: "/etc/docker"
    state: "directory"
    owner: "root"
    group: "root"
    mode: "0755"

- name: Generate kuryr config
  openstack.config_template.config_template:
    content: |
      {
        "live-restore": true,
        "default-ipc-mode": "shareable"
      }
    dest: "/etc/docker/daemon.json"
    owner: "root"
    group: "root"
    mode: "0644"
    config_overrides: "{{ zun_docker_config_overrides }}"
    config_type: "json"
  notify:
    - Restart docker

- name: Create the kuryr system group
  ansible.builtin.group:
    name: "{{ zun_kuryr_system_group_name }}"
    gid: "{{ zun_kuryr_system_group_gid | default(omit) }}"
    state: "present"
    system: "yes"
  tags:
    - zun-kuryr-group

- name: Create the kuryr system user
  ansible.builtin.user:
    name: "{{ zun_kuryr_system_user_name }}"
    uid: "{{ zun_kuryr_system_user_uid | default(omit) }}"
    group: "{{ zun_kuryr_system_group_name }}"
    comment: "{{ zun_kuryr_system_comment }}"
    shell: "{{ zun_kuryr_system_shell }}"
    system: "yes"
    createhome: "yes"
    home: "{{ zun_kuryr_system_home_folder }}"
  when: zun_kuryr_system_user_name != 'root'
  tags:
    - zun-kuryr-user

- name: Create kuryr dir
  ansible.builtin.file:
    path: "{{ item.path }}"
    state: directory
    owner: "{{ item.owner | default('root') }}"
    group: "{{ item.group | default('root') }}"
    mode: "{{ item.mode | default('0755') }}"
  with_items:
    - path: "/etc/kuryr"
      mode: "0750"
      owner: "{{ zun_kuryr_system_user_name }}"
      group: "{{ zun_kuryr_system_group_name }}"
    - path: "/etc/docker/plugins"
  tags:
    - zun-kuryr-dirs

- name: Generate kuryr config
  openstack.config_template.config_template:
    src: "{{ item.src }}"
    dest: "{{ item.dest }}"
    owner: "{{ zun_kuryr_system_user_name }}"
    group: "{{ zun_system_group_name }}"
    mode: "0640"
    config_overrides: "{{ item.config_overrides }}"
    config_type: "{{ item.config_type }}"
  with_items:
    - src: "kuryr-libnetwork.conf.j2"
      dest: "/etc/kuryr/kuryr.conf"
      config_overrides: "{{ zun_kuryr_conf_overrides }}"
      config_type: "ini"
  notify:
    - Restart docker
  tags:
    - zun-config
    - zun-post-install

- name: Generate kuryr docker plugin config
  openstack.config_template.config_template:
    content: |
      {
        "Name": "kuryr",
        "Addr": "http://127.0.0.1:23750"
      }
    dest: "/etc/docker/plugins/kuryr.json"
    owner: "root"
    group: "root"
    mode: "0644"
    config_overrides: "{{ zun_kuryr_config_overrides }}"
    config_type: "json"
  notify:
    - Restart docker

- name: Ensure docker users are added to the docker group
  ansible.builtin.user:
    name: "{{ item }}"
    groups: "{{ zun_docker_groupname }}"
    append: true
  with_items: "{{ zun_docker_users }}"

- name: Drop sudoers file
  ansible.builtin.template:
    src: "sudoers.j2"
    dest: "/etc/sudoers.d/{{ zun_system_user_name }}_sudoers"
    mode: "0440"
    owner: "root"
    group: "root"
  tags:
    - sudoers
    - zun-sudoers

- name: Configure multipathd (RedHat only)
  ansible.builtin.command:
    cmd: "/sbin/mpathconf --enable"
    creates: "/etc/multipath.conf"
  when: ansible_facts['os_family'] == "RedHat"

- name: Enable multipathd service
  ansible.builtin.systemd:
    name: multipathd
    state: started
    enabled: true

- name: Create script to clean up old Docker data
  ansible.builtin.template:
    src: "zun-docker-cleanup.j2"
    dest: "{{ zun_bin }}/zun-docker-cleanup"
    owner: "root"
    group: "root"
    mode: "0755"

- name: Set state for timed data cleanup
  ansible.builtin.file:
    path: "/var/tmp/zun-docker-cleanup.disabled"
    state: "{{ zun_docker_prune_images | ternary('absent', 'touch') }}"
    mode: "0644"

- name: Remove legacy systemd docker override
  ansible.builtin.file:
    path: "/etc/systemd/system/docker.service.d/zun-docker.conf"
    state: absent