diff --git a/src/cmd/linuxkit/go.mod b/src/cmd/linuxkit/go.mod index 5bc146727..4200fb19a 100644 --- a/src/cmd/linuxkit/go.mod +++ b/src/cmd/linuxkit/go.mod @@ -8,7 +8,6 @@ require ( github.com/Azure/go-autorest/autorest v0.11.24 github.com/Azure/go-autorest/autorest/adal v0.9.18 github.com/Azure/go-autorest/autorest/to v0.4.0 - github.com/Code-Hex/vz v0.0.4 github.com/Microsoft/go-winio v0.5.2 github.com/ScaleFT/sshkeys v0.0.0-20181112160850-82451a803681 github.com/aws/aws-sdk-go v1.44.82 @@ -43,7 +42,7 @@ require ( github.com/surma/gocpio v1.0.2-0.20160926205914-fcb68777e7dc github.com/vmware/govmomi v0.20.3 github.com/xeipuuv/gojsonschema v1.2.0 - golang.org/x/crypto v0.0.0-20220525230936-793ad666bf5e + golang.org/x/crypto v0.1.0 golang.org/x/net v0.1.0 golang.org/x/oauth2 v0.1.0 golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4 @@ -60,6 +59,7 @@ require ( github.com/Azure/go-autorest/autorest/validation v0.3.1 // indirect github.com/Azure/go-autorest/logger v0.2.1 // indirect github.com/Azure/go-autorest/tracing v0.6.0 // indirect + github.com/Code-Hex/vz/v3 v3.0.0 // indirect github.com/agext/levenshtein v1.2.3 // indirect github.com/beorn7/perks v1.0.1 // indirect github.com/cespare/xxhash/v2 v2.1.2 // indirect @@ -130,6 +130,7 @@ require ( go.opentelemetry.io/otel/sdk v1.4.1 // indirect go.opentelemetry.io/otel/trace v1.4.1 // indirect go.opentelemetry.io/proto/otlp v0.12.0 // indirect + golang.org/x/mod v0.6.0 // indirect golang.org/x/text v0.4.0 // indirect golang.org/x/time v0.0.0-20220210224613-90d013bbcef8 // indirect google.golang.org/appengine v1.6.7 // indirect diff --git a/src/cmd/linuxkit/go.sum b/src/cmd/linuxkit/go.sum index e422c7c80..ff60d37cd 100644 --- a/src/cmd/linuxkit/go.sum +++ b/src/cmd/linuxkit/go.sum @@ -149,6 +149,8 @@ github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03 github.com/BurntSushi/xgb v0.0.0-20160522181843-27f122750802/go.mod h1:IVnqGOEym/WlBOVXweHU+Q+/VP0lqqI8lqeDx9IjBqo= github.com/Code-Hex/vz v0.0.4 h1:1rM8ijE+znlrOeYIer441cSwpYq2rk57Fd3dRpxUDUA= github.com/Code-Hex/vz v0.0.4/go.mod h1:UeHKXSv3hP7BzU6IaVE/a7VHSHUHpqbS3oVko4O5UYI= +github.com/Code-Hex/vz/v3 v3.0.0 h1:UuYAZz8NF8n+R4MLfn/lpUlepgzZ8BlhKtioQ+q9LXk= +github.com/Code-Hex/vz/v3 v3.0.0/go.mod h1:+xPQOXVzNaZ4OeIIhlJFumtbFhsvRfqKwX7wuZS4dFA= github.com/Djarvur/go-err113 v0.0.0-20200410182137-af658d038157/go.mod h1:4UJr5HIiMZrwgkSPdsjy2uOQExX/WEILpIrO9UPGuXs= github.com/Djarvur/go-err113 v0.1.0/go.mod h1:4UJr5HIiMZrwgkSPdsjy2uOQExX/WEILpIrO9UPGuXs= github.com/GoogleCloudPlatform/cloudsql-proxy v0.0.0-20191009163259-e802c2cb94ae/go.mod h1:mjwGPas4yKduTyubHvD1Atl9r1rUq8DfVy+gkVvZ+oo= @@ -1590,6 +1592,8 @@ golang.org/x/crypto v0.0.0-20211202192323-5770296d904e/go.mod h1:IxCIyHEi3zRg3s0 golang.org/x/crypto v0.0.0-20211215153901-e495a2d5b3d3/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4= golang.org/x/crypto v0.0.0-20220525230936-793ad666bf5e h1:T8NU3HyQ8ClP4SEE+KbFlg6n0NhuTsN4MyznaarGsZM= golang.org/x/crypto v0.0.0-20220525230936-793ad666bf5e/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4= +golang.org/x/crypto v0.1.0 h1:MDRAIl0xIo9Io2xV565hzXHw3zVseKrJKodhohM5CjU= +golang.org/x/crypto v0.1.0/go.mod h1:RecgLatLF4+eUMCP1PoPZQb+cVrJcOPbHkTkbkB9sbw= golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/exp v0.0.0-20190125153040-c74c464bbbf2/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/exp v0.0.0-20190306152737-a1d7652674e8/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= @@ -1629,6 +1633,8 @@ golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.4.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.4.1/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.4.2/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= +golang.org/x/mod v0.6.0 h1:b9gGHsz9/HhJ3HF5DHQytPpuwocVTChQJK3AvoLRD5I= +golang.org/x/mod v0.6.0/go.mod h1:4mET923SAdbXp2ki8ey+zGs1SLqsuM2Y0uvdZR/fUNI= golang.org/x/net v0.0.0-20170114055629-f2499483f923/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20180811021610-c39426892332/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= diff --git a/src/cmd/linuxkit/run_virtualizationframework_darwin_cgo_enabled.go b/src/cmd/linuxkit/run_virtualizationframework_darwin_cgo_enabled.go index 559c3f9b5..0949e3e57 100644 --- a/src/cmd/linuxkit/run_virtualizationframework_darwin_cgo_enabled.go +++ b/src/cmd/linuxkit/run_virtualizationframework_darwin_cgo_enabled.go @@ -16,7 +16,7 @@ import ( "strings" "syscall" - "github.com/Code-Hex/vz" + vz "github.com/Code-Hex/vz/v3" "github.com/pkg/term/termios" log "github.com/sirupsen/logrus" "golang.org/x/sys/unix" @@ -147,22 +147,34 @@ func runVirtualizationFramework(args []string) { } vmlinuzFile = vmlinuzUncompressed } - bootLoader := vz.NewLinuxBootLoader( + bootLoader, err := vz.NewLinuxBootLoader( vmlinuzFile, vz.WithCommandLine(strings.Join(kernelCommandLineArguments, " ")), vz.WithInitrd(initrd), ) + if err != nil { + log.Fatalf("unable to create bootloader: %v", err) + } - config := vz.NewVirtualMachineConfiguration( + config, err := vz.NewVirtualMachineConfiguration( bootLoader, *cpus, memBytes, ) + if err != nil { + log.Fatalf("unable to create VM config: %v", err) + } // console stdin, stdout := os.Stdin, os.Stdout - serialPortAttachment := vz.NewFileHandleSerialPortAttachment(stdin, stdout) - consoleConfig := vz.NewVirtioConsoleDeviceSerialPortConfiguration(serialPortAttachment) + serialPortAttachment, err := vz.NewFileHandleSerialPortAttachment(stdin, stdout) + if err != nil { + log.Fatalf("unable to create serial port attachment: %v", err) + } + consoleConfig, err := vz.NewVirtioConsoleDeviceSerialPortConfiguration(serialPortAttachment) + if err != nil { + log.Fatalf("unable to create console config: %v", err) + } config.SetSerialPortsVirtualMachineConfiguration([]*vz.VirtioConsoleDeviceSerialPortConfiguration{ consoleConfig, }) @@ -179,19 +191,33 @@ func runVirtualizationFramework(args []string) { switch netMode[0] { case virtualizationNetworkingVMNet: - natAttachment := vz.NewNATNetworkDeviceAttachment() - networkConfig := vz.NewVirtioNetworkDeviceConfiguration(natAttachment) + natAttachment, err := vz.NewNATNetworkDeviceAttachment() + if err != nil { + log.Fatalf("Could not create NAT network device attachment: %v", err) + } + networkConfig, err := vz.NewVirtioNetworkDeviceConfiguration(natAttachment) + if err != nil { + log.Fatalf("Could not create virtio network device configuration: %v", err) + } config.SetNetworkDevicesVirtualMachineConfiguration([]*vz.VirtioNetworkDeviceConfiguration{ networkConfig, }) - networkConfig.SetMacAddress(vz.NewRandomLocallyAdministeredMACAddress()) + macAddress, err := vz.NewRandomLocallyAdministeredMACAddress() + if err != nil { + log.Fatalf("Could not create random MAC address: %v", err) + } + networkConfig.SetMACAddress(macAddress) case virtualizationNetworkingNone: default: log.Fatalf("Invalid networking mode: %s", netMode[0]) } // entropy - entropyConfig := vz.NewVirtioEntropyDeviceConfiguration() + entropyConfig, err := vz.NewVirtioEntropyDeviceConfiguration() + if err != nil { + log.Fatalf("Could not create virtio entropy device configuration: %v", err) + } + config.SetEntropyDevicesVirtualMachineConfiguration([]*vz.VirtioEntropyDeviceConfiguration{ entropyConfig, }) @@ -215,7 +241,10 @@ func runVirtualizationFramework(args []string) { if err != nil { log.Fatal(err) } - storageDeviceConfig := vz.NewVirtioBlockDeviceConfiguration(diskImageAttachment) + storageDeviceConfig, err := vz.NewVirtioBlockDeviceConfiguration(diskImageAttachment) + if err != nil { + log.Fatalf("Could not create virtio block device configuration: %v", err) + } storageDevices = append(storageDevices, storageDeviceConfig) } for _, iso := range isoPaths { @@ -226,38 +255,50 @@ func runVirtualizationFramework(args []string) { if err != nil { log.Fatal(err) } - storageDeviceConfig := vz.NewVirtioBlockDeviceConfiguration(diskImageAttachment) + storageDeviceConfig, err := vz.NewVirtioBlockDeviceConfiguration(diskImageAttachment) + if err != nil { + log.Fatalf("Could not create virtio block device configuration: %v", err) + } storageDevices = append(storageDevices, storageDeviceConfig) } config.SetStorageDevicesVirtualMachineConfiguration(storageDevices) // traditional memory balloon device which allows for managing guest memory. (optional) + memoryBalloonDeviceConfiguration, err := vz.NewVirtioTraditionalMemoryBalloonDeviceConfiguration() + if err != nil { + log.Fatalf("Could not create virtio traditional memory balloon device configuration: %v", err) + } config.SetMemoryBalloonDevicesVirtualMachineConfiguration([]vz.MemoryBalloonDeviceConfiguration{ - vz.NewVirtioTraditionalMemoryBalloonDeviceConfiguration(), + memoryBalloonDeviceConfiguration, }) // socket device (optional) + socketDeviceConfiguration, err := vz.NewVirtioSocketDeviceConfiguration() + if err != nil { + log.Fatalf("Could not create virtio socket device configuration: %v", err) + } config.SetSocketDevicesVirtualMachineConfiguration([]vz.SocketDeviceConfiguration{ - vz.NewVirtioSocketDeviceConfiguration(), + socketDeviceConfiguration, }) validated, err := config.Validate() if !validated || err != nil { log.Fatal("validation failed", err) } - vm := vz.NewVirtualMachine(config) + vm, err := vz.NewVirtualMachine(config) + if err != nil { + log.Fatalf("Could not create virtual machine: %v", err) + } signalCh := make(chan os.Signal, 1) signal.Notify(signalCh, syscall.SIGTERM) errCh := make(chan error, 1) - vm.Start(func(err error) { - if err != nil { - errCh <- err - } - }) + if err := vm.Start(); err != nil { + errCh <- err + } for { select { diff --git a/src/cmd/linuxkit/vendor/github.com/Code-Hex/vz/.gitignore b/src/cmd/linuxkit/vendor/github.com/Code-Hex/vz/.gitignore deleted file mode 100644 index 0631cc8a1..000000000 --- a/src/cmd/linuxkit/vendor/github.com/Code-Hex/vz/.gitignore +++ /dev/null @@ -1,2 +0,0 @@ -virtualization -*.log \ No newline at end of file diff --git a/src/cmd/linuxkit/vendor/github.com/Code-Hex/vz/README.md b/src/cmd/linuxkit/vendor/github.com/Code-Hex/vz/README.md deleted file mode 100644 index 648631869..000000000 --- a/src/cmd/linuxkit/vendor/github.com/Code-Hex/vz/README.md +++ /dev/null @@ -1,52 +0,0 @@ -vz - Go binding with Apple [Virtualization.framework](https://developer.apple.com/documentation/virtualization?language=objc) -======= - -vz provides the power of the Apple Virtualization.framework in Go. Put here is block quote of overreview which is written what is Virtualization.framework from the document. - -> The Virtualization framework provides high-level APIs for creating and managing virtual machines on Apple silicon and Intel-based Mac computers. Use this framework to boot and run a Linux-based operating system in a custom environment that you define. The framework supports the Virtio specification, which defines standard interfaces for many device types, including network, socket, serial port, storage, entropy, and memory-balloon devices. - -## USAGE - -Please see the example directory. - -## REQUIREMENTS - -- Higher or equal to macOS Big Sur (11.0.0) -- If you're M1 Mac User need higher or equal to Go 1.16 - -## IMPORTANT - -For binaries used in this package, you need to create an entitlements file like the one below and apply the following command. - -
-vz.entitlements - -``` - - - - - com.apple.security.virtualization - - - -``` - -
- -```sh -$ codesign --entitlements vz.entitlements -s - -``` - -> A process must have the com.apple.security.virtualization entitlement to use the Virtualization APIs. - -If you want to use [`VZBridgedNetworkDeviceAttachment`](https://developer.apple.com/documentation/virtualization/vzbridgednetworkdeviceattachment?language=objc), you need to add also `com.apple.vm.networking` entitlement. - -## TODO - -- [x] [VZMACAddress](https://developer.apple.com/documentation/virtualization/vzmacaddress?language=objc) -- [ ] [VZVirtioSocketDeviceConfiguration](https://developer.apple.com/documentation/virtualization/sockets?language=objc) - -## LICENSE - -MIT License \ No newline at end of file diff --git a/src/cmd/linuxkit/vendor/github.com/Code-Hex/vz/bootloader.go b/src/cmd/linuxkit/vendor/github.com/Code-Hex/vz/bootloader.go deleted file mode 100644 index 96f7b89be..000000000 --- a/src/cmd/linuxkit/vendor/github.com/Code-Hex/vz/bootloader.go +++ /dev/null @@ -1,89 +0,0 @@ -package vz - -/* -#cgo darwin CFLAGS: -x objective-c -fno-objc-arc -#cgo darwin LDFLAGS: -lobjc -framework Foundation -framework Virtualization -# include "virtualization.h" -*/ -import "C" -import ( - "fmt" - "runtime" -) - -// BootLoader is the interface of boot loader definitions. -// see: LinuxBootLoader -type BootLoader interface { - NSObject - - bootLoader() -} - -type baseBootLoader struct{} - -func (*baseBootLoader) bootLoader() {} - -var _ BootLoader = (*LinuxBootLoader)(nil) - -// LinuxBootLoader Boot loader configuration for a Linux kernel. -type LinuxBootLoader struct { - vmlinuzPath string - initrdPath string - cmdLine string - pointer - - *baseBootLoader -} - -func (b *LinuxBootLoader) String() string { - return fmt.Sprintf( - "vmlinuz: %q, initrd: %q, command-line: %q", - b.vmlinuzPath, - b.initrdPath, - b.cmdLine, - ) -} - -type LinuxBootLoaderOption func(b *LinuxBootLoader) - -// WithCommandLine sets the command-line parameters. -// see: https://www.kernel.org/doc/html/latest/admin-guide/kernel-parameters.html -func WithCommandLine(cmdLine string) LinuxBootLoaderOption { - return func(b *LinuxBootLoader) { - b.cmdLine = cmdLine - cs := charWithGoString(cmdLine) - defer cs.Free() - C.setCommandLineVZLinuxBootLoader(b.Ptr(), cs.CString()) - } -} - -// WithInitrd sets the optional initial RAM disk. -func WithInitrd(initrdPath string) LinuxBootLoaderOption { - return func(b *LinuxBootLoader) { - b.initrdPath = initrdPath - cs := charWithGoString(initrdPath) - defer cs.Free() - C.setInitialRamdiskURLVZLinuxBootLoader(b.Ptr(), cs.CString()) - } -} - -// NewLinuxBootLoader creates a LinuxBootLoader with the Linux kernel passed as Path. -func NewLinuxBootLoader(vmlinuz string, opts ...LinuxBootLoaderOption) *LinuxBootLoader { - vmlinuzPath := charWithGoString(vmlinuz) - defer vmlinuzPath.Free() - bootLoader := &LinuxBootLoader{ - vmlinuzPath: vmlinuz, - pointer: pointer{ - ptr: C.newVZLinuxBootLoader( - vmlinuzPath.CString(), - ), - }, - } - runtime.SetFinalizer(bootLoader, func(self *LinuxBootLoader) { - self.Release() - }) - for _, opt := range opts { - opt(bootLoader) - } - return bootLoader -} diff --git a/src/cmd/linuxkit/vendor/github.com/Code-Hex/vz/configuration.go b/src/cmd/linuxkit/vendor/github.com/Code-Hex/vz/configuration.go deleted file mode 100644 index 14a36beba..000000000 --- a/src/cmd/linuxkit/vendor/github.com/Code-Hex/vz/configuration.go +++ /dev/null @@ -1,137 +0,0 @@ -package vz - -/* -#cgo darwin CFLAGS: -x objective-c -fno-objc-arc -#cgo darwin LDFLAGS: -lobjc -framework Foundation -framework Virtualization -# include "virtualization.h" -*/ -import "C" -import "runtime" - -// VirtualMachineConfiguration defines the configuration of a VirtualMachine. -// -// The following properties must be configured before creating a virtual machine: -// - bootLoader -// -// The configuration of devices is often done in two parts: -// - Device configuration -// - Device attachment -// -// The device configuration defines the characteristics of the emulated hardware device. -// For example, for a network device, the device configuration defines the type of network adapter present -// in the virtual machine and its MAC address. -// -// The device attachment defines the host machine's resources that are exposed by the virtual device. -// For example, for a network device, the device attachment can be virtual network interface with a NAT -// to the real network. -// -// Creating a virtual machine using the Virtualization framework requires the app to have the "com.apple.security.virtualization" entitlement. -// A VirtualMachineConfiguration is considered invalid if the application does not have the entitlement. -// -// see: https://developer.apple.com/documentation/virtualization/vzvirtualmachineconfiguration?language=objc -type VirtualMachineConfiguration struct { - cpuCount uint - memorySize uint64 - pointer -} - -// NewVirtualMachineConfiguration creates a new configuration. -// -// - bootLoader parameter is used when the virtual machine starts. -// - cpu parameter is The number of CPUs must be a value between -// VZVirtualMachineConfiguration.minimumAllowedCPUCount and VZVirtualMachineConfiguration.maximumAllowedCPUCount. -// - memorySize parameter represents memory size in bytes. -// The memory size must be a multiple of a 1 megabyte (1024 * 1024 bytes) between -// VZVirtualMachineConfiguration.minimumAllowedMemorySize and VZVirtualMachineConfiguration.maximumAllowedMemorySize. -func NewVirtualMachineConfiguration(bootLoader BootLoader, cpu uint, memorySize uint64) *VirtualMachineConfiguration { - config := &VirtualMachineConfiguration{ - cpuCount: cpu, - memorySize: memorySize, - pointer: pointer{ - ptr: C.newVZVirtualMachineConfiguration( - bootLoader.Ptr(), - C.uint(cpu), - C.ulonglong(memorySize), - ), - }, - } - runtime.SetFinalizer(config, func(self *VirtualMachineConfiguration) { - self.Release() - }) - return config -} - -// Validate the configuration. -// -// Return true if the configuration is valid. -// If error is not nil, assigned with the validation error if the validation failed. -func (v *VirtualMachineConfiguration) Validate() (bool, error) { - nserr := newNSErrorAsNil() - nserrPtr := nserr.Ptr() - ret := C.validateVZVirtualMachineConfiguration(v.Ptr(), &nserrPtr) - err := newNSError(nserrPtr) - if err != nil { - return false, err - } - return (bool)(ret), nil -} - -// SetEntropyDevicesVirtualMachineConfiguration sets list of entropy devices. Empty by default. -func (v *VirtualMachineConfiguration) SetEntropyDevicesVirtualMachineConfiguration(cs []*VirtioEntropyDeviceConfiguration) { - ptrs := make([]NSObject, len(cs)) - for i, val := range cs { - ptrs[i] = val - } - array := convertToNSMutableArray(ptrs) - C.setEntropyDevicesVZVirtualMachineConfiguration(v.Ptr(), array.Ptr()) -} - -// SetMemoryBalloonDevicesVirtualMachineConfiguration sets list of memory balloon devices. Empty by default. -func (v *VirtualMachineConfiguration) SetMemoryBalloonDevicesVirtualMachineConfiguration(cs []MemoryBalloonDeviceConfiguration) { - ptrs := make([]NSObject, len(cs)) - for i, val := range cs { - ptrs[i] = val - } - array := convertToNSMutableArray(ptrs) - C.setMemoryBalloonDevicesVZVirtualMachineConfiguration(v.Ptr(), array.Ptr()) -} - -// SetNetworkDevicesVirtualMachineConfiguration sets list of network adapters. Empty by default. -func (v *VirtualMachineConfiguration) SetNetworkDevicesVirtualMachineConfiguration(cs []*VirtioNetworkDeviceConfiguration) { - ptrs := make([]NSObject, len(cs)) - for i, val := range cs { - ptrs[i] = val - } - array := convertToNSMutableArray(ptrs) - C.setNetworkDevicesVZVirtualMachineConfiguration(v.Ptr(), array.Ptr()) -} - -// SetSerialPortsVirtualMachineConfiguration sets list of serial ports. Empty by default. -func (v *VirtualMachineConfiguration) SetSerialPortsVirtualMachineConfiguration(cs []*VirtioConsoleDeviceSerialPortConfiguration) { - ptrs := make([]NSObject, len(cs)) - for i, val := range cs { - ptrs[i] = val - } - array := convertToNSMutableArray(ptrs) - C.setSerialPortsVZVirtualMachineConfiguration(v.Ptr(), array.Ptr()) -} - -// SetSocketDevicesVirtualMachineConfiguration sets list of socket devices. Empty by default. -func (v *VirtualMachineConfiguration) SetSocketDevicesVirtualMachineConfiguration(cs []SocketDeviceConfiguration) { - ptrs := make([]NSObject, len(cs)) - for i, val := range cs { - ptrs[i] = val - } - array := convertToNSMutableArray(ptrs) - C.setSocketDevicesVZVirtualMachineConfiguration(v.Ptr(), array.Ptr()) -} - -// SetStorageDevicesVirtualMachineConfiguration sets list of disk devices. Empty by default. -func (v *VirtualMachineConfiguration) SetStorageDevicesVirtualMachineConfiguration(cs []StorageDeviceConfiguration) { - ptrs := make([]NSObject, len(cs)) - for i, val := range cs { - ptrs[i] = val - } - array := convertToNSMutableArray(ptrs) - C.setStorageDevicesVZVirtualMachineConfiguration(v.Ptr(), array.Ptr()) -} diff --git a/src/cmd/linuxkit/vendor/github.com/Code-Hex/vz/objcutil.go b/src/cmd/linuxkit/vendor/github.com/Code-Hex/vz/objcutil.go deleted file mode 100644 index 8b4a9cea9..000000000 --- a/src/cmd/linuxkit/vendor/github.com/Code-Hex/vz/objcutil.go +++ /dev/null @@ -1,206 +0,0 @@ -package vz - -/* -#cgo darwin CFLAGS: -x objective-c -#cgo darwin LDFLAGS: -lobjc -framework Foundation -framework Virtualization -# include "virtualization.h" - -const char *getNSErrorLocalizedDescription(void *err) -{ - NSString *ld = (NSString *)[(NSError *)err localizedDescription]; - return [ld UTF8String]; -} - -const char *getNSErrorDomain(void *err) -{ - const char *ret; - @autoreleasepool { - NSString *domain = (NSString *)[(NSError *)err domain]; - ret = [domain UTF8String]; - } - return ret; -} - -const char *getNSErrorUserInfo(void *err) -{ - NSDictionary *ui = [(NSError *)err userInfo]; - NSString *uis = [NSString stringWithFormat:@"%@", ui]; - return [uis UTF8String]; -} - -NSInteger getNSErrorCode(void *err) -{ - return (NSInteger)[(NSError *)err code]; -} - -void *makeNSMutableArray(unsigned long cap) -{ - return [[NSMutableArray alloc] initWithCapacity:(NSUInteger)cap]; -} - -void addNSMutableArrayVal(void *ary, void *val) -{ - [(NSMutableArray *)ary addObject:(NSObject *)val]; -} - -void *newNSError() -{ - NSError *err = nil; - return err; -} - -bool hasError(void *err) -{ - return (NSError *)err != nil; -} - -void *minimumAlloc() -{ - return [[NSMutableData dataWithLength:1] mutableBytes]; -} - -void releaseNSObject(void* o) -{ - @autoreleasepool { - [(NSObject*)o release]; - } -} - -static inline void startNSThread() -{ - [[NSThread new] start]; // put the runtime into multi-threaded mode -} - -static inline void releaseDispatch(void *queue) -{ - dispatch_release((dispatch_queue_t)queue); -} -*/ -import "C" -import ( - "fmt" - "runtime" - "unsafe" -) - -// startNSThread starts NSThread. -func startNSThread() { - C.startNSThread() -} - -// releaseDispatch releases allocated dispatch_queue_t -func releaseDispatch(p unsafe.Pointer) { - C.releaseDispatch(p) -} - -// CharWithGoString makes *Char which is *C.Char wrapper from Go string. -func charWithGoString(s string) *char { - return (*char)(unsafe.Pointer(C.CString(s))) -} - -// Char is a wrapper of C.char -type char C.char - -// CString converts *C.char from *Char -func (c *char) CString() *C.char { - return (*C.char)(c) -} - -// String converts Go string from *Char -func (c *char) String() string { - return C.GoString((*C.char)(c)) -} - -// Free frees allocated *C.char in Go code -func (c *char) Free() { - C.free(unsafe.Pointer(c)) -} - -// pointer indicates any pointers which are allocated in objective-c world. -type pointer struct { - ptr unsafe.Pointer -} - -// Release releases allocated resources in objective-c world. -func (p *pointer) Release() { - C.releaseNSObject(p.Ptr()) - runtime.KeepAlive(p) -} - -// Ptr returns raw pointer. -func (o *pointer) Ptr() unsafe.Pointer { - if o == nil { - return nil - } - return o.ptr -} - -// NSObject indicates NSObject -type NSObject interface { - Ptr() unsafe.Pointer -} - -// NSError indicates NSError. -type NSError struct { - Domain string - Code int - LocalizedDescription string - UserInfo string - pointer -} - -// newNSErrorAsNil makes nil NSError in objective-c world. -func newNSErrorAsNil() *pointer { - p := &pointer{ - ptr: unsafe.Pointer(C.newNSError()), - } - return p -} - -// hasNSError checks passed pointer is NSError or not. -func hasNSError(nserrPtr unsafe.Pointer) bool { - return (bool)(C.hasError(nserrPtr)) -} - -func (n *NSError) Error() string { - if n == nil { - return "" - } - return fmt.Sprintf( - "Error Domain=%s Code=%d Description=%q UserInfo=%s", - n.Domain, - n.Code, - n.LocalizedDescription, - n.UserInfo, - ) -} - -// TODO(codehex): improvement (3 times called C functions now) -func newNSError(p unsafe.Pointer) *NSError { - if !hasNSError(p) { - return nil - } - domain := (*char)(C.getNSErrorDomain(p)) - description := (*char)(C.getNSErrorLocalizedDescription(p)) - userInfo := (*char)(C.getNSErrorUserInfo(p)) - return &NSError{ - Domain: domain.String(), - Code: int(C.getNSErrorCode(p)), - LocalizedDescription: description.String(), - UserInfo: userInfo.String(), // NOTE(codehex): maybe we can convert to map[string]interface{} - } -} - -// convertToNSMutableArray converts to NSMutableArray from NSObject slice in Go world. -func convertToNSMutableArray(s []NSObject) *pointer { - ln := len(s) - ary := C.makeNSMutableArray(C.ulong(ln)) - for _, v := range s { - C.addNSMutableArrayVal(ary, v.Ptr()) - } - p := &pointer{ptr: ary} - runtime.SetFinalizer(p, func(self *pointer) { - self.Release() - }) - return p -} diff --git a/src/cmd/linuxkit/vendor/github.com/Code-Hex/vz/socket.go b/src/cmd/linuxkit/vendor/github.com/Code-Hex/vz/socket.go deleted file mode 100644 index cc62d6fe5..000000000 --- a/src/cmd/linuxkit/vendor/github.com/Code-Hex/vz/socket.go +++ /dev/null @@ -1,46 +0,0 @@ -package vz - -/* -#cgo darwin CFLAGS: -x objective-c -fno-objc-arc -#cgo darwin LDFLAGS: -lobjc -framework Foundation -framework Virtualization -# include "virtualization.h" -*/ -import "C" -import "runtime" - -// SocketDeviceConfiguration for a socket device configuration. -type SocketDeviceConfiguration interface { - NSObject - - socketDeviceConfiguration() -} - -type baseSocketDeviceConfiguration struct{} - -func (*baseSocketDeviceConfiguration) socketDeviceConfiguration() {} - -var _ SocketDeviceConfiguration = (*VirtioSocketDeviceConfiguration)(nil) - -// VirtioSocketDeviceConfiguration is a configuration of the Virtio socket device. -// -// This configuration creates a Virtio socket device for the guest which communicates with the host through the Virtio interface. -// Only one Virtio socket device can be used per virtual machine. -// see: https://developer.apple.com/documentation/virtualization/vzvirtiosocketdeviceconfiguration?language=objc -type VirtioSocketDeviceConfiguration struct { - pointer - - *baseSocketDeviceConfiguration -} - -// NewVirtioSocketDeviceConfiguration creates a new VirtioSocketDeviceConfiguration. -func NewVirtioSocketDeviceConfiguration() *VirtioSocketDeviceConfiguration { - config := &VirtioSocketDeviceConfiguration{ - pointer: pointer{ - ptr: C.newVZVirtioSocketDeviceConfiguration(), - }, - } - runtime.SetFinalizer(config, func(self *VirtioSocketDeviceConfiguration) { - self.Release() - }) - return config -} diff --git a/src/cmd/linuxkit/vendor/github.com/Code-Hex/vz/storage.go b/src/cmd/linuxkit/vendor/github.com/Code-Hex/vz/storage.go deleted file mode 100644 index d29493cf0..000000000 --- a/src/cmd/linuxkit/vendor/github.com/Code-Hex/vz/storage.go +++ /dev/null @@ -1,109 +0,0 @@ -package vz - -/* -#cgo darwin CFLAGS: -x objective-c -fno-objc-arc -#cgo darwin LDFLAGS: -lobjc -framework Foundation -framework Virtualization -# include "virtualization.h" -*/ -import "C" -import "runtime" - -type baseStorageDeviceAttachment struct{} - -func (*baseStorageDeviceAttachment) storageDeviceAttachment() {} - -// StorageDeviceAttachment for a storage device attachment. -// -// A storage device attachment defines how a virtual machine storage device interfaces with the host system. -// see: https://developer.apple.com/documentation/virtualization/vzstoragedeviceattachment?language=objc -type StorageDeviceAttachment interface { - NSObject - - storageDeviceAttachment() -} - -var _ StorageDeviceAttachment = (*DiskImageStorageDeviceAttachment)(nil) - -// DiskImageStorageDeviceAttachment is a storage device attachment using a disk image to implement the storage. -// -// This storage device attachment uses a disk image on the host file system as the drive of the storage device. -// Only raw data disk images are supported. -// see: https://developer.apple.com/documentation/virtualization/vzdiskimagestoragedeviceattachment?language=objc -type DiskImageStorageDeviceAttachment struct { - pointer - - *baseStorageDeviceAttachment -} - -// NewDiskImageStorageDeviceAttachment initialize the attachment from a local file path. -// Returns error is not nil, assigned with the error if the initialization failed. -// -// - diskPath is local file URL to the disk image in RAW format. -// - readOnly if YES, the device attachment is read-only, otherwise the device can write data to the disk image. -func NewDiskImageStorageDeviceAttachment(diskPath string, readOnly bool) (*DiskImageStorageDeviceAttachment, error) { - nserr := newNSErrorAsNil() - nserrPtr := nserr.Ptr() - - diskPathChar := charWithGoString(diskPath) - defer diskPathChar.Free() - attachment := &DiskImageStorageDeviceAttachment{ - pointer: pointer{ - ptr: C.newVZDiskImageStorageDeviceAttachment( - diskPathChar.CString(), - C.bool(readOnly), - &nserrPtr, - ), - }, - } - if err := newNSError(nserrPtr); err != nil { - return nil, err - } - runtime.SetFinalizer(attachment, func(self *DiskImageStorageDeviceAttachment) { - self.Release() - }) - return attachment, nil -} - -// StorageDeviceConfiguration for a storage device configuration. -type StorageDeviceConfiguration interface { - NSObject - - storageDeviceConfiguration() -} - -type baseStorageDeviceConfiguration struct{} - -func (*baseStorageDeviceConfiguration) storageDeviceConfiguration() {} - -var _ StorageDeviceConfiguration = (*VirtioBlockDeviceConfiguration)(nil) - -// VirtioBlockDeviceConfiguration is a configuration of a paravirtualized storage device of type Virtio Block Device. -// -// This device configuration creates a storage device using paravirtualization. -// The emulated device follows the Virtio Block Device specification. -// -// The host implementation of the device is done through an attachment subclassing VZStorageDeviceAttachment -// like VZDiskImageStorageDeviceAttachment. -// see: https://developer.apple.com/documentation/virtualization/vzvirtioblockdeviceconfiguration?language=objc -type VirtioBlockDeviceConfiguration struct { - pointer - - *baseStorageDeviceConfiguration -} - -// NewVirtioBlockDeviceConfiguration initialize a VZVirtioBlockDeviceConfiguration with a device attachment. -// -// - attachment The storage device attachment. This defines how the virtualized device operates on the host side. -func NewVirtioBlockDeviceConfiguration(attachment StorageDeviceAttachment) *VirtioBlockDeviceConfiguration { - config := &VirtioBlockDeviceConfiguration{ - pointer: pointer{ - ptr: C.newVZVirtioBlockDeviceConfiguration( - attachment.Ptr(), - ), - }, - } - runtime.SetFinalizer(config, func(self *VirtioBlockDeviceConfiguration) { - self.Release() - }) - return config -} diff --git a/src/cmd/linuxkit/vendor/github.com/Code-Hex/vz/v3/.clang-format b/src/cmd/linuxkit/vendor/github.com/Code-Hex/vz/v3/.clang-format new file mode 100644 index 000000000..451b578f1 --- /dev/null +++ b/src/cmd/linuxkit/vendor/github.com/Code-Hex/vz/v3/.clang-format @@ -0,0 +1,4 @@ +BasedOnStyle: WebKit +Language: ObjC +TabWidth: 4 +PointerAlignment: Right diff --git a/src/cmd/linuxkit/vendor/github.com/Code-Hex/vz/v3/.gitignore b/src/cmd/linuxkit/vendor/github.com/Code-Hex/vz/v3/.gitignore new file mode 100644 index 000000000..6deebbd8d --- /dev/null +++ b/src/cmd/linuxkit/vendor/github.com/Code-Hex/vz/v3/.gitignore @@ -0,0 +1,7 @@ +virtualization +*.log +.envrc +.env +RestoreImage.ipsw +testdata/* +!testdata/.gitkeep \ No newline at end of file diff --git a/src/cmd/linuxkit/vendor/github.com/Code-Hex/vz/v3/CONTRIBUTING.md b/src/cmd/linuxkit/vendor/github.com/Code-Hex/vz/v3/CONTRIBUTING.md new file mode 100644 index 000000000..5b681976c --- /dev/null +++ b/src/cmd/linuxkit/vendor/github.com/Code-Hex/vz/v3/CONTRIBUTING.md @@ -0,0 +1,23 @@ +## How to contribute to github.com/Code-Hex/vz + +#### **Did you find a bug?** + +* **Ensure the bug was not already reported** by searching on GitHub under [Issues](https://github.com/Code-Hex/vz/issues). + +* If you're unable to find an open issue addressing the problem, [open a new one](https://github.com/Code-Hex/vz/issues/new). Be sure to include a **title and clear description**, as much relevant information as possible, and a **code sample** or an **executable test case** demonstrating the expected behavior that is not occurring. + +#### **Did you write a patch that fixes a bug?** + +* Open a new GitHub pull request with the patch. + +* Ensure the PR description clearly describes the problem and solution. **Must** be included the relevant issue number. + +> **Note** +> Basically, this can be done after a policy has been decided like how to write the code or how to implement, etc in an issue. + +> **Warning** +> We generally do not accept some pull requests like either did not follow the owner's opinion or harassing. + +#### **Did you fix whitespace, format code, or make a purely cosmetic patch?** + +Changes that are cosmetic in nature and do not add anything substantial to the stability, functionality, or testability of github.com/Code-Hex/vz will generally not be accepted. diff --git a/src/cmd/linuxkit/vendor/github.com/Code-Hex/vz/LICENSE b/src/cmd/linuxkit/vendor/github.com/Code-Hex/vz/v3/LICENSE similarity index 100% rename from src/cmd/linuxkit/vendor/github.com/Code-Hex/vz/LICENSE rename to src/cmd/linuxkit/vendor/github.com/Code-Hex/vz/v3/LICENSE diff --git a/src/cmd/linuxkit/vendor/github.com/Code-Hex/vz/v3/Makefile b/src/cmd/linuxkit/vendor/github.com/Code-Hex/vz/v3/Makefile new file mode 100644 index 000000000..4bd73a3a5 --- /dev/null +++ b/src/cmd/linuxkit/vendor/github.com/Code-Hex/vz/v3/Makefile @@ -0,0 +1,31 @@ +PUIPUI_LINUX_VERSION := 0.0.1 +ARCH := $(shell uname -m) +KERNEL_ARCH := $(shell echo $(ARCH) | sed -e s/arm64/aarch64/) +KERNEL_TAR := puipui_linux_v$(PUIPUI_LINUX_VERSION)_$(KERNEL_ARCH).tar.gz +KERNEL_DOWNLOAD_URL := https://github.com/Code-Hex/puipui-linux/releases/download/v$(PUIPUI_LINUX_VERSION)/$(KERNEL_TAR) + +.PHONY: fmt +fmt: + @ls | grep -E '\.(h|m)$$' | xargs clang-format -i --verbose + +.PHONY: test +test: + go test -exec "go run $(PWD)/cmd/codesign" ./... -timeout 60s -v + +.PHONY: download_kernel +download_kernel: + curl --output-dir testdata -LO $(KERNEL_DOWNLOAD_URL) + @tar xvf testdata/$(KERNEL_TAR) -C testdata +ifeq ($(ARCH),arm64) + @gunzip -f testdata/Image.gz +else + @mv testdata/bzImage testdata/Image +endif + +.PHONY: install/stringer +install/stringer: + @go install golang.org/x/tools/cmd/stringer@latest + +.PHONY: clean +clean: + @rm testdata/{Image,initramfs.cpio.gz,*.tar.gz} \ No newline at end of file diff --git a/src/cmd/linuxkit/vendor/github.com/Code-Hex/vz/v3/README.md b/src/cmd/linuxkit/vendor/github.com/Code-Hex/vz/v3/README.md new file mode 100644 index 000000000..e4a0cddd7 --- /dev/null +++ b/src/cmd/linuxkit/vendor/github.com/Code-Hex/vz/v3/README.md @@ -0,0 +1,137 @@ +vz - Go binding with Apple [Virtualization.framework](https://developer.apple.com/documentation/virtualization?language=objc) +======= + +[![Build](https://github.com/Code-Hex/vz/actions/workflows/compile.yml/badge.svg)](https://github.com/Code-Hex/vz/actions/workflows/compile.yml) [![Go Reference](https://pkg.go.dev/badge/github.com/Code-Hex/vz/v3.svg)](https://pkg.go.dev/github.com/Code-Hex/vz/v3) + +vz provides the power of the Apple Virtualization.framework in Go. Put here is block quote of overreview which is written what is Virtualization.framework from the document. + +> The Virtualization framework provides high-level APIs for creating and managing virtual machines (VM) on Apple silicon and Intel-based Mac computers. Use this framework to boot and run macOS or Linux-based operating systems in custom environments that you define. The framework supports the [Virtual I/O Device (VIRTIO)](https://docs.oasis-open.org/virtio/virtio/v1.1/csprd01/virtio-v1.1-csprd01.html) specification, which defines standard interfaces for many device types, including network, socket, serial port, storage, entropy, and memory-balloon devices. + +## Usage + +Please see the [example](https://github.com/Code-Hex/vz/tree/main/example) directory. + +## Requirements + +- Higher or equal to macOS Big Sur (11.0.0). +- Latest version of vz supports last two Go major [releases](https://go.dev/doc/devel/release) and might work with older versions. + +## Installation + +Initialize your project by creating a folder and then running `go mod init github.com/your/repo` ([learn more](https://go.dev/blog/using-go-modules)) inside the folder. Then install vz with the go get command: + +``` +$ go get github.com/Code-Hex/vz/v3 +``` + +Deprecated older versions (v1, v2). + +## Feature Overview + +- ✅ Virtualize Linux on a Mac **(x86_64, arm64)** + - GUI Support + - Boot Extensible Firmware Interface (EFI) ROM + - Clipboard sharing through the SPICE agent +- ✅ Virtualize macOS on Apple Silicon Macs **(arm64)** + - Fetches the latest restore image supported by this host from the network + - Start in recovery mode +- ✅ Running Intel Binaries in Linux VMs with Rosetta **(arm64)** +- ✅ [Shared Directories](https://github.com/Code-Hex/vz/wiki/Shared-Directories) +- ✅ [Virtio Sockets](https://github.com/Code-Hex/vz/wiki/Sockets) +- ✅ Less dependent (only under golang.org/x/*) + +## Important + +For binaries used in this package, you need to create an entitlements file like the one below and apply the following command. + +
+vz.entitlements + +``` + + + + + com.apple.security.virtualization + + + +``` + +
+ +```sh +$ codesign --entitlements vz.entitlements -s - +``` + +> A process must have the com.apple.security.virtualization entitlement to use the Virtualization APIs. + +If you want to use [`VZBridgedNetworkDeviceAttachment`](https://developer.apple.com/documentation/virtualization/vzbridgednetworkdeviceattachment?language=objc), you need to add also `com.apple.vm.networking` entitlement. + +## Known compile-time warnings + +If you compile using an older Xcode SDK, you will get the following warnings. + +This example warns that macOS 12.3 API and macOS 13 API are not available in the binary build. Running this binary on a modern OS (macOS 12.3 or macOS 13) means that these APIs are not available. This means these APIs are not available even if you are running this binary on a modern OS (macOS 12.3 or macOS 13). + +``` +$ go build . +# github.com/Code-Hex/vz/v3 +In file included from _cgo_export.c:4: +In file included from socket.go:6: +In file included from ./virtualization_11.h:9: +./virtualization_helper.h:25:9: warning: macOS 12.3 API has been disabled [-W#pragma-messages] +./virtualization_helper.h:32:9: warning: macOS 13 API has been disabled [-W#pragma-messages] +``` + +If you want to build a binary that can use the API on all operating systems, make sure the Xcode SDK is up-to-date. + +You can check the version of the Xcode SDK available for each macOS on this site. + +https://xcodereleases.com/ + +## Version compatibility check + +The package provides a mechanism for checking the availability of the respective API through error handling: + +```go +bootLoader, err := vz.NewEFIBootLoader() +if errors.Is(err, vz.ErrUnsupportedOSVersion) || errors.Is(err, ErrBuildTargetOSVersion) { + return fallbackBootLoader() +} +if err != nil { + return nil, err +} +return bootLoader, nil +``` + +There are two items to check. + +1. API is compatible with the version of macOS +2. The binary was built with the API enabled + +## Knowledge for the Apple Virtualization.framework + +There is a lot of knowledge required to use this Apple Virtualization.framework, but the information is too scattered and very difficult to understand. In most cases, this can be found in [the official documentation](https://developer.apple.com/documentation/virtualization?language=objc). However, the Linux kernel knowledge required to use the feature provided by this framework is not documented. Therefore, I have compiled the knowledge I have gathered so far into this wiki. + +https://github.com/Code-Hex/vz/wiki + +Anyone is free to edit this wiki. It would help someone if you could add information not listed here. Let's make a good wiki together! + +## Testing + +If you want to contribute some code, you will need to add tests. + +[PUI PUI Linux](https://github.com/Code-Hex/puipui-linux) is used to test this library. This Linux is designed to provide only the minimum functionality required for the Apple Virtualization.framework (Virtio), so the kernel file size is very small. + +The test code uses the `Makefile` in the project root. + +``` +$ # Download PUI PUI Linux, Only required the first time. +$ make download_kernel +$ make test +``` + +## LICENSE + +MIT License diff --git a/src/cmd/linuxkit/vendor/github.com/Code-Hex/vz/v3/audio.go b/src/cmd/linuxkit/vendor/github.com/Code-Hex/vz/v3/audio.go new file mode 100644 index 000000000..cf7443f1b --- /dev/null +++ b/src/cmd/linuxkit/vendor/github.com/Code-Hex/vz/v3/audio.go @@ -0,0 +1,141 @@ +package vz + +/* +#cgo darwin CFLAGS: -mmacosx-version-min=11 -x objective-c -fno-objc-arc +#cgo darwin LDFLAGS: -lobjc -framework Foundation -framework Virtualization +# include "virtualization_11.h" +# include "virtualization_12.h" +*/ +import "C" +import ( + "github.com/Code-Hex/vz/v3/internal/objc" +) + +// AudioDeviceConfiguration interface for an audio device configuration. +type AudioDeviceConfiguration interface { + objc.NSObject + + audioDeviceConfiguration() +} + +type baseAudioDeviceConfiguration struct{} + +func (*baseAudioDeviceConfiguration) audioDeviceConfiguration() {} + +// VirtioSoundDeviceConfiguration is a struct that defines a Virtio sound device configuration. +// +// Use a VirtioSoundDeviceConfiguration to configure an audio device for your VM. After creating +// this struct, assign appropriate values via the SetStreams method which defines the behaviors of +// the underlying audio streams for this audio device. +// +// After creating and configuring a VirtioSoundDeviceConfiguration struct, assign it to the +// SetAudioDevicesVirtualMachineConfiguration method of your VM’s configuration. +type VirtioSoundDeviceConfiguration struct { + *pointer + + *baseAudioDeviceConfiguration +} + +var _ AudioDeviceConfiguration = (*VirtioSoundDeviceConfiguration)(nil) + +// NewVirtioSoundDeviceConfiguration creates a new sound device configuration. +// +// This is only supported on macOS 12 and newer, error will be returned +// on older versions. +func NewVirtioSoundDeviceConfiguration() (*VirtioSoundDeviceConfiguration, error) { + if err := macOSAvailable(12); err != nil { + return nil, err + } + config := &VirtioSoundDeviceConfiguration{ + pointer: objc.NewPointer( + C.newVZVirtioSoundDeviceConfiguration(), + ), + } + objc.SetFinalizer(config, func(self *VirtioSoundDeviceConfiguration) { + objc.Release(self) + }) + return config, nil +} + +// SetStreams sets the list of audio streams exposed by this device. +func (v *VirtioSoundDeviceConfiguration) SetStreams(streams ...VirtioSoundDeviceStreamConfiguration) { + ptrs := make([]objc.NSObject, len(streams)) + for i, val := range streams { + ptrs[i] = val + } + array := objc.ConvertToNSMutableArray(ptrs) + C.setStreamsVZVirtioSoundDeviceConfiguration( + objc.Ptr(v), objc.Ptr(array), + ) +} + +// VirtioSoundDeviceStreamConfiguration interface for Virtio Sound Device Stream Configuration. +type VirtioSoundDeviceStreamConfiguration interface { + objc.NSObject + + virtioSoundDeviceStreamConfiguration() +} + +type baseVirtioSoundDeviceStreamConfiguration struct{} + +func (*baseVirtioSoundDeviceStreamConfiguration) virtioSoundDeviceStreamConfiguration() {} + +// VirtioSoundDeviceHostInputStreamConfiguration is a PCM stream of input audio data, +// such as from a microphone via host. +type VirtioSoundDeviceHostInputStreamConfiguration struct { + *pointer + + *baseVirtioSoundDeviceStreamConfiguration +} + +var _ VirtioSoundDeviceStreamConfiguration = (*VirtioSoundDeviceHostInputStreamConfiguration)(nil) + +// NewVirtioSoundDeviceHostInputStreamConfiguration creates a new PCM stream configuration of input audio data from host. +// +// This is only supported on macOS 12 and newer, error will be returned +// on older versions. +func NewVirtioSoundDeviceHostInputStreamConfiguration() (*VirtioSoundDeviceHostInputStreamConfiguration, error) { + if err := macOSAvailable(12); err != nil { + return nil, err + } + config := &VirtioSoundDeviceHostInputStreamConfiguration{ + pointer: objc.NewPointer( + C.newVZVirtioSoundDeviceHostInputStreamConfiguration(), + ), + } + objc.SetFinalizer(config, func(self *VirtioSoundDeviceHostInputStreamConfiguration) { + objc.Release(self) + }) + return config, nil +} + +// VirtioSoundDeviceHostOutputStreamConfiguration is a struct that +// defines a Virtio host sound device output stream configuration. +// +// A PCM stream of output audio data, such as to a speaker from host. +type VirtioSoundDeviceHostOutputStreamConfiguration struct { + *pointer + + *baseVirtioSoundDeviceStreamConfiguration +} + +var _ VirtioSoundDeviceStreamConfiguration = (*VirtioSoundDeviceHostOutputStreamConfiguration)(nil) + +// NewVirtioSoundDeviceHostOutputStreamConfiguration creates a new sounds device output stream configuration. +// +// This is only supported on macOS 12 and newer, error will be returned +// on older versions. +func NewVirtioSoundDeviceHostOutputStreamConfiguration() (*VirtioSoundDeviceHostOutputStreamConfiguration, error) { + if err := macOSAvailable(12); err != nil { + return nil, err + } + config := &VirtioSoundDeviceHostOutputStreamConfiguration{ + pointer: objc.NewPointer( + C.newVZVirtioSoundDeviceHostOutputStreamConfiguration(), + ), + } + objc.SetFinalizer(config, func(self *VirtioSoundDeviceHostOutputStreamConfiguration) { + objc.Release(self) + }) + return config, nil +} diff --git a/src/cmd/linuxkit/vendor/github.com/Code-Hex/vz/v3/bootloader.go b/src/cmd/linuxkit/vendor/github.com/Code-Hex/vz/v3/bootloader.go new file mode 100644 index 000000000..828af2ccb --- /dev/null +++ b/src/cmd/linuxkit/vendor/github.com/Code-Hex/vz/v3/bootloader.go @@ -0,0 +1,226 @@ +package vz + +/* +#cgo darwin CFLAGS: -mmacosx-version-min=11 -x objective-c -fno-objc-arc +#cgo darwin LDFLAGS: -lobjc -framework Foundation -framework Virtualization +# include "virtualization_11.h" +# include "virtualization_13.h" +*/ +import "C" +import ( + "fmt" + "os" + + "github.com/Code-Hex/vz/v3/internal/objc" +) + +// BootLoader is the interface of boot loader definitions. +type BootLoader interface { + objc.NSObject + + bootLoader() +} + +type baseBootLoader struct{} + +func (*baseBootLoader) bootLoader() {} + +var _ BootLoader = (*LinuxBootLoader)(nil) + +// LinuxBootLoader Boot loader configuration for a Linux kernel. +// see: https://developer.apple.com/documentation/virtualization/vzlinuxbootloader?language=objc +type LinuxBootLoader struct { + vmlinuzPath string + initrdPath string + cmdLine string + *pointer + + *baseBootLoader +} + +func (b *LinuxBootLoader) String() string { + return fmt.Sprintf( + "vmlinuz: %q, initrd: %q, command-line: %q", + b.vmlinuzPath, + b.initrdPath, + b.cmdLine, + ) +} + +// LinuxBootLoaderOption is an option for LinuxBootLoader. +type LinuxBootLoaderOption func(b *LinuxBootLoader) error + +// WithCommandLine sets the command-line parameters. +// see: https://www.kernel.org/doc/html/latest/admin-guide/kernel-parameters.html +func WithCommandLine(cmdLine string) LinuxBootLoaderOption { + return func(b *LinuxBootLoader) error { + b.cmdLine = cmdLine + cs := charWithGoString(cmdLine) + defer cs.Free() + C.setCommandLineVZLinuxBootLoader(objc.Ptr(b), cs.CString()) + return nil + } +} + +// WithInitrd sets the optional initial RAM disk. +func WithInitrd(initrdPath string) LinuxBootLoaderOption { + return func(b *LinuxBootLoader) error { + if _, err := os.Stat(initrdPath); err != nil { + return fmt.Errorf("invalid initial RAM disk path: %w", err) + } + b.initrdPath = initrdPath + cs := charWithGoString(initrdPath) + defer cs.Free() + C.setInitialRamdiskURLVZLinuxBootLoader(objc.Ptr(b), cs.CString()) + return nil + } +} + +// NewLinuxBootLoader creates a LinuxBootLoader with the Linux kernel passed as Path. +// +// This is only supported on macOS 11 and newer, error will +// be returned on older versions. +func NewLinuxBootLoader(vmlinuz string, opts ...LinuxBootLoaderOption) (*LinuxBootLoader, error) { + if err := macOSAvailable(11); err != nil { + return nil, err + } + if _, err := os.Stat(vmlinuz); err != nil { + return nil, fmt.Errorf("invalid linux kernel path: %w", err) + } + + vmlinuzPath := charWithGoString(vmlinuz) + defer vmlinuzPath.Free() + bootLoader := &LinuxBootLoader{ + vmlinuzPath: vmlinuz, + pointer: objc.NewPointer( + C.newVZLinuxBootLoader(vmlinuzPath.CString()), + ), + } + objc.SetFinalizer(bootLoader, func(self *LinuxBootLoader) { + objc.Release(self) + }) + for _, opt := range opts { + if err := opt(bootLoader); err != nil { + return nil, err + } + } + return bootLoader, nil +} + +var _ BootLoader = (*LinuxBootLoader)(nil) + +// EFIBootLoader Boot loader configuration for booting guest operating systems expecting an EFI ROM. +// see: https://developer.apple.com/documentation/virtualization/vzefibootloader?language=objc +type EFIBootLoader struct { + *pointer + + *baseBootLoader + + variableStore *EFIVariableStore +} + +// NewEFIBootLoaderOption is an option type to initialize a new EFIBootLoader. +type NewEFIBootLoaderOption func(b *EFIBootLoader) + +// WithEFIVariableStore sets the optional EFI variable store. +func WithEFIVariableStore(variableStore *EFIVariableStore) NewEFIBootLoaderOption { + return func(e *EFIBootLoader) { + C.setVariableStoreVZEFIBootLoader(objc.Ptr(e), objc.Ptr(variableStore)) + e.variableStore = variableStore + } +} + +// NewEFIBootLoader creates a new EFI boot loader. +// +// This is only supported on macOS 13 and newer, error will +// be returned on older versions. +func NewEFIBootLoader(opts ...NewEFIBootLoaderOption) (*EFIBootLoader, error) { + if err := macOSAvailable(13); err != nil { + return nil, err + } + bootLoader := &EFIBootLoader{ + pointer: objc.NewPointer( + C.newVZEFIBootLoader(), + ), + } + for _, optFunc := range opts { + optFunc(bootLoader) + } + objc.SetFinalizer(bootLoader, func(self *EFIBootLoader) { + objc.Release(self) + }) + return bootLoader, nil +} + +// VariableStore returns EFI variable store. +func (e *EFIBootLoader) VariableStore() *EFIVariableStore { + return e.variableStore +} + +// EFIVariableStore is EFI variable store. +// The EFI variable store contains NVRAM variables exposed by the EFI ROM. +// +// see: https://developer.apple.com/documentation/virtualization/vzefivariablestore?language=objc +type EFIVariableStore struct { + *pointer + + path string +} + +// NewEFIVariableStoreOption is an option type to initialize a new EFIVariableStore. +type NewEFIVariableStoreOption func(*EFIVariableStore) error + +// WithCreatingEFIVariableStore is an option to initialized VZEFIVariableStore to a path on a file system. +// If the variable store already exists in path, it is overwritten. +func WithCreatingEFIVariableStore() NewEFIVariableStoreOption { + return func(es *EFIVariableStore) error { + cpath := charWithGoString(es.path) + defer cpath.Free() + + nserrPtr := newNSErrorAsNil() + es.pointer = objc.NewPointer( + C.newCreatingVZEFIVariableStoreAtPath( + cpath.CString(), + &nserrPtr, + ), + ) + if err := newNSError(nserrPtr); err != nil { + return err + } + return nil + } +} + +// NewEFIVariableStore Initialize the variable store. If no options are specified, +// it initialises from the paths that exist. +// +// This is only supported on macOS 13 and newer, error will +// be returned on older versions. +func NewEFIVariableStore(path string, opts ...NewEFIVariableStoreOption) (*EFIVariableStore, error) { + if err := macOSAvailable(13); err != nil { + return nil, err + } + variableStore := &EFIVariableStore{path: path} + for _, optFunc := range opts { + if err := optFunc(variableStore); err != nil { + return nil, err + } + } + if objc.Ptr(variableStore) == nil { + if _, err := os.Stat(path); err != nil { + return nil, err + } + cpath := charWithGoString(path) + defer cpath.Free() + variableStore.pointer = objc.NewPointer( + C.newVZEFIVariableStorePath(cpath.CString()), + ) + } + objc.SetFinalizer(variableStore, func(self *EFIVariableStore) { + objc.Release(self) + }) + return variableStore, nil +} + +// Path returns the path of the variable store on the local file system. +func (e *EFIVariableStore) Path() string { return e.path } diff --git a/src/cmd/linuxkit/vendor/github.com/Code-Hex/vz/v3/bootloader_arm64.go b/src/cmd/linuxkit/vendor/github.com/Code-Hex/vz/v3/bootloader_arm64.go new file mode 100644 index 000000000..c57c7dac8 --- /dev/null +++ b/src/cmd/linuxkit/vendor/github.com/Code-Hex/vz/v3/bootloader_arm64.go @@ -0,0 +1,43 @@ +//go:build darwin && arm64 +// +build darwin,arm64 + +package vz + +/* +#cgo darwin CFLAGS: -mmacosx-version-min=11 -x objective-c -fno-objc-arc +#cgo darwin LDFLAGS: -lobjc -framework Foundation -framework Virtualization +# include "virtualization_12_arm64.h" +*/ +import "C" +import ( + "github.com/Code-Hex/vz/v3/internal/objc" +) + +// MacOSBootLoader is a boot loader configuration for booting macOS on Apple Silicon. +type MacOSBootLoader struct { + *pointer + + *baseBootLoader +} + +var _ BootLoader = (*MacOSBootLoader)(nil) + +// NewMacOSBootLoader creates a new MacOSBootLoader struct. +// +// This is only supported on macOS 12 and newer, error will +// be returned on older versions. +func NewMacOSBootLoader() (*MacOSBootLoader, error) { + if err := macOSAvailable(12); err != nil { + return nil, err + } + + bootLoader := &MacOSBootLoader{ + pointer: objc.NewPointer( + C.newVZMacOSBootLoader(), + ), + } + objc.SetFinalizer(bootLoader, func(self *MacOSBootLoader) { + objc.Release(self) + }) + return bootLoader, nil +} diff --git a/src/cmd/linuxkit/vendor/github.com/Code-Hex/vz/v3/cgoutil.go b/src/cmd/linuxkit/vendor/github.com/Code-Hex/vz/v3/cgoutil.go new file mode 100644 index 000000000..7799fc102 --- /dev/null +++ b/src/cmd/linuxkit/vendor/github.com/Code-Hex/vz/v3/cgoutil.go @@ -0,0 +1,139 @@ +package vz + +/* +#cgo darwin CFLAGS: -mmacosx-version-min=11 -x objective-c +#cgo darwin LDFLAGS: -lobjc -framework Foundation +#import + + +const char *getNSErrorLocalizedDescription(void *err) +{ + NSString *ld = (NSString *)[(NSError *)err localizedDescription]; + return [ld UTF8String]; +} + +const char *getNSErrorDomain(void *err) +{ + NSString *domain = (NSString *)[(NSError *)err domain]; + return [domain UTF8String]; +} + +const char *getNSErrorUserInfo(void *err) +{ + NSDictionary *ui = [(NSError *)err userInfo]; + NSString *uis = [NSString stringWithFormat:@"%@", ui]; + return [uis UTF8String]; +} + +NSInteger getNSErrorCode(void *err) +{ + return (NSInteger)[(NSError *)err code]; +} + +typedef struct NSErrorFlat { + const char *domain; + const char *localizedDescription; + const char *userinfo; + int code; +} NSErrorFlat; + +NSErrorFlat convertNSError2Flat(void *err) +{ + NSErrorFlat ret; + ret.domain = getNSErrorDomain(err); + ret.localizedDescription = getNSErrorLocalizedDescription(err); + ret.userinfo = getNSErrorUserInfo(err); + ret.code = (int)getNSErrorCode(err); + + return ret; +} + +void *newNSError() +{ + NSError *err = nil; + return err; +} + +bool hasError(void *err) +{ + return (NSError *)err != nil; +} +*/ +import "C" +import ( + "fmt" + "unsafe" + + "github.com/Code-Hex/vz/v3/internal/objc" +) + +// pointer is a type alias which is able to use as embedded type and +// makes as unexported it. +type pointer = objc.Pointer + +// NSError indicates NSError. +type NSError struct { + Domain string + Code int + LocalizedDescription string + UserInfo string +} + +// newNSErrorAsNil makes nil NSError in objective-c world. +func newNSErrorAsNil() unsafe.Pointer { + return unsafe.Pointer(C.newNSError()) +} + +// hasNSError checks passed pointer is NSError or not. +func hasNSError(nserrPtr unsafe.Pointer) bool { + return (bool)(C.hasError(nserrPtr)) +} + +func (n *NSError) Error() string { + if n == nil { + return "" + } + return fmt.Sprintf( + "Error Domain=%s Code=%d Description=%q UserInfo=%s", + n.Domain, + n.Code, + n.LocalizedDescription, + n.UserInfo, + ) +} + +func newNSError(p unsafe.Pointer) *NSError { + if !hasNSError(p) { + return nil + } + nsError := C.convertNSError2Flat(p) + return &NSError{ + Domain: (*char)(nsError.domain).String(), + Code: int((nsError.code)), + LocalizedDescription: (*char)(nsError.localizedDescription).String(), + UserInfo: (*char)(nsError.userinfo).String(), // NOTE(codehex): maybe we can convert to map[string]interface{} + } +} + +// CharWithGoString makes *Char which is *C.Char wrapper from Go string. +func charWithGoString(s string) *char { + return (*char)(unsafe.Pointer(C.CString(s))) +} + +// Char is a wrapper of C.char +type char C.char + +// CString converts *C.char from *Char +func (c *char) CString() *C.char { + return (*C.char)(c) +} + +// String converts Go string from *Char +func (c *char) String() string { + return C.GoString((*C.char)(c)) +} + +// Free frees allocated *C.char in Go code +func (c *char) Free() { + C.free(unsafe.Pointer(c)) +} diff --git a/src/cmd/linuxkit/vendor/github.com/Code-Hex/vz/v3/clipboard.go b/src/cmd/linuxkit/vendor/github.com/Code-Hex/vz/v3/clipboard.go new file mode 100644 index 000000000..abeeedbc8 --- /dev/null +++ b/src/cmd/linuxkit/vendor/github.com/Code-Hex/vz/v3/clipboard.go @@ -0,0 +1,66 @@ +package vz + +/* +#cgo darwin CFLAGS: -mmacosx-version-min=11 -x objective-c -fno-objc-arc +#cgo darwin LDFLAGS: -lobjc -framework Foundation -framework Virtualization +# include "virtualization_13.h" +*/ +import "C" +import ( + "github.com/Code-Hex/vz/v3/internal/objc" +) + +// SpiceAgentPortAttachment is an attachment point that enables +// the Spice clipboard sharing capability. +// +// see: https://developer.apple.com/documentation/virtualization/vzspiceagentportattachment?language=objc +type SpiceAgentPortAttachment struct { + *pointer + + *baseSerialPortAttachment + + enabledSharesClipboard bool +} + +var _ SerialPortAttachment = (*SpiceAgentPortAttachment)(nil) + +// NewSpiceAgentPortAttachment creates a new Spice agent port attachment. +// +// This is only supported on macOS 13 and newer, error will +// be returned on older versions. +func NewSpiceAgentPortAttachment() (*SpiceAgentPortAttachment, error) { + if err := macOSAvailable(13); err != nil { + return nil, err + } + spiceAgent := &SpiceAgentPortAttachment{ + pointer: objc.NewPointer( + C.newVZSpiceAgentPortAttachment(), + ), + enabledSharesClipboard: true, + } + objc.SetFinalizer(spiceAgent, func(self *SpiceAgentPortAttachment) { + objc.Release(self) + }) + return spiceAgent, nil +} + +// SetSharesClipboard sets enable the Spice agent clipboard sharing capability. +func (s *SpiceAgentPortAttachment) SetSharesClipboard(enable bool) { + C.setSharesClipboardVZSpiceAgentPortAttachment( + objc.Ptr(s), + C.bool(enable), + ) + s.enabledSharesClipboard = enable +} + +// SharesClipboard returns enable the Spice agent clipboard sharing capability. +func (s *SpiceAgentPortAttachment) SharesClipboard() bool { return s.enabledSharesClipboard } + +// SpiceAgentPortAttachmentName returns the Spice agent port name. +func SpiceAgentPortAttachmentName() (string, error) { + if err := macOSAvailable(13); err != nil { + return "", err + } + cstring := (*char)(C.getSpiceAgentPortName()) + return cstring.String(), nil +} diff --git a/src/cmd/linuxkit/vendor/github.com/Code-Hex/vz/v3/configuration.go b/src/cmd/linuxkit/vendor/github.com/Code-Hex/vz/v3/configuration.go new file mode 100644 index 000000000..e59aa82f1 --- /dev/null +++ b/src/cmd/linuxkit/vendor/github.com/Code-Hex/vz/v3/configuration.go @@ -0,0 +1,299 @@ +package vz + +/* +#cgo darwin CFLAGS: -mmacosx-version-min=11 -x objective-c -fno-objc-arc +#cgo darwin LDFLAGS: -lobjc -framework Foundation -framework Virtualization +# include "virtualization_11.h" +# include "virtualization_12.h" +# include "virtualization_13.h" +*/ +import "C" +import ( + "github.com/Code-Hex/vz/v3/internal/objc" +) + +// VirtualMachineConfiguration defines the configuration of a VirtualMachine. +// +// The following properties must be configured before creating a virtual machine: +// - bootLoader +// +// The configuration of devices is often done in two parts: +// - Device configuration +// - Device attachment +// +// The device configuration defines the characteristics of the emulated hardware device. +// For example, for a network device, the device configuration defines the type of network adapter present +// in the virtual machine and its MAC address. +// +// The device attachment defines the host machine's resources that are exposed by the virtual device. +// For example, for a network device, the device attachment can be virtual network interface with a NAT +// to the real network. +// +// Creating a virtual machine using the Virtualization framework requires the app to have the "com.apple.security.virtualization" entitlement. +// A VirtualMachineConfiguration is considered invalid if the application does not have the entitlement. +// +// see: https://developer.apple.com/documentation/virtualization/vzvirtualmachineconfiguration?language=objc +type VirtualMachineConfiguration struct { + cpuCount uint + memorySize uint64 + *pointer +} + +// NewVirtualMachineConfiguration creates a new configuration. +// +// - bootLoader parameter is used when the virtual machine starts. +// - cpu parameter is The number of CPUs must be a value between +// VZVirtualMachineConfiguration.minimumAllowedCPUCount and VZVirtualMachineConfiguration.maximumAllowedCPUCount. +// - memorySize parameter represents memory size in bytes. +// The memory size must be a multiple of a 1 megabyte (1024 * 1024 bytes) between +// VZVirtualMachineConfiguration.minimumAllowedMemorySize and VZVirtualMachineConfiguration.maximumAllowedMemorySize. +// +// This is only supported on macOS 11 and newer, error will +// be returned on older versions. +func NewVirtualMachineConfiguration(bootLoader BootLoader, cpu uint, memorySize uint64) (*VirtualMachineConfiguration, error) { + if err := macOSAvailable(11); err != nil { + return nil, err + } + + config := &VirtualMachineConfiguration{ + cpuCount: cpu, + memorySize: memorySize, + pointer: objc.NewPointer( + C.newVZVirtualMachineConfiguration( + objc.Ptr(bootLoader), + C.uint(cpu), + C.ulonglong(memorySize), + ), + ), + } + objc.SetFinalizer(config, func(self *VirtualMachineConfiguration) { + objc.Release(self) + }) + return config, nil +} + +// Validate the configuration. +// +// Return true if the configuration is valid. +// If error is not nil, assigned with the validation error if the validation failed. +func (v *VirtualMachineConfiguration) Validate() (bool, error) { + nserrPtr := newNSErrorAsNil() + ret := C.validateVZVirtualMachineConfiguration(objc.Ptr(v), &nserrPtr) + err := newNSError(nserrPtr) + if err != nil { + return false, err + } + return (bool)(ret), nil +} + +// SetEntropyDevicesVirtualMachineConfiguration sets list of entropy devices. Empty by default. +func (v *VirtualMachineConfiguration) SetEntropyDevicesVirtualMachineConfiguration(cs []*VirtioEntropyDeviceConfiguration) { + ptrs := make([]objc.NSObject, len(cs)) + for i, val := range cs { + ptrs[i] = val + } + array := objc.ConvertToNSMutableArray(ptrs) + C.setEntropyDevicesVZVirtualMachineConfiguration(objc.Ptr(v), objc.Ptr(array)) +} + +// SetMemoryBalloonDevicesVirtualMachineConfiguration sets list of memory balloon devices. Empty by default. +func (v *VirtualMachineConfiguration) SetMemoryBalloonDevicesVirtualMachineConfiguration(cs []MemoryBalloonDeviceConfiguration) { + ptrs := make([]objc.NSObject, len(cs)) + for i, val := range cs { + ptrs[i] = val + } + array := objc.ConvertToNSMutableArray(ptrs) + C.setMemoryBalloonDevicesVZVirtualMachineConfiguration(objc.Ptr(v), objc.Ptr(array)) +} + +// SetNetworkDevicesVirtualMachineConfiguration sets list of network adapters. Empty by default. +func (v *VirtualMachineConfiguration) SetNetworkDevicesVirtualMachineConfiguration(cs []*VirtioNetworkDeviceConfiguration) { + ptrs := make([]objc.NSObject, len(cs)) + for i, val := range cs { + ptrs[i] = val + } + array := objc.ConvertToNSMutableArray(ptrs) + C.setNetworkDevicesVZVirtualMachineConfiguration(objc.Ptr(v), objc.Ptr(array)) +} + +// NetworkDevices return the list of network device configuration set in this virtual machine configuration. +// Return an empty array if no network device configuration is set. +func (v *VirtualMachineConfiguration) NetworkDevices() []*VirtioNetworkDeviceConfiguration { + nsArray := objc.NewNSArray( + C.networkDevicesVZVirtualMachineConfiguration(objc.Ptr(v)), + ) + ptrs := nsArray.ToPointerSlice() + networkDevices := make([]*VirtioNetworkDeviceConfiguration, len(ptrs)) + for i, ptr := range ptrs { + networkDevices[i] = newVirtioNetworkDeviceConfiguration(ptr) + } + return networkDevices +} + +// SetSerialPortsVirtualMachineConfiguration sets list of serial ports. Empty by default. +func (v *VirtualMachineConfiguration) SetSerialPortsVirtualMachineConfiguration(cs []*VirtioConsoleDeviceSerialPortConfiguration) { + ptrs := make([]objc.NSObject, len(cs)) + for i, val := range cs { + ptrs[i] = val + } + array := objc.ConvertToNSMutableArray(ptrs) + C.setSerialPortsVZVirtualMachineConfiguration(objc.Ptr(v), objc.Ptr(array)) +} + +// SetSocketDevicesVirtualMachineConfiguration sets list of socket devices. Empty by default. +func (v *VirtualMachineConfiguration) SetSocketDevicesVirtualMachineConfiguration(cs []SocketDeviceConfiguration) { + ptrs := make([]objc.NSObject, len(cs)) + for i, val := range cs { + ptrs[i] = val + } + array := objc.ConvertToNSMutableArray(ptrs) + C.setSocketDevicesVZVirtualMachineConfiguration(objc.Ptr(v), objc.Ptr(array)) +} + +// SocketDevices return the list of socket device configuration configured in this virtual machine configuration. +// Return an empty array if no socket device configuration is set. +func (v *VirtualMachineConfiguration) SocketDevices() []SocketDeviceConfiguration { + nsArray := objc.NewNSArray( + C.socketDevicesVZVirtualMachineConfiguration(objc.Ptr(v)), + ) + ptrs := nsArray.ToPointerSlice() + socketDevices := make([]SocketDeviceConfiguration, len(ptrs)) + for i, ptr := range ptrs { + socketDevices[i] = newVirtioSocketDeviceConfiguration(ptr) + } + return socketDevices +} + +// SetStorageDevicesVirtualMachineConfiguration sets list of disk devices. Empty by default. +func (v *VirtualMachineConfiguration) SetStorageDevicesVirtualMachineConfiguration(cs []StorageDeviceConfiguration) { + ptrs := make([]objc.NSObject, len(cs)) + for i, val := range cs { + ptrs[i] = val + } + array := objc.ConvertToNSMutableArray(ptrs) + C.setStorageDevicesVZVirtualMachineConfiguration(objc.Ptr(v), objc.Ptr(array)) +} + +// SetDirectorySharingDevicesVirtualMachineConfiguration sets list of directory sharing devices. Empty by default. +// +// This is only supported on macOS 12 and newer. Older versions do nothing. +func (v *VirtualMachineConfiguration) SetDirectorySharingDevicesVirtualMachineConfiguration(cs []DirectorySharingDeviceConfiguration) { + if err := macOSAvailable(12); err != nil { + return + } + ptrs := make([]objc.NSObject, len(cs)) + for i, val := range cs { + ptrs[i] = val + } + array := objc.ConvertToNSMutableArray(ptrs) + C.setDirectorySharingDevicesVZVirtualMachineConfiguration(objc.Ptr(v), objc.Ptr(array)) +} + +// SetPlatformVirtualMachineConfiguration sets the hardware platform to use. Defaults to GenericPlatformConfiguration. +// +// This is only supported on macOS 12 and newer. Older versions do nothing. +func (v *VirtualMachineConfiguration) SetPlatformVirtualMachineConfiguration(c PlatformConfiguration) { + if err := macOSAvailable(12); err != nil { + return + } + C.setPlatformVZVirtualMachineConfiguration(objc.Ptr(v), objc.Ptr(c)) +} + +// SetGraphicsDevicesVirtualMachineConfiguration sets list of graphics devices. Empty by default. +// +// This is only supported on macOS 12 and newer. Older versions do nothing. +func (v *VirtualMachineConfiguration) SetGraphicsDevicesVirtualMachineConfiguration(cs []GraphicsDeviceConfiguration) { + if err := macOSAvailable(12); err != nil { + return + } + ptrs := make([]objc.NSObject, len(cs)) + for i, val := range cs { + ptrs[i] = val + } + array := objc.ConvertToNSMutableArray(ptrs) + C.setGraphicsDevicesVZVirtualMachineConfiguration(objc.Ptr(v), objc.Ptr(array)) +} + +// SetPointingDevicesVirtualMachineConfiguration sets list of pointing devices. Empty by default. +// +// This is only supported on macOS 12 and newer. Older versions do nothing. +func (v *VirtualMachineConfiguration) SetPointingDevicesVirtualMachineConfiguration(cs []PointingDeviceConfiguration) { + if err := macOSAvailable(12); err != nil { + return + } + ptrs := make([]objc.NSObject, len(cs)) + for i, val := range cs { + ptrs[i] = val + } + array := objc.ConvertToNSMutableArray(ptrs) + C.setPointingDevicesVZVirtualMachineConfiguration(objc.Ptr(v), objc.Ptr(array)) +} + +// SetKeyboardsVirtualMachineConfiguration sets list of keyboards. Empty by default. +// +// This is only supported on macOS 12 and newer. Older versions do nothing. +func (v *VirtualMachineConfiguration) SetKeyboardsVirtualMachineConfiguration(cs []KeyboardConfiguration) { + if err := macOSAvailable(12); err != nil { + return + } + ptrs := make([]objc.NSObject, len(cs)) + for i, val := range cs { + ptrs[i] = val + } + array := objc.ConvertToNSMutableArray(ptrs) + C.setKeyboardsVZVirtualMachineConfiguration(objc.Ptr(v), objc.Ptr(array)) +} + +// SetAudioDevicesVirtualMachineConfiguration sets list of audio devices. Empty by default. +// +// This is only supported on macOS 12 and newer. Older versions do nothing. +func (v *VirtualMachineConfiguration) SetAudioDevicesVirtualMachineConfiguration(cs []AudioDeviceConfiguration) { + if err := macOSAvailable(12); err != nil { + return + } + ptrs := make([]objc.NSObject, len(cs)) + for i, val := range cs { + ptrs[i] = val + } + array := objc.ConvertToNSMutableArray(ptrs) + C.setAudioDevicesVZVirtualMachineConfiguration(objc.Ptr(v), objc.Ptr(array)) +} + +// SetConsoleDevicesVirtualMachineConfiguration sets list of console devices. Empty by default. +// +// This is only supported on macOS 13 and newer. Older versions do nothing. +func (v *VirtualMachineConfiguration) SetConsoleDevicesVirtualMachineConfiguration(cs []ConsoleDeviceConfiguration) { + if err := macOSAvailable(13); err != nil { + return + } + ptrs := make([]objc.NSObject, len(cs)) + for i, val := range cs { + ptrs[i] = val + } + array := objc.ConvertToNSMutableArray(ptrs) + C.setConsoleDevicesVZVirtualMachineConfiguration(objc.Ptr(v), objc.Ptr(array)) +} + +// VirtualMachineConfigurationMinimumAllowedMemorySize returns minimum +// amount of memory required by virtual machines. +func VirtualMachineConfigurationMinimumAllowedMemorySize() uint64 { + return uint64(C.minimumAllowedMemorySizeVZVirtualMachineConfiguration()) +} + +// VirtualMachineConfigurationMaximumAllowedMemorySize returns maximum +// amount of memory allowed for a virtual machine. +func VirtualMachineConfigurationMaximumAllowedMemorySize() uint64 { + return uint64(C.maximumAllowedMemorySizeVZVirtualMachineConfiguration()) +} + +// VirtualMachineConfigurationMinimumAllowedCPUCount returns minimum +// number of CPUs for a virtual machine. +func VirtualMachineConfigurationMinimumAllowedCPUCount() uint { + return uint(C.minimumAllowedCPUCountVZVirtualMachineConfiguration()) +} + +// VirtualMachineConfigurationMaximumAllowedCPUCount returns maximum +// number of CPUs for a virtual machine. +func VirtualMachineConfigurationMaximumAllowedCPUCount() uint { + return uint(C.maximumAllowedCPUCountVZVirtualMachineConfiguration()) +} diff --git a/src/cmd/linuxkit/vendor/github.com/Code-Hex/vz/v3/console.go b/src/cmd/linuxkit/vendor/github.com/Code-Hex/vz/v3/console.go new file mode 100644 index 000000000..653833b15 --- /dev/null +++ b/src/cmd/linuxkit/vendor/github.com/Code-Hex/vz/v3/console.go @@ -0,0 +1,173 @@ +package vz + +/* +#cgo darwin CFLAGS: -mmacosx-version-min=11 -x objective-c -fno-objc-arc +#cgo darwin LDFLAGS: -lobjc -framework Foundation -framework Virtualization +# include "virtualization_13.h" +*/ +import "C" +import ( + "unsafe" + + "github.com/Code-Hex/vz/v3/internal/objc" +) + +// ConsoleDeviceConfiguration interface for an console device configuration. +type ConsoleDeviceConfiguration interface { + objc.NSObject + + consoleDeviceConfiguration() +} + +type baseConsoleDeviceConfiguration struct{} + +func (*baseConsoleDeviceConfiguration) consoleDeviceConfiguration() {} + +// VirtioConsoleDeviceConfiguration is Virtio Console Device. +type VirtioConsoleDeviceConfiguration struct { + *pointer + portsPtr unsafe.Pointer + + *baseConsoleDeviceConfiguration + + consolePorts map[int]*VirtioConsolePortConfiguration +} + +var _ ConsoleDeviceConfiguration = (*VirtioConsoleDeviceConfiguration)(nil) + +// NewVirtioConsoleDeviceConfiguration creates a new VirtioConsoleDeviceConfiguration. +func NewVirtioConsoleDeviceConfiguration() (*VirtioConsoleDeviceConfiguration, error) { + if err := macOSAvailable(13); err != nil { + return nil, err + } + config := &VirtioConsoleDeviceConfiguration{ + pointer: objc.NewPointer( + C.newVZVirtioConsoleDeviceConfiguration(), + ), + consolePorts: make(map[int]*VirtioConsolePortConfiguration), + } + config.portsPtr = C.portsVZVirtioConsoleDeviceConfiguration(objc.Ptr(config)) + + objc.SetFinalizer(config, func(self *VirtioConsoleDeviceConfiguration) { + objc.Release(self) + }) + return config, nil +} + +// MaximumPortCount returns the maximum number of ports allocated by this device. +// The default is the number of ports attached to this device. +func (v *VirtioConsoleDeviceConfiguration) MaximumPortCount() uint32 { + return uint32(C.maximumPortCountVZVirtioConsolePortConfigurationArray(v.portsPtr)) +} + +func (v *VirtioConsoleDeviceConfiguration) SetVirtioConsolePortConfiguration(idx int, portConfig *VirtioConsolePortConfiguration) { + C.setObjectAtIndexedSubscriptVZVirtioConsolePortConfigurationArray( + v.portsPtr, + objc.Ptr(portConfig), + C.int(idx), + ) + + // to mark as currently reachable. + // This ensures that the object is not freed, and its finalizer is not run + v.consolePorts[idx] = portConfig +} + +type ConsolePortConfiguration interface { + objc.NSObject + + consolePortConfiguration() +} + +type baseConsolePortConfiguration struct{} + +func (*baseConsolePortConfiguration) consolePortConfiguration() {} + +// VirtioConsolePortConfiguration is Virtio Console Port +// +// A console port is a two-way communication channel between a host VZSerialPortAttachment and +// a virtual machine console port. One or more console ports are attached to a Virtio console device. +type VirtioConsolePortConfiguration struct { + *pointer + + *baseConsolePortConfiguration + + isConsole bool + name string + attachment SerialPortAttachment +} + +var _ ConsolePortConfiguration = (*VirtioConsolePortConfiguration)(nil) + +// NewVirtioConsolePortConfigurationOption is an option type to initialize a new VirtioConsolePortConfiguration +type NewVirtioConsolePortConfigurationOption func(*VirtioConsolePortConfiguration) + +// WithVirtioConsolePortConfigurationName sets the console port's name. +// The default behavior is to not use a name unless set. +func WithVirtioConsolePortConfigurationName(name string) NewVirtioConsolePortConfigurationOption { + return func(vcpc *VirtioConsolePortConfiguration) { + consolePortName := charWithGoString(name) + defer consolePortName.Free() + C.setNameVZVirtioConsolePortConfiguration( + objc.Ptr(vcpc), + consolePortName.CString(), + ) + vcpc.name = name + } +} + +// WithVirtioConsolePortConfigurationIsConsole sets the console port may be marked +// for use as the system console. The default is false. +func WithVirtioConsolePortConfigurationIsConsole(isConsole bool) NewVirtioConsolePortConfigurationOption { + return func(vcpc *VirtioConsolePortConfiguration) { + C.setIsConsoleVZVirtioConsolePortConfiguration( + objc.Ptr(vcpc), + C.bool(isConsole), + ) + vcpc.isConsole = isConsole + } +} + +// WithVirtioConsolePortConfigurationAttachment sets the console port attachment. +// The default is nil. +func WithVirtioConsolePortConfigurationAttachment(attachment SerialPortAttachment) NewVirtioConsolePortConfigurationOption { + return func(vcpc *VirtioConsolePortConfiguration) { + C.setAttachmentVZVirtioConsolePortConfiguration( + objc.Ptr(vcpc), + objc.Ptr(attachment), + ) + vcpc.attachment = attachment + } +} + +// NewVirtioConsolePortConfiguration creates a new VirtioConsolePortConfiguration. +// +// This is only supported on macOS 13 and newer, error will +// be returned on older versions. +func NewVirtioConsolePortConfiguration(opts ...NewVirtioConsolePortConfigurationOption) (*VirtioConsolePortConfiguration, error) { + if err := macOSAvailable(13); err != nil { + return nil, err + } + vcpc := &VirtioConsolePortConfiguration{ + pointer: objc.NewPointer( + C.newVZVirtioConsolePortConfiguration(), + ), + } + for _, optFunc := range opts { + optFunc(vcpc) + } + objc.SetFinalizer(vcpc, func(self *VirtioConsolePortConfiguration) { + objc.Release(self) + }) + return vcpc, nil +} + +// Name returns the console port's name. +func (v *VirtioConsolePortConfiguration) Name() string { return v.name } + +// IsConsole returns the console port may be marked for use as the system console. +func (v *VirtioConsolePortConfiguration) IsConsole() bool { return v.isConsole } + +// Attachment returns the console port attachment. +func (v *VirtioConsolePortConfiguration) Attachment() SerialPortAttachment { + return v.attachment +} diff --git a/src/cmd/linuxkit/vendor/github.com/Code-Hex/vz/v3/debug.go b/src/cmd/linuxkit/vendor/github.com/Code-Hex/vz/v3/debug.go new file mode 100644 index 000000000..26d9aeaed --- /dev/null +++ b/src/cmd/linuxkit/vendor/github.com/Code-Hex/vz/v3/debug.go @@ -0,0 +1,65 @@ +//go:build darwin && debug +// +build darwin,debug + +package vz + +/* +#cgo darwin CFLAGS: -mmacosx-version-min=11 -x objective-c -fno-objc-arc +#cgo darwin LDFLAGS: -lobjc -framework Foundation -framework Virtualization +# include "virtualization_debug.h" +*/ +import "C" +import ( + "runtime" + + "github.com/Code-Hex/vz/v3/internal/objc" +) + +// DebugStubConfiguration is an interface to debug configuration. +type DebugStubConfiguration interface { + objc.NSObject + + debugStubConfiguration() +} + +type baseDebugStubConfiguration struct{} + +func (*baseDebugStubConfiguration) debugStubConfiguration() {} + +// GDBDebugStubConfiguration is a configuration for gdb debugging. +type GDBDebugStubConfiguration struct { + *pointer + + *baseDebugStubConfiguration +} + +var _ DebugStubConfiguration = (*GDBDebugStubConfiguration)(nil) + +// NewGDBDebugStubConfiguration creates a new GDB debug confiuration. +// +// This API is not officially published and is subject to change without notice. +// +// This is only supported on macOS 11 and newer, error will +// be returned on older versions. +func NewGDBDebugStubConfiguration(port uint32) (*GDBDebugStubConfiguration, error) { + if err := macOSAvailable(11); err != nil { + return nil, err + } + + config := &GDBDebugStubConfiguration{ + pointer: objc.NewPointer( + C.newVZGDBDebugStubConfiguration(C.uint32_t(port)), + ), + } + objc.SetFinalizer(config, func(self *GDBDebugStubConfiguration) { + objc.Release(self) + }) + return config, nil +} + +// SetDebugStubVirtualMachineConfiguration sets debug stub configuration. Empty by default. +// +// This API is not officially published and is subject to change without notice. +func (v *VirtualMachineConfiguration) SetDebugStubVirtualMachineConfiguration(dc DebugStubConfiguration) { + C.setDebugStubVZVirtualMachineConfiguration(objc.Ptr(v), objc.Ptr(dc)) +} diff --git a/src/cmd/linuxkit/vendor/github.com/Code-Hex/vz/v3/disk.go b/src/cmd/linuxkit/vendor/github.com/Code-Hex/vz/v3/disk.go new file mode 100644 index 000000000..58f947f2e --- /dev/null +++ b/src/cmd/linuxkit/vendor/github.com/Code-Hex/vz/v3/disk.go @@ -0,0 +1,23 @@ +package vz + +import ( + "os" +) + +// CreateDiskImage is creating disk image with specified filename and filesize. +// For example, if you want to create disk with 64GiB, you can set "64 * 1024 * 1024 * 1024" to size. +// +// Note that if you have specified a pathname which already exists, this function +// returns os.ErrExist error. So you can handle it with os.IsExist function. +func CreateDiskImage(pathname string, size int64) error { + f, err := os.OpenFile(pathname, os.O_RDWR|os.O_CREATE|os.O_EXCL, 0600) + if err != nil { + return err + } + defer f.Close() + + if err := f.Truncate(size); err != nil { + return err + } + return nil +} diff --git a/src/cmd/linuxkit/vendor/github.com/Code-Hex/vz/entropy.go b/src/cmd/linuxkit/vendor/github.com/Code-Hex/vz/v3/entropy.go similarity index 56% rename from src/cmd/linuxkit/vendor/github.com/Code-Hex/vz/entropy.go rename to src/cmd/linuxkit/vendor/github.com/Code-Hex/vz/v3/entropy.go index 21b2a343b..68941cd4f 100644 --- a/src/cmd/linuxkit/vendor/github.com/Code-Hex/vz/entropy.go +++ b/src/cmd/linuxkit/vendor/github.com/Code-Hex/vz/v3/entropy.go @@ -1,12 +1,14 @@ package vz /* -#cgo darwin CFLAGS: -x objective-c -fno-objc-arc +#cgo darwin CFLAGS: -mmacosx-version-min=11 -x objective-c -fno-objc-arc #cgo darwin LDFLAGS: -lobjc -framework Foundation -framework Virtualization -# include "virtualization.h" +# include "virtualization_11.h" */ import "C" -import "runtime" +import ( + "github.com/Code-Hex/vz/v3/internal/objc" +) // VirtioEntropyDeviceConfiguration is used to expose a source of entropy for the guest operating system’s random-number generator. // When you create this object and add it to your virtual machine’s configuration, the virtual machine configures a Virtio-compliant @@ -14,18 +16,25 @@ import "runtime" // // see: https://developer.apple.com/documentation/virtualization/vzvirtioentropydeviceconfiguration?language=objc type VirtioEntropyDeviceConfiguration struct { - pointer + *pointer } // NewVirtioEntropyDeviceConfiguration creates a new Virtio Entropy Device confiuration. -func NewVirtioEntropyDeviceConfiguration() *VirtioEntropyDeviceConfiguration { - config := &VirtioEntropyDeviceConfiguration{ - pointer: pointer{ - ptr: C.newVZVirtioEntropyDeviceConfiguration(), - }, +// +// This is only supported on macOS 11 and newer, error will +// be returned on older versions. +func NewVirtioEntropyDeviceConfiguration() (*VirtioEntropyDeviceConfiguration, error) { + if err := macOSAvailable(11); err != nil { + return nil, err } - runtime.SetFinalizer(config, func(self *VirtioEntropyDeviceConfiguration) { - self.Release() + + config := &VirtioEntropyDeviceConfiguration{ + pointer: objc.NewPointer( + C.newVZVirtioEntropyDeviceConfiguration(), + ), + } + objc.SetFinalizer(config, func(self *VirtioEntropyDeviceConfiguration) { + objc.Release(self) }) - return config + return config, nil } diff --git a/src/cmd/linuxkit/vendor/github.com/Code-Hex/vz/v3/errorcode_string.go b/src/cmd/linuxkit/vendor/github.com/Code-Hex/vz/v3/errorcode_string.go new file mode 100644 index 000000000..08b3b3d1c --- /dev/null +++ b/src/cmd/linuxkit/vendor/github.com/Code-Hex/vz/v3/errorcode_string.go @@ -0,0 +1,51 @@ +// Code generated by "stringer -type=ErrorCode"; DO NOT EDIT. + +package vz + +import "strconv" + +func _() { + // An "invalid array index" compiler error signifies that the constant values have changed. + // Re-run the stringer command to generate them again. + var x [1]struct{} + _ = x[ErrorInternal-1] + _ = x[ErrorInvalidVirtualMachineConfiguration-2] + _ = x[ErrorInvalidVirtualMachineState-3] + _ = x[ErrorInvalidVirtualMachineStateTransition-4] + _ = x[ErrorInvalidDiskImage-5] + _ = x[ErrorVirtualMachineLimitExceeded-6] + _ = x[ErrorNetworkError-7] + _ = x[ErrorOutOfDiskSpace-8] + _ = x[ErrorOperationCancelled-9] + _ = x[ErrorNotSupported-10] + _ = x[ErrorRestoreImageCatalogLoadFailed-10001] + _ = x[ErrorInvalidRestoreImageCatalog-10002] + _ = x[ErrorNoSupportedRestoreImagesInCatalog-10003] + _ = x[ErrorRestoreImageLoadFailed-10004] + _ = x[ErrorInvalidRestoreImage-10005] + _ = x[ErrorInstallationRequiresUpdate-10006] + _ = x[ErrorInstallationFailed-10007] +} + +const ( + _ErrorCode_name_0 = "ErrorInternalErrorInvalidVirtualMachineConfigurationErrorInvalidVirtualMachineStateErrorInvalidVirtualMachineStateTransitionErrorInvalidDiskImageErrorVirtualMachineLimitExceededErrorNetworkErrorErrorOutOfDiskSpaceErrorOperationCancelledErrorNotSupported" + _ErrorCode_name_1 = "ErrorRestoreImageCatalogLoadFailedErrorInvalidRestoreImageCatalogErrorNoSupportedRestoreImagesInCatalogErrorRestoreImageLoadFailedErrorInvalidRestoreImageErrorInstallationRequiresUpdateErrorInstallationFailed" +) + +var ( + _ErrorCode_index_0 = [...]uint8{0, 13, 52, 83, 124, 145, 177, 194, 213, 236, 253} + _ErrorCode_index_1 = [...]uint8{0, 34, 65, 103, 130, 154, 185, 208} +) + +func (i ErrorCode) String() string { + switch { + case 1 <= i && i <= 10: + i -= 1 + return _ErrorCode_name_0[_ErrorCode_index_0[i]:_ErrorCode_index_0[i+1]] + case 10001 <= i && i <= 10007: + i -= 10001 + return _ErrorCode_name_1[_ErrorCode_index_1[i]:_ErrorCode_index_1[i+1]] + default: + return "ErrorCode(" + strconv.FormatInt(int64(i), 10) + ")" + } +} diff --git a/src/cmd/linuxkit/vendor/github.com/Code-Hex/vz/v3/graphics.go b/src/cmd/linuxkit/vendor/github.com/Code-Hex/vz/v3/graphics.go new file mode 100644 index 000000000..5126667fc --- /dev/null +++ b/src/cmd/linuxkit/vendor/github.com/Code-Hex/vz/v3/graphics.go @@ -0,0 +1,98 @@ +package vz + +/* +#cgo darwin CFLAGS: -mmacosx-version-min=11 -x objective-c -fno-objc-arc +#cgo darwin LDFLAGS: -lobjc -framework Foundation -framework Virtualization +# include "virtualization_13.h" +*/ +import "C" +import ( + "github.com/Code-Hex/vz/v3/internal/objc" +) + +// GraphicsDeviceConfiguration is an interface for a graphics device configuration. +type GraphicsDeviceConfiguration interface { + objc.NSObject + + graphicsDeviceConfiguration() +} + +type baseGraphicsDeviceConfiguration struct{} + +func (*baseGraphicsDeviceConfiguration) graphicsDeviceConfiguration() {} + +// VirtioGraphicsDeviceConfiguration is configuration that represents the configuration +// of a Virtio graphics device for a Linux VM. +// +// This device configuration creates a graphics device using paravirtualization. +// The emulated device follows the Virtio GPU Device specification. +// +// see: https://developer.apple.com/documentation/virtualization/vzvirtiographicsdeviceconfiguration?language=objc +type VirtioGraphicsDeviceConfiguration struct { + *pointer + + *baseGraphicsDeviceConfiguration +} + +var _ GraphicsDeviceConfiguration = (*VirtioGraphicsDeviceConfiguration)(nil) + +// NewVirtioGraphicsDeviceConfiguration creates a new Virtio graphics device. +// +// This is only supported on macOS 13 and newer, error will +// be returned on older versions. +func NewVirtioGraphicsDeviceConfiguration() (*VirtioGraphicsDeviceConfiguration, error) { + if err := macOSAvailable(13); err != nil { + return nil, err + } + graphicsConfiguration := &VirtioGraphicsDeviceConfiguration{ + pointer: objc.NewPointer( + C.newVZVirtioGraphicsDeviceConfiguration(), + ), + } + objc.SetFinalizer(graphicsConfiguration, func(self *VirtioGraphicsDeviceConfiguration) { + objc.Release(self) + }) + return graphicsConfiguration, nil +} + +// SetScanouts sets the displays associated with this graphics device. +// +// Maximum of one scanout is supported. +func (v *VirtioGraphicsDeviceConfiguration) SetScanouts(scanoutConfigs ...*VirtioGraphicsScanoutConfiguration) { + ptrs := make([]objc.NSObject, len(scanoutConfigs)) + for i, val := range scanoutConfigs { + ptrs[i] = val + } + array := objc.ConvertToNSMutableArray(ptrs) + C.setScanoutsVZVirtioGraphicsDeviceConfiguration(objc.Ptr(v), objc.Ptr(array)) +} + +// VirtioGraphicsScanoutConfiguration is the configuration for a Virtio graphics device +// that configures the dimensions of the graphics device for a Linux VM. +// see: https://developer.apple.com/documentation/virtualization/vzvirtiographicsscanoutconfiguration?language=objc +type VirtioGraphicsScanoutConfiguration struct { + *pointer +} + +// NewVirtioGraphicsScanoutConfiguration creates a Virtio graphics device with the specified dimensions. +// +// This is only supported on macOS 13 and newer, error will +// be returned on older versions. +func NewVirtioGraphicsScanoutConfiguration(widthInPixels int64, heightInPixels int64) (*VirtioGraphicsScanoutConfiguration, error) { + if err := macOSAvailable(13); err != nil { + return nil, err + } + + graphicsScanoutConfiguration := &VirtioGraphicsScanoutConfiguration{ + pointer: objc.NewPointer( + C.newVZVirtioGraphicsScanoutConfiguration( + C.NSInteger(widthInPixels), + C.NSInteger(heightInPixels), + ), + ), + } + objc.SetFinalizer(graphicsScanoutConfiguration, func(self *VirtioGraphicsScanoutConfiguration) { + objc.Release(self) + }) + return graphicsScanoutConfiguration, nil +} diff --git a/src/cmd/linuxkit/vendor/github.com/Code-Hex/vz/v3/graphics_arm64.go b/src/cmd/linuxkit/vendor/github.com/Code-Hex/vz/v3/graphics_arm64.go new file mode 100644 index 000000000..dbeaed606 --- /dev/null +++ b/src/cmd/linuxkit/vendor/github.com/Code-Hex/vz/v3/graphics_arm64.go @@ -0,0 +1,84 @@ +//go:build darwin && arm64 +// +build darwin,arm64 + +package vz + +/* +#cgo darwin CFLAGS: -mmacosx-version-min=11 -x objective-c -fno-objc-arc +#cgo darwin LDFLAGS: -lobjc -framework Foundation -framework Virtualization +# include "virtualization_12_arm64.h" +*/ +import "C" +import ( + "github.com/Code-Hex/vz/v3/internal/objc" +) + +// MacGraphicsDeviceConfiguration is a configuration for a display attached to a Mac graphics device. +type MacGraphicsDeviceConfiguration struct { + *pointer + + *baseGraphicsDeviceConfiguration +} + +var _ GraphicsDeviceConfiguration = (*MacGraphicsDeviceConfiguration)(nil) + +// NewMacGraphicsDeviceConfiguration creates a new MacGraphicsDeviceConfiguration. +// +// This is only supported on macOS 12 and newer, error will +// be returned on older versions. +func NewMacGraphicsDeviceConfiguration() (*MacGraphicsDeviceConfiguration, error) { + if err := macOSAvailable(12); err != nil { + return nil, err + } + + graphicsConfiguration := &MacGraphicsDeviceConfiguration{ + pointer: objc.NewPointer( + C.newVZMacGraphicsDeviceConfiguration(), + ), + } + objc.SetFinalizer(graphicsConfiguration, func(self *MacGraphicsDeviceConfiguration) { + objc.Release(self) + }) + return graphicsConfiguration, nil +} + +// SetDisplays sets the displays associated with this graphics device. +func (m *MacGraphicsDeviceConfiguration) SetDisplays(displayConfigs ...*MacGraphicsDisplayConfiguration) { + ptrs := make([]objc.NSObject, len(displayConfigs)) + for i, val := range displayConfigs { + ptrs[i] = val + } + array := objc.ConvertToNSMutableArray(ptrs) + C.setDisplaysVZMacGraphicsDeviceConfiguration(objc.Ptr(m), objc.Ptr(array)) +} + +// MacGraphicsDisplayConfiguration is the configuration for a Mac graphics device. +type MacGraphicsDisplayConfiguration struct { + *pointer +} + +// NewMacGraphicsDisplayConfiguration creates a new MacGraphicsDisplayConfiguration. +// +// Creates a display configuration with the specified pixel dimensions and pixel density. +// +// This is only supported on macOS 12 and newer, error will +// be returned on older versions. +func NewMacGraphicsDisplayConfiguration(widthInPixels int64, heightInPixels int64, pixelsPerInch int64) (*MacGraphicsDisplayConfiguration, error) { + if err := macOSAvailable(12); err != nil { + return nil, err + } + + graphicsDisplayConfiguration := &MacGraphicsDisplayConfiguration{ + pointer: objc.NewPointer( + C.newVZMacGraphicsDisplayConfiguration( + C.NSInteger(widthInPixels), + C.NSInteger(heightInPixels), + C.NSInteger(pixelsPerInch), + ), + ), + } + objc.SetFinalizer(graphicsDisplayConfiguration, func(self *MacGraphicsDisplayConfiguration) { + objc.Release(self) + }) + return graphicsDisplayConfiguration, nil +} diff --git a/src/cmd/linuxkit/vendor/github.com/Code-Hex/vz/v3/internal/objc/finalizer.go b/src/cmd/linuxkit/vendor/github.com/Code-Hex/vz/v3/internal/objc/finalizer.go new file mode 100644 index 000000000..f9dfd69f0 --- /dev/null +++ b/src/cmd/linuxkit/vendor/github.com/Code-Hex/vz/v3/internal/objc/finalizer.go @@ -0,0 +1,10 @@ +//go:build !go1.18 +// +build !go1.18 + +package objc + +import "runtime" + +func SetFinalizer(obj interface{}, finalizer interface{}) { + runtime.SetFinalizer(obj, finalizer) +} diff --git a/src/cmd/linuxkit/vendor/github.com/Code-Hex/vz/v3/internal/objc/finalizer_118.go b/src/cmd/linuxkit/vendor/github.com/Code-Hex/vz/v3/internal/objc/finalizer_118.go new file mode 100644 index 000000000..9ebeca78d --- /dev/null +++ b/src/cmd/linuxkit/vendor/github.com/Code-Hex/vz/v3/internal/objc/finalizer_118.go @@ -0,0 +1,10 @@ +//go:build go1.18 +// +build go1.18 + +package objc + +import "runtime" + +func SetFinalizer[T any](obj T, finalizer func(T)) { + runtime.SetFinalizer(obj, finalizer) +} diff --git a/src/cmd/linuxkit/vendor/github.com/Code-Hex/vz/v3/internal/objc/objc.go b/src/cmd/linuxkit/vendor/github.com/Code-Hex/vz/v3/internal/objc/objc.go new file mode 100644 index 000000000..3610cce4f --- /dev/null +++ b/src/cmd/linuxkit/vendor/github.com/Code-Hex/vz/v3/internal/objc/objc.go @@ -0,0 +1,160 @@ +package objc + +/* +#cgo darwin CFLAGS: -mmacosx-version-min=11 -x objective-c +#cgo darwin LDFLAGS: -lobjc -framework Foundation +#import + +void *makeNSMutableArray(unsigned long cap) +{ + return [[NSMutableArray alloc] initWithCapacity:(NSUInteger)cap]; +} + +void addNSMutableArrayVal(void *ary, void *val) +{ + [(NSMutableArray *)ary addObject:(NSObject *)val]; +} + +void *makeNSMutableDictionary() +{ + return [[NSMutableDictionary alloc] init]; +} + +void insertNSMutableDictionary(void *dict, char *key, void *val) +{ + NSString *nskey = [NSString stringWithUTF8String: key]; + [(NSMutableDictionary *)dict setValue:(NSObject *)val forKey:nskey]; +} + +void releaseNSObject(void* o) +{ + @autoreleasepool { + [(NSObject*)o release]; + } +} + +static inline void releaseDispatch(void *queue) +{ + dispatch_release((dispatch_queue_t)queue); +} + +int getNSArrayCount(void *ptr) +{ + return (int)[(NSArray*)ptr count]; +} + +void* getNSArrayItem(void *ptr, int i) +{ + NSArray *arr = (NSArray *)ptr; + return [arr objectAtIndex:i]; +} + +const char *getUUID() +{ + NSString *uuid = [[NSUUID UUID] UUIDString]; + return [uuid UTF8String]; +} +*/ +import "C" +import ( + "runtime" + "unsafe" +) + +// ReleaseDispatch releases allocated dispatch_queue_t +func ReleaseDispatch(p unsafe.Pointer) { + C.releaseDispatch(p) +} + +// Pointer indicates any pointers which are allocated in objective-c world. +type Pointer struct { + _ptr unsafe.Pointer +} + +// NewPointer creates a new Pointer for objc +func NewPointer(p unsafe.Pointer) *Pointer { + return &Pointer{_ptr: p} +} + +// release releases allocated resources in objective-c world. +func (p *Pointer) release() { + C.releaseNSObject(p._ptr) + runtime.KeepAlive(p) +} + +// Ptr returns raw pointer. +func (o *Pointer) ptr() unsafe.Pointer { + if o == nil { + return nil + } + return o._ptr +} + +// NSObject indicates NSObject +type NSObject interface { + ptr() unsafe.Pointer + release() +} + +// Release releases allocated resources in objective-c world. +func Release(o NSObject) { + o.release() +} + +// Ptr returns unsafe.Pointer of the NSObject +func Ptr(o NSObject) unsafe.Pointer { + return o.ptr() +} + +// NSArray indicates NSArray +type NSArray struct { + *Pointer +} + +// NewNSArray creates a new NSArray from pointer. +func NewNSArray(p unsafe.Pointer) *NSArray { + return &NSArray{NewPointer(p)} +} + +// ToPointerSlice method returns slice of the obj-c object as unsafe.Pointer. +func (n *NSArray) ToPointerSlice() []unsafe.Pointer { + count := int(C.getNSArrayCount(n.ptr())) + ret := make([]unsafe.Pointer, count) + for i := 0; i < count; i++ { + ret[i] = C.getNSArrayItem(n.ptr(), C.int(i)) + } + return ret +} + +// ConvertToNSMutableArray converts to NSMutableArray from NSObject slice in Go world. +func ConvertToNSMutableArray(s []NSObject) *Pointer { + ln := len(s) + ary := C.makeNSMutableArray(C.ulong(ln)) + for _, v := range s { + C.addNSMutableArrayVal(ary, v.ptr()) + } + p := NewPointer(ary) + runtime.SetFinalizer(p, func(self *Pointer) { + self.release() + }) + return p +} + +// ConvertToNSMutableDictionary converts to NSMutableDictionary from map[string]NSObject in Go world. +func ConvertToNSMutableDictionary(d map[string]NSObject) *Pointer { + dict := C.makeNSMutableDictionary() + for key, value := range d { + cs := (*C.char)(C.CString(key)) + C.insertNSMutableDictionary(dict, cs, value.ptr()) + C.free(unsafe.Pointer(cs)) + } + p := NewPointer(dict) + runtime.SetFinalizer(p, func(self *Pointer) { + self.release() + }) + return p +} + +func GetUUID() *C.char { + return C.getUUID() +} diff --git a/src/cmd/linuxkit/vendor/github.com/Code-Hex/vz/v3/internal/progress/reader.go b/src/cmd/linuxkit/vendor/github.com/Code-Hex/vz/v3/internal/progress/reader.go new file mode 100644 index 000000000..ebd9836b8 --- /dev/null +++ b/src/cmd/linuxkit/vendor/github.com/Code-Hex/vz/v3/internal/progress/reader.go @@ -0,0 +1,62 @@ +package progress + +import ( + "io" + "sync" + "sync/atomic" +) + +// Reader is an io.Reader for checking progress. +type Reader struct { + once sync.Once + + reader io.Reader + total int64 + current int64 + finish chan struct{} + err error +} + +// NewReader create a new io.Reader for checking progress. +func NewReader(rd io.Reader, total, current int64) *Reader { + return &Reader{ + reader: rd, + total: total, + current: current, + finish: make(chan struct{}), + } +} + +var _ io.Reader = (*Reader)(nil) + +// Finish finishes the progress check operation. +func (r *Reader) Finish(err error) { + r.once.Do(func() { + r.err = err + close(r.finish) + }) +} + +// Err returns err. +func (r *Reader) Err() error { return r.err } + +// Finish sends notification when finished any progress. +func (r *Reader) Finished() <-chan struct{} { return r.finish } + +// FractionCompleted returns the fraction of the overall work completed by this progress struct, +// including work done by any children it may have. +func (r *Reader) FractionCompleted() float64 { + return float64(r.Current()) / float64(r.total) +} + +func (r *Reader) Current() int64 { + return atomic.LoadInt64(&r.current) +} + +// Read reads data using underlying io.Reader. +// The number of bytes read is added to the current progress status. +func (r *Reader) Read(p []byte) (n int, err error) { + n, err = r.reader.Read(p) + atomic.AddInt64(&r.current, int64(n)) + return +} diff --git a/src/cmd/linuxkit/vendor/github.com/Code-Hex/vz/v3/keyboard.go b/src/cmd/linuxkit/vendor/github.com/Code-Hex/vz/v3/keyboard.go new file mode 100644 index 000000000..f1627e0ac --- /dev/null +++ b/src/cmd/linuxkit/vendor/github.com/Code-Hex/vz/v3/keyboard.go @@ -0,0 +1,49 @@ +package vz + +/* +#cgo darwin CFLAGS: -mmacosx-version-min=11 -x objective-c -fno-objc-arc +#cgo darwin LDFLAGS: -lobjc -framework Foundation -framework Virtualization +# include "virtualization_11.h" +# include "virtualization_12.h" +*/ +import "C" +import ( + "github.com/Code-Hex/vz/v3/internal/objc" +) + +// KeyboardConfiguration interface for a keyboard configuration. +type KeyboardConfiguration interface { + objc.NSObject + + keyboardConfiguration() +} + +type baseKeyboardConfiguration struct{} + +func (*baseKeyboardConfiguration) keyboardConfiguration() {} + +// USBKeyboardConfiguration is a device that defines the configuration for a USB keyboard. +type USBKeyboardConfiguration struct { + *pointer + + *baseKeyboardConfiguration +} + +var _ KeyboardConfiguration = (*USBKeyboardConfiguration)(nil) + +// NewUSBKeyboardConfiguration creates a new USB keyboard configuration. +// +// This is only supported on macOS 12 and newer, error will +// be returned on older versions. +func NewUSBKeyboardConfiguration() (*USBKeyboardConfiguration, error) { + if err := macOSAvailable(12); err != nil { + return nil, err + } + config := &USBKeyboardConfiguration{ + pointer: objc.NewPointer(C.newVZUSBKeyboardConfiguration()), + } + objc.SetFinalizer(config, func(self *USBKeyboardConfiguration) { + objc.Release(self) + }) + return config, nil +} diff --git a/src/cmd/linuxkit/vendor/github.com/Code-Hex/vz/v3/linuxrosettaavailability_string_arm64.go b/src/cmd/linuxkit/vendor/github.com/Code-Hex/vz/v3/linuxrosettaavailability_string_arm64.go new file mode 100644 index 000000000..f64cadb59 --- /dev/null +++ b/src/cmd/linuxkit/vendor/github.com/Code-Hex/vz/v3/linuxrosettaavailability_string_arm64.go @@ -0,0 +1,28 @@ +//go:build darwin && arm64 +// +build darwin,arm64 + +// Code generated by "stringer -type=LinuxRosettaAvailability -output=linuxrosettaavailability_string_arm64.go"; DO NOT EDIT. + +package vz + +import "strconv" + +func _() { + // An "invalid array index" compiler error signifies that the constant values have changed. + // Re-run the stringer command to generate them again. + var x [1]struct{} + _ = x[LinuxRosettaAvailabilityNotSupported-0] + _ = x[LinuxRosettaAvailabilityNotInstalled-1] + _ = x[LinuxRosettaAvailabilityInstalled-2] +} + +const _LinuxRosettaAvailability_name = "LinuxRosettaAvailabilityNotSupportedLinuxRosettaAvailabilityNotInstalledLinuxRosettaAvailabilityInstalled" + +var _LinuxRosettaAvailability_index = [...]uint8{0, 36, 72, 105} + +func (i LinuxRosettaAvailability) String() string { + if i < 0 || i >= LinuxRosettaAvailability(len(_LinuxRosettaAvailability_index)-1) { + return "LinuxRosettaAvailability(" + strconv.FormatInt(int64(i), 10) + ")" + } + return _LinuxRosettaAvailability_name[_LinuxRosettaAvailability_index[i]:_LinuxRosettaAvailability_index[i+1]] +} diff --git a/src/cmd/linuxkit/vendor/github.com/Code-Hex/vz/memory_balloon.go b/src/cmd/linuxkit/vendor/github.com/Code-Hex/vz/v3/memory_balloon.go similarity index 60% rename from src/cmd/linuxkit/vendor/github.com/Code-Hex/vz/memory_balloon.go rename to src/cmd/linuxkit/vendor/github.com/Code-Hex/vz/v3/memory_balloon.go index 5315ba6b7..5a8a2d6cb 100644 --- a/src/cmd/linuxkit/vendor/github.com/Code-Hex/vz/memory_balloon.go +++ b/src/cmd/linuxkit/vendor/github.com/Code-Hex/vz/v3/memory_balloon.go @@ -1,16 +1,18 @@ package vz /* -#cgo darwin CFLAGS: -x objective-c -fno-objc-arc +#cgo darwin CFLAGS: -mmacosx-version-min=11 -x objective-c -fno-objc-arc #cgo darwin LDFLAGS: -lobjc -framework Foundation -framework Virtualization -# include "virtualization.h" +# include "virtualization_11.h" */ import "C" -import "runtime" +import ( + "github.com/Code-Hex/vz/v3/internal/objc" +) // MemoryBalloonDeviceConfiguration for a memory balloon device configuration. type MemoryBalloonDeviceConfiguration interface { - NSObject + objc.NSObject memoryBalloonDeviceConfiguration() } @@ -25,20 +27,27 @@ var _ MemoryBalloonDeviceConfiguration = (*VirtioTraditionalMemoryBalloonDeviceC // // see: https://developer.apple.com/documentation/virtualization/vzvirtiotraditionalmemoryballoondeviceconfiguration?language=objc type VirtioTraditionalMemoryBalloonDeviceConfiguration struct { - pointer + *pointer *baseMemoryBalloonDeviceConfiguration } // NewVirtioTraditionalMemoryBalloonDeviceConfiguration creates a new VirtioTraditionalMemoryBalloonDeviceConfiguration. -func NewVirtioTraditionalMemoryBalloonDeviceConfiguration() *VirtioTraditionalMemoryBalloonDeviceConfiguration { - config := &VirtioTraditionalMemoryBalloonDeviceConfiguration{ - pointer: pointer{ - ptr: C.newVZVirtioTraditionalMemoryBalloonDeviceConfiguration(), - }, +// +// This is only supported on macOS 11 and newer, error will +// be returned on older versions. +func NewVirtioTraditionalMemoryBalloonDeviceConfiguration() (*VirtioTraditionalMemoryBalloonDeviceConfiguration, error) { + if err := macOSAvailable(11); err != nil { + return nil, err } - runtime.SetFinalizer(config, func(self *VirtioTraditionalMemoryBalloonDeviceConfiguration) { - self.Release() + + config := &VirtioTraditionalMemoryBalloonDeviceConfiguration{ + pointer: objc.NewPointer( + C.newVZVirtioTraditionalMemoryBalloonDeviceConfiguration(), + ), + } + objc.SetFinalizer(config, func(self *VirtioTraditionalMemoryBalloonDeviceConfiguration) { + objc.Release(self) }) - return config + return config, nil } diff --git a/src/cmd/linuxkit/vendor/github.com/Code-Hex/vz/network.go b/src/cmd/linuxkit/vendor/github.com/Code-Hex/vz/v3/network.go similarity index 51% rename from src/cmd/linuxkit/vendor/github.com/Code-Hex/vz/network.go rename to src/cmd/linuxkit/vendor/github.com/Code-Hex/vz/v3/network.go index d2ae03673..fbfcee272 100644 --- a/src/cmd/linuxkit/vendor/github.com/Code-Hex/vz/network.go +++ b/src/cmd/linuxkit/vendor/github.com/Code-Hex/vz/v3/network.go @@ -1,15 +1,20 @@ package vz /* -#cgo darwin CFLAGS: -x objective-c -fno-objc-arc +#cgo darwin CFLAGS: -mmacosx-version-min=11 -x objective-c -fno-objc-arc #cgo darwin LDFLAGS: -lobjc -framework Foundation -framework Virtualization -# include "virtualization.h" +# include "virtualization_11.h" +# include "virtualization_13.h" */ import "C" import ( + "fmt" "net" "os" - "runtime" + "syscall" + "unsafe" + + "github.com/Code-Hex/vz/v3/internal/objc" ) // BridgedNetwork defines a network interface that bridges a physical interface with a virtual machine. @@ -21,7 +26,7 @@ import ( // TODO(codehex): implement... // see: https://developer.apple.com/documentation/virtualization/vzbridgednetworkinterface?language=objc type BridgedNetwork interface { - NSObject + objc.NSObject // NetworkInterfaces returns the list of network interfaces available for bridging. NetworkInterfaces() []BridgedNetwork @@ -40,7 +45,7 @@ type BridgedNetwork interface { // for accesses to outside networks. // see: https://developer.apple.com/documentation/virtualization/vznatnetworkdeviceattachment?language=objc type NATNetworkDeviceAttachment struct { - pointer + *pointer *baseNetworkDeviceAttachment } @@ -48,16 +53,21 @@ type NATNetworkDeviceAttachment struct { var _ NetworkDeviceAttachment = (*NATNetworkDeviceAttachment)(nil) // NewNATNetworkDeviceAttachment creates a new NATNetworkDeviceAttachment. -func NewNATNetworkDeviceAttachment() *NATNetworkDeviceAttachment { - attachment := &NATNetworkDeviceAttachment{ - pointer: pointer{ - ptr: C.newVZNATNetworkDeviceAttachment(), - }, +// +// This is only supported on macOS 11 and newer, error will +// be returned on older versions. +func NewNATNetworkDeviceAttachment() (*NATNetworkDeviceAttachment, error) { + if err := macOSAvailable(11); err != nil { + return nil, err } - runtime.SetFinalizer(attachment, func(self *NATNetworkDeviceAttachment) { - self.Release() + + attachment := &NATNetworkDeviceAttachment{ + pointer: objc.NewPointer(C.newVZNATNetworkDeviceAttachment()), + } + objc.SetFinalizer(attachment, func(self *NATNetworkDeviceAttachment) { + objc.Release(self) }) - return attachment + return attachment, nil } // BridgedNetworkDeviceAttachment represents a physical interface on the host computer. @@ -71,7 +81,7 @@ func NewNATNetworkDeviceAttachment() *NATNetworkDeviceAttachment { // // see: https://developer.apple.com/documentation/virtualization/vzbridgednetworkdeviceattachment?language=objc type BridgedNetworkDeviceAttachment struct { - pointer + *pointer *baseNetworkDeviceAttachment } @@ -79,18 +89,25 @@ type BridgedNetworkDeviceAttachment struct { var _ NetworkDeviceAttachment = (*BridgedNetworkDeviceAttachment)(nil) // NewBridgedNetworkDeviceAttachment creates a new BridgedNetworkDeviceAttachment with networkInterface. -func NewBridgedNetworkDeviceAttachment(networkInterface BridgedNetwork) *BridgedNetworkDeviceAttachment { - attachment := &BridgedNetworkDeviceAttachment{ - pointer: pointer{ - ptr: C.newVZBridgedNetworkDeviceAttachment( - networkInterface.Ptr(), - ), - }, +// +// This is only supported on macOS 11 and newer, error will +// be returned on older versions. +func NewBridgedNetworkDeviceAttachment(networkInterface BridgedNetwork) (*BridgedNetworkDeviceAttachment, error) { + if err := macOSAvailable(11); err != nil { + return nil, err } - runtime.SetFinalizer(attachment, func(self *BridgedNetworkDeviceAttachment) { - self.Release() + + attachment := &BridgedNetworkDeviceAttachment{ + pointer: objc.NewPointer( + C.newVZBridgedNetworkDeviceAttachment( + objc.Ptr(networkInterface), + ), + ), + } + objc.SetFinalizer(attachment, func(self *BridgedNetworkDeviceAttachment) { + objc.Release(self) }) - return attachment + return attachment, nil } // FileHandleNetworkDeviceAttachment sending raw network packets over a file handle. @@ -99,9 +116,11 @@ func NewBridgedNetworkDeviceAttachment(networkInterface BridgedNetwork) *Bridged // The data transmitted through this attachment is at the level of the data link layer. // see: https://developer.apple.com/documentation/virtualization/vzfilehandlenetworkdeviceattachment?language=objc type FileHandleNetworkDeviceAttachment struct { - pointer + *pointer *baseNetworkDeviceAttachment + + mtu int } var _ NetworkDeviceAttachment = (*FileHandleNetworkDeviceAttachment)(nil) @@ -109,24 +128,90 @@ var _ NetworkDeviceAttachment = (*FileHandleNetworkDeviceAttachment)(nil) // NewFileHandleNetworkDeviceAttachment initialize the attachment with a file handle. // // file parameter is holding a connected datagram socket. -func NewFileHandleNetworkDeviceAttachment(file *os.File) *FileHandleNetworkDeviceAttachment { +// +// This is only supported on macOS 11 and newer, error will +// be returned on older versions. +func NewFileHandleNetworkDeviceAttachment(file *os.File) (*FileHandleNetworkDeviceAttachment, error) { + if err := macOSAvailable(11); err != nil { + return nil, err + } + err := validateDatagramSocket(int(file.Fd())) + if err != nil { + return nil, err + } + attachment := &FileHandleNetworkDeviceAttachment{ - pointer: pointer{ - ptr: C.newVZFileHandleNetworkDeviceAttachment( + pointer: objc.NewPointer( + C.newVZFileHandleNetworkDeviceAttachment( C.int(file.Fd()), ), - }, + ), + mtu: 1500, // The default MTU is 1500. } - runtime.SetFinalizer(attachment, func(self *FileHandleNetworkDeviceAttachment) { - self.Release() + objc.SetFinalizer(attachment, func(self *FileHandleNetworkDeviceAttachment) { + objc.Release(self) }) - return attachment + return attachment, nil +} + +func validateDatagramSocket(fd int) error { + sotype, err := syscall.GetsockoptInt( + fd, + syscall.SOL_SOCKET, + syscall.SO_TYPE, + ) + if err != nil { + return os.NewSyscallError("getsockopt", err) + } + if sotype == syscall.SOCK_DGRAM && isAvailableDatagram(fd) { + return nil + } + return fmt.Errorf("The fileHandle must be a datagram socket") +} + +func isAvailableDatagram(fd int) bool { + lsa, _ := syscall.Getsockname(fd) + switch lsa.(type) { + case *syscall.SockaddrInet4, *syscall.SockaddrInet6, *syscall.SockaddrUnix: + return true + } + return false +} + +// SetMaximumTransmissionUnit sets the maximum transmission unit (MTU) associated with this attachment. +// +// The maximum MTU allowed is 65535, and the minimum MTU allowed is 1500. An invalid MTU value will result in an invalid +// virtual machine configuration. +// +// The client side of the associated datagram socket must be properly configured with the appropriate values +// for SO_SNDBUF, and SO_RCVBUF. Set these using the setsockopt(_:_:_:_:_:) system call. The system expects +// the value of SO_RCVBUF to be at least double the value of SO_SNDBUF, and for optimal performance, the +// recommended value of SO_RCVBUF is four times the value of SO_SNDBUF. +// +// This is only supported on macOS 13 and newer, error will +// be returned on older versions. +func (f *FileHandleNetworkDeviceAttachment) SetMaximumTransmissionUnit(mtu int) error { + if err := macOSAvailable(13); err != nil { + return err + } + C.setMaximumTransmissionUnitVZFileHandleNetworkDeviceAttachment( + objc.Ptr(f), + C.NSInteger(mtu), + ) + f.mtu = mtu + return nil +} + +// MaximumTransmissionUnit returns the maximum transmission unit (MTU) associated with this attachment. +// The default MTU is 1500. +func (f *FileHandleNetworkDeviceAttachment) MaximumTransmissionUnit() int { + return f.mtu } // NetworkDeviceAttachment for a network device attachment. // see: https://developer.apple.com/documentation/virtualization/vznetworkdeviceattachment?language=objc type NetworkDeviceAttachment interface { - NSObject + objc.NSObject networkDeviceAttachment() } @@ -144,64 +229,89 @@ func (*baseNetworkDeviceAttachment) networkDeviceAttachment() {} // // see: https://developer.apple.com/documentation/virtualization/vzvirtionetworkdeviceconfiguration?language=objc type VirtioNetworkDeviceConfiguration struct { - pointer + *pointer } // NewVirtioNetworkDeviceConfiguration creates a new VirtioNetworkDeviceConfiguration with NetworkDeviceAttachment. -func NewVirtioNetworkDeviceConfiguration(attachment NetworkDeviceAttachment) *VirtioNetworkDeviceConfiguration { - config := &VirtioNetworkDeviceConfiguration{ - pointer: pointer{ - ptr: C.newVZVirtioNetworkDeviceConfiguration( - attachment.Ptr(), - ), - }, +// +// This is only supported on macOS 11 and newer, error will +// be returned on older versions. +func NewVirtioNetworkDeviceConfiguration(attachment NetworkDeviceAttachment) (*VirtioNetworkDeviceConfiguration, error) { + if err := macOSAvailable(11); err != nil { + return nil, err } - runtime.SetFinalizer(config, func(self *VirtioNetworkDeviceConfiguration) { - self.Release() + + config := newVirtioNetworkDeviceConfiguration( + C.newVZVirtioNetworkDeviceConfiguration( + objc.Ptr(attachment), + ), + ) + objc.SetFinalizer(config, func(self *VirtioNetworkDeviceConfiguration) { + objc.Release(self) }) - return config + return config, nil } -func (v *VirtioNetworkDeviceConfiguration) SetMacAddress(macAddress *MACAddress) { - C.setNetworkDevicesVZMACAddress(v.Ptr(), macAddress.Ptr()) +func newVirtioNetworkDeviceConfiguration(ptr unsafe.Pointer) *VirtioNetworkDeviceConfiguration { + return &VirtioNetworkDeviceConfiguration{ + pointer: objc.NewPointer(ptr), + } +} + +func (v *VirtioNetworkDeviceConfiguration) SetMACAddress(macAddress *MACAddress) { + C.setNetworkDevicesVZMACAddress(objc.Ptr(v), objc.Ptr(macAddress)) } // MACAddress represents a media access control address (MAC address), the 48-bit ethernet address. // see: https://developer.apple.com/documentation/virtualization/vzmacaddress?language=objc type MACAddress struct { - pointer + *pointer } // NewMACAddress creates a new MACAddress with net.HardwareAddr (MAC address). -func NewMACAddress(macAddr net.HardwareAddr) *MACAddress { +// +// This is only supported on macOS 11 and newer, error will +// be returned on older versions. +func NewMACAddress(macAddr net.HardwareAddr) (*MACAddress, error) { + if err := macOSAvailable(11); err != nil { + return nil, err + } + macAddrChar := charWithGoString(macAddr.String()) defer macAddrChar.Free() ma := &MACAddress{ - pointer: pointer{ - ptr: C.newVZMACAddress(macAddrChar.CString()), - }, + pointer: objc.NewPointer( + C.newVZMACAddress(macAddrChar.CString()), + ), } - runtime.SetFinalizer(ma, func(self *MACAddress) { - self.Release() + objc.SetFinalizer(ma, func(self *MACAddress) { + objc.Release(self) }) - return ma + return ma, nil } // NewRandomLocallyAdministeredMACAddress creates a valid, random, unicast, locally administered address. -func NewRandomLocallyAdministeredMACAddress() *MACAddress { - ma := &MACAddress{ - pointer: pointer{ - ptr: C.newRandomLocallyAdministeredVZMACAddress(), - }, +// +// This is only supported on macOS 11 and newer, error will +// be returned on older versions. +func NewRandomLocallyAdministeredMACAddress() (*MACAddress, error) { + if err := macOSAvailable(11); err != nil { + return nil, err } - runtime.SetFinalizer(ma, func(self *MACAddress) { - self.Release() + + ma := &MACAddress{ + pointer: objc.NewPointer( + C.newRandomLocallyAdministeredVZMACAddress(), + ), + } + objc.SetFinalizer(ma, func(self *MACAddress) { + objc.Release(self) }) - return ma + return ma, nil } func (m *MACAddress) String() string { - cstring := (*char)(C.getVZMACAddressString(m.Ptr())) + cstring := (*char)(C.getVZMACAddressString(objc.Ptr(m))) return cstring.String() } diff --git a/src/cmd/linuxkit/vendor/github.com/Code-Hex/vz/v3/osversion.go b/src/cmd/linuxkit/vendor/github.com/Code-Hex/vz/v3/osversion.go new file mode 100644 index 000000000..d72a7856d --- /dev/null +++ b/src/cmd/linuxkit/vendor/github.com/Code-Hex/vz/v3/osversion.go @@ -0,0 +1,111 @@ +package vz + +/* +#cgo darwin CFLAGS: -mmacosx-version-min=11 -x objective-c -fno-objc-arc +#cgo darwin LDFLAGS: -lobjc -framework Foundation +# include "virtualization_helper.h" +*/ +import "C" +import ( + "errors" + "fmt" + "strconv" + "strings" + "sync" + "syscall" + + "golang.org/x/mod/semver" +) + +var ( + // ErrUnsupportedOSVersion is returned when calling a method which is only + // available in newer macOS versions. + ErrUnsupportedOSVersion = errors.New("unsupported macOS version") + + // ErrBuildTargetOSVersion indicates that the API is available but the + // running program has disabled it. + ErrBuildTargetOSVersion = errors.New("unsupported build target macOS version") +) + +func macOSAvailable(version float64) error { + if macOSMajorMinorVersion() < version { + return ErrUnsupportedOSVersion + } + return macOSBuildTargetAvailable(version) +} + +var ( + majorMinorVersion float64 + majorMinorVersionOnce interface{ Do(func()) } = &sync.Once{} + + // This can be replaced in the test code to enable mock. + // It will not be changed in production. + sysctl = syscall.Sysctl +) + +func fetchMajorMinorVersion() (float64, error) { + osver, err := sysctl("kern.osproductversion") + if err != nil { + return 0, err + } + prefix := "v" + majorMinor := strings.TrimPrefix(semver.MajorMinor(prefix+osver), prefix) + version, err := strconv.ParseFloat(majorMinor, 64) + if err != nil { + return 0, err + } + return version, nil +} + +func macOSMajorMinorVersion() float64 { + majorMinorVersionOnce.Do(func() { + version, err := fetchMajorMinorVersion() + if err != nil { + panic(err) + } + majorMinorVersion = version + }) + return majorMinorVersion +} + +var ( + maxAllowedVersion int + maxAllowedVersionOnce interface{ Do(func()) } = &sync.Once{} + + getMaxAllowedVersion = func() int { + return int(C.mac_os_x_version_max_allowed()) + } +) + +func fetchMaxAllowedVersion() int { + maxAllowedVersionOnce.Do(func() { + maxAllowedVersion = getMaxAllowedVersion() + }) + return maxAllowedVersion +} + +// macOSBuildTargetAvailable checks whether the API available in a given version has been compiled. +func macOSBuildTargetAvailable(version float64) error { + allowedVersion := fetchMaxAllowedVersion() + if allowedVersion == 0 { + return fmt.Errorf("undefined __MAC_OS_X_VERSION_MAX_ALLOWED: %w", ErrBuildTargetOSVersion) + } + + // FIXME(codehex): smart way + // This list from AvailabilityVersions.h + var target int + switch version { + case 11: + target = 110000 // __MAC_11_0 + case 12: + target = 120000 // __MAC_12_0 + case 12.3: + target = 120300 // __MAC_12_3 + case 13: + target = 130000 // __MAC_13_0 + } + if allowedVersion < target { + return fmt.Errorf("%w for %.1f", ErrBuildTargetOSVersion, version) + } + return nil +} diff --git a/src/cmd/linuxkit/vendor/github.com/Code-Hex/vz/v3/platform.go b/src/cmd/linuxkit/vendor/github.com/Code-Hex/vz/v3/platform.go new file mode 100644 index 000000000..1c3b8f066 --- /dev/null +++ b/src/cmd/linuxkit/vendor/github.com/Code-Hex/vz/v3/platform.go @@ -0,0 +1,154 @@ +package vz + +/* +#cgo darwin CFLAGS: -mmacosx-version-min=11 -x objective-c -fno-objc-arc +#cgo darwin LDFLAGS: -lobjc -framework Foundation -framework Virtualization +# include "virtualization_11.h" +# include "virtualization_12.h" +# include "virtualization_13.h" +*/ +import "C" +import ( + "os" + "unsafe" + + "github.com/Code-Hex/vz/v3/internal/objc" +) + +// PlatformConfiguration is an interface for a platform configuration. +type PlatformConfiguration interface { + objc.NSObject + + platformConfiguration() +} + +type basePlatformConfiguration struct{} + +func (*basePlatformConfiguration) platformConfiguration() {} + +// GenericPlatformConfiguration is the platform configuration for a generic Intel or ARM virtual machine. +type GenericPlatformConfiguration struct { + *pointer + + *basePlatformConfiguration + + machineIdentifier *GenericMachineIdentifier +} + +// MachineIdentifier returns the machine identifier. +func (m *GenericPlatformConfiguration) MachineIdentifier() *GenericMachineIdentifier { + return m.machineIdentifier +} + +var _ PlatformConfiguration = (*GenericPlatformConfiguration)(nil) + +// NewGenericPlatformConfiguration creates a new generic platform configuration. +// +// This is only supported on macOS 12 and newer, error will +// be returned on older versions. +func NewGenericPlatformConfiguration(opts ...GenericPlatformConfigurationOption) (*GenericPlatformConfiguration, error) { + if err := macOSAvailable(12); err != nil { + return nil, err + } + + platformConfig := &GenericPlatformConfiguration{ + pointer: objc.NewPointer( + C.newVZGenericPlatformConfiguration(), + ), + } + for _, optFunc := range opts { + if err := optFunc(platformConfig); err != nil { + return nil, err + } + } + objc.SetFinalizer(platformConfig, func(self *GenericPlatformConfiguration) { + objc.Release(self) + }) + return platformConfig, nil +} + +// GenericMachineIdentifier is a struct that represents a unique identifier +// for a virtual machine. +type GenericMachineIdentifier struct { + *pointer + + dataRepresentation []byte +} + +// NewGenericMachineIdentifierWithDataPath initialize a new machine identifier described by the specified pathname. +// +// This is only supported on macOS 13 and newer, error will +// be returned on older versions. +func NewGenericMachineIdentifierWithDataPath(pathname string) (*GenericMachineIdentifier, error) { + b, err := os.ReadFile(pathname) + if err != nil { + return nil, err + } + return NewGenericMachineIdentifierWithData(b) +} + +// NewGenericMachineIdentifierWithData initialize a new machine identifier described by the specified data representation. +// +// This is only supported on macOS 13 and newer, error will +// be returned on older versions. +func NewGenericMachineIdentifierWithData(b []byte) (*GenericMachineIdentifier, error) { + if err := macOSAvailable(13); err != nil { + return nil, err + } + + ptr := C.newVZGenericMachineIdentifierWithBytes( + unsafe.Pointer(&b[0]), + C.int(len(b)), + ) + return newGenericMachineIdentifier(ptr), nil +} + +// NewGenericMachineIdentifier initialize a new machine identifier is used by guests to uniquely +// identify the virtual hardware. +// +// Two virtual machines running concurrently should not use the same identifier. +// +// If the virtual machine is serialized to disk, the identifier can be preserved in a binary representation through +// DataRepresentation method. +// The identifier can then be recreated with NewGenericMachineIdentifierWithData function from the binary representation. +// +// This is only supported on macOS 13 and newer, error will +// be returned on older versions. +func NewGenericMachineIdentifier() (*GenericMachineIdentifier, error) { + if err := macOSAvailable(13); err != nil { + return nil, err + } + return newGenericMachineIdentifier(C.newVZGenericMachineIdentifier()), nil +} + +func newGenericMachineIdentifier(ptr unsafe.Pointer) *GenericMachineIdentifier { + dataRepresentation := C.getVZGenericMachineIdentifierDataRepresentation(ptr) + bytePointer := (*byte)(unsafe.Pointer(dataRepresentation.ptr)) + return &GenericMachineIdentifier{ + pointer: objc.NewPointer(ptr), + // https://github.com/golang/go/wiki/cgo#turning-c-arrays-into-go-slices + dataRepresentation: unsafe.Slice(bytePointer, dataRepresentation.len), + } +} + +// DataRepresentation opaque data representation of the machine identifier. +// This can be used to recreate the same machine identifier with NewGenericMachineIdentifierWithData function. +func (g *GenericMachineIdentifier) DataRepresentation() []byte { return g.dataRepresentation } + +// GenericPlatformConfigurationOption is an optional function to create its configuration. +type GenericPlatformConfigurationOption func(*GenericPlatformConfiguration) error + +// WithGenericMachineIdentifier is an option to create a new GenericPlatformConfiguration. +// +// This is only supported on macOS 13 and newer, error will +// be returned on older versions. +func WithGenericMachineIdentifier(m *GenericMachineIdentifier) GenericPlatformConfigurationOption { + return func(mpc *GenericPlatformConfiguration) error { + if err := macOSAvailable(13); err != nil { + return err + } + mpc.machineIdentifier = m + C.setMachineIdentifierVZGenericPlatformConfiguration(objc.Ptr(mpc), objc.Ptr(m)) + return nil + } +} diff --git a/src/cmd/linuxkit/vendor/github.com/Code-Hex/vz/v3/platform_arm64.go b/src/cmd/linuxkit/vendor/github.com/Code-Hex/vz/v3/platform_arm64.go new file mode 100644 index 000000000..8e78deedf --- /dev/null +++ b/src/cmd/linuxkit/vendor/github.com/Code-Hex/vz/v3/platform_arm64.go @@ -0,0 +1,101 @@ +//go:build darwin && arm64 +// +build darwin,arm64 + +package vz + +/* +#cgo darwin CFLAGS: -mmacosx-version-min=11 -x objective-c -fno-objc-arc +#cgo darwin LDFLAGS: -lobjc -framework Foundation -framework Virtualization +# include "virtualization_12_arm64.h" +*/ +import "C" +import ( + "github.com/Code-Hex/vz/v3/internal/objc" +) + +// MacPlatformConfiguration is the platform configuration for booting macOS on Apple silicon. +// +// When creating a VM, the hardwareModel and auxiliaryStorage depend on the restore image that you use to install macOS. +// +// To choose the hardware model, start from MacOSRestoreImage.MostFeaturefulSupportedConfiguration method to get a supported +// configuration, then use its MacOSConfigurationRequirements.HardwareModel method to get the hardware model. +// +// Use the hardware model to set up MacPlatformConfiguration and to initialize a new auxiliary storage with +// `WithCreatingStorage` functional option of the `NewMacAuxiliaryStorage`. +// +// When you save a VM to disk and load it again, you must restore the HardwareModel, MachineIdentifier and +// AuxiliaryStorage methods to their original values. +// +// If you create multiple VMs from the same configuration, each should have a unique auxiliaryStorage and machineIdentifier. +type MacPlatformConfiguration struct { + *pointer + + *basePlatformConfiguration + + hardwareModel *MacHardwareModel + machineIdentifier *MacMachineIdentifier + auxiliaryStorage *MacAuxiliaryStorage +} + +var _ PlatformConfiguration = (*MacPlatformConfiguration)(nil) + +// MacPlatformConfigurationOption is an optional function to create its configuration. +type MacPlatformConfigurationOption func(*MacPlatformConfiguration) + +// WithMacHardwareModel is an option to create a new MacPlatformConfiguration. +func WithMacHardwareModel(m *MacHardwareModel) MacPlatformConfigurationOption { + return func(mpc *MacPlatformConfiguration) { + mpc.hardwareModel = m + C.setHardwareModelVZMacPlatformConfiguration(objc.Ptr(mpc), objc.Ptr(m)) + } +} + +// WithMacMachineIdentifier is an option to create a new MacPlatformConfiguration. +func WithMacMachineIdentifier(m *MacMachineIdentifier) MacPlatformConfigurationOption { + return func(mpc *MacPlatformConfiguration) { + mpc.machineIdentifier = m + C.setMachineIdentifierVZMacPlatformConfiguration(objc.Ptr(mpc), objc.Ptr(m)) + } +} + +// WithMacAuxiliaryStorage is an option to create a new MacPlatformConfiguration. +func WithMacAuxiliaryStorage(m *MacAuxiliaryStorage) MacPlatformConfigurationOption { + return func(mpc *MacPlatformConfiguration) { + mpc.auxiliaryStorage = m + C.setAuxiliaryStorageVZMacPlatformConfiguration(objc.Ptr(mpc), objc.Ptr(m)) + } +} + +// NewMacPlatformConfiguration creates a new MacPlatformConfiguration. see also it's document. +// +// This is only supported on macOS 12 and newer, error will +// be returned on older versions. +func NewMacPlatformConfiguration(opts ...MacPlatformConfigurationOption) (*MacPlatformConfiguration, error) { + if err := macOSAvailable(12); err != nil { + return nil, err + } + + platformConfig := &MacPlatformConfiguration{ + pointer: objc.NewPointer( + C.newVZMacPlatformConfiguration(), + ), + } + for _, optFunc := range opts { + optFunc(platformConfig) + } + objc.SetFinalizer(platformConfig, func(self *MacPlatformConfiguration) { + objc.Release(self) + }) + return platformConfig, nil +} + +// HardwareModel returns the Mac hardware model. +func (m *MacPlatformConfiguration) HardwareModel() *MacHardwareModel { return m.hardwareModel } + +// MachineIdentifier returns the Mac machine identifier. +func (m *MacPlatformConfiguration) MachineIdentifier() *MacMachineIdentifier { + return m.machineIdentifier +} + +// AuxiliaryStorage returns the Mac auxiliary storage. +func (m *MacPlatformConfiguration) AuxiliaryStorage() *MacAuxiliaryStorage { return m.auxiliaryStorage } diff --git a/src/cmd/linuxkit/vendor/github.com/Code-Hex/vz/v3/pointing_device.go b/src/cmd/linuxkit/vendor/github.com/Code-Hex/vz/v3/pointing_device.go new file mode 100644 index 000000000..b1368d8c2 --- /dev/null +++ b/src/cmd/linuxkit/vendor/github.com/Code-Hex/vz/v3/pointing_device.go @@ -0,0 +1,52 @@ +package vz + +/* +#cgo darwin CFLAGS: -mmacosx-version-min=11 -x objective-c -fno-objc-arc +#cgo darwin LDFLAGS: -lobjc -framework Foundation -framework Virtualization +# include "virtualization_11.h" +# include "virtualization_12.h" +*/ +import "C" +import ( + "github.com/Code-Hex/vz/v3/internal/objc" +) + +// PointingDeviceConfiguration is an interface for a pointing device configuration. +type PointingDeviceConfiguration interface { + objc.NSObject + + pointingDeviceConfiguration() +} + +type basePointingDeviceConfiguration struct{} + +func (*basePointingDeviceConfiguration) pointingDeviceConfiguration() {} + +// USBScreenCoordinatePointingDeviceConfiguration is a struct that defines the configuration +// for a USB pointing device that reports absolute coordinates. +type USBScreenCoordinatePointingDeviceConfiguration struct { + *pointer + + *basePointingDeviceConfiguration +} + +var _ PointingDeviceConfiguration = (*USBScreenCoordinatePointingDeviceConfiguration)(nil) + +// NewUSBScreenCoordinatePointingDeviceConfiguration creates a new USBScreenCoordinatePointingDeviceConfiguration. +// +// This is only supported on macOS 12 and newer, error will +// be returned on older versions. +func NewUSBScreenCoordinatePointingDeviceConfiguration() (*USBScreenCoordinatePointingDeviceConfiguration, error) { + if err := macOSAvailable(12); err != nil { + return nil, err + } + config := &USBScreenCoordinatePointingDeviceConfiguration{ + pointer: objc.NewPointer( + C.newVZUSBScreenCoordinatePointingDeviceConfiguration(), + ), + } + objc.SetFinalizer(config, func(self *USBScreenCoordinatePointingDeviceConfiguration) { + objc.Release(self) + }) + return config, nil +} diff --git a/src/cmd/linuxkit/vendor/github.com/Code-Hex/vz/v3/pointing_device_arm64.go b/src/cmd/linuxkit/vendor/github.com/Code-Hex/vz/v3/pointing_device_arm64.go new file mode 100644 index 000000000..4bced868d --- /dev/null +++ b/src/cmd/linuxkit/vendor/github.com/Code-Hex/vz/v3/pointing_device_arm64.go @@ -0,0 +1,51 @@ +//go:build darwin && arm64 +// +build darwin,arm64 + +package vz + +/* +#cgo darwin CFLAGS: -mmacosx-version-min=11 -x objective-c -fno-objc-arc +#cgo darwin LDFLAGS: -lobjc -framework Foundation -framework Virtualization +# include "virtualization_13_arm64.h" +*/ +import "C" +import ( + "github.com/Code-Hex/vz/v3/internal/objc" +) + +// MacTrackpadConfiguration is a struct that defines the configuration +// for a Mac trackpad. +// +// This device is only recognized by virtual machines running macOS 13.0 and later. +// In order to support both macOS 13.0 and earlier guests, VirtualMachineConfiguration.pointingDevices +// can be set to an array containing both a MacTrackpadConfiguration and +// a USBScreenCoordinatePointingDeviceConfiguration object. macOS 13.0 and later guests will use +// the multi-touch trackpad device, while earlier versions of macOS will use the USB pointing device. +// +// see: https://developer.apple.com/documentation/virtualization/vzmactrackpadconfiguration?language=objc +type MacTrackpadConfiguration struct { + *pointer + + *basePointingDeviceConfiguration +} + +var _ PointingDeviceConfiguration = (*MacTrackpadConfiguration)(nil) + +// NewMacTrackpadConfiguration creates a new MacTrackpadConfiguration. +// +// This is only supported on macOS 13 and newer, error will +// be returned on older versions. +func NewMacTrackpadConfiguration() (*MacTrackpadConfiguration, error) { + if err := macOSAvailable(13); err != nil { + return nil, err + } + config := &MacTrackpadConfiguration{ + pointer: objc.NewPointer( + C.newVZMacTrackpadConfiguration(), + ), + } + objc.SetFinalizer(config, func(self *MacTrackpadConfiguration) { + objc.Release(self) + }) + return config, nil +} diff --git a/src/cmd/linuxkit/vendor/github.com/Code-Hex/vz/console.go b/src/cmd/linuxkit/vendor/github.com/Code-Hex/vz/v3/serial_console.go similarity index 63% rename from src/cmd/linuxkit/vendor/github.com/Code-Hex/vz/console.go rename to src/cmd/linuxkit/vendor/github.com/Code-Hex/vz/v3/serial_console.go index b6146ff15..19171c962 100644 --- a/src/cmd/linuxkit/vendor/github.com/Code-Hex/vz/console.go +++ b/src/cmd/linuxkit/vendor/github.com/Code-Hex/vz/v3/serial_console.go @@ -1,21 +1,22 @@ package vz /* -#cgo darwin CFLAGS: -x objective-c -fno-objc-arc +#cgo darwin CFLAGS: -mmacosx-version-min=11 -x objective-c -fno-objc-arc #cgo darwin LDFLAGS: -lobjc -framework Foundation -framework Virtualization -# include "virtualization.h" +# include "virtualization_11.h" */ import "C" import ( "os" - "runtime" + + "github.com/Code-Hex/vz/v3/internal/objc" ) // SerialPortAttachment interface for a serial port attachment. // // A serial port attachment defines how the virtual machine's serial port interfaces with the host system. type SerialPortAttachment interface { - NSObject + objc.NSObject serialPortAttachment() } @@ -31,7 +32,7 @@ var _ SerialPortAttachment = (*FileHandleSerialPortAttachment)(nil) // Data written to fileHandleForReading goes to the guest. Data sent from the guest appears on fileHandleForWriting. // see: https://developer.apple.com/documentation/virtualization/vzfilehandleserialportattachment?language=objc type FileHandleSerialPortAttachment struct { - pointer + *pointer *baseSerialPortAttachment } @@ -40,19 +41,26 @@ type FileHandleSerialPortAttachment struct { // // read parameter is an *os.File for reading from the file. // write parameter is an *os.File for writing to the file. -func NewFileHandleSerialPortAttachment(read, write *os.File) *FileHandleSerialPortAttachment { +// +// This is only supported on macOS 11 and newer, error will +// be returned on older versions. +func NewFileHandleSerialPortAttachment(read, write *os.File) (*FileHandleSerialPortAttachment, error) { + if err := macOSAvailable(11); err != nil { + return nil, err + } + attachment := &FileHandleSerialPortAttachment{ - pointer: pointer{ - ptr: C.newVZFileHandleSerialPortAttachment( + pointer: objc.NewPointer( + C.newVZFileHandleSerialPortAttachment( C.int(read.Fd()), C.int(write.Fd()), ), - }, + ), } - runtime.SetFinalizer(attachment, func(self *FileHandleSerialPortAttachment) { - self.Release() + objc.SetFinalizer(attachment, func(self *FileHandleSerialPortAttachment) { + objc.Release(self) }) - return attachment + return attachment, nil } var _ SerialPortAttachment = (*FileSerialPortAttachment)(nil) @@ -63,7 +71,7 @@ var _ SerialPortAttachment = (*FileSerialPortAttachment)(nil) // No data is sent to the guest over serial with this attachment. // see: https://developer.apple.com/documentation/virtualization/vzfileserialportattachment?language=objc type FileSerialPortAttachment struct { - pointer + *pointer *baseSerialPortAttachment } @@ -71,29 +79,35 @@ type FileSerialPortAttachment struct { // NewFileSerialPortAttachment initialize the FileSerialPortAttachment from a path of a file. // If error is not nil, used to report errors if intialization fails. // -// - path of the file for the attachment on the local file system. -// - shouldAppend True if the file should be opened in append mode, false otherwise. -// When a file is opened in append mode, writing to that file will append to the end of it. +// - path of the file for the attachment on the local file system. +// - shouldAppend True if the file should be opened in append mode, false otherwise. +// When a file is opened in append mode, writing to that file will append to the end of it. +// +// This is only supported on macOS 11 and newer, error will +// be returned on older versions. func NewFileSerialPortAttachment(path string, shouldAppend bool) (*FileSerialPortAttachment, error) { + if err := macOSAvailable(11); err != nil { + return nil, err + } + cpath := charWithGoString(path) defer cpath.Free() - nserr := newNSErrorAsNil() - nserrPtr := nserr.Ptr() + nserrPtr := newNSErrorAsNil() attachment := &FileSerialPortAttachment{ - pointer: pointer{ - ptr: C.newVZFileSerialPortAttachment( + pointer: objc.NewPointer( + C.newVZFileSerialPortAttachment( cpath.CString(), C.bool(shouldAppend), &nserrPtr, ), - }, + ), } if err := newNSError(nserrPtr); err != nil { return nil, err } - runtime.SetFinalizer(attachment, func(self *FileSerialPortAttachment) { - self.Release() + objc.SetFinalizer(attachment, func(self *FileSerialPortAttachment) { + objc.Release(self) }) return attachment, nil } @@ -104,20 +118,27 @@ func NewFileSerialPortAttachment(path string, shouldAppend bool) (*FileSerialPor // The device sets up a single port on the Virtio console device. // see: https://developer.apple.com/documentation/virtualization/vzvirtioconsoledeviceserialportconfiguration?language=objc type VirtioConsoleDeviceSerialPortConfiguration struct { - pointer + *pointer } // NewVirtioConsoleDeviceSerialPortConfiguration creates a new NewVirtioConsoleDeviceSerialPortConfiguration. -func NewVirtioConsoleDeviceSerialPortConfiguration(attachment SerialPortAttachment) *VirtioConsoleDeviceSerialPortConfiguration { - config := &VirtioConsoleDeviceSerialPortConfiguration{ - pointer: pointer{ - ptr: C.newVZVirtioConsoleDeviceSerialPortConfiguration( - attachment.Ptr(), - ), - }, +// +// This is only supported on macOS 11 and newer, error will +// be returned on older versions. +func NewVirtioConsoleDeviceSerialPortConfiguration(attachment SerialPortAttachment) (*VirtioConsoleDeviceSerialPortConfiguration, error) { + if err := macOSAvailable(11); err != nil { + return nil, err } - runtime.SetFinalizer(config, func(self *VirtioConsoleDeviceSerialPortConfiguration) { - self.Release() + + config := &VirtioConsoleDeviceSerialPortConfiguration{ + pointer: objc.NewPointer( + C.newVZVirtioConsoleDeviceSerialPortConfiguration( + objc.Ptr(attachment), + ), + ), + } + objc.SetFinalizer(config, func(self *VirtioConsoleDeviceSerialPortConfiguration) { + objc.Release(self) }) - return config + return config, nil } diff --git a/src/cmd/linuxkit/vendor/github.com/Code-Hex/vz/v3/shared_directory.go b/src/cmd/linuxkit/vendor/github.com/Code-Hex/vz/v3/shared_directory.go new file mode 100644 index 000000000..8b6288907 --- /dev/null +++ b/src/cmd/linuxkit/vendor/github.com/Code-Hex/vz/v3/shared_directory.go @@ -0,0 +1,184 @@ +package vz + +/* +#cgo darwin CFLAGS: -mmacosx-version-min=11 -x objective-c -fno-objc-arc +#cgo darwin LDFLAGS: -lobjc -framework Foundation -framework Virtualization +# include "virtualization_11.h" +# include "virtualization_12.h" +# include "virtualization_13.h" +*/ +import "C" +import ( + "os" + + "github.com/Code-Hex/vz/v3/internal/objc" +) + +// DirectorySharingDeviceConfiguration for a directory sharing device configuration. +type DirectorySharingDeviceConfiguration interface { + objc.NSObject + + directorySharingDeviceConfiguration() +} + +type baseDirectorySharingDeviceConfiguration struct{} + +func (*baseDirectorySharingDeviceConfiguration) directorySharingDeviceConfiguration() {} + +var _ DirectorySharingDeviceConfiguration = (*VirtioFileSystemDeviceConfiguration)(nil) + +// VirtioFileSystemDeviceConfiguration is a configuration of a Virtio file system device. +// +// see: https://developer.apple.com/documentation/virtualization/vzvirtiofilesystemdeviceconfiguration?language=objc +type VirtioFileSystemDeviceConfiguration struct { + *pointer + + *baseDirectorySharingDeviceConfiguration +} + +// NewVirtioFileSystemDeviceConfiguration create a new VirtioFileSystemDeviceConfiguration. +// +// This is only supported on macOS 12 and newer, error will +// be returned on older versions. +func NewVirtioFileSystemDeviceConfiguration(tag string) (*VirtioFileSystemDeviceConfiguration, error) { + if err := macOSAvailable(12); err != nil { + return nil, err + } + tagChar := charWithGoString(tag) + defer tagChar.Free() + + nserrPtr := newNSErrorAsNil() + fsdConfig := &VirtioFileSystemDeviceConfiguration{ + pointer: objc.NewPointer( + C.newVZVirtioFileSystemDeviceConfiguration(tagChar.CString(), &nserrPtr), + ), + } + if err := newNSError(nserrPtr); err != nil { + return nil, err + } + objc.SetFinalizer(fsdConfig, func(self *VirtioFileSystemDeviceConfiguration) { + objc.Release(self) + }) + return fsdConfig, nil +} + +// SetDirectoryShare sets the directory share associated with this configuration. +func (c *VirtioFileSystemDeviceConfiguration) SetDirectoryShare(share DirectoryShare) { + C.setVZVirtioFileSystemDeviceConfigurationShare(objc.Ptr(c), objc.Ptr(share)) +} + +// SharedDirectory is a shared directory. +type SharedDirectory struct { + *pointer +} + +// NewSharedDirectory creates a new shared directory. +// +// This is only supported on macOS 12 and newer, error will +// be returned on older versions. +func NewSharedDirectory(dirPath string, readOnly bool) (*SharedDirectory, error) { + if err := macOSAvailable(12); err != nil { + return nil, err + } + if _, err := os.Stat(dirPath); err != nil { + return nil, err + } + + dirPathChar := charWithGoString(dirPath) + defer dirPathChar.Free() + sd := &SharedDirectory{ + pointer: objc.NewPointer( + C.newVZSharedDirectory(dirPathChar.CString(), C.bool(readOnly)), + ), + } + objc.SetFinalizer(sd, func(self *SharedDirectory) { + objc.Release(self) + }) + return sd, nil +} + +// DirectoryShare is the base interface for a directory share. +type DirectoryShare interface { + objc.NSObject + + directoryShare() +} + +type baseDirectoryShare struct{} + +func (*baseDirectoryShare) directoryShare() {} + +var _ DirectoryShare = (*SingleDirectoryShare)(nil) + +// SingleDirectoryShare defines the directory share for a single directory. +type SingleDirectoryShare struct { + *pointer + + *baseDirectoryShare +} + +// NewSingleDirectoryShare creates a new single directory share. +// +// This is only supported on macOS 12 and newer, error will +// be returned on older versions. +func NewSingleDirectoryShare(share *SharedDirectory) (*SingleDirectoryShare, error) { + if err := macOSAvailable(12); err != nil { + return nil, err + } + config := &SingleDirectoryShare{ + pointer: objc.NewPointer( + C.newVZSingleDirectoryShare(objc.Ptr(share)), + ), + } + objc.SetFinalizer(config, func(self *SingleDirectoryShare) { + objc.Release(self) + }) + return config, nil +} + +// MultipleDirectoryShare defines the directory share for multiple directories. +type MultipleDirectoryShare struct { + *pointer + + *baseDirectoryShare +} + +var _ DirectoryShare = (*MultipleDirectoryShare)(nil) + +// NewMultipleDirectoryShare creates a new multiple directories share. +// +// This is only supported on macOS 12 and newer, error will +// be returned on older versions. +func NewMultipleDirectoryShare(shares map[string]*SharedDirectory) (*MultipleDirectoryShare, error) { + if err := macOSAvailable(12); err != nil { + return nil, err + } + directories := make(map[string]objc.NSObject, len(shares)) + for k, v := range shares { + directories[k] = v + } + + dict := objc.ConvertToNSMutableDictionary(directories) + + config := &MultipleDirectoryShare{ + pointer: objc.NewPointer( + C.newVZMultipleDirectoryShare(objc.Ptr(dict)), + ), + } + objc.SetFinalizer(config, func(self *MultipleDirectoryShare) { + objc.Release(self) + }) + return config, nil +} + +// MacOSGuestAutomountTag returns the macOS automount tag. +// +// A device configured with this tag will be automatically mounted in a macOS guest. +// This is only supported on macOS 13 and newer, error will be returned on older versions. +func MacOSGuestAutomountTag() (string, error) { + if err := macOSAvailable(13); err != nil { + return "", err + } + cstring := (*char)(C.getMacOSGuestAutomountTag()) + return cstring.String(), nil +} diff --git a/src/cmd/linuxkit/vendor/github.com/Code-Hex/vz/v3/shared_directory_arm64.go b/src/cmd/linuxkit/vendor/github.com/Code-Hex/vz/v3/shared_directory_arm64.go new file mode 100644 index 000000000..f3170511d --- /dev/null +++ b/src/cmd/linuxkit/vendor/github.com/Code-Hex/vz/v3/shared_directory_arm64.go @@ -0,0 +1,109 @@ +//go:build darwin && arm64 +// +build darwin,arm64 + +package vz + +/* +#cgo darwin CFLAGS: -mmacosx-version-min=11 -x objective-c -fno-objc-arc +#cgo darwin LDFLAGS: -lobjc -framework Foundation -framework Virtualization +# include "virtualization_13_arm64.h" +*/ +import "C" +import ( + "runtime/cgo" + "unsafe" + + "github.com/Code-Hex/vz/v3/internal/objc" +) + +// LinuxRosettaAvailability represents an availability of Rosetta support for Linux binaries. +// +//go:generate go run ./cmd/addtags -tags=darwin,arm64 -file linuxrosettaavailability_string_arm64.go stringer -type=LinuxRosettaAvailability -output=linuxrosettaavailability_string_arm64.go +type LinuxRosettaAvailability int + +const ( + // LinuxRosettaAvailabilityNotSupported Rosetta support for Linux binaries is not available on the host system. + LinuxRosettaAvailabilityNotSupported LinuxRosettaAvailability = iota + + // LinuxRosettaAvailabilityNotInstalled Rosetta support for Linux binaries is not installed on the host system. + LinuxRosettaAvailabilityNotInstalled + + // LinuxRosettaAvailabilityInstalled Rosetta support for Linux is installed on the host system. + LinuxRosettaAvailabilityInstalled +) + +//export linuxInstallRosettaWithCompletionHandler +func linuxInstallRosettaWithCompletionHandler(cgoHandlerPtr, errPtr unsafe.Pointer) { + cgoHandler := *(*cgo.Handle)(cgoHandlerPtr) + + handler := cgoHandler.Value().(func(error)) + + if err := newNSError(errPtr); err != nil { + handler(err) + } else { + handler(nil) + } +} + +// LinuxRosettaDirectoryShare directory share to enable Rosetta support for Linux binaries. +// see: https://developer.apple.com/documentation/virtualization/vzlinuxrosettadirectoryshare?language=objc +type LinuxRosettaDirectoryShare struct { + *pointer + + *baseDirectoryShare +} + +var _ DirectoryShare = (*LinuxRosettaDirectoryShare)(nil) + +// NewLinuxRosettaDirectoryShare creates a new Rosetta directory share if Rosetta support +// for Linux binaries is installed. +// +// This is only supported on macOS 13 and newer, error will +// be returned on older versions. +func NewLinuxRosettaDirectoryShare() (*LinuxRosettaDirectoryShare, error) { + if err := macOSAvailable(13); err != nil { + return nil, err + } + nserrPtr := newNSErrorAsNil() + ds := &LinuxRosettaDirectoryShare{ + pointer: objc.NewPointer( + C.newVZLinuxRosettaDirectoryShare(&nserrPtr), + ), + } + if err := newNSError(nserrPtr); err != nil { + return nil, err + } + objc.SetFinalizer(ds, func(self *LinuxRosettaDirectoryShare) { + objc.Release(self) + }) + return ds, nil +} + +// LinuxRosettaDirectoryShareInstallRosetta download and install Rosetta support +// for Linux binaries if necessary. +// +// This is only supported on macOS 13 and newer, error will +// be returned on older versions. +func LinuxRosettaDirectoryShareInstallRosetta() error { + if err := macOSAvailable(13); err != nil { + return err + } + errCh := make(chan error, 1) + cgoHandler := cgo.NewHandle(func(err error) { + errCh <- err + }) + C.linuxInstallRosetta(unsafe.Pointer(&cgoHandler)) + return <-errCh +} + +// LinuxRosettaDirectoryShareAvailability checks the availability of Rosetta support +// for the directory share. +// +// This is only supported on macOS 13 and newer, LinuxRosettaAvailabilityNotSupported will +// be returned on older versions. +func LinuxRosettaDirectoryShareAvailability() LinuxRosettaAvailability { + if err := macOSAvailable(13); err != nil { + return LinuxRosettaAvailabilityNotSupported + } + return LinuxRosettaAvailability(C.availabilityVZLinuxRosettaDirectoryShare()) +} diff --git a/src/cmd/linuxkit/vendor/github.com/Code-Hex/vz/v3/socket.go b/src/cmd/linuxkit/vendor/github.com/Code-Hex/vz/v3/socket.go new file mode 100644 index 000000000..d624c8918 --- /dev/null +++ b/src/cmd/linuxkit/vendor/github.com/Code-Hex/vz/v3/socket.go @@ -0,0 +1,330 @@ +package vz + +/* +#cgo darwin CFLAGS: -mmacosx-version-min=11 -x objective-c -fno-objc-arc +#cgo darwin LDFLAGS: -lobjc -framework Foundation -framework Virtualization +# include "virtualization_11.h" +*/ +import "C" +import ( + "fmt" + "net" + "os" + "runtime" + "runtime/cgo" + "sync" + "time" + "unsafe" + + "github.com/Code-Hex/vz/v3/internal/objc" +) + +// SocketDeviceConfiguration for a socket device configuration. +type SocketDeviceConfiguration interface { + objc.NSObject + + socketDeviceConfiguration() +} + +type baseSocketDeviceConfiguration struct{} + +func (*baseSocketDeviceConfiguration) socketDeviceConfiguration() {} + +var _ SocketDeviceConfiguration = (*VirtioSocketDeviceConfiguration)(nil) + +// VirtioSocketDeviceConfiguration is a configuration of the Virtio socket device. +// +// This configuration creates a Virtio socket device for the guest which communicates with the host through the Virtio interface. +// Only one Virtio socket device can be used per virtual machine. +// see: https://developer.apple.com/documentation/virtualization/vzvirtiosocketdeviceconfiguration?language=objc +type VirtioSocketDeviceConfiguration struct { + *pointer + + *baseSocketDeviceConfiguration +} + +// NewVirtioSocketDeviceConfiguration creates a new VirtioSocketDeviceConfiguration. +// +// This is only supported on macOS 11 and newer, error will +// be returned on older versions. +func NewVirtioSocketDeviceConfiguration() (*VirtioSocketDeviceConfiguration, error) { + if err := macOSAvailable(11); err != nil { + return nil, err + } + + config := newVirtioSocketDeviceConfiguration(C.newVZVirtioSocketDeviceConfiguration()) + + objc.SetFinalizer(config, func(self *VirtioSocketDeviceConfiguration) { + objc.Release(self) + }) + return config, nil +} + +func newVirtioSocketDeviceConfiguration(ptr unsafe.Pointer) *VirtioSocketDeviceConfiguration { + return &VirtioSocketDeviceConfiguration{ + pointer: objc.NewPointer(ptr), + } +} + +// VirtioSocketDevice a device that manages port-based connections between the guest system and the host computer. +// +// Don’t create a VirtioSocketDevice struct directly. Instead, when you request a socket device in your configuration, +// the virtual machine creates it and you can get it via SocketDevices method. +// see: https://developer.apple.com/documentation/virtualization/vzvirtiosocketdevice?language=objc +type VirtioSocketDevice struct { + dispatchQueue unsafe.Pointer + *pointer +} + +func newVirtioSocketDevice(ptr, dispatchQueue unsafe.Pointer) *VirtioSocketDevice { + return &VirtioSocketDevice{ + dispatchQueue: dispatchQueue, + pointer: objc.NewPointer(ptr), + } +} + +// Listen creates a new VirtioSocketListener which is a struct that listens for port-based connection requests +// from the guest operating system. +// +// Be sure to close the listener by calling `VirtioSocketListener.Close` after used this one. +// +// This is only supported on macOS 11 and newer, error will +// be returned on older versions. +func (v *VirtioSocketDevice) Listen(port uint32) (*VirtioSocketListener, error) { + if err := macOSAvailable(11); err != nil { + return nil, err + } + + ch := make(chan connResults, 1) // should I increase more caps? + + handler := cgo.NewHandle(func(conn *VirtioSocketConnection, err error) { + ch <- connResults{conn, err} + }) + ptr := C.newVZVirtioSocketListener( + unsafe.Pointer(&handler), + ) + listener := &VirtioSocketListener{ + pointer: objc.NewPointer(ptr), + vsockDevice: v, + port: port, + handler: handler, + acceptch: ch, + } + + C.VZVirtioSocketDevice_setSocketListenerForPort( + objc.Ptr(v), + v.dispatchQueue, + objc.Ptr(listener), + C.uint32_t(port), + ) + + return listener, nil +} + +//export connectionHandler +func connectionHandler(connPtr, errPtr, cgoHandlerPtr unsafe.Pointer) { + cgoHandler := *(*cgo.Handle)(cgoHandlerPtr) + handler := cgoHandler.Value().(func(*VirtioSocketConnection, error)) + defer cgoHandler.Delete() + // see: startHandler + if err := newNSError(errPtr); err != nil { + handler(nil, err) + } else { + conn, err := newVirtioSocketConnection(connPtr) + handler(conn, err) + } +} + +// Connect Initiates a connection to the specified port of the guest operating system. +// +// This method initiates the connection asynchronously, and executes the completion handler when the results are available. +// If the guest operating system doesn’t listen for connections to the specifed port, this method does nothing. +// +// For a successful connection, this method sets the sourcePort property of the resulting VZVirtioSocketConnection object to a random port number. +// see: https://developer.apple.com/documentation/virtualization/vzvirtiosocketdevice/3656677-connecttoport?language=objc +func (v *VirtioSocketDevice) Connect(port uint32) (*VirtioSocketConnection, error) { + ch := make(chan connResults, 1) + cgoHandler := cgo.NewHandle(func(conn *VirtioSocketConnection, err error) { + ch <- connResults{conn, err} + close(ch) + }) + C.VZVirtioSocketDevice_connectToPort( + objc.Ptr(v), + v.dispatchQueue, + C.uint32_t(port), + unsafe.Pointer(&cgoHandler), + ) + result := <-ch + runtime.KeepAlive(v) + return result.conn, result.err +} + +type connResults struct { + conn *VirtioSocketConnection + err error +} + +// VirtioSocketListener a struct that listens for port-based connection requests from the guest operating system. +// +// see: https://developer.apple.com/documentation/virtualization/vzvirtiosocketlistener?language=objc +type VirtioSocketListener struct { + *pointer + vsockDevice *VirtioSocketDevice + handler cgo.Handle + port uint32 + acceptch chan connResults + closeOnce sync.Once +} + +var _ net.Listener = (*VirtioSocketListener)(nil) + +// Accept implements the Accept method in the Listener interface; it waits for the next call and returns a net.Conn. +func (v *VirtioSocketListener) Accept() (net.Conn, error) { + return v.AcceptVirtioSocketConnection() +} + +// AcceptVirtioSocketConnection accepts the next incoming call and returns the new connection. +func (v *VirtioSocketListener) AcceptVirtioSocketConnection() (*VirtioSocketConnection, error) { + result := <-v.acceptch + return result.conn, result.err +} + +// Close stops listening on the virtio socket. +func (v *VirtioSocketListener) Close() error { + v.closeOnce.Do(func() { + C.VZVirtioSocketDevice_removeSocketListenerForPort( + objc.Ptr(v.vsockDevice), + v.vsockDevice.dispatchQueue, + C.uint32_t(v.port), + ) + v.handler.Delete() + }) + return nil +} + +// Addr returns the listener's network address, a *VirtioSocketListenerAddr. +func (v *VirtioSocketListener) Addr() net.Addr { + const VMADDR_CID_HOST = 2 // copied from unix pacage + return &VirtioSocketListenerAddr{ + CID: VMADDR_CID_HOST, + Port: v.port, + } +} + +// VirtioSocketListenerAddr represents a network end point address for the vsock protocol. +type VirtioSocketListenerAddr struct { + CID uint32 + Port uint32 +} + +var _ net.Addr = (*VirtioSocketListenerAddr)(nil) + +// Network returns "vsock". +func (a *VirtioSocketListenerAddr) Network() string { return "vsock" } + +// String returns string of ":" +func (a *VirtioSocketListenerAddr) String() string { return fmt.Sprintf("%d:%d", a.CID, a.Port) } + +//export shouldAcceptNewConnectionHandler +func shouldAcceptNewConnectionHandler(cgoHandlerPtr, connPtr, devicePtr unsafe.Pointer) C.bool { + cgoHandler := *(*cgo.Handle)(cgoHandlerPtr) + handler := cgoHandler.Value().(func(*VirtioSocketConnection, error)) + + // see: startHandler + conn, err := newVirtioSocketConnection(connPtr) + go handler(conn, err) + return (C.bool)(true) +} + +// VirtioSocketConnection is a port-based connection between the guest operating system and the host computer. +// +// You don’t create connection objects directly. When the guest operating system initiates a connection, the virtual machine creates +// the connection object and passes it to the appropriate VirtioSocketListener struct, which forwards the object to its delegate. +// +// This is implemented net.Conn interface. This is generated from duplicated a file descriptor which is returned +// from virtualization.framework. macOS cannot connect directly to the Guest operating system using vsock. The vsock +// connection must always be made via virtualization.framework. The diagram looks like this. +// +// ┌─────────┐ ┌────────────────────────────┐ ┌────────────┐ +// │ macOS │<─── unix socket ───>│ virtualization.framework │<─── vsock ───>│ Guest OS │ +// └─────────┘ └────────────────────────────┘ └────────────┘ +// +// You will notice that this is not vsock in using this library. However, all data this connection goes through to the vsock +// connection to which the Guest OS is connected. +// +// This struct does not have any pointers for objects of the Objective-C. Because the various values +// of the VZVirtioSocketConnection object handled by Objective-C are no longer needed after the conversion +// to the Go struct. +// +// see: https://developer.apple.com/documentation/virtualization/vzvirtiosocketconnection?language=objc +type VirtioSocketConnection struct { + rawConn net.Conn + destinationPort uint32 + sourcePort uint32 +} + +var _ net.Conn = (*VirtioSocketConnection)(nil) + +func newVirtioSocketConnection(ptr unsafe.Pointer) (*VirtioSocketConnection, error) { + vzVirtioSocketConnection := C.convertVZVirtioSocketConnection2Flat(ptr) + file := os.NewFile((uintptr)(vzVirtioSocketConnection.fileDescriptor), "") + defer file.Close() + rawConn, err := net.FileConn(file) + if err != nil { + return nil, err + } + conn := &VirtioSocketConnection{ + rawConn: rawConn, + destinationPort: (uint32)(vzVirtioSocketConnection.destinationPort), + sourcePort: (uint32)(vzVirtioSocketConnection.sourcePort), + } + return conn, nil +} + +// Read reads data from connection of the vsock protocol. +func (v *VirtioSocketConnection) Read(b []byte) (n int, err error) { return v.rawConn.Read(b) } + +// Write writes data to the connection of the vsock protocol. +func (v *VirtioSocketConnection) Write(b []byte) (n int, err error) { return v.rawConn.Write(b) } + +// Close will be called when caused something error in socket. +func (v *VirtioSocketConnection) Close() error { + return v.rawConn.Close() +} + +// LocalAddr returns the local network address. +func (v *VirtioSocketConnection) LocalAddr() net.Addr { return v.rawConn.LocalAddr() } + +// RemoteAddr returns the remote network address. +func (v *VirtioSocketConnection) RemoteAddr() net.Addr { return v.rawConn.RemoteAddr() } + +// SetDeadline sets the read and write deadlines associated +// with the connection. It is equivalent to calling both +// SetReadDeadline and SetWriteDeadline. +func (v *VirtioSocketConnection) SetDeadline(t time.Time) error { return v.rawConn.SetDeadline(t) } + +// SetReadDeadline sets the deadline for future Read calls +// and any currently-blocked Read call. +// A zero value for t means Read will not time out. +func (v *VirtioSocketConnection) SetReadDeadline(t time.Time) error { + return v.rawConn.SetReadDeadline(t) +} + +// SetWriteDeadline sets the deadline for future Write calls +// and any currently-blocked Write call. +// Even if write times out, it may return n > 0, indicating that +// some of the data was successfully written. +// A zero value for t means Write will not time out. +func (v *VirtioSocketConnection) SetWriteDeadline(t time.Time) error { + return v.rawConn.SetWriteDeadline(t) +} + +// DestinationPort returns the destination port number of the connection. +func (v *VirtioSocketConnection) DestinationPort() uint32 { + return v.destinationPort +} + +// SourcePort returns the source port number of the connection. +func (v *VirtioSocketConnection) SourcePort() uint32 { + return v.sourcePort +} diff --git a/src/cmd/linuxkit/vendor/github.com/Code-Hex/vz/v3/storage.go b/src/cmd/linuxkit/vendor/github.com/Code-Hex/vz/v3/storage.go new file mode 100644 index 000000000..14ce4e2e8 --- /dev/null +++ b/src/cmd/linuxkit/vendor/github.com/Code-Hex/vz/v3/storage.go @@ -0,0 +1,211 @@ +package vz + +/* +#cgo darwin CFLAGS: -mmacosx-version-min=11 -x objective-c -fno-objc-arc +#cgo darwin LDFLAGS: -lobjc -framework Foundation -framework Virtualization +# include "virtualization_11.h" +# include "virtualization_12_3.h" +# include "virtualization_13.h" +*/ +import "C" +import ( + "os" + + "github.com/Code-Hex/vz/v3/internal/objc" +) + +type baseStorageDeviceAttachment struct{} + +func (*baseStorageDeviceAttachment) storageDeviceAttachment() {} + +// StorageDeviceAttachment for a storage device attachment. +// +// A storage device attachment defines how a virtual machine storage device interfaces with the host system. +// see: https://developer.apple.com/documentation/virtualization/vzstoragedeviceattachment?language=objc +type StorageDeviceAttachment interface { + objc.NSObject + + storageDeviceAttachment() +} + +var _ StorageDeviceAttachment = (*DiskImageStorageDeviceAttachment)(nil) + +// DiskImageStorageDeviceAttachment is a storage device attachment using a disk image to implement the storage. +// +// This storage device attachment uses a disk image on the host file system as the drive of the storage device. +// Only raw data disk images are supported. +// see: https://developer.apple.com/documentation/virtualization/vzdiskimagestoragedeviceattachment?language=objc +type DiskImageStorageDeviceAttachment struct { + *pointer + + *baseStorageDeviceAttachment +} + +// NewDiskImageStorageDeviceAttachment initialize the attachment from a local file path. +// Returns error is not nil, assigned with the error if the initialization failed. +// +// - diskPath is local file URL to the disk image in RAW format. +// - readOnly if YES, the device attachment is read-only, otherwise the device can write data to the disk image. +// +// This is only supported on macOS 11 and newer, error will +// be returned on older versions. +func NewDiskImageStorageDeviceAttachment(diskPath string, readOnly bool) (*DiskImageStorageDeviceAttachment, error) { + if err := macOSAvailable(11); err != nil { + return nil, err + } + if _, err := os.Stat(diskPath); err != nil { + return nil, err + } + + nserrPtr := newNSErrorAsNil() + + diskPathChar := charWithGoString(diskPath) + defer diskPathChar.Free() + attachment := &DiskImageStorageDeviceAttachment{ + pointer: objc.NewPointer( + C.newVZDiskImageStorageDeviceAttachment( + diskPathChar.CString(), + C.bool(readOnly), + &nserrPtr, + ), + ), + } + if err := newNSError(nserrPtr); err != nil { + return nil, err + } + objc.SetFinalizer(attachment, func(self *DiskImageStorageDeviceAttachment) { + objc.Release(self) + }) + return attachment, nil +} + +// StorageDeviceConfiguration for a storage device configuration. +type StorageDeviceConfiguration interface { + objc.NSObject + + storageDeviceConfiguration() +} + +type baseStorageDeviceConfiguration struct{} + +func (*baseStorageDeviceConfiguration) storageDeviceConfiguration() {} + +var _ StorageDeviceConfiguration = (*VirtioBlockDeviceConfiguration)(nil) + +// VirtioBlockDeviceConfiguration is a configuration of a paravirtualized storage device of type Virtio Block Device. +// +// This device configuration creates a storage device using paravirtualization. +// The emulated device follows the Virtio Block Device specification. +// +// The host implementation of the device is done through an attachment subclassing VZStorageDeviceAttachment +// like VZDiskImageStorageDeviceAttachment. +// see: https://developer.apple.com/documentation/virtualization/vzvirtioblockdeviceconfiguration?language=objc +type VirtioBlockDeviceConfiguration struct { + *pointer + + *baseStorageDeviceConfiguration + + blockDeviceIdentifier string +} + +// NewVirtioBlockDeviceConfiguration initialize a VZVirtioBlockDeviceConfiguration with a device attachment. +// +// - attachment The storage device attachment. This defines how the virtualized device operates on the host side. +// +// This is only supported on macOS 11 and newer, error will +// be returned on older versions. +func NewVirtioBlockDeviceConfiguration(attachment StorageDeviceAttachment) (*VirtioBlockDeviceConfiguration, error) { + if err := macOSAvailable(11); err != nil { + return nil, err + } + + config := &VirtioBlockDeviceConfiguration{ + pointer: objc.NewPointer( + C.newVZVirtioBlockDeviceConfiguration( + objc.Ptr(attachment), + ), + ), + } + objc.SetFinalizer(config, func(self *VirtioBlockDeviceConfiguration) { + objc.Release(self) + }) + return config, nil +} + +// BlockDeviceIdentifier returns the device identifier is a string identifying the Virtio block device. +// Empty string by default. +// +// The identifier can be retrieved in the guest via a VIRTIO_BLK_T_GET_ID request. +// +// This is only supported on macOS 12.3 and newer, error will be returned on older versions. +// +// see: https://developer.apple.com/documentation/virtualization/vzvirtioblockdeviceconfiguration/3917717-blockdeviceidentifier +func (v *VirtioBlockDeviceConfiguration) BlockDeviceIdentifier() (string, error) { + if err := macOSAvailable(12.3); err != nil { + return "", err + } + return v.blockDeviceIdentifier, nil +} + +// SetBlockDeviceIdentifier sets the device identifier is a string identifying the Virtio block device. +// +// The device identifier must be at most 20 bytes in length and ASCII-encodable. +// +// This is only supported on macOS 12.3 and newer, error will be returned on older versions. +// +// see: https://developer.apple.com/documentation/virtualization/vzvirtioblockdeviceconfiguration/3917717-blockdeviceidentifier +func (v *VirtioBlockDeviceConfiguration) SetBlockDeviceIdentifier(identifier string) error { + if err := macOSAvailable(12.3); err != nil { + return err + } + idChar := charWithGoString(identifier) + defer idChar.Free() + + nserrPtr := newNSErrorAsNil() + C.setBlockDeviceIdentifierVZVirtioBlockDeviceConfiguration( + objc.Ptr(v), + idChar.CString(), + &nserrPtr, + ) + if err := newNSError(nserrPtr); err != nil { + return err + } + v.blockDeviceIdentifier = identifier + return nil +} + +// USBMassStorageDeviceConfiguration is a configuration of a USB Mass Storage storage device. +// +// This device configuration creates a storage device that conforms to the USB Mass Storage specification. +// +// see: https://developer.apple.com/documentation/virtualization/vzusbmassstoragedeviceconfiguration?language=objc +type USBMassStorageDeviceConfiguration struct { + *pointer + + *baseStorageDeviceConfiguration + + // marking as currently reachable. + // This ensures that the object is not freed, and its finalizer is not run + attachment StorageDeviceAttachment +} + +// NewUSBMassStorageDeviceConfiguration initialize a USBMassStorageDeviceConfiguration +// with a device attachment. +// +// This is only supported on macOS 13 and newer, error will +// be returned on older versions. +func NewUSBMassStorageDeviceConfiguration(attachment StorageDeviceAttachment) (*USBMassStorageDeviceConfiguration, error) { + if err := macOSAvailable(13); err != nil { + return nil, err + } + usbMass := &USBMassStorageDeviceConfiguration{ + pointer: objc.NewPointer( + C.newVZUSBMassStorageDeviceConfiguration(objc.Ptr(attachment)), + ), + attachment: attachment, + } + objc.SetFinalizer(usbMass, func(self *USBMassStorageDeviceConfiguration) { + objc.Release(self) + }) + return usbMass, nil +} diff --git a/src/cmd/linuxkit/vendor/github.com/Code-Hex/vz/v3/virtualization.go b/src/cmd/linuxkit/vendor/github.com/Code-Hex/vz/v3/virtualization.go new file mode 100644 index 000000000..9b95df7eb --- /dev/null +++ b/src/cmd/linuxkit/vendor/github.com/Code-Hex/vz/v3/virtualization.go @@ -0,0 +1,345 @@ +package vz + +/* +#cgo darwin CFLAGS: -mmacosx-version-min=11 -x objective-c -fno-objc-arc +#cgo darwin LDFLAGS: -lobjc -framework Foundation -framework Virtualization -framework Cocoa +# include "virtualization_11.h" +# include "virtualization_12.h" +# include "virtualization_13.h" +*/ +import "C" +import ( + "runtime/cgo" + "sync" + "unsafe" + + "github.com/Code-Hex/vz/v3/internal/objc" +) + +func init() { + C.sharedApplication() +} + +// VirtualMachineState represents execution state of the virtual machine. +// +//go:generate stringer -type=VirtualMachineState +type VirtualMachineState int + +const ( + // VirtualMachineStateStopped Initial state before the virtual machine is started. + VirtualMachineStateStopped VirtualMachineState = iota + + // VirtualMachineStateRunning Running virtual machine. + VirtualMachineStateRunning + + // VirtualMachineStatePaused A started virtual machine is paused. + // This state can only be transitioned from VirtualMachineStatePausing. + VirtualMachineStatePaused + + // VirtualMachineStateError The virtual machine has encountered an internal error. + VirtualMachineStateError + + // VirtualMachineStateStarting The virtual machine is configuring the hardware and starting. + VirtualMachineStateStarting + + // VirtualMachineStatePausing The virtual machine is being paused. + // This is the intermediate state between VirtualMachineStateRunning and VirtualMachineStatePaused. + VirtualMachineStatePausing + + // VirtualMachineStateResuming The virtual machine is being resumed. + // This is the intermediate state between VirtualMachineStatePaused and VirtualMachineStateRunning. + VirtualMachineStateResuming + + // VZVirtualMachineStateStopping The virtual machine is being stopped. + // This is the intermediate state between VZVirtualMachineStateRunning and VZVirtualMachineStateStop. + VirtualMachineStateStopping +) + +// VirtualMachine represents the entire state of a single virtual machine. +// +// A Virtual Machine is the emulation of a complete hardware machine of the same architecture as the real hardware machine. +// When executing the Virtual Machine, the Virtualization framework uses certain hardware resources and emulates others to provide isolation +// and great performance. +// +// The definition of a virtual machine starts with its configuration. This is done by setting up a VirtualMachineConfiguration struct. +// Once configured, the virtual machine can be started with (*VirtualMachine).Start() method. +// +// Creating a virtual machine using the Virtualization framework requires the app to have the "com.apple.security.virtualization" entitlement. +// see: https://developer.apple.com/documentation/virtualization/vzvirtualmachine?language=objc +type VirtualMachine struct { + // id for this struct. + id string + + // Indicate whether or not virtualization is available. + // + // If virtualization is unavailable, no VirtualMachineConfiguration will validate. + // The validation error of the VirtualMachineConfiguration provides more information about why virtualization is unavailable. + supported bool + + *pointer + dispatchQueue unsafe.Pointer + status cgo.Handle + + mu sync.Mutex +} + +type machineStatus struct { + state VirtualMachineState + stateNotify chan VirtualMachineState + + mu sync.RWMutex +} + +// NewVirtualMachine creates a new VirtualMachine with VirtualMachineConfiguration. +// +// The configuration must be valid. Validation can be performed at runtime with (*VirtualMachineConfiguration).Validate() method. +// The configuration is copied by the initializer. +// +// This is only supported on macOS 11 and newer, error will +// be returned on older versions. +func NewVirtualMachine(config *VirtualMachineConfiguration) (*VirtualMachine, error) { + if err := macOSAvailable(11); err != nil { + return nil, err + } + + // should not call Free function for this string. + cs := (*char)(objc.GetUUID()) + dispatchQueue := C.makeDispatchQueue(cs.CString()) + + status := cgo.NewHandle(&machineStatus{ + state: VirtualMachineState(0), + stateNotify: make(chan VirtualMachineState), + }) + + v := &VirtualMachine{ + id: cs.String(), + pointer: objc.NewPointer( + C.newVZVirtualMachineWithDispatchQueue( + objc.Ptr(config), + dispatchQueue, + unsafe.Pointer(&status), + ), + ), + dispatchQueue: dispatchQueue, + status: status, + } + + objc.SetFinalizer(v, func(self *VirtualMachine) { + self.status.Delete() + objc.ReleaseDispatch(self.dispatchQueue) + objc.Release(self) + }) + return v, nil +} + +// SocketDevices return the list of socket devices configured on this virtual machine. +// Return an empty array if no socket device is configured. +// +// Since only NewVirtioSocketDeviceConfiguration is available in vz package, +// it will always return VirtioSocketDevice. +// see: https://developer.apple.com/documentation/virtualization/vzvirtualmachine/3656702-socketdevices?language=objc +func (v *VirtualMachine) SocketDevices() []*VirtioSocketDevice { + nsArray := objc.NewNSArray( + C.VZVirtualMachine_socketDevices(objc.Ptr(v)), + ) + ptrs := nsArray.ToPointerSlice() + socketDevices := make([]*VirtioSocketDevice, len(ptrs)) + for i, ptr := range ptrs { + socketDevices[i] = newVirtioSocketDevice(ptr, v.dispatchQueue) + } + return socketDevices +} + +//export changeStateOnObserver +func changeStateOnObserver(state C.int, cgoHandlerPtr unsafe.Pointer) { + status := *(*cgo.Handle)(cgoHandlerPtr) + // I expected it will not cause panic. + // if caused panic, that's unexpected behavior. + v, _ := status.Value().(*machineStatus) + v.mu.Lock() + newState := VirtualMachineState(state) + v.state = newState + // for non-blocking + go func() { v.stateNotify <- newState }() + v.mu.Unlock() +} + +// State represents execution state of the virtual machine. +func (v *VirtualMachine) State() VirtualMachineState { + // I expected it will not cause panic. + // if caused panic, that's unexpected behavior. + val, _ := v.status.Value().(*machineStatus) + val.mu.RLock() + defer val.mu.RUnlock() + return val.state +} + +// StateChangedNotify gets notification is changed execution state of the virtual machine. +func (v *VirtualMachine) StateChangedNotify() <-chan VirtualMachineState { + // I expected it will not cause panic. + // if caused panic, that's unexpected behavior. + val, _ := v.status.Value().(*machineStatus) + val.mu.RLock() + defer val.mu.RUnlock() + return val.stateNotify +} + +// CanStart returns true if the machine is in a state that can be started. +func (v *VirtualMachine) CanStart() bool { + return bool(C.vmCanStart(objc.Ptr(v), v.dispatchQueue)) +} + +// CanPause returns true if the machine is in a state that can be paused. +func (v *VirtualMachine) CanPause() bool { + return bool(C.vmCanPause(objc.Ptr(v), v.dispatchQueue)) +} + +// CanResume returns true if the machine is in a state that can be resumed. +func (v *VirtualMachine) CanResume() bool { + return (bool)(C.vmCanResume(objc.Ptr(v), v.dispatchQueue)) +} + +// CanRequestStop returns whether the machine is in a state where the guest can be asked to stop. +func (v *VirtualMachine) CanRequestStop() bool { + return (bool)(C.vmCanRequestStop(objc.Ptr(v), v.dispatchQueue)) +} + +// CanStop returns whether the machine is in a state that can be stopped. +// +// This is only supported on macOS 12 and newer, false will always be returned +// on older versions. +func (v *VirtualMachine) CanStop() bool { + if err := macOSAvailable(12); err != nil { + return false + } + return (bool)(C.vmCanStop(objc.Ptr(v), v.dispatchQueue)) +} + +//export virtualMachineCompletionHandler +func virtualMachineCompletionHandler(cgoHandlerPtr, errPtr unsafe.Pointer) { + cgoHandler := *(*cgo.Handle)(cgoHandlerPtr) + + handler := cgoHandler.Value().(func(error)) + + if err := newNSError(errPtr); err != nil { + handler(err) + } else { + handler(nil) + } +} + +func makeHandler() (func(error), chan error) { + ch := make(chan error, 1) + return func(err error) { + ch <- err + close(ch) + }, ch +} + +type virtualMachineStartOptions struct { + macOSVirtualMachineStartOptionsPtr unsafe.Pointer +} + +// VirtualMachineStartOption is an option for virtual machine start. +type VirtualMachineStartOption func(*virtualMachineStartOptions) error + +// Start a virtual machine that is in either Stopped or Error state. +// +// If you want to listen status change events, use the "StateChangedNotify" method. +// +// If options are specified, also checks whether these options are +// available in use your macOS version available. +func (v *VirtualMachine) Start(opts ...VirtualMachineStartOption) error { + o := &virtualMachineStartOptions{} + for _, optFunc := range opts { + if err := optFunc(o); err != nil { + return err + } + } + + h, errCh := makeHandler() + handler := cgo.NewHandle(h) + defer handler.Delete() + + if o.macOSVirtualMachineStartOptionsPtr != nil { + C.startWithOptionsCompletionHandler( + objc.Ptr(v), + v.dispatchQueue, + o.macOSVirtualMachineStartOptionsPtr, + unsafe.Pointer(&handler), + ) + } else { + C.startWithCompletionHandler(objc.Ptr(v), v.dispatchQueue, unsafe.Pointer(&handler)) + } + return <-errCh +} + +// Pause a virtual machine that is in Running state. +// +// If you want to listen status change events, use the "StateChangedNotify" method. +func (v *VirtualMachine) Pause() error { + h, errCh := makeHandler() + handler := cgo.NewHandle(h) + defer handler.Delete() + C.pauseWithCompletionHandler(objc.Ptr(v), v.dispatchQueue, unsafe.Pointer(&handler)) + return <-errCh +} + +// Resume a virtual machine that is in the Paused state. +// +// If you want to listen status change events, use the "StateChangedNotify" method. +func (v *VirtualMachine) Resume() error { + h, errCh := makeHandler() + handler := cgo.NewHandle(h) + defer handler.Delete() + C.resumeWithCompletionHandler(objc.Ptr(v), v.dispatchQueue, unsafe.Pointer(&handler)) + return <-errCh +} + +// RequestStop requests that the guest turns itself off. +// +// If returned error is not nil, assigned with the error if the request failed. +// Returns true if the request was made successfully. +func (v *VirtualMachine) RequestStop() (bool, error) { + nserrPtr := newNSErrorAsNil() + ret := (bool)(C.requestStopVirtualMachine(objc.Ptr(v), v.dispatchQueue, &nserrPtr)) + if err := newNSError(nserrPtr); err != nil { + return ret, err + } + return ret, nil +} + +// Stop stops a VM that’s in either a running or paused state. +// +// The completion handler returns an error object when the VM fails to stop, +// or nil if the stop was successful. +// +// If you want to listen status change events, use the "StateChangedNotify" method. +// +// Warning: This is a destructive operation. It stops the VM without +// giving the guest a chance to stop cleanly. +// +// This is only supported on macOS 12 and newer, error will be returned on older versions. +func (v *VirtualMachine) Stop() error { + if err := macOSAvailable(12); err != nil { + return err + } + h, errCh := makeHandler() + handler := cgo.NewHandle(h) + defer handler.Delete() + C.stopWithCompletionHandler(objc.Ptr(v), v.dispatchQueue, unsafe.Pointer(&handler)) + return <-errCh +} + +// StartGraphicApplication starts an application to display graphics of the VM. +// +// You must to call runtime.LockOSThread before calling this method. +// +// This is only supported on macOS 12 and newer, error will be returned on older versions. +func (v *VirtualMachine) StartGraphicApplication(width, height float64) error { + if err := macOSAvailable(12); err != nil { + return err + } + C.startVirtualMachineWindow(objc.Ptr(v), C.double(width), C.double(height)) + return nil +} diff --git a/src/cmd/linuxkit/vendor/github.com/Code-Hex/vz/virtualization.h b/src/cmd/linuxkit/vendor/github.com/Code-Hex/vz/v3/virtualization_11.h similarity index 51% rename from src/cmd/linuxkit/vendor/github.com/Code-Hex/vz/virtualization.h rename to src/cmd/linuxkit/vendor/github.com/Code-Hex/vz/v3/virtualization_11.h index 5286cb114..92b1000ea 100644 --- a/src/cmd/linuxkit/vendor/github.com/Code-Hex/vz/virtualization.h +++ b/src/cmd/linuxkit/vendor/github.com/Code-Hex/vz/v3/virtualization_11.h @@ -1,24 +1,29 @@ // -// virtualization.h +// virtualization_11.h // // Created by codehex. // #pragma once -#import +#import "virtualization_helper.h" #import /* exported from cgo */ -void startHandler(void *err, char *id); -void pauseHandler(void *err, char *id); -void resumeHandler(void *err, char *id); -void changeStateOnObserver(int state, char *id); +void connectionHandler(void *connection, void *err, void *cgoHandlerPtr); +void changeStateOnObserver(int state, void *cgoHandler); +bool shouldAcceptNewConnectionHandler(void *cgoHandler, void *connection, void *socketDevice); @interface Observer : NSObject - (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context; @end +/* VZVirtioSocketListener */ +@interface VZVirtioSocketListenerDelegateImpl : NSObject +- (instancetype)initWithHandler:(void *)cgoHandler; +- (BOOL)listener:(VZVirtioSocketListener *)listener shouldAcceptNewConnection:(VZVirtioSocketConnection *)connection fromSocketDevice:(VZVirtioSocketDevice *)socketDevice; +@end + /* BootLoader */ void *newVZLinuxBootLoader(const char *kernelPath); void setCommandLineVZLinuxBootLoader(void *bootLoaderPtr, const char *commandLine); @@ -26,21 +31,27 @@ void setInitialRamdiskURLVZLinuxBootLoader(void *bootLoaderPtr, const char *ramd /* VirtualMachineConfiguration */ bool validateVZVirtualMachineConfiguration(void *config, void **error); +unsigned long long minimumAllowedMemorySizeVZVirtualMachineConfiguration(); +unsigned long long maximumAllowedMemorySizeVZVirtualMachineConfiguration(); +unsigned int minimumAllowedCPUCountVZVirtualMachineConfiguration(); +unsigned int maximumAllowedCPUCountVZVirtualMachineConfiguration(); void *newVZVirtualMachineConfiguration(void *bootLoader, - unsigned int CPUCount, - unsigned long long memorySize); + unsigned int CPUCount, + unsigned long long memorySize); void setEntropyDevicesVZVirtualMachineConfiguration(void *config, - void *entropyDevices); + void *entropyDevices); void setMemoryBalloonDevicesVZVirtualMachineConfiguration(void *config, - void *memoryBalloonDevices); + void *memoryBalloonDevices); void setNetworkDevicesVZVirtualMachineConfiguration(void *config, - void *networkDevices); + void *networkDevices); +void *networkDevicesVZVirtualMachineConfiguration(void *config); void setSerialPortsVZVirtualMachineConfiguration(void *config, - void *serialPorts); + void *serialPorts); void setSocketDevicesVZVirtualMachineConfiguration(void *config, - void *socketDevices); + void *socketDevices); +void *socketDevicesVZVirtualMachineConfiguration(void *config); void setStorageDevicesVZVirtualMachineConfiguration(void *config, - void *storageDevices); + void *storageDevices); /* Configurations */ void *newVZFileHandleSerialPortAttachment(int readFileDescriptor, int writeFileDescriptor); @@ -59,16 +70,30 @@ void *newVZVirtioSocketDeviceConfiguration(); void *newVZMACAddress(const char *macAddress); void *newRandomLocallyAdministeredVZMACAddress(); const char *getVZMACAddressString(void *macAddress); +void *newVZVirtioSocketListener(void *cgoHandlerPtr); +void *VZVirtualMachine_socketDevices(void *machine); +void VZVirtioSocketDevice_setSocketListenerForPort(void *socketDevice, void *vmQueue, void *listener, uint32_t port); +void VZVirtioSocketDevice_removeSocketListenerForPort(void *socketDevice, void *vmQueue, uint32_t port); +void VZVirtioSocketDevice_connectToPort(void *socketDevice, void *vmQueue, uint32_t port, void *cgoHandlerPtr); /* VirtualMachine */ -void *newVZVirtualMachineWithDispatchQueue(void *config, void *queue, const char *vmid); +void *newVZVirtualMachineWithDispatchQueue(void *config, void *queue, void *statusHandler); bool requestStopVirtualMachine(void *machine, void *queue, void **error); -void startWithCompletionHandler(void *machine, void *queue, const char *vmid); -void pauseWithCompletionHandler(void *machine, void *queue, const char *vmid); -void resumeWithCompletionHandler(void *machine, void *queue, const char *vmid); +void startWithCompletionHandler(void *machine, void *queue, void *completionHandler); +void pauseWithCompletionHandler(void *machine, void *queue, void *completionHandler); +void resumeWithCompletionHandler(void *machine, void *queue, void *completionHandler); bool vmCanStart(void *machine, void *queue); bool vmCanPause(void *machine, void *queue); bool vmCanResume(void *machine, void *queue); bool vmCanRequestStop(void *machine, void *queue); -void *makeDispatchQueue(const char *label); \ No newline at end of file +void *makeDispatchQueue(const char *label); + +/* VZVirtioSocketConnection */ +typedef struct VZVirtioSocketConnectionFlat { + uint32_t destinationPort; + uint32_t sourcePort; + int fileDescriptor; +} VZVirtioSocketConnectionFlat; + +VZVirtioSocketConnectionFlat convertVZVirtioSocketConnection2Flat(void *connection); diff --git a/src/cmd/linuxkit/vendor/github.com/Code-Hex/vz/v3/virtualization_11.m b/src/cmd/linuxkit/vendor/github.com/Code-Hex/vz/v3/virtualization_11.m new file mode 100644 index 000000000..fb411571d --- /dev/null +++ b/src/cmd/linuxkit/vendor/github.com/Code-Hex/vz/v3/virtualization_11.m @@ -0,0 +1,887 @@ +// +// virtualization_11.m +// +// Created by codehex. +// + +#import "virtualization_11.h" + +char *copyCString(NSString *nss) +{ + const char *cc = [nss UTF8String]; + char *c = calloc([nss length] + 1, 1); + strncpy(c, cc, [nss length]); + return c; +} + +@implementation Observer +- (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context; +{ + + @autoreleasepool { + if ([keyPath isEqualToString:@"state"]) { + int newState = (int)[change[NSKeyValueChangeNewKey] integerValue]; + changeStateOnObserver(newState, context); + } else { + // bool canVal = (bool)[change[NSKeyValueChangeNewKey] boolValue]; + // char *vmid = copyCString((NSString *)context); + // char *key = copyCString(keyPath); + // changeCanPropertyOnObserver(canVal, vmid, key); + // free(vmid); + // free(key); + } + } +} +@end + +@implementation VZVirtioSocketListenerDelegateImpl { + void *_cgoHandler; +} + +- (instancetype)initWithHandler:(void *)cgoHandler +{ + self = [super init]; + _cgoHandler = cgoHandler; + return self; +} + +- (BOOL)listener:(VZVirtioSocketListener *)listener shouldAcceptNewConnection:(VZVirtioSocketConnection *)connection fromSocketDevice:(VZVirtioSocketDevice *)socketDevice; +{ + return (BOOL)shouldAcceptNewConnectionHandler(_cgoHandler, connection, socketDevice); +} +@end + +/*! + @abstract Create a VZLinuxBootLoader with the Linux kernel passed as URL. + @param kernelPath Path of Linux kernel on the local file system. +*/ +void *newVZLinuxBootLoader(const char *kernelPath) +{ + if (@available(macOS 11, *)) { + NSString *kernelPathNSString = [NSString stringWithUTF8String:kernelPath]; + NSURL *kernelURL = [NSURL fileURLWithPath:kernelPathNSString]; + return [[VZLinuxBootLoader alloc] initWithKernelURL:kernelURL]; + } + + RAISE_UNSUPPORTED_MACOS_EXCEPTION(); +} + +/*! + @abstract Set the command-line parameters. + @param bootLoader VZLinuxBootLoader + @param commandLine The command-line parameters passed to the kernel on boot. + @link https://www.kernel.org/doc/html/latest/admin-guide/kernel-parameters.html + */ +void setCommandLineVZLinuxBootLoader(void *bootLoaderPtr, const char *commandLine) +{ + if (@available(macOS 11, *)) { + NSString *commandLineNSString = [NSString stringWithUTF8String:commandLine]; + [(VZLinuxBootLoader *)bootLoaderPtr setCommandLine:commandLineNSString]; + return; + } + + RAISE_UNSUPPORTED_MACOS_EXCEPTION(); +} + +/*! + @abstract Set the optional initial RAM disk. + @param bootLoader VZLinuxBootLoader + @param ramdiskPath The RAM disk is mapped into memory before booting the kernel. + @link https://www.kernel.org/doc/html/latest/admin-guide/kernel-parameters.html + */ +void setInitialRamdiskURLVZLinuxBootLoader(void *bootLoaderPtr, const char *ramdiskPath) +{ + if (@available(macOS 11, *)) { + NSString *ramdiskPathNSString = [NSString stringWithUTF8String:ramdiskPath]; + NSURL *ramdiskURL = [NSURL fileURLWithPath:ramdiskPathNSString]; + [(VZLinuxBootLoader *)bootLoaderPtr setInitialRamdiskURL:ramdiskURL]; + return; + } + + RAISE_UNSUPPORTED_MACOS_EXCEPTION(); +} + +/*! + @abstract Validate the configuration. + @param config Virtual machine configuration. + @param error If not nil, assigned with the validation error if the validation failed. + @return true if the configuration is valid. + */ +bool validateVZVirtualMachineConfiguration(void *config, void **error) +{ + if (@available(macOS 11, *)) { + return (bool)[(VZVirtualMachineConfiguration *)config + validateWithError:(NSError *_Nullable *_Nullable)error]; + } + + RAISE_UNSUPPORTED_MACOS_EXCEPTION(); +} + +/*! + @abstract: Minimum amount of memory required by virtual machines. + @see VZVirtualMachineConfiguration.memorySize + */ +unsigned long long minimumAllowedMemorySizeVZVirtualMachineConfiguration() +{ + if (@available(macOS 11, *)) { + return (unsigned long long)[VZVirtualMachineConfiguration minimumAllowedMemorySize]; + } + + RAISE_UNSUPPORTED_MACOS_EXCEPTION(); +} + +/*! + @abstract: Maximum amount of memory allowed for a virtual machine. + @see VZVirtualMachineConfiguration.memorySize + */ +unsigned long long maximumAllowedMemorySizeVZVirtualMachineConfiguration() +{ + if (@available(macOS 11, *)) { + return (unsigned long long)[VZVirtualMachineConfiguration maximumAllowedMemorySize]; + } + + RAISE_UNSUPPORTED_MACOS_EXCEPTION(); +} + +/*! + @abstract: Minimum number of CPUs for a virtual machine. + @see VZVirtualMachineConfiguration.CPUCount + */ +unsigned int minimumAllowedCPUCountVZVirtualMachineConfiguration() +{ + if (@available(macOS 11, *)) { + return (unsigned int)[VZVirtualMachineConfiguration minimumAllowedCPUCount]; + } + + RAISE_UNSUPPORTED_MACOS_EXCEPTION(); +} + +/*! + @abstract: Maximum number of CPUs for a virtual machine. + @see VZVirtualMachineConfiguration.CPUCount + */ +unsigned int maximumAllowedCPUCountVZVirtualMachineConfiguration() +{ + if (@available(macOS 11, *)) { + return (unsigned int)[VZVirtualMachineConfiguration maximumAllowedCPUCount]; + } + + RAISE_UNSUPPORTED_MACOS_EXCEPTION(); +} + +/*! + @abstract Create a new Virtual machine configuration. + @param bootLoader Boot loader used when the virtual machine starts. + + @param CPUCount Number of CPUs. + @discussion + The number of CPUs must be a value between VZVirtualMachineConfiguration.minimumAllowedCPUCount + and VZVirtualMachineConfiguration.maximumAllowedCPUCount. + + @see VZVirtualMachineConfiguration.minimumAllowedCPUCount + @see VZVirtualMachineConfiguration.maximumAllowedCPUCount + + @param memorySize Virtual machine memory size in bytes. + @discussion + The memory size must be a multiple of a 1 megabyte (1024 * 1024 bytes) between VZVirtualMachineConfiguration.minimumAllowedMemorySize + and VZVirtualMachineConfiguration.maximumAllowedMemorySize. + + The memorySize represents the total physical memory seen by a guest OS running in the virtual machine. + Not all memory is allocated on start, the virtual machine allocates memory on demand. + @see VZVirtualMachineConfiguration.minimumAllowedMemorySize + @see VZVirtualMachineConfiguration.maximumAllowedMemorySize + */ +void *newVZVirtualMachineConfiguration(void *bootLoaderPtr, + unsigned int CPUCount, + unsigned long long memorySize) +{ + if (@available(macOS 11, *)) { + VZVirtualMachineConfiguration *config = [[VZVirtualMachineConfiguration alloc] init]; + [config setBootLoader:(VZLinuxBootLoader *)bootLoaderPtr]; + [config setCPUCount:(NSUInteger)CPUCount]; + [config setMemorySize:memorySize]; + return config; + } + + RAISE_UNSUPPORTED_MACOS_EXCEPTION(); +} + +/*! + @abstract List of entropy devices. Empty by default. + @see VZVirtioEntropyDeviceConfiguration +*/ +void setEntropyDevicesVZVirtualMachineConfiguration(void *config, + void *entropyDevices) +{ + if (@available(macOS 11, *)) { + [(VZVirtualMachineConfiguration *)config setEntropyDevices:[(NSMutableArray *)entropyDevices copy]]; + return; + } + + RAISE_UNSUPPORTED_MACOS_EXCEPTION(); +} + +/*! + @abstract List of memory balloon devices. Empty by default. + @see VZVirtioTraditionalMemoryBalloonDeviceConfiguration +*/ +void setMemoryBalloonDevicesVZVirtualMachineConfiguration(void *config, + void *memoryBalloonDevices) +{ + if (@available(macOS 11, *)) { + [(VZVirtualMachineConfiguration *)config setMemoryBalloonDevices:[(NSMutableArray *)memoryBalloonDevices copy]]; + return; + } + + RAISE_UNSUPPORTED_MACOS_EXCEPTION(); +} + +/*! + @abstract List of network adapters. Empty by default. + @see VZVirtioNetworkDeviceConfiguration + */ +void setNetworkDevicesVZVirtualMachineConfiguration(void *config, + void *networkDevices) +{ + if (@available(macOS 11, *)) { + [(VZVirtualMachineConfiguration *)config setNetworkDevices:[(NSMutableArray *)networkDevices copy]]; + return; + } + + RAISE_UNSUPPORTED_MACOS_EXCEPTION(); +} + +/*! + @abstract Return the list of network devices configurations for this VZVirtualMachineConfiguration. Return an empty array if no network device configuration is set. + */ +void *networkDevicesVZVirtualMachineConfiguration(void *config) +{ + if (@available(macOS 11, *)) { + return [(VZVirtualMachineConfiguration *)config networkDevices]; // NSArray + } + + RAISE_UNSUPPORTED_MACOS_EXCEPTION(); +} + +/*! + @abstract List of serial ports. Empty by default. + @see VZVirtioConsoleDeviceSerialPortConfiguration + */ +void setSerialPortsVZVirtualMachineConfiguration(void *config, + void *serialPorts) +{ + if (@available(macOS 11, *)) { + [(VZVirtualMachineConfiguration *)config setSerialPorts:[(NSMutableArray *)serialPorts copy]]; + return; + } + + RAISE_UNSUPPORTED_MACOS_EXCEPTION(); +} + +/*! + @abstract List of socket devices. Empty by default. + @see VZVirtioSocketDeviceConfiguration + */ +void setSocketDevicesVZVirtualMachineConfiguration(void *config, + void *socketDevices) +{ + if (@available(macOS 11, *)) { + [(VZVirtualMachineConfiguration *)config setSocketDevices:[(NSMutableArray *)socketDevices copy]]; + return; + } + + RAISE_UNSUPPORTED_MACOS_EXCEPTION(); +} + +/*! + @abstract Return the list of socket devices configurations for this VZVirtualMachineConfiguration. Return an empty array if no socket device configuration is set. + */ +void *socketDevicesVZVirtualMachineConfiguration(void *config) +{ + if (@available(macOS 11, *)) { + return [(VZVirtualMachineConfiguration *)config socketDevices]; // NSArray + } + + RAISE_UNSUPPORTED_MACOS_EXCEPTION(); +} + +/*! + @abstract List of disk devices. Empty by default. + @see VZVirtioBlockDeviceConfiguration + */ +void setStorageDevicesVZVirtualMachineConfiguration(void *config, + void *storageDevices) +{ + if (@available(macOS 11, *)) { + [(VZVirtualMachineConfiguration *)config setStorageDevices:[(NSMutableArray *)storageDevices copy]]; + return; + } + + RAISE_UNSUPPORTED_MACOS_EXCEPTION(); +} + +/*! + @abstract Intialize the VZFileHandleSerialPortAttachment from file descriptors. + @param readFileDescriptor File descriptor for reading from the file. + @param writeFileDescriptor File descriptor for writing to the file. + @discussion + Each file descriptor must a valid. +*/ +void *newVZFileHandleSerialPortAttachment(int readFileDescriptor, int writeFileDescriptor) +{ + if (@available(macOS 11, *)) { + VZFileHandleSerialPortAttachment *ret; + @autoreleasepool { + NSFileHandle *fileHandleForReading = [[NSFileHandle alloc] initWithFileDescriptor:readFileDescriptor]; + NSFileHandle *fileHandleForWriting = [[NSFileHandle alloc] initWithFileDescriptor:writeFileDescriptor]; + ret = [[VZFileHandleSerialPortAttachment alloc] + initWithFileHandleForReading:fileHandleForReading + fileHandleForWriting:fileHandleForWriting]; + } + return ret; + } + + RAISE_UNSUPPORTED_MACOS_EXCEPTION(); +} + +/*! + @abstract Initialize the VZFileSerialPortAttachment from a URL of a file. + @param filePath The path of the file for the attachment on the local file system. + @param shouldAppend True if the file should be opened in append mode, false otherwise. + When a file is opened in append mode, writing to that file will append to the end of it. + @param error If not nil, used to report errors if initialization fails. + @return A VZFileSerialPortAttachment on success. Nil otherwise and the error parameter is populated if set. + */ +void *newVZFileSerialPortAttachment(const char *filePath, bool shouldAppend, void **error) +{ + if (@available(macOS 11, *)) { + NSString *filePathNSString = [NSString stringWithUTF8String:filePath]; + NSURL *fileURL = [NSURL fileURLWithPath:filePathNSString]; + return [[VZFileSerialPortAttachment alloc] + initWithURL:fileURL + append:(BOOL)shouldAppend + error:(NSError *_Nullable *_Nullable)error]; + } + + RAISE_UNSUPPORTED_MACOS_EXCEPTION(); +} + +/*! + @abstract Create a new Virtio Console Serial Port Device configuration + @param attachment Base class for a serial port attachment. + @discussion + The device creates a console which enables communication between the host and the guest through the Virtio interface. + + The device sets up a single port on the Virtio console device. + */ +void *newVZVirtioConsoleDeviceSerialPortConfiguration(void *attachment) +{ + if (@available(macOS 11, *)) { + VZVirtioConsoleDeviceSerialPortConfiguration *config = [[VZVirtioConsoleDeviceSerialPortConfiguration alloc] init]; + [config setAttachment:(VZSerialPortAttachment *)attachment]; + return config; + } + + RAISE_UNSUPPORTED_MACOS_EXCEPTION(); +} + +/*! + @abstract Create a new Network device attachment bridging a host physical interface with a virtual network device. + @param networkInterface a network interface that bridges a physical interface. + @discussion + A bridged network allows the virtual machine to use the same physical interface as the host. Both host and virtual machine + send and receive packets on the same physical interface but have distinct network layers. + + The bridge network device attachment is used with a VZNetworkDeviceConfiguration to define a virtual network device. + + Using a VZBridgedNetworkDeviceAttachment requires the app to have the "com.apple.vm.networking" entitlement. + + @see VZBridgedNetworkInterface + @see VZNetworkDeviceConfiguration + @see VZVirtioNetworkDeviceConfiguration + */ +void *newVZBridgedNetworkDeviceAttachment(void *networkInterface) +{ + if (@available(macOS 11, *)) { + return [[VZBridgedNetworkDeviceAttachment alloc] initWithInterface:(VZBridgedNetworkInterface *)networkInterface]; + } + + RAISE_UNSUPPORTED_MACOS_EXCEPTION(); +} + +/*! + @abstract Create a new Network device attachment using network address translation (NAT) with outside networks. + @discussion + Using the NAT attachment type, the host serves as router and performs network address translation for accesses to outside networks. + + @see VZNetworkDeviceConfiguration + @see VZVirtioNetworkDeviceConfiguration + */ +void *newVZNATNetworkDeviceAttachment() +{ + if (@available(macOS 11, *)) { + return [[VZNATNetworkDeviceAttachment alloc] init]; + } + + RAISE_UNSUPPORTED_MACOS_EXCEPTION(); +} + +/*! + @abstract Create a new Network device attachment sending raw network packets over a file handle. + @discussion + The file handle attachment transmits the raw packets/frames between the virtual network interface and a file handle. + The data transmitted through this attachment is at the level of the data link layer. + + The file handle must hold a connected datagram socket. + + @see VZNetworkDeviceConfiguration + @see VZVirtioNetworkDeviceConfiguration + */ +void *newVZFileHandleNetworkDeviceAttachment(int fileDescriptor) +{ + if (@available(macOS 11, *)) { + VZFileHandleNetworkDeviceAttachment *ret; + @autoreleasepool { + NSFileHandle *fileHandle = [[NSFileHandle alloc] initWithFileDescriptor:fileDescriptor]; + ret = [[VZFileHandleNetworkDeviceAttachment alloc] initWithFileHandle:fileHandle]; + } + return ret; + } + + RAISE_UNSUPPORTED_MACOS_EXCEPTION(); +} + +/*! + @abstract Create a new Configuration of a paravirtualized network device of type Virtio Network Device. + @discussion + The communication channel used on the host is defined through the attachment. It is set with the VZNetworkDeviceConfiguration.attachment property. + + The configuration is only valid with valid MACAddress and attachment. + + @see VZVirtualMachineConfiguration.networkDevices + + @param attachment Base class for a network device attachment. + @discussion + A network device attachment defines how a virtual network device interfaces with the host system. + + VZNetworkDeviceAttachment should not be instantiated directly. One of its subclasses should be used instead. + + Common attachment types include: + - VZNATNetworkDeviceAttachment + - VZFileHandleNetworkDeviceAttachment + + @see VZBridgedNetworkDeviceAttachment + @see VZFileHandleNetworkDeviceAttachment + @see VZNATNetworkDeviceAttachment + */ +void *newVZVirtioNetworkDeviceConfiguration(void *attachment) +{ + if (@available(macOS 11, *)) { + VZVirtioNetworkDeviceConfiguration *config = [[VZVirtioNetworkDeviceConfiguration alloc] init]; + [config setAttachment:(VZNetworkDeviceAttachment *)attachment]; + return config; + } + + RAISE_UNSUPPORTED_MACOS_EXCEPTION(); +} + +/*! + @abstract Create a new Virtio Entropy Device confiuration + @discussion The device exposes a source of entropy for the guest's random number generator. +*/ +void *newVZVirtioEntropyDeviceConfiguration() +{ + if (@available(macOS 11, *)) { + return [[VZVirtioEntropyDeviceConfiguration alloc] init]; + } + + RAISE_UNSUPPORTED_MACOS_EXCEPTION(); +} + +/*! + @abstract Initialize a VZVirtioBlockDeviceConfiguration with a device attachment. + @param attachment The storage device attachment. This defines how the virtualized device operates on the host side. + @see VZDiskImageStorageDeviceAttachment + */ +void *newVZVirtioBlockDeviceConfiguration(void *attachment) +{ + if (@available(macOS 11, *)) { + return [[VZVirtioBlockDeviceConfiguration alloc] initWithAttachment:(VZStorageDeviceAttachment *)attachment]; + } + + RAISE_UNSUPPORTED_MACOS_EXCEPTION(); +} + +/*! + @abstract Initialize the attachment from a local file url. + @param diskPath Local file path to the disk image in RAW format. + @param readOnly If YES, the device attachment is read-only, otherwise the device can write data to the disk image. + @param error If not nil, assigned with the error if the initialization failed. + @return A VZDiskImageStorageDeviceAttachment on success. Nil otherwise and the error parameter is populated if set. + */ +void *newVZDiskImageStorageDeviceAttachment(const char *diskPath, bool readOnly, void **error) +{ + if (@available(macOS 11, *)) { + NSString *diskPathNSString = [NSString stringWithUTF8String:diskPath]; + NSURL *diskURL = [NSURL fileURLWithPath:diskPathNSString]; + return [[VZDiskImageStorageDeviceAttachment alloc] + initWithURL:diskURL + readOnly:(BOOL)readOnly + error:(NSError *_Nullable *_Nullable)error]; + } + + RAISE_UNSUPPORTED_MACOS_EXCEPTION(); +} + +/*! + @abstract Create a configuration of the Virtio traditional memory balloon device. + @discussion + This configuration creates a Virtio traditional memory balloon device which allows for managing guest memory. + Only one Virtio traditional memory balloon device can be used per virtual machine. + @see VZVirtioTraditionalMemoryBalloonDevice + */ +void *newVZVirtioTraditionalMemoryBalloonDeviceConfiguration() +{ + if (@available(macOS 11, *)) { + return [[VZVirtioTraditionalMemoryBalloonDeviceConfiguration alloc] init]; + } + + RAISE_UNSUPPORTED_MACOS_EXCEPTION(); +} + +/*! + @abstract Create a configuration of the Virtio socket device. + @discussion + This configuration creates a Virtio socket device for the guest which communicates with the host through the Virtio interface. + + Only one Virtio socket device can be used per virtual machine. + @see VZVirtioSocketDevice + */ +void *newVZVirtioSocketDeviceConfiguration() +{ + if (@available(macOS 11, *)) { + return [[VZVirtioSocketDeviceConfiguration alloc] init]; + } + + RAISE_UNSUPPORTED_MACOS_EXCEPTION(); +} + +/*! + @abstract The VZVirtioSocketListener object represents a listener for the Virtio socket device. + @discussion + The listener encompasses a VZVirtioSocketListenerDelegate object. + VZVirtioSocketListener is used with VZVirtioSocketDevice to listen to a particular port. + The delegate is used when a guest connects to a port associated with the listener. + @see VZVirtioSocketDevice + @see VZVirtioSocketListenerDelegate + */ +void *newVZVirtioSocketListener(void *cgoHandlerPtr) +{ + if (@available(macOS 11, *)) { + VZVirtioSocketListener *ret = [[VZVirtioSocketListener alloc] init]; + [ret setDelegate:[[VZVirtioSocketListenerDelegateImpl alloc] initWithHandler:cgoHandlerPtr]]; + return ret; + } + + RAISE_UNSUPPORTED_MACOS_EXCEPTION(); +} + +/*! + @abstract Sets a listener at a specified port. + @discussion + There is only one listener per port, any existing listener will be removed, and the specified listener here will be set instead. + The same listener can be registered on multiple ports. + The listener's delegate will be called whenever the guest connects to that port. + @param listener The VZVirtioSocketListener object to be set. + @param port The port number to set the listener at. + */ +void VZVirtioSocketDevice_setSocketListenerForPort(void *socketDevice, void *vmQueue, void *listener, uint32_t port) +{ + if (@available(macOS 11, *)) { + dispatch_sync((dispatch_queue_t)vmQueue, ^{ + [(VZVirtioSocketDevice *)socketDevice setSocketListener:(VZVirtioSocketListener *)listener forPort:port]; + }); + return; + } + + RAISE_UNSUPPORTED_MACOS_EXCEPTION(); +} + +/*! + @abstract Removes the listener at a specfied port. + @discussion Does nothing if the port had no listener. + @param port The port number at which the listener is to be removed. + */ +void VZVirtioSocketDevice_removeSocketListenerForPort(void *socketDevice, void *vmQueue, uint32_t port) +{ + if (@available(macOS 11, *)) { + dispatch_sync((dispatch_queue_t)vmQueue, ^{ + [(VZVirtioSocketDevice *)socketDevice removeSocketListenerForPort:port]; + }); + return; + } + + RAISE_UNSUPPORTED_MACOS_EXCEPTION(); +} + +/*! + @abstract Connects to a specified port. + @discussion Does nothing if the guest does not listen on that port. + @param port The port number to connect to. + @param completionHandler Block called after the connection has been successfully established or on error. + The error parameter passed to the block is nil if the connection was successful. + */ +void VZVirtioSocketDevice_connectToPort(void *socketDevice, void *vmQueue, uint32_t port, void *cgoHandlerPtr) +{ + if (@available(macOS 11, *)) { + dispatch_async((dispatch_queue_t)vmQueue, ^{ + [(VZVirtioSocketDevice *)socketDevice connectToPort:port + completionHandler:^(VZVirtioSocketConnection *connection, NSError *err) { + connectionHandler(connection, err, cgoHandlerPtr); + }]; + }); + return; + } + + RAISE_UNSUPPORTED_MACOS_EXCEPTION(); +} + +VZVirtioSocketConnectionFlat convertVZVirtioSocketConnection2Flat(void *connection) +{ + if (@available(macOS 11, *)) { + VZVirtioSocketConnectionFlat ret; + ret.sourcePort = [(VZVirtioSocketConnection *)connection sourcePort]; + ret.destinationPort = [(VZVirtioSocketConnection *)connection destinationPort]; + ret.fileDescriptor = [(VZVirtioSocketConnection *)connection fileDescriptor]; + return ret; + } + + RAISE_UNSUPPORTED_MACOS_EXCEPTION(); +} + +/*! + @abstract Initialize the virtual machine. + @param config The configuration of the virtual machine. + The configuration must be valid. Validation can be performed at runtime with [VZVirtualMachineConfiguration validateWithError:]. + The configuration is copied by the initializer. + @param queue The serial queue on which the virtual machine operates. + Every operation on the virtual machine must be done on that queue. The callbacks and delegate methods are invoked on that queue. + If the queue is not serial, the behavior is undefined. + */ +void *newVZVirtualMachineWithDispatchQueue(void *config, void *queue, void *statusHandler) +{ + if (@available(macOS 11, *)) { + VZVirtualMachine *vm = [[VZVirtualMachine alloc] + initWithConfiguration:(VZVirtualMachineConfiguration *)config + queue:(dispatch_queue_t)queue]; + @autoreleasepool { + Observer *o = [[Observer alloc] init]; + [vm addObserver:o + forKeyPath:@"state" + options:NSKeyValueObservingOptionNew + context:statusHandler]; + } + return vm; + } + + RAISE_UNSUPPORTED_MACOS_EXCEPTION(); +} + +/*! + @abstract Return the list of socket devices configured on this virtual machine. Return an empty array if no socket device is configured. + @see VZVirtioSocketDeviceConfiguration + @see VZVirtualMachineConfiguration + */ +void *VZVirtualMachine_socketDevices(void *machine) +{ + if (@available(macOS 11, *)) { + return [(VZVirtualMachine *)machine socketDevices]; // NSArray + } + + RAISE_UNSUPPORTED_MACOS_EXCEPTION(); +} + +/*! + @abstract Initialize the VZMACAddress from a string representation of a MAC address. + @param string + The string should be formatted representing the 6 bytes in hexadecimal separated by a colon character. + e.g. "01:23:45:ab:cd:ef" + + The alphabetical characters can appear lowercase or uppercase. + @return A VZMACAddress or nil if the string is not formatted correctly. + */ +void *newVZMACAddress(const char *macAddress) +{ + if (@available(macOS 11, *)) { + NSString *str = [NSString stringWithUTF8String:macAddress]; + return [[VZMACAddress alloc] initWithString:str]; + } + + RAISE_UNSUPPORTED_MACOS_EXCEPTION(); +} + +/*! + @abstract Create a valid, random, unicast, locally administered address. + @discussion The generated address is not guaranteed to be unique. + */ +void *newRandomLocallyAdministeredVZMACAddress() +{ + if (@available(macOS 11, *)) { + return [VZMACAddress randomLocallyAdministeredAddress]; + } + + RAISE_UNSUPPORTED_MACOS_EXCEPTION(); +} + +/*! + @abstract Sets the media access control address of the device. + */ +void setNetworkDevicesVZMACAddress(void *config, void *macAddress) +{ + if (@available(macOS 11, *)) { + [(VZNetworkDeviceConfiguration *)config setMACAddress:[(VZMACAddress *)macAddress copy]]; + return; + } + + RAISE_UNSUPPORTED_MACOS_EXCEPTION(); +} + +/*! + @abstract The address represented as a string. + @discussion + The 6 bytes are represented in hexadecimal form, separated by a colon character. + Alphabetical characters are lowercase. + + The address is compatible with the parameter of -[VZMACAddress initWithString:]. + */ +const char *getVZMACAddressString(void *macAddress) +{ + if (@available(macOS 11, *)) { + return [[(VZMACAddress *)macAddress string] UTF8String]; + } + + RAISE_UNSUPPORTED_MACOS_EXCEPTION(); +} + +/*! + @abstract Request that the guest turns itself off. + @param error If not nil, assigned with the error if the request failed. + @return YES if the request was made successfully. + */ +bool requestStopVirtualMachine(void *machine, void *queue, void **error) +{ + if (@available(macOS 11, *)) { + __block BOOL ret; + dispatch_sync((dispatch_queue_t)queue, ^{ + ret = [(VZVirtualMachine *)machine requestStopWithError:(NSError *_Nullable *_Nullable)error]; + }); + return (bool)ret; + } + + RAISE_UNSUPPORTED_MACOS_EXCEPTION(); +} + +void *makeDispatchQueue(const char *label) +{ + // dispatch_queue_attr_t attr = dispatch_queue_attr_make_with_qos_class(DISPATCH_QUEUE_SERIAL, QOS_CLASS_DEFAULT, 0); + dispatch_queue_t queue = dispatch_queue_create(label, DISPATCH_QUEUE_SERIAL); + // dispatch_retain(queue); + return queue; +} + +void startWithCompletionHandler(void *machine, void *queue, void *completionHandler) +{ + if (@available(macOS 11, *)) { + vm_completion_handler_t handler = makeVMCompletionHandler(completionHandler); + dispatch_sync((dispatch_queue_t)queue, ^{ + [(VZVirtualMachine *)machine startWithCompletionHandler:handler]; + }); + Block_release(handler); + return; + } + + RAISE_UNSUPPORTED_MACOS_EXCEPTION(); +} + +void pauseWithCompletionHandler(void *machine, void *queue, void *completionHandler) +{ + if (@available(macOS 11, *)) { + vm_completion_handler_t handler = makeVMCompletionHandler(completionHandler); + dispatch_sync((dispatch_queue_t)queue, ^{ + [(VZVirtualMachine *)machine pauseWithCompletionHandler:handler]; + }); + Block_release(handler); + return; + } + + RAISE_UNSUPPORTED_MACOS_EXCEPTION(); +} + +void resumeWithCompletionHandler(void *machine, void *queue, void *completionHandler) +{ + if (@available(macOS 11, *)) { + vm_completion_handler_t handler = makeVMCompletionHandler(completionHandler); + dispatch_sync((dispatch_queue_t)queue, ^{ + [(VZVirtualMachine *)machine resumeWithCompletionHandler:handler]; + }); + Block_release(handler); + return; + } + + RAISE_UNSUPPORTED_MACOS_EXCEPTION(); +} + +// TODO(codehex): use KVO +bool vmCanStart(void *machine, void *queue) +{ + if (@available(macOS 11, *)) { + __block BOOL result; + dispatch_sync((dispatch_queue_t)queue, ^{ + result = ((VZVirtualMachine *)machine).canStart; + }); + return (bool)result; + } + + RAISE_UNSUPPORTED_MACOS_EXCEPTION(); +} + +bool vmCanPause(void *machine, void *queue) +{ + if (@available(macOS 11, *)) { + __block BOOL result; + dispatch_sync((dispatch_queue_t)queue, ^{ + result = ((VZVirtualMachine *)machine).canPause; + }); + return (bool)result; + } + + RAISE_UNSUPPORTED_MACOS_EXCEPTION(); +} + +bool vmCanResume(void *machine, void *queue) +{ + if (@available(macOS 11, *)) { + __block BOOL result; + dispatch_sync((dispatch_queue_t)queue, ^{ + result = ((VZVirtualMachine *)machine).canResume; + }); + return (bool)result; + } + + RAISE_UNSUPPORTED_MACOS_EXCEPTION(); +} + +bool vmCanRequestStop(void *machine, void *queue) +{ + if (@available(macOS 11, *)) { + __block BOOL result; + dispatch_sync((dispatch_queue_t)queue, ^{ + result = ((VZVirtualMachine *)machine).canRequestStop; + }); + return (bool)result; + } + + RAISE_UNSUPPORTED_MACOS_EXCEPTION(); +} + +// --- TODO end diff --git a/src/cmd/linuxkit/vendor/github.com/Code-Hex/vz/v3/virtualization_12.h b/src/cmd/linuxkit/vendor/github.com/Code-Hex/vz/v3/virtualization_12.h new file mode 100644 index 000000000..0623c5c26 --- /dev/null +++ b/src/cmd/linuxkit/vendor/github.com/Code-Hex/vz/v3/virtualization_12.h @@ -0,0 +1,48 @@ +// +// virtualization_12.h +// +// Created by codehex. +// + +#import "virtualization_helper.h" +#import "virtualization_view.h" + +// FIXME(codehex): this is dirty hack to avoid clang-format error like below +// "Configuration file(s) do(es) not support C++: /github.com/Code-Hex/vz/.clang-format" +#define NSURLComponents NSURLComponents + +bool vmCanStop(void *machine, void *queue); +void stopWithCompletionHandler(void *machine, void *queue, void *completionHandler); + +void *newVZGenericPlatformConfiguration(); + +void *newVZVirtioSoundDeviceInputStreamConfiguration(); +void *newVZVirtioSoundDeviceHostInputStreamConfiguration(); // use in Go +void *newVZVirtioSoundDeviceOutputStreamConfiguration(); +void *newVZVirtioSoundDeviceHostOutputStreamConfiguration(); // use in Go + +void *newVZUSBScreenCoordinatePointingDeviceConfiguration(); +void *newVZUSBKeyboardConfiguration(); +void *newVZVirtioSoundDeviceConfiguration(); +void setStreamsVZVirtioSoundDeviceConfiguration(void *audioDeviceConfiguration, void *streams); + +void *newVZSharedDirectory(const char *dirPath, bool readOnly); +void *newVZSingleDirectoryShare(void *sharedDirectory); +void *newVZMultipleDirectoryShare(void *sharedDirectories); +void *newVZVirtioFileSystemDeviceConfiguration(const char *tag, void **error); +void setVZVirtioFileSystemDeviceConfigurationShare(void *config, void *share); + +void setDirectorySharingDevicesVZVirtualMachineConfiguration(void *config, void *directorySharingDevices); +void setPlatformVZVirtualMachineConfiguration(void *config, + void *platform); +void setGraphicsDevicesVZVirtualMachineConfiguration(void *config, + void *graphicsDevices); +void setPointingDevicesVZVirtualMachineConfiguration(void *config, + void *pointingDevices); +void setKeyboardsVZVirtualMachineConfiguration(void *config, + void *keyboards); +void setAudioDevicesVZVirtualMachineConfiguration(void *config, + void *audioDevices); + +void sharedApplication(); +void startVirtualMachineWindow(void *machine, double width, double height); \ No newline at end of file diff --git a/src/cmd/linuxkit/vendor/github.com/Code-Hex/vz/v3/virtualization_12.m b/src/cmd/linuxkit/vendor/github.com/Code-Hex/vz/v3/virtualization_12.m new file mode 100644 index 000000000..567172ba2 --- /dev/null +++ b/src/cmd/linuxkit/vendor/github.com/Code-Hex/vz/v3/virtualization_12.m @@ -0,0 +1,344 @@ +// +// virtualization_12.m +// +// Created by codehex. +// + +#import "virtualization_12.h" + +bool vmCanStop(void *machine, void *queue) +{ + if (@available(macOS 12, *)) { + __block BOOL result; + dispatch_sync((dispatch_queue_t)queue, ^{ + result = ((VZVirtualMachine *)machine).canStop; + }); + return (bool)result; + } + + RAISE_UNSUPPORTED_MACOS_EXCEPTION(); +} + +void stopWithCompletionHandler(void *machine, void *queue, void *completionHandler) +{ + if (@available(macOS 12, *)) { + vm_completion_handler_t handler = makeVMCompletionHandler(completionHandler); + dispatch_sync((dispatch_queue_t)queue, ^{ + [(VZVirtualMachine *)machine stopWithCompletionHandler:handler]; + }); + Block_release(handler); + return; + } + + RAISE_UNSUPPORTED_MACOS_EXCEPTION(); +} + +/*! + @abstract The platform configuration for a generic Intel or ARM virtual machine. +*/ +void *newVZGenericPlatformConfiguration() +{ + if (@available(macOS 12, *)) { + return [[VZGenericPlatformConfiguration alloc] init]; + } + + RAISE_UNSUPPORTED_MACOS_EXCEPTION(); +} + +/*! + @abstract List of directory sharing devices. Empty by default. + @see VZDirectorySharingDeviceConfiguration + */ +void setDirectorySharingDevicesVZVirtualMachineConfiguration(void *config, void *directorySharingDevices) +{ + if (@available(macOS 12, *)) { + [(VZVirtualMachineConfiguration *)config setDirectorySharingDevices:[(NSMutableArray *)directorySharingDevices copy]]; + return; + } + + RAISE_UNSUPPORTED_MACOS_EXCEPTION(); +} + +/*! + @abstract The hardware platform to use. + @discussion + Can be an instance of a VZGenericPlatformConfiguration or VZMacPlatformConfiguration. Defaults to VZGenericPlatformConfiguration. + */ +void setPlatformVZVirtualMachineConfiguration(void *config, void *platform) +{ + if (@available(macOS 12, *)) { + [(VZVirtualMachineConfiguration *)config setPlatform:(VZPlatformConfiguration *)platform]; + return; + } + + RAISE_UNSUPPORTED_MACOS_EXCEPTION(); +} + +/*! + @abstract List of graphics devices. Empty by default. + @see VZMacGraphicsDeviceConfiguration + */ +void setGraphicsDevicesVZVirtualMachineConfiguration(void *config, void *graphicsDevices) +{ + if (@available(macOS 12, *)) { + [(VZVirtualMachineConfiguration *)config setGraphicsDevices:[(NSMutableArray *)graphicsDevices copy]]; + return; + } + + RAISE_UNSUPPORTED_MACOS_EXCEPTION(); +} + +/*! + @abstract List of pointing devices. Empty by default. + @see VZUSBScreenCoordinatePointingDeviceConfiguration + */ +void setPointingDevicesVZVirtualMachineConfiguration(void *config, void *pointingDevices) +{ + if (@available(macOS 12, *)) { + [(VZVirtualMachineConfiguration *)config setPointingDevices:[(NSMutableArray *)pointingDevices copy]]; + return; + } + + RAISE_UNSUPPORTED_MACOS_EXCEPTION(); +} + +/*! + @abstract List of keyboards. Empty by default. + @see VZUSBKeyboardConfiguration + */ +void setKeyboardsVZVirtualMachineConfiguration(void *config, void *keyboards) +{ + if (@available(macOS 12, *)) { + [(VZVirtualMachineConfiguration *)config setKeyboards:[(NSMutableArray *)keyboards copy]]; + return; + } + + RAISE_UNSUPPORTED_MACOS_EXCEPTION(); +} + +/*! + @abstract List of audio devices. Empty by default. + @see VZVirtioSoundDeviceConfiguration + */ +void setAudioDevicesVZVirtualMachineConfiguration(void *config, void *audioDevices) +{ + if (@available(macOS 12, *)) { + [(VZVirtualMachineConfiguration *)config setAudioDevices:[(NSMutableArray *)audioDevices copy]]; + return; + } + + RAISE_UNSUPPORTED_MACOS_EXCEPTION(); +} + +/*! + @abstract Initialize a new Virtio Sound Device Configuration. + @discussion The device exposes a source or destination of sound. + */ +void *newVZVirtioSoundDeviceConfiguration() +{ + if (@available(macOS 12, *)) { + return [[VZVirtioSoundDeviceConfiguration alloc] init]; + } + + RAISE_UNSUPPORTED_MACOS_EXCEPTION(); +} + +/*! + @abstract Set the list of audio streams exposed by this device. Empty by default. +*/ +void setStreamsVZVirtioSoundDeviceConfiguration(void *audioDeviceConfiguration, void *streams) +{ + if (@available(macOS 12, *)) { + [(VZVirtioSoundDeviceConfiguration *)audioDeviceConfiguration setStreams:[(NSMutableArray *)streams copy]]; + return; + } + + RAISE_UNSUPPORTED_MACOS_EXCEPTION(); +} + +/*! + @abstract Initialize a new Virtio Sound Device Input Stream Configuration. + @discussion A PCM stream of input audio data, such as from a microphone. + */ +void *newVZVirtioSoundDeviceInputStreamConfiguration() +{ + if (@available(macOS 12, *)) { + return [[VZVirtioSoundDeviceInputStreamConfiguration alloc] init]; + } + + RAISE_UNSUPPORTED_MACOS_EXCEPTION(); +} + +/*! + @abstract Initialize a new Virtio Sound Device Host Audio Input Stream Configuration. + */ +void *newVZVirtioSoundDeviceHostInputStreamConfiguration() +{ + if (@available(macOS 12, *)) { + VZVirtioSoundDeviceInputStreamConfiguration *inputStream = (VZVirtioSoundDeviceInputStreamConfiguration *)newVZVirtioSoundDeviceInputStreamConfiguration(); + [inputStream setSource:[[VZHostAudioInputStreamSource alloc] init]]; + return inputStream; + } + + RAISE_UNSUPPORTED_MACOS_EXCEPTION(); +} + +/*! + @abstract Initialize a new Virtio Sound Device Output Stream Configuration. + @discussion A PCM stream of output audio data, such as to a speaker. + */ +void *newVZVirtioSoundDeviceOutputStreamConfiguration() +{ + if (@available(macOS 12, *)) { + return [[VZVirtioSoundDeviceOutputStreamConfiguration alloc] init]; + } + + RAISE_UNSUPPORTED_MACOS_EXCEPTION(); +} + +/*! + @abstract Initialize a new Virtio Sound Device Host Audio Output Stream Configuration. + */ +void *newVZVirtioSoundDeviceHostOutputStreamConfiguration() +{ + if (@available(macOS 12, *)) { + VZVirtioSoundDeviceOutputStreamConfiguration *outputStream = (VZVirtioSoundDeviceOutputStreamConfiguration *)newVZVirtioSoundDeviceOutputStreamConfiguration(); + [outputStream setSink:[[VZHostAudioOutputStreamSink alloc] init]]; + return outputStream; + } + + RAISE_UNSUPPORTED_MACOS_EXCEPTION(); +} + +/*! + @abstract Initialize the VZSharedDirectory from the directory path and read only option. + @param dirPath + The directory path that will be share. + @param readOnly + If the directory should be mounted read only. + @return A VZSharedDirectory + */ +void *newVZSharedDirectory(const char *dirPath, bool readOnly) +{ + if (@available(macOS 12, *)) { + NSString *dirPathNSString = [NSString stringWithUTF8String:dirPath]; + NSURL *dirURL = [NSURL fileURLWithPath:dirPathNSString]; + return [[VZSharedDirectory alloc] initWithURL:dirURL readOnly:(BOOL)readOnly]; + } + + RAISE_UNSUPPORTED_MACOS_EXCEPTION(); +} + +/*! + @abstract Initialize the VZSingleDirectoryShare from the shared directory. + @param sharedDirectory + The shared directory to use. + @return A VZSingleDirectoryShare + */ +void *newVZSingleDirectoryShare(void *sharedDirectory) +{ + if (@available(macOS 12, *)) { + return [[VZSingleDirectoryShare alloc] initWithDirectory:(VZSharedDirectory *)sharedDirectory]; + } + + RAISE_UNSUPPORTED_MACOS_EXCEPTION(); +} + +/*! + @abstract Initialize the VZMultipleDirectoryShare from the shared directories. + @param sharedDirectories + NSDictionary mapping names to shared directories. + @return A VZMultipleDirectoryShare + */ +void *newVZMultipleDirectoryShare(void *sharedDirectories) +{ + if (@available(macOS 12, *)) { + return [[VZMultipleDirectoryShare alloc] initWithDirectories:(NSDictionary *)sharedDirectories]; + } + + RAISE_UNSUPPORTED_MACOS_EXCEPTION(); +} + +/*! + @abstract Initialize the VZVirtioFileSystemDeviceConfiguration from the fs tag. + @param tag + The tag to use for this device configuration. + @return A VZVirtioFileSystemDeviceConfiguration + */ +void *newVZVirtioFileSystemDeviceConfiguration(const char *tag, void **error) +{ + if (@available(macOS 12, *)) { + NSString *tagNSString = [NSString stringWithUTF8String:tag]; + BOOL valid = [VZVirtioFileSystemDeviceConfiguration validateTag:tagNSString error:(NSError *_Nullable *_Nullable)error]; + if (!valid) { + return nil; + } + return [[VZVirtioFileSystemDeviceConfiguration alloc] initWithTag:tagNSString]; + } + + RAISE_UNSUPPORTED_MACOS_EXCEPTION(); +} + +/*! + @abstract Sets share associated with this configuration. + */ +void setVZVirtioFileSystemDeviceConfigurationShare(void *config, void *share) +{ + if (@available(macOS 12, *)) { + [(VZVirtioFileSystemDeviceConfiguration *)config setShare:(VZDirectoryShare *)share]; + return; + } + + RAISE_UNSUPPORTED_MACOS_EXCEPTION(); +} + +/*! + @abstract Initialize a new configuration for a USB pointing device that reports absolute coordinates. + @discussion This device can be used by VZVirtualMachineView to send pointer events to the virtual machine. + */ +void *newVZUSBScreenCoordinatePointingDeviceConfiguration() +{ + if (@available(macOS 12, *)) { + return [[VZUSBScreenCoordinatePointingDeviceConfiguration alloc] init]; + } + + RAISE_UNSUPPORTED_MACOS_EXCEPTION(); +} + +/*! + @abstract Initialize a new configuration for a USB keyboard. + @discussion This device can be used by VZVirtualMachineView to send key events to the virtual machine. + */ +void *newVZUSBKeyboardConfiguration() +{ + if (@available(macOS 12, *)) { + return [[VZUSBKeyboardConfiguration alloc] init]; + } + + RAISE_UNSUPPORTED_MACOS_EXCEPTION(); +} + +void sharedApplication() +{ + // Create a shared app instance. + // This will initialize the global variable + // 'NSApp' with the application instance. + [VZApplication sharedApplication]; +} + +void startVirtualMachineWindow(void *machine, double width, double height) +{ + if (@available(macOS 12, *)) { + @autoreleasepool { + AppDelegate *appDelegate = [[[AppDelegate alloc] + initWithVirtualMachine:(VZVirtualMachine *)machine + windowWidth:(CGFloat)width + windowHeight:(CGFloat)height] autorelease]; + + NSApp.delegate = appDelegate; + [NSApp run]; + return; + } + } + RAISE_UNSUPPORTED_MACOS_EXCEPTION(); +} diff --git a/src/cmd/linuxkit/vendor/github.com/Code-Hex/vz/v3/virtualization_12_3.h b/src/cmd/linuxkit/vendor/github.com/Code-Hex/vz/v3/virtualization_12_3.h new file mode 100644 index 000000000..5d210cd00 --- /dev/null +++ b/src/cmd/linuxkit/vendor/github.com/Code-Hex/vz/v3/virtualization_12_3.h @@ -0,0 +1,16 @@ +// +// virtualization_12_3.h +// +// Created by codehex. +// + +#pragma once + +#import "virtualization_helper.h" +#import + +// FIXME(codehex): this is dirty hack to avoid clang-format error like below +// "Configuration file(s) do(es) not support C++: /github.com/Code-Hex/vz/.clang-format" +#define NSURLComponents NSURLComponents + +void setBlockDeviceIdentifierVZVirtioBlockDeviceConfiguration(void *blockDeviceConfig, const char *identifier, void **error); \ No newline at end of file diff --git a/src/cmd/linuxkit/vendor/github.com/Code-Hex/vz/v3/virtualization_12_3.m b/src/cmd/linuxkit/vendor/github.com/Code-Hex/vz/v3/virtualization_12_3.m new file mode 100644 index 000000000..196b638d4 --- /dev/null +++ b/src/cmd/linuxkit/vendor/github.com/Code-Hex/vz/v3/virtualization_12_3.m @@ -0,0 +1,25 @@ +// +// virtualization_12_3.m +// +// Created by codehex. +// + +#import "virtualization_12_3.h" + +void setBlockDeviceIdentifierVZVirtioBlockDeviceConfiguration(void *blockDeviceConfig, const char *identifier, void **error) +{ +#ifdef INCLUDE_TARGET_OSX_12_3 + if (@available(macOS 12.3, *)) { + NSString *identifierNSString = [NSString stringWithUTF8String:identifier]; + BOOL valid = [VZVirtioBlockDeviceConfiguration + validateBlockDeviceIdentifier:identifierNSString + error:(NSError *_Nullable *_Nullable)error]; + if (!valid) { + return; + } + [(VZVirtioBlockDeviceConfiguration *)blockDeviceConfig setBlockDeviceIdentifier:identifierNSString]; + return; + } +#endif + RAISE_UNSUPPORTED_MACOS_EXCEPTION(); +} \ No newline at end of file diff --git a/src/cmd/linuxkit/vendor/github.com/Code-Hex/vz/v3/virtualization_12_arm64.h b/src/cmd/linuxkit/vendor/github.com/Code-Hex/vz/v3/virtualization_12_arm64.h new file mode 100644 index 000000000..50bf12c7f --- /dev/null +++ b/src/cmd/linuxkit/vendor/github.com/Code-Hex/vz/v3/virtualization_12_arm64.h @@ -0,0 +1,76 @@ +// +// virtualization_12_arm64.h +// +// Created by codehex. +// + +#pragma once + +#import "virtualization_helper.h" +#import +#import +#import + +#ifdef __arm64__ + +@interface ProgressObserver : NSObject +- (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context; +@end + +typedef struct VZMacOSRestoreImageStruct { + const char *url; + const char *buildVersion; + NSOperatingSystemVersion operatingSystemVersion; + void *mostFeaturefulSupportedConfiguration; // (VZMacOSConfigurationRequirements *) +} VZMacOSRestoreImageStruct; + +typedef struct VZMacOSConfigurationRequirementsStruct { + uint64_t minimumSupportedCPUCount; + uint64_t minimumSupportedMemorySize; + void *hardwareModel; // (VZMacHardwareModel *) +} VZMacOSConfigurationRequirementsStruct; + +typedef struct VZMacHardwareModelStruct { + bool supported; + nbyteslice dataRepresentation; +} VZMacHardwareModelStruct; + +/* exported from cgo */ +void macOSRestoreImageCompletionHandler(void *cgoHandler, void *restoreImage, void *errPtr); +void macOSInstallCompletionHandler(void *cgoHandler, void *errPtr); +void macOSInstallFractionCompletedHandler(void *cgoHandlerPtr, double completed); + +/* Mac Configurations */ +void *newVZMacPlatformConfiguration(); +void *newVZMacAuxiliaryStorageWithCreating(const char *storagePath, void *hardwareModel, void **error); +void *newVZMacAuxiliaryStorage(const char *storagePath); +void *newVZMacPlatformConfiguration(); +void setHardwareModelVZMacPlatformConfiguration(void *config, void *hardwareModel); +void storeHardwareModelDataVZMacPlatformConfiguration(void *config, const char *filePath); +void setMachineIdentifierVZMacPlatformConfiguration(void *config, void *machineIdentifier); +void storeMachineIdentifierDataVZMacPlatformConfiguration(void *config, const char *filePath); +void setAuxiliaryStorageVZMacPlatformConfiguration(void *config, void *auxiliaryStorage); +void *newVZMacOSBootLoader(); +void *newVZMacGraphicsDeviceConfiguration(); +void setDisplaysVZMacGraphicsDeviceConfiguration(void *graphicsConfiguration, void *displays); +void *newVZMacGraphicsDisplayConfiguration(NSInteger widthInPixels, NSInteger heightInPixels, NSInteger pixelsPerInch); +void *newVZMacHardwareModelWithPath(const char *hardwareModelPath); +void *newVZMacHardwareModelWithBytes(void *hardwareModelBytes, int len); +void *newVZMacMachineIdentifier(); +void *newVZMacMachineIdentifierWithPath(const char *machineIdentifierPath); +void *newVZMacMachineIdentifierWithBytes(void *machineIdentifierBytes, int len); +nbyteslice getVZMacMachineIdentifierDataRepresentation(void *machineIdentifierPtr); + +VZMacOSRestoreImageStruct convertVZMacOSRestoreImage2Struct(void *restoreImagePtr); +void fetchLatestSupportedMacOSRestoreImageWithCompletionHandler(void *cgoHandler); +void loadMacOSRestoreImageFile(const char *ipswPath, void *cgoHandler); + +VZMacOSConfigurationRequirementsStruct convertVZMacOSConfigurationRequirements2Struct(void *requirementsPtr); +VZMacHardwareModelStruct convertVZMacHardwareModel2Struct(void *hardwareModelPtr); + +void *newVZMacOSInstaller(void *virtualMachine, void *vmQueue, const char *restoreImageFilePath); +void *newProgressObserverVZMacOSInstaller(); +void installByVZMacOSInstaller(void *installerPtr, void *vmQueue, void *progressObserverPtr, void *completionHandler, void *fractionCompletedHandler); +void cancelInstallVZMacOSInstaller(void *installerPtr); + +#endif \ No newline at end of file diff --git a/src/cmd/linuxkit/vendor/github.com/Code-Hex/vz/v3/virtualization_12_arm64.m b/src/cmd/linuxkit/vendor/github.com/Code-Hex/vz/v3/virtualization_12_arm64.m new file mode 100644 index 000000000..4fbaf6cb7 --- /dev/null +++ b/src/cmd/linuxkit/vendor/github.com/Code-Hex/vz/v3/virtualization_12_arm64.m @@ -0,0 +1,459 @@ +// +// virtualization_12_arm64.m +// +// Created by codehex. +// + +#ifdef __arm64__ +#import "virtualization_12_arm64.h" + +@implementation ProgressObserver +- (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context; +{ + if ([keyPath isEqualToString:@"fractionCompleted"] && [object isKindOfClass:[NSProgress class]]) { + NSProgress *progress = (NSProgress *)object; + macOSInstallFractionCompletedHandler(context, progress.fractionCompleted); + if (progress.finished) { + [progress removeObserver:self forKeyPath:@"fractionCompleted"]; + } + } +} +@end + +/*! + @abstract Write an initialized VZMacAuxiliaryStorage to a storagePath on a file system. + @param storagePath The storagePath to write the auxiliary storage to on the local file system. + @param hardwareModel The hardware model to use. The auxiliary storage can be laid out differently for different hardware models. + @param options Initialization options. + @param error If not nil, used to report errors if creation fails. + @return A newly initialized VZMacAuxiliaryStorage on success. If an error was encountered returns @c nil, and @c error contains the error. + */ +void *newVZMacAuxiliaryStorageWithCreating(const char *storagePath, void *hardwareModel, void **error) +{ + if (@available(macOS 12, *)) { + NSString *storagePathNSString = [NSString stringWithUTF8String:storagePath]; + NSURL *storageURL = [NSURL fileURLWithPath:storagePathNSString]; + return [[VZMacAuxiliaryStorage alloc] initCreatingStorageAtURL:storageURL + hardwareModel:(VZMacHardwareModel *)hardwareModel + options:VZMacAuxiliaryStorageInitializationOptionAllowOverwrite + error:(NSError *_Nullable *_Nullable)error]; + } + + RAISE_UNSUPPORTED_MACOS_EXCEPTION(); +} + +/*! + @abstract Initialize the auxiliary storage from the storagePath of an existing file. + @param URL The URL of the auxiliary storage on the local file system. + @discussion To create a new auxiliary storage, use -[VZMacAuxiliaryStorage initCreatingStorageAtURL:hardwareModel:options:error]. + */ +void *newVZMacAuxiliaryStorage(const char *storagePath) +{ + if (@available(macOS 12, *)) { + NSString *storagePathNSString = [NSString stringWithUTF8String:storagePath]; + NSURL *storageURL = [NSURL fileURLWithPath:storagePathNSString]; + // Use initWithURL: in macOS 13.x + // https://developer.apple.com/documentation/virtualization/vzmacauxiliarystorage?language=objc + return [[VZMacAuxiliaryStorage alloc] initWithContentsOfURL:storageURL]; + } + + RAISE_UNSUPPORTED_MACOS_EXCEPTION(); +} + +/*! + @abstract The platform configuration for booting macOS on Apple Silicon. + @discussion + When creating a virtual machine from scratch, the “hardwareModel” and “auxiliaryStorage” depend on the restore image + that will be used to install macOS. + + To choose the hardware model, start from VZMacOSRestoreImage.mostFeaturefulSupportedConfiguration to get a supported configuration, then + use its VZMacOSConfigurationRequirements.hardwareModel property to get the hardware model. + Use the hardware model to set up VZMacPlatformConfiguration and to initialize a new auxiliary storage with + -[VZMacAuxiliaryStorage initCreatingStorageAtURL:hardwareModel:options:error:]. + + When a virtual machine is saved to disk then loaded again, the “hardwareModel”, “machineIdentifier” and “auxiliaryStorage” + must be restored to their original values. + + If multiple virtual machines are created from the same configuration, each should have a unique “auxiliaryStorage” and “machineIdentifier”. + @seealso VZMacOSRestoreImage + @seealso VZMacOSConfigurationRequirements +*/ +void *newVZMacPlatformConfiguration() +{ + if (@available(macOS 12, *)) { + return [[VZMacPlatformConfiguration alloc] init]; + } + + RAISE_UNSUPPORTED_MACOS_EXCEPTION(); +} + +/*! + @abstract Set the Mac hardware model. + */ +void setHardwareModelVZMacPlatformConfiguration(void *config, void *hardwareModel) +{ + if (@available(macOS 12, *)) { + [(VZMacPlatformConfiguration *)config setHardwareModel:(VZMacHardwareModel *)hardwareModel]; + return; + } + + RAISE_UNSUPPORTED_MACOS_EXCEPTION(); +} + +// Store the hardware model to disk so that we can retrieve them for subsequent boots. +void storeHardwareModelDataVZMacPlatformConfiguration(void *config, const char *filePath) +{ + if (@available(macOS 12, *)) { + VZMacPlatformConfiguration *macPlatformConfiguration = (VZMacPlatformConfiguration *)config; + NSString *filePathNSString = [NSString stringWithUTF8String:filePath]; + NSURL *fileURL = [NSURL fileURLWithPath:filePathNSString]; + [macPlatformConfiguration.hardwareModel.dataRepresentation writeToURL:fileURL atomically:YES]; + return; + } + + RAISE_UNSUPPORTED_MACOS_EXCEPTION(); +} + +/*! + @abstract Set the Mac machine identifier. + @discussion + Running two virtual machines concurrently with the same identifier results in undefined behavior in the guest operating system. + */ +void setMachineIdentifierVZMacPlatformConfiguration(void *config, void *machineIdentifier) +{ + if (@available(macOS 12, *)) { + [(VZMacPlatformConfiguration *)config setMachineIdentifier:(VZMacMachineIdentifier *)machineIdentifier]; + return; + } + + RAISE_UNSUPPORTED_MACOS_EXCEPTION(); +} + +// Store the machine identifier to disk so that we can retrieve them for subsequent boots. +void storeMachineIdentifierDataVZMacPlatformConfiguration(void *config, const char *filePath) +{ + if (@available(macOS 12, *)) { + VZMacPlatformConfiguration *macPlatformConfiguration = (VZMacPlatformConfiguration *)config; + NSString *filePathNSString = [NSString stringWithUTF8String:filePath]; + NSURL *fileURL = [NSURL fileURLWithPath:filePathNSString]; + [macPlatformConfiguration.machineIdentifier.dataRepresentation writeToURL:fileURL atomically:YES]; + return; + } + + RAISE_UNSUPPORTED_MACOS_EXCEPTION(); +} + +/*! + @abstract Set the Mac auxiliary storage. + @discussion + When creating a virtual machine from scratch, the hardware model of the “auxiliaryStorage” must match the hardware model of + the “hardwareModel” property. + */ +void setAuxiliaryStorageVZMacPlatformConfiguration(void *config, void *auxiliaryStorage) +{ + if (@available(macOS 12, *)) { + [(VZMacPlatformConfiguration *)config setAuxiliaryStorage:(VZMacAuxiliaryStorage *)auxiliaryStorage]; + return; + } + + RAISE_UNSUPPORTED_MACOS_EXCEPTION(); +} + +/*! + @abstract Boot loader configuration for booting macOS on Apple Silicon. + @discussion + You must use a VZMacPlatformConfiguration in conjunction with the macOS boot loader. + It is invalid to use it with any other platform configuration. + @see VZMacPlatformConfiguration + @see VZVirtualMachineConfiguration.platform. +*/ +void *newVZMacOSBootLoader() +{ + if (@available(macOS 12, *)) { + return [[VZMacOSBootLoader alloc] init]; + } + + RAISE_UNSUPPORTED_MACOS_EXCEPTION(); +} + +/*! + @abstract Initialize a new configuration for a Mac graphics device. + @discussion This device can be used to attach a display to be shown in a VZVirtualMachineView. +*/ +void *newVZMacGraphicsDeviceConfiguration() +{ + if (@available(macOS 12, *)) { + return [[VZMacGraphicsDeviceConfiguration alloc] init]; + } + + RAISE_UNSUPPORTED_MACOS_EXCEPTION(); +} + +/*! + @abstract Set the displays to be attached to this graphics device. +*/ +void setDisplaysVZMacGraphicsDeviceConfiguration(void *graphicsConfiguration, void *displays) +{ + if (@available(macOS 12, *)) { + [(VZMacGraphicsDeviceConfiguration *)graphicsConfiguration setDisplays:[(NSMutableArray *)displays copy]]; + return; + } + + RAISE_UNSUPPORTED_MACOS_EXCEPTION(); +} + +/*! + @abstract Create a display configuration with the specified pixel dimensions and pixel density. + @param widthInPixels The width of the display, in pixels. + @param heightInPixels The height of the display, in pixels. + @param pixelsPerInch The pixel density as a number of pixels per inch. +*/ +void *newVZMacGraphicsDisplayConfiguration(NSInteger widthInPixels, NSInteger heightInPixels, NSInteger pixelsPerInch) +{ + if (@available(macOS 12, *)) { + return [[VZMacGraphicsDisplayConfiguration alloc] + initWithWidthInPixels:widthInPixels + heightInPixels:heightInPixels + pixelsPerInch:pixelsPerInch]; + } + + RAISE_UNSUPPORTED_MACOS_EXCEPTION(); +} + +/*! + @abstract Get the hardware model described by the specified data representation. + @param dataRepresentation The opaque data representation of the hardware model to be obtained. + */ +void *newVZMacHardwareModelWithPath(const char *hardwareModelPath) +{ + if (@available(macOS 12, *)) { + VZMacHardwareModel *hardwareModel; + NSString *hardwareModelPathNSString = [NSString stringWithUTF8String:hardwareModelPath]; + NSURL *hardwareModelPathURL = [NSURL fileURLWithPath:hardwareModelPathNSString]; + @autoreleasepool { + NSData *hardwareModelData = [[NSData alloc] initWithContentsOfURL:hardwareModelPathURL]; + hardwareModel = [[VZMacHardwareModel alloc] initWithDataRepresentation:hardwareModelData]; + } + return hardwareModel; + } + + RAISE_UNSUPPORTED_MACOS_EXCEPTION(); +} + +void *newVZMacHardwareModelWithBytes(void *hardwareModelBytes, int len) +{ + if (@available(macOS 12, *)) { + VZMacHardwareModel *hardwareModel; + @autoreleasepool { + NSData *hardwareModelData = [[NSData alloc] initWithBytes:hardwareModelBytes length:(NSUInteger)len]; + hardwareModel = [[VZMacHardwareModel alloc] initWithDataRepresentation:hardwareModelData]; + } + return hardwareModel; + } + + RAISE_UNSUPPORTED_MACOS_EXCEPTION(); +} + +/*! + @abstract Create a new unique machine identifier. + */ +void *newVZMacMachineIdentifier() +{ + if (@available(macOS 12, *)) { + return [[VZMacMachineIdentifier alloc] init]; + } + + RAISE_UNSUPPORTED_MACOS_EXCEPTION(); +} + +/*! + @abstract Get the machine identifier described by the specified data representation. + @param dataRepresentation The opaque data representation of the machine identifier to be obtained. + @return A unique identifier identical to the one that generated the dataRepresentation, or nil if the data is invalid. + @see VZMacMachineIdentifier.dataRepresentation + */ +void *newVZMacMachineIdentifierWithPath(const char *machineIdentifierPath) +{ + if (@available(macOS 12, *)) { + VZMacMachineIdentifier *machineIdentifier; + NSString *machineIdentifierPathNSString = [NSString stringWithUTF8String:machineIdentifierPath]; + NSURL *machineIdentifierPathURL = [NSURL fileURLWithPath:machineIdentifierPathNSString]; + @autoreleasepool { + NSData *machineIdentifierData = [[NSData alloc] initWithContentsOfURL:machineIdentifierPathURL]; + machineIdentifier = [[VZMacMachineIdentifier alloc] initWithDataRepresentation:machineIdentifierData]; + } + return machineIdentifier; + } + + RAISE_UNSUPPORTED_MACOS_EXCEPTION(); +} + +void *newVZMacMachineIdentifierWithBytes(void *machineIdentifierBytes, int len) +{ + if (@available(macOS 12, *)) { + VZMacMachineIdentifier *machineIdentifier; + @autoreleasepool { + NSData *machineIdentifierData = [[NSData alloc] initWithBytes:machineIdentifierBytes length:(NSUInteger)len]; + machineIdentifier = [[VZMacMachineIdentifier alloc] initWithDataRepresentation:machineIdentifierData]; + } + return machineIdentifier; + } + + RAISE_UNSUPPORTED_MACOS_EXCEPTION(); +} + +nbyteslice getVZMacMachineIdentifierDataRepresentation(void *machineIdentifierPtr) +{ + if (@available(macOS 12, *)) { + VZMacMachineIdentifier *machineIdentifier = (VZMacMachineIdentifier *)machineIdentifierPtr; + NSData *data = [machineIdentifier dataRepresentation]; + nbyteslice ret = { + .ptr = (void *)[data bytes], + .len = (int)[data length], + }; + return ret; + } + + RAISE_UNSUPPORTED_MACOS_EXCEPTION(); +} + +VZMacOSRestoreImageStruct convertVZMacOSRestoreImage2Struct(void *restoreImagePtr) +{ + if (@available(macOS 12, *)) { + VZMacOSRestoreImage *restoreImage = (VZMacOSRestoreImage *)restoreImagePtr; + VZMacOSRestoreImageStruct ret; + ret.url = [[[restoreImage URL] absoluteString] UTF8String]; + ret.buildVersion = [[restoreImage buildVersion] UTF8String]; + ret.operatingSystemVersion = [restoreImage operatingSystemVersion]; + // maybe unnecessary CFBridgingRetain. if use CFBridgingRetain, should use CFRelease. + ret.mostFeaturefulSupportedConfiguration = (void *)CFBridgingRetain([restoreImage mostFeaturefulSupportedConfiguration]); + return ret; + } + + RAISE_UNSUPPORTED_MACOS_EXCEPTION(); +} + +void fetchLatestSupportedMacOSRestoreImageWithCompletionHandler(void *cgoHandler) +{ + if (@available(macOS 12, *)) { + [VZMacOSRestoreImage fetchLatestSupportedWithCompletionHandler:^(VZMacOSRestoreImage *restoreImage, NSError *error) { + VZMacOSRestoreImageStruct restoreImageStruct = convertVZMacOSRestoreImage2Struct(restoreImage); + macOSRestoreImageCompletionHandler(cgoHandler, &restoreImageStruct, error); + }]; + return; + } + + RAISE_UNSUPPORTED_MACOS_EXCEPTION(); +} + +void loadMacOSRestoreImageFile(const char *ipswPath, void *cgoHandler) +{ + if (@available(macOS 12, *)) { + NSString *ipswPathNSString = [NSString stringWithUTF8String:ipswPath]; + NSURL *ipswURL = [NSURL fileURLWithPath:ipswPathNSString]; + [VZMacOSRestoreImage loadFileURL:ipswURL + completionHandler:^(VZMacOSRestoreImage *restoreImage, NSError *error) { + VZMacOSRestoreImageStruct restoreImageStruct = convertVZMacOSRestoreImage2Struct(restoreImage); + macOSRestoreImageCompletionHandler(cgoHandler, &restoreImageStruct, error); + }]; + return; + } + + RAISE_UNSUPPORTED_MACOS_EXCEPTION(); +} + +VZMacOSConfigurationRequirementsStruct convertVZMacOSConfigurationRequirements2Struct(void *requirementsPtr) +{ + if (@available(macOS 12, *)) { + VZMacOSConfigurationRequirements *requirements = (VZMacOSConfigurationRequirements *)requirementsPtr; + VZMacOSConfigurationRequirementsStruct ret; + ret.minimumSupportedCPUCount = (uint64_t)[requirements minimumSupportedCPUCount]; + ret.minimumSupportedMemorySize = (uint64_t)[requirements minimumSupportedMemorySize]; + // maybe unnecessary CFBridgingRetain. if use CFBridgingRetain, should use CFRelease. + ret.hardwareModel = (void *)CFBridgingRetain([requirements hardwareModel]); + return ret; + } + + RAISE_UNSUPPORTED_MACOS_EXCEPTION(); +} + +VZMacHardwareModelStruct convertVZMacHardwareModel2Struct(void *hardwareModelPtr) +{ + if (@available(macOS 12, *)) { + VZMacHardwareModel *hardwareModel = (VZMacHardwareModel *)hardwareModelPtr; + VZMacHardwareModelStruct ret; + ret.supported = (bool)[hardwareModel isSupported]; + NSData *data = [hardwareModel dataRepresentation]; + nbyteslice retByteSlice = { + .ptr = (void *)[data bytes], + .len = (int)[data length], + }; + ret.dataRepresentation = retByteSlice; + return ret; + } + + RAISE_UNSUPPORTED_MACOS_EXCEPTION(); +} + +/*! + @abstract Initialize a VZMacOSInstaller object. + @param virtualMachine The virtual machine that the operating system will be installed onto. + @param restoreImageFileURL A file URL indicating the macOS restore image to install. + @discussion + The virtual machine platform must be macOS and the restore image URL must be a file URL referring to a file on disk or an exception will be raised. + This method must be called on the virtual machine's queue. + */ +void *newVZMacOSInstaller(void *virtualMachine, void *vmQueue, const char *restoreImageFilePath) +{ + if (@available(macOS 12, *)) { + __block VZMacOSInstaller *ret; + NSString *restoreImageFilePathNSString = [NSString stringWithUTF8String:restoreImageFilePath]; + NSURL *restoreImageFileURL = [NSURL fileURLWithPath:restoreImageFilePathNSString]; + dispatch_sync((dispatch_queue_t)vmQueue, ^{ + ret = [[VZMacOSInstaller alloc] initWithVirtualMachine:(VZVirtualMachine *)virtualMachine restoreImageURL:restoreImageFileURL]; + }); + return ret; + } + + RAISE_UNSUPPORTED_MACOS_EXCEPTION(); +} + +void *newProgressObserverVZMacOSInstaller() +{ + return [[ProgressObserver alloc] init]; +} + +void installByVZMacOSInstaller(void *installerPtr, void *vmQueue, void *progressObserverPtr, void *completionHandler, void *fractionCompletedHandler) +{ + if (@available(macOS 12, *)) { + VZMacOSInstaller *installer = (VZMacOSInstaller *)installerPtr; + dispatch_sync((dispatch_queue_t)vmQueue, ^{ + [installer installWithCompletionHandler:^(NSError *error) { + macOSInstallCompletionHandler(completionHandler, error); + }]; + [installer.progress + addObserver:(ProgressObserver *)progressObserverPtr + forKeyPath:@"fractionCompleted" + options:NSKeyValueObservingOptionInitial | NSKeyValueObservingOptionNew + context:fractionCompletedHandler]; + }); + return; + } + + RAISE_UNSUPPORTED_MACOS_EXCEPTION(); +} + +void cancelInstallVZMacOSInstaller(void *installerPtr) +{ + if (@available(macOS 12, *)) { + VZMacOSInstaller *installer = (VZMacOSInstaller *)installerPtr; + if (installer.progress.cancellable) { + [installer.progress cancel]; + } + return; + } + + RAISE_UNSUPPORTED_MACOS_EXCEPTION(); +} + +#endif diff --git a/src/cmd/linuxkit/vendor/github.com/Code-Hex/vz/v3/virtualization_13.h b/src/cmd/linuxkit/vendor/github.com/Code-Hex/vz/v3/virtualization_13.h new file mode 100644 index 000000000..4c0072dac --- /dev/null +++ b/src/cmd/linuxkit/vendor/github.com/Code-Hex/vz/v3/virtualization_13.h @@ -0,0 +1,48 @@ +// +// virtualization_13.h +// +// Created by codehex. +// + +#pragma once + +#import "virtualization_helper.h" +#import + +/* macOS 13 API */ +void setConsoleDevicesVZVirtualMachineConfiguration(void *config, void *consoleDevices); + +void *newVZEFIBootLoader(); +void setVariableStoreVZEFIBootLoader(void *bootLoaderPtr, void *variableStore); +void *newVZEFIVariableStorePath(const char *variableStorePath); +void *newCreatingVZEFIVariableStoreAtPath(const char *variableStorePath, void **error); + +void *newVZGenericMachineIdentifierWithBytes(void *machineIdentifierBytes, int len); +nbyteslice getVZGenericMachineIdentifierDataRepresentation(void *machineIdentifierPtr); +void *newVZGenericMachineIdentifier(); +void setMachineIdentifierVZGenericPlatformConfiguration(void *config, void *machineIdentifier); + +void *newVZUSBMassStorageDeviceConfiguration(void *attachment); +void *newVZVirtioGraphicsDeviceConfiguration(); +void setScanoutsVZVirtioGraphicsDeviceConfiguration(void *graphicsConfiguration, void *scanouts); +void *newVZVirtioGraphicsScanoutConfiguration(NSInteger widthInPixels, NSInteger heightInPixels); + +void *newVZVirtioConsoleDeviceConfiguration(); +void *portsVZVirtioConsoleDeviceConfiguration(void *consoleDevice); +uint32_t maximumPortCountVZVirtioConsolePortConfigurationArray(void *ports); +void *getObjectAtIndexedSubscriptVZVirtioConsolePortConfigurationArray(void *portsPtr, int portIndex); +void setObjectAtIndexedSubscriptVZVirtioConsolePortConfigurationArray(void *portsPtr, void *portConfig, int portIndex); + +void *newVZVirtioConsolePortConfiguration(); +void setNameVZVirtioConsolePortConfiguration(void *consolePortConfig, const char *name); +void setIsConsoleVZVirtioConsolePortConfiguration(void *consolePortConfig, bool isConsole); +void setAttachmentVZVirtioConsolePortConfiguration(void *consolePortConfig, void *serialPortAttachment); +void *newVZSpiceAgentPortAttachment(); +void setSharesClipboardVZSpiceAgentPortAttachment(void *attachment, bool sharesClipboard); +const char *getSpiceAgentPortName(); + +void startWithOptionsCompletionHandler(void *machine, void *queue, void *options, void *completionHandler); + +const char *getMacOSGuestAutomountTag(); + +void setMaximumTransmissionUnitVZFileHandleNetworkDeviceAttachment(void *attachment, NSInteger mtu); \ No newline at end of file diff --git a/src/cmd/linuxkit/vendor/github.com/Code-Hex/vz/v3/virtualization_13.m b/src/cmd/linuxkit/vendor/github.com/Code-Hex/vz/v3/virtualization_13.m new file mode 100644 index 000000000..f6e26a2f3 --- /dev/null +++ b/src/cmd/linuxkit/vendor/github.com/Code-Hex/vz/v3/virtualization_13.m @@ -0,0 +1,478 @@ +// +// virtualization_13.m +// +// Created by codehex. +// + +#import "virtualization_13.h" +#import "virtualization_view.h" + +/*! + @abstract List of console devices. Empty by default. + @see VZVirtioConsoleDeviceConfiguration + */ +void setConsoleDevicesVZVirtualMachineConfiguration(void *config, void *consoleDevices) +{ +#ifdef INCLUDE_TARGET_OSX_13 + if (@available(macOS 13, *)) { + [(VZVirtualMachineConfiguration *)config + setConsoleDevices:[(NSMutableArray *)consoleDevices copy]]; + return; + } +#endif + RAISE_UNSUPPORTED_MACOS_EXCEPTION(); +} + +/*! + @abstract Boot loader configuration for booting guest operating systems expecting an EFI ROM. + @discussion + You must use a VZGenericPlatformConfiguration in conjunction with the EFI boot loader. + It is invalid to use it with any other platform configuration. + @see VZGenericPlatformConfiguration + @see VZVirtualMachineConfiguration.platform. +*/ +void *newVZEFIBootLoader() +{ +#ifdef INCLUDE_TARGET_OSX_13 + if (@available(macOS 13, *)) { + return [[VZEFIBootLoader alloc] init]; + } +#endif + RAISE_UNSUPPORTED_MACOS_EXCEPTION(); +} + +/*! + @abstract Set the EFI variable store. + */ +void setVariableStoreVZEFIBootLoader(void *bootLoaderPtr, void *variableStore) +{ +#ifdef INCLUDE_TARGET_OSX_13 + if (@available(macOS 13, *)) { + [(VZEFIBootLoader *)bootLoaderPtr setVariableStore:(VZEFIVariableStore *)variableStore]; + return; + } +#endif + RAISE_UNSUPPORTED_MACOS_EXCEPTION(); +} + +/*! + @abstract Initialize the variable store from the path of an existing file. + @param variableStorePath The path of the variable store on the local file system. + @discussion To create a new variable store, use -[VZEFIVariableStore initCreatingVariableStoreAtURL:options:error]. + */ +void *newVZEFIVariableStorePath(const char *variableStorePath) +{ +#ifdef INCLUDE_TARGET_OSX_13 + if (@available(macOS 13, *)) { + NSString *variableStorePathNSString = [NSString stringWithUTF8String:variableStorePath]; + NSURL *variableStoreURL = [NSURL fileURLWithPath:variableStorePathNSString]; + return [[VZEFIVariableStore alloc] initWithURL:variableStoreURL]; + } +#endif + RAISE_UNSUPPORTED_MACOS_EXCEPTION(); +} + +/*! + @abstract Write an initialized VZEFIVariableStore to path on a file system. + @param variableStorePath The path to write the variable store to on the local file system. + @param error If not nil, used to report errors if creation fails. + @return A newly initialized VZEFIVariableStore on success. If an error was encountered returns @c nil, and @c error contains the error. + */ +void *newCreatingVZEFIVariableStoreAtPath(const char *variableStorePath, void **error) +{ +#ifdef INCLUDE_TARGET_OSX_13 + if (@available(macOS 13, *)) { + NSString *variableStorePathNSString = [NSString stringWithUTF8String:variableStorePath]; + NSURL *variableStoreURL = [NSURL fileURLWithPath:variableStorePathNSString]; + return [[VZEFIVariableStore alloc] + initCreatingVariableStoreAtURL:variableStoreURL + options:VZEFIVariableStoreInitializationOptionAllowOverwrite + error:(NSError *_Nullable *_Nullable)error]; + } +#endif + RAISE_UNSUPPORTED_MACOS_EXCEPTION(); +} + +/*! + @abstract Get the machine identifier described by the specified data representation. + @param dataRepresentation The opaque data representation of the machine identifier to be obtained. + @return A unique identifier identical to the one that generated the dataRepresentation, or nil if the data is invalid. + @see VZGenericMachineIdentifier.dataRepresentation + */ +void *newVZGenericMachineIdentifierWithBytes(void *machineIdentifierBytes, int len) +{ +#ifdef INCLUDE_TARGET_OSX_13 + if (@available(macOS 13, *)) { + VZGenericMachineIdentifier *machineIdentifier; + @autoreleasepool { + NSData *machineIdentifierData = [[NSData alloc] initWithBytes:machineIdentifierBytes length:(NSUInteger)len]; + machineIdentifier = [[VZGenericMachineIdentifier alloc] initWithDataRepresentation:machineIdentifierData]; + } + return machineIdentifier; + } +#endif + RAISE_UNSUPPORTED_MACOS_EXCEPTION(); +} + +/*! + @abstract Opaque data representation of the machine identifier. + @discussion This can be used to recreate the same machine identifier with -[VZGenericMachineIdentifier initWithDataRepresentation:]. + @see -[VZGenericMachineIdentifier initWithDataRepresentation:] + */ +nbyteslice getVZGenericMachineIdentifierDataRepresentation(void *machineIdentifierPtr) +{ +#ifdef INCLUDE_TARGET_OSX_13 + if (@available(macOS 13, *)) { + VZGenericMachineIdentifier *machineIdentifier = (VZGenericMachineIdentifier *)machineIdentifierPtr; + NSData *data = [machineIdentifier dataRepresentation]; + nbyteslice ret = { + .ptr = (void *)[data bytes], + .len = (int)[data length], + }; + return ret; + } +#endif + RAISE_UNSUPPORTED_MACOS_EXCEPTION(); +} + +/*! + @abstract Create a new unique machine identifier. + */ +void *newVZGenericMachineIdentifier() +{ +#ifdef INCLUDE_TARGET_OSX_13 + if (@available(macOS 13, *)) { + return [[VZGenericMachineIdentifier alloc] init]; + } +#endif + RAISE_UNSUPPORTED_MACOS_EXCEPTION(); +} + +/*! + @abstract Set the machine identifier. + */ +void setMachineIdentifierVZGenericPlatformConfiguration(void *config, void *machineIdentifier) +{ +#ifdef INCLUDE_TARGET_OSX_13 + if (@available(macOS 13, *)) { + [(VZGenericPlatformConfiguration *)config setMachineIdentifier:(VZGenericMachineIdentifier *)machineIdentifier]; + return; + } +#endif + RAISE_UNSUPPORTED_MACOS_EXCEPTION(); +} + +/*! + @abstract Initialize a VZUSBMassStorageDeviceConfiguration with a device attachment. + @param attachment The storage device attachment. This defines how the virtualized device operates on the host side. + @see VZDiskImageStorageDeviceAttachment + */ +void *newVZUSBMassStorageDeviceConfiguration(void *attachment) +{ +#ifdef INCLUDE_TARGET_OSX_13 + if (@available(macOS 13, *)) { + return [[VZUSBMassStorageDeviceConfiguration alloc] + initWithAttachment:(VZStorageDeviceAttachment *)attachment]; + } +#endif + RAISE_UNSUPPORTED_MACOS_EXCEPTION(); +} + +/*! + @abstract Creates a new Configuration for a Virtio graphics device. + @discussion + This device configuration creates a graphics device using paravirtualization. + The emulated device follows the Virtio GPU Device specification. + + This device can be used to attach a display to be shown in a VZVirtualMachineView. +*/ +void *newVZVirtioGraphicsDeviceConfiguration() +{ +#ifdef INCLUDE_TARGET_OSX_13 + if (@available(macOS 13, *)) { + return [[VZVirtioGraphicsDeviceConfiguration alloc] init]; + } +#endif + RAISE_UNSUPPORTED_MACOS_EXCEPTION(); +} + +/*! + @abstract Set the scanouts to be attached to this graphics device. + @discussion + Maximum of one scanout is supported. +*/ +void setScanoutsVZVirtioGraphicsDeviceConfiguration(void *graphicsConfiguration, void *scanouts) +{ +#ifdef INCLUDE_TARGET_OSX_13 + if (@available(macOS 13, *)) { + [(VZVirtioGraphicsDeviceConfiguration *)graphicsConfiguration + setScanouts:[(NSMutableArray *)scanouts copy]]; + return; + } +#endif + RAISE_UNSUPPORTED_MACOS_EXCEPTION(); +} + +/*! + @abstract Create a scanout configuration with the specified pixel dimensions. + @param widthInPixels The width of the scanout, in pixels. + @param heightInPixels The height of the scanout, in pixels. +*/ +void *newVZVirtioGraphicsScanoutConfiguration(NSInteger widthInPixels, NSInteger heightInPixels) +{ +#ifdef INCLUDE_TARGET_OSX_13 + if (@available(macOS 13, *)) { + return [[VZVirtioGraphicsScanoutConfiguration alloc] + initWithWidthInPixels:widthInPixels + heightInPixels:heightInPixels]; + } +#endif + RAISE_UNSUPPORTED_MACOS_EXCEPTION(); +} + +/*! + @abstract Create a new Virtio Console Device + @discussion + This console device enables communication between the host and the guest using console ports through the Virtio interface. + + The device sets up one or more ports via VZVirtioConsolePortConfiguration on the Virtio console device. + @see VZVirtioConsolePortConfiguration + @see VZVirtualMachineConfiguration.consoleDevices + */ +void *newVZVirtioConsoleDeviceConfiguration() +{ +#ifdef INCLUDE_TARGET_OSX_13 + if (@available(macOS 13, *)) { + return [[VZVirtioConsoleDeviceConfiguration alloc] init]; + } +#endif + RAISE_UNSUPPORTED_MACOS_EXCEPTION(); +} + +/*! + @abstract The console ports to be configured for this console device. + */ +void *portsVZVirtioConsoleDeviceConfiguration(void *consoleDevice) +{ +#ifdef INCLUDE_TARGET_OSX_13 + if (@available(macOS 13, *)) { + return [(VZVirtioConsoleDeviceConfiguration *)consoleDevice ports]; // VZVirtioConsolePortConfigurationArray + } +#endif + RAISE_UNSUPPORTED_MACOS_EXCEPTION(); +} + +/*! + @abstract The maximum number of ports allocated by this device. The default is the number of ports attached to this device. + */ +uint32_t maximumPortCountVZVirtioConsolePortConfigurationArray(void *ports) +{ +#ifdef INCLUDE_TARGET_OSX_13 + if (@available(macOS 13, *)) { + return [(VZVirtioConsolePortConfigurationArray *)ports maximumPortCount]; + } +#endif + RAISE_UNSUPPORTED_MACOS_EXCEPTION(); +} + +/*! + @abstract Get a port configuration at the specified index. + */ +void *getObjectAtIndexedSubscriptVZVirtioConsolePortConfigurationArray(void *portsPtr, int portIndex) +{ +#ifdef INCLUDE_TARGET_OSX_13 + if (@available(macOS 13, *)) { + VZVirtioConsolePortConfigurationArray *ports = (VZVirtioConsolePortConfigurationArray *)portsPtr; + return ports[portIndex]; + } +#endif + RAISE_UNSUPPORTED_MACOS_EXCEPTION(); +} + +/*! + @abstract Set a port configuration at the specified index. + */ +void setObjectAtIndexedSubscriptVZVirtioConsolePortConfigurationArray(void *portsPtr, void *portConfig, int portIndex) +{ +#ifdef INCLUDE_TARGET_OSX_13 + if (@available(macOS 13, *)) { + VZVirtioConsolePortConfigurationArray *ports = (VZVirtioConsolePortConfigurationArray *)portsPtr; + ports[portIndex] = (VZVirtioConsolePortConfiguration *)portConfig; + return; + } +#endif + RAISE_UNSUPPORTED_MACOS_EXCEPTION(); +} + +/*! + @abstract Virtio Console Port + @discussion + A console port is a two-way communication channel between a host VZSerialPortAttachment and a virtual machine console port. One or more console ports are attached to a Virtio console device. + + An optional name may be set for a console port. A console port may also be configured for use as the system console. + @see VZConsolePortConfiguration + @see VZVirtualMachineConfiguration.consoleDevices + */ +void *newVZVirtioConsolePortConfiguration() +{ +#ifdef INCLUDE_TARGET_OSX_13 + if (@available(macOS 13, *)) { + return [[VZVirtioConsolePortConfiguration alloc] init]; + } +#endif + RAISE_UNSUPPORTED_MACOS_EXCEPTION(); +} + +/*! + @abstract Set the console port's name. The default behavior is to not use a name unless set. + */ +void setNameVZVirtioConsolePortConfiguration(void *consolePortConfig, const char *name) +{ +#ifdef INCLUDE_TARGET_OSX_13 + if (@available(macOS 13, *)) { + NSString *nameNSString = [NSString stringWithUTF8String:name]; + [(VZVirtioConsolePortConfiguration *)consolePortConfig setName:nameNSString]; + return; + } +#endif + RAISE_UNSUPPORTED_MACOS_EXCEPTION(); +} + +/*! + @abstract Set the console port may be marked for use as the system console. The default is false. + */ +void setIsConsoleVZVirtioConsolePortConfiguration(void *consolePortConfig, bool isConsole) +{ +#ifdef INCLUDE_TARGET_OSX_13 + if (@available(macOS 13, *)) { + [(VZVirtioConsolePortConfiguration *)consolePortConfig setIsConsole:(BOOL)isConsole]; + return; + } +#endif + RAISE_UNSUPPORTED_MACOS_EXCEPTION(); +} + +/*! + @abstract Set the console port attachment. Defines how the virtual machine's console port interfaces with the host system. Default is nil. + @see VZFileHandleSerialPortAttachment + @see VZFileSerialPortAttachment + @see VZSpiceAgentPortAttachment + */ +void setAttachmentVZVirtioConsolePortConfiguration(void *consolePortConfig, void *serialPortAttachment) +{ +#ifdef INCLUDE_TARGET_OSX_13 + if (@available(macOS 13, *)) { + [(VZVirtioConsolePortConfiguration *)consolePortConfig + setAttachment:(VZSerialPortAttachment *)serialPortAttachment]; + return; + } +#endif + RAISE_UNSUPPORTED_MACOS_EXCEPTION(); +} + +void *newVZSpiceAgentPortAttachment() +{ +#ifdef INCLUDE_TARGET_OSX_13 + if (@available(macOS 13, *)) { + return [[VZSpiceAgentPortAttachment alloc] init]; + } +#endif + RAISE_UNSUPPORTED_MACOS_EXCEPTION(); +} + +/*! + @abstract Enable the Spice agent clipboard sharing capability. + @discussion + If enabled, the clipboard capability will be advertised to the Spice guest agent. Copy and paste events + will be shared between the host and the virtual machine. + + This property is enabled by default. + */ +void setSharesClipboardVZSpiceAgentPortAttachment(void *attachment, bool sharesClipboard) +{ +#ifdef INCLUDE_TARGET_OSX_13 + if (@available(macOS 13, *)) { + return [(VZSpiceAgentPortAttachment *)attachment setSharesClipboard:(BOOL)sharesClipboard]; + } +#endif + RAISE_UNSUPPORTED_MACOS_EXCEPTION(); +} + +/*! + @abstract The Spice agent port name. + @discussion + A console port configured with this name will spawn a Spice guest agent if supported by the guest. + + VZConsolePortConfiguration.attachment must be set to VZSpiceAgentPortAttachment. + VZVirtioConsolePortConfiguration.isConsole must remain false on a Spice agent port. + */ +const char *getSpiceAgentPortName() +{ +#ifdef INCLUDE_TARGET_OSX_13 + if (@available(macOS 13, *)) { + return [[VZSpiceAgentPortAttachment spiceAgentPortName] UTF8String]; + } +#endif + RAISE_UNSUPPORTED_MACOS_EXCEPTION(); +} + +/*! + @abstract Start a virtual machine with options. + @discussion + Start a virtual machine that is in either Stopped or Error state. + @param options Options used to control how the virtual machine is started. + @param completionHandler Block called after the virtual machine has been successfully started or on error. + The error parameter passed to the block is nil if the start was successful. + @seealso VZMacOSVirtualMachineStartOptions + */ +void startWithOptionsCompletionHandler(void *machine, void *queue, void *options, void *completionHandler) +{ +#ifdef INCLUDE_TARGET_OSX_13 + if (@available(macOS 13, *)) { + vm_completion_handler_t handler = makeVMCompletionHandler(completionHandler); + dispatch_sync((dispatch_queue_t)queue, ^{ + [(VZVirtualMachine *)machine startWithOptions:options completionHandler:handler]; + }); + Block_release(handler); + return; + } +#endif + RAISE_UNSUPPORTED_MACOS_EXCEPTION(); +} + +/*! + @abstract The macOS automount tag. + @discussion A device configured with this tag will be automatically mounted in a macOS guest. + */ +const char *getMacOSGuestAutomountTag() +{ +#ifdef INCLUDE_TARGET_OSX_13 + if (@available(macOS 13, *)) { + return [[VZVirtioFileSystemDeviceConfiguration macOSGuestAutomountTag] UTF8String]; + } +#endif + RAISE_UNSUPPORTED_MACOS_EXCEPTION(); +} + +/*! + @abstract The maximum transmission unit (MTU) associated with this attachment. + @discussion + The client side of the associated datagram socket must be properly configured with the appropriate values for + `SO_SNDBUF`, and `SO_RCVBUF`, which can be set using the `setsockopt` system call. The value of `SO_RCVBUF` is + expected to be at least double the value of `SO_SNDBUF`, and for optimal performance, the value of `SO_RCVBUF` + is recommended to be four times the value of `SO_SNDBUF`. + + The default MTU is 1500. + The maximum MTU allowed is 65535, and the minimum MTU allowed is 1500. An invalid MTU value will result in an invalid + virtual machine configuration. + */ +void setMaximumTransmissionUnitVZFileHandleNetworkDeviceAttachment(void *attachment, NSInteger mtu) +{ +#ifdef INCLUDE_TARGET_OSX_13 + if (@available(macOS 13, *)) { + [(VZFileHandleNetworkDeviceAttachment *)attachment setMaximumTransmissionUnit:mtu]; + return; + } +#endif + RAISE_UNSUPPORTED_MACOS_EXCEPTION(); +} \ No newline at end of file diff --git a/src/cmd/linuxkit/vendor/github.com/Code-Hex/vz/v3/virtualization_13_arm64.h b/src/cmd/linuxkit/vendor/github.com/Code-Hex/vz/v3/virtualization_13_arm64.h new file mode 100644 index 000000000..4f79596dd --- /dev/null +++ b/src/cmd/linuxkit/vendor/github.com/Code-Hex/vz/v3/virtualization_13_arm64.h @@ -0,0 +1,29 @@ +// +// virtualization_13_arm64.h +// +// Created by codehex. +// + +#pragma once + +#ifdef __arm64__ + +// FIXME(codehex): this is dirty hack to avoid clang-format error like below +// "Configuration file(s) do(es) not support C++: /github.com/Code-Hex/vz/.clang-format" +#define NSURLComponents NSURLComponents + +#import "virtualization_helper.h" +#import + +/* exported from cgo */ +void linuxInstallRosettaWithCompletionHandler(void *cgoHandler, void *errPtr); + +void *newVZLinuxRosettaDirectoryShare(void **error); +void linuxInstallRosetta(void *cgoHandler); +int availabilityVZLinuxRosettaDirectoryShare(); + +void *newVZMacOSVirtualMachineStartOptions(bool startUpFromMacOSRecovery); + +void *newVZMacTrackpadConfiguration(); + +#endif \ No newline at end of file diff --git a/src/cmd/linuxkit/vendor/github.com/Code-Hex/vz/v3/virtualization_13_arm64.m b/src/cmd/linuxkit/vendor/github.com/Code-Hex/vz/v3/virtualization_13_arm64.m new file mode 100644 index 000000000..79c1fdfdf --- /dev/null +++ b/src/cmd/linuxkit/vendor/github.com/Code-Hex/vz/v3/virtualization_13_arm64.m @@ -0,0 +1,89 @@ +// +// virtualization_13_arm64.m +// +// Created by codehex. +// + +#import "virtualization_13_arm64.h" + +/*! + @abstract Initialize a Rosetta directory share if Rosetta support for Linux binaries is installed. + @param error Error object to store the error, if an error exists. + @discussion The call returns an error if Rosetta is not available for a directory share. To install Rosetta support, use +[VZLinuxRosettaDirectoryShare installRosettaWithCompletionHandler:]. + */ +void *newVZLinuxRosettaDirectoryShare(void **error) +{ +#ifdef INCLUDE_TARGET_OSX_13 + if (@available(macOS 13, *)) { + return [[VZLinuxRosettaDirectoryShare alloc] initWithError:(NSError *_Nullable *_Nullable)error]; + } +#endif + RAISE_UNSUPPORTED_MACOS_EXCEPTION(); +} + +/*! + @abstract Download and install Rosetta support for Linux binaries if necessary. + @param completionHandler The completion handler gets called with a valid error on failure and a nil error on success. It will also be invoked on an arbitrary queue. + @discussion + The call prompts the user through the download and install flow for Rosetta. This call is successful if the error is nil. + @see +[VZLinuxRosettaDirectoryShare availability] + */ +void linuxInstallRosetta(void *cgoHandler) +{ +#ifdef INCLUDE_TARGET_OSX_13 + if (@available(macOS 13, *)) { + [VZLinuxRosettaDirectoryShare installRosettaWithCompletionHandler:^(NSError *error) { + linuxInstallRosettaWithCompletionHandler(cgoHandler, error); + }]; + return; + } +#endif + RAISE_UNSUPPORTED_MACOS_EXCEPTION(); +} + +/*! + @abstract Check the availability of Rosetta support for the directory share. + */ +int availabilityVZLinuxRosettaDirectoryShare() +{ +#ifdef INCLUDE_TARGET_OSX_13 + if (@available(macOS 13, *)) { + return (int)[VZLinuxRosettaDirectoryShare availability]; + } +#endif + RAISE_UNSUPPORTED_MACOS_EXCEPTION(); +} + +/*! + @abstract Options controlling startup behavior of a virtual machine using VZMacOSBootLoader. + */ +void *newVZMacOSVirtualMachineStartOptions(bool startUpFromMacOSRecovery) +{ +#ifdef INCLUDE_TARGET_OSX_13 + if (@available(macOS 13, *)) { + VZMacOSVirtualMachineStartOptions *opts = [[VZMacOSVirtualMachineStartOptions alloc] init]; + [opts setStartUpFromMacOSRecovery:(BOOL)startUpFromMacOSRecovery]; + return opts; + } +#endif + RAISE_UNSUPPORTED_MACOS_EXCEPTION(); +} + +/*! + @abstract Configuration for a Mac trackpad. + @discussion + This device can be used by VZVirtualMachineView to send pointer events and multi-touch trackpad gestures to the virtual machine. + Note: this device is only recognized by virtual machines running macOS 13.0 and later. In order to support both macOS 13.0 and earlier + guests, VZVirtualMachineConfiguration.pointingDevices can be set to an array containing both a VZMacTrackpadConfiguration and + a VZUSBScreenCoordinatePointingDeviceConfiguration object. macOS 13.0 and later guests will use the multi-touch trackpad device, + while earlier versions of macOS will use the USB pointing device. + */ +void *newVZMacTrackpadConfiguration() +{ +#ifdef INCLUDE_TARGET_OSX_13 + if (@available(macOS 13, *)) { + return [[VZMacTrackpadConfiguration alloc] init]; + } +#endif + RAISE_UNSUPPORTED_MACOS_EXCEPTION(); +} \ No newline at end of file diff --git a/src/cmd/linuxkit/vendor/github.com/Code-Hex/vz/v3/virtualization_arm64.go b/src/cmd/linuxkit/vendor/github.com/Code-Hex/vz/v3/virtualization_arm64.go new file mode 100644 index 000000000..a0a28e103 --- /dev/null +++ b/src/cmd/linuxkit/vendor/github.com/Code-Hex/vz/v3/virtualization_arm64.go @@ -0,0 +1,578 @@ +//go:build darwin && arm64 +// +build darwin,arm64 + +package vz + +/* +#cgo darwin CFLAGS: -mmacosx-version-min=11 -x objective-c -fno-objc-arc +#cgo darwin LDFLAGS: -lobjc -framework Foundation -framework Virtualization +# include "virtualization_11.h" +# include "virtualization_12_arm64.h" +# include "virtualization_13_arm64.h" +*/ +import "C" +import ( + "context" + "fmt" + "io" + "net/http" + "os" + "runtime/cgo" + "sync" + "sync/atomic" + "unsafe" + + "github.com/Code-Hex/vz/v3/internal/objc" + "github.com/Code-Hex/vz/v3/internal/progress" +) + +// WithStartUpFromMacOSRecovery is an option to specifiy whether to start up +// from macOS Recovery for macOS VM. +// +// This is only supported on macOS 13 and newer, error will +// be returned on older versions. +func WithStartUpFromMacOSRecovery(startInRecovery bool) VirtualMachineStartOption { + return func(vmso *virtualMachineStartOptions) error { + if err := macOSAvailable(13); err != nil { + return err + } + vmso.macOSVirtualMachineStartOptionsPtr = C.newVZMacOSVirtualMachineStartOptions( + C.bool(startInRecovery), + ) + return nil + } +} + +// MacHardwareModel describes a specific virtual Mac hardware model. +type MacHardwareModel struct { + *pointer + + supported bool + dataRepresentation []byte +} + +// NewMacHardwareModelWithDataPath initialize a new hardware model described by the specified pathname. +// +// This is only supported on macOS 12 and newer, error will +// be returned on older versions. +func NewMacHardwareModelWithDataPath(pathname string) (*MacHardwareModel, error) { + b, err := os.ReadFile(pathname) + if err != nil { + return nil, err + } + return NewMacHardwareModelWithData(b) +} + +// NewMacHardwareModelWithData initialize a new hardware model described by the specified data representation. +// +// This is only supported on macOS 12 and newer, error will +// be returned on older versions. +func NewMacHardwareModelWithData(b []byte) (*MacHardwareModel, error) { + if err := macOSAvailable(12); err != nil { + return nil, err + } + + ptr := C.newVZMacHardwareModelWithBytes( + unsafe.Pointer(&b[0]), + C.int(len(b)), + ) + ret := newMacHardwareModel(ptr) + objc.SetFinalizer(ret, func(self *MacHardwareModel) { + objc.Release(self) + }) + return ret, nil +} + +func newMacHardwareModel(ptr unsafe.Pointer) *MacHardwareModel { + ret := C.convertVZMacHardwareModel2Struct(ptr) + dataRepresentation := ret.dataRepresentation + bytePointer := (*byte)(unsafe.Pointer(dataRepresentation.ptr)) + return &MacHardwareModel{ + pointer: objc.NewPointer(ptr), + supported: bool(ret.supported), + // https://github.com/golang/go/wiki/cgo#turning-c-arrays-into-go-slices + dataRepresentation: unsafe.Slice(bytePointer, dataRepresentation.len), + } +} + +// Supported indicate whether this hardware model is supported by the host. +func (m *MacHardwareModel) Supported() bool { return m.supported } + +// DataRepresentation opaque data representation of the hardware model. +// This can be used to recreate the same hardware model with NewMacHardwareModelWithData function. +func (m *MacHardwareModel) DataRepresentation() []byte { return m.dataRepresentation } + +// MacMachineIdentifier an identifier to make a virtual machine unique. +type MacMachineIdentifier struct { + *pointer + + dataRepresentation []byte +} + +// NewMacMachineIdentifierWithDataPath initialize a new machine identifier described by the specified pathname. +// +// This is only supported on macOS 12 and newer, error will +// be returned on older versions. +func NewMacMachineIdentifierWithDataPath(pathname string) (*MacMachineIdentifier, error) { + b, err := os.ReadFile(pathname) + if err != nil { + return nil, err + } + return NewMacMachineIdentifierWithData(b) +} + +// NewMacMachineIdentifierWithData initialize a new machine identifier described by the specified data representation. +// +// This is only supported on macOS 12 and newer, error will +// be returned on older versions. +func NewMacMachineIdentifierWithData(b []byte) (*MacMachineIdentifier, error) { + if err := macOSAvailable(12); err != nil { + return nil, err + } + + ptr := C.newVZMacMachineIdentifierWithBytes( + unsafe.Pointer(&b[0]), + C.int(len(b)), + ) + return newMacMachineIdentifier(ptr), nil +} + +// NewMacMachineIdentifier initialize a new Mac machine identifier is used by macOS guests to uniquely +// identify the virtual hardware. +// +// Two virtual machines running concurrently should not use the same identifier. +// +// If the virtual machine is serialized to disk, the identifier can be preserved in a binary representation through +// DataRepresentation method. +// The identifier can then be recreated with NewMacMachineIdentifierWithData function from the binary representation. +// +// This is only supported on macOS 12 and newer, error will +// be returned on older versions. +func NewMacMachineIdentifier() (*MacMachineIdentifier, error) { + if err := macOSAvailable(12); err != nil { + return nil, err + } + return newMacMachineIdentifier(C.newVZMacMachineIdentifier()), nil +} + +func newMacMachineIdentifier(ptr unsafe.Pointer) *MacMachineIdentifier { + dataRepresentation := C.getVZMacMachineIdentifierDataRepresentation(ptr) + bytePointer := (*byte)(unsafe.Pointer(dataRepresentation.ptr)) + return &MacMachineIdentifier{ + pointer: objc.NewPointer(ptr), + // https://github.com/golang/go/wiki/cgo#turning-c-arrays-into-go-slices + dataRepresentation: unsafe.Slice(bytePointer, dataRepresentation.len), + } +} + +// DataRepresentation opaque data representation of the machine identifier. +// This can be used to recreate the same machine identifier with NewMacMachineIdentifierWithData function. +func (m *MacMachineIdentifier) DataRepresentation() []byte { return m.dataRepresentation } + +// MacAuxiliaryStorage is a struct that contains information the boot loader +// needs for booting macOS as a guest operating system. +type MacAuxiliaryStorage struct { + *pointer + + storagePath string +} + +// NewMacAuxiliaryStorageOption is an option type to initialize a new Mac auxiliary storage +type NewMacAuxiliaryStorageOption func(*MacAuxiliaryStorage) error + +// WithCreatingMacAuxiliaryStorage is an option when initialize a new Mac auxiliary storage with data creation +// to you specified storage path. +func WithCreatingMacAuxiliaryStorage(hardwareModel *MacHardwareModel) NewMacAuxiliaryStorageOption { + return func(mas *MacAuxiliaryStorage) error { + cpath := charWithGoString(mas.storagePath) + defer cpath.Free() + + nserrPtr := newNSErrorAsNil() + mas.pointer = objc.NewPointer( + C.newVZMacAuxiliaryStorageWithCreating( + cpath.CString(), + objc.Ptr(hardwareModel), + &nserrPtr, + ), + ) + if err := newNSError(nserrPtr); err != nil { + return err + } + return nil + } +} + +// NewMacAuxiliaryStorage creates a new MacAuxiliaryStorage is based Mac auxiliary storage data from the storagePath +// of an existing file by default. +// +// This is only supported on macOS 12 and newer, error will +// be returned on older versions. +func NewMacAuxiliaryStorage(storagePath string, opts ...NewMacAuxiliaryStorageOption) (*MacAuxiliaryStorage, error) { + if err := macOSAvailable(12); err != nil { + return nil, err + } + + storage := &MacAuxiliaryStorage{storagePath: storagePath} + for _, opt := range opts { + if err := opt(storage); err != nil { + return nil, err + } + } + + if objc.Ptr(storage) == nil { + cpath := charWithGoString(storagePath) + defer cpath.Free() + storage.pointer = objc.NewPointer( + C.newVZMacAuxiliaryStorage(cpath.CString()), + ) + } + return storage, nil +} + +// MacOSRestoreImage is a struct that describes a version of macOS to install on to a virtual machine. +type MacOSRestoreImage struct { + url string + buildVersion string + operatingSystemVersion OperatingSystemVersion + mostFeaturefulSupportedConfigurationPtr unsafe.Pointer +} + +// URL returns URL of this restore image. +// the value of this property will be a file URL. (https://~) +// the value of this property will be a network URL referring to an installation media file. (file:///~) +func (m *MacOSRestoreImage) URL() string { + return m.url +} + +// BuildVersion returns the build version this restore image contains. +func (m *MacOSRestoreImage) BuildVersion() string { + return m.buildVersion +} + +// OperatingSystemVersion represents the operating system version this restore image contains. +type OperatingSystemVersion struct { + MajorVersion int64 + MinorVersion int64 + PatchVersion int64 +} + +// String returns string for the build version this restore image contains. +func (osv OperatingSystemVersion) String() string { + return fmt.Sprintf("%d.%d.%d", osv.MajorVersion, osv.MinorVersion, osv.PatchVersion) +} + +// OperatingSystemVersion returns the operating system version this restore image contains. +func (m *MacOSRestoreImage) OperatingSystemVersion() OperatingSystemVersion { + return m.operatingSystemVersion +} + +// MostFeaturefulSupportedConfiguration returns the configuration requirements for the most featureful +// configuration supported by the current host and by this restore image. +// +// A MacOSRestoreImage can contain installation media for multiple Mac hardware models (MacHardwareModel). Some of these +// hardware models may not be supported by the current host. This method can be used to determine the hardware model and +// configuration requirements that will provide the most complete feature set on the current host. +// If none of the hardware models are supported on the current host, this property is nil. +func (m *MacOSRestoreImage) MostFeaturefulSupportedConfiguration() *MacOSConfigurationRequirements { + return newMacOSConfigurationRequirements(m.mostFeaturefulSupportedConfigurationPtr) +} + +// MacOSConfigurationRequirements describes the parameter constraints required by a specific configuration of macOS. +// +// When a VZMacOSRestoreImage is loaded, it can be inspected to determine the configurations supported by that restore image. +type MacOSConfigurationRequirements struct { + minimumSupportedCPUCount uint64 + minimumSupportedMemorySize uint64 + hardwareModelPtr unsafe.Pointer +} + +func newMacOSConfigurationRequirements(ptr unsafe.Pointer) *MacOSConfigurationRequirements { + ret := C.convertVZMacOSConfigurationRequirements2Struct(ptr) + return &MacOSConfigurationRequirements{ + minimumSupportedCPUCount: uint64(ret.minimumSupportedCPUCount), + minimumSupportedMemorySize: uint64(ret.minimumSupportedMemorySize), + hardwareModelPtr: ret.hardwareModel, + } +} + +// HardwareModel returns the hardware model for this configuration. +// +// The hardware model can be used to configure a new virtual machine that meets the requirements. +// Use VZMacPlatformConfiguration.hardwareModel to configure the Mac platform, and +// Use `WithCreatingStorage` functional option of the `NewMacAuxiliaryStorage` to create its auxiliary storage. +func (m *MacOSConfigurationRequirements) HardwareModel() *MacHardwareModel { + return newMacHardwareModel(m.hardwareModelPtr) +} + +// MinimumSupportedCPUCount returns the minimum supported number of CPUs for this configuration. +func (m *MacOSConfigurationRequirements) MinimumSupportedCPUCount() uint64 { + return m.minimumSupportedCPUCount +} + +// MinimumSupportedMemorySize returns the minimum supported memory size for this configuration. +func (m *MacOSConfigurationRequirements) MinimumSupportedMemorySize() uint64 { + return m.minimumSupportedMemorySize +} + +type macOSRestoreImageHandler func(restoreImage *MacOSRestoreImage, err error) + +//export macOSRestoreImageCompletionHandler +func macOSRestoreImageCompletionHandler(cgoHandlerPtr, restoreImagePtr, errPtr unsafe.Pointer) { + cgoHandler := *(*cgo.Handle)(cgoHandlerPtr) + + handler := cgoHandler.Value().(macOSRestoreImageHandler) + defer cgoHandler.Delete() + + restoreImageStruct := (*C.VZMacOSRestoreImageStruct)(restoreImagePtr) + + restoreImage := &MacOSRestoreImage{ + url: (*char)(restoreImageStruct.url).String(), + buildVersion: (*char)(restoreImageStruct.buildVersion).String(), + operatingSystemVersion: OperatingSystemVersion{ + MajorVersion: int64(restoreImageStruct.operatingSystemVersion.majorVersion), + MinorVersion: int64(restoreImageStruct.operatingSystemVersion.minorVersion), + PatchVersion: int64(restoreImageStruct.operatingSystemVersion.patchVersion), + }, + mostFeaturefulSupportedConfigurationPtr: restoreImageStruct.mostFeaturefulSupportedConfiguration, + } + + if err := newNSError(errPtr); err != nil { + handler(restoreImage, err) + } else { + handler(restoreImage, nil) + } +} + +// downloadRestoreImage resumable downloads macOS restore image (ipsw) file. +func downloadRestoreImage(ctx context.Context, url string, destPath string) (*progress.Reader, error) { + // open or create + f, err := os.OpenFile(destPath, os.O_APPEND|os.O_CREATE|os.O_WRONLY, 0666) + if err != nil { + return nil, err + } + + fileInfo, err := f.Stat() + if err != nil { + f.Close() + return nil, err + } + + req, err := http.NewRequestWithContext(ctx, "GET", url, nil) + if err != nil { + f.Close() + return nil, err + } + + req.Header.Add("User-Agent", "github.com/Code-Hex/vz") + req.Header.Add("Range", fmt.Sprintf("bytes=%d-", fileInfo.Size())) + + resp, err := http.DefaultClient.Do(req) + if err != nil { + f.Close() + return nil, err + } + + if 200 > resp.StatusCode || resp.StatusCode >= 300 { + f.Close() + resp.Body.Close() + return nil, fmt.Errorf("unexpected http status code: %d", resp.StatusCode) + } + + reader := progress.NewReader(resp.Body, resp.ContentLength, fileInfo.Size()) + + go func() { + defer f.Close() + defer resp.Body.Close() + _, err := io.Copy(f, reader) + reader.Finish(err) + }() + + return reader, nil +} + +// FetchLatestSupportedMacOSRestoreImage fetches the latest macOS restore image supported by this host from the network. +// +// After downloading the restore image, you can initialize a MacOSInstaller using LoadMacOSRestoreImageFromPath function +// with the local restore image file. +// +// This is only supported on macOS 12 and newer, error will +// be returned on older versions. +func FetchLatestSupportedMacOSRestoreImage(ctx context.Context, destPath string) (*progress.Reader, error) { + if err := macOSAvailable(12); err != nil { + return nil, err + } + + waitCh := make(chan struct{}) + var ( + url string + fetchErr error + ) + handler := macOSRestoreImageHandler(func(restoreImage *MacOSRestoreImage, err error) { + url = restoreImage.URL() + fetchErr = err + defer close(waitCh) + }) + cgoHandler := cgo.NewHandle(handler) + C.fetchLatestSupportedMacOSRestoreImageWithCompletionHandler( + unsafe.Pointer(&cgoHandler), + ) + <-waitCh + if fetchErr != nil { + return nil, fetchErr + } + progressReader, err := downloadRestoreImage(ctx, url, destPath) + if err != nil { + return nil, fmt.Errorf("failed to download from %q: %w", url, err) + } + return progressReader, nil +} + +// LoadMacOSRestoreImageFromPath loads a macOS restore image from a filepath on the local file system. +// +// If the imagePath parameter doesn’t refer to a local file, the system raises an exception via Objective-C. +// +// This is only supported on macOS 12 and newer, error will +// be returned on older versions. +func LoadMacOSRestoreImageFromPath(imagePath string) (retImage *MacOSRestoreImage, retErr error) { + if err := macOSAvailable(12); err != nil { + return nil, err + } + if _, err := os.Stat(imagePath); err != nil { + return nil, err + } + + waitCh := make(chan struct{}) + handler := macOSRestoreImageHandler(func(restoreImage *MacOSRestoreImage, err error) { + retImage = restoreImage + retErr = err + close(waitCh) + }) + cgoHandler := cgo.NewHandle(handler) + + cs := charWithGoString(imagePath) + defer cs.Free() + C.loadMacOSRestoreImageFile(cs.CString(), unsafe.Pointer(&cgoHandler)) + <-waitCh + return +} + +// MacOSInstaller is a struct you use to install macOS on the specified virtual machine. +type MacOSInstaller struct { + *pointer + observerPointer *pointer + + vm *VirtualMachine + progress atomic.Value + doneCh chan struct{} + once sync.Once + err error +} + +// NewMacOSInstaller creates a new MacOSInstaller struct. +// +// A param vm is the virtual machine that the operating system will be installed onto. +// A param restoreImageIpsw is a file path indicating the macOS restore image to install. +// +// This is only supported on macOS 12 and newer, error will +// be returned on older versions. +func NewMacOSInstaller(vm *VirtualMachine, restoreImageIpsw string) (*MacOSInstaller, error) { + if err := macOSAvailable(12); err != nil { + return nil, err + } + if _, err := os.Stat(restoreImageIpsw); err != nil { + return nil, err + } + + cs := charWithGoString(restoreImageIpsw) + defer cs.Free() + ret := &MacOSInstaller{ + pointer: objc.NewPointer( + C.newVZMacOSInstaller(objc.Ptr(vm), vm.dispatchQueue, cs.CString()), + ), + observerPointer: objc.NewPointer( + C.newProgressObserverVZMacOSInstaller(), + ), + vm: vm, + doneCh: make(chan struct{}), + } + ret.setFractionCompleted(0) + objc.SetFinalizer(ret, func(self *MacOSInstaller) { + objc.Release(self.observerPointer) + objc.Release(self) + }) + return ret, nil +} + +//export macOSInstallCompletionHandler +func macOSInstallCompletionHandler(cgoHandlerPtr, errPtr unsafe.Pointer) { + cgoHandler := *(*cgo.Handle)(cgoHandlerPtr) + + handler := cgoHandler.Value().(func(error)) + defer cgoHandler.Delete() + + if err := newNSError(errPtr); err != nil { + handler(err) + } else { + handler(nil) + } +} + +//export macOSInstallFractionCompletedHandler +func macOSInstallFractionCompletedHandler(cgoHandlerPtr unsafe.Pointer, completed C.double) { + cgoHandler := *(*cgo.Handle)(cgoHandlerPtr) + + handler := cgoHandler.Value().(func(float64)) + handler(float64(completed)) +} + +// Install starts installing macOS. +// +// This method starts the installation process. The VM must be in a stopped state. +// During the installation operation, pausing or stopping the VM results in an undefined behavior. +func (m *MacOSInstaller) Install(ctx context.Context) error { + select { + case <-ctx.Done(): + return ctx.Err() + default: + } + + m.once.Do(func() { + completionHandler := cgo.NewHandle(func(err error) { + m.err = err + close(m.doneCh) + }) + fractionCompletedHandler := cgo.NewHandle(func(v float64) { + m.setFractionCompleted(v) + }) + + C.installByVZMacOSInstaller( + objc.Ptr(m), + m.vm.dispatchQueue, + objc.Ptr(m.observerPointer), + unsafe.Pointer(&completionHandler), + unsafe.Pointer(&fractionCompletedHandler), + ) + }) + + select { + case <-ctx.Done(): + C.cancelInstallVZMacOSInstaller(objc.Ptr(m)) + return ctx.Err() + case <-m.doneCh: + } + + return m.err +} + +func (m *MacOSInstaller) setFractionCompleted(completed float64) { + m.progress.Store(completed) +} + +// FractionCompleted returns the fraction of the overall work that the install process +// completes. +func (m *MacOSInstaller) FractionCompleted() float64 { + return m.progress.Load().(float64) +} + +// Done recieves a notification that indicates the install process is completed. +func (m *MacOSInstaller) Done() <-chan struct{} { return m.doneCh } diff --git a/src/cmd/linuxkit/vendor/github.com/Code-Hex/vz/v3/virtualization_debug.h b/src/cmd/linuxkit/vendor/github.com/Code-Hex/vz/v3/virtualization_debug.h new file mode 100644 index 000000000..9dae69d10 --- /dev/null +++ b/src/cmd/linuxkit/vendor/github.com/Code-Hex/vz/v3/virtualization_debug.h @@ -0,0 +1,25 @@ +// +// virtualization_debug.h +// +// Created by codehex. +// + +#pragma once + +#import +#import + +@interface _VZDebugStubConfiguration : NSObject +@end + +@interface _VZGDBDebugStubConfiguration : NSObject +@property NSInteger port; +- (instancetype)initWithPort:(NSInteger)port; +@end + +@interface VZVirtualMachineConfiguration () +- (void)_setDebugStub:(_VZDebugStubConfiguration *)config; +@end + +void *newVZGDBDebugStubConfiguration(uint32_t port); +void setDebugStubVZVirtualMachineConfiguration(void *config, void *debugStub); \ No newline at end of file diff --git a/src/cmd/linuxkit/vendor/github.com/Code-Hex/vz/v3/virtualization_debug.m b/src/cmd/linuxkit/vendor/github.com/Code-Hex/vz/v3/virtualization_debug.m new file mode 100644 index 000000000..67fe356ae --- /dev/null +++ b/src/cmd/linuxkit/vendor/github.com/Code-Hex/vz/v3/virtualization_debug.m @@ -0,0 +1,33 @@ +// +// virtualization_debug.m +// +// Created by codehex. +// + +#import "virtualization_debug.h" +#import "virtualization_helper.h" + +/*! + @abstract Create a VZGDBDebugStubConfiguration with debug port for GDB server. +*/ +void *newVZGDBDebugStubConfiguration(uint32_t port) +{ + if (@available(macOS 12, *)) { + return [[_VZGDBDebugStubConfiguration alloc] initWithPort:(NSInteger)port]; + } + + RAISE_UNSUPPORTED_MACOS_EXCEPTION(); +} + +/*! + @abstract _VZDebugStubConfiguration. Empty by default. +*/ +void setDebugStubVZVirtualMachineConfiguration(void *config, void *debugStub) +{ + if (@available(macOS 12, *)) { + [(VZVirtualMachineConfiguration *)config _setDebugStub:(_VZDebugStubConfiguration *)debugStub]; + return; + } + + RAISE_UNSUPPORTED_MACOS_EXCEPTION(); +} \ No newline at end of file diff --git a/src/cmd/linuxkit/vendor/github.com/Code-Hex/vz/v3/virtualization_helper.h b/src/cmd/linuxkit/vendor/github.com/Code-Hex/vz/v3/virtualization_helper.h new file mode 100644 index 000000000..995b40882 --- /dev/null +++ b/src/cmd/linuxkit/vendor/github.com/Code-Hex/vz/v3/virtualization_helper.h @@ -0,0 +1,59 @@ +#pragma once + +#import +#import + +NSDictionary *dumpProcessinfo(); + +#define RAISE_REASON_MESSAGE \ + "This may possibly be a bug due to library handling errors.\n" \ + "I would appreciate it if you could report it to https://github.com/Code-Hex/vz/issues/new/choose\n\n" \ + "Information: %@\n" + +#define RAISE_UNSUPPORTED_MACOS_EXCEPTION() \ + do { \ + [NSException \ + raise:@"UnhandledAvailabilityException" \ + format:@RAISE_REASON_MESSAGE, dumpProcessinfo()]; \ + __builtin_unreachable(); \ + } while (0) + +// for macOS 12.3 API +#if __MAC_OS_X_VERSION_MAX_ALLOWED >= 120300 +#define INCLUDE_TARGET_OSX_12_3 1 +#else +#pragma message("macOS 12.3 API has been disabled") +#endif + +// for macOS 13 API +#if __MAC_OS_X_VERSION_MAX_ALLOWED >= 130000 +#define INCLUDE_TARGET_OSX_13 1 +#else +#pragma message("macOS 13 API has been disabled") +#endif + +static inline int mac_os_x_version_max_allowed() +{ +#ifdef __MAC_OS_X_VERSION_MAX_ALLOWED + return __MAC_OS_X_VERSION_MAX_ALLOWED; +#else + return 0; +#endif +} + +typedef struct nbyteslice { + void *ptr; + int len; +} nbyteslice; + +/* exported from cgo */ +void virtualMachineCompletionHandler(void *cgoHandler, void *errPtr); + +typedef void (^vm_completion_handler_t)(NSError *); + +static inline vm_completion_handler_t makeVMCompletionHandler(void *completionHandler) +{ + return Block_copy(^(NSError *err) { + virtualMachineCompletionHandler(completionHandler, err); + }); +} diff --git a/src/cmd/linuxkit/vendor/github.com/Code-Hex/vz/v3/virtualization_helper.m b/src/cmd/linuxkit/vendor/github.com/Code-Hex/vz/v3/virtualization_helper.m new file mode 100644 index 000000000..9d65b341e --- /dev/null +++ b/src/cmd/linuxkit/vendor/github.com/Code-Hex/vz/v3/virtualization_helper.m @@ -0,0 +1,30 @@ +// +// virtualization_helper.m +// +// Created by codehex. +// + +#import "virtualization_helper.h" + +#ifdef __arm64__ +#define TARGET_ARM64 1 +#else +#define TARGET_ARM64 0 +#endif + +NSDictionary *dumpProcessinfo() +{ + NSString *osVersionString = [[NSProcessInfo processInfo] operatingSystemVersionString]; + return @{ + @"LLVM (Clang) Version" : @__VERSION__, + @"Target for arm64" : @TARGET_ARM64, + // The version of the macOS on which the process is executing. + @"Running OS Version" : osVersionString, +#ifdef __MAC_OS_X_VERSION_MAX_ALLOWED + @"Max Allowed OS Version" : @__MAC_OS_X_VERSION_MAX_ALLOWED, +#endif +#ifdef __MAC_OS_X_VERSION_MIN_REQUIRED + @"Min Required OS Version" : @__MAC_OS_X_VERSION_MIN_REQUIRED, +#endif + }; +} \ No newline at end of file diff --git a/src/cmd/linuxkit/vendor/github.com/Code-Hex/vz/v3/virtualization_view.h b/src/cmd/linuxkit/vendor/github.com/Code-Hex/vz/v3/virtualization_view.h new file mode 100644 index 000000000..ab00b9225 --- /dev/null +++ b/src/cmd/linuxkit/vendor/github.com/Code-Hex/vz/v3/virtualization_view.h @@ -0,0 +1,31 @@ +// +// virtualization_view.h +// +// Created by codehex. +// + +#pragma once + +#import +#import +#import + +@interface VZApplication : NSApplication { + bool shouldKeepRunning; +} +@end + +@interface AboutViewController : NSViewController +- (instancetype)init; +@end + +@interface AboutPanel : NSPanel +- (instancetype)init; +@end + +API_AVAILABLE(macos(12.0)) +@interface AppDelegate : NSObject +- (instancetype)initWithVirtualMachine:(VZVirtualMachine *)virtualMachine + windowWidth:(CGFloat)windowWidth + windowHeight:(CGFloat)windowHeight; +@end \ No newline at end of file diff --git a/src/cmd/linuxkit/vendor/github.com/Code-Hex/vz/v3/virtualization_view.m b/src/cmd/linuxkit/vendor/github.com/Code-Hex/vz/v3/virtualization_view.m new file mode 100644 index 000000000..9031c44f1 --- /dev/null +++ b/src/cmd/linuxkit/vendor/github.com/Code-Hex/vz/v3/virtualization_view.m @@ -0,0 +1,374 @@ +// +// virtualization_view.m +// +// Created by codehex. +// + +#import "virtualization_view.h" + +@implementation VZApplication + +- (void)run +{ + @autoreleasepool { + [self finishLaunching]; + + shouldKeepRunning = YES; + do { + NSEvent *event = [self + nextEventMatchingMask:NSEventMaskAny + untilDate:[NSDate distantFuture] + inMode:NSDefaultRunLoopMode + dequeue:YES]; + // NSLog(@"event: %@", event); + [self sendEvent:event]; + [self updateWindows]; + } while (shouldKeepRunning); + } +} + +- (void)terminate:(id)sender +{ + shouldKeepRunning = NO; + + // We should call this method if we want to use `applicationWillTerminate` method. + // + // [[NSNotificationCenter defaultCenter] + // postNotificationName:NSApplicationWillTerminateNotification + // object:NSApp]; + + // This method is used to end up the event loop. + // If no events are coming, the event loop will always be in a waiting state. + [self postEvent:self.currentEvent atStart:NO]; +} +@end + +@implementation AboutViewController + +- (instancetype)init +{ + self = [super initWithNibName:nil bundle:nil]; + return self; +} + +- (void)loadView +{ + self.view = [NSView new]; + NSImageView *imageView = [NSImageView imageViewWithImage:[NSApp applicationIconImage]]; + NSTextField *appLabel = [self makeLabel:[[NSProcessInfo processInfo] processName]]; + [appLabel setFont:[NSFont boldSystemFontOfSize:16]]; + NSTextField *subLabel = [self makePoweredByLabel]; + + NSStackView *stackView = [NSStackView stackViewWithViews:@[ + imageView, + appLabel, + subLabel, + ]]; + [stackView setOrientation:NSUserInterfaceLayoutOrientationVertical]; + [stackView setDistribution:NSStackViewDistributionFillProportionally]; + [stackView setSpacing:10]; + [stackView setAlignment:NSLayoutAttributeCenterX]; + [stackView setContentCompressionResistancePriority:NSLayoutPriorityRequired forOrientation:NSLayoutConstraintOrientationHorizontal]; + [stackView setContentCompressionResistancePriority:NSLayoutPriorityRequired forOrientation:NSLayoutConstraintOrientationVertical]; + + [self.view addSubview:stackView]; + + [NSLayoutConstraint activateConstraints:@[ + [imageView.widthAnchor constraintEqualToConstant:80], // image size + [imageView.heightAnchor constraintEqualToConstant:80], // image size + [stackView.topAnchor constraintEqualToAnchor:self.view.topAnchor + constant:4], + [stackView.bottomAnchor constraintEqualToAnchor:self.view.bottomAnchor + constant:-16], + [stackView.leadingAnchor constraintEqualToAnchor:self.view.leadingAnchor + constant:32], + [stackView.trailingAnchor constraintEqualToAnchor:self.view.trailingAnchor + constant:-32], + [stackView.widthAnchor constraintEqualToConstant:300] + ]]; +} + +- (NSTextField *)makePoweredByLabel +{ + NSMutableAttributedString *poweredByAttr = [[[NSMutableAttributedString alloc] + initWithString:@"Powered by " + attributes:@{ + NSForegroundColorAttributeName : [NSColor labelColor] + }] autorelease]; + NSURL *repositoryURL = [NSURL URLWithString:@"https://github.com/Code-Hex/vz"]; + NSMutableAttributedString *repository = [self makeHyperLink:@"github.com/Code-Hex/vz" withURL:repositoryURL]; + [poweredByAttr appendAttributedString:repository]; + [poweredByAttr addAttribute:NSFontAttributeName + value:[NSFont systemFontOfSize:12] + range:NSMakeRange(0, [poweredByAttr length])]; + + NSTextField *label = [self makeLabel:@""]; + [label setSelectable:YES]; + [label setAllowsEditingTextAttributes:YES]; + [label setAttributedStringValue:poweredByAttr]; + return label; +} + +- (NSTextField *)makeLabel:(NSString *)label +{ + NSTextField *appLabel = [NSTextField labelWithString:label]; + [appLabel setTextColor:[NSColor labelColor]]; + [appLabel setEditable:NO]; + [appLabel setSelectable:NO]; + [appLabel setBezeled:NO]; + [appLabel setBordered:NO]; + [appLabel setBackgroundColor:[NSColor clearColor]]; + [appLabel setAlignment:NSTextAlignmentCenter]; + [appLabel setLineBreakMode:NSLineBreakByWordWrapping]; + [appLabel setUsesSingleLineMode:NO]; + [appLabel setMaximumNumberOfLines:20]; + return appLabel; +} + +// https://developer.apple.com/library/archive/qa/qa1487/_index.html +- (NSMutableAttributedString *)makeHyperLink:(NSString *)inString withURL:(NSURL *)aURL +{ + NSMutableAttributedString *attrString = [[NSMutableAttributedString alloc] initWithString:inString]; + NSRange range = NSMakeRange(0, [attrString length]); + + [attrString beginEditing]; + [attrString addAttribute:NSLinkAttributeName value:[aURL absoluteString] range:range]; + + // make the text appear in blue + [attrString addAttribute:NSForegroundColorAttributeName value:[NSColor blueColor] range:range]; + + // next make the text appear with an underline + [attrString addAttribute:NSUnderlineStyleAttributeName + value:[NSNumber numberWithInt:NSUnderlineStyleSingle] + range:range]; + + [attrString endEditing]; + return [attrString autorelease]; +} + +@end + +@implementation AboutPanel + +- (instancetype)init +{ + self = [super initWithContentRect:NSZeroRect styleMask:NSWindowStyleMaskTitled | NSWindowStyleMaskClosable backing:NSBackingStoreBuffered defer:NO]; + + AboutViewController *viewController = [[[AboutViewController alloc] init] autorelease]; + [self setContentViewController:viewController]; + [self setTitleVisibility:NSWindowTitleHidden]; + [self setTitlebarAppearsTransparent:YES]; + [self setBecomesKeyOnlyIfNeeded:NO]; + [self center]; + return self; +} + +@end + +@implementation AppDelegate { + VZVirtualMachine *_virtualMachine; + VZVirtualMachineView *_virtualMachineView; + CGFloat _windowWidth; + CGFloat _windowHeight; +} + +- (instancetype)initWithVirtualMachine:(VZVirtualMachine *)virtualMachine + windowWidth:(CGFloat)windowWidth + windowHeight:(CGFloat)windowHeight +{ + self = [super init]; + _virtualMachine = virtualMachine; + _virtualMachine.delegate = self; + + // Setup virtual machine view configs + VZVirtualMachineView *view = [[[VZVirtualMachineView alloc] init] autorelease]; + view.capturesSystemKeys = YES; + view.virtualMachine = _virtualMachine; + _virtualMachineView = view; + + // Setup some window configs + _windowWidth = windowWidth; + _windowHeight = windowHeight; + return self; +} + +/* IMPORTANT: delegate methods are called from VM's queue */ +- (void)guestDidStopVirtualMachine:(VZVirtualMachine *)virtualMachine +{ + [NSApp performSelectorOnMainThread:@selector(terminate:) withObject:self waitUntilDone:NO]; +} + +- (void)virtualMachine:(VZVirtualMachine *)virtualMachine didStopWithError:(NSError *)error +{ + NSLog(@"VM %@ didStopWithError: %@", virtualMachine, error); + [NSApp performSelectorOnMainThread:@selector(terminate:) withObject:self waitUntilDone:NO]; +} + +- (void)applicationDidFinishLaunching:(NSNotification *)notification +{ + [self setupMenuBar]; + [self setupGraphicWindow]; + + // These methods are required to call here. Because the menubar will be not active even if + // application is running. + // See: https://stackoverflow.com/questions/62739862/why-doesnt-activateignoringotherapps-enable-the-menu-bar + [NSApp setActivationPolicy:NSApplicationActivationPolicyRegular]; + [NSApp activateIgnoringOtherApps:YES]; +} + +- (void)windowWillClose:(NSNotification *)notification +{ + [NSApp performSelectorOnMainThread:@selector(terminate:) withObject:self waitUntilDone:NO]; +} + +- (void)setupGraphicWindow +{ + NSRect rect = NSMakeRect(0, 0, _windowWidth, _windowHeight); + NSWindow *window = [[[NSWindow alloc] initWithContentRect:rect + styleMask:NSWindowStyleMaskTitled | NSWindowStyleMaskClosable | NSWindowStyleMaskMiniaturizable | NSWindowStyleMaskResizable //|NSTexturedBackgroundWindowMask + backing:NSBackingStoreBuffered + defer:NO] autorelease]; + + [window setOpaque:NO]; + [window setContentView:_virtualMachineView]; + [window setTitleVisibility:NSWindowTitleHidden]; + [window center]; + + [window setDelegate:self]; + [window makeKeyAndOrderFront:nil]; + + // This code to prevent crash when called applicationShouldTerminateAfterLastWindowClosed. + // https://stackoverflow.com/a/13470694 + [window setReleasedWhenClosed:NO]; +} + +- (void)setupMenuBar +{ + NSMenu *menuBar = [[[NSMenu alloc] init] autorelease]; + NSMenuItem *menuBarItem = [[[NSMenuItem alloc] init] autorelease]; + [menuBar addItem:menuBarItem]; + [NSApp setMainMenu:menuBar]; + + // App menu + NSMenu *appMenu = [self setupApplicationMenu]; + [menuBarItem setSubmenu:appMenu]; + + // Window menu + NSMenu *windowMenu = [self setupWindowMenu]; + NSMenuItem *windowMenuItem = [[[NSMenuItem alloc] initWithTitle:@"Window" action:nil keyEquivalent:@""] autorelease]; + [menuBar addItem:windowMenuItem]; + [windowMenuItem setSubmenu:windowMenu]; + + // Help menu + NSMenu *helpMenu = [self setupHelpMenu]; + NSMenuItem *helpMenuItem = [[[NSMenuItem alloc] initWithTitle:@"Help" action:nil keyEquivalent:@""] autorelease]; + [menuBar addItem:helpMenuItem]; + [helpMenuItem setSubmenu:helpMenu]; +} + +- (NSMenu *)setupApplicationMenu +{ + NSMenu *appMenu = [[[NSMenu alloc] init] autorelease]; + NSString *applicationName = [[NSProcessInfo processInfo] processName]; + + NSMenuItem *aboutMenuItem = [[[NSMenuItem alloc] + initWithTitle:[NSString stringWithFormat:@"About %@", applicationName] + action:@selector(openAboutWindow:) + keyEquivalent:@""] autorelease]; + + // CapturesSystemKeys toggle + NSMenuItem *capturesSystemKeysItem = [[[NSMenuItem alloc] + initWithTitle:@"Enable to send system hot keys to virtual machine" + action:@selector(toggleCapturesSystemKeys:) + keyEquivalent:@""] autorelease]; + [capturesSystemKeysItem setState:[self capturesSystemKeysState]]; + + // Service menu + NSMenuItem *servicesMenuItem = [[[NSMenuItem alloc] initWithTitle:@"Services" action:nil keyEquivalent:@""] autorelease]; + NSMenu *servicesMenu = [[[NSMenu alloc] initWithTitle:@"Services"] autorelease]; + [servicesMenuItem setSubmenu:servicesMenu]; + [NSApp setServicesMenu:servicesMenu]; + + NSMenuItem *hideOthersItem = [[[NSMenuItem alloc] + initWithTitle:@"Hide Others" + action:@selector(hideOtherApplications:) + keyEquivalent:@"h"] autorelease]; + [hideOthersItem setKeyEquivalentModifierMask:(NSEventModifierFlagOption | NSEventModifierFlagCommand)]; + + NSArray *menuItems = @[ + aboutMenuItem, + [NSMenuItem separatorItem], + capturesSystemKeysItem, + [NSMenuItem separatorItem], + servicesMenuItem, + [NSMenuItem separatorItem], + [[[NSMenuItem alloc] + initWithTitle:[@"Hide " stringByAppendingString:applicationName] + action:@selector(hide:) + keyEquivalent:@"h"] autorelease], + hideOthersItem, + [NSMenuItem separatorItem], + [[[NSMenuItem alloc] + initWithTitle:[@"Quit " stringByAppendingString:applicationName] + action:@selector(terminate:) + keyEquivalent:@"q"] autorelease], + ]; + for (NSMenuItem *menuItem in menuItems) { + [appMenu addItem:menuItem]; + } + return appMenu; +} + +- (NSMenu *)setupWindowMenu +{ + NSMenu *windowMenu = [[[NSMenu alloc] initWithTitle:@"Window"] autorelease]; + NSArray *menuItems = @[ + [[[NSMenuItem alloc] initWithTitle:@"Minimize" action:@selector(performMiniaturize:) keyEquivalent:@"m"] autorelease], + [[[NSMenuItem alloc] initWithTitle:@"Zoom" action:@selector(performZoom:) keyEquivalent:@""] autorelease], + [NSMenuItem separatorItem], + [[[NSMenuItem alloc] initWithTitle:@"Bring All to Front" action:@selector(arrangeInFront:) keyEquivalent:@""] autorelease], + ]; + for (NSMenuItem *menuItem in menuItems) { + [windowMenu addItem:menuItem]; + } + [NSApp setWindowsMenu:windowMenu]; + return windowMenu; +} + +- (NSMenu *)setupHelpMenu +{ + NSMenu *helpMenu = [[[NSMenu alloc] initWithTitle:@"Help"] autorelease]; + NSArray *menuItems = @[ + [[[NSMenuItem alloc] initWithTitle:@"Report issue" action:@selector(reportIssue:) keyEquivalent:@""] autorelease], + ]; + for (NSMenuItem *menuItem in menuItems) { + [helpMenu addItem:menuItem]; + } + [NSApp setHelpMenu:helpMenu]; + return helpMenu; +} + +- (void)toggleCapturesSystemKeys:(id)sender +{ + NSMenuItem *item = (NSMenuItem *)sender; + _virtualMachineView.capturesSystemKeys = !_virtualMachineView.capturesSystemKeys; + [item setState:[self capturesSystemKeysState]]; +} + +- (NSControlStateValue)capturesSystemKeysState +{ + return _virtualMachineView.capturesSystemKeys ? NSControlStateValueOn : NSControlStateValueOff; +} + +- (void)reportIssue:(id)sender +{ + NSString *url = @"https://github.com/Code-Hex/vz/issues/new"; + [[NSWorkspace sharedWorkspace] openURL:[NSURL URLWithString:url]]; +} + +- (void)openAboutWindow:(id)sender +{ + AboutPanel *aboutPanel = [[[AboutPanel alloc] init] autorelease]; + [aboutPanel makeKeyAndOrderFront:nil]; +} +@end diff --git a/src/cmd/linuxkit/vendor/github.com/Code-Hex/vz/v3/virtualmachinestate_string.go b/src/cmd/linuxkit/vendor/github.com/Code-Hex/vz/v3/virtualmachinestate_string.go new file mode 100644 index 000000000..87c16d5d8 --- /dev/null +++ b/src/cmd/linuxkit/vendor/github.com/Code-Hex/vz/v3/virtualmachinestate_string.go @@ -0,0 +1,30 @@ +// Code generated by "stringer -type=VirtualMachineState"; DO NOT EDIT. + +package vz + +import "strconv" + +func _() { + // An "invalid array index" compiler error signifies that the constant values have changed. + // Re-run the stringer command to generate them again. + var x [1]struct{} + _ = x[VirtualMachineStateStopped-0] + _ = x[VirtualMachineStateRunning-1] + _ = x[VirtualMachineStatePaused-2] + _ = x[VirtualMachineStateError-3] + _ = x[VirtualMachineStateStarting-4] + _ = x[VirtualMachineStatePausing-5] + _ = x[VirtualMachineStateResuming-6] + _ = x[VirtualMachineStateStopping-7] +} + +const _VirtualMachineState_name = "VirtualMachineStateStoppedVirtualMachineStateRunningVirtualMachineStatePausedVirtualMachineStateErrorVirtualMachineStateStartingVirtualMachineStatePausingVirtualMachineStateResumingVirtualMachineStateStopping" + +var _VirtualMachineState_index = [...]uint8{0, 26, 52, 77, 101, 128, 154, 181, 208} + +func (i VirtualMachineState) String() string { + if i < 0 || i >= VirtualMachineState(len(_VirtualMachineState_index)-1) { + return "VirtualMachineState(" + strconv.FormatInt(int64(i), 10) + ")" + } + return _VirtualMachineState_name[_VirtualMachineState_index[i]:_VirtualMachineState_index[i+1]] +} diff --git a/src/cmd/linuxkit/vendor/github.com/Code-Hex/vz/v3/vzerror.go b/src/cmd/linuxkit/vendor/github.com/Code-Hex/vz/v3/vzerror.go new file mode 100644 index 000000000..8298269c4 --- /dev/null +++ b/src/cmd/linuxkit/vendor/github.com/Code-Hex/vz/v3/vzerror.go @@ -0,0 +1,77 @@ +package vz + +// Error type returned by the Virtualization framework. +// The NSError domain is VZErrorDomain, the code is one of the ErrorCode constants. +// +//go:generate stringer -type=ErrorCode +type ErrorCode int + +const ( + // ErrorInternal is an internal error such as the virtual machine unexpectedly stopping. + ErrorInternal ErrorCode = 1 + iota + + // ErrorInvalidVirtualMachineConfiguration represents invalid machine configuration. + ErrorInvalidVirtualMachineConfiguration + + // ErrorInvalidVirtualMachineState represents API used with a machine in the wrong state + // (e.g. interacting with a machine before it is running). + ErrorInvalidVirtualMachineState + + // ErrorInvalidVirtualMachineStateTransition is invalid change of state + // (e.g. pausing a virtual machine that is not started). + ErrorInvalidVirtualMachineStateTransition + + // ErrorInvalidDiskImage represents unrecognized disk image format or invalid disk image. + ErrorInvalidDiskImage + + // ErrorVirtualMachineLimitExceeded represents the running virtual machine limit was exceeded. + // Available from macOS 12.0 and above. + ErrorVirtualMachineLimitExceeded + + // ErrorNetworkError represents network error occurred. + // Available from macOS 13.0 and above. + ErrorNetworkError + + // ErrorOutOfDiskSpace represents machine ran out of disk space. + // Available from macOS 13.0 and above. + ErrorOutOfDiskSpace + + // ErrorOperationCancelled represents the operation was cancelled. + // Available from macOS 13.0 and above. + ErrorOperationCancelled + + // ErrorNotSupported represents the operation is not supported. + // Available from macOS 13.0 and above. + ErrorNotSupported +) + +/* macOS installation errors. */ +const ( + // ErrorRestoreImageCatalogLoadFailed represents the restore image catalog failed to load. + // Available from macOS 13.0 and above. + ErrorRestoreImageCatalogLoadFailed ErrorCode = 10001 + iota + + // ErrorInvalidRestoreImageCatalog represents the restore image catalog is invalid. + // Available from macOS 13.0 and above. + ErrorInvalidRestoreImageCatalog + + // ErrorNoSupportedRestoreImagesInCatalog represents the restore image catalog has no supported restore images. + // Available from macOS 13.0 and above. + ErrorNoSupportedRestoreImagesInCatalog + + // ErrorRestoreImageLoadFailed represents the restore image failed to load. + // Available from macOS 13.0 and above. + ErrorRestoreImageLoadFailed + + // ErrorInvalidRestoreImage represents the restore image is invalid. + // Available from macOS 13.0 and above. + ErrorInvalidRestoreImage + + // ErrorInstallationRequiresUpdate represents a software update is required to complete the installation. + // Available from macOS 13.0 and above. + ErrorInstallationRequiresUpdate + + // ErrorInstallationFailed is an error occurred during installation. + // Available from macOS 13.0 and above. + ErrorInstallationFailed +) diff --git a/src/cmd/linuxkit/vendor/github.com/Code-Hex/vz/virtualization.go b/src/cmd/linuxkit/vendor/github.com/Code-Hex/vz/virtualization.go deleted file mode 100644 index 5dd0c78d4..000000000 --- a/src/cmd/linuxkit/vendor/github.com/Code-Hex/vz/virtualization.go +++ /dev/null @@ -1,283 +0,0 @@ -package vz - -/* -#cgo darwin CFLAGS: -x objective-c -fno-objc-arc -#cgo darwin LDFLAGS: -lobjc -framework Foundation -framework Virtualization -# include "virtualization.h" -*/ -import "C" -import ( - "runtime" - "sync" - "unsafe" - - "github.com/rs/xid" -) - -func init() { - startNSThread() -} - -// VirtualMachineState represents execution state of the virtual machine. -type VirtualMachineState int - -const ( - // VirtualMachineStateStopped Initial state before the virtual machine is started. - VirtualMachineStateStopped VirtualMachineState = iota - - // VirtualMachineStateRunning Running virtual machine. - VirtualMachineStateRunning - - // VirtualMachineStatePaused A started virtual machine is paused. - // This state can only be transitioned from VirtualMachineStatePausing. - VirtualMachineStatePaused - - // VirtualMachineStateError The virtual machine has encountered an internal error. - VirtualMachineStateError - - // VirtualMachineStateStarting The virtual machine is configuring the hardware and starting. - VirtualMachineStateStarting - - // VirtualMachineStatePausing The virtual machine is being paused. - // This is the intermediate state between VirtualMachineStateRunning and VirtualMachineStatePaused. - VirtualMachineStatePausing - - // VirtualMachineStateResuming The virtual machine is being resumed. - // This is the intermediate state between VirtualMachineStatePaused and VirtualMachineStateRunning. - VirtualMachineStateResuming -) - -// VirtualMachine represents the entire state of a single virtual machine. -// -// A Virtual Machine is the emulation of a complete hardware machine of the same architecture as the real hardware machine. -// When executing the Virtual Machine, the Virtualization framework uses certain hardware resources and emulates others to provide isolation -// and great performance. -// -// The definition of a virtual machine starts with its configuration. This is done by setting up a VirtualMachineConfiguration struct. -// Once configured, the virtual machine can be started with (*VirtualMachine).Start() method. -// -// Creating a virtual machine using the Virtualization framework requires the app to have the "com.apple.security.virtualization" entitlement. -// see: https://developer.apple.com/documentation/virtualization/vzvirtualmachine?language=objc -type VirtualMachine struct { - // id for this struct. - id string - - // Indicate whether or not virtualization is available. - // - // If virtualization is unavailable, no VirtualMachineConfiguration will validate. - // The validation error of the VirtualMachineConfiguration provides more information about why virtualization is unavailable. - supported bool - - pointer - dispatchQueue unsafe.Pointer - - mu sync.Mutex -} - -type ( - machineStatus struct { - state VirtualMachineState - stateNotify chan VirtualMachineState - - mu sync.RWMutex - } - machineHandlers struct { - start func(error) - pause func(error) - resume func(error) - } -) - -var ( - handlers = map[string]*machineHandlers{} - statuses = map[string]*machineStatus{} -) - -// NewVirtualMachine creates a new VirtualMachine with VirtualMachineConfiguration. -// -// The configuration must be valid. Validation can be performed at runtime with (*VirtualMachineConfiguration).Validate() method. -// The configuration is copied by the initializer. -// -// A new dispatch queue will create when called this function. -// Every operation on the virtual machine must be done on that queue. The callbacks and delegate methods are invoked on that queue. -func NewVirtualMachine(config *VirtualMachineConfiguration) *VirtualMachine { - id := xid.New().String() - cs := charWithGoString(id) - defer cs.Free() - statuses[id] = &machineStatus{ - state: VirtualMachineState(0), - stateNotify: make(chan VirtualMachineState), - } - handlers[id] = &machineHandlers{ - start: func(error) {}, - pause: func(error) {}, - resume: func(error) {}, - } - dispatchQueue := C.makeDispatchQueue(cs.CString()) - v := &VirtualMachine{ - id: id, - pointer: pointer{ - ptr: C.newVZVirtualMachineWithDispatchQueue( - config.Ptr(), - dispatchQueue, - cs.CString(), - ), - }, - dispatchQueue: dispatchQueue, - } - runtime.SetFinalizer(v, func(self *VirtualMachine) { - releaseDispatch(self.dispatchQueue) - self.Release() - }) - return v -} - -//export changeStateOnObserver -func changeStateOnObserver(state C.int, cID *C.char) { - id := (*char)(cID) - // I expected it will not cause panic. - // if caused panic, that's unexpected behavior. - v, _ := statuses[id.String()] - v.mu.Lock() - newState := VirtualMachineState(state) - v.state = newState - // for non-blocking - go func() { v.stateNotify <- newState }() - statuses[id.String()] = v - v.mu.Unlock() -} - -// State represents execution state of the virtual machine. -func (v *VirtualMachine) State() VirtualMachineState { - // I expected it will not cause panic. - // if caused panic, that's unexpected behavior. - val, _ := statuses[v.id] - val.mu.RLock() - defer val.mu.RUnlock() - return val.state -} - -// StateChangedNotify gets notification is changed execution state of the virtual machine. -func (v *VirtualMachine) StateChangedNotify() <-chan VirtualMachineState { - // I expected it will not cause panic. - // if caused panic, that's unexpected behavior. - val, _ := statuses[v.id] - val.mu.RLock() - defer val.mu.RUnlock() - return val.stateNotify -} - -// CanStart returns true if the machine is in a state that can be started. -func (v *VirtualMachine) CanStart() bool { - return bool(C.vmCanStart(v.Ptr(), v.dispatchQueue)) -} - -// CanPause returns true if the machine is in a state that can be paused. -func (v *VirtualMachine) CanPause() bool { - return bool(C.vmCanPause(v.Ptr(), v.dispatchQueue)) -} - -// CanResume returns true if the machine is in a state that can be resumed. -func (v *VirtualMachine) CanResume() bool { - return (bool)(C.vmCanResume(v.Ptr(), v.dispatchQueue)) -} - -// CanRequestStop returns whether the machine is in a state where the guest can be asked to stop. -func (v *VirtualMachine) CanRequestStop() bool { - return (bool)(C.vmCanRequestStop(v.Ptr(), v.dispatchQueue)) -} - -//export startHandler -func startHandler(errPtr unsafe.Pointer, cid *C.char) { - id := (*char)(cid).String() - // If returns nil in the cgo world, the nil will not be treated as nil in the Go world - // so this is temporarily handled (Go 1.17) - if err := newNSError(errPtr); err != nil { - handlers[id].start(err) - } else { - handlers[id].start(nil) - } -} - -//export pauseHandler -func pauseHandler(errPtr unsafe.Pointer, cid *C.char) { - id := (*char)(cid).String() - // see: startHandler - if err := newNSError(errPtr); err != nil { - handlers[id].pause(err) - } else { - handlers[id].pause(nil) - } -} - -//export resumeHandler -func resumeHandler(errPtr unsafe.Pointer, cid *C.char) { - id := (*char)(cid).String() - // see: startHandler - if err := newNSError(errPtr); err != nil { - handlers[id].resume(err) - } else { - handlers[id].resume(nil) - } -} - -func makeHandler(fn func(error)) (func(error), chan struct{}) { - done := make(chan struct{}) - return func(err error) { - fn(err) - close(done) - }, done -} - -// Start a virtual machine that is in either Stopped or Error state. -// -// - fn parameter called after the virtual machine has been successfully started or on error. -// The error parameter passed to the block is null if the start was successful. -func (v *VirtualMachine) Start(fn func(error)) { - h, done := makeHandler(fn) - handlers[v.id].start = h - cid := charWithGoString(v.id) - defer cid.Free() - C.startWithCompletionHandler(v.Ptr(), v.dispatchQueue, cid.CString()) - <-done -} - -// Pause a virtual machine that is in Running state. -// -// - fn parameter called after the virtual machine has been successfully paused or on error. -// The error parameter passed to the block is null if the start was successful. -func (v *VirtualMachine) Pause(fn func(error)) { - h, done := makeHandler(fn) - handlers[v.id].pause = h - cid := charWithGoString(v.id) - defer cid.Free() - C.pauseWithCompletionHandler(v.Ptr(), v.dispatchQueue, cid.CString()) - <-done -} - -// Resume a virtual machine that is in the Paused state. -// -// - fn parameter called after the virtual machine has been successfully resumed or on error. -// The error parameter passed to the block is null if the resumption was successful. -func (v *VirtualMachine) Resume(fn func(error)) { - h, done := makeHandler(fn) - handlers[v.id].resume = h - cid := charWithGoString(v.id) - defer cid.Free() - C.resumeWithCompletionHandler(v.Ptr(), v.dispatchQueue, cid.CString()) - <-done -} - -// RequestStop requests that the guest turns itself off. -// -// If returned error is not nil, assigned with the error if the request failed. -// Returens true if the request was made successfully. -func (v *VirtualMachine) RequestStop() (bool, error) { - nserr := newNSErrorAsNil() - nserrPtr := nserr.Ptr() - ret := (bool)(C.requestStopVirtualMachine(v.Ptr(), v.dispatchQueue, &nserrPtr)) - if err := newNSError(nserrPtr); err != nil { - return ret, err - } - return ret, nil -} diff --git a/src/cmd/linuxkit/vendor/github.com/Code-Hex/vz/virtualization.m b/src/cmd/linuxkit/vendor/github.com/Code-Hex/vz/virtualization.m deleted file mode 100644 index 91a9b9056..000000000 --- a/src/cmd/linuxkit/vendor/github.com/Code-Hex/vz/virtualization.m +++ /dev/null @@ -1,570 +0,0 @@ -// -// virtualization.m -// -// Created by codehex. -// - -#import "virtualization.h" - -char *copyCString(NSString *nss) -{ - const char *cc = [nss UTF8String]; - char *c = calloc([nss length]+1, 1); - strncpy(c, cc, [nss length]); - return c; -} - -@implementation Observer -- (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context; -{ - - @autoreleasepool { - if ([keyPath isEqualToString:@"state"]) { - int newState = (int)[change[NSKeyValueChangeNewKey] integerValue]; - char *vmid = copyCString((NSString *)context); - changeStateOnObserver(newState, vmid); - free(vmid); - } else { - // bool canVal = (bool)[change[NSKeyValueChangeNewKey] boolValue]; - // char *vmid = copyCString((NSString *)context); - // char *key = copyCString(keyPath); - // changeCanPropertyOnObserver(canVal, vmid, key); - // free(vmid); - // free(key); - } - } -} -@end - -/*! - @abstract Create a VZLinuxBootLoader with the Linux kernel passed as URL. - @param kernelPath Path of Linux kernel on the local file system. -*/ -void *newVZLinuxBootLoader(const char *kernelPath) -{ - VZLinuxBootLoader *ret; - @autoreleasepool { - NSString *kernelPathNSString = [NSString stringWithUTF8String:kernelPath]; - NSURL *kernelURL = [NSURL fileURLWithPath:kernelPathNSString]; - ret = [[VZLinuxBootLoader alloc] initWithKernelURL:kernelURL]; - } - return ret; -} - -/*! - @abstract Set the command-line parameters. - @param bootLoader VZLinuxBootLoader - @param commandLine The command-line parameters passed to the kernel on boot. - @link https://www.kernel.org/doc/html/latest/admin-guide/kernel-parameters.html - */ -void setCommandLineVZLinuxBootLoader(void *bootLoaderPtr, const char *commandLine) -{ - VZLinuxBootLoader *bootLoader = (VZLinuxBootLoader *)bootLoaderPtr; - @autoreleasepool { - NSString *commandLineNSString = [NSString stringWithUTF8String:commandLine]; - [bootLoader setCommandLine:commandLineNSString]; - } -} - -/*! - @abstract Set the optional initial RAM disk. - @param bootLoader VZLinuxBootLoader - @param ramdiskPath The RAM disk is mapped into memory before booting the kernel. - @link https://www.kernel.org/doc/html/latest/admin-guide/kernel-parameters.html - */ -void setInitialRamdiskURLVZLinuxBootLoader(void *bootLoaderPtr, const char *ramdiskPath) -{ - VZLinuxBootLoader *bootLoader = (VZLinuxBootLoader *)bootLoaderPtr; - @autoreleasepool { - NSString *ramdiskPathNSString = [NSString stringWithUTF8String:ramdiskPath]; - NSURL *ramdiskURL = [NSURL fileURLWithPath:ramdiskPathNSString]; - [bootLoader setInitialRamdiskURL:ramdiskURL]; - } -} - - -/*! - @abstract Validate the configuration. - @param config Virtual machine configuration. - @param error If not nil, assigned with the validation error if the validation failed. - @return true if the configuration is valid. - */ -bool validateVZVirtualMachineConfiguration(void *config, void **error) -{ - return (bool)[(VZVirtualMachineConfiguration *)config - validateWithError:(NSError * _Nullable * _Nullable)error]; -} - -/*! - @abstract Create a new Virtual machine configuration. - @param bootLoader Boot loader used when the virtual machine starts. - - @param CPUCount Number of CPUs. - @discussion - The number of CPUs must be a value between VZVirtualMachineConfiguration.minimumAllowedCPUCount - and VZVirtualMachineConfiguration.maximumAllowedCPUCount. - - @see VZVirtualMachineConfiguration.minimumAllowedCPUCount - @see VZVirtualMachineConfiguration.maximumAllowedCPUCount - - @param memorySize Virtual machine memory size in bytes. - @discussion - The memory size must be a multiple of a 1 megabyte (1024 * 1024 bytes) between VZVirtualMachineConfiguration.minimumAllowedMemorySize - and VZVirtualMachineConfiguration.maximumAllowedMemorySize. - - The memorySize represents the total physical memory seen by a guest OS running in the virtual machine. - Not all memory is allocated on start, the virtual machine allocates memory on demand. - @see VZVirtualMachineConfiguration.minimumAllowedMemorySize - @see VZVirtualMachineConfiguration.maximumAllowedMemorySize - */ -void *newVZVirtualMachineConfiguration(void *bootLoaderPtr, - unsigned int CPUCount, - unsigned long long memorySize) -{ - VZVirtualMachineConfiguration *config = [[VZVirtualMachineConfiguration alloc] init]; - [config setBootLoader:(VZLinuxBootLoader *)bootLoaderPtr]; - [config setCPUCount:(NSUInteger)CPUCount]; - [config setMemorySize:memorySize]; - return config; -} - -/*! - @abstract List of entropy devices. Empty by default. - @see VZVirtioEntropyDeviceConfiguration -*/ -void setEntropyDevicesVZVirtualMachineConfiguration(void *config, - void *entropyDevices) -{ - [(VZVirtualMachineConfiguration *)config setEntropyDevices:[(NSMutableArray *)entropyDevices copy]]; -} - - -/*! - @abstract List of memory balloon devices. Empty by default. - @see VZVirtioTraditionalMemoryBalloonDeviceConfiguration -*/ -void setMemoryBalloonDevicesVZVirtualMachineConfiguration(void *config, - void *memoryBalloonDevices) -{ - [(VZVirtualMachineConfiguration *)config setMemoryBalloonDevices:[(NSMutableArray *)memoryBalloonDevices copy]]; -} - -/*! - @abstract List of network adapters. Empty by default. - @see VZVirtioNetworkDeviceConfiguration - */ -void setNetworkDevicesVZVirtualMachineConfiguration(void *config, - void *networkDevices) -{ - [(VZVirtualMachineConfiguration *)config setNetworkDevices:[(NSMutableArray *)networkDevices copy]]; -} - -/*! - @abstract List of serial ports. Empty by default. - @see VZVirtioConsoleDeviceSerialPortConfiguration - */ -void setSerialPortsVZVirtualMachineConfiguration(void *config, - void *serialPorts) -{ - [(VZVirtualMachineConfiguration *)config setSerialPorts:[(NSMutableArray *)serialPorts copy]]; -} - - -/*! - @abstract List of socket devices. Empty by default. - @see VZVirtioSocketDeviceConfiguration - */ -void setSocketDevicesVZVirtualMachineConfiguration(void *config, - void *socketDevices) -{ - [(VZVirtualMachineConfiguration *)config setSocketDevices:[(NSMutableArray *)socketDevices copy]]; -} - -/*! - @abstract List of disk devices. Empty by default. - @see VZVirtioBlockDeviceConfiguration - */ -void setStorageDevicesVZVirtualMachineConfiguration(void *config, - void *storageDevices) -{ - [(VZVirtualMachineConfiguration *)config setStorageDevices:[(NSMutableArray *)storageDevices copy]]; -} - -/*! - @abstract Intialize the VZFileHandleSerialPortAttachment from file descriptors. - @param readFileDescriptor File descriptor for reading from the file. - @param writeFileDescriptor File descriptor for writing to the file. - @discussion - Each file descriptor must a valid. -*/ -void *newVZFileHandleSerialPortAttachment(int readFileDescriptor, int writeFileDescriptor) -{ - VZFileHandleSerialPortAttachment *ret; - @autoreleasepool { - NSFileHandle *fileHandleForReading = [[NSFileHandle alloc] initWithFileDescriptor:readFileDescriptor]; - NSFileHandle *fileHandleForWriting = [[NSFileHandle alloc] initWithFileDescriptor:writeFileDescriptor]; - ret = [[VZFileHandleSerialPortAttachment alloc] - initWithFileHandleForReading:fileHandleForReading - fileHandleForWriting:fileHandleForWriting]; - } - return ret; -} - -/*! - @abstract Initialize the VZFileSerialPortAttachment from a URL of a file. - @param filePath The path of the file for the attachment on the local file system. - @param shouldAppend True if the file should be opened in append mode, false otherwise. - When a file is opened in append mode, writing to that file will append to the end of it. - @param error If not nil, used to report errors if intialization fails. - @return A VZFileSerialPortAttachment on success. Nil otherwise and the error parameter is populated if set. - */ -void *newVZFileSerialPortAttachment(const char *filePath, bool shouldAppend, void **error) -{ - VZFileSerialPortAttachment *ret; - @autoreleasepool { - NSString *filePathNSString = [NSString stringWithUTF8String:filePath]; - NSURL *fileURL = [NSURL fileURLWithPath:filePathNSString]; - ret = [[VZFileSerialPortAttachment alloc] - initWithURL:fileURL append:(BOOL)shouldAppend error:(NSError * _Nullable * _Nullable)error]; - } - return ret; -} - -/*! - @abstract Create a new Virtio Console Serial Port Device configuration - @param attachment Base class for a serial port attachment. - @discussion - The device creates a console which enables communication between the host and the guest through the Virtio interface. - - The device sets up a single port on the Virtio console device. - */ -void *newVZVirtioConsoleDeviceSerialPortConfiguration(void *attachment) -{ - VZVirtioConsoleDeviceSerialPortConfiguration *config = [[VZVirtioConsoleDeviceSerialPortConfiguration alloc] init]; - [config setAttachment:(VZSerialPortAttachment *)attachment]; - return config; -} - -/*! - @abstract Create a new Network device attachment bridging a host physical interface with a virtual network device. - @param networkInterface a network interface that bridges a physical interface. - @discussion - A bridged network allows the virtual machine to use the same physical interface as the host. Both host and virtual machine - send and receive packets on the same physical interface but have distinct network layers. - - The bridge network device attachment is used with a VZNetworkDeviceConfiguration to define a virtual network device. - - Using a VZBridgedNetworkDeviceAttachment requires the app to have the "com.apple.vm.networking" entitlement. - - @see VZBridgedNetworkInterface - @see VZNetworkDeviceConfiguration - @see VZVirtioNetworkDeviceConfiguration - */ -void *newVZBridgedNetworkDeviceAttachment(void *networkInterface) -{ - return [[VZBridgedNetworkDeviceAttachment alloc] initWithInterface:(VZBridgedNetworkInterface *)networkInterface]; -} - -/*! - @abstract Create a new Network device attachment using network address translation (NAT) with outside networks. - @discussion - Using the NAT attachment type, the host serves as router and performs network address translation for accesses to outside networks. - - @see VZNetworkDeviceConfiguration - @see VZVirtioNetworkDeviceConfiguration - */ -void *newVZNATNetworkDeviceAttachment() -{ - return [[VZNATNetworkDeviceAttachment alloc] init]; -} - -/*! - @abstract Create a new Network device attachment sending raw network packets over a file handle. - @discussion - The file handle attachment transmits the raw packets/frames between the virtual network interface and a file handle. - The data transmitted through this attachment is at the level of the data link layer. - - The file handle must hold a connected datagram socket. - - @see VZNetworkDeviceConfiguration - @see VZVirtioNetworkDeviceConfiguration - */ -void *newVZFileHandleNetworkDeviceAttachment(int fileDescriptor) -{ - VZFileHandleNetworkDeviceAttachment *ret; - @autoreleasepool { - NSFileHandle *fileHandle = [[NSFileHandle alloc] initWithFileDescriptor:fileDescriptor]; - ret = [[VZFileHandleNetworkDeviceAttachment alloc] initWithFileHandle:fileHandle]; - } - return ret; -} - -/*! - @abstract Create a new Configuration of a paravirtualized network device of type Virtio Network Device. - @discussion - The communication channel used on the host is defined through the attachment. It is set with the VZNetworkDeviceConfiguration.attachment property. - - The configuration is only valid with valid MACAddress and attachment. - - @see VZVirtualMachineConfiguration.networkDevices - - @param attachment Base class for a network device attachment. - @discussion - A network device attachment defines how a virtual network device interfaces with the host system. - - VZNetworkDeviceAttachment should not be instantiated directly. One of its subclasses should be used instead. - - Common attachment types include: - - VZNATNetworkDeviceAttachment - - VZFileHandleNetworkDeviceAttachment - - @see VZBridgedNetworkDeviceAttachment - @see VZFileHandleNetworkDeviceAttachment - @see VZNATNetworkDeviceAttachment - */ -void *newVZVirtioNetworkDeviceConfiguration(void *attachment) -{ - VZVirtioNetworkDeviceConfiguration *config = [[VZVirtioNetworkDeviceConfiguration alloc] init]; - [config setAttachment:(VZNetworkDeviceAttachment *)attachment]; - return config; -} - -/*! - @abstract Create a new Virtio Entropy Device confiuration - @discussion The device exposes a source of entropy for the guest's random number generator. -*/ -void *newVZVirtioEntropyDeviceConfiguration() -{ - return [[VZVirtioEntropyDeviceConfiguration alloc] init]; -} - -/*! - @abstract Initialize a VZVirtioBlockDeviceConfiguration with a device attachment. - @param attachment The storage device attachment. This defines how the virtualized device operates on the host side. - @see VZDiskImageStorageDeviceAttachment - */ -void *newVZVirtioBlockDeviceConfiguration(void *attachment) -{ - return [[VZVirtioBlockDeviceConfiguration alloc] initWithAttachment:(VZStorageDeviceAttachment *)attachment]; -} - -/*! - @abstract Initialize the attachment from a local file url. - @param diskPath Local file path to the disk image in RAW format. - @param readOnly If YES, the device attachment is read-only, otherwise the device can write data to the disk image. - @param error If not nil, assigned with the error if the initialization failed. - @return A VZDiskImageStorageDeviceAttachment on success. Nil otherwise and the error parameter is populated if set. - */ -void *newVZDiskImageStorageDeviceAttachment(const char *diskPath, bool readOnly, void **error) -{ - VZDiskImageStorageDeviceAttachment *ret; - @autoreleasepool { - NSString *diskPathNSString = [NSString stringWithUTF8String:diskPath]; - NSURL *diskURL = [NSURL fileURLWithPath:diskPathNSString]; - ret = [[VZDiskImageStorageDeviceAttachment alloc] - initWithURL:diskURL - readOnly:(BOOL)readOnly - error:(NSError * _Nullable * _Nullable)error]; - } - return ret; -} - - -/*! - @abstract Create a configuration of the Virtio traditional memory balloon device. - @discussion - This configuration creates a Virtio traditional memory balloon device which allows for managing guest memory. - Only one Virtio traditional memory balloon device can be used per virtual machine. - @see VZVirtioTraditionalMemoryBalloonDevice - */ -void *newVZVirtioTraditionalMemoryBalloonDeviceConfiguration() -{ - return [[VZVirtioTraditionalMemoryBalloonDeviceConfiguration alloc] init]; -} - -/*! - @abstract Create a configuration of the Virtio socket device. - @discussion - This configuration creates a Virtio socket device for the guest which communicates with the host through the Virtio interface. - - Only one Virtio socket device can be used per virtual machine. - @see VZVirtioSocketDevice - */ -void *newVZVirtioSocketDeviceConfiguration() -{ - return [[VZVirtioSocketDeviceConfiguration alloc] init]; -} - -/*! - @abstract Initialize the virtual machine. - @param config The configuration of the virtual machine. - The configuration must be valid. Validation can be performed at runtime with [VZVirtualMachineConfiguration validateWithError:]. - The configuration is copied by the initializer. - @param queue The serial queue on which the virtual machine operates. - Every operation on the virtual machine must be done on that queue. The callbacks and delegate methods are invoked on that queue. - If the queue is not serial, the behavior is undefined. - */ -void *newVZVirtualMachineWithDispatchQueue(void *config, void *queue, const char *vmid) -{ - VZVirtualMachine *vm = [[VZVirtualMachine alloc] - initWithConfiguration:(VZVirtualMachineConfiguration *)config - queue:(dispatch_queue_t)queue]; - @autoreleasepool { - Observer *o = [[Observer alloc] init]; - NSString *str = [NSString stringWithUTF8String:vmid]; - [vm addObserver:o forKeyPath:@"state" - options:NSKeyValueObservingOptionNew - context:[str copy]]; - } - return vm; -} - -/*! - @abstract Initialize the VZMACAddress from a string representation of a MAC address. - @param string - The string should be formatted representing the 6 bytes in hexadecimal separated by a colon character. - e.g. "01:23:45:ab:cd:ef" - - The alphabetical characters can appear lowercase or uppercase. - @return A VZMACAddress or nil if the string is not formatted correctly. - */ -void *newVZMACAddress(const char *macAddress) -{ - VZMACAddress *ret; - @autoreleasepool { - NSString *str = [NSString stringWithUTF8String:macAddress]; - ret = [[VZMACAddress alloc] initWithString:str]; - } - return ret; -} - -/*! - @abstract Create a valid, random, unicast, locally administered address. - @discussion The generated address is not guaranteed to be unique. - */ -void *newRandomLocallyAdministeredVZMACAddress() -{ - return [VZMACAddress randomLocallyAdministeredAddress]; -} - -/*! - @abstract Sets the media access control address of the device. - */ -void setNetworkDevicesVZMACAddress(void *config, void *macAddress) -{ - [(VZNetworkDeviceConfiguration *)config setMACAddress:[(VZMACAddress *)macAddress copy]]; -} - -/*! - @abstract The address represented as a string. - @discussion - The 6 bytes are represented in hexadecimal form, separated by a colon character. - Alphabetical characters are lowercase. - - The address is compatible with the parameter of -[VZMACAddress initWithString:]. - */ -const char *getVZMACAddressString(void *macAddress) -{ - return [[(VZMACAddress *)macAddress string] UTF8String]; -} - -/*! - @abstract Request that the guest turns itself off. - @param error If not nil, assigned with the error if the request failed. - @return YES if the request was made successfully. - */ -bool requestStopVirtualMachine(void *machine, void *queue, void **error) -{ - __block BOOL ret; - dispatch_sync((dispatch_queue_t)queue, ^{ - ret = [(VZVirtualMachine *)machine requestStopWithError:(NSError * _Nullable *_Nullable)error]; - }); - return (bool)ret; -} - -void *makeDispatchQueue(const char *label) -{ - //dispatch_queue_attr_t attr = dispatch_queue_attr_make_with_qos_class(DISPATCH_QUEUE_SERIAL, QOS_CLASS_DEFAULT, 0); - dispatch_queue_t queue = dispatch_queue_create(label, DISPATCH_QUEUE_SERIAL); - //dispatch_retain(queue); - return queue; -} - -typedef void (^handler_t)(NSError *); - -handler_t generateHandler(const char *vmid, void handler(void *, char *)) -{ - handler_t ret; - @autoreleasepool { - NSString *str = [NSString stringWithUTF8String:vmid]; - ret = Block_copy(^(NSError *err){ - handler(err, copyCString(str)); - }); - } - return ret; -} - -void startWithCompletionHandler(void *machine, void *queue, const char *vmid) -{ - handler_t handler = generateHandler(vmid, startHandler); - dispatch_sync((dispatch_queue_t)queue, ^{ - [(VZVirtualMachine *)machine startWithCompletionHandler:handler]; - }); - Block_release(handler); -} - -void pauseWithCompletionHandler(void *machine, void *queue, const char *vmid) -{ - handler_t handler = generateHandler(vmid, pauseHandler); - dispatch_sync((dispatch_queue_t)queue, ^{ - [(VZVirtualMachine *)machine pauseWithCompletionHandler:handler]; - }); - Block_release(handler); -} - -void resumeWithCompletionHandler(void *machine, void *queue, const char *vmid) -{ - handler_t handler = generateHandler(vmid, pauseHandler); - dispatch_sync((dispatch_queue_t)queue, ^{ - [(VZVirtualMachine *)machine resumeWithCompletionHandler:handler]; - }); - Block_release(handler); -} - -// TODO(codehex): use KVO -bool vmCanStart(void *machine, void *queue) -{ - __block BOOL result; - dispatch_sync((dispatch_queue_t)queue, ^{ - result = ((VZVirtualMachine *)machine).canStart; - }); - return (bool)result; -} - -bool vmCanPause(void *machine, void *queue) -{ - __block BOOL result; - dispatch_sync((dispatch_queue_t)queue, ^{ - result = ((VZVirtualMachine *)machine).canPause; - }); - return (bool)result; -} - -bool vmCanResume(void *machine, void *queue) -{ - __block BOOL result; - dispatch_sync((dispatch_queue_t)queue, ^{ - result = ((VZVirtualMachine *)machine).canResume; - }); - return (bool)result; -} - -bool vmCanRequestStop(void *machine, void *queue) -{ - __block BOOL result; - dispatch_sync((dispatch_queue_t)queue, ^{ - result = ((VZVirtualMachine *)machine).canRequestStop; - }); - return (bool)result; -} -// --- TODO end diff --git a/src/cmd/linuxkit/vendor/github.com/rs/xid/.appveyor.yml b/src/cmd/linuxkit/vendor/github.com/rs/xid/.appveyor.yml deleted file mode 100644 index c73bb33ba..000000000 --- a/src/cmd/linuxkit/vendor/github.com/rs/xid/.appveyor.yml +++ /dev/null @@ -1,27 +0,0 @@ -version: 1.0.0.{build} - -platform: x64 - -branches: - only: - - master - -clone_folder: c:\gopath\src\github.com\rs\xid - -environment: - GOPATH: c:\gopath - -install: - - echo %PATH% - - echo %GOPATH% - - set PATH=%GOPATH%\bin;c:\go\bin;%PATH% - - go version - - go env - - go get -t . - -build_script: - - go build - -test_script: - - go test - diff --git a/src/cmd/linuxkit/vendor/github.com/rs/xid/.travis.yml b/src/cmd/linuxkit/vendor/github.com/rs/xid/.travis.yml deleted file mode 100644 index b37da1594..000000000 --- a/src/cmd/linuxkit/vendor/github.com/rs/xid/.travis.yml +++ /dev/null @@ -1,8 +0,0 @@ -language: go -go: -- "1.9" -- "1.10" -- "master" -matrix: - allow_failures: - - go: "master" diff --git a/src/cmd/linuxkit/vendor/github.com/rs/xid/LICENSE b/src/cmd/linuxkit/vendor/github.com/rs/xid/LICENSE deleted file mode 100644 index 47c5e9d2d..000000000 --- a/src/cmd/linuxkit/vendor/github.com/rs/xid/LICENSE +++ /dev/null @@ -1,19 +0,0 @@ -Copyright (c) 2015 Olivier Poitrey - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is furnished -to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -THE SOFTWARE. diff --git a/src/cmd/linuxkit/vendor/github.com/rs/xid/README.md b/src/cmd/linuxkit/vendor/github.com/rs/xid/README.md deleted file mode 100644 index 79818877b..000000000 --- a/src/cmd/linuxkit/vendor/github.com/rs/xid/README.md +++ /dev/null @@ -1,115 +0,0 @@ -# Globally Unique ID Generator - -[![godoc](http://img.shields.io/badge/godoc-reference-blue.svg?style=flat)](https://godoc.org/github.com/rs/xid) [![license](http://img.shields.io/badge/license-MIT-red.svg?style=flat)](https://raw.githubusercontent.com/rs/xid/master/LICENSE) [![Build Status](https://travis-ci.org/rs/xid.svg?branch=master)](https://travis-ci.org/rs/xid) [![Coverage](http://gocover.io/_badge/github.com/rs/xid)](http://gocover.io/github.com/rs/xid) - -Package xid is a globally unique id generator library, ready to safely be used directly in your server code. - -Xid uses the Mongo Object ID algorithm to generate globally unique ids with a different serialization (base64) to make it shorter when transported as a string: -https://docs.mongodb.org/manual/reference/object-id/ - -- 4-byte value representing the seconds since the Unix epoch, -- 3-byte machine identifier, -- 2-byte process id, and -- 3-byte counter, starting with a random value. - -The binary representation of the id is compatible with Mongo 12 bytes Object IDs. -The string representation is using base32 hex (w/o padding) for better space efficiency -when stored in that form (20 bytes). The hex variant of base32 is used to retain the -sortable property of the id. - -Xid doesn't use base64 because case sensitivity and the 2 non alphanum chars may be an -issue when transported as a string between various systems. Base36 wasn't retained either -because 1/ it's not standard 2/ the resulting size is not predictable (not bit aligned) -and 3/ it would not remain sortable. To validate a base32 `xid`, expect a 20 chars long, -all lowercase sequence of `a` to `v` letters and `0` to `9` numbers (`[0-9a-v]{20}`). - -UUIDs are 16 bytes (128 bits) and 36 chars as string representation. Twitter Snowflake -ids are 8 bytes (64 bits) but require machine/data-center configuration and/or central -generator servers. xid stands in between with 12 bytes (96 bits) and a more compact -URL-safe string representation (20 chars). No configuration or central generator server -is required so it can be used directly in server's code. - -| Name | Binary Size | String Size | Features -|-------------|-------------|----------------|---------------- -| [UUID] | 16 bytes | 36 chars | configuration free, not sortable -| [shortuuid] | 16 bytes | 22 chars | configuration free, not sortable -| [Snowflake] | 8 bytes | up to 20 chars | needs machine/DC configuration, needs central server, sortable -| [MongoID] | 12 bytes | 24 chars | configuration free, sortable -| xid | 12 bytes | 20 chars | configuration free, sortable - -[UUID]: https://en.wikipedia.org/wiki/Universally_unique_identifier -[shortuuid]: https://github.com/stochastic-technologies/shortuuid -[Snowflake]: https://blog.twitter.com/2010/announcing-snowflake -[MongoID]: https://docs.mongodb.org/manual/reference/object-id/ - -Features: - -- Size: 12 bytes (96 bits), smaller than UUID, larger than snowflake -- Base32 hex encoded by default (20 chars when transported as printable string, still sortable) -- Non configured, you don't need set a unique machine and/or data center id -- K-ordered -- Embedded time with 1 second precision -- Unicity guaranteed for 16,777,216 (24 bits) unique ids per second and per host/process -- Lock-free (i.e.: unlike UUIDv1 and v2) - -Best used with [zerolog](https://github.com/rs/zerolog)'s -[RequestIDHandler](https://godoc.org/github.com/rs/zerolog/hlog#RequestIDHandler). - -Notes: - -- Xid is dependent on the system time, a monotonic counter and so is not cryptographically secure. If unpredictability of IDs is important, you should not use Xids. It is worth noting that most other UUID-like implementations are also not cryptographically secure. You should use libraries that rely on cryptographically secure sources (like /dev/urandom on unix, crypto/rand in golang), if you want a truly random ID generator. - -References: - -- http://www.slideshare.net/davegardnerisme/unique-id-generation-in-distributed-systems -- https://en.wikipedia.org/wiki/Universally_unique_identifier -- https://blog.twitter.com/2010/announcing-snowflake -- Python port by [Graham Abbott](https://github.com/graham): https://github.com/graham/python_xid -- Scala port by [Egor Kolotaev](https://github.com/kolotaev): https://github.com/kolotaev/ride -- Rust port by [Jérôme Renard](https://github.com/jeromer/): https://github.com/jeromer/libxid -- Ruby port by [Valar](https://github.com/valarpirai/): https://github.com/valarpirai/ruby_xid -- Java port by [0xShamil](https://github.com/0xShamil/): https://github.com/0xShamil/java-xid - -## Install - - go get github.com/rs/xid - -## Usage - -```go -guid := xid.New() - -println(guid.String()) -// Output: 9m4e2mr0ui3e8a215n4g -``` - -Get `xid` embedded info: - -```go -guid.Machine() -guid.Pid() -guid.Time() -guid.Counter() -``` - -## Benchmark - -Benchmark against Go [Maxim Bublis](https://github.com/satori)'s [UUID](https://github.com/satori/go.uuid). - -``` -BenchmarkXID 20000000 91.1 ns/op 32 B/op 1 allocs/op -BenchmarkXID-2 20000000 55.9 ns/op 32 B/op 1 allocs/op -BenchmarkXID-4 50000000 32.3 ns/op 32 B/op 1 allocs/op -BenchmarkUUIDv1 10000000 204 ns/op 48 B/op 1 allocs/op -BenchmarkUUIDv1-2 10000000 160 ns/op 48 B/op 1 allocs/op -BenchmarkUUIDv1-4 10000000 195 ns/op 48 B/op 1 allocs/op -BenchmarkUUIDv4 1000000 1503 ns/op 64 B/op 2 allocs/op -BenchmarkUUIDv4-2 1000000 1427 ns/op 64 B/op 2 allocs/op -BenchmarkUUIDv4-4 1000000 1452 ns/op 64 B/op 2 allocs/op -``` - -Note: UUIDv1 requires a global lock, hence the performance degradation as we add more CPUs. - -## Licenses - -All source code is licensed under the [MIT License](https://raw.github.com/rs/xid/master/LICENSE). diff --git a/src/cmd/linuxkit/vendor/github.com/rs/xid/hostid_darwin.go b/src/cmd/linuxkit/vendor/github.com/rs/xid/hostid_darwin.go deleted file mode 100644 index 08351ff72..000000000 --- a/src/cmd/linuxkit/vendor/github.com/rs/xid/hostid_darwin.go +++ /dev/null @@ -1,9 +0,0 @@ -// +build darwin - -package xid - -import "syscall" - -func readPlatformMachineID() (string, error) { - return syscall.Sysctl("kern.uuid") -} diff --git a/src/cmd/linuxkit/vendor/github.com/rs/xid/hostid_fallback.go b/src/cmd/linuxkit/vendor/github.com/rs/xid/hostid_fallback.go deleted file mode 100644 index 7fbd3c004..000000000 --- a/src/cmd/linuxkit/vendor/github.com/rs/xid/hostid_fallback.go +++ /dev/null @@ -1,9 +0,0 @@ -// +build !darwin,!linux,!freebsd,!windows - -package xid - -import "errors" - -func readPlatformMachineID() (string, error) { - return "", errors.New("not implemented") -} diff --git a/src/cmd/linuxkit/vendor/github.com/rs/xid/hostid_freebsd.go b/src/cmd/linuxkit/vendor/github.com/rs/xid/hostid_freebsd.go deleted file mode 100644 index be25a039e..000000000 --- a/src/cmd/linuxkit/vendor/github.com/rs/xid/hostid_freebsd.go +++ /dev/null @@ -1,9 +0,0 @@ -// +build freebsd - -package xid - -import "syscall" - -func readPlatformMachineID() (string, error) { - return syscall.Sysctl("kern.hostuuid") -} diff --git a/src/cmd/linuxkit/vendor/github.com/rs/xid/hostid_linux.go b/src/cmd/linuxkit/vendor/github.com/rs/xid/hostid_linux.go deleted file mode 100644 index 837b20436..000000000 --- a/src/cmd/linuxkit/vendor/github.com/rs/xid/hostid_linux.go +++ /dev/null @@ -1,13 +0,0 @@ -// +build linux - -package xid - -import "io/ioutil" - -func readPlatformMachineID() (string, error) { - b, err := ioutil.ReadFile("/etc/machine-id") - if err != nil || len(b) == 0 { - b, err = ioutil.ReadFile("/sys/class/dmi/id/product_uuid") - } - return string(b), err -} diff --git a/src/cmd/linuxkit/vendor/github.com/rs/xid/hostid_windows.go b/src/cmd/linuxkit/vendor/github.com/rs/xid/hostid_windows.go deleted file mode 100644 index ec2593ee3..000000000 --- a/src/cmd/linuxkit/vendor/github.com/rs/xid/hostid_windows.go +++ /dev/null @@ -1,38 +0,0 @@ -// +build windows - -package xid - -import ( - "fmt" - "syscall" - "unsafe" -) - -func readPlatformMachineID() (string, error) { - // source: https://github.com/shirou/gopsutil/blob/master/host/host_syscall.go - var h syscall.Handle - err := syscall.RegOpenKeyEx(syscall.HKEY_LOCAL_MACHINE, syscall.StringToUTF16Ptr(`SOFTWARE\Microsoft\Cryptography`), 0, syscall.KEY_READ|syscall.KEY_WOW64_64KEY, &h) - if err != nil { - return "", err - } - defer syscall.RegCloseKey(h) - - const syscallRegBufLen = 74 // len(`{`) + len(`abcdefgh-1234-456789012-123345456671` * 2) + len(`}`) // 2 == bytes/UTF16 - const uuidLen = 36 - - var regBuf [syscallRegBufLen]uint16 - bufLen := uint32(syscallRegBufLen) - var valType uint32 - err = syscall.RegQueryValueEx(h, syscall.StringToUTF16Ptr(`MachineGuid`), nil, &valType, (*byte)(unsafe.Pointer(®Buf[0])), &bufLen) - if err != nil { - return "", err - } - - hostID := syscall.UTF16ToString(regBuf[:]) - hostIDLen := len(hostID) - if hostIDLen != uuidLen { - return "", fmt.Errorf("HostID incorrect: %q\n", hostID) - } - - return hostID, nil -} diff --git a/src/cmd/linuxkit/vendor/github.com/rs/xid/id.go b/src/cmd/linuxkit/vendor/github.com/rs/xid/id.go deleted file mode 100644 index f1db1a18e..000000000 --- a/src/cmd/linuxkit/vendor/github.com/rs/xid/id.go +++ /dev/null @@ -1,380 +0,0 @@ -// Package xid is a globally unique id generator suited for web scale -// -// Xid is using Mongo Object ID algorithm to generate globally unique ids: -// https://docs.mongodb.org/manual/reference/object-id/ -// -// - 4-byte value representing the seconds since the Unix epoch, -// - 3-byte machine identifier, -// - 2-byte process id, and -// - 3-byte counter, starting with a random value. -// -// The binary representation of the id is compatible with Mongo 12 bytes Object IDs. -// The string representation is using base32 hex (w/o padding) for better space efficiency -// when stored in that form (20 bytes). The hex variant of base32 is used to retain the -// sortable property of the id. -// -// Xid doesn't use base64 because case sensitivity and the 2 non alphanum chars may be an -// issue when transported as a string between various systems. Base36 wasn't retained either -// because 1/ it's not standard 2/ the resulting size is not predictable (not bit aligned) -// and 3/ it would not remain sortable. To validate a base32 `xid`, expect a 20 chars long, -// all lowercase sequence of `a` to `v` letters and `0` to `9` numbers (`[0-9a-v]{20}`). -// -// UUID is 16 bytes (128 bits), snowflake is 8 bytes (64 bits), xid stands in between -// with 12 bytes with a more compact string representation ready for the web and no -// required configuration or central generation server. -// -// Features: -// -// - Size: 12 bytes (96 bits), smaller than UUID, larger than snowflake -// - Base32 hex encoded by default (16 bytes storage when transported as printable string) -// - Non configured, you don't need set a unique machine and/or data center id -// - K-ordered -// - Embedded time with 1 second precision -// - Unicity guaranteed for 16,777,216 (24 bits) unique ids per second and per host/process -// -// Best used with xlog's RequestIDHandler (https://godoc.org/github.com/rs/xlog#RequestIDHandler). -// -// References: -// -// - http://www.slideshare.net/davegardnerisme/unique-id-generation-in-distributed-systems -// - https://en.wikipedia.org/wiki/Universally_unique_identifier -// - https://blog.twitter.com/2010/announcing-snowflake -package xid - -import ( - "bytes" - "crypto/md5" - "crypto/rand" - "database/sql/driver" - "encoding/binary" - "errors" - "fmt" - "hash/crc32" - "io/ioutil" - "os" - "sort" - "sync/atomic" - "time" - "unsafe" -) - -// Code inspired from mgo/bson ObjectId - -// ID represents a unique request id -type ID [rawLen]byte - -const ( - encodedLen = 20 // string encoded len - rawLen = 12 // binary raw len - - // encoding stores a custom version of the base32 encoding with lower case - // letters. - encoding = "0123456789abcdefghijklmnopqrstuv" -) - -var ( - // ErrInvalidID is returned when trying to unmarshal an invalid ID - ErrInvalidID = errors.New("xid: invalid ID") - - // objectIDCounter is atomically incremented when generating a new ObjectId - // using NewObjectId() function. It's used as a counter part of an id. - // This id is initialized with a random value. - objectIDCounter = randInt() - - // machineId stores machine id generated once and used in subsequent calls - // to NewObjectId function. - machineID = readMachineID() - - // pid stores the current process id - pid = os.Getpid() - - nilID ID - - // dec is the decoding map for base32 encoding - dec [256]byte -) - -func init() { - for i := 0; i < len(dec); i++ { - dec[i] = 0xFF - } - for i := 0; i < len(encoding); i++ { - dec[encoding[i]] = byte(i) - } - - // If /proc/self/cpuset exists and is not /, we can assume that we are in a - // form of container and use the content of cpuset xor-ed with the PID in - // order get a reasonable machine global unique PID. - b, err := ioutil.ReadFile("/proc/self/cpuset") - if err == nil && len(b) > 1 { - pid ^= int(crc32.ChecksumIEEE(b)) - } -} - -// readMachineId generates machine id and puts it into the machineId global -// variable. If this function fails to get the hostname, it will cause -// a runtime error. -func readMachineID() []byte { - id := make([]byte, 3) - hid, err := readPlatformMachineID() - if err != nil || len(hid) == 0 { - hid, err = os.Hostname() - } - if err == nil && len(hid) != 0 { - hw := md5.New() - hw.Write([]byte(hid)) - copy(id, hw.Sum(nil)) - } else { - // Fallback to rand number if machine id can't be gathered - if _, randErr := rand.Reader.Read(id); randErr != nil { - panic(fmt.Errorf("xid: cannot get hostname nor generate a random number: %v; %v", err, randErr)) - } - } - return id -} - -// randInt generates a random uint32 -func randInt() uint32 { - b := make([]byte, 3) - if _, err := rand.Reader.Read(b); err != nil { - panic(fmt.Errorf("xid: cannot generate random number: %v;", err)) - } - return uint32(b[0])<<16 | uint32(b[1])<<8 | uint32(b[2]) -} - -// New generates a globally unique ID -func New() ID { - return NewWithTime(time.Now()) -} - -// NewWithTime generates a globally unique ID with the passed in time -func NewWithTime(t time.Time) ID { - var id ID - // Timestamp, 4 bytes, big endian - binary.BigEndian.PutUint32(id[:], uint32(t.Unix())) - // Machine, first 3 bytes of md5(hostname) - id[4] = machineID[0] - id[5] = machineID[1] - id[6] = machineID[2] - // Pid, 2 bytes, specs don't specify endianness, but we use big endian. - id[7] = byte(pid >> 8) - id[8] = byte(pid) - // Increment, 3 bytes, big endian - i := atomic.AddUint32(&objectIDCounter, 1) - id[9] = byte(i >> 16) - id[10] = byte(i >> 8) - id[11] = byte(i) - return id -} - -// FromString reads an ID from its string representation -func FromString(id string) (ID, error) { - i := &ID{} - err := i.UnmarshalText([]byte(id)) - return *i, err -} - -// String returns a base32 hex lowercased with no padding representation of the id (char set is 0-9, a-v). -func (id ID) String() string { - text := make([]byte, encodedLen) - encode(text, id[:]) - return *(*string)(unsafe.Pointer(&text)) -} - -// Encode encodes the id using base32 encoding, writing 20 bytes to dst and return it. -func (id ID) Encode(dst []byte) []byte { - encode(dst, id[:]) - return dst -} - -// MarshalText implements encoding/text TextMarshaler interface -func (id ID) MarshalText() ([]byte, error) { - text := make([]byte, encodedLen) - encode(text, id[:]) - return text, nil -} - -// MarshalJSON implements encoding/json Marshaler interface -func (id ID) MarshalJSON() ([]byte, error) { - if id.IsNil() { - return []byte("null"), nil - } - text := make([]byte, encodedLen+2) - encode(text[1:encodedLen+1], id[:]) - text[0], text[encodedLen+1] = '"', '"' - return text, nil -} - -// encode by unrolling the stdlib base32 algorithm + removing all safe checks -func encode(dst, id []byte) { - _ = dst[19] - _ = id[11] - - dst[19] = encoding[(id[11]<<4)&0x1F] - dst[18] = encoding[(id[11]>>1)&0x1F] - dst[17] = encoding[(id[11]>>6)&0x1F|(id[10]<<2)&0x1F] - dst[16] = encoding[id[10]>>3] - dst[15] = encoding[id[9]&0x1F] - dst[14] = encoding[(id[9]>>5)|(id[8]<<3)&0x1F] - dst[13] = encoding[(id[8]>>2)&0x1F] - dst[12] = encoding[id[8]>>7|(id[7]<<1)&0x1F] - dst[11] = encoding[(id[7]>>4)&0x1F|(id[6]<<4)&0x1F] - dst[10] = encoding[(id[6]>>1)&0x1F] - dst[9] = encoding[(id[6]>>6)&0x1F|(id[5]<<2)&0x1F] - dst[8] = encoding[id[5]>>3] - dst[7] = encoding[id[4]&0x1F] - dst[6] = encoding[id[4]>>5|(id[3]<<3)&0x1F] - dst[5] = encoding[(id[3]>>2)&0x1F] - dst[4] = encoding[id[3]>>7|(id[2]<<1)&0x1F] - dst[3] = encoding[(id[2]>>4)&0x1F|(id[1]<<4)&0x1F] - dst[2] = encoding[(id[1]>>1)&0x1F] - dst[1] = encoding[(id[1]>>6)&0x1F|(id[0]<<2)&0x1F] - dst[0] = encoding[id[0]>>3] -} - -// UnmarshalText implements encoding/text TextUnmarshaler interface -func (id *ID) UnmarshalText(text []byte) error { - if len(text) != encodedLen { - return ErrInvalidID - } - for _, c := range text { - if dec[c] == 0xFF { - return ErrInvalidID - } - } - decode(id, text) - return nil -} - -// UnmarshalJSON implements encoding/json Unmarshaler interface -func (id *ID) UnmarshalJSON(b []byte) error { - s := string(b) - if s == "null" { - *id = nilID - return nil - } - return id.UnmarshalText(b[1 : len(b)-1]) -} - -// decode by unrolling the stdlib base32 algorithm + removing all safe checks -func decode(id *ID, src []byte) { - _ = src[19] - _ = id[11] - - id[11] = dec[src[17]]<<6 | dec[src[18]]<<1 | dec[src[19]]>>4 - id[10] = dec[src[16]]<<3 | dec[src[17]]>>2 - id[9] = dec[src[14]]<<5 | dec[src[15]] - id[8] = dec[src[12]]<<7 | dec[src[13]]<<2 | dec[src[14]]>>3 - id[7] = dec[src[11]]<<4 | dec[src[12]]>>1 - id[6] = dec[src[9]]<<6 | dec[src[10]]<<1 | dec[src[11]]>>4 - id[5] = dec[src[8]]<<3 | dec[src[9]]>>2 - id[4] = dec[src[6]]<<5 | dec[src[7]] - id[3] = dec[src[4]]<<7 | dec[src[5]]<<2 | dec[src[6]]>>3 - id[2] = dec[src[3]]<<4 | dec[src[4]]>>1 - id[1] = dec[src[1]]<<6 | dec[src[2]]<<1 | dec[src[3]]>>4 - id[0] = dec[src[0]]<<3 | dec[src[1]]>>2 -} - -// Time returns the timestamp part of the id. -// It's a runtime error to call this method with an invalid id. -func (id ID) Time() time.Time { - // First 4 bytes of ObjectId is 32-bit big-endian seconds from epoch. - secs := int64(binary.BigEndian.Uint32(id[0:4])) - return time.Unix(secs, 0) -} - -// Machine returns the 3-byte machine id part of the id. -// It's a runtime error to call this method with an invalid id. -func (id ID) Machine() []byte { - return id[4:7] -} - -// Pid returns the process id part of the id. -// It's a runtime error to call this method with an invalid id. -func (id ID) Pid() uint16 { - return binary.BigEndian.Uint16(id[7:9]) -} - -// Counter returns the incrementing value part of the id. -// It's a runtime error to call this method with an invalid id. -func (id ID) Counter() int32 { - b := id[9:12] - // Counter is stored as big-endian 3-byte value - return int32(uint32(b[0])<<16 | uint32(b[1])<<8 | uint32(b[2])) -} - -// Value implements the driver.Valuer interface. -func (id ID) Value() (driver.Value, error) { - if id.IsNil() { - return nil, nil - } - b, err := id.MarshalText() - return string(b), err -} - -// Scan implements the sql.Scanner interface. -func (id *ID) Scan(value interface{}) (err error) { - switch val := value.(type) { - case string: - return id.UnmarshalText([]byte(val)) - case []byte: - return id.UnmarshalText(val) - case nil: - *id = nilID - return nil - default: - return fmt.Errorf("xid: scanning unsupported type: %T", value) - } -} - -// IsNil Returns true if this is a "nil" ID -func (id ID) IsNil() bool { - return id == nilID -} - -// NilID returns a zero value for `xid.ID`. -func NilID() ID { - return nilID -} - -// Bytes returns the byte array representation of `ID` -func (id ID) Bytes() []byte { - return id[:] -} - -// FromBytes convert the byte array representation of `ID` back to `ID` -func FromBytes(b []byte) (ID, error) { - var id ID - if len(b) != rawLen { - return id, ErrInvalidID - } - copy(id[:], b) - return id, nil -} - -// Compare returns an integer comparing two IDs. It behaves just like `bytes.Compare`. -// The result will be 0 if two IDs are identical, -1 if current id is less than the other one, -// and 1 if current id is greater than the other. -func (id ID) Compare(other ID) int { - return bytes.Compare(id[:], other[:]) -} - -type sorter []ID - -func (s sorter) Len() int { - return len(s) -} - -func (s sorter) Less(i, j int) bool { - return s[i].Compare(s[j]) < 0 -} - -func (s sorter) Swap(i, j int) { - s[i], s[j] = s[j], s[i] -} - -// Sort sorts an array of IDs inplace. -// It works by wrapping `[]ID` and use `sort.Sort`. -func Sort(ids []ID) { - sort.Sort(sorter(ids)) -} diff --git a/src/cmd/linuxkit/vendor/golang.org/x/crypto/AUTHORS b/src/cmd/linuxkit/vendor/golang.org/x/crypto/AUTHORS deleted file mode 100644 index 2b00ddba0..000000000 --- a/src/cmd/linuxkit/vendor/golang.org/x/crypto/AUTHORS +++ /dev/null @@ -1,3 +0,0 @@ -# This source code refers to The Go Authors for copyright purposes. -# The master list of authors is in the main Go distribution, -# visible at https://tip.golang.org/AUTHORS. diff --git a/src/cmd/linuxkit/vendor/golang.org/x/crypto/CONTRIBUTORS b/src/cmd/linuxkit/vendor/golang.org/x/crypto/CONTRIBUTORS deleted file mode 100644 index 1fbd3e976..000000000 --- a/src/cmd/linuxkit/vendor/golang.org/x/crypto/CONTRIBUTORS +++ /dev/null @@ -1,3 +0,0 @@ -# This source code was written by the Go contributors. -# The master list of contributors is in the main Go distribution, -# visible at https://tip.golang.org/CONTRIBUTORS. diff --git a/src/cmd/linuxkit/vendor/golang.org/x/crypto/chacha20/chacha_generic.go b/src/cmd/linuxkit/vendor/golang.org/x/crypto/chacha20/chacha_generic.go index a2ecf5c32..93eb5ae6d 100644 --- a/src/cmd/linuxkit/vendor/golang.org/x/crypto/chacha20/chacha_generic.go +++ b/src/cmd/linuxkit/vendor/golang.org/x/crypto/chacha20/chacha_generic.go @@ -12,7 +12,7 @@ import ( "errors" "math/bits" - "golang.org/x/crypto/internal/subtle" + "golang.org/x/crypto/internal/alias" ) const ( @@ -189,7 +189,7 @@ func (s *Cipher) XORKeyStream(dst, src []byte) { panic("chacha20: output smaller than input") } dst = dst[:len(src)] - if subtle.InexactOverlap(dst, src) { + if alias.InexactOverlap(dst, src) { panic("chacha20: invalid buffer overlap") } diff --git a/src/cmd/linuxkit/vendor/golang.org/x/crypto/curve25519/curve25519.go b/src/cmd/linuxkit/vendor/golang.org/x/crypto/curve25519/curve25519.go index cda3fdd35..bc62161d6 100644 --- a/src/cmd/linuxkit/vendor/golang.org/x/crypto/curve25519/curve25519.go +++ b/src/cmd/linuxkit/vendor/golang.org/x/crypto/curve25519/curve25519.go @@ -9,7 +9,8 @@ package curve25519 // import "golang.org/x/crypto/curve25519" import ( "crypto/subtle" - "fmt" + "errors" + "strconv" "golang.org/x/crypto/curve25519/internal/field" ) @@ -124,10 +125,10 @@ func X25519(scalar, point []byte) ([]byte, error) { func x25519(dst *[32]byte, scalar, point []byte) ([]byte, error) { var in [32]byte if l := len(scalar); l != 32 { - return nil, fmt.Errorf("bad scalar length: %d, expected %d", l, 32) + return nil, errors.New("bad scalar length: " + strconv.Itoa(l) + ", expected 32") } if l := len(point); l != 32 { - return nil, fmt.Errorf("bad point length: %d, expected %d", l, 32) + return nil, errors.New("bad point length: " + strconv.Itoa(l) + ", expected 32") } copy(in[:], scalar) if &point[0] == &Basepoint[0] { @@ -138,7 +139,7 @@ func x25519(dst *[32]byte, scalar, point []byte) ([]byte, error) { copy(base[:], point) ScalarMult(dst, &in, &base) if subtle.ConstantTimeCompare(dst[:], zero[:]) == 1 { - return nil, fmt.Errorf("bad input point: low order point") + return nil, errors.New("bad input point: low order point") } } return dst[:], nil diff --git a/src/cmd/linuxkit/vendor/golang.org/x/crypto/internal/subtle/aliasing.go b/src/cmd/linuxkit/vendor/golang.org/x/crypto/internal/alias/alias.go similarity index 84% rename from src/cmd/linuxkit/vendor/golang.org/x/crypto/internal/subtle/aliasing.go rename to src/cmd/linuxkit/vendor/golang.org/x/crypto/internal/alias/alias.go index 4fad24f8d..69c17f822 100644 --- a/src/cmd/linuxkit/vendor/golang.org/x/crypto/internal/subtle/aliasing.go +++ b/src/cmd/linuxkit/vendor/golang.org/x/crypto/internal/alias/alias.go @@ -5,9 +5,8 @@ //go:build !purego // +build !purego -// Package subtle implements functions that are often useful in cryptographic -// code but require careful thought to use correctly. -package subtle // import "golang.org/x/crypto/internal/subtle" +// Package alias implements memory aliasing tests. +package alias import "unsafe" diff --git a/src/cmd/linuxkit/vendor/golang.org/x/crypto/internal/subtle/aliasing_purego.go b/src/cmd/linuxkit/vendor/golang.org/x/crypto/internal/alias/alias_purego.go similarity index 86% rename from src/cmd/linuxkit/vendor/golang.org/x/crypto/internal/subtle/aliasing_purego.go rename to src/cmd/linuxkit/vendor/golang.org/x/crypto/internal/alias/alias_purego.go index 80ccbed2c..4775b0a43 100644 --- a/src/cmd/linuxkit/vendor/golang.org/x/crypto/internal/subtle/aliasing_purego.go +++ b/src/cmd/linuxkit/vendor/golang.org/x/crypto/internal/alias/alias_purego.go @@ -5,9 +5,8 @@ //go:build purego // +build purego -// Package subtle implements functions that are often useful in cryptographic -// code but require careful thought to use correctly. -package subtle // import "golang.org/x/crypto/internal/subtle" +// Package alias implements memory aliasing tests. +package alias // This is the Google App Engine standard variant based on reflect // because the unsafe package and cgo are disallowed. diff --git a/src/cmd/linuxkit/vendor/golang.org/x/crypto/pkcs12/crypto.go b/src/cmd/linuxkit/vendor/golang.org/x/crypto/pkcs12/crypto.go index 484ca51b7..96f4a1a56 100644 --- a/src/cmd/linuxkit/vendor/golang.org/x/crypto/pkcs12/crypto.go +++ b/src/cmd/linuxkit/vendor/golang.org/x/crypto/pkcs12/crypto.go @@ -117,7 +117,7 @@ func pbDecrypt(info decryptable, password []byte) (decrypted []byte, err error) } ps := decrypted[len(decrypted)-psLen:] decrypted = decrypted[:len(decrypted)-psLen] - if bytes.Compare(ps, bytes.Repeat([]byte{byte(psLen)}, psLen)) != 0 { + if !bytes.Equal(ps, bytes.Repeat([]byte{byte(psLen)}, psLen)) { return nil, ErrDecryption } diff --git a/src/cmd/linuxkit/vendor/golang.org/x/crypto/ssh/agent/client.go b/src/cmd/linuxkit/vendor/golang.org/x/crypto/ssh/agent/client.go index 3c4d18a15..c3e112a93 100644 --- a/src/cmd/linuxkit/vendor/golang.org/x/crypto/ssh/agent/client.go +++ b/src/cmd/linuxkit/vendor/golang.org/x/crypto/ssh/agent/client.go @@ -93,7 +93,7 @@ type ExtendedAgent interface { type ConstraintExtension struct { // ExtensionName consist of a UTF-8 string suffixed by the // implementation domain following the naming scheme defined - // in Section 4.2 of [RFC4251], e.g. "foo@example.com". + // in Section 4.2 of RFC 4251, e.g. "foo@example.com". ExtensionName string // ExtensionDetails contains the actual content of the extended // constraint. @@ -226,7 +226,9 @@ var ErrExtensionUnsupported = errors.New("agent: extension unsupported") type extensionAgentMsg struct { ExtensionType string `sshtype:"27"` - Contents []byte + // NOTE: this matches OpenSSH's PROTOCOL.agent, not the IETF draft [PROTOCOL.agent], + // so that it matches what OpenSSH actually implements in the wild. + Contents []byte `ssh:"rest"` } // Key represents a protocol 2 public key as defined in @@ -729,7 +731,7 @@ func (c *client) insertCert(s interface{}, cert *ssh.Certificate, comment string if err != nil { return err } - if bytes.Compare(cert.Key.Marshal(), signer.PublicKey().Marshal()) != 0 { + if !bytes.Equal(cert.Key.Marshal(), signer.PublicKey().Marshal()) { return errors.New("agent: signer and cert have different public key") } diff --git a/src/cmd/linuxkit/vendor/golang.org/x/crypto/ssh/certs.go b/src/cmd/linuxkit/vendor/golang.org/x/crypto/ssh/certs.go index 4600c2077..fc04d03e1 100644 --- a/src/cmd/linuxkit/vendor/golang.org/x/crypto/ssh/certs.go +++ b/src/cmd/linuxkit/vendor/golang.org/x/crypto/ssh/certs.go @@ -251,7 +251,7 @@ type algorithmOpenSSHCertSigner struct { // private key is held by signer. It returns an error if the public key in cert // doesn't match the key used by signer. func NewCertSigner(cert *Certificate, signer Signer) (Signer, error) { - if bytes.Compare(cert.Key.Marshal(), signer.PublicKey().Marshal()) != 0 { + if !bytes.Equal(cert.Key.Marshal(), signer.PublicKey().Marshal()) { return nil, errors.New("ssh: signer and cert have different public key") } diff --git a/src/cmd/linuxkit/vendor/golang.org/x/crypto/ssh/cipher.go b/src/cmd/linuxkit/vendor/golang.org/x/crypto/ssh/cipher.go index 770e8a663..87f48552c 100644 --- a/src/cmd/linuxkit/vendor/golang.org/x/crypto/ssh/cipher.go +++ b/src/cmd/linuxkit/vendor/golang.org/x/crypto/ssh/cipher.go @@ -15,7 +15,6 @@ import ( "fmt" "hash" "io" - "io/ioutil" "golang.org/x/crypto/chacha20" "golang.org/x/crypto/internal/poly1305" @@ -97,13 +96,13 @@ func streamCipherMode(skip int, createFunc func(key, iv []byte) (cipher.Stream, // are not supported and will not be negotiated, even if explicitly requested in // ClientConfig.Crypto.Ciphers. var cipherModes = map[string]*cipherMode{ - // Ciphers from RFC4344, which introduced many CTR-based ciphers. Algorithms + // Ciphers from RFC 4344, which introduced many CTR-based ciphers. Algorithms // are defined in the order specified in the RFC. "aes128-ctr": {16, aes.BlockSize, streamCipherMode(0, newAESCTR)}, "aes192-ctr": {24, aes.BlockSize, streamCipherMode(0, newAESCTR)}, "aes256-ctr": {32, aes.BlockSize, streamCipherMode(0, newAESCTR)}, - // Ciphers from RFC4345, which introduces security-improved arcfour ciphers. + // Ciphers from RFC 4345, which introduces security-improved arcfour ciphers. // They are defined in the order specified in the RFC. "arcfour128": {16, 0, streamCipherMode(1536, newRC4)}, "arcfour256": {32, 0, streamCipherMode(1536, newRC4)}, @@ -111,7 +110,7 @@ var cipherModes = map[string]*cipherMode{ // Cipher defined in RFC 4253, which describes SSH Transport Layer Protocol. // Note that this cipher is not safe, as stated in RFC 4253: "Arcfour (and // RC4) has problems with weak keys, and should be used with caution." - // RFC4345 introduces improved versions of Arcfour. + // RFC 4345 introduces improved versions of Arcfour. "arcfour": {16, 0, streamCipherMode(0, newRC4)}, // AEAD ciphers @@ -497,7 +496,7 @@ func (c *cbcCipher) readCipherPacket(seqNum uint32, r io.Reader) ([]byte, error) // data, to make distinguishing between // failing MAC and failing length check more // difficult. - io.CopyN(ioutil.Discard, r, int64(c.oracleCamouflage)) + io.CopyN(io.Discard, r, int64(c.oracleCamouflage)) } } return p, err @@ -642,7 +641,7 @@ const chacha20Poly1305ID = "chacha20-poly1305@openssh.com" // // https://tools.ietf.org/html/draft-josefsson-ssh-chacha20-poly1305-openssh-00 // -// the methods here also implement padding, which RFC4253 Section 6 +// the methods here also implement padding, which RFC 4253 Section 6 // also requires of stream ciphers. type chacha20Poly1305Cipher struct { lengthKey [32]byte diff --git a/src/cmd/linuxkit/vendor/golang.org/x/crypto/ssh/common.go b/src/cmd/linuxkit/vendor/golang.org/x/crypto/ssh/common.go index 2a47a61de..7a5ff2d2e 100644 --- a/src/cmd/linuxkit/vendor/golang.org/x/crypto/ssh/common.go +++ b/src/cmd/linuxkit/vendor/golang.org/x/crypto/ssh/common.go @@ -149,7 +149,7 @@ type directionAlgorithms struct { // rekeyBytes returns a rekeying intervals in bytes. func (a *directionAlgorithms) rekeyBytes() int64 { - // According to RFC4344 block ciphers should rekey after + // According to RFC 4344 block ciphers should rekey after // 2^(BLOCKSIZE/4) blocks. For all AES flavors BLOCKSIZE is // 128. switch a.Cipher { @@ -158,7 +158,7 @@ func (a *directionAlgorithms) rekeyBytes() int64 { } - // For others, stick with RFC4253 recommendation to rekey after 1 Gb of data. + // For others, stick with RFC 4253 recommendation to rekey after 1 Gb of data. return 1 << 30 } diff --git a/src/cmd/linuxkit/vendor/golang.org/x/crypto/ssh/connection.go b/src/cmd/linuxkit/vendor/golang.org/x/crypto/ssh/connection.go index fd6b0681b..35661a52b 100644 --- a/src/cmd/linuxkit/vendor/golang.org/x/crypto/ssh/connection.go +++ b/src/cmd/linuxkit/vendor/golang.org/x/crypto/ssh/connection.go @@ -52,7 +52,7 @@ type Conn interface { // SendRequest sends a global request, and returns the // reply. If wantReply is true, it returns the response status - // and payload. See also RFC4254, section 4. + // and payload. See also RFC 4254, section 4. SendRequest(name string, wantReply bool, payload []byte) (bool, []byte, error) // OpenChannel tries to open an channel. If the request is diff --git a/src/cmd/linuxkit/vendor/golang.org/x/crypto/ssh/keys.go b/src/cmd/linuxkit/vendor/golang.org/x/crypto/ssh/keys.go index 1c7de1a6d..729698041 100644 --- a/src/cmd/linuxkit/vendor/golang.org/x/crypto/ssh/keys.go +++ b/src/cmd/linuxkit/vendor/golang.org/x/crypto/ssh/keys.go @@ -184,7 +184,7 @@ func ParseKnownHosts(in []byte) (marker string, hosts []string, pubKey PublicKey return "", nil, nil, "", nil, io.EOF } -// ParseAuthorizedKeys parses a public key from an authorized_keys +// ParseAuthorizedKey parses a public key from an authorized_keys // file used in OpenSSH according to the sshd(8) manual page. func ParseAuthorizedKey(in []byte) (out PublicKey, comment string, options []string, rest []byte, err error) { for len(in) > 0 { diff --git a/src/cmd/linuxkit/vendor/golang.org/x/crypto/ssh/server.go b/src/cmd/linuxkit/vendor/golang.org/x/crypto/ssh/server.go index 70045bdfd..2260b20af 100644 --- a/src/cmd/linuxkit/vendor/golang.org/x/crypto/ssh/server.go +++ b/src/cmd/linuxkit/vendor/golang.org/x/crypto/ssh/server.go @@ -68,8 +68,16 @@ type ServerConfig struct { // NoClientAuth is true if clients are allowed to connect without // authenticating. + // To determine NoClientAuth at runtime, set NoClientAuth to true + // and the optional NoClientAuthCallback to a non-nil value. NoClientAuth bool + // NoClientAuthCallback, if non-nil, is called when a user + // attempts to authenticate with auth method "none". + // NoClientAuth must also be set to true for this be used, or + // this func is unused. + NoClientAuthCallback func(ConnMetadata) (*Permissions, error) + // MaxAuthTries specifies the maximum number of authentication attempts // permitted per connection. If set to a negative number, the number of // attempts are unlimited. If set to zero, the number of attempts are limited @@ -455,7 +463,11 @@ userAuthLoop: switch userAuthReq.Method { case "none": if config.NoClientAuth { - authErr = nil + if config.NoClientAuthCallback != nil { + perms, authErr = config.NoClientAuthCallback(s) + } else { + authErr = nil + } } // allow initial attempt of 'none' without penalty diff --git a/src/cmd/linuxkit/vendor/golang.org/x/crypto/ssh/session.go b/src/cmd/linuxkit/vendor/golang.org/x/crypto/ssh/session.go index eca31a22d..acef62259 100644 --- a/src/cmd/linuxkit/vendor/golang.org/x/crypto/ssh/session.go +++ b/src/cmd/linuxkit/vendor/golang.org/x/crypto/ssh/session.go @@ -13,7 +13,6 @@ import ( "errors" "fmt" "io" - "io/ioutil" "sync" ) @@ -124,7 +123,7 @@ type Session struct { // output and error. // // If either is nil, Run connects the corresponding file - // descriptor to an instance of ioutil.Discard. There is a + // descriptor to an instance of io.Discard. There is a // fixed amount of buffering that is shared for the two streams. // If either blocks it may eventually cause the remote // command to block. @@ -506,7 +505,7 @@ func (s *Session) stdout() { return } if s.Stdout == nil { - s.Stdout = ioutil.Discard + s.Stdout = io.Discard } s.copyFuncs = append(s.copyFuncs, func() error { _, err := io.Copy(s.Stdout, s.ch) @@ -519,7 +518,7 @@ func (s *Session) stderr() { return } if s.Stderr == nil { - s.Stderr = ioutil.Discard + s.Stderr = io.Discard } s.copyFuncs = append(s.copyFuncs, func() error { _, err := io.Copy(s.Stderr, s.ch.Stderr()) diff --git a/src/cmd/linuxkit/vendor/golang.org/x/mod/LICENSE b/src/cmd/linuxkit/vendor/golang.org/x/mod/LICENSE new file mode 100644 index 000000000..6a66aea5e --- /dev/null +++ b/src/cmd/linuxkit/vendor/golang.org/x/mod/LICENSE @@ -0,0 +1,27 @@ +Copyright (c) 2009 The Go Authors. All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are +met: + + * Redistributions of source code must retain the above copyright +notice, this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above +copyright notice, this list of conditions and the following disclaimer +in the documentation and/or other materials provided with the +distribution. + * Neither the name of Google Inc. nor the names of its +contributors may be used to endorse or promote products derived from +this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. diff --git a/src/cmd/linuxkit/vendor/golang.org/x/mod/PATENTS b/src/cmd/linuxkit/vendor/golang.org/x/mod/PATENTS new file mode 100644 index 000000000..733099041 --- /dev/null +++ b/src/cmd/linuxkit/vendor/golang.org/x/mod/PATENTS @@ -0,0 +1,22 @@ +Additional IP Rights Grant (Patents) + +"This implementation" means the copyrightable works distributed by +Google as part of the Go project. + +Google hereby grants to You a perpetual, worldwide, non-exclusive, +no-charge, royalty-free, irrevocable (except as stated in this section) +patent license to make, have made, use, offer to sell, sell, import, +transfer and otherwise run, modify and propagate the contents of this +implementation of Go, where such license applies only to those patent +claims, both currently owned or controlled by Google and acquired in +the future, licensable by Google that are necessarily infringed by this +implementation of Go. This grant does not include claims that would be +infringed only as a consequence of further modification of this +implementation. If you or your agent or exclusive licensee institute or +order or agree to the institution of patent litigation against any +entity (including a cross-claim or counterclaim in a lawsuit) alleging +that this implementation of Go or any code incorporated within this +implementation of Go constitutes direct or contributory patent +infringement, or inducement of patent infringement, then any patent +rights granted to you under this License for this implementation of Go +shall terminate as of the date such litigation is filed. diff --git a/src/cmd/linuxkit/vendor/golang.org/x/mod/semver/semver.go b/src/cmd/linuxkit/vendor/golang.org/x/mod/semver/semver.go new file mode 100644 index 000000000..a30a22bf2 --- /dev/null +++ b/src/cmd/linuxkit/vendor/golang.org/x/mod/semver/semver.go @@ -0,0 +1,401 @@ +// Copyright 2018 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +// Package semver implements comparison of semantic version strings. +// In this package, semantic version strings must begin with a leading "v", +// as in "v1.0.0". +// +// The general form of a semantic version string accepted by this package is +// +// vMAJOR[.MINOR[.PATCH[-PRERELEASE][+BUILD]]] +// +// where square brackets indicate optional parts of the syntax; +// MAJOR, MINOR, and PATCH are decimal integers without extra leading zeros; +// PRERELEASE and BUILD are each a series of non-empty dot-separated identifiers +// using only alphanumeric characters and hyphens; and +// all-numeric PRERELEASE identifiers must not have leading zeros. +// +// This package follows Semantic Versioning 2.0.0 (see semver.org) +// with two exceptions. First, it requires the "v" prefix. Second, it recognizes +// vMAJOR and vMAJOR.MINOR (with no prerelease or build suffixes) +// as shorthands for vMAJOR.0.0 and vMAJOR.MINOR.0. +package semver + +import "sort" + +// parsed returns the parsed form of a semantic version string. +type parsed struct { + major string + minor string + patch string + short string + prerelease string + build string +} + +// IsValid reports whether v is a valid semantic version string. +func IsValid(v string) bool { + _, ok := parse(v) + return ok +} + +// Canonical returns the canonical formatting of the semantic version v. +// It fills in any missing .MINOR or .PATCH and discards build metadata. +// Two semantic versions compare equal only if their canonical formattings +// are identical strings. +// The canonical invalid semantic version is the empty string. +func Canonical(v string) string { + p, ok := parse(v) + if !ok { + return "" + } + if p.build != "" { + return v[:len(v)-len(p.build)] + } + if p.short != "" { + return v + p.short + } + return v +} + +// Major returns the major version prefix of the semantic version v. +// For example, Major("v2.1.0") == "v2". +// If v is an invalid semantic version string, Major returns the empty string. +func Major(v string) string { + pv, ok := parse(v) + if !ok { + return "" + } + return v[:1+len(pv.major)] +} + +// MajorMinor returns the major.minor version prefix of the semantic version v. +// For example, MajorMinor("v2.1.0") == "v2.1". +// If v is an invalid semantic version string, MajorMinor returns the empty string. +func MajorMinor(v string) string { + pv, ok := parse(v) + if !ok { + return "" + } + i := 1 + len(pv.major) + if j := i + 1 + len(pv.minor); j <= len(v) && v[i] == '.' && v[i+1:j] == pv.minor { + return v[:j] + } + return v[:i] + "." + pv.minor +} + +// Prerelease returns the prerelease suffix of the semantic version v. +// For example, Prerelease("v2.1.0-pre+meta") == "-pre". +// If v is an invalid semantic version string, Prerelease returns the empty string. +func Prerelease(v string) string { + pv, ok := parse(v) + if !ok { + return "" + } + return pv.prerelease +} + +// Build returns the build suffix of the semantic version v. +// For example, Build("v2.1.0+meta") == "+meta". +// If v is an invalid semantic version string, Build returns the empty string. +func Build(v string) string { + pv, ok := parse(v) + if !ok { + return "" + } + return pv.build +} + +// Compare returns an integer comparing two versions according to +// semantic version precedence. +// The result will be 0 if v == w, -1 if v < w, or +1 if v > w. +// +// An invalid semantic version string is considered less than a valid one. +// All invalid semantic version strings compare equal to each other. +func Compare(v, w string) int { + pv, ok1 := parse(v) + pw, ok2 := parse(w) + if !ok1 && !ok2 { + return 0 + } + if !ok1 { + return -1 + } + if !ok2 { + return +1 + } + if c := compareInt(pv.major, pw.major); c != 0 { + return c + } + if c := compareInt(pv.minor, pw.minor); c != 0 { + return c + } + if c := compareInt(pv.patch, pw.patch); c != 0 { + return c + } + return comparePrerelease(pv.prerelease, pw.prerelease) +} + +// Max canonicalizes its arguments and then returns the version string +// that compares greater. +// +// Deprecated: use Compare instead. In most cases, returning a canonicalized +// version is not expected or desired. +func Max(v, w string) string { + v = Canonical(v) + w = Canonical(w) + if Compare(v, w) > 0 { + return v + } + return w +} + +// ByVersion implements sort.Interface for sorting semantic version strings. +type ByVersion []string + +func (vs ByVersion) Len() int { return len(vs) } +func (vs ByVersion) Swap(i, j int) { vs[i], vs[j] = vs[j], vs[i] } +func (vs ByVersion) Less(i, j int) bool { + cmp := Compare(vs[i], vs[j]) + if cmp != 0 { + return cmp < 0 + } + return vs[i] < vs[j] +} + +// Sort sorts a list of semantic version strings using ByVersion. +func Sort(list []string) { + sort.Sort(ByVersion(list)) +} + +func parse(v string) (p parsed, ok bool) { + if v == "" || v[0] != 'v' { + return + } + p.major, v, ok = parseInt(v[1:]) + if !ok { + return + } + if v == "" { + p.minor = "0" + p.patch = "0" + p.short = ".0.0" + return + } + if v[0] != '.' { + ok = false + return + } + p.minor, v, ok = parseInt(v[1:]) + if !ok { + return + } + if v == "" { + p.patch = "0" + p.short = ".0" + return + } + if v[0] != '.' { + ok = false + return + } + p.patch, v, ok = parseInt(v[1:]) + if !ok { + return + } + if len(v) > 0 && v[0] == '-' { + p.prerelease, v, ok = parsePrerelease(v) + if !ok { + return + } + } + if len(v) > 0 && v[0] == '+' { + p.build, v, ok = parseBuild(v) + if !ok { + return + } + } + if v != "" { + ok = false + return + } + ok = true + return +} + +func parseInt(v string) (t, rest string, ok bool) { + if v == "" { + return + } + if v[0] < '0' || '9' < v[0] { + return + } + i := 1 + for i < len(v) && '0' <= v[i] && v[i] <= '9' { + i++ + } + if v[0] == '0' && i != 1 { + return + } + return v[:i], v[i:], true +} + +func parsePrerelease(v string) (t, rest string, ok bool) { + // "A pre-release version MAY be denoted by appending a hyphen and + // a series of dot separated identifiers immediately following the patch version. + // Identifiers MUST comprise only ASCII alphanumerics and hyphen [0-9A-Za-z-]. + // Identifiers MUST NOT be empty. Numeric identifiers MUST NOT include leading zeroes." + if v == "" || v[0] != '-' { + return + } + i := 1 + start := 1 + for i < len(v) && v[i] != '+' { + if !isIdentChar(v[i]) && v[i] != '.' { + return + } + if v[i] == '.' { + if start == i || isBadNum(v[start:i]) { + return + } + start = i + 1 + } + i++ + } + if start == i || isBadNum(v[start:i]) { + return + } + return v[:i], v[i:], true +} + +func parseBuild(v string) (t, rest string, ok bool) { + if v == "" || v[0] != '+' { + return + } + i := 1 + start := 1 + for i < len(v) { + if !isIdentChar(v[i]) && v[i] != '.' { + return + } + if v[i] == '.' { + if start == i { + return + } + start = i + 1 + } + i++ + } + if start == i { + return + } + return v[:i], v[i:], true +} + +func isIdentChar(c byte) bool { + return 'A' <= c && c <= 'Z' || 'a' <= c && c <= 'z' || '0' <= c && c <= '9' || c == '-' +} + +func isBadNum(v string) bool { + i := 0 + for i < len(v) && '0' <= v[i] && v[i] <= '9' { + i++ + } + return i == len(v) && i > 1 && v[0] == '0' +} + +func isNum(v string) bool { + i := 0 + for i < len(v) && '0' <= v[i] && v[i] <= '9' { + i++ + } + return i == len(v) +} + +func compareInt(x, y string) int { + if x == y { + return 0 + } + if len(x) < len(y) { + return -1 + } + if len(x) > len(y) { + return +1 + } + if x < y { + return -1 + } else { + return +1 + } +} + +func comparePrerelease(x, y string) int { + // "When major, minor, and patch are equal, a pre-release version has + // lower precedence than a normal version. + // Example: 1.0.0-alpha < 1.0.0. + // Precedence for two pre-release versions with the same major, minor, + // and patch version MUST be determined by comparing each dot separated + // identifier from left to right until a difference is found as follows: + // identifiers consisting of only digits are compared numerically and + // identifiers with letters or hyphens are compared lexically in ASCII + // sort order. Numeric identifiers always have lower precedence than + // non-numeric identifiers. A larger set of pre-release fields has a + // higher precedence than a smaller set, if all of the preceding + // identifiers are equal. + // Example: 1.0.0-alpha < 1.0.0-alpha.1 < 1.0.0-alpha.beta < + // 1.0.0-beta < 1.0.0-beta.2 < 1.0.0-beta.11 < 1.0.0-rc.1 < 1.0.0." + if x == y { + return 0 + } + if x == "" { + return +1 + } + if y == "" { + return -1 + } + for x != "" && y != "" { + x = x[1:] // skip - or . + y = y[1:] // skip - or . + var dx, dy string + dx, x = nextIdent(x) + dy, y = nextIdent(y) + if dx != dy { + ix := isNum(dx) + iy := isNum(dy) + if ix != iy { + if ix { + return -1 + } else { + return +1 + } + } + if ix { + if len(dx) < len(dy) { + return -1 + } + if len(dx) > len(dy) { + return +1 + } + } + if dx < dy { + return -1 + } else { + return +1 + } + } + } + if x == "" { + return -1 + } else { + return +1 + } +} + +func nextIdent(x string) (dx, rest string) { + i := 0 + for i < len(x) && x[i] != '.' { + i++ + } + return x[:i], x[i:] +} diff --git a/src/cmd/linuxkit/vendor/modules.txt b/src/cmd/linuxkit/vendor/modules.txt index 569254420..a69e8114e 100644 --- a/src/cmd/linuxkit/vendor/modules.txt +++ b/src/cmd/linuxkit/vendor/modules.txt @@ -41,9 +41,11 @@ github.com/Azure/go-autorest/logger # github.com/Azure/go-autorest/tracing v0.6.0 ## explicit; go 1.12 github.com/Azure/go-autorest/tracing -# github.com/Code-Hex/vz v0.0.4 -## explicit; go 1.16 -github.com/Code-Hex/vz +# github.com/Code-Hex/vz/v3 v3.0.0 +## explicit; go 1.19 +github.com/Code-Hex/vz/v3 +github.com/Code-Hex/vz/v3/internal/objc +github.com/Code-Hex/vz/v3/internal/progress # github.com/Microsoft/go-winio v0.5.2 ## explicit; go 1.13 github.com/Microsoft/go-winio @@ -559,7 +561,6 @@ github.com/radu-matei/azure-vhd-utils/vhdcore/writer github.com/rn/iso9660wrap # github.com/rs/xid v1.3.0 ## explicit; go 1.12 -github.com/rs/xid # github.com/scaleway/scaleway-sdk-go v1.0.0-beta.6 ## explicit; go 1.12 github.com/scaleway/scaleway-sdk-go/api/instance/v1 @@ -698,20 +699,23 @@ go.opentelemetry.io/proto/otlp/collector/trace/v1 go.opentelemetry.io/proto/otlp/common/v1 go.opentelemetry.io/proto/otlp/resource/v1 go.opentelemetry.io/proto/otlp/trace/v1 -# golang.org/x/crypto v0.0.0-20220525230936-793ad666bf5e +# golang.org/x/crypto v0.1.0 ## explicit; go 1.17 golang.org/x/crypto/blowfish golang.org/x/crypto/chacha20 golang.org/x/crypto/curve25519 golang.org/x/crypto/curve25519/internal/field golang.org/x/crypto/ed25519 +golang.org/x/crypto/internal/alias golang.org/x/crypto/internal/poly1305 -golang.org/x/crypto/internal/subtle golang.org/x/crypto/pkcs12 golang.org/x/crypto/pkcs12/internal/rc2 golang.org/x/crypto/ssh golang.org/x/crypto/ssh/agent golang.org/x/crypto/ssh/internal/bcrypt_pbkdf +# golang.org/x/mod v0.6.0 +## explicit; go 1.17 +golang.org/x/mod/semver # golang.org/x/net v0.1.0 ## explicit; go 1.17 golang.org/x/net/context