-
Notifications
You must be signed in to change notification settings - Fork 603
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Support for Virtualization.Framework for macOS 13 #1147
Conversation
examples/docker.yaml
Outdated
@@ -7,6 +7,7 @@ | |||
# $ docker ... | |||
|
|||
# This example requires Lima v0.8.0 or later | |||
driver: "vz" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The default must remain qemu
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You can create examples/vz.yaml
for the VZ example. (Maybe under experimental
dir?)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes yes that make sense. Will put it under experimental directory.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done.
pkg/store/filenames/filenames.go
Outdated
@@ -42,6 +42,8 @@ const ( | |||
HostAgentSock = "ha.sock" | |||
HostAgentStdoutLog = "ha.stdout.log" | |||
HostAgentStderrLog = "ha.stderr.log" | |||
Identifier = "identifier" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Please describe in https://github.com/lima-vm/lima/blob/master/docs/internal.md
Also, perhaps the filename should be something like vz-identifier
?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done
pkg/store/filenames/filenames.go
Outdated
@@ -42,6 +42,8 @@ const ( | |||
HostAgentSock = "ha.sock" | |||
HostAgentStdoutLog = "ha.stdout.log" | |||
HostAgentStderrLog = "ha.stderr.log" | |||
Identifier = "identifier" | |||
EFI = "efi" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done
pkg/vz/vm_darwin.go
Outdated
|
||
err = machine.Start() | ||
|
||
networks.StartGVisor(ctx, &networks.GVisorOpts{ |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
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.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Maybe StartGVisorNetstack
? StartNetstack
? StartGvisorNet
?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done
pkg/limayaml/limayaml.go
Outdated
@@ -7,6 +7,7 @@ import ( | |||
) | |||
|
|||
type LimaYAML struct { | |||
Driver *Driver `yaml:"driver,omitempty" json:"driver,omitempty"` |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Should this be called like VMType
for consistency with MountType
?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
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.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
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.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
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.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
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.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
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.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Perhaps just runtime.GOOS != "windows"
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done
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.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can we use switch{}
for newState
comparisons?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done
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.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Did you mean gvisor network?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes, updated the comments
pkg/vz/vm_darwin.go
Outdated
return vz.NewEFIVariableStore(efi) | ||
} | ||
|
||
func createFileAndWriteTo(data []byte, path string) error { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
os.WriteFile
may suffice
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done
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.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
vz.yaml
should not have Docker.
You may create docker-vz.yaml
separately though
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
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.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
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.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@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.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What do you mean by "NAT"?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Anyway probably it should be a separate PR
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
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.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
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.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
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.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
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.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The network.Socket
value does not seem consumed
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
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.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
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.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Every switch{}
should have default:
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
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.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
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.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Sure. Will take care of this in follow-up PR
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
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.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
nits: I think Stat is better because if the file exists, it will not be closed until it is GC'd.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done
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.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
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.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@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.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@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.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Sure will add that as well
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done
return nil | ||
} | ||
|
||
func attachOtherDevices(_ *driver.BaseDriver, vmConfig *vz.VirtualMachineConfiguration) error { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
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
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can be another PR
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.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is this outrightly not supported by the driver, and with no workarounds?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
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.