Support for Virtualization.Framework for macOS 13#1147
Support for Virtualization.Framework for macOS 13#1147AkihiroSuda merged 1 commit intolima-vm:masterfrom
Conversation
examples/docker.yaml
Outdated
| # $ docker ... | ||
|
|
||
| # This example requires Lima v0.8.0 or later | ||
| driver: "vz" |
There was a problem hiding this comment.
The default must remain qemu
There was a problem hiding this comment.
You can create examples/vz.yaml for the VZ example. (Maybe under experimental dir?)
There was a problem hiding this comment.
Yes yes that make sense. Will put it under experimental directory.
pkg/store/filenames/filenames.go
Outdated
| HostAgentSock = "ha.sock" | ||
| HostAgentStdoutLog = "ha.stdout.log" | ||
| HostAgentStderrLog = "ha.stderr.log" | ||
| Identifier = "identifier" |
There was a problem hiding this comment.
Please describe in https://github.com/lima-vm/lima/blob/master/docs/internal.md
Also, perhaps the filename should be something like vz-identifier?
pkg/store/filenames/filenames.go
Outdated
| HostAgentStdoutLog = "ha.stdout.log" | ||
| HostAgentStderrLog = "ha.stderr.log" | ||
| Identifier = "identifier" | ||
| EFI = "efi" |
pkg/vz/vm_darwin.go
Outdated
|
|
||
| err = machine.Start() | ||
|
|
||
| networks.StartGVisor(ctx, &networks.GVisorOpts{ |
There was a problem hiding this comment.
This looks a misnomer.
This starts the network stack that originates from gvisor, but does not start gvisor (sandboxed kernel) actually
There was a problem hiding this comment.
Maybe StartGVisorNetstack? StartNetstack? StartGvisorNet?
pkg/limayaml/limayaml.go
Outdated
| ) | ||
|
|
||
| type LimaYAML struct { | ||
| Driver *Driver `yaml:"driver,omitempty" json:"driver,omitempty"` |
There was a problem hiding this comment.
Should this be called like VMType for consistency with MountType?
There was a problem hiding this comment.
Also please create a document like docs/vmtype.md or docs/vz.md to explain the usage, requirements, and limitations of vz
There was a problem hiding this comment.
Isn't VMType kind of gives a wrong meaning (Type of VM like linux etc).
How about DriverType ?
There was a problem hiding this comment.
Type of VM like linux etc
We only support Linux.
Eventually we may support FreeBSD (if somebody contributes), but that will be probably called "type of guest", not "type of VM"
There was a problem hiding this comment.
Done the VMType change only for yaml config related places.
Do let me know if you want to change the word driver everywhere (like driver interface, implementations etc).
Will add doc related things as next step.
There was a problem hiding this comment.
Thanks, "driver" in the interface and impl is ok
pkg/networks/gvisor.go
Outdated
| } | ||
|
|
||
| func searchDomains() []string { | ||
| if runtime.GOOS == "darwin" || runtime.GOOS == "linux" { |
There was a problem hiding this comment.
Perhaps just runtime.GOOS != "windows"
pkg/vz/vm_darwin.go
Outdated
| logrus.Errorf("Error while stopping the VM %q", err) | ||
| } | ||
| case newState := <-machine.StateChangedNotify(): | ||
| if newState == vz.VirtualMachineStateRunning { |
There was a problem hiding this comment.
Can we use switch{} for newState comparisons?
pkg/vz/vm_darwin.go
Outdated
| } | ||
|
|
||
| func attachNetwork(driver *driver.BaseDriver, vmConfig *vz.VirtualMachineConfiguration, networkConn *os.File) error { | ||
| //Slirp network |
There was a problem hiding this comment.
Did you mean gvisor network?
There was a problem hiding this comment.
Yes, updated the comments
pkg/vz/vm_darwin.go
Outdated
| return vz.NewEFIVariableStore(efi) | ||
| } | ||
|
|
||
| func createFileAndWriteTo(data []byte, path string) error { |
examples/experimental/vz.yaml
Outdated
| set -eux -o pipefail | ||
| command -v docker >/dev/null 2>&1 && exit 0 | ||
| export DEBIAN_FRONTEND=noninteractive | ||
| curl -fsSL https://get.docker.com | sh |
There was a problem hiding this comment.
vz.yaml should not have Docker.
You may create docker-vz.yaml separately though
There was a problem hiding this comment.
But anyway no need to keep docker-vz.yaml separately when we have limactl start --set K=V or maybe limactl start --vm-type vz
There was a problem hiding this comment.
Sure. Then i will keep a default example alone in vz.yaml
pkg/vz/vm_darwin.go
Outdated
| //Other networks | ||
| for _, network := range driver.Yaml.Networks { | ||
| //TODO - Handle NAT network type | ||
| if network.Socket != "" { |
There was a problem hiding this comment.
@AkihiroSuda
For NAT network type, shall i go ahead with network.NAT: true/false or network.socket: NAT ?
There was a problem hiding this comment.
Anyway probably it should be a separate PR
There was a problem hiding this comment.
For host to guest network, the below code uses https://developer.apple.com/documentation/virtualization/vznatnetworkdeviceattachment provided from virtualization.framework itself.
This doesn't require sudo access.
There was a problem hiding this comment.
Would it be possible to just use vznat by default and drop gvisor netstack ?
If vznat has to be optional, probably it should be like (EDIT: see #1161 (comment)) (separate PR would be preferrable)network.VZNAT: true/false
There was a problem hiding this comment.
Yes that should work but with vzNAT there will be other issues like VPN won't be working.
Also i faced issues with calls to host dns resolver via UDP didn't work
There was a problem hiding this comment.
Thanks, let's keep using gvisor netstack by default, and revisit VZNAT in a separate PR
pkg/vz/vm_darwin.go
Outdated
| //Other networks | ||
| for _, network := range driver.Yaml.Networks { | ||
| //TODO - Handle NAT network type | ||
| if network.Socket != "" { |
There was a problem hiding this comment.
The network.Socket value does not seem consumed
There was a problem hiding this comment.
I expected it could be supported via VZFileHandleNetworkDeviceAttachment , but seems incompatible with QEMU:
https://developer.apple.com/documentation/virtualization/vzfilehandlenetworkdeviceattachment?language=objc
So we have to error out when network.Socket is non-empty
There was a problem hiding this comment.
I think we can support it, maybe some extra support might be needed from socker_vmnet as well. I will try to support this in a different PR.
| case vz.VirtualMachineStateStopped: | ||
| logrus.Println("[VZ] - VM state change: stopped") | ||
| cancelHa() | ||
| } |
There was a problem hiding this comment.
Every switch{} should have default:
There was a problem hiding this comment.
Done. By default doing a debug log.
| if *l.Yaml.MountType == limayaml.NINEP { | ||
| return fmt.Errorf("field `mountType` must be %q or %q for VZ driver , got %q", limayaml.REVSSHFS, limayaml.VIRTIOFS, *l.Yaml.MountType) | ||
| } | ||
| return nil |
There was a problem hiding this comment.
Warnings should be printed for ignored YAML propertries: https://github.com/containerd/nerdctl/blob/c1a4159035b77a4a739a503b98139a17ac3440b8/pkg/composer/serviceparser/serviceparser.go#L38
Can be another PR though
There was a problem hiding this comment.
Sure. Will take care of this in follow-up PR
There was a problem hiding this comment.
Added errors for not supported one like legacyBios. As vm will not even start with this as true.
For other things will take it up in a follow-up PR like networks, mount as 9p etc.
pkg/vz/vm_darwin.go
Outdated
|
|
||
| func getEFI(driver *driver.BaseDriver) (*vz.EFIVariableStore, error) { | ||
| efi := filepath.Join(driver.Instance.Dir, filenames.VzEfi) | ||
| if _, err := os.Open(efi); os.IsNotExist(err) { |
There was a problem hiding this comment.
nits: I think Stat is better because if the file exists, it will not be closed until it is GC'd.
pkg/vz/vz_driver_darwin.go
Outdated
| vm, err := startVM(ctx, l.BaseDriver) | ||
| if err != nil { | ||
| return err | ||
| } |
There was a problem hiding this comment.
I think error handling would be required to check version compatibility. Given that lima-vm will be built with the latest OS, handling of vz.ErrBuildTargetOSVersion is unnecessary. (maybe)
https://github.com/Code-Hex/vz#version-compatibility-check
There was a problem hiding this comment.
@Code-Hex
Lima will only support macOS 13 based EFILoader. Not the old ones. With that, i believe we don't need to do any check right ?
If either the driver is disabled / os version is incompatible, vz already throws a appropriate error. Am i missing something ?
There was a problem hiding this comment.
@balajiv113 Right. However, will be returned error might be not helpful for user side. So I meant to return an error with message which is helpful that this driver cannot use below macOS 13. (Or better logging?)
There was a problem hiding this comment.
Sure will add that as well
| return nil | ||
| } | ||
|
|
||
| func attachOtherDevices(_ *driver.BaseDriver, vmConfig *vz.VirtualMachineConfiguration) error { |
There was a problem hiding this comment.
does it make sense to register there also NewLinuxRosettaDirectoryShare
So we have Rosetta inside VZ? https://github.com/Code-Hex/vz/blob/c436fc367107393c6eda419ff0f69903f674c118/shared_directory_arm64.go#L63
|
Done testing with all the templates,
|
|
No need to support legacy BIOS (in this PR, at least). Also please consider squashing commits |
|
@balajiv113 I believe it's correct behavior that It's started up and it does not appear kernel early messages on the serial attachment because the console is provided via
https://github.com/evansm7/vftool#kernelsnotes However, as noted on the wiki, some messages are displayed.
https://github.com/Code-Hex/vz/wiki#linux-kernel-requirements |
575880e to
1300c9c
Compare
|
@chancez Thanks, could you open your rosetta PR after merging this base PR?
We already have VM-specific configs in the top-level struct, so I guess we are too late to make that change 😞 Lines 212 to 219 in 06a4b33 Lines 226 to 233 in 06a4b33 |
Yeah I'll make a PR with some adjustments to make it closer to "ready" and we can discuss the rest a bit further in that PR. |
|
Sorry, needs another rebase |
|
Done the rebase. |
added support for drivers to lima, migrated exiting qemu to drivers modal and support for apple virtualization.framework as new driver Signed-off-by: Balaji Vijayakumar <kuttibalaji.v6@gmail.com>
|
|
||
| ### Known Issues | ||
| - "vz" doesn't support `legacyBoot: true` option, so guest machine like centos-stream, archlinux, oraclelinux will not work | ||
| - Host to guest networking (`networks` section in lima yaml) is not supported |
There was a problem hiding this comment.
Is this outrightly not supported by the driver, and with no workarounds?
There was a problem hiding this comment.
Expected to be added as "vznat" network in a separate PR
#1147 (comment)
|
I've been testing this PR today on an M1 machine running Ventura, and I saw this error when starting Which seems to originate from https://github.com/containers/gvisor-tap-vsock/blob/main/pkg/services/forwarder/tcp.go#L45. Is this expected? There was no additional information in |
I'm fine with the I've not had time to review the code in detail, but so far it all looks good, and most importantly: works. I've only tested on M1 so far, but should be able to get remote access to an Intel Ventura machine for testing as well. |
This PR provides support for using Virtualization.Framework as a optional driver.
The following are the changes done related to using drivers,
The following are the features of lima, the vz driver should provide support for below,
Notes
Know Issues
[e.connection](tcpproxy:)during start-up (This is because of port 22 Forwards being tried before VM is ready) [Not a failure/blocker just info message thrown, but we can look into fixing in a follow-up to call ssh forward manually]Testing
Tested the following templates with
driver: vz. All test are done on macOS 13 intel as of now.