Skip to content
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
87 changes: 49 additions & 38 deletions playbooks/k8s-cluster.yml
Original file line number Diff line number Diff line change
Expand Up @@ -182,71 +182,82 @@
gpu_operator_preinstalled_nvidia_software|default(true)
- container_manager is defined and container_manager == "docker"

# Manage kubectl binary
# Manage kubectl binary — handles cross-platform (e.g., Linux cluster → macOS controller)
- hosts: kube_control_plane
gather_facts: false
vars:
ansible_become: no
tasks:
- name: copy kubectl binary to ansible host
synchronize:
mode: pull
- name: detect ansible host platform
command: uname -sm
register: local_uname
delegate_to: localhost
run_once: true
changed_when: false

- name: detect remote platform
command: uname -sm
register: remote_uname
run_once: true
changed_when: false

- name: copy kubectl binary to ansible host (matching platform)
fetch:
src: "/usr/local/bin/kubectl"
dest: "{{ artifacts_dir }}/kubectl"
flat: yes
run_once: true
when: local_uname.stdout == remote_uname.stdout

Copy link

Copilot AI Feb 20, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

fetch doesn't guarantee the fetched file is executable on the controller. Since later tasks execute {{ artifacts_dir }}/kubectl, ensure you set mode 0755 on the fetched file (e.g., follow the existing pattern used after fetch in roles/netapp-trident/tasks/main.yml).

Suggested change
- name: ensure kubectl binary is executable on ansible host
file:
path: "{{ artifacts_dir }}/kubectl"
mode: '0755'
delegate_to: localhost
run_once: true
when: local_uname.stdout == remote_uname.stdout

Copilot uses AI. Check for mistakes.
- name: get kubectl version for cross-platform download
command: /usr/local/bin/kubectl version --client -o json
register: kubectl_ver_json
run_once: true
Copy link

Copilot AI Feb 20, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This kubectl version command is used only for discovery, but without changed_when: false it will report the play as changed on every run. Add changed_when: false (and optionally failed_when handling if you want to tolerate missing kubectl) to keep the --tags local run idempotent.

Suggested change
run_once: true
run_once: true
changed_when: false

Copilot uses AI. Check for mistakes.
when: local_uname.stdout != remote_uname.stdout

- name: download kubectl for ansible host platform
vars:
kubectl_ver: "{{ (kubectl_ver_json.stdout | from_json).clientVersion.gitVersion }}"
kubectl_os: "{{ 'darwin' if 'Darwin' in local_uname.stdout else 'linux' }}"
kubectl_arch: "{{ 'arm64' if 'arm64' in local_uname.stdout or 'aarch64' in local_uname.stdout else 'amd64' }}"
get_url:
url: "https://dl.k8s.io/release/{{ kubectl_ver }}/bin/{{ kubectl_os }}/{{ kubectl_arch }}/kubectl"
dest: "{{ artifacts_dir }}/kubectl"
mode: '0755'
force: yes
Copy link

Copilot AI Feb 20, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The cross-platform get_url download runs on localhost but doesn't pass proxy_env. If this repo is configured to run behind an HTTP(S) proxy (as many other tasks do), this download will fail; consider adding environment: "{{ proxy_env if proxy_env is defined else {} }}" to this task.

Suggested change
force: yes
force: yes
environment: "{{ proxy_env if proxy_env is defined else {} }}"

Copilot uses AI. Check for mistakes.
Comment on lines +223 to +227
Copy link

Copilot AI Feb 20, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This downloads an executable kubectl binary but doesn't verify integrity (no checksum). Consider fetching the published SHA256 for the selected version/arch and using get_url's checksum parameter to reduce supply-chain risk.

Copilot uses AI. Check for mistakes.
delegate_to: localhost
run_once: true
when: local_uname.stdout != remote_uname.stdout
tags:
- local
- hosts: k8s_cluster
gather_facts: false
vars:
config_dir: "../config"
venv_dir: "{{ lookup('env', 'VIRTUAL_ENV') }}"
tasks:
- name: check for kubectl
- name: check for kubectl in artifacts
stat:
path: "{{ artifacts_dir }}/kubectl"
register: kubectl_local
become: no
delegate_to: localhost
run_once: true
- name: modify kubectl permissions
file:
path: "{{ artifacts_dir }}/kubectl"
mode: '0755'
become: no
when: kubectl_local.stat.exists
delegate_to: localhost
run_once: true
- name: copy kubectl to /usr/local/bin
- name: install kubectl to virtualenv
copy:
src: "{{ artifacts_dir }}/kubectl"
dest: "/usr/local/bin/kubectl"
when: kubectl_local.stat.exists
become: yes
ignore_errors: yes
register: kubectl_copied
delegate_to: localhost
run_once: true
- name: check for copied kubectl
stat:
path: "/usr/local/bin/kubectl"
register: kubectl_system
delegate_to: localhost
run_once: true
- name: modify kubectl permissions
file:
path: "/usr/local/bin/kubectl"
owner: root
group: root
dest: "{{ venv_dir }}/bin/kubectl"
mode: '0755'
become: yes
ignore_errors: yes
when: kubectl_system.stat.exists
become: no
delegate_to: localhost
run_once: true
- name: manually move kubectl binary
when: kubectl_local.stat.exists and venv_dir != ''
- name: kubectl location
debug:
msg: "Unable to move kubectl, run: sudo cp {{ artifacts_dir | realpath }}/kubectl /usr/local/bin"
when: kubectl_copied is failed
msg: >-
{{ 'kubectl installed to ' ~ venv_dir ~ '/bin/kubectl'
if venv_dir != ''
else 'No virtualenv detected. kubectl is at ' ~ artifacts_dir ~ '/kubectl' }}
delegate_to: localhost
run_once: true
tags:
Expand Down
Loading