Skip to content

Commit

Permalink
Merge pull request #93 from Code-Hex/add/13-api-for-mac
Browse files Browse the repository at this point in the history
added a few of APIs for mac guest
  • Loading branch information
Code-Hex authored Oct 30, 2022
2 parents 831f637 + 86d8b8a commit 961cd19
Show file tree
Hide file tree
Showing 9 changed files with 145 additions and 13 deletions.
38 changes: 37 additions & 1 deletion example/macOS/installer.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,13 +3,26 @@ package main
import (
"context"
"fmt"
"os"
"time"

"github.com/Code-Hex/vz/v2"
)

func installMacOS(ctx context.Context) error {
if err := CreateVMBundle(); err != nil {
return fmt.Errorf("failed to VM.bundle in home directory: %w", err)
}

restoreImagePath := GetRestoreImagePath()
if _, err := os.Stat(restoreImagePath); err != nil {
if !os.IsNotExist(err) {
return err
}
if err := downloadRestoreImage(ctx, restoreImagePath); err != nil {
return fmt.Errorf("failed to download restore image: %w", err)
}
}
restoreImage, err := vz.LoadMacOSRestoreImageFromPath(restoreImagePath)
if err != nil {
return fmt.Errorf("failed to load restore image: %w", err)
Expand Down Expand Up @@ -46,7 +59,7 @@ func installMacOS(ctx context.Context) error {
fmt.Println("install has been completed")
return
case <-ticker.C:
fmt.Printf("install: %d\r", int(installer.FractionCompleted()*100))
fmt.Printf("install: %.3f%%\r", installer.FractionCompleted()*100)
}
}
}()
Expand Down Expand Up @@ -95,3 +108,26 @@ func createMacInstallerPlatformConfiguration(macOSConfiguration *vz.MacOSConfigu
vz.WithMachineIdentifier(machineIdentifier),
)
}

func downloadRestoreImage(ctx context.Context, destPath string) error {
progress, err := vz.FetchLatestSupportedMacOSRestoreImage(ctx, destPath)
if err != nil {
return err
}

fmt.Printf("download restore image in %q\n", destPath)
ticker := time.NewTicker(500 * time.Millisecond)
defer ticker.Stop()
for {
select {
case <-ctx.Done():
fmt.Println("download has been cancelled")
return ctx.Err()
case <-progress.Finished():
fmt.Println("download has been completed")
return progress.Err()
case <-ticker.C:
fmt.Printf("download: %.3f%%\r", progress.FractionCompleted()*100)
}
}
}
16 changes: 8 additions & 8 deletions example/macOS/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -173,10 +173,6 @@ func createNetworkDeviceConfiguration() (*vz.VirtioNetworkDeviceConfiguration, e
return vz.NewVirtioNetworkDeviceConfiguration(natAttachment)
}

func createPointingDeviceConfiguration() (*vz.USBScreenCoordinatePointingDeviceConfiguration, error) {
return vz.NewUSBScreenCoordinatePointingDeviceConfiguration()
}

func createKeyboardConfiguration() (*vz.USBKeyboardConfiguration, error) {
return vz.NewUSBKeyboardConfiguration()
}
Expand Down Expand Up @@ -262,13 +258,17 @@ func setupVMConfiguration(platformConfig vz.PlatformConfiguration) (*vz.VirtualM
networkDeviceConfig,
})

pointingDeviceConfig, err := createPointingDeviceConfiguration()
usbScreenPointingDevice, err := vz.NewUSBScreenCoordinatePointingDeviceConfiguration()
if err != nil {
return nil, fmt.Errorf("failed to create pointing device configuration: %w", err)
}
config.SetPointingDevicesVirtualMachineConfiguration([]vz.PointingDeviceConfiguration{
pointingDeviceConfig,
})
pointingDevices := []vz.PointingDeviceConfiguration{usbScreenPointingDevice}

trackpad, err := vz.NewMacTrackpadConfiguration()
if err == nil {
pointingDevices = append(pointingDevices, trackpad)
}
config.SetPointingDevicesVirtualMachineConfiguration(pointingDevices)

keyboardDeviceConfig, err := createKeyboardConfiguration()
if err != nil {
Expand Down
49 changes: 49 additions & 0 deletions pointing_device_arm64.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
//go:build darwin && arm64
// +build darwin,arm64

package vz

/*
#cgo darwin CFLAGS: -x objective-c -fno-objc-arc
#cgo darwin LDFLAGS: -lobjc -framework Foundation -framework Virtualization
# include "virtualization_13_arm64.h"
*/
import "C"
import "runtime"

// 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, ErrUnsupportedOSVersion will
// be returned on older versions.
func NewMacTrackpadConfiguration() (*MacTrackpadConfiguration, error) {
if macosMajorVersionLessThan(13) {
return nil, ErrUnsupportedOSVersion
}
config := &MacTrackpadConfiguration{
pointer: pointer{
ptr: C.newVZMacTrackpadConfiguration(),
},
}
runtime.SetFinalizer(config, func(self *MacTrackpadConfiguration) {
self.Release()
})
return config, nil
}
13 changes: 13 additions & 0 deletions shared_directory.go
Original file line number Diff line number Diff line change
Expand Up @@ -170,3 +170,16 @@ func NewMultipleDirectoryShare(shares map[string]*SharedDirectory) (*MultipleDir
})
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, ErrUnsupportedOSVersion will
// be returned on older versions.
func MacOSGuestAutomountTag() (string, error) {
if macosMajorVersionLessThan(13) {
return "", ErrUnsupportedOSVersion
}
cstring := (*char)(C.getMacOSGuestAutomountTag())
return cstring.String(), nil
}
4 changes: 3 additions & 1 deletion virtualization_13.h
Original file line number Diff line number Diff line change
Expand Up @@ -41,4 +41,6 @@ void *newVZSpiceAgentPortAttachment();
void setSharesClipboardVZSpiceAgentPortAttachment(void *attachment, bool sharesClipboard);
const char *getSpiceAgentPortName();

void startWithOptionsCompletionHandler(void *machine, void *queue, void *options, void *completionHandler);
void startWithOptionsCompletionHandler(void *machine, void *queue, void *options, void *completionHandler);

const char *getMacOSGuestAutomountTag();
14 changes: 14 additions & 0 deletions virtualization_13.m
Original file line number Diff line number Diff line change
Expand Up @@ -438,4 +438,18 @@ void startWithOptionsCompletionHandler(void *machine, void *queue, void *options
}
#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();
}
2 changes: 2 additions & 0 deletions virtualization_13_arm64.h
Original file line number Diff line number Diff line change
Expand Up @@ -24,4 +24,6 @@ int availabilityVZLinuxRosettaDirectoryShare();

void *newVZMacOSVirtualMachineStartOptions(bool startUpFromMacOSRecovery);

void *newVZMacTrackpadConfiguration();

#endif
19 changes: 19 additions & 0 deletions virtualization_13_arm64.m
Original file line number Diff line number Diff line change
Expand Up @@ -68,3 +68,22 @@ int availabilityVZLinuxRosettaDirectoryShare()
#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();
}
3 changes: 0 additions & 3 deletions virtualization_arm64.go
Original file line number Diff line number Diff line change
Expand Up @@ -216,9 +216,6 @@ func NewMacAuxiliaryStorage(storagePath string, opts ...NewMacAuxiliaryStorageOp
if macosMajorVersionLessThan(12) {
return nil, ErrUnsupportedOSVersion
}
if _, err := os.Stat(storagePath); err != nil {
return nil, err
}

storage := &MacAuxiliaryStorage{storagePath: storagePath}
for _, opt := range opts {
Expand Down

0 comments on commit 961cd19

Please sign in to comment.