fix(utils): make install-minikube-cluster.sh work on macOS#970
Conversation
Fixes vllm-project#931. The script previously assumed Linux throughout and failed on macOS in three distinct ways: 1. **Minikube binary selection.** Unconditionally downloaded minikube-linux-amd64 even on Darwin. Also short-circuited on 'minikube already on PATH' without checking the binary is executable, so a Linux ELF copied to /usr/local/bin/minikube would never get replaced. Now detects OS (uname -s) and arch (uname -m), downloads the matching minikube-{linux,darwin}-{amd64,arm64} release, and requires the existing binary to actually run before considering it installed. 2. **calculate_safe_memory.** Read /proc/meminfo, which doesn't exist on macOS. Now uses 'sysctl -n hw.memsize' on Darwin (with ~60% available estimate, since Docker Desktop's VM budget has no clean equivalent to MemAvailable) and keeps the existing /proc/meminfo path on Linux. cgroup-v2 detection stays Linux-only. 3. **systemctl restart docker / sudo sysctl fs.protected_regular=0.** Both Linux-only — systemctl isn't on macOS, and fs.protected_regular is a Linux sysctl. Now guarded on HOST_OS == linux, with a hint on macOS to restart Docker Desktop manually. BPF section was already guarded on /proc/sys path existence, no change needed there. Signed-off-by: HumphreySun98 <[email protected]>
There was a problem hiding this comment.
Code Review
This pull request updates utils/install-minikube-cluster.sh to support macOS and ARM64 architectures by adding OS and architecture detection, adjusting memory calculation, and restricting Linux-specific commands (like systemctl and sysctl fs.protected_regular) to Linux environments. Feedback points out that install-kubectl.sh (called by this script) still unconditionally downloads the Linux AMD64 binary, which will fail on macOS. Additionally, it is recommended to use the -f flag with curl when downloading Minikube to ensure the script fails immediately on HTTP errors.
| OS_KERNEL="$(uname -s)" | ||
| case "$OS_KERNEL" in | ||
| Linux) HOST_OS=linux ;; | ||
| Darwin) HOST_OS=darwin ;; | ||
| *) echo "ERROR: unsupported OS: $OS_KERNEL" >&2; exit 1 ;; | ||
| esac |
There was a problem hiding this comment.
While this PR successfully adds OS and architecture detection to install-minikube-cluster.sh, the script still calls install-kubectl.sh (on line 38), which unconditionally downloads the Linux AMD64 binary of kubectl:
curl -LO "https://dl.k8s.io/release/$(curl -L -s https://dl.k8s.io/release/stable.txt)/bin/linux/amd64/kubectl"On macOS, this results in an unexecutable Linux ELF binary being installed to ~/.local/bin/kubectl, causing any subsequent kubectl commands to fail with an execution format error.
To fully support macOS, utils/install-kubectl.sh also needs to be updated to detect the OS and architecture (similar to how it is done here) and download the correct binary.
| curl -LO "https://github.com/kubernetes/minikube/releases/latest/download/minikube-${HOST_OS}-${HOST_ARCH}" | ||
| sudo install "minikube-${HOST_OS}-${HOST_ARCH}" /usr/local/bin/minikube && rm "minikube-${HOST_OS}-${HOST_ARCH}" |
There was a problem hiding this comment.
Using curl -LO without the -f (or --fail) option can be problematic. If the server returns an HTTP error (such as a 404 or 500), curl will still exit with status 0 and save the error page's HTML content to the destination file. The script will then proceed to install this HTML file as the minikube binary, leading to confusing failures.
Adding the -f flag ensures curl fails immediately on server errors, allowing set -e to abort the script safely.
| curl -LO "https://github.com/kubernetes/minikube/releases/latest/download/minikube-${HOST_OS}-${HOST_ARCH}" | |
| sudo install "minikube-${HOST_OS}-${HOST_ARCH}" /usr/local/bin/minikube && rm "minikube-${HOST_OS}-${HOST_ARCH}" | |
| curl -fLO "https://github.com/kubernetes/minikube/releases/latest/download/minikube-${HOST_OS}-${HOST_ARCH}" | |
| sudo install "minikube-${HOST_OS}-${HOST_ARCH}" /usr/local/bin/minikube && rm "minikube-${HOST_OS}-${HOST_ARCH}" |
Without -f, curl saves the server's error page (e.g. a 404/500 HTML body)
to minikube-${HOST_OS}-${HOST_ARCH} and exits 0, so the script then tries
to install that HTML as the minikube binary. -f makes curl exit non-zero on
HTTP errors, letting set -e abort cleanly.
Addresses review feedback on vllm-project#970.
Signed-off-by: HumphreySun98 <[email protected]>
|
Thanks for the review! Addressed both points:
Also updated the branch to latest |
|
Follow-up for the |
install-kubectl.sh always downloaded the linux/amd64 kubectl, so on macOS
it installed an unexecutable Linux ELF (later kubectl calls fail with an
exec format error). Detect OS (uname -s) and arch (uname -m) and download
the matching bin/{linux,darwin}/{amd64,arm64}/kubectl, mirroring the OS/arch
detection added to install-minikube-cluster.sh in #970.
Also: treat an existing kubectl as installed only if it actually runs
(`kubectl version --client`), so a stale Linux binary left on PATH on macOS
is replaced rather than skipped; and use `curl -f` so HTTP errors abort
instead of saving an error page as the binary.
Follow-up to the review on #970; relates to #931.
Signed-off-by: HumphreySun98 <[email protected]>
Co-authored-by: Rui Zhang <[email protected]>
Fixes #931.
Summary
The script assumed Linux throughout and failed on macOS in three distinct ways. All are fixed in this PR without changing Linux behavior.
Fixes
Minikube binary selection. Previously downloaded `minikube-linux-amd64` unconditionally even on Darwin. Also short-circuited on "minikube already on PATH" without checking the binary is actually executable — a Linux ELF copied to `/usr/local/bin/minikube` would never get replaced (matches the issue's reproduction: `/usr/local/bin/minikube: cannot execute binary file`). Now detects OS (`uname -s`) and arch (`uname -m`), downloads the matching `minikube-{linux,darwin}-{amd64,arm64}` release, and requires the existing binary to actually `minikube version` cleanly before treating it as installed.
`calculate_safe_memory`. Read `/proc/meminfo`, which doesn't exist on macOS. Now uses `sysctl -n hw.memsize` on Darwin (with a ~60% available estimate, since Docker Desktop's VM budget has no clean equivalent to Linux's `MemAvailable`) and keeps the existing `/proc/meminfo` path on Linux. cgroup-v2 detection stays Linux-only.
`systemctl restart docker` / `sudo sysctl fs.protected_regular=0`. Both Linux-only — `systemctl` isn't on macOS, and `fs.protected_regular` is a Linux sysctl. Now guarded on `HOST_OS == linux`, with a hint on macOS to restart Docker Desktop manually.
The BPF section was already guarded on `/proc/sys/net/core/bpf_jit_harden` existence, so no change needed there.
Test plan
Out of scope
Docker Desktop restart automation on macOS (would need `osascript` + user permission). Left as a printed instruction. Same for the GPU Operator step — NVIDIA GPU passthrough on Apple Silicon Docker Desktop isn't supported by NVIDIA Container Toolkit, so users on macOS will hit the `No NVIDIA GPU detected` branch anyway.