vagrant_utm 0.1.6 → 0.2.0
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 +4 -4
- data/CHANGELOG.md +19 -1
- data/README.md +1 -1
- data/docs/commands.md +16 -6
- data/docs/configuration.md +29 -0
- data/docs/internals/actions.md +13 -12
- data/docs/internals/utm_api.md +4 -4
- data/docs/known_issues.md +2 -3
- data/lib/vagrant_utm/action/customize.rb +25 -16
- data/lib/vagrant_utm/action.rb +8 -26
- data/lib/vagrant_utm/cap.rb +1 -7
- data/lib/vagrant_utm/config.rb +54 -0
- data/lib/vagrant_utm/driver/base.rb +33 -0
- data/lib/vagrant_utm/driver/meta.rb +1 -0
- data/lib/vagrant_utm/driver/version_4_5.rb +0 -66
- data/lib/vagrant_utm/driver/version_5_0.rb +99 -0
- data/lib/vagrant_utm/errors.rb +0 -20
- data/lib/vagrant_utm/scripts/update_network_interface.applescript +86 -0
- data/lib/vagrant_utm/version.rb +1 -1
- data/locales/en.yml +0 -21
- data/notes/README.md +36 -10
- metadata +3 -3
- data/lib/vagrant_utm/action/check_qemu_img.rb +0 -21
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: ec09354bc45c159ba048b7965ffd6802e865a3f60e99e74d2bdd5f9bb5bf3166
|
|
4
|
+
data.tar.gz: 001d7226ab9fdd498d8340b0a095eaebe1774424418095f0a73fbb42e04fc1c9
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: d83c1d82fdcb5dc2983edd7b16c4a72b76b934a7b66bb379b80e46e85a70a6ad0b2e1720c56f1311f3cc42f465034d08acf66c78f8a6ddac15c155ab0b001236
|
|
7
|
+
data.tar.gz: 5247adf195d74c9992cb03451baa55f5ac5c7c5d4bc8a58f2e651b73f044bcf806fe7a8ed66a43119e549bf2c8df754e7c137f75119394c31155626e5c7662e7
|
data/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,23 @@
|
|
|
1
1
|
## [Unreleased]
|
|
2
2
|
|
|
3
|
+
## [0.2.0] - 2026-10-14
|
|
4
|
+
|
|
5
|
+
### Added
|
|
6
|
+
- Use UTM 5.0.6's native snapshot API through `utmctl` for supported QEMU
|
|
7
|
+
and Apple Virtualization VMs (Apple snapshots require macOS 27).
|
|
8
|
+
- Support UTM 5.0.4+ VLAN guest and DHCP network properties through
|
|
9
|
+
`network_interface` and `update_network_interface`.
|
|
10
|
+
|
|
11
|
+
### Changed
|
|
12
|
+
- Let UTM handle snapshot creation, listing, restoration, and deletion across
|
|
13
|
+
supported VM states.
|
|
14
|
+
- Stop a running VM before restoring a snapshot to avoid UTM's live restore RPC
|
|
15
|
+
timeout, then restart it unless Vagrant's `--no-start` option is given.
|
|
16
|
+
|
|
17
|
+
### Removed
|
|
18
|
+
- Remove the `qemu-img` snapshot workaround. Snapshots now require UTM 5.0.6 or
|
|
19
|
+
newer; keep an older plugin release if you need snapshots on older UTM.
|
|
20
|
+
|
|
3
21
|
## [0.1.6] - 2026-08-14
|
|
4
22
|
|
|
5
23
|
### Added
|
|
@@ -94,4 +112,4 @@ IMPORTANT: This version of the plugin only works with UTM version 4.5.1 and abov
|
|
|
94
112
|
## [0.0.1] (Pilot release) - 2024-08-08
|
|
95
113
|
|
|
96
114
|
* Initial release with all basic vagrant commands
|
|
97
|
-
* Uses UTM file in zip format from a url as VM box to import
|
|
115
|
+
* Uses UTM file in zip format from a url as VM box to import
|
data/README.md
CHANGED
|
@@ -27,7 +27,7 @@ vagrant up
|
|
|
27
27
|
|
|
28
28
|
After checking out the repo, run `bin/setup` to install dependencies. Then, run `rake spec` to run the tests. You can also run `bin/console` for an interactive prompt that will allow you to experiment.
|
|
29
29
|
|
|
30
|
-
To install this gem onto your local machine, run `bundle exec rake install`. To release a new version,
|
|
30
|
+
To install this gem onto your local machine, run `bundle exec rake install`. To release a new version, follow the [release steps](notes/README.md#to-release). The tag-triggered GitHub Actions workflow builds and publishes the gem.
|
|
31
31
|
|
|
32
32
|
### Vagrant
|
|
33
33
|
|
data/docs/commands.md
CHANGED
|
@@ -9,7 +9,7 @@ nav_order: 2
|
|
|
9
9
|
|
|
10
10
|
This page lists all the supported Vagrant commands which depend on the UTM provider. Eg. `up`, `suspend`, `resume`, `halt`.
|
|
11
11
|
|
|
12
|
-
Adds
|
|
12
|
+
Adds notes to commands which have provider-specific behavior. Eg. `snapshot`.
|
|
13
13
|
|
|
14
14
|
The Vagrant commands that do not depend on provider are not listed and will continue to work. Eg. `global-status`
|
|
15
15
|
|
|
@@ -84,13 +84,23 @@ This resumes a Vagrant managed machine that was previously suspended, perhaps wi
|
|
|
84
84
|
|
|
85
85
|
**Command: `vagrant snapshot`**
|
|
86
86
|
|
|
87
|
-
|
|
88
|
-
Snapshot feature is not available in UTM.
|
|
89
|
-
The plugin just provides experimental feature using qemu-img
|
|
87
|
+
`utmctl snapshot`
|
|
90
88
|
|
|
91
|
-
|
|
92
|
-
|
|
89
|
+
With UTM 5.0.6 or newer, the provider uses UTM's native named snapshots.
|
|
90
|
+
UTM supports QEMU snapshots on macOS. Apple Virtualization snapshots require
|
|
91
|
+
macOS 27. A snapshot of a running QEMU VM includes its running state; a
|
|
92
|
+
snapshot of a stopped VM saves its disks. UTM handles saving, listing, and
|
|
93
|
+
deleting snapshots through its native API.
|
|
93
94
|
|
|
95
|
+
`vagrant snapshot restore` stops a running VM before restoring its snapshot.
|
|
96
|
+
Vagrant starts the restored VM afterward unless `--no-start` is given. UTM may
|
|
97
|
+
resume saved RAM state when the restored VM next starts. The provider does not call
|
|
98
|
+
`utmctl discard-state` during a restore, because that would discard the saved
|
|
99
|
+
running state.
|
|
100
|
+
|
|
101
|
+
Older UTM releases do not expose the 5.0.6 snapshot API. This plugin no longer uses
|
|
102
|
+
`qemu-img` as a fallback. If you need snapshots on UTM older than 5.0.6,
|
|
103
|
+
keep the previous plugin version that paired with that UTM release.
|
|
94
104
|
|
|
95
105
|
|
|
96
106
|
## **SSH**
|
data/docs/configuration.md
CHANGED
|
@@ -27,6 +27,35 @@ config.vm.provider "utm" do |u|
|
|
|
27
27
|
end
|
|
28
28
|
```
|
|
29
29
|
|
|
30
|
+
## Shared network VLAN / DHCP (UTM 5.0.4+)
|
|
31
|
+
|
|
32
|
+
UTM 5.0.4 exposed AppleScript properties for the shared/host network VLAN subnet and DHCP pool ([utmapp/UTM#7710](https://github.com/utmapp/UTM/pull/7710)), so you no longer need to set them manually in the UTM UI ([utmapp/UTM#3294](https://github.com/utmapp/UTM/issues/3294)).
|
|
33
|
+
|
|
34
|
+
Index `0` is typically the first (Shared Network) adapter used by Vagrant boxes:
|
|
35
|
+
|
|
36
|
+
```ruby
|
|
37
|
+
config.vm.provider "utm" do |u|
|
|
38
|
+
u.network_interface 0,
|
|
39
|
+
vlan_guest_address: "192.168.222.0/24",
|
|
40
|
+
vlan_dhcp_start_address: "192.168.222.2",
|
|
41
|
+
vlan_dhcp_end_address: "192.168.222.254",
|
|
42
|
+
isolate_from_host: false
|
|
43
|
+
end
|
|
44
|
+
```
|
|
45
|
+
|
|
46
|
+
Optional keys: `vlan_guest_address`, `vlan_guest_address_ipv6`, `vlan_dhcp_start_address`, `vlan_dhcp_end_address`, `isolate_from_host`.
|
|
47
|
+
|
|
48
|
+
You can also call the driver directly when the machine already exists:
|
|
49
|
+
|
|
50
|
+
```ruby
|
|
51
|
+
machine.provider.driver.update_network_interface(
|
|
52
|
+
0,
|
|
53
|
+
vlan_guest_address: "192.168.222.0/24",
|
|
54
|
+
vlan_dhcp_start_address: "192.168.222.2",
|
|
55
|
+
vlan_dhcp_end_address: "192.168.222.254"
|
|
56
|
+
)
|
|
57
|
+
```
|
|
58
|
+
|
|
30
59
|
## Other customization
|
|
31
60
|
|
|
32
61
|
```ruby
|
data/docs/internals/actions.md
CHANGED
|
@@ -7,15 +7,16 @@ nav_order: 1
|
|
|
7
7
|
|
|
8
8
|
The Table below maps the vagrant commands to the corresponding UTM commands that are executed.
|
|
9
9
|
|
|
10
|
-
| Vagrant
|
|
11
|
-
| ---
|
|
12
|
-
| `vagrant up`
|
|
13
|
-
| `vagrant halt`
|
|
14
|
-
| `vagrant suspend`
|
|
15
|
-
| `vagrant resume`
|
|
16
|
-
| `vagrant reload`
|
|
17
|
-
| `vagrant destroy`
|
|
18
|
-
| `vagrant status`
|
|
19
|
-
| `vagrant disposable`
|
|
20
|
-
| `vagrant snapshot`
|
|
21
|
-
| `vagrant ip-address`
|
|
10
|
+
| Vagrant | utmctl / AppleScript |
|
|
11
|
+
| --- | --- |
|
|
12
|
+
| `vagrant up` | `utmctl start` |
|
|
13
|
+
| `vagrant halt` | `utmctl stop` |
|
|
14
|
+
| `vagrant suspend` | `utmctl suspend` |
|
|
15
|
+
| `vagrant resume` | `utmctl start` |
|
|
16
|
+
| `vagrant reload` | update configuration of vm with config |
|
|
17
|
+
| `vagrant destroy` | `utmctl delete` |
|
|
18
|
+
| `vagrant status` | `utmctl status` |
|
|
19
|
+
| `vagrant disposable` | `utmctl start --disposable` |
|
|
20
|
+
| `vagrant snapshot` | `utmctl snapshot` |
|
|
21
|
+
| `vagrant ip-address` | `utmctl ip-address` |
|
|
22
|
+
| Provider `network_interface` (UTM 5.0.4+) | AppleScript network VLAN/DHCP properties |
|
data/docs/internals/utm_api.md
CHANGED
|
@@ -23,8 +23,8 @@ So we rely on Apple Scripting Bridge scripts which can be executed using `osascr
|
|
|
23
23
|
When it comes to writing the OSA scripts, our first choice is applescript language due to its simplicity and support.
|
|
24
24
|
But, if we need to exchange complex data like json from UTM to plugin we use Javascript (Note: Some APIs are difficult to get it working in JS, hence our first choice is applescript).
|
|
25
25
|
|
|
26
|
-
**3. Shell command** :
|
|
27
|
-
All interactions with UTM should be possible with `utmctl` or `osascript`.
|
|
28
|
-
|
|
26
|
+
**3. Shell command** :
|
|
27
|
+
All interactions with UTM should be possible with `utmctl` or `osascript`.
|
|
28
|
+
Direct shell commands are reserved for capabilities that UTM does not expose.
|
|
29
29
|
|
|
30
|
-
|
|
30
|
+
Snapshots use UTM's native `utmctl snapshot` commands.
|
data/docs/known_issues.md
CHANGED
|
@@ -19,6 +19,5 @@ Draw back - UTM does not expose export API. (UTM already has 'Share')~~
|
|
|
19
19
|
|
|
20
20
|
4. Hide: Any plugin action will bring up the main UTM window. However, a properly built UTM box with no display will run headless.
|
|
21
21
|
|
|
22
|
-
5. vagrant snapshot
|
|
23
|
-
|
|
24
|
-
The snapshot only works for **single** qcow2 based VM images
|
|
22
|
+
5. `vagrant snapshot` requires UTM 5.0.6 or newer (native `utmctl snapshot`).
|
|
23
|
+
There is no `qemu-img` fallback in this plugin version.
|
|
@@ -13,7 +13,7 @@ module VagrantPlugins
|
|
|
13
13
|
@event = event
|
|
14
14
|
end
|
|
15
15
|
|
|
16
|
-
def call(env)
|
|
16
|
+
def call(env)
|
|
17
17
|
customizations = []
|
|
18
18
|
env[:machine].provider_config.customizations.each do |event, command|
|
|
19
19
|
customizations << command if event == @event
|
|
@@ -24,26 +24,35 @@ module VagrantPlugins
|
|
|
24
24
|
|
|
25
25
|
# Execute each customization command.
|
|
26
26
|
customizations.each do |command|
|
|
27
|
-
|
|
28
|
-
arg = env[:machine].id if arg == :id
|
|
29
|
-
arg.to_s
|
|
30
|
-
end
|
|
31
|
-
|
|
32
|
-
begin
|
|
33
|
-
env[:machine].provider.driver.execute_osa_script(
|
|
34
|
-
processed_command
|
|
35
|
-
)
|
|
36
|
-
rescue VagrantPlugins::Utm::Errors::CommandError => e
|
|
37
|
-
raise Vagrant::Errors::VMCustomizationFailed, {
|
|
38
|
-
command: command,
|
|
39
|
-
error: e.inspect
|
|
40
|
-
}
|
|
41
|
-
end
|
|
27
|
+
execute_customization(env, command)
|
|
42
28
|
end
|
|
43
29
|
end
|
|
44
30
|
|
|
45
31
|
@app.call(env)
|
|
46
32
|
end
|
|
33
|
+
|
|
34
|
+
private
|
|
35
|
+
|
|
36
|
+
def execute_customization(env, command)
|
|
37
|
+
if command.first == :network_interface
|
|
38
|
+
env[:machine].provider.driver.update_network_interface(command[1], command[2])
|
|
39
|
+
else
|
|
40
|
+
execute_osa_customization(env, command)
|
|
41
|
+
end
|
|
42
|
+
rescue VagrantPlugins::Utm::Errors::CommandError => e
|
|
43
|
+
raise Vagrant::Errors::VMCustomizationFailed, {
|
|
44
|
+
command: command,
|
|
45
|
+
error: e.inspect
|
|
46
|
+
}
|
|
47
|
+
end
|
|
48
|
+
|
|
49
|
+
def execute_osa_customization(env, command)
|
|
50
|
+
processed_command = command.map do |arg|
|
|
51
|
+
arg = env[:machine].id if arg == :id
|
|
52
|
+
arg.to_s
|
|
53
|
+
end
|
|
54
|
+
env[:machine].provider.driver.execute_osa_script(processed_command)
|
|
55
|
+
end
|
|
47
56
|
end
|
|
48
57
|
end
|
|
49
58
|
end
|
data/lib/vagrant_utm/action.rb
CHANGED
|
@@ -14,7 +14,6 @@ module VagrantPlugins
|
|
|
14
14
|
autoload :CheckAccessible, action_root.join("check_accessible")
|
|
15
15
|
autoload :CheckCreated, action_root.join("check_created")
|
|
16
16
|
autoload :CheckGuestAdditions, action_root.join("check_guest_additions")
|
|
17
|
-
autoload :CheckQemuImg, action_root.join("check_qemu_img")
|
|
18
17
|
autoload :CheckRunning, action_root.join("check_running")
|
|
19
18
|
autoload :CheckUtm, action_root.join("check_utm")
|
|
20
19
|
autoload :ClearForwardedPorts, action_root.join("clear_forwarded_ports")
|
|
@@ -266,17 +265,9 @@ module VagrantPlugins
|
|
|
266
265
|
def self.action_snapshot_delete
|
|
267
266
|
Vagrant::Action::Builder.new.tap do |b|
|
|
268
267
|
b.use CheckUtm
|
|
269
|
-
b.use CheckQemuImg
|
|
270
268
|
b.use Call, Created do |env, b2|
|
|
271
269
|
if env[:result]
|
|
272
|
-
|
|
273
|
-
b2.use Call, IsStopped do |env2, b3|
|
|
274
|
-
if env2[:result]
|
|
275
|
-
b3.use SnapshotDelete
|
|
276
|
-
else
|
|
277
|
-
b3.use MessageNotStopped
|
|
278
|
-
end
|
|
279
|
-
end
|
|
270
|
+
b2.use SnapshotDelete
|
|
280
271
|
else
|
|
281
272
|
b2.use MessageNotCreated
|
|
282
273
|
end
|
|
@@ -288,20 +279,19 @@ module VagrantPlugins
|
|
|
288
279
|
def self.action_snapshot_restore # rubocop:disable Metrics/AbcSize
|
|
289
280
|
Vagrant::Action::Builder.new.tap do |b|
|
|
290
281
|
b.use CheckUtm
|
|
291
|
-
b.use CheckQemuImg
|
|
292
282
|
b.use Call, Created do |env, b2|
|
|
293
283
|
raise Vagrant::Errors::VMNotCreatedError unless env[:result]
|
|
294
284
|
|
|
295
285
|
b2.use CheckAccessible
|
|
286
|
+
# Restoring a running QEMU VM can leave UTM waiting for its RPC.
|
|
287
|
+
# Stop it first, then let Vagrant honor --no-start below.
|
|
296
288
|
b2.use EnvSet, force_halt: true
|
|
297
289
|
b2.use action_halt
|
|
298
|
-
b2.use SnapshotRestore
|
|
299
|
-
|
|
300
|
-
b2.use Call, IsEnvSet, :snapshot_delete do |env2, b3|
|
|
301
|
-
b3.use action_snapshot_delete if env2[:result]
|
|
302
|
-
end
|
|
303
|
-
|
|
304
290
|
b2.use Call, IsEnvSet, :snapshot_start do |env2, b3|
|
|
291
|
+
b3.use SnapshotRestore
|
|
292
|
+
b3.use Call, IsEnvSet, :snapshot_delete do |env3, b4|
|
|
293
|
+
b4.use action_snapshot_delete if env3[:result]
|
|
294
|
+
end
|
|
305
295
|
b3.use action_start if env2[:result]
|
|
306
296
|
end
|
|
307
297
|
end
|
|
@@ -312,17 +302,9 @@ module VagrantPlugins
|
|
|
312
302
|
def self.action_snapshot_save
|
|
313
303
|
Vagrant::Action::Builder.new.tap do |b|
|
|
314
304
|
b.use CheckUtm
|
|
315
|
-
b.use CheckQemuImg
|
|
316
305
|
b.use Call, Created do |env, b2|
|
|
317
306
|
if env[:result]
|
|
318
|
-
|
|
319
|
-
b2.use Call, IsStopped do |env2, b3|
|
|
320
|
-
if env2[:result]
|
|
321
|
-
b3.use SnapshotSave
|
|
322
|
-
else
|
|
323
|
-
b3.use MessageNotStopped
|
|
324
|
-
end
|
|
325
|
-
end
|
|
307
|
+
b2.use SnapshotSave
|
|
326
308
|
else
|
|
327
309
|
b2.use MessageNotCreated
|
|
328
310
|
end
|
data/lib/vagrant_utm/cap.rb
CHANGED
|
@@ -27,13 +27,7 @@ module VagrantPlugins
|
|
|
27
27
|
def self.snapshot_list(machine)
|
|
28
28
|
return [] if machine.id.nil?
|
|
29
29
|
|
|
30
|
-
|
|
31
|
-
machine.provider.driver.list_snapshots(machine.id)
|
|
32
|
-
rescue VagrantPlugins::Utm::Errors::CommandError => e
|
|
33
|
-
raise Errors::SnapShotCommandFailed, {
|
|
34
|
-
stderr: e.inspect
|
|
35
|
-
}
|
|
36
|
-
end
|
|
30
|
+
machine.provider.driver.list_snapshots(machine.id)
|
|
37
31
|
end
|
|
38
32
|
end
|
|
39
33
|
end
|
data/lib/vagrant_utm/config.rb
CHANGED
|
@@ -7,6 +7,13 @@ 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
|
+
NETWORK_OPTION_FLAGS = {
|
|
11
|
+
vlan_guest_address: "--vlan-guest-address",
|
|
12
|
+
vlan_guest_address_ipv6: "--vlan-guest-address-ipv6",
|
|
13
|
+
vlan_dhcp_start_address: "--vlan-dhcp-start-address",
|
|
14
|
+
vlan_dhcp_end_address: "--vlan-dhcp-end-address"
|
|
15
|
+
}.freeze
|
|
16
|
+
|
|
10
17
|
# If true, will check if guest additions are installed and up to
|
|
11
18
|
# date. By default, this is true.
|
|
12
19
|
#
|
|
@@ -123,6 +130,33 @@ module VagrantPlugins
|
|
|
123
130
|
customize("pre-boot", ["customize_vm.applescript", :id, "--directory-share-mode", mode_code])
|
|
124
131
|
end
|
|
125
132
|
|
|
133
|
+
# Configure VLAN / DHCP settings on a UTM network interface.
|
|
134
|
+
#
|
|
135
|
+
# Maps to the AppleScript network properties added in UTM 5.0.4
|
|
136
|
+
# (utmapp/UTM#7710). These apply to shared/host network modes and let
|
|
137
|
+
# you pin the guest subnet / DHCP pool without editing the UTM UI
|
|
138
|
+
# (see utmapp/UTM#3294).
|
|
139
|
+
#
|
|
140
|
+
# @param index [Integer] network interface index (0 = first adapter)
|
|
141
|
+
# @param options [Hash]
|
|
142
|
+
# @option options [String] :vlan_guest_address IPv4 subnet CIDR (e.g. "192.168.222.0/24")
|
|
143
|
+
# @option options [String] :vlan_guest_address_ipv6 IPv6 prefix (e.g. "fec0::/64")
|
|
144
|
+
# @option options [String] :vlan_dhcp_start_address first DHCP pool address
|
|
145
|
+
# @option options [String] :vlan_dhcp_end_address last DHCP pool address
|
|
146
|
+
# @option options [Boolean] :isolate_from_host isolate guest from host
|
|
147
|
+
# @return [void]
|
|
148
|
+
def network_interface(index, **options)
|
|
149
|
+
if network_option_arguments(options).empty?
|
|
150
|
+
raise Vagrant::Errors::ConfigInvalid,
|
|
151
|
+
errors: "network_interface requires at least one of: " \
|
|
152
|
+
"vlan_guest_address, vlan_guest_address_ipv6, " \
|
|
153
|
+
"vlan_dhcp_start_address, vlan_dhcp_end_address, " \
|
|
154
|
+
"isolate_from_host"
|
|
155
|
+
end
|
|
156
|
+
|
|
157
|
+
customize("pre-boot", [:network_interface, index, options])
|
|
158
|
+
end
|
|
159
|
+
|
|
126
160
|
# This is the hook that is called to finalize the object before it
|
|
127
161
|
# is put into use.
|
|
128
162
|
def finalize!
|
|
@@ -161,6 +195,26 @@ module VagrantPlugins
|
|
|
161
195
|
def to_s
|
|
162
196
|
"UTM"
|
|
163
197
|
end
|
|
198
|
+
|
|
199
|
+
private
|
|
200
|
+
|
|
201
|
+
def network_option_arguments(options)
|
|
202
|
+
NETWORK_OPTION_FLAGS.flat_map do |key, flag|
|
|
203
|
+
option_argument(flag, options[key])
|
|
204
|
+
end + isolate_from_host_argument(options[:isolate_from_host])
|
|
205
|
+
end
|
|
206
|
+
|
|
207
|
+
def option_argument(flag, value)
|
|
208
|
+
return [] if value.nil? || value.to_s.empty?
|
|
209
|
+
|
|
210
|
+
[flag, value.to_s]
|
|
211
|
+
end
|
|
212
|
+
|
|
213
|
+
def isolate_from_host_argument(value)
|
|
214
|
+
return [] if value.nil?
|
|
215
|
+
|
|
216
|
+
["--isolate-from-host", value ? "true" : "false"]
|
|
217
|
+
end
|
|
164
218
|
end
|
|
165
219
|
end
|
|
166
220
|
end
|
|
@@ -39,6 +39,26 @@ module VagrantPlugins
|
|
|
39
39
|
# @return [Boolean]
|
|
40
40
|
def check_qemu_guest_agent; end
|
|
41
41
|
|
|
42
|
+
# Create a named full-VM snapshot.
|
|
43
|
+
def create_snapshot(_machine_id, _snapshot_name)
|
|
44
|
+
snapshot_unsupported!
|
|
45
|
+
end
|
|
46
|
+
|
|
47
|
+
# Delete a named full-VM snapshot.
|
|
48
|
+
def delete_snapshot(_machine_id, _snapshot_name)
|
|
49
|
+
snapshot_unsupported!
|
|
50
|
+
end
|
|
51
|
+
|
|
52
|
+
# List named full-VM snapshots.
|
|
53
|
+
def list_snapshots(_machine_id)
|
|
54
|
+
snapshot_unsupported!
|
|
55
|
+
end
|
|
56
|
+
|
|
57
|
+
# Restore a named full-VM snapshot.
|
|
58
|
+
def restore_snapshot(_machine_id, _snapshot_name)
|
|
59
|
+
snapshot_unsupported!
|
|
60
|
+
end
|
|
61
|
+
|
|
42
62
|
# Forwards a set of ports for a VM.
|
|
43
63
|
#
|
|
44
64
|
# This will not affect any previously set forwarded ports,
|
|
@@ -103,6 +123,14 @@ module VagrantPlugins
|
|
|
103
123
|
# @return [Hash]
|
|
104
124
|
def read_network_interfaces; end
|
|
105
125
|
|
|
126
|
+
# Update VLAN / DHCP settings on a network interface (UTM 5.0.4+).
|
|
127
|
+
#
|
|
128
|
+
# @param [Integer] index Network interface index
|
|
129
|
+
# @param [Hash] options VLAN / DHCP options
|
|
130
|
+
def update_network_interface(_index, _options = {})
|
|
131
|
+
raise Errors::UtmInvalidVersion, supported_versions: "5.0.4+"
|
|
132
|
+
end
|
|
133
|
+
|
|
106
134
|
# Sets the MAC address of the first network adapter.
|
|
107
135
|
#
|
|
108
136
|
# @param [String] mac MAC address without any spaces/hyphens.
|
|
@@ -333,6 +361,11 @@ module VagrantPlugins
|
|
|
333
361
|
|
|
334
362
|
private
|
|
335
363
|
|
|
364
|
+
def snapshot_unsupported!
|
|
365
|
+
raise Errors::UtmInvalidVersion,
|
|
366
|
+
supported_versions: "5.0.6+ (required for snapshots)"
|
|
367
|
+
end
|
|
368
|
+
|
|
336
369
|
# List of LANG values to attempt to use
|
|
337
370
|
LANG_VARIATIONS = %w[C.UTF-8 C.utf8 en_US.UTF-8 en_US.utf8 C POSIX].map(&:freeze).freeze
|
|
338
371
|
|
|
@@ -1,8 +1,6 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
3
|
require "log4r"
|
|
4
|
-
require "etc"
|
|
5
|
-
require "vagrant/util/platform"
|
|
6
4
|
|
|
7
5
|
require File.expand_path("base", __dir__)
|
|
8
6
|
|
|
@@ -38,50 +36,11 @@ module VagrantPlugins
|
|
|
38
36
|
output.include?("root")
|
|
39
37
|
end
|
|
40
38
|
|
|
41
|
-
def create_snapshot(machine_id, snapshot_name)
|
|
42
|
-
list_result = list
|
|
43
|
-
machine_name = list_result.find(uuid: machine_id).name
|
|
44
|
-
machine_file = get_vm_file(machine_name)
|
|
45
|
-
execute_shell("qemu-img", "snapshot", "-c", snapshot_name, machine_file)
|
|
46
|
-
end
|
|
47
|
-
|
|
48
|
-
def delete_snapshot(machine_id, snapshot_name)
|
|
49
|
-
list_result = list
|
|
50
|
-
machine_name = list_result.find(uuid: machine_id).name
|
|
51
|
-
machine_file = get_vm_file(machine_name)
|
|
52
|
-
execute_shell("qemu-img", "snapshot", "-d", snapshot_name, machine_file)
|
|
53
|
-
end
|
|
54
|
-
|
|
55
39
|
def export(_path)
|
|
56
40
|
@logger.info("This version of UTM does not support exporting VMs
|
|
57
41
|
Please upgrade to the latest version of UTM or UTM 'Share' feature in UI to export the virtual machine")
|
|
58
42
|
end
|
|
59
43
|
|
|
60
|
-
def list_snapshots(machine_id) # rubocop:disable Metrics/AbcSize
|
|
61
|
-
list_result = list
|
|
62
|
-
machine_name = list_result.find(uuid: machine_id).name
|
|
63
|
-
machine_file = get_vm_file(machine_name)
|
|
64
|
-
output = execute_shell("qemu-img", "snapshot", "-l", machine_file)
|
|
65
|
-
|
|
66
|
-
return [] if output.nil? || output.strip.empty?
|
|
67
|
-
|
|
68
|
-
@logger.debug("list_snapshots_here: #{output}")
|
|
69
|
-
|
|
70
|
-
result = []
|
|
71
|
-
output.split("\n").map do |line|
|
|
72
|
-
result << ::Regexp.last_match(1).to_s if line =~ /^\d+\s+(\w+)/
|
|
73
|
-
end
|
|
74
|
-
|
|
75
|
-
result.sort
|
|
76
|
-
end
|
|
77
|
-
|
|
78
|
-
def restore_snapshot(machine_id, snapshot_name)
|
|
79
|
-
list_result = list
|
|
80
|
-
machine_name = list_result.find(uuid: machine_id).name
|
|
81
|
-
machine_file = get_vm_file(machine_name)
|
|
82
|
-
execute_shell("qemu-img", "snapshot", "-a", snapshot_name, machine_file)
|
|
83
|
-
end
|
|
84
|
-
|
|
85
44
|
def forward_ports(ports) # rubocop:disable Metrics/CyclomaticComplexity
|
|
86
45
|
args = []
|
|
87
46
|
ports.each do |options|
|
|
@@ -112,31 +71,6 @@ module VagrantPlugins
|
|
|
112
71
|
execute_osa_script(command) unless args.empty?
|
|
113
72
|
end
|
|
114
73
|
|
|
115
|
-
def get_vm_file(vm_name)
|
|
116
|
-
# Get the current username
|
|
117
|
-
username = ENV["USER"] || Etc.getlogin
|
|
118
|
-
|
|
119
|
-
data_path = "/Users/#{username}/Library/Containers/com.utmapp.UTM/Data/Documents/#{vm_name}.utm/Data"
|
|
120
|
-
# Define the regex for UUID pattern
|
|
121
|
-
pattern = /^\b[0-9a-fA-F]{8}\b-[0-9a-fA-F]{4}\b-[0-9a-fA-F]{4}\b-[0-9a-fA-F]{4}\b-[0-9a-fA-F]{12}\b.qcow2$/
|
|
122
|
-
|
|
123
|
-
# List the files in the directory and filter by regex
|
|
124
|
-
matching_files = Dir.entries(data_path).select do |file|
|
|
125
|
-
file.match?(pattern)
|
|
126
|
-
end
|
|
127
|
-
|
|
128
|
-
if matching_files.length == 1
|
|
129
|
-
# If there is exactly one matching file, return full path to file
|
|
130
|
-
"#{data_path}/#{matching_files[0]}"
|
|
131
|
-
elsif matching_files.length > 1
|
|
132
|
-
# If there are multiple matching files, raise an error
|
|
133
|
-
raise Errors::SnapShotMultipleVMFiles, directory: data_path, files: matching_files
|
|
134
|
-
else
|
|
135
|
-
# If there are no matching files, raise an error
|
|
136
|
-
raise Errors::SnapShotVMFileNotFound, directory: data_path
|
|
137
|
-
end
|
|
138
|
-
end
|
|
139
|
-
|
|
140
74
|
# Check if the VM with the given UUID exists.
|
|
141
75
|
def vm_exists?(uuid)
|
|
142
76
|
list_result = list
|
|
@@ -1,5 +1,7 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
|
+
require "json"
|
|
4
|
+
|
|
3
5
|
require File.expand_path("version_4_7", __dir__)
|
|
4
6
|
|
|
5
7
|
module VagrantPlugins
|
|
@@ -7,11 +9,108 @@ module VagrantPlugins
|
|
|
7
9
|
module Driver
|
|
8
10
|
# Driver for UTM 5.0.x
|
|
9
11
|
class Version_5_0 < Version_4_7 # rubocop:disable Naming/ClassAndModuleCamelCase
|
|
12
|
+
# UTM AppleScript VLAN network properties land in 5.0.4
|
|
13
|
+
# (utmapp/UTM#7710).
|
|
14
|
+
VLAN_NETWORK_MIN_VERSION = "5.0.4"
|
|
15
|
+
NETWORK_OPTION_FLAGS = {
|
|
16
|
+
vlan_guest_address: "--vlan-guest-address",
|
|
17
|
+
vlan_guest_address_ipv6: "--vlan-guest-address-ipv6",
|
|
18
|
+
vlan_dhcp_start_address: "--vlan-dhcp-start-address",
|
|
19
|
+
vlan_dhcp_end_address: "--vlan-dhcp-end-address"
|
|
20
|
+
}.freeze
|
|
21
|
+
SNAPSHOT_MIN_VERSION = "5.0.6"
|
|
22
|
+
|
|
10
23
|
def initialize(uuid)
|
|
11
24
|
super
|
|
12
25
|
|
|
13
26
|
@logger = Log4r::Logger.new("vagrant::provider::utm::version_5_0")
|
|
14
27
|
end
|
|
28
|
+
|
|
29
|
+
# Update VLAN / DHCP settings on a network interface.
|
|
30
|
+
#
|
|
31
|
+
# These properties apply to shared/host network modes and map to the
|
|
32
|
+
# AppleScript fields added in utmapp/UTM#7710 (UTM 5.0.4+).
|
|
33
|
+
#
|
|
34
|
+
# @param [Integer] index Network interface index (0-based)
|
|
35
|
+
# @param [Hash] options
|
|
36
|
+
# @option options [String] :vlan_guest_address IPv4 subnet CIDR
|
|
37
|
+
# @option options [String] :vlan_guest_address_ipv6 IPv6 prefix
|
|
38
|
+
# @option options [String] :vlan_dhcp_start_address DHCP pool start
|
|
39
|
+
# @option options [String] :vlan_dhcp_end_address DHCP pool end
|
|
40
|
+
# @option options [Boolean] :isolate_from_host Isolate guest from host
|
|
41
|
+
def update_network_interface(index, options = {})
|
|
42
|
+
require_vlan_network_support!(__method__)
|
|
43
|
+
|
|
44
|
+
args = ["--index", index.to_s] + network_option_arguments(options)
|
|
45
|
+
|
|
46
|
+
if args.length == 2
|
|
47
|
+
raise ArgumentError,
|
|
48
|
+
"update_network_interface requires at least one network option"
|
|
49
|
+
end
|
|
50
|
+
|
|
51
|
+
command = ["update_network_interface.applescript", @uuid] + args
|
|
52
|
+
execute_osa_script(command)
|
|
53
|
+
end
|
|
54
|
+
|
|
55
|
+
def create_snapshot(machine_id, snapshot_name)
|
|
56
|
+
require_snapshot_support!
|
|
57
|
+
execute("snapshot", "create", machine_id, "--name", snapshot_name)
|
|
58
|
+
end
|
|
59
|
+
|
|
60
|
+
def delete_snapshot(machine_id, snapshot_name)
|
|
61
|
+
require_snapshot_support!
|
|
62
|
+
execute("snapshot", "delete", machine_id, "--snapshot", snapshot_name)
|
|
63
|
+
end
|
|
64
|
+
|
|
65
|
+
def list_snapshots(machine_id)
|
|
66
|
+
require_snapshot_support!
|
|
67
|
+
output = execute("snapshot", "list", machine_id, "--json")
|
|
68
|
+
JSON.parse(output).map { |snapshot| snapshot.fetch("name") }
|
|
69
|
+
end
|
|
70
|
+
|
|
71
|
+
def restore_snapshot(machine_id, snapshot_name)
|
|
72
|
+
require_snapshot_support!
|
|
73
|
+
execute("snapshot", "restore", machine_id, "--snapshot", snapshot_name)
|
|
74
|
+
end
|
|
75
|
+
|
|
76
|
+
private
|
|
77
|
+
|
|
78
|
+
def network_option_arguments(options)
|
|
79
|
+
NETWORK_OPTION_FLAGS.flat_map do |key, flag|
|
|
80
|
+
option_argument(flag, options[key])
|
|
81
|
+
end + isolate_from_host_argument(options[:isolate_from_host])
|
|
82
|
+
end
|
|
83
|
+
|
|
84
|
+
def option_argument(flag, value)
|
|
85
|
+
return [] if value.nil? || value.to_s.empty?
|
|
86
|
+
|
|
87
|
+
[flag, value.to_s]
|
|
88
|
+
end
|
|
89
|
+
|
|
90
|
+
def isolate_from_host_argument(value)
|
|
91
|
+
return [] if value.nil?
|
|
92
|
+
|
|
93
|
+
["--isolate-from-host", value ? "true" : "false"]
|
|
94
|
+
end
|
|
95
|
+
|
|
96
|
+
def require_vlan_network_support!(method_name)
|
|
97
|
+
version = read_utm_version
|
|
98
|
+
return if Gem::Version.new(version) >= Gem::Version.new(VLAN_NETWORK_MIN_VERSION)
|
|
99
|
+
|
|
100
|
+
raise Errors::UtmInvalidVersion,
|
|
101
|
+
supported_versions: "#{VLAN_NETWORK_MIN_VERSION}+ " \
|
|
102
|
+
"(required for #{method_name})"
|
|
103
|
+
end
|
|
104
|
+
|
|
105
|
+
def require_snapshot_support!
|
|
106
|
+
return if Gem::Version.new(read_utm_version) >= Gem::Version.new(SNAPSHOT_MIN_VERSION)
|
|
107
|
+
|
|
108
|
+
snapshot_unsupported!
|
|
109
|
+
end
|
|
110
|
+
|
|
111
|
+
def read_utm_version
|
|
112
|
+
@read_utm_version ||= execute("version").strip
|
|
113
|
+
end
|
|
15
114
|
end
|
|
16
115
|
end
|
|
17
116
|
end
|
data/lib/vagrant_utm/errors.rb
CHANGED
|
@@ -52,26 +52,6 @@ module VagrantPlugins
|
|
|
52
52
|
class ForwardedPortInvalidProtocol < UtmError
|
|
53
53
|
error_key(:forwarded_port_invalid_protocol)
|
|
54
54
|
end
|
|
55
|
-
|
|
56
|
-
# This error is raised if the qemu-img is not detected.
|
|
57
|
-
class QemuImgRequired < UtmError
|
|
58
|
-
error_key(:qemu_img_required)
|
|
59
|
-
end
|
|
60
|
-
|
|
61
|
-
# This error is raised if the snapshot command failed.
|
|
62
|
-
class SnapShotCommandFailed < UtmError
|
|
63
|
-
error_key(:snapshot_command_failed)
|
|
64
|
-
end
|
|
65
|
-
|
|
66
|
-
# This error is raised if multiple VM files are found during snapshot.
|
|
67
|
-
class SnapShotMultipleVMFiles < UtmError
|
|
68
|
-
error_key(:snapshot_multiple_vm_files)
|
|
69
|
-
end
|
|
70
|
-
|
|
71
|
-
# This error is raised if the VM is not found.
|
|
72
|
-
class SnapShotVMFileNotFound < UtmError
|
|
73
|
-
error_key(:snapshot_vm_file_not_found)
|
|
74
|
-
end
|
|
75
55
|
end
|
|
76
56
|
end
|
|
77
57
|
end
|
|
@@ -0,0 +1,86 @@
|
|
|
1
|
+
---
|
|
2
|
+
-- update_network_interface.applescript
|
|
3
|
+
-- Update VLAN / DHCP settings on a UTM network interface (UTM 5.0.4+).
|
|
4
|
+
--
|
|
5
|
+
-- Usage:
|
|
6
|
+
-- osascript update_network_interface.applescript <VM_UUID> --index <N> [options]
|
|
7
|
+
--
|
|
8
|
+
-- Options (all optional; omitted values are left unchanged):
|
|
9
|
+
-- --vlan-guest-address <CIDR> e.g. 192.168.222.0/24
|
|
10
|
+
-- --vlan-guest-address-ipv6 <prefix> e.g. fec0::/64
|
|
11
|
+
-- --vlan-dhcp-start-address <IPv4>
|
|
12
|
+
-- --vlan-dhcp-end-address <IPv4>
|
|
13
|
+
-- --isolate-from-host <true|false>
|
|
14
|
+
--
|
|
15
|
+
-- These properties apply to shared/host network modes (see UTM #7710 / #3294).
|
|
16
|
+
|
|
17
|
+
on run argv
|
|
18
|
+
set vmID to item 1 of argv
|
|
19
|
+
set nicIndex to missing value
|
|
20
|
+
set vlanGuestAddress to missing value
|
|
21
|
+
set vlanGuestAddressIpv6 to missing value
|
|
22
|
+
set vlanDhcpStartAddress to missing value
|
|
23
|
+
set vlanDhcpEndAddress to missing value
|
|
24
|
+
set isolateFromHost to missing value
|
|
25
|
+
|
|
26
|
+
repeat with i from 2 to (count of argv)
|
|
27
|
+
set currentArg to item i of argv
|
|
28
|
+
if currentArg is "--index" then
|
|
29
|
+
set nicIndex to item (i + 1) of argv as integer
|
|
30
|
+
else if currentArg is "--vlan-guest-address" then
|
|
31
|
+
set vlanGuestAddress to item (i + 1) of argv
|
|
32
|
+
else if currentArg is "--vlan-guest-address-ipv6" then
|
|
33
|
+
set vlanGuestAddressIpv6 to item (i + 1) of argv
|
|
34
|
+
else if currentArg is "--vlan-dhcp-start-address" then
|
|
35
|
+
set vlanDhcpStartAddress to item (i + 1) of argv
|
|
36
|
+
else if currentArg is "--vlan-dhcp-end-address" then
|
|
37
|
+
set vlanDhcpEndAddress to item (i + 1) of argv
|
|
38
|
+
else if currentArg is "--isolate-from-host" then
|
|
39
|
+
set isolateArg to item (i + 1) of argv
|
|
40
|
+
if isolateArg is "true" or isolateArg is "yes" or isolateArg is "1" then
|
|
41
|
+
set isolateFromHost to true
|
|
42
|
+
else
|
|
43
|
+
set isolateFromHost to false
|
|
44
|
+
end if
|
|
45
|
+
end if
|
|
46
|
+
end repeat
|
|
47
|
+
|
|
48
|
+
if nicIndex is missing value then
|
|
49
|
+
error "Missing required --index <nicIndex>"
|
|
50
|
+
end if
|
|
51
|
+
|
|
52
|
+
tell application "UTM"
|
|
53
|
+
set vm to virtual machine id vmID
|
|
54
|
+
set config to configuration of vm
|
|
55
|
+
set networkInterfaces to network interfaces of config
|
|
56
|
+
set updated to false
|
|
57
|
+
|
|
58
|
+
repeat with anInterface in networkInterfaces
|
|
59
|
+
if nicIndex is index of anInterface then
|
|
60
|
+
if vlanGuestAddress is not missing value then
|
|
61
|
+
set vlan guest address of anInterface to vlanGuestAddress
|
|
62
|
+
end if
|
|
63
|
+
if vlanGuestAddressIpv6 is not missing value then
|
|
64
|
+
set vlan guest address ipv6 of anInterface to vlanGuestAddressIpv6
|
|
65
|
+
end if
|
|
66
|
+
if vlanDhcpStartAddress is not missing value then
|
|
67
|
+
set vlan dhcp start address of anInterface to vlanDhcpStartAddress
|
|
68
|
+
end if
|
|
69
|
+
if vlanDhcpEndAddress is not missing value then
|
|
70
|
+
set vlan dhcp end address of anInterface to vlanDhcpEndAddress
|
|
71
|
+
end if
|
|
72
|
+
if isolateFromHost is not missing value then
|
|
73
|
+
set isolate from host of anInterface to isolateFromHost
|
|
74
|
+
end if
|
|
75
|
+
set updated to true
|
|
76
|
+
end if
|
|
77
|
+
end repeat
|
|
78
|
+
|
|
79
|
+
if updated is false then
|
|
80
|
+
error "Network interface index " & nicIndex & " not found"
|
|
81
|
+
end if
|
|
82
|
+
|
|
83
|
+
-- VM must be stopped
|
|
84
|
+
update configuration of vm with config
|
|
85
|
+
end tell
|
|
86
|
+
end run
|
data/lib/vagrant_utm/version.rb
CHANGED
data/locales/en.yml
CHANGED
|
@@ -32,27 +32,6 @@ en:
|
|
|
32
32
|
The virtual machine is not running.
|
|
33
33
|
macos_required: |-
|
|
34
34
|
MacOS is required to run this provider
|
|
35
|
-
qemu_img_required: |-
|
|
36
|
-
qemu-img is required to use snapshot feature.
|
|
37
|
-
You can install qemu-img using `brew install qemu`.
|
|
38
|
-
snapshot_command_failed: |-
|
|
39
|
-
There was an error while executing `qemu-img`, a CLI used by vagrant-utm
|
|
40
|
-
for managing UTM snapshots. qemu-img only supports offline operations, so
|
|
41
|
-
the VM must be stopped before any snapshot operation.
|
|
42
|
-
The error is shown below.
|
|
43
|
-
|
|
44
|
-
Error: %{stderr}
|
|
45
|
-
snapshot_multiple_vm_files: |-
|
|
46
|
-
Multiple VM files detected. vagrant-utm which uses qemu-img does not support
|
|
47
|
-
snapshot feature when multiple VM files are present.
|
|
48
|
-
|
|
49
|
-
Directory checked: %{directory}
|
|
50
|
-
Files found: %{files}
|
|
51
|
-
snapshot_vm_file_not_found: |-
|
|
52
|
-
VM file not detected. vagrant-utm checks for single qcow2 file named in
|
|
53
|
-
UUID format in VM's data directory.
|
|
54
|
-
|
|
55
|
-
Directory checked: %{directory}
|
|
56
35
|
utm_import_failed: |-
|
|
57
36
|
UTM virtual machine import failed.
|
|
58
37
|
utmctl_error: |-
|
data/notes/README.md
CHANGED
|
@@ -16,20 +16,34 @@ cd docs
|
|
|
16
16
|
bundle exec jekyll serve
|
|
17
17
|
```
|
|
18
18
|
|
|
19
|
-
To release
|
|
19
|
+
To release
|
|
20
20
|
|
|
21
|
-
|
|
22
|
-
|
|
21
|
+
Publishing is done by GitHub Actions. Pushing a tag matching "v*" triggers `.github/workflows/gem.yml`,
|
|
22
|
+
which builds the gem once and then publishes it to GitHub Packages and rubygems.org, and creates the
|
|
23
|
+
GitHub release with the `.gem` attached.
|
|
23
24
|
|
|
24
|
-
|
|
25
|
-
|
|
25
|
+
So locally we only bump the version and push the tag.
|
|
26
|
+
|
|
27
|
+
1. Update
|
|
28
|
+
CHANGELOG.md (move the `[Unreleased]` entries under a new `[x.y.z] - YYYY-MM-DD` heading)
|
|
26
29
|
version number in `version.rb`
|
|
27
|
-
version number
|
|
28
|
-
2. Commit
|
|
29
|
-
3. Run `bundle exec rake release`
|
|
30
|
-
|
|
30
|
+
version number in `Gemfile.lock` (the `vagrant_utm (x.y.z)` line under `PATH`)
|
|
31
|
+
2. Commit
|
|
32
|
+
3. Run `bundle exec rake release:guard_clean release:source_control_push`
|
|
33
|
+
(checks the tree is clean, creates the annotated tag, pushes the commit and the tag)
|
|
34
|
+
4. Watch the run: `gh run watch $(gh run list --limit 1 --json databaseId --jq '.[0].databaseId')`
|
|
35
|
+
|
|
36
|
+
Do not run plain `bundle exec rake release`. It appends `release:rubygem_push`, which publishes the gem
|
|
37
|
+
from your machine and duplicates what GHA already does — the old workaround was to cancel that push by
|
|
38
|
+
hand, which is a race you can lose. Running the two subtasks above is the same flow without the race.
|
|
39
|
+
|
|
40
|
+
After the run, confirm the gem actually shipped what you expect:
|
|
31
41
|
|
|
32
|
-
|
|
42
|
+
```bash
|
|
43
|
+
gem unpack vagrant_utm-x.y.z.gem
|
|
44
|
+
# every shipped applescript should be ASCII; non-ASCII bytes broke 0.1.5 (see #50)
|
|
45
|
+
file vagrant_utm-x.y.z/lib/vagrant_utm/scripts/*.applescript
|
|
46
|
+
```
|
|
33
47
|
|
|
34
48
|
|
|
35
49
|
To update specific gems in the project
|
|
@@ -48,3 +62,15 @@ Unable to resolve dependency: user requested 'vagrant_utm (= 0.1.1)'
|
|
|
48
62
|
|
|
49
63
|
Due to mismatch versions between global installed version and plugin version in the development setup, since they are same name.
|
|
50
64
|
Fix: Uninstall the global version, while using different version of development setup
|
|
65
|
+
|
|
66
|
+
If `bundle install` fails building grpc
|
|
67
|
+
|
|
68
|
+
```
|
|
69
|
+
third_party/zlib/zutil.h:147: #define fdopen(fd,mode) NULL
|
|
70
|
+
_stdio.h:320: error: expected identifier or '('
|
|
71
|
+
```
|
|
72
|
+
|
|
73
|
+
grpc 1.56.2 (pulled in by the pinned vagrant 2.4.1) vendors a zlib that defines `fdopen` to `NULL` on
|
|
74
|
+
macOS, which newer Xcode clang rejects. CI is unaffected because Linux uses a precompiled grpc, so the
|
|
75
|
+
test suite still runs there. Until the vagrant pin moves, `rake` also works without `bundle exec`, which
|
|
76
|
+
is enough to run the release subtasks above.
|
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.
|
|
4
|
+
version: 0.2.0
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Naveenraj M
|
|
8
8
|
autorequire:
|
|
9
9
|
bindir: exe
|
|
10
10
|
cert_chain: []
|
|
11
|
-
date: 2026-
|
|
11
|
+
date: 2026-10-14 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:
|
|
@@ -57,7 +57,6 @@ files:
|
|
|
57
57
|
- lib/vagrant_utm/action/check_accessible.rb
|
|
58
58
|
- lib/vagrant_utm/action/check_created.rb
|
|
59
59
|
- lib/vagrant_utm/action/check_guest_additions.rb
|
|
60
|
-
- lib/vagrant_utm/action/check_qemu_img.rb
|
|
61
60
|
- lib/vagrant_utm/action/check_running.rb
|
|
62
61
|
- lib/vagrant_utm/action/check_utm.rb
|
|
63
62
|
- lib/vagrant_utm/action/clear_forwarded_ports.rb
|
|
@@ -126,6 +125,7 @@ files:
|
|
|
126
125
|
- lib/vagrant_utm/scripts/read_shared_folders_args.js
|
|
127
126
|
- lib/vagrant_utm/scripts/remove_qemu_additional_args.applescript
|
|
128
127
|
- lib/vagrant_utm/scripts/set_mac_address.applescript
|
|
128
|
+
- lib/vagrant_utm/scripts/update_network_interface.applescript
|
|
129
129
|
- lib/vagrant_utm/synced_folder.rb
|
|
130
130
|
- lib/vagrant_utm/util/compile_forwarded_ports.rb
|
|
131
131
|
- lib/vagrant_utm/util/unix_mount_helpers.rb
|
|
@@ -1,21 +0,0 @@
|
|
|
1
|
-
# frozen_string_literal: true
|
|
2
|
-
|
|
3
|
-
module VagrantPlugins
|
|
4
|
-
module Utm
|
|
5
|
-
module Action
|
|
6
|
-
# This action checks if qemu-img is installed.
|
|
7
|
-
class CheckQemuImg
|
|
8
|
-
def initialize(app, _env)
|
|
9
|
-
@app = app
|
|
10
|
-
end
|
|
11
|
-
|
|
12
|
-
def call(env)
|
|
13
|
-
qemu_img_present = Vagrant::Util::Which.which("qemu-img")
|
|
14
|
-
raise Errors::QemuImgRequired unless qemu_img_present
|
|
15
|
-
|
|
16
|
-
@app.call(env)
|
|
17
|
-
end
|
|
18
|
-
end
|
|
19
|
-
end
|
|
20
|
-
end
|
|
21
|
-
end
|