Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Basic implementation of shared folders #28

Merged
merged 20 commits into from
Aug 10, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
15 changes: 11 additions & 4 deletions .github/workflows/compile.yml
Original file line number Diff line number Diff line change
@@ -1,20 +1,27 @@
name: Build
on:
push:
paths-ignore:
- example/**
- README.md
branches:
- "master"
pull_request: {}
- "master"
pull_request:
paths-ignore:
- example/**
- README.md
jobs:
build:
runs-on: ${{ matrix.os }}
strategy:
fail-fast: false
matrix:
os:
- macOS-11
- macOS-12
go:
- 1.16
- 1.17
- 1.18
- 1.19
steps:
- name: Check out repository code
uses: actions/checkout@v2
Expand Down
17 changes: 15 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -13,8 +13,21 @@ 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
Higher or equal to Go 1.17.

### macOS Monterey (v12.x.x)

For the latest macOS version is developed on the [master](https://github.com/Code-Hex/vz) branch and released as `v2.x.x`.

You can install by `go get github.com/Code-Hex/vz/v2`

### macOS Big Sur (v11.x.x)

Some methods of this framework are available and some are not, depending on the version of macOS. Therefore, Go language side also needs to control which methods are available depending on the macOS version.

From now on, those available in Big Sur (11.0.0) will be developed on the [v1](https://github.com/Code-Hex/vz/tree/v1) branch and released as `v1.x.x`.

You can install by `go get github.com/Code-Hex/vz`

## IMPORTANT

Expand Down
10 changes: 10 additions & 0 deletions configuration.go
Original file line number Diff line number Diff line change
Expand Up @@ -135,3 +135,13 @@ func (v *VirtualMachineConfiguration) SetStorageDevicesVirtualMachineConfigurati
array := convertToNSMutableArray(ptrs)
C.setStorageDevicesVZVirtualMachineConfiguration(v.Ptr(), array.Ptr())
}

// SetDirectorySharingDevicesVirtualMachineConfiguration sets list of directory sharing devices. Empty by default.
func (v *VirtualMachineConfiguration) SetDirectorySharingDevicesVirtualMachineConfiguration(cs []DirectorySharingDeviceConfiguration) {
ptrs := make([]NSObject, len(cs))
for i, val := range cs {
ptrs[i] = val
}
array := convertToNSMutableArray(ptrs)
C.setDirectorySharingDevicesVZVirtualMachineConfiguration(v.Ptr(), array.Ptr())
}
7 changes: 3 additions & 4 deletions example/go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,10 @@ module github.com/Code-Hex/vz/example

go 1.16

replace github.com/Code-Hex/vz => ../
replace github.com/Code-Hex/vz/v2 => ../

require (
github.com/Code-Hex/vz v0.0.3
github.com/Code-Hex/vz/v2 v2.0.0-00010101000000-000000000000
github.com/pkg/term v1.1.0
github.com/rs/xid v1.3.0 // indirect
golang.org/x/sys v0.0.0-20211210111614-af8b64212486
golang.org/x/sys v0.0.0-20220808155132-1c4a2a72c664
)
9 changes: 4 additions & 5 deletions example/go.sum
Original file line number Diff line number Diff line change
@@ -1,8 +1,7 @@
github.com/pkg/term v1.1.0 h1:xIAAdCMh3QIAy+5FrE8Ad8XoDhEU4ufwbaSozViP9kk=
github.com/pkg/term v1.1.0/go.mod h1:E25nymQcrSllhX42Ok8MRm1+hyBdHY0dCeiKZ9jpNGw=
github.com/rs/xid v1.2.1/go.mod h1:+uKXf+4Djp6Md1KODXJxgGQPKngRmWyn10oCKFzNHOQ=
github.com/rs/xid v1.3.0 h1:6NjYksEUlhurdVehpc7S7dk6DAmcKv8V9gG0FsVN2U4=
github.com/rs/xid v1.3.0/go.mod h1:trrq9SKmegXys3aeAKXMUTdJsYXVwGY3RLcfgqegfbg=
github.com/rs/xid v1.4.0 h1:qd7wPTDkN6KQx2VmMBLrpHkiyQwgFXRnkOLacUiaSNY=
github.com/rs/xid v1.4.0/go.mod h1:trrq9SKmegXys3aeAKXMUTdJsYXVwGY3RLcfgqegfbg=
golang.org/x/sys v0.0.0-20200909081042-eff7692f9009/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20211210111614-af8b64212486 h1:5hpz5aRr+W1erYCL5JRhSUBJRph7l9XkNveoExlrKYk=
golang.org/x/sys v0.0.0-20211210111614-af8b64212486/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20220808155132-1c4a2a72c664 h1:v1W7bwXHsnLLloWYTVEdvGvA7BHMeBYsPcF0GLDxIRs=
golang.org/x/sys v0.0.0-20220808155132-1c4a2a72c664/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
2 changes: 1 addition & 1 deletion example/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ import (
"strings"
"syscall"

"github.com/Code-Hex/vz"
"github.com/Code-Hex/vz/v2"
"github.com/pkg/term/termios"
"golang.org/x/sys/unix"
)
Expand Down
8 changes: 4 additions & 4 deletions go.mod
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
module github.com/Code-Hex/vz
module github.com/Code-Hex/vz/v2

go 1.16
go 1.17

require (
github.com/rs/xid v1.2.1
golang.org/x/sys v0.0.0-20211210111614-af8b64212486
github.com/rs/xid v1.4.0
golang.org/x/sys v0.0.0-20220808155132-1c4a2a72c664
)
8 changes: 4 additions & 4 deletions go.sum
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
github.com/rs/xid v1.2.1 h1:mhH9Nq+C1fY2l1XIpgxIiUOfNpRBYH1kKcr+qfKgjRc=
github.com/rs/xid v1.2.1/go.mod h1:+uKXf+4Djp6Md1KODXJxgGQPKngRmWyn10oCKFzNHOQ=
golang.org/x/sys v0.0.0-20211210111614-af8b64212486 h1:5hpz5aRr+W1erYCL5JRhSUBJRph7l9XkNveoExlrKYk=
golang.org/x/sys v0.0.0-20211210111614-af8b64212486/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
github.com/rs/xid v1.4.0 h1:qd7wPTDkN6KQx2VmMBLrpHkiyQwgFXRnkOLacUiaSNY=
github.com/rs/xid v1.4.0/go.mod h1:trrq9SKmegXys3aeAKXMUTdJsYXVwGY3RLcfgqegfbg=
golang.org/x/sys v0.0.0-20220808155132-1c4a2a72c664 h1:v1W7bwXHsnLLloWYTVEdvGvA7BHMeBYsPcF0GLDxIRs=
golang.org/x/sys v0.0.0-20220808155132-1c4a2a72c664/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
27 changes: 27 additions & 0 deletions objcutil.go
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,19 @@ 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)
{
@autoreleasepool {
NSString *nskey = [NSString stringWithUTF8String: key];
[(NSMutableDictionary *)dict setValue:(NSObject *)val forKey:nskey];
}
}

void *newNSError()
{
NSError *err = nil;
Expand Down Expand Up @@ -245,3 +258,17 @@ func convertToNSMutableArray(s []NSObject) *pointer {
})
return p
}

func convertToNSMutableDictionary(d map[string]NSObject) *pointer {
dict := C.makeNSMutableDictionary()
for key, value := range d {
cs := charWithGoString(key)
C.insertNSMutableDictionary(dict, cs.CString(), value.Ptr())
cs.Free()
}
p := &pointer{ptr: dict}
runtime.SetFinalizer(p, func(self *pointer) {
self.Release()
})
return p
}
131 changes: 131 additions & 0 deletions shared_folder.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,131 @@
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"

// DirectorySharingDeviceConfiguration for a directory sharing device configuration.
type DirectorySharingDeviceConfiguration interface {
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.
func NewVirtioFileSystemDeviceConfiguration(tag string) *VirtioFileSystemDeviceConfiguration {
tagChar := charWithGoString(tag)
defer tagChar.Free()
fsdConfig := &VirtioFileSystemDeviceConfiguration{
pointer: pointer{
ptr: C.newVZVirtioFileSystemDeviceConfiguration(tagChar.CString()),
},
}
runtime.SetFinalizer(fsdConfig, func(self *VirtioFileSystemDeviceConfiguration) {
self.Release()
})
return fsdConfig
}

// SetDirectoryShare sets the directory share associated with this configuration.
func (c *VirtioFileSystemDeviceConfiguration) SetDirectoryShare(share DirectoryShare) {
C.setVZVirtioFileSystemDeviceConfigurationShare(c.Ptr(), share.Ptr())
}

// SharedDirectory is a shared directory.
type SharedDirectory struct {
pointer
}

// NewSharedDirectory creates a new shared directory.
func NewSharedDirectory(dirPath string, readOnly bool) *SharedDirectory {
dirPathChar := charWithGoString(dirPath)
defer dirPathChar.Free()
sd := &SharedDirectory{
pointer: pointer{
ptr: C.newVZSharedDirectory(dirPathChar.CString(), C.bool(readOnly)),
},
}
runtime.SetFinalizer(sd, func(self *SharedDirectory) {
self.Release()
})
return sd
}

// DirectoryShare is the base interface for a directory share.
type DirectoryShare interface {
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.
func NewSingleDirectoryShare(share *SharedDirectory) *SingleDirectoryShare {
config := &SingleDirectoryShare{
pointer: pointer{
ptr: C.newVZSingleDirectoryShare(share.Ptr()),
},
}
runtime.SetFinalizer(config, func(self *SingleDirectoryShare) {
self.Release()
})
return config
}

// MultipleDirectoryShare defines the directory share for multiple directories.
type MultipleDirectoryShare struct {
pointer

*baseDirectoryShare
}

// NewMultipleDirectoryShare creates a new multiple directories share.
func NewMultipleDirectoryShare(shares map[string]*SharedDirectory) *MultipleDirectoryShare {
directories := make(map[string]NSObject, len(shares))
for k, v := range shares {
directories[k] = v
}

dict := convertToNSMutableDictionary(directories)

config := &MultipleDirectoryShare{
pointer: pointer{
ptr: C.newVZMultipleDirectoryShare(dict.Ptr()),
},
}
runtime.SetFinalizer(config, func(self *SingleDirectoryShare) {
self.Release()
})
return config
}
4 changes: 4 additions & 0 deletions socket.go
Original file line number Diff line number Diff line change
Expand Up @@ -210,6 +210,10 @@ var _ net.Conn = (*VirtioSocketConnection)(nil)
func newVirtioSocketConnection(ptr unsafe.Pointer) *VirtioSocketConnection {
id := xid.New().String()
vzVirtioSocketConnection := C.convertVZVirtioSocketConnection2Flat(ptr)
err := unix.SetNonblock(int(vzVirtioSocketConnection.fileDescriptor), true)
if err != nil {
fmt.Printf("set nonblock: %s\n", err.Error())
}
conn := &VirtioSocketConnection{
id: id,
sourcePort: (uint32)(vzVirtioSocketConnection.sourcePort),
Expand Down
14 changes: 10 additions & 4 deletions virtualization.h
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,6 @@ bool shouldAcceptNewConnectionHandler(void *listener, void *connection, void *so
- (BOOL)listener:(VZVirtioSocketListener *)listener shouldAcceptNewConnection:(VZVirtioSocketConnection *)connection fromSocketDevice:(VZVirtioSocketDevice *)socketDevice;
@end


/* BootLoader */
void *newVZLinuxBootLoader(const char *kernelPath);
void setCommandLineVZLinuxBootLoader(void *bootLoaderPtr, const char *commandLine);
Expand All @@ -35,8 +34,8 @@ void setInitialRamdiskURLVZLinuxBootLoader(void *bootLoaderPtr, const char *ramd
/* VirtualMachineConfiguration */
bool validateVZVirtualMachineConfiguration(void *config, void **error);
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 setMemoryBalloonDevicesVZVirtualMachineConfiguration(void *config,
Expand All @@ -49,6 +48,7 @@ void setSocketDevicesVZVirtualMachineConfiguration(void *config,
void *socketDevices);
void setStorageDevicesVZVirtualMachineConfiguration(void *config,
void *storageDevices);
void setDirectorySharingDevicesVZVirtualMachineConfiguration(void *config, void *directorySharingDevices);

/* Configurations */
void *newVZFileHandleSerialPortAttachment(int readFileDescriptor, int writeFileDescriptor);
Expand All @@ -68,6 +68,11 @@ void *newVZMACAddress(const char *macAddress);
void *newRandomLocallyAdministeredVZMACAddress();
const char *getVZMACAddressString(void *macAddress);
void *newVZVirtioSocketListener();
void *newVZSharedDirectory(const char *dirPath, bool readOnly);
void *newVZSingleDirectoryShare(void *sharedDirectory);
void *newVZMultipleDirectoryShare(void *sharedDirectories);
void *newVZVirtioFileSystemDeviceConfiguration(const char *tag);
void setVZVirtioFileSystemDeviceConfigurationShare(void *config, void *share);
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);
Expand All @@ -87,7 +92,8 @@ bool vmCanRequestStop(void *machine, void *queue);
void *makeDispatchQueue(const char *label);

/* VZVirtioSocketConnection */
typedef struct VZVirtioSocketConnectionFlat {
typedef struct VZVirtioSocketConnectionFlat
{
uint32_t destinationPort;
uint32_t sourcePort;
int fileDescriptor;
Expand Down
Loading