---
# showcase/k3s-control.yml — K3s server (control plane) setup
#
# Installs K3s in server mode. The join token is stored at
# /var/lib/rancher/k3s/server/token for workers to read
# via the Incus API.
#
# Note: The Aether blueprint profile should include:
#   security.nesting: "true"
# for K3s to manage pods and containers properly.

- name: Generate K3s server setup script
  ansible.builtin.set_fact:
    k3s_server_script: |
      #!/bin/bash
      set -e

      echo "=== K3s server setup starting ==="
      export DEBIAN_FRONTEND=noninteractive

      # Container workaround: create /dev/kmsg if missing
      [ -e /dev/kmsg ] || ln -s /dev/console /dev/kmsg

      # Install prerequisites
      apt-get install -y -qq curl 2>&1 | tail -1

      # Install K3s server
      echo "Installing K3s server (this takes 1-2 minutes)..."
      curl -sfL https://get.k3s.io | INSTALL_K3S_EXEC="\
        --write-kubeconfig-mode=644 \
        --disable=traefik \
        --snapshotter=native \
        --kubelet-arg=feature-gates=KubeletInUserNamespace=true \
        --node-ip={{ ffsdn_instance_ip | default('127.0.0.1') }} \
        --tls-san={{ ffsdn_instance_ip | default('127.0.0.1') }}" sh -
      echo "[OK] K3s installed"

      # Wait for K3s to be ready
      echo "Waiting for K3s node to be ready..."
      export KUBECONFIG=/etc/rancher/k3s/k3s.yaml
      for i in $(seq 1 60); do
        if kubectl get nodes 2>/dev/null | grep -q ' Ready'; then
          echo "[OK] K3s node ready"
          break
        fi
        sleep 5
      done

      # Show node status
      kubectl get nodes -o wide 2>/dev/null || true

      # Verify token file exists
      if [ -f /var/lib/rancher/k3s/server/node-token ]; then
        echo "[OK] Join token stored at /var/lib/rancher/k3s/server/node-token"
      else
        echo "[ERROR] Join token not found"
        exit 1
      fi

      echo "=== K3s server setup complete ==="

- name: Push K3s server setup script
  ansible.builtin.uri:
    url: "{{ incus_api }}/1.0/instances/{{ ffsdn_instance_name }}/files?path=/tmp/k3s-server-setup.sh"
    method: POST
    client_cert: "{{ incus_cert }}"
    client_key: "{{ incus_key }}"
    validate_certs: false
    body: "{{ k3s_server_script }}"
    headers:
      Content-Type: "application/octet-stream"
      X-Incus-type: "file"
      X-Incus-mode: "0755"
    status_code: [200]

- name: Execute K3s server setup script
  ansible.builtin.uri:
    url: "{{ incus_api }}/1.0/instances/{{ ffsdn_instance_name }}/exec"
    method: POST
    client_cert: "{{ incus_cert }}"
    client_key: "{{ incus_key }}"
    validate_certs: false
    body_format: json
    body:
      command: ["/bin/bash", "/tmp/k3s-server-setup.sh"]
      record-output: true
      interactive: false
      wait-for-websocket: false
      environment:
        DEBIAN_FRONTEND: "noninteractive"
    status_code: [202]
    return_content: true
  register: k3s_server_exec

- name: Wait for K3s server setup to complete (up to 10 minutes)
  ansible.builtin.uri:
    url: "{{ incus_api }}{{ k3s_server_exec.json.operation }}/wait?timeout=600"
    method: GET
    client_cert: "{{ incus_cert }}"
    client_key: "{{ incus_key }}"
    validate_certs: false
    return_content: true
    timeout: 620
  register: k3s_server_wait
  failed_when: k3s_server_wait.json.metadata.status != "Success"

- name: Verify K3s server setup exit code
  ansible.builtin.assert:
    that:
      - k3s_server_wait.json.metadata.metadata.return | int == 0
    fail_msg: "K3s server setup exited with code {{ k3s_server_wait.json.metadata.metadata.return }}"
    success_msg: "K3s server setup completed — control plane ready"

- name: Verify join token is accessible
  ansible.builtin.uri:
    url: "{{ incus_api }}/1.0/instances/{{ ffsdn_instance_name }}/files?path=/var/lib/rancher/k3s/server/token"
    method: GET
    client_cert: "{{ incus_cert }}"
    client_key: "{{ incus_key }}"
    validate_certs: false
    return_content: true
  register: token_check

- name: Display K3s server info
  ansible.builtin.debug:
    msg: "K3s control plane ready at {{ ffsdn_instance_ip | default('unknown') }}:6443 — token available for workers"

- name: Clean up setup script
  ansible.builtin.uri:
    url: "{{ incus_api }}/1.0/instances/{{ ffsdn_instance_name }}/exec"
    method: POST
    client_cert: "{{ incus_cert }}"
    client_key: "{{ incus_key }}"
    validate_certs: false
    body_format: json
    body:
      command: ["/bin/rm", "-f", "/tmp/k3s-server-setup.sh"]
      record-output: false
      interactive: false
      wait-for-websocket: false
    status_code: [202]
  ignore_errors: true
