vagrant_utm 0.1.2.beta → 0.1.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 4afb59e8282747e3cca61c9ed2b297b7084606c268cc4e6231856f12fb2510b0
4
- data.tar.gz: 1a4ba9a73219106a661fdddad221d14128d203fc8c273dc22fa3018d72b25e0b
3
+ metadata.gz: bc0499e6b39496b2bd9590d3683631bcc213f7b0f4f1a5fc259b9373e160da33
4
+ data.tar.gz: 36b2a3029c3d8ddb9d4e84865f657a989732495f59adf90e4f2eb19731780ae0
5
5
  SHA512:
6
- metadata.gz: 01e79bc38a232a68a08eb43e7cddfcc2ed0866acd54a559b797e8c26f84fce16c5d8ec171492758fc514080c8b98be32dd2505554f9e04a8c2897a1d05fb3d2a
7
- data.tar.gz: '07951106f1403e2bb7811f699ed914c12eb701e15cb4142f6f2318a2ffc4fd9065e49bfdc098b544d547f3129005b4cf8370bad9d513a356d0b9c9b77b8b2719'
6
+ metadata.gz: adf69f5cc2fbb3d73e5453b761d374dfd29aded42d1581927a1bbfea2405a93817c11e4a79de57d1c144b6acd120e4d21dceb9140c38083436605f2f2f4a2889
7
+ data.tar.gz: c305e4949e66c6643646025c649dba12093e228dbbe298b0aada54be0974fa526bfdded85afbcf2b0c062d1982100f601bb77d290784b9d4b57e8fc4173644cf
data/CHANGELOG.md CHANGED
@@ -1,6 +1,20 @@
1
1
  ## [Unreleased]
2
2
 
3
3
 
4
+ ## [0.1.3] - 2025-04-20
5
+
6
+ ### Added
7
+
8
+ - Implements VirtFS synced folder in UTM using qemu additional args and vm registry (for permission)
9
+
10
+ ### Changed
11
+
12
+ - Config: Makes `virtFS` as default directory_share_mode in UTM
13
+
14
+ ### Removed
15
+
16
+ - Driver: Removed support for UTM versions < 4.6.5
17
+
4
18
  ## [0.1.2.beta] - 2024-12-05
5
19
 
6
20
  WARNING: This version of the plugin adds initial synced folder support. By default, Vagrant will pick the directory share method which it supports and prefers. e.g., SMB. However, SMB is not fully tested, so you need to force the plugin to pick the one that is simple and tested `rsync`
data/README.md CHANGED
@@ -15,7 +15,7 @@ vagrant plugin install vagrant_utm
15
15
 
16
16
  ```ruby
17
17
  Vagrant.configure("2") do |config|
18
- config.vm.box = "utm/debian11"
18
+ config.vm.box = "utm/bookworm"
19
19
  end
20
20
  ```
21
21
 
data/docs/Gemfile.lock CHANGED
@@ -261,8 +261,8 @@ GEM
261
261
  tzinfo (2.0.6)
262
262
  concurrent-ruby (~> 1.0)
263
263
  unicode-display_width (1.8.0)
264
- uri (0.13.0)
265
- webrick (1.8.1)
264
+ uri (0.13.2)
265
+ webrick (1.8.2)
266
266
 
267
267
  PLATFORMS
268
268
  arm64-darwin
data/docs/_config.yml CHANGED
@@ -28,8 +28,8 @@ nav_external_links:
28
28
  url: https://mac.getutm.app
29
29
  - title: Packer plugin for UTM
30
30
  url: https://github.com/naveenrajm7/packer-plugin-utm
31
- # - title: GitHub
32
- # url: https://github.com/naveenrajm7/vagrant_utm
31
+ - title: UTM Gallery
32
+ url: https://naveenrajm7.github.io/utm-gallery/
33
33
 
34
34
 
35
35
  # Aux links for the upper right navigation
@@ -60,17 +60,18 @@ Check the [UTM Guide on Guest Support](https://docs.getutm.app/guest-support/gue
60
60
 
61
61
  By satisfying the [general guidance on creating vagrant boxes](https://developer.hashicorp.com/vagrant/docs/boxes/base) and the above [Virtual Machine](#virtual-machine) requirements you can use your VM with Vagrant UTM plugin.
62
62
 
63
- Apart from manually building the boxes, you can also use the semi-automated way of building these boxes using [packer plugin for UTM](https://github.com/naveenrajm7/packer-plugin-utm).
63
+ Apart from manually building the boxes, you can also use the automated (almost) way of building these boxes using [packer plugin for UTM](https://github.com/naveenrajm7/packer-plugin-utm).
64
64
  The packer plugin has the following components:
65
65
  1. Builder
66
- 1. UTM - Use existing utm file
67
- 2. ISO - Start from scratch using ISO files
66
+ 1. UTM - Use existing utm file
67
+ 2. ISO - Start from scratch using ISO files
68
+ 3. CLOUD - Use existing qcow2 cloud images
68
69
  2. Post-processor
69
- 1. ZIP - Package UTM VM into zip file
70
- 2. Vagrant - Package UTM VM into vagrant box.
70
+ 1. ZIP - Package UTM VM into zip file
71
+ 2. Vagrant - Package UTM VM into vagrant box.
71
72
 
72
73
 
73
- Checkout [UTM Box Guide](https://github.com/naveenrajm7/utm-box/blob/main/HowToBuild/DebianUTM.md) to know how to build Box using packer.
74
+ Checkout [UTM Box Packer recipe](https://github.com/naveenrajm7/utm-box?tab=readme-ov-file#building-boxes) to know how to build Box using packer.
74
75
 
75
76
  ## Using your own UTM VMs
76
77
 
@@ -10,22 +10,27 @@ nav_order: 1
10
10
  To work with Vagrant, a base VM (box) must have
11
11
  [certain features](https://developer.hashicorp.com/vagrant/docs/boxes/base), like an ssh user for vagrant to connect.
12
12
 
13
- To help you get started with Vagrant UTM provider, a couple of pre-built VMs that work with Vagrant and are published in [HCP Vagrant registry](https://portal.cloud.hashicorp.com/vagrant/discover/utm).
13
+ To help you get started with Vagrant UTM provider, some pre-built VMs that work with Vagrant are published in [HCP Vagrant registry](https://portal.cloud.hashicorp.com/vagrant/discover/utm).
14
14
 
15
15
  {: .important}
16
- All the VMs provided are built from [UTM Gallery VMs](https://mac.getutm.app/gallery/) or ISO in an (semi) automated way using [packer plugin for UTM][packer plugin for UTM]. Please see the [UTM Box Guide][UTM Box Guide] on how these UTM Vagrant boxes were built using packer.
16
+ All the VMs provided are built from Cloud Images or ISO files in an (semi) automated way using [packer plugin for UTM][packer plugin for UTM]. Please see the [UTM Box Guide][UTM Box Guide] on how these UTM Vagrant boxes were built using packer.
17
17
 
18
- * Debian 11 (Xfce):
18
+ * Debian 12 - Built from cloud image:
19
+ ```ruby
20
+ config.vm.box = "utm/bookworm"
21
+ ```
22
+
23
+ * Debian 11 (Xfce) - Built from UTM file of UTM gallery:
19
24
  ```ruby
20
25
  config.vm.box = "utm/debian11"
21
26
  ```
22
27
 
23
- * Ubuntu 24.04 :
28
+ * Ubuntu 24.04 - Built from ISO:
24
29
  ```ruby
25
30
  config.vm.box = "utm/ubuntu-24.04"
26
31
  ```
27
32
 
28
- * Help build more boxes using [packer plugin for UTM][packer plugin for UTM]
33
+ * Build your own boxes using [packer plugin for UTM][packer plugin for UTM]
29
34
  <!-- * ArchLinux ARM -->
30
35
 
31
36
 
@@ -7,22 +7,22 @@ nav_order: 1
7
7
 
8
8
  # Synced Folders
9
9
 
10
- UTM Vagrant plugin currently gives rudimentary support for syncing folders between host and guest machine.
11
- The plugin provides option to configure the Qemu directory share mode.
12
- After which the the host directory can be selected from UTM UI, and the guest directory can be mounted in guest OS. Both of these steps are now manual until UTM exposes API to configure Host/Guest directory.
10
+ UTM Vagrant plugin has support for syncing multiple folders between host and guest machine.
11
+ The plugin implements [UTM QEMU VirtFS](https://docs.getutm.app/guest-support/linux/#virtfs) as the default synced folder implementation for UTM provider.
13
12
 
14
13
  ```ruby
15
14
  Vagrant.configure("2") do |config|
16
- config.vm.box = "utm/debian11"
17
- config.vm.provider :utm do |u|
18
- # QEMU Directoy Share mode for the VM.
19
- # Takes none, webDAV or virtFS
20
- u.directory_share_mode = "webDAV"
21
- end
15
+ config.vm.box = "utm/bookworm"
16
+ config.vm.synced_folder "../test", "/vagrant-test"
22
17
  end
23
18
  ```
24
19
 
25
- ## Other Vagrant options
20
+ Vagrant by default syncs the current folder where that Vagrantfile is, and you can access them at `/vagrant` in the guest.
26
21
 
27
22
  {: .important}
28
- Apart from the provider specific Sync options, Vagrant has components to provide sync folders feature using NFS and RSync. These features are not yet supported in UTM plugin.
23
+
24
+
25
+ ## Other Vagrant options
26
+
27
+ Apart from the provider specific Sync options, Vagrant has components to provide sync folders feature using NFS and RSync. These features are also supported in UTM plugin.
28
+ Check all Vagrant provided sync options at [Vagrant synced folders](https://developer.hashicorp.com/vagrant/docs/synced-folders).
data/docs/index.md CHANGED
@@ -19,8 +19,8 @@ allowing Vagrant to control and provision machines via UTM's API.
19
19
  ---
20
20
 
21
21
  {: .new}
22
- > UTM Vagrant plugin now supports [Vagrant boxes](https://developer.hashicorp.com/vagrant/docs/boxes)!
23
- > Find UTM boxes at [HCP Vagrant registry](https://portal.cloud.hashicorp.com/vagrant/discover/utm).
22
+ > Plugin now supports [Vagrant boxes](https://developer.hashicorp.com/vagrant/docs/boxes)!, find UTM boxes at [HCP Vagrant registry](https://portal.cloud.hashicorp.com/vagrant/discover/utm)
23
+ > Plugin now supports multiple synced folders, check out [Synced Folder](features/synced_folders.md)
24
24
 
25
25
  [UTM] is a free, full-featured system emulator and virtual machine host for iOS and macOS.
26
26
  The UTM provider currently supports UTM versions
@@ -59,14 +59,14 @@ vagrant plugin install vagrant_utm
59
59
  Option 1: Create a Vagrantfile and initiate the box (OR)
60
60
 
61
61
  ```
62
- vagrant init utm/debian11
62
+ vagrant init utm/bookworm
63
63
  ```
64
64
 
65
65
  Option 2: Open the Vagrantfile and replace the contents with the following
66
66
 
67
67
  ```ruby
68
68
  Vagrant.configure("2") do |config|
69
- config.vm.box = "utm/debian11"
69
+ config.vm.box = "utm/bookworm"
70
70
  end
71
71
  ```
72
72
 
@@ -81,9 +81,9 @@ Now start using your machine!
81
81
 
82
82
  `vagrant ssh` to log into machine or forward ports to check your website or share folders and start developing.
83
83
 
84
- Check [Commands](commands.md) for all supported Vagrant commands.
85
- Check [Configuration](configuration.md) for more UTM provider config options.
86
-
84
+ Check [Commands](commands.md) for all supported Vagrant commands.
85
+ Check [Configuration](configuration.md) for more UTM provider config options.
86
+ Discover UTM Vagrant boxes at [HCP Vagrant UTM Registry](https://portal.cloud.hashicorp.com/vagrant/discover/utm), which as boxes of popular OS including OpenBSD!
87
87
 
88
88
  ## About the project
89
89
 
@@ -17,4 +17,5 @@ The Table below maps the vagrant commands to the corresponding UTM commands that
17
17
  | `vagrant destroy` | `utmctl delete` |
18
18
  | `vagrant status` | `utmctl status` |
19
19
  | `vagrant disposable` | `utmctl start --disposable` |
20
- | `vagrant snapshot` | `qemu-img snapshot` |
20
+ | `vagrant snapshot` | `qemu-img snapshot` |
21
+ | `vagrant ip-address` | `utmctl ip-address` |
data/docs/known_issues.md CHANGED
@@ -5,7 +5,7 @@ nav_order: 7
5
5
 
6
6
  # Known Issues
7
7
 
8
- This plugin was built built around the existing UTM API.
8
+ This plugin is built around the existing UTM API.
9
9
  Hence there are things which are not ideal.
10
10
 
11
11
  1. ~~vagrant up : Loads new VM by downloading zip file every time, and manually asks the user to confirm the download completion.~~
@@ -21,4 +21,4 @@ Draw back - UTM does not expose export API. (UTM already has 'Share')~~
21
21
 
22
22
  5. vagrant snapshot: Even though UTM does not have snapshot feature, this plugin has a experimental support for offline VM snapshots using qemu-img.
23
23
  The VM must be stopped, for any snapshot commands to work.
24
- The snapshot only works for **single** qcow2 based VM images
24
+ The snapshot only works for **single** qcow2 based VM images
@@ -0,0 +1,55 @@
1
+ # frozen_string_literal: true
2
+
3
+ # Copyright (c) HashiCorp, Inc.
4
+ # SPDX-License-Identifier: BUSL-1.1
5
+
6
+ require_relative "../util/unix_mount_helpers"
7
+
8
+ module VagrantPlugins
9
+ module Utm
10
+ module Cap
11
+ # Capability for mount options
12
+ module MountOptions
13
+ extend VagrantPlugins::SyncedFolder::UnixMountHelpers
14
+
15
+ # Mount type for VirtFS
16
+ UTM_MOUNT_TYPE = "9p"
17
+
18
+ # Returns mount options for a utm synced folder
19
+ #
20
+ # @param [Machine] machine
21
+ # @param [String] name of mount
22
+ # @param [String] path of mount on guest
23
+ # @param [Hash] hash of mount options
24
+ def self.mount_options(machine, _name, guest_path, options)
25
+ mount_options = options.fetch(:mount_options, [])
26
+ detected_ids = detect_owner_group_ids(machine, guest_path, mount_options, options)
27
+ mount_uid = detected_ids[:uid]
28
+ mount_gid = detected_ids[:gid]
29
+
30
+ # VirtFS mount options
31
+ mount_options << "trans=virtio"
32
+ mount_options << "version=9p2000.L"
33
+ mount_options << if mount_options.include?("ro")
34
+ "ro"
35
+ else
36
+ "rw"
37
+ end
38
+ mount_options << "_netdev"
39
+ mount_options << "nofail"
40
+
41
+ mount_options = mount_options.join(",")
42
+ [mount_options, mount_uid, mount_gid]
43
+ end
44
+
45
+ def self.mount_type(_machine)
46
+ UTM_MOUNT_TYPE
47
+ end
48
+
49
+ def self.mount_name(_machine, name, _data)
50
+ name.gsub(%r{[\s/\\]}, "_").sub(/^_/, "")
51
+ end
52
+ end
53
+ end
54
+ end
55
+ end
@@ -7,11 +7,6 @@ module VagrantPlugins
7
7
  module Utm
8
8
  # This is the configuration class for the UTM provider.
9
9
  class Config < Vagrant.plugin("2", :config)
10
- # This should be set to the name of the machine in the UTM GUI.
11
- #
12
- # @return [String]
13
- attr_accessor :name
14
-
15
10
  # If true, will check if guest additions are installed and up to
16
11
  # date. By default, this is true.
17
12
  #
@@ -23,6 +18,19 @@ module VagrantPlugins
23
18
  # @return [Array]
24
19
  attr_reader :customizations
25
20
 
21
+ # Whether or not this VM has a functional VirtFS 9P filesystem module
22
+ # for VirtFS directory sharing to work.
23
+ # This defaults to true. If you set this to false, then the "utm"
24
+ # synced folder type won't be valid.
25
+ #
26
+ # @return [Boolean]
27
+ attr_accessor :functional_9pfs
28
+
29
+ # This should be set to the name of the machine in the UTM GUI.
30
+ #
31
+ # @return [String]
32
+ attr_accessor :name
33
+
26
34
  # The time to wait for the VM to be 'running' after 'started'.
27
35
  #
28
36
  # @return [Integer]
@@ -33,6 +41,7 @@ module VagrantPlugins
33
41
  super
34
42
  @check_guest_additions = UNSET_VALUE
35
43
  @customizations = []
44
+ @functional_9pfs = UNSET_VALUE
36
45
  @name = UNSET_VALUE
37
46
  @wait_time = UNSET_VALUE
38
47
  end
@@ -76,6 +85,8 @@ module VagrantPlugins
76
85
  customize("pre-boot", ["customize_vm.applescript", :id, "--notes", notes])
77
86
  end
78
87
 
88
+ # TODO: All warning if user sets directory_share_mode,
89
+ # because default implementation is 'virtFS'
79
90
  # Shortcut for setting the directory share mode of the virtual machine.
80
91
  # Calls #customize internally.
81
92
  #
@@ -101,8 +112,13 @@ module VagrantPlugins
101
112
  # This is the hook that is called to finalize the object before it
102
113
  # is put into use.
103
114
  def finalize!
115
+ # By default, we check for guest additions (qemu-ga)
104
116
  @check_guest_additions = true if @check_guest_additions == UNSET_VALUE
105
-
117
+ # Always set the directory share mode to 'virtFS'
118
+ # default share folder implementation in utm plugin
119
+ self.directory_share_mode = "virtFS"
120
+ # By default, we assume the VM supports virtio 9p filesystems
121
+ @functional_9pfs = true if @functional_9pfs == UNSET_VALUE
106
122
  # The default name is just nothing, and we default it
107
123
  @name = nil if @name == UNSET_VALUE
108
124
 
@@ -127,6 +143,10 @@ module VagrantPlugins
127
143
 
128
144
  { "UTM Provider" => errors }
129
145
  end
146
+
147
+ def to_s
148
+ "UTM"
149
+ end
130
150
  end
131
151
  end
132
152
  end
@@ -58,9 +58,14 @@ module VagrantPlugins
58
58
  "4.6" => Version_4_6
59
59
  }
60
60
 
61
- # UTM 4.6.0 doesn't have import support to work with Vagrant box,
62
- # so show error
63
- raise Errors::UtmInvalidVersion if @version.start_with?("4.6.0")
61
+ # UTM version < 4.6.5 doesn't have
62
+ # import support to work with Vagrant box (< 4.6.1)
63
+ # registry support to work with synced folders (< 4.6.5)
64
+ # Restrict to UTM versions >= 4.6.5
65
+ unless Gem::Version.new(@version) >= Gem::Version.new("4.6.5")
66
+ raise Errors::UtmInvalidVersion,
67
+ supported_versions: "4.6.5 or earlier"
68
+ end
64
69
 
65
70
  driver_klass = nil
66
71
  driver_map.each do |key, klass|
@@ -88,6 +93,7 @@ module VagrantPlugins
88
93
  def_delegators :@driver,
89
94
  :check_qemu_guest_agent,
90
95
  :clear_forwarded_ports,
96
+ :clear_shared_folders,
91
97
  :create_snapshot,
92
98
  :delete,
93
99
  :delete_snapshot,
@@ -108,6 +114,7 @@ module VagrantPlugins
108
114
  :restore_snapshot,
109
115
  :set_mac_address,
110
116
  :set_name,
117
+ :share_folders,
111
118
  :ssh_port,
112
119
  :start,
113
120
  :start_disposable,
@@ -13,6 +13,25 @@ module VagrantPlugins
13
13
  @logger = Log4r::Logger.new("vagrant::provider::utm::version_4_6")
14
14
  end
15
15
 
16
+ # Implement clear_shared_folders
17
+ def clear_shared_folders
18
+ # Get the list of shared folders
19
+ shared_folders = read_shared_folders
20
+ # Get the args to remove the shared folders
21
+ script_path = @script_path.join("read_shared_folders_args.js")
22
+ cmd = ["osascript", script_path.to_s, @uuid, "--ids", shared_folders.join(",")]
23
+ output = execute_shell(*cmd)
24
+ result = JSON.parse(output)
25
+ return unless result["status"]
26
+
27
+ # Flatten the list of args and build the command
28
+ sf_args = result["result"].flatten
29
+ return unless sf_args.any?
30
+
31
+ command = ["remove_qemu_additional_args.applescript", @uuid, "--args", *sf_args]
32
+ execute_osa_script(command)
33
+ end
34
+
16
35
  def import(utm)
17
36
  utm = Vagrant::Util::Platform.windows_path(utm)
18
37
 
@@ -36,6 +55,54 @@ module VagrantPlugins
36
55
  command = ["export_vm.applescript", @uuid, path]
37
56
  execute_osa_script(command)
38
57
  end
58
+
59
+ def read_shared_folders
60
+ @logger.debug("Reading shared folders")
61
+ script_path = @script_path.join("read_shared_folders.js")
62
+ cmd = ["osascript", script_path.to_s, @uuid]
63
+ output = execute_shell(*cmd)
64
+ result = JSON.parse(output)
65
+ return unless result["status"]
66
+
67
+ # Return the list of shared folders names(id)
68
+ result["result"]
69
+ end
70
+
71
+ def share_folders(folders)
72
+ # sync folder cleanup will call clear_shared_folders
73
+ # This is just a precaution, to make sure we don't
74
+ # have duplicate shared folders
75
+ shared_folders = read_shared_folders
76
+ @logger.debug("Shared folders: #{shared_folders}")
77
+ @logger.debug("Sharing folders: #{folders}")
78
+
79
+ folders.each do |folder|
80
+ # Skip if the folder is already shared
81
+ next if shared_folders.include?(folder[:name])
82
+
83
+ args = ["--id", folder[:name],
84
+ "--dir", folder[:hostpath]]
85
+ command = ["add_folder_share.applescript", @uuid, *args]
86
+ execute_osa_script(command)
87
+ end
88
+ end
89
+
90
+ def unshare_folders(folders)
91
+ @logger.debug("Unsharing folder: #{folder[:name]}")
92
+ # Get the args to remove the shared folders
93
+ script_path = @script_path.join("read_shared_folders_args.js")
94
+ cmd = ["osascript", script_path.to_s, @uuid, "--ids", folders.join(",")]
95
+ output = execute_shell(*cmd)
96
+ result = JSON.parse(output)
97
+ return unless result["status"]
98
+
99
+ # Flatten the list of args and build the command
100
+ sf_args = result["result"].flatten
101
+ return unless sf_args.any?
102
+
103
+ command = ["remove_qemu_additional_args.applescript", @uuid, "--args", *sf_args]
104
+ execute_osa_script(command)
105
+ end
39
106
  end
40
107
  end
41
108
  end
@@ -33,6 +33,12 @@ module VagrantPlugins
33
33
  Config
34
34
  end
35
35
 
36
+ # Register the synced folder implementation
37
+ synced_folder(:utm) do
38
+ require_relative "synced_folder"
39
+ SyncedFolder
40
+ end
41
+
36
42
  # Register capabilities
37
43
  provider_capability(:utm, :forwarded_ports) do
38
44
  require_relative "cap"
@@ -44,6 +50,21 @@ module VagrantPlugins
44
50
  Cap
45
51
  end
46
52
 
53
+ synced_folder_capability(:utm, "mount_options") do
54
+ require_relative "cap/mount_options"
55
+ Cap::MountOptions
56
+ end
57
+
58
+ synced_folder_capability(:utm, "mount_type") do
59
+ require_relative "cap/mount_options"
60
+ Cap::MountOptions
61
+ end
62
+
63
+ synced_folder_capability(:utm, "mount_name") do
64
+ require_relative "cap/mount_options"
65
+ Cap::MountOptions
66
+ end
67
+
47
68
  # Register the command
48
69
  ## Start machine as a snapshot and do not save changes to disk
49
70
  command "disposable" do
@@ -0,0 +1,96 @@
1
+ ---
2
+ -- add_directory_share.applescript
3
+ -- This script adds QEMU arguments for directory sharing in UTM (QEMU) for given id and directory pairs.
4
+ -- Usage: osascript add_directory_share.applescript UUID --id <ID1> --dir <DIR1> --id <ID2> --dir <DIR2> ...
5
+ -- Example: osascript add_directory_share.applescript UUID --id no1 --dir "/path/to/dir1" --id no2 --dir "/path/to/dir2"
6
+
7
+ -- Function to create QEMU arguments for directory sharing
8
+ on createQemuArgsForDir(dirId, dirPath)
9
+
10
+ -- Prepare the QEMU argument strings
11
+ set fsdevArgStr to "-fsdev local,id=" & dirId & ",path=" & dirPath & ",security_model=mapped-xattr"
12
+ set deviceArgStr to "-device virtio-9p-pci,fsdev=" & dirId & ",mount_tag=" & dirId
13
+
14
+ return {fsdevArgStr, deviceArgStr}
15
+ end createQemuArgsForDir
16
+
17
+ -- Main script
18
+ on run argv
19
+ -- VM id is assumed to be the first argument
20
+ set vmId to item 1 of argv
21
+
22
+ -- Initialize variables
23
+ set idList to {} --
24
+ set dirList to {}
25
+ set idFlag to false
26
+ set dirFlag to false
27
+
28
+ -- Parse arguments
29
+ repeat with i from 2 to (count of argv)
30
+ set currentArg to item i of argv
31
+ if currentArg is "--id" then
32
+ set idFlag to true
33
+ set dirFlag to false
34
+ else if currentArg is "--dir" then
35
+ set dirFlag to true
36
+ set idFlag to false
37
+ else if idFlag then
38
+ set end of idList to currentArg
39
+ set idFlag to false
40
+ else if dirFlag then
41
+ set end of dirList to currentArg
42
+ set dirFlag to false
43
+ end if
44
+ end repeat
45
+
46
+ -- Ensure the lists are of the same length
47
+ if (count of idList) is not (count of dirList) then
48
+ error "The number of IDs and directories must be the same."
49
+ end if
50
+
51
+ -- Initialize the list of QEMU arguments
52
+ set qemuNewArgs to {}
53
+
54
+ -- Initialize the directory list
55
+ set directoryList to {}
56
+
57
+ -- Create QEMU arguments for each directory
58
+ repeat with i from 1 to (count of dirList)
59
+ set dirPath to item i of dirList
60
+ set dirId to item i of idList
61
+ set dirURL to POSIX file dirPath
62
+ set {fsdevArgStr, deviceArgStr} to createQemuArgsForDir(dirId, dirPath)
63
+
64
+ -- add the directory file obj to the list
65
+ set end of directoryList to dirURL
66
+ -- append the arguments to the list
67
+ set end of qemuNewArgs to {fsdevArg:fsdevArgStr, deviceArg:deviceArgStr, dirURL:dirURL}
68
+ end repeat
69
+
70
+ -- Example usage in UTM
71
+ tell application "UTM"
72
+ set vm to virtual machine id vmId
73
+ set config to configuration of vm
74
+
75
+ -- Get the current QEMU additional arguments
76
+ set qemuAddArgs to qemu additional arguments of config
77
+
78
+ -- Add the new arguments to the existing ones
79
+ repeat with arg in qemuNewArgs
80
+ -- SKIP: adding file urls to qemu args file urls , since it is not necessary. UTM#6977
81
+ set end of qemuAddArgs to {argument string:fsdevArg of arg}
82
+ set end of qemuAddArgs to {argument string:deviceArg of arg}
83
+ end repeat
84
+
85
+ -- Update the configuration with the new arguments list
86
+ set qemu additional arguments of config to qemuAddArgs
87
+ update configuration of vm with config
88
+
89
+ -- Get the current directory shares in registry
90
+ set reg to registry of vm
91
+ -- Add new directory shares to the registry
92
+ set reg to reg & directoryList
93
+ -- Update registry of vm with new directory shares
94
+ update registry of vm with reg
95
+ end tell
96
+ end run
@@ -0,0 +1,43 @@
1
+ ---
2
+ -- add_qemu_additional_args.applescript
3
+ -- This script adds qemu arguments to a specified UTM virtual machine.
4
+ -- Usage: osascript add_qemu_additional_args.applescript <VM_UUID> --args <arg1> <arg2> ...
5
+ -- Example: osascript add_qemu_additional_args.applescript A123 --args "-vnc 127.0.0.1:13" "-vnc..."
6
+
7
+ on run argv
8
+ set vmId to item 1 of argv # UUID of the VM
9
+
10
+ -- Initialize variables
11
+ set argsList to {}
12
+ set argsFlag to false
13
+
14
+ -- Parse the --args arguments
15
+ repeat with i from 2 to (count of argv)
16
+ set currentArg to item i of argv
17
+ if currentArg is "--args" then
18
+ set argsFlag to true
19
+ else if argsFlag then
20
+ set end of argsList to currentArg
21
+ end if
22
+ end repeat
23
+
24
+ tell application "UTM"
25
+ -- Get the VM and its configuration
26
+ set vm to virtual machine id vmId -- Id is assumed to be valid
27
+ set config to configuration of vm
28
+
29
+ -- Existing arguments
30
+ set qemuAddArgs to qemu additional arguments of config
31
+
32
+ -- Create new arguments from argsList and add them to the existing arguments
33
+ repeat with arg in argsList
34
+ set end of qemuAddArgs to {argument string:arg}
35
+ end repeat
36
+
37
+ --- set qemu args with new args list
38
+ set qemu additional arguments of config to qemuAddArgs
39
+
40
+ --- save the configuration (VM must be stopped)
41
+ update configuration of vm with config
42
+ end tell
43
+ end run
@@ -0,0 +1,47 @@
1
+ /**
2
+ * Reads the shared directory IDs from the QEMU additional arguments of a specified VM in UTM.
3
+ *
4
+ * This function uses the UTM application to read the QEMU additional arguments
5
+ * of a VM identified by the given VM ID and extracts the IDs of shared directories.
6
+ *
7
+ * @param {string} vmIdentifier - The ID of the VM.
8
+ * @returns {string} A JSON string containing the shared directory IDs or an error message.
9
+ */
10
+ function run(argv) {
11
+ // Check if a VM ID is provided
12
+ if (argv.length === 0) {
13
+ console.log("Usage: osascript -l JavaScript read_shared_directories.js <vm_id>");
14
+ return JSON.stringify({ status: false, result: "No VM ID provided." });
15
+ }
16
+
17
+ const vmIdentifier = argv[0];
18
+ const utm = Application('UTM');
19
+ utm.includeStandardAdditions = true;
20
+
21
+ try {
22
+ // Attempt to get the VM by ID
23
+ const vm = utm.virtualMachines.byId(vmIdentifier);
24
+ // Get the config of the VM
25
+ const config = vm.configuration();
26
+ // Get the QEMU additional arguments
27
+ const qemuArgs = config.qemuAdditionalArguments;
28
+
29
+ // Extract shared directory IDs
30
+ const sharedDirIds = [];
31
+ qemuArgs.forEach(arg => {
32
+ const argStr = arg.argumentString;
33
+ if (argStr.startsWith("-fsdev")) {
34
+ const match = argStr.match(/id=([^,]+)/);
35
+ if (match) {
36
+ sharedDirIds.push(match[1]);
37
+ }
38
+ }
39
+ });
40
+
41
+ // Return the shared directory IDs
42
+ return JSON.stringify({ status: true, result: sharedDirIds });
43
+ } catch (error) {
44
+ // Return an error message
45
+ return JSON.stringify({ status: false, result: error.message });
46
+ }
47
+ }
@@ -0,0 +1,53 @@
1
+ /**
2
+ * Reads the shared folder QEMU arguments for specified IDs from the QEMU additional arguments of a VM in UTM.
3
+ *
4
+ * This function uses the UTM application to read the QEMU additional arguments
5
+ * of a VM identified by the given VM ID and extracts the arguments for the specified IDs.
6
+ *
7
+ * @param {string} vmIdentifier - The ID of the VM.
8
+ * @param {string} ids - Comma-separated list of directory IDs.
9
+ * @returns {string} A JSON string containing the QEMU arguments for the specified IDs or an error message.
10
+ */
11
+ function run(argv) {
12
+ // Check if a VM ID and IDs are provided
13
+ if (argv.length < 2) {
14
+ console.log("Usage: osascript -l JavaScript read_shared_folders_args.js <vm_id> --ids <dirID>,<dirID>");
15
+ return JSON.stringify({ status: false, result: "No VM ID or IDs provided." });
16
+ }
17
+
18
+ const vmIdentifier = argv[0];
19
+ const idsArgIndex = argv.indexOf("--ids");
20
+ if (idsArgIndex === -1 || idsArgIndex + 1 >= argv.length) {
21
+ return JSON.stringify({ status: false, result: "No IDs provided." });
22
+ }
23
+ const ids = argv[idsArgIndex + 1].split(",");
24
+
25
+ const utm = Application('UTM');
26
+ utm.includeStandardAdditions = true;
27
+
28
+ try {
29
+ // Attempt to get the VM by ID
30
+ const vm = utm.virtualMachines.byId(vmIdentifier);
31
+ // Get the config of the VM
32
+ const config = vm.configuration();
33
+ // Get the QEMU additional arguments
34
+ const qemuArgs = config.qemuAdditionalArguments;
35
+
36
+ // Extract QEMU arguments for the specified IDs
37
+ const sharedDirArgs = [];
38
+ qemuArgs.forEach(arg => {
39
+ const argStr = arg.argumentString;
40
+ ids.forEach(id => {
41
+ if (argStr.includes(`id=${id}`) || argStr.includes(`fsdev=${id}`)) {
42
+ sharedDirArgs.push(argStr);
43
+ }
44
+ });
45
+ });
46
+
47
+ // Return the QEMU arguments for the specified IDs
48
+ return JSON.stringify({ status: true, result: sharedDirArgs });
49
+ } catch (error) {
50
+ // Return an error message
51
+ return JSON.stringify({ status: false, result: error.message });
52
+ }
53
+ }
@@ -0,0 +1,46 @@
1
+ ---
2
+ -- remove_qemu_additional_args.applescript
3
+ -- This script removes specified qemu arguments from a specified UTM virtual machine.
4
+ -- Usage: osascript remove_qemu_additional_args.applescript <VM_UUID> --args <arg1> <arg2> ...
5
+ -- Example: osascript remove_qemu_additional_args.applescript A123 --args "-vnc 127.0.0.1:13" "-vnc..."
6
+
7
+ on run argv
8
+ set vmId to item 1 of argv -- UUID of the VM
9
+
10
+ -- Initialize variables
11
+ set argsToRemove to {}
12
+ set argsFlag to false
13
+
14
+ -- Parse the --args arguments
15
+ repeat with i from 2 to (count of argv)
16
+ set currentArg to item i of argv
17
+ if currentArg is "--args" then
18
+ set argsFlag to true
19
+ else if argsFlag then
20
+ set end of argsToRemove to currentArg
21
+ end if
22
+ end repeat
23
+
24
+ tell application "UTM"
25
+ -- Get the VM and its configuration
26
+ set vm to virtual machine id vmId -- Id is assumed to be valid
27
+ set config to configuration of vm
28
+
29
+ -- Get the current QEMU additional arguments
30
+ set qemuAddArgs to qemu additional arguments of config
31
+
32
+ -- Initialize a new list for the updated arguments
33
+ set updatedArgs to {}
34
+
35
+ -- Iterate through the current arguments and add all except the ones to remove
36
+ repeat with arg in qemuAddArgs
37
+ if arg is not in argsToRemove then
38
+ set end of updatedArgs to arg
39
+ end if
40
+ end repeat
41
+
42
+ -- Update the configuration with the new arguments list
43
+ set qemu additional arguments of config to updatedArgs
44
+ update configuration of vm with config
45
+ end tell
46
+ end run
@@ -0,0 +1,127 @@
1
+ # frozen_string_literal: true
2
+
3
+ module VagrantPlugins
4
+ module Utm
5
+ # Default Synced folder implementation for UTM
6
+ class SyncedFolder < Vagrant.plugin("2", :synced_folder)
7
+ def usable?(machine, _raise_errors = false) # rubocop:disable Style/OptionalBooleanParameter
8
+ # These synced folders only work if the provider is UTM
9
+ return false if machine.provider_name != :utm
10
+
11
+ # This only happens with `vagrant package --base`. Sigh.
12
+ return true unless machine.provider_config
13
+
14
+ machine.provider_config.functional_9pfs
15
+ end
16
+
17
+ # This is called before VM Boot to prepare the synced folders.
18
+ # Add required configs to the VM.
19
+ def prepare(machine, folders, _opts)
20
+ share_folders(machine, folders)
21
+ end
22
+
23
+ # This is called after VM Boot to mount the synced folders.
24
+ # Mount the shared folders inside the VM.
25
+ def enable(machine, folders, _opts) # rubocop:disable Metrics/AbcSize,Metrics/MethodLength,Metrics/PerceivedComplexity
26
+ share_folders(machine, folders)
27
+
28
+ # sort guestpaths first, so we don't step on ourselves
29
+ folders = folders.sort_by do |_id, data|
30
+ if data[:guestpath]
31
+ data[:guestpath].length
32
+ else
33
+ # A long enough path to just do this at the end.
34
+ 10_000
35
+ end
36
+ end
37
+
38
+ # Go through each folder and mount
39
+ machine.ui.output(I18n.t("vagrant.actions.vm.share_folders.mounting"))
40
+ # refresh fstab
41
+ fstab_folders = [] # rubocop:disable Lint/UselessAssignment
42
+ folders.each do |id, data|
43
+ if data[:guestpath]
44
+ # Guest path specified, so mount the folder to specified point
45
+ machine.ui.detail(I18n.t("vagrant.actions.vm.share_folders.mounting_entry",
46
+ guestpath: data[:guestpath],
47
+ hostpath: data[:hostpath]))
48
+
49
+ # Dup the data so we can pass it to the guest API
50
+ data = data.dup
51
+
52
+ # Calculate the owner and group
53
+ ssh_info = machine.ssh_info
54
+ data[:owner] ||= ssh_info[:username]
55
+ data[:group] ||= ssh_info[:username]
56
+
57
+ # Unmount the folder before we mount it
58
+ machine.guest.capability(
59
+ :unmount_virtualbox_shared_folder,
60
+ data[:guestpath], data
61
+ )
62
+
63
+ # Mount the actual folder
64
+ machine.guest.capability(
65
+ :mount_virtualbox_shared_folder,
66
+ os_friendly_id(id), data[:guestpath], data
67
+ )
68
+ else
69
+ # If no guest path is specified, then automounting is disabled
70
+ machine.ui.detail(I18n.t("vagrant.actions.vm.share_folders.nomount_entry",
71
+ hostpath: data[:hostpath]))
72
+ end
73
+ end
74
+ end
75
+
76
+ def disable(machine, folders, _opts)
77
+ if machine.guest.capability?(:unmount_virtualbox_shared_folder)
78
+ folders.each_value do |data|
79
+ machine.guest.capability(
80
+ :unmount_virtualbox_shared_folder,
81
+ data[:guestpath], data
82
+ )
83
+ end
84
+ end
85
+
86
+ # Remove the shared folders from the VM metadata
87
+ names = folders.map { |id, _data| os_friendly_id(id) }
88
+ driver(machine).unshare_folders(names)
89
+ end
90
+
91
+ def cleanup(machine, _opts)
92
+ driver(machine).clear_shared_folders if machine.id && machine.id != ""
93
+ end
94
+
95
+ protected
96
+
97
+ # This is here so that we can stub it for tests
98
+ def driver(machine)
99
+ machine.provider.driver
100
+ end
101
+
102
+ def os_friendly_id(id)
103
+ id.gsub(%r{[\s/\\]}, "_").sub(/^_/, "")
104
+ end
105
+
106
+ # share_folders sets up the shared folder definitions on the
107
+ # UTM VM.
108
+ #
109
+ def share_folders(machine, folders)
110
+ defs = []
111
+
112
+ folders.each do |id, data|
113
+ hostpath = data[:hostpath]
114
+ hostpath = Vagrant::Util::Platform.cygwin_windows_path(hostpath) unless data[:hostpath_exact]
115
+
116
+ defs << {
117
+ name: os_friendly_id(id),
118
+ hostpath: hostpath.to_s,
119
+ automount: !data[:automount].nil?
120
+ }
121
+ end
122
+
123
+ driver(machine).share_folders(defs)
124
+ end
125
+ end
126
+ end
127
+ end
@@ -0,0 +1,124 @@
1
+ # frozen_string_literal: true
2
+
3
+ # Copied from vagrant/plugins/synced_folder/unix_mount_helpers.rb
4
+ # Copyright (c) HashiCorp, Inc.
5
+ # SPDX-License-Identifier: BUSL-1.1
6
+
7
+ require "shellwords"
8
+ require "vagrant/util/retryable"
9
+
10
+ module VagrantPlugins
11
+ module SyncedFolder
12
+ # Contains helper methods for mounting folders on Unix-based systems.
13
+ module UnixMountHelpers # rubocop:disable Metrics/ModuleLength
14
+ def self.extended(klass)
15
+ unless klass.class_variable_defined?(:@@logger)
16
+ klass.class_variable_set(:@@logger, Log4r::Logger.new(klass.name.downcase)) # rubocop:disable Style/ClassVars
17
+ end
18
+ klass.extend Vagrant::Util::Retryable
19
+ end
20
+
21
+ def detect_owner_group_ids(machine, guest_path, mount_options, options) # rubocop:disable Metrics/AbcSize,Metrics/CyclomaticComplexity,Metrics/MethodLength,Metrics/PerceivedComplexity
22
+ mount_uid = find_mount_options_id("uid", mount_options)
23
+ mount_gid = find_mount_options_id("gid", mount_options)
24
+
25
+ if mount_uid.nil?
26
+ if options[:owner].to_i.to_s == options[:owner].to_s
27
+ mount_uid = options[:owner]
28
+ class_variable_get(:@@logger).debug("Owner user ID (provided): #{mount_uid}")
29
+ else
30
+ output = { stdout: String.new, stderr: String.new } # Ensure strings are not frozen
31
+ uid_command = "id -u #{options[:owner]}"
32
+ machine.communicate.execute(uid_command,
33
+ error_class: Vagrant::Errors::VirtualBoxMountFailed,
34
+ error_key: :virtualbox_mount_failed,
35
+ command: uid_command,
36
+ output: output[:stderr]) { |type, data| output[type] << data if output[type] }
37
+ mount_uid = output[:stdout].chomp
38
+ class_variable_get(:@@logger).debug("Owner user ID (lookup): #{options[:owner]} -> #{mount_uid}")
39
+ end
40
+ else
41
+ machine.ui.warn "Detected mount owner ID within mount options. (uid: #{mount_uid} guestpath: #{guest_path})"
42
+ end
43
+
44
+ if mount_gid.nil?
45
+ if options[:group].to_i.to_s == options[:group].to_s
46
+ mount_gid = options[:group]
47
+ class_variable_get(:@@logger).debug("Owner group ID (provided): #{mount_gid}")
48
+ else
49
+ begin
50
+ { stdout: String.new, stderr: String.new } # Ensure strings are not frozen
51
+ gid_command = "getent group #{options[:group]}"
52
+ machine.communicate.execute(gid_command,
53
+ error_class: Vagrant::Errors::VirtualBoxMountFailed,
54
+ error_key: :virtualbox_mount_failed,
55
+ command: gid_command,
56
+ output: output[:stderr]) { |type, data| output[type] << data if output[type] }
57
+ mount_gid = output[:stdout].split(":").at(2).to_s.chomp
58
+ class_variable_get(:@@logger).debug("Owner group ID (lookup): #{options[:group]} -> #{mount_gid}")
59
+ rescue Vagrant::Errors::VirtualBoxMountFailed
60
+ if options[:owner] == options[:group] # rubocop:disable Metrics/BlockNesting
61
+ class_variable_get(:@@logger).debug("Failed to locate group `#{options[:group]}`. Group name matches owner. Fetching effective group ID.") # rubocop:disable Layout/LineLength
62
+ output = { stdout: String.new }
63
+ result = machine.communicate.execute("id -g #{options[:owner]}",
64
+ error_check: false) do |type, data|
65
+ output[type] << data if output[type] # rubocop:disable Metrics/BlockNesting
66
+ end
67
+ mount_gid = output[:stdout].chomp if result.zero? # rubocop:disable Metrics/BlockNesting
68
+ class_variable_get(:@@logger).debug("Owner group ID (effective): #{mount_gid}")
69
+ end
70
+ raise unless mount_gid
71
+ end
72
+ end
73
+ else
74
+ machine.ui.warn "Detected mount group ID within mount options. (gid: #{mount_gid} guestpath: #{guest_path})"
75
+ end
76
+ { gid: mount_gid, uid: mount_uid }
77
+ end
78
+
79
+ def find_mount_options_id(id_name, mount_options) # rubocop:disable Metrics/AbcSize
80
+ id_line = mount_options.detect { |line| line.include?("#{id_name}=") }
81
+ if id_line
82
+ match = id_line.match(/,?#{Regexp.escape(id_name)}=(?<option_id>\d+),?/)
83
+ found_id = match["option_id"]
84
+ updated_id_line = [
85
+ match.pre_match,
86
+ match.post_match
87
+ ].find_all { |string| !string.empty? }.join(",")
88
+ if updated_id_line.empty?
89
+ mount_options.delete(id_line)
90
+ else
91
+ idx = mount_options.index(id_line)
92
+ mount_options.delete(idx)
93
+ mount_options.insert(idx, updated_id_line)
94
+ end
95
+ end
96
+ found_id
97
+ end
98
+
99
+ def emit_upstart_notification(machine, guest_path)
100
+ # Emit an upstart event if we can
101
+ machine.communicate.sudo <<-NOTIFICATION.gsub(/^ {12}/, "")
102
+ if test -x /sbin/initctl && command -v /sbin/init && /sbin/init 2>/dev/null --version | grep upstart; then
103
+ /sbin/initctl emit --no-wait vagrant-mounted MOUNTPOINT=#{guest_path}
104
+ fi
105
+ NOTIFICATION
106
+ end
107
+
108
+ def merge_mount_options(base, overrides) # rubocop:disable Metrics/AbcSize
109
+ base = base.join(",").split(",")
110
+ overrides = overrides.join(",").split(",")
111
+ b_kv = Hash[base.map { |item| item.split("=", 2) }]
112
+ o_kv = Hash[overrides.map { |item| item.split("=", 2) }]
113
+ merged = {}.tap do |opts|
114
+ (b_kv.keys + o_kv.keys).uniq.each do |key|
115
+ opts[key] = o_kv.fetch(key, b_kv[key])
116
+ end
117
+ end
118
+ merged.map do |key, value|
119
+ [key, value].compact.join("=")
120
+ end
121
+ end
122
+ end
123
+ end
124
+ end
@@ -4,6 +4,6 @@ module VagrantPlugins
4
4
  # Top level module for the Utm provider plugin.
5
5
  module Utm
6
6
  # Current version of the Utm provider plugin.
7
- VERSION = "0.1.2.beta"
7
+ VERSION = "0.1.3"
8
8
  end
9
9
  end
data/notes/README.md CHANGED
@@ -34,4 +34,17 @@ GHA will publish gems to GHR and rubygems
34
34
 
35
35
  To update specific gems in the project
36
36
 
37
- `bundle update rubocop`
37
+ `bundle update rubocop`
38
+
39
+ To update all gems
40
+
41
+ `bundle update`
42
+
43
+ To update project after a version bump
44
+
45
+ ```
46
+ Unable to resolve dependency: user requested 'vagrant_utm (= 0.1.1)'
47
+ ```
48
+
49
+ Due to mismatch versions between global installed version and plugin version in the development setup, since they are same name.
50
+ Fix: Uninstall the global version, while using different version of development setup
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: vagrant_utm
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.2.beta
4
+ version: 0.1.3
5
5
  platform: ruby
6
6
  authors:
7
7
  - Naveenraj M
8
- autorequire:
8
+ autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2024-12-05 00:00:00.000000000 Z
11
+ date: 2025-04-21 00:00:00.000000000 Z
12
12
  dependencies: []
13
13
  description: Vagrant UTM provider that allows you to manage UTM virtual machines.
14
14
  email:
@@ -95,6 +95,7 @@ files:
95
95
  - lib/vagrant_utm/action/suspend.rb
96
96
  - lib/vagrant_utm/action/wait_for_running.rb
97
97
  - lib/vagrant_utm/cap.rb
98
+ - lib/vagrant_utm/cap/mount_options.rb
98
99
  - lib/vagrant_utm/commands/disposable.rb
99
100
  - lib/vagrant_utm/commands/ip_address.rb
100
101
  - lib/vagrant_utm/config.rb
@@ -107,7 +108,9 @@ files:
107
108
  - lib/vagrant_utm/model/list_result.rb
108
109
  - lib/vagrant_utm/plugin.rb
109
110
  - lib/vagrant_utm/provider.rb
111
+ - lib/vagrant_utm/scripts/add_folder_share.applescript
110
112
  - lib/vagrant_utm/scripts/add_port_forwards.applescript
113
+ - lib/vagrant_utm/scripts/add_qemu_additional_args.applescript
111
114
  - lib/vagrant_utm/scripts/clear_port_forwards.applescript
112
115
  - lib/vagrant_utm/scripts/customize_vm.applescript
113
116
  - lib/vagrant_utm/scripts/downloadVM.sh
@@ -117,8 +120,13 @@ files:
117
120
  - lib/vagrant_utm/scripts/open_with_utm.js
118
121
  - lib/vagrant_utm/scripts/read_forwarded_ports.applescript
119
122
  - lib/vagrant_utm/scripts/read_network_interfaces.applescript
123
+ - lib/vagrant_utm/scripts/read_shared_folders.js
124
+ - lib/vagrant_utm/scripts/read_shared_folders_args.js
125
+ - lib/vagrant_utm/scripts/remove_qemu_additional_args.applescript
120
126
  - lib/vagrant_utm/scripts/set_mac_address.applescript
127
+ - lib/vagrant_utm/synced_folder.rb
121
128
  - lib/vagrant_utm/util/compile_forwarded_ports.rb
129
+ - lib/vagrant_utm/util/unix_mount_helpers.rb
122
130
  - lib/vagrant_utm/version.rb
123
131
  - locales/en.yml
124
132
  - notes/README.md
@@ -131,7 +139,7 @@ metadata:
131
139
  homepage_uri: https://naveenrajm7.github.io/vagrant_utm/
132
140
  source_code_uri: https://github.com/naveenrajm7/vagrant_utm
133
141
  changelog_uri: https://github.com/naveenrajm7/vagrant_utm/blob/main/CHANGELOG.md
134
- post_install_message:
142
+ post_install_message:
135
143
  rdoc_options: []
136
144
  require_paths:
137
145
  - lib
@@ -147,7 +155,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
147
155
  version: '0'
148
156
  requirements: []
149
157
  rubygems_version: 3.5.11
150
- signing_key:
158
+ signing_key:
151
159
  specification_version: 4
152
160
  summary: Vagrant UTM provider
153
161
  test_files: []