---
- name: Check for runner-provided kube-vip image archive
  stat:
    path: "{{ playbook_dir }}/../outputs/kube-vip-bootstrap.tar"
  delegate_to: localhost
  become: false
  register: kube_vip_bootstrap_archive

- name: Copy runner-provided kube-vip image archive
  copy:
    src: "{{ playbook_dir }}/../outputs/kube-vip-bootstrap.tar"
    dest: /tmp/kube-vip-bootstrap.tar
    mode: "0644"
  when: kube_vip_bootstrap_archive.stat.exists

- name: Import runner-provided kube-vip image archive
  command: /usr/local/bin/ctr -n k8s.io images import /tmp/kube-vip-bootstrap.tar
  changed_when: false
  when: kube_vip_bootstrap_archive.stat.exists

- name: Pre-pull kube-vip bootstrap images into containerd
  shell: |
    if /usr/local/bin/ctr -n k8s.io images ls -q | grep -Fx -- "{{ item }}" >/dev/null; then
      echo "already present"
      exit 0
    fi

    for attempt in 1 2 3; do
      if timeout 120s /usr/local/bin/ctr -n k8s.io images pull "{{ item }}"; then
        echo "pulled image"
        exit 0
      fi

      sleep 10
    done

    exit 1
  args:
    executable: /bin/bash
  register: kube_vip_image_pull
  loop: "{{ kube_vip_prepull_images }}"
  changed_when: "'pulled image' in kube_vip_image_pull.stdout"
  failed_when: false

- name: Report kube-vip images that did not pre-pull after retries
  debug:
    msg: >-
      Best-effort kube-vip image pre-pull did not complete for {{ item.item }} after
      3 attempt(s): {{ item.stderr | default('no stderr') }}
  loop: "{{ kube_vip_image_pull.results | default([]) }}"
  loop_control:
    label: "{{ item.item }}"
  when: item.rc is defined and item.rc != 0

- name: Render kube-vip control plane manifest
  template:
    src: kube-vip-control-plane.yaml.j2
    dest: /tmp/kube-vip-control-plane.yaml
    mode: "0644"

- name: Apply kube-vip control plane manifest
  command: kubectl apply -f /tmp/kube-vip-control-plane.yaml
  changed_when: true

- name: Wait for local kube-vip pod to be ready
  shell: >-
    kubectl -n kube-system get pods
    -l app.kubernetes.io/name=kube-vip
    --field-selector spec.nodeName={{ inventory_hostname }}
    -o jsonpath='{.items[0].status.conditions[?(@.type=="Ready")].status}'
  register: kube_vip_pod_ready
  changed_when: false
  until: kube_vip_pod_ready.stdout == "True"
  retries: 30
  delay: 10

- name: Show kube-vip pod status on failure
  command: kubectl -n kube-system get pods -l app.kubernetes.io/name=kube-vip -o wide
  register: kube_vip_pods
  changed_when: false
  failed_when: false
  when: kube_vip_pod_ready is failed

- name: Describe kube-vip pod on failure
  shell: >-
    kubectl -n kube-system describe pod
    $(kubectl -n kube-system get pods -l app.kubernetes.io/name=kube-vip --field-selector spec.nodeName={{ inventory_hostname }} -o jsonpath='{.items[0].metadata.name}')
  register: kube_vip_pod_describe
  changed_when: false
  failed_when: false
  when: kube_vip_pod_ready is failed

- name: Fail with kube-vip diagnostics
  fail:
    msg: |
      kube-vip failed to become ready on {{ inventory_hostname }}.
      Pods:
      {{ kube_vip_pods.stdout | default('n/a') }}

      Describe:
      {{ kube_vip_pod_describe.stdout | default('n/a') }}
  when: kube_vip_pod_ready is failed

- name: Wait for API VIP on 6443
  wait_for:
    host: "{{ kube_vip_address }}"
    port: 6443
    state: started
    timeout: 180
