Skip to content

Comments

fix: kubectl binary copy works through bastion and cross-platform#1339

Merged
michael-balint merged 1 commit intoNVIDIA:masterfrom
dholt:fix/kubectl-cross-platform
Feb 20, 2026
Merged

fix: kubectl binary copy works through bastion and cross-platform#1339
michael-balint merged 1 commit intoNVIDIA:masterfrom
dholt:fix/kubectl-cross-platform

Conversation

@dholt
Copy link
Contributor

@dholt dholt commented Feb 20, 2026

Summary

  • Replace synchronize (rsync) with fetch module for copying kubectl from the cluster — rsync spawns its own SSH connection that bypasses ansible_ssh_common_args, failing when a bastion/proxy is required.
  • Add cross-platform support: detect when the ansible controller and cluster have different OS/arch (e.g., macOS ARM vs Linux x86-64) and download the correct kubectl binary from dl.k8s.io matching the cluster's K8s version.
  • Install kubectl to the active virtualenv ($VIRTUAL_ENV/bin/) instead of /usr/local/bin, eliminating the need for sudo.

Test plan

  • fetch copies kubectl through SSH bastion successfully
  • Cross-platform download detects macOS ARM vs Linux x86-64 and downloads correct binary
  • kubectl installed to .venv/bin/kubectl — correct Mach-O arm64 binary
  • kubectl version --client returns matching cluster version (v1.34.3)
  • Full playbook run with --tags local completes with zero failures
  • No sudo required for kubectl installation

🤖 Generated with Claude Code

Replace synchronize (rsync) with fetch module for copying kubectl from
the cluster — rsync spawns its own SSH that bypasses ansible_ssh_common_args,
failing when a bastion/proxy is required.

Add cross-platform support: detect when the ansible controller and cluster
have different OS/arch (e.g., macOS ARM vs Linux x86-64) and download the
correct kubectl binary from dl.k8s.io matching the cluster's K8s version.

Install kubectl to the active virtualenv ($VIRTUAL_ENV/bin/) instead of
/usr/local/bin, eliminating the need for sudo and keeping it scoped to
the DeepOps environment.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Signed-off-by: Douglas Holt <dholt@nvidia.com>
Copy link

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

Updates the Kubernetes cluster playbook’s “local” kubectl handling so it works when connecting through a bastion/proxy and when the Ansible controller platform differs from the cluster platform, while also avoiding sudo by installing kubectl into the active virtualenv.

Changes:

  • Replace synchronize/rsync pull with fetch to copy kubectl through the existing Ansible SSH connection (bastion-friendly).
  • Add controller/remote platform detection and download a matching kubectl binary for the controller when OS/arch differs.
  • Install kubectl into $VIRTUAL_ENV/bin/ (when available) instead of /usr/local/bin.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

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.
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
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.

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.
@michael-balint michael-balint merged commit d15df99 into NVIDIA:master Feb 20, 2026
20 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants