fix(llmkube_core): drive metal-agent install via ansible become instead of Makefile sudo#11
Merged
Merged
Conversation
…ad of Makefile sudo The role's previous `make install-metal-agent` call failed under ansible because the Makefile target runs `sudo cp bin/llmkube-metal -agent /usr/local/bin/...` internally. brew/make's sudo bypasses ansible's BECOME plumbing -- there is no TTY for the password prompt, so the cp fails with 'a terminal is required to read the password' (#10). Replace the single make-target task with explicit ansible tasks: 1. `make build-metal-agent` -- builds the binary, no sudo 2. ensure /usr/local/bin exists -- become: true (fresh Apple Silicon Macs lack it) 3. install binary to /usr/local/bin -- become: true, ansible.builtin.copy equivalent to the Makefile's `sudo cp` but going through ansible BECOME (--ask-become-pass) 4. ensure ~/Library/LaunchAgents -- no become; user-space 5. install launchd plist -- no become; user-space 6. reload launchd unit -- launchctl bootout + bootstrap, gated on binary or plist change. Uses modern bootstrap API instead of legacy 'launchctl load'. The existing env vars on the build call (model_store, memory_fraction, llama_server_port) are preserved for forward-compat with any future Makefile templating; they are no-ops today. ansible-playbook --syntax-check: clean. The LLMKube Makefile itself still has the sudo-cp issue for anyone running 'make install-metal-agent' manually in a non-TTY context; a separate bug against the LLMKube repo should ask for either an Apple Silicon /opt/homebrew/bin install path or clear TTY-requirement docs. Out of scope for this PR. Fixes #10
…ml[line-length] ansible-lint flagged line 121 as 1 char over the 120-char limit (launchctl bootstrap invocation with the inlined plist path). Hoist the path into a task-scoped 'vars:' block; both lines fit cleanly.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
What
Replace
make install-metal-agentin the llmkube_core role withexplicit ansible tasks that use
become: truefor the privilegedcopy + the modern
launchctl bootstrap/bootoutAPI for thelaunchd reload.
Why
Fixes #10.
The Mac Studio bootstrap run on 2026-05-23 failed at the
metal-agent install step. Root cause is the same TTY-less sudo
class we keep hitting: the LLMKube Makefile's
install-metal-agenttarget runs
sudo cp bin/llmkube-metal-agent /usr/local/bin/...internally, brew/make's sudo bypasses ansible's BECOME plumbing,
no TTY for the password prompt.
We cannot remove the sudo from the upstream Makefile in this PR
(separate concern; a follow-up bug should be filed against
defilantech/LLMKubeto switch to/opt/homebrew/binon AppleSilicon). What we CAN do is have llmkube-bootstrap drive the
install through ansible's own BECOME channel, which already has
the password from
--ask-become-pass.How
In
roles/llmkube_core/tasks/main.yml, the previous single task:becomes six explicit tasks:
make build-metal-agentcreates:file: /usr/local/bincopy: bin/llmkube-metal-agent → /usr/local/bin/...file: ~/Library/LaunchAgentscopy: plistThe launchctl call moved from the legacy
launchctl load(whichthe Makefile uses) to the modern
bootstrap/bootoutAPI. ModernmacOS treats
load/unloadas deprecated andbootstrapis thedocumented user-LaunchAgent install path. Idempotent because
bootoutswallows "service not loaded" errors via|| true.The env vars on the build call
(
LLMKUBE_METAL_AGENT_{MODEL_STORE,MEMORY_FRACTION,LLAMA_SERVER_PORT})are preserved for forward-compat. Today they are no-ops because
the Makefile does not template the plist, but if/when it does the
bootstrap continues to provide the values.
Verification
Local:
ansible-playbook --syntax-check: cleanCI:
yamllint,ansible-lint,shellcheck,macos-check,macos-homebrewall run on every PRmacos-homebrewdoes NOT exercise llmkube_core (it runs--tags 'always,system,homebrew'), so the actual fix lands onthe next real Mac Studio re-run. Worth noting as a CI coverage
gap for [FEATURE] CI: smoke-test ./bootstrap.sh end-to-end (closes the gap that let #2 ship) #4 to address (smoke-test bootstrap.sh end-to-end).
Live (post-merge):
git pullon the Studio + re-run./bootstrap.sh. Expected:binary builds, copies into
/usr/local/binunder become, plistinstalls, launchctl bootstraps the daemon, role completes.
Manual unblock for the Studio (while CI runs)
Related
Checklist
ansible-playbook --syntax-checkpasses