Bug Description
./bootstrap.sh fails in the llmkube_core role at the
Build + install metal-agent via LLMKube's Makefile task. The
underlying error is the same TTY-less sudo class we keep hitting:
sudo: a terminal is required to read the password
make: *** [install-metal-agent] Error 1
Root Cause
The role calls make install-metal-agent against the cloned
LLMKube source. That Makefile target runs sudo cp bin/llmkube-metal-agent /usr/local/bin/llmkube-metal-agent
internally. Same pattern as the docker-desktop cask bug (#8):
brew/make's sudo bypasses Ansible's BECOME plumbing, so the
sudo prompt has no TTY and bails.
The Makefile is also the source of truth for the manual install
path (anyone running make install-metal-agent in a Terminal),
so we can't just remove sudo from it; we have to bypass that
target from the bootstrap side.
Fix
Replace the single make install-metal-agent task with explicit
Ansible tasks that use become: true for the privileged step
and Ansible's BECOME password (from --ask-become-pass) for
authentication:
make build-metal-agent — builds the binary into
<repo>/bin/llmkube-metal-agent. No sudo.
ansible.builtin.file become: true — ensure /usr/local/bin
exists (it does not on a fresh Apple Silicon Mac since
Homebrew lives at /opt/homebrew/bin).
ansible.builtin.copy become: true — install the binary
into /usr/local/bin/llmkube-metal-agent. Equivalent to the
Makefile's sudo cp but driven through the channel that
actually has the password.
ansible.builtin.file — ensure ~/Library/LaunchAgents
exists (no become; user-space).
ansible.builtin.copy — install the launchd plist (no
become; user-space).
ansible.builtin.shell — launchctl bootout || true +
launchctl bootstrap gui/<uid> <plist> to atomically reload
the daemon. Modern bootstrap/bootout API instead of the
legacy launchctl load. Triggers only on binary or plist
change.
The role's existing env vars
(LLMKUBE_METAL_AGENT_{MODEL_STORE,MEMORY_FRACTION,LLAMA_SERVER_PORT})
are preserved on the build call for forward-compat with any
future Makefile templating; today they're unused but the cost
of keeping them is zero.
Related: fix the LLMKube Makefile too
This bootstrap fix unblocks ./bootstrap.sh, but the LLMKube
Makefile itself still has the problem for anyone running
make install-metal-agent manually on a non-TTY context.
Follow-up bug should be filed against defilantech/LLMKube to
either:
- Detect Apple Silicon and install to
/opt/homebrew/bin (no
sudo needed there), or
- Document the TTY requirement clearly + suggest using ansible
/ a wrapper script for headless installs
Filed as a separate issue against the LLMKube repo, linked from
the bootstrap PR.
Severity
High. Default ./bootstrap.sh cannot complete a full install
on a fresh Apple Silicon Mac. Same severity class as #5 / #8.
Surfaced on the Mac Studio bootstrap run on 2026-05-23,
immediately after PR #9 (colima switch) cleared the previous
docker-desktop failure.
Bug Description
./bootstrap.shfails in thellmkube_corerole at theBuild + install metal-agent via LLMKube's Makefiletask. Theunderlying error is the same TTY-less sudo class we keep hitting:
Root Cause
The role calls
make install-metal-agentagainst the clonedLLMKube source. That Makefile target runs
sudo cp bin/llmkube-metal-agent /usr/local/bin/llmkube-metal-agentinternally. Same pattern as the docker-desktop cask bug (#8):
brew/make's sudo bypasses Ansible's BECOME plumbing, so the
sudo prompt has no TTY and bails.
The Makefile is also the source of truth for the manual install
path (anyone running
make install-metal-agentin a Terminal),so we can't just remove sudo from it; we have to bypass that
target from the bootstrap side.
Fix
Replace the single
make install-metal-agenttask with explicitAnsible tasks that use
become: truefor the privileged stepand Ansible's BECOME password (from
--ask-become-pass) forauthentication:
make build-metal-agent— builds the binary into<repo>/bin/llmkube-metal-agent. No sudo.ansible.builtin.file become: true— ensure/usr/local/binexists (it does not on a fresh Apple Silicon Mac since
Homebrew lives at
/opt/homebrew/bin).ansible.builtin.copy become: true— install the binaryinto
/usr/local/bin/llmkube-metal-agent. Equivalent to theMakefile's
sudo cpbut driven through the channel thatactually has the password.
ansible.builtin.file— ensure~/Library/LaunchAgentsexists (no become; user-space).
ansible.builtin.copy— install the launchd plist (nobecome; user-space).
ansible.builtin.shell—launchctl bootout || true+launchctl bootstrap gui/<uid> <plist>to atomically reloadthe daemon. Modern
bootstrap/bootoutAPI instead of thelegacy
launchctl load. Triggers only on binary or plistchange.
The role's existing env vars
(
LLMKUBE_METAL_AGENT_{MODEL_STORE,MEMORY_FRACTION,LLAMA_SERVER_PORT})are preserved on the
buildcall for forward-compat with anyfuture Makefile templating; today they're unused but the cost
of keeping them is zero.
Related: fix the LLMKube Makefile too
This bootstrap fix unblocks
./bootstrap.sh, but the LLMKubeMakefile itself still has the problem for anyone running
make install-metal-agentmanually on a non-TTY context.Follow-up bug should be filed against
defilantech/LLMKubetoeither:
/opt/homebrew/bin(nosudo needed there), or
/ a wrapper script for headless installs
Filed as a separate issue against the LLMKube repo, linked from
the bootstrap PR.
Severity
High. Default
./bootstrap.shcannot complete a full installon a fresh Apple Silicon Mac. Same severity class as #5 / #8.
Surfaced on the Mac Studio bootstrap run on 2026-05-23,
immediately after PR #9 (colima switch) cleared the previous
docker-desktop failure.