vagrant-qemu 0.3.11 → 0.3.12

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: 65b2cb386bb53bca93a879047e5b6a61ac690fd63a55e785b719b2b5379fb678
4
- data.tar.gz: b3b4b879c90d4b7df411019f6fe8c80ea572f4751887444fc8e9e041e634ea38
3
+ metadata.gz: 22e76d0b973e4e459a0780c79265d30b6cd0b48d4e94d28fdc82ef9cccfca37f
4
+ data.tar.gz: '049fb94522b7197b4d77975da222b033755761d0db699d90c6a98cb1fe49cd33'
5
5
  SHA512:
6
- metadata.gz: e825fc1bee4029c89a1a0acc9af2b4a2ee1f646976ac64234ef19b57078a43dd32a7330aee2c1da7b63582a3f1358fbe17e0e632e1a5337d9387be5d810ab551
7
- data.tar.gz: c989f426b5232f93ca87a5f4564e36c32f42b906ff8dbe3e11f671312535993b85ac888f3a1d823f7cbb4e2c1308c733e66d33e08032a0fe2c16819bd218e5fd
6
+ metadata.gz: '06901f39eac546967a57ca981739ca160caae09ec28ae9ade2c809bae6862bdeaf61ec8ac8f8cea6fbaba37146323ca08f1bb60bab53433381ac5619bf9f3517'
7
+ data.tar.gz: c815fe0029b54a7e092543fddbb5769add49393ef5fdd4e84584b8c893a164f88e1d56aebe5251b891dac7bee4a13037366988e22abdbb3189f96b979f338680
data/CHANGELOG.md CHANGED
@@ -93,3 +93,10 @@
93
93
  # 0.3.11 (2025-05-06)
94
94
 
95
95
  * Re-publish with repacked gem
96
+
97
+ # 0.3.22 (2025-05-19)
98
+
99
+ * Add support for extra `-drive` arguments
100
+ * Add `extra_image_opts` to customize image creation
101
+ * Add support for cloud-init and disks
102
+ * Add support for resizing disk on vm setup
data/README.md CHANGED
@@ -37,6 +37,8 @@ Others:
37
37
  * Synced folder support via SMB
38
38
  * Basic operation: up, ssh, halt, destroy
39
39
  * Basic suport to forwarded ports, see [vagrant doc](https://www.vagrantup.com/docs/networking/forwarded_ports) for details
40
+ * Support Cloud-init, see [vagrant doc](https://developer.hashicorp.com/vagrant/docs/cloud-init/usage) for details
41
+ * Support Disks, see [vagrant doc](https://developer.hashicorp.com/vagrant/docs/disks/usage) for details
40
42
 
41
43
  ## Usage
42
44
 
@@ -84,6 +86,7 @@ This provider exposes a few provider-specific configuration options:
84
86
  * `cpu` - The cpu model of VM, default: `cortex-a72`
85
87
  * `smp` - The smp setting (Simulate an SMP system with n CPUs) of VM, default: `2`
86
88
  * `memory` - The memory setting of VM, default: `4G`
89
+ * `disk_resize` - The target disk size of the primary disk, requires resizing of filesystem inside of VM, default: `nil`.
87
90
  * debug/expert
88
91
  * `ssh_host` - The SSH IP used to access VM, default: `127.0.0.1`
89
92
  * `ssh_auto_correct` - Auto correct port collisions for ssh port, default: `false`
@@ -94,11 +97,13 @@ This provider exposes a few provider-specific configuration options:
94
97
  * `qemu_dir` - The path to QEMU's install dir, default: `/opt/homebrew/share/qemu`
95
98
  * `extra_qemu_args` - The raw list of additional arguments to pass to QEMU. Use with extreme caution. (see "Force Multicore" below as example)
96
99
  * `extra_netdev_args` - extra, comma-separated arguments to pass to the -netdev parameter. Use with caution. (see "Force Local IP" below as example)
100
+ * `extra_drive_args` - Add optional extra arguments to each drive attached, default: `[]`
97
101
  * `control_port` - The port number used to control vm from vagrant, default is nil value. (nil means use unix socket)
98
102
  * `debug_port` - The port number used to export serial port of the vm for debug, default is nil value. (nil means use unix socket, see "Debug" below for details)
99
103
  * `no_daemonize` - Disable the "daemonize" mode of QEMU, default is false. (see "Windows host" below as example)
100
104
  * `firmware_format` - The format of aarch64 firmware images (`edk2-aarch64-code.fd` and `edk2-arm-vars.fd`) loaded from `qemu_dir`, default: `raw`
101
105
  * `other_default` - The other default arguments used by this plugin, default: `%W(-parallel null -monitor none -display none -vga none)`
106
+ * `extra_image_opts` - Options passed via `-o` to `qemu-img` when the base qcow2 images are created, default: `[]`
102
107
 
103
108
  ### Usage
104
109
 
@@ -273,6 +278,32 @@ Thanks example from @Leandros.
273
278
 
274
279
  See [pr#73](https://github.com/ppggff/vagrant-qemu/pull/73) for details.
275
280
 
281
+ 11. Improved VM I/O performance
282
+
283
+ When creating the disks that are attached, each disk is an id assign in order
284
+ they appear in the `Vagrantfile`. The primary disk has the `id` of `disk0`.
285
+
286
+ ```ruby
287
+ Vagrant.configure("2") do |config|
288
+ # ... other stuff
289
+
290
+ config.vm.provider "qemu" do |qe|
291
+ # Use a `none` drive interface.
292
+ qe.drive_interface = "none"
293
+ qe.extra_drive_args = "cache=none,aio=threads"
294
+
295
+ # To improve I/O performance, create a separate I/O thread.
296
+ # We refer to the primary disk as `disk0`.
297
+ qe.extra_qemu_args = %w(
298
+ -object iothread,id=io1
299
+ -device virtio-blk-pci,drive=disk0,iothread=io1
300
+ )
301
+ end
302
+ end
303
+ ```
304
+
305
+ See the [QEMU Documentation](https://www.qemu.org/docs/master/devel/multiple-iothreads.html) and [heiko-sieger.info/tuning-vm-disk-performance/](https://www.heiko-sieger.info/tuning-vm-disk-performance/) for more details.
306
+
276
307
  ## Debug
277
308
 
278
309
  Serial port is exported to unix socket: `<user_home>/.vagrant.d/tmp/vagrant-qemu/<id>/qemu_socket_serial`, or `debug_port`.
@@ -75,7 +75,9 @@ module VagrantPlugins
75
75
  :image_path => image_path,
76
76
  :qemu_dir => qemu_dir,
77
77
  :arch => env[:machine].provider_config.arch,
78
- :firmware_format => env[:machine].provider_config.firmware_format
78
+ :firmware_format => env[:machine].provider_config.firmware_format,
79
+ :extra_image_opts => env[:machine].provider_config.extra_image_opts,
80
+ :disk_resize => env[:machine].provider_config.disk_resize,
79
81
  }
80
82
 
81
83
  env[:ui].detail("Creating and registering the VM...")
@@ -25,12 +25,14 @@ module VagrantPlugins
25
25
  :qemu_bin => env[:machine].provider_config.qemu_bin,
26
26
  :extra_qemu_args => env[:machine].provider_config.extra_qemu_args,
27
27
  :extra_netdev_args => env[:machine].provider_config.extra_netdev_args,
28
+ :extra_drive_args => env[:machine].provider_config.extra_drive_args,
28
29
  :ports => fwPorts,
29
30
  :control_port => env[:machine].provider_config.control_port,
30
31
  :debug_port => env[:machine].provider_config.debug_port,
31
32
  :no_daemonize => env[:machine].provider_config.no_daemonize,
32
33
  :firmware_format => env[:machine].provider_config.firmware_format,
33
- :other_default => env[:machine].provider_config.other_default
34
+ :other_default => env[:machine].provider_config.other_default,
35
+ :extra_image_opts => env[:machine].provider_config.extra_image_opts,
34
36
  }
35
37
 
36
38
  env[:ui].output(I18n.t("vagrant_qemu.starting"))
@@ -115,6 +115,9 @@ module VagrantPlugins
115
115
  next
116
116
  end
117
117
 
118
+ b1.use CloudInitSetup
119
+ b1.use CleanupDisks
120
+ b1.use Disk
118
121
  b1.use Provision
119
122
  b1.use EnvSet, port_collision_repair: true
120
123
  b1.use PrepareForwardedPortCollisionParams
@@ -0,0 +1,104 @@
1
+ require "log4r"
2
+
3
+ module VagrantPlugins
4
+ module QEMU
5
+ module Cap
6
+ module Disk
7
+ @@logger = Log4r::Logger.new("vagrant_qemu::cap::disk")
8
+
9
+ DEFAULT_DISK_EXT_LIST = ["qcow2", "iso"].map(&:freeze).freeze
10
+ DEFAULT_DISK_EXT = "qcow2".freeze
11
+
12
+ # @param [Vagrant::Machine] machine
13
+ # @return [String]
14
+ def self.set_default_disk_ext(machine)
15
+ DEFAULT_DISK_EXT
16
+ end
17
+
18
+ # @param [Vagrant::Machine] machine
19
+ # @return [Array]
20
+ def self.default_disk_exts(machine)
21
+ DEFAULT_DISK_EXT_LIST
22
+ end
23
+
24
+ # @param [Vagrant::Machine] machine
25
+ # @param [String] disk_ext
26
+ # @return [Bool]
27
+ def self.validate_disk_ext(machine, disk_ext)
28
+ DEFAULT_DISK_EXT_LIST.include?(disk_ext)
29
+ end
30
+
31
+ # @param [Vagrant::Machine] machine
32
+ # @param [VagrantPlugins::Kernel_V2::VagrantConfigDisk] defined_disks
33
+ # @return [Hash] configured_disks - A hash of all the current configured disks
34
+ def self.configure_disks(machine, defined_disks)
35
+ return {} if defined_disks.empty?
36
+
37
+ configured_disks = {disk: [], floppy: [], dvd: []}
38
+ defined_disks.each do |disk|
39
+ @@logger.info("Disk: #{disk.to_yaml}")
40
+ case disk.type
41
+ when :disk
42
+ disk_data = setup_disk(machine, disk)
43
+ if !disk_data.empty?
44
+ configured_disks[:disk] << disk_data
45
+ machine.provider.driver.attach_disk(disk_data)
46
+ end
47
+ when :floppy
48
+ machine.ui.info(I18n.t("vagrant_qemu.errors.floppy_unsupported"))
49
+ when :dvd
50
+ disk_data = setup_dvd(machine, disk)
51
+ if !disk_data.empty?
52
+ configured_disks[:dvd] << disk_data
53
+ machine.provider.driver.attach_dvd(disk_data)
54
+ end
55
+ else
56
+ @@logger.info("unsupported disk type: #{disk.type}")
57
+ end
58
+ end
59
+
60
+ configured_disks
61
+ end
62
+
63
+ # @param [Vagrant::Machine] machine
64
+ # @param [VagrantPlugins::Kernel_V2::VagrantConfigDisk] defined_disks
65
+ # @param [Hash] disk_meta - A hash of all the previously defined disks
66
+ # from the last configure_disk action
67
+ # @return [nil]
68
+ def self.cleanup_disks(machine, defined_disks, disk_meta)
69
+ return if disk_meta.values.flatten.empty?
70
+ end
71
+
72
+ protected
73
+
74
+ # Sets up all disk configs of type `:disk`
75
+ #
76
+ # @param [Vagrant::Machine] machine - the current machine
77
+ # @param [Config::Disk] disk - the current disk to configure
78
+ # @return [Hash] - disk_metadata
79
+ def self.setup_disk(machine, disk)
80
+ disk_dir = machine.provider.driver.disk_dir
81
+ disk_path = disk_dir.join("#{disk.name}.#{disk.disk_ext}")
82
+ args = ["create", "-f", "qcow2"]
83
+
84
+ disk_provider_config = disk.provider_config[:qemu] if disk.provider_config
85
+ args.push(disk_path.to_s)
86
+ args.push("#{disk.size}")
87
+ machine.provider.driver.execute("qemu-img", *args)
88
+
89
+ {UUID: disk.id, Name: disk.name, Path: disk_path.to_s, primary: !!disk.primary}
90
+ end
91
+
92
+ # Sets up all disk configs of type `:dvd`
93
+ #
94
+ # @param [Vagrant::Machine] machine - the current machine
95
+ # @param [Config::Disk] disk - the current disk to configure
96
+ # @return [Hash] - disk_metadata
97
+ def self.setup_dvd(machine, disk)
98
+ {UUID: disk.id, Name: disk.name, Path: disk.file, primary: !!disk.primary}
99
+ end
100
+
101
+ end
102
+ end
103
+ end
104
+ end
@@ -0,0 +1,8 @@
1
+
2
+ module VagrantPlugins
3
+ module QEMU
4
+ module Cap
5
+ autoload :Disk, "vagrant-qemu/cap/disk"
6
+ end
7
+ end
8
+ end
@@ -16,13 +16,16 @@ module VagrantPlugins
16
16
  attr_accessor :image_path
17
17
  attr_accessor :qemu_bin
18
18
  attr_accessor :qemu_dir
19
+ attr_accessor :disk_resize
19
20
  attr_accessor :extra_qemu_args
20
21
  attr_accessor :extra_netdev_args
22
+ attr_accessor :extra_drive_args
21
23
  attr_accessor :control_port
22
24
  attr_accessor :debug_port
23
25
  attr_accessor :no_daemonize
24
26
  attr_accessor :firmware_format
25
27
  attr_accessor :other_default
28
+ attr_accessor :extra_image_opts
26
29
 
27
30
  def initialize
28
31
  @ssh_host = UNSET_VALUE
@@ -38,13 +41,16 @@ module VagrantPlugins
38
41
  @image_path = UNSET_VALUE
39
42
  @qemu_bin = UNSET_VALUE
40
43
  @qemu_dir = UNSET_VALUE
44
+ @disk_resize = UNSET_VALUE
41
45
  @extra_qemu_args = UNSET_VALUE
42
46
  @extra_netdev_args = UNSET_VALUE
47
+ @extra_drive_args = UNSET_VALUE
43
48
  @control_port = UNSET_VALUE
44
49
  @debug_port = UNSET_VALUE
45
50
  @no_daemonize = UNSET_VALUE
46
51
  @firmware_format = UNSET_VALUE
47
52
  @other_default = UNSET_VALUE
53
+ @extra_image_opts = UNSET_VALUE
48
54
  end
49
55
 
50
56
  #-------------------------------------------------------------------
@@ -70,13 +76,16 @@ module VagrantPlugins
70
76
  @image_path = nil if @image_path == UNSET_VALUE
71
77
  @qemu_bin = nil if @qemu_bin == UNSET_VALUE
72
78
  @qemu_dir = "/opt/homebrew/share/qemu" if @qemu_dir == UNSET_VALUE
79
+ @disk_resize = nil if @disk_resize == UNSET_VALUE
73
80
  @extra_qemu_args = [] if @extra_qemu_args == UNSET_VALUE
74
81
  @extra_netdev_args = nil if @extra_netdev_args == UNSET_VALUE
82
+ @extra_drive_args = nil if @extra_drive_args == UNSET_VALUE
75
83
  @control_port = nil if @control_port == UNSET_VALUE
76
84
  @debug_port = nil if @debug_port == UNSET_VALUE
77
85
  @no_daemonize = false if @no_daemonize == UNSET_VALUE
78
86
  @firmware_format = "raw" if @firmware_format == UNSET_VALUE
79
87
  @other_default = %W(-parallel null -monitor none -display none -vga none) if @other_default == UNSET_VALUE
88
+ @extra_image_opts = nil if @extra_image_opts == UNSET_VALUE
80
89
 
81
90
  # TODO better error msg
82
91
  @ssh_port = Integer(@ssh_port)
@@ -1,3 +1,4 @@
1
+ require 'log4r'
1
2
  require 'childprocess'
2
3
  require 'securerandom'
3
4
  require 'yaml'
@@ -16,11 +17,14 @@ module VagrantPlugins
16
17
  attr_reader :vm_id
17
18
  attr_reader :data_dir
18
19
  attr_reader :tmp_dir
20
+ attr_reader :attached_drives
19
21
 
20
22
  def initialize(id, dir, tmp)
21
23
  @vm_id = id
22
24
  @data_dir = dir
23
25
  @tmp_dir = tmp.join("vagrant-qemu")
26
+ @attached_drives = {disk: [], floppy: [], dvd: []}
27
+ @logger = Log4r::Logger.new("vagrant_qemu::driver")
24
28
  end
25
29
 
26
30
  def get_current_state
@@ -112,9 +116,16 @@ module VagrantPlugins
112
116
  end
113
117
 
114
118
  # drive
119
+ diskid = 0
120
+ extra_drive_args = ""
121
+ if !options[:extra_drive_args].nil?
122
+ extra_drive_args = ",#{options[:extra_drive_args]}"
123
+ end
124
+
115
125
  if !options[:drive_interface].nil?
116
126
  image_path.each do |img|
117
- cmd += %W(-drive if=#{options[:drive_interface]},format=qcow2,file=#{img})
127
+ cmd += %W(-drive if=#{options[:drive_interface]},id=disk#{diskid},format=qcow2,file=#{img}#{extra_drive_args})
128
+ diskid += 1
118
129
  end
119
130
  end
120
131
  if options[:arch] == "aarch64" && !options[:firmware_format].nil?
@@ -124,6 +135,18 @@ module VagrantPlugins
124
135
  cmd += %W(-drive if=pflash,format=#{options[:firmware_format]},file=#{fm2_path})
125
136
  end
126
137
 
138
+ dvd_index = 1
139
+ @attached_drives[:dvd].each do |disk|
140
+ cmd += %W(-drive file=#{disk[:Path]},index=#{dvd_index},media=cdrom)
141
+ dvd_index += 1
142
+ end
143
+ if !options[:drive_interface].nil?
144
+ @attached_drives[:disk].each do |disk|
145
+ cmd += %W(-drive if=#{options[:drive_interface]},id=disk#{diskid},format=qcow2,file=#{disk[:Path]}#{extra_drive_args})
146
+ diskid += 1
147
+ end
148
+ end
149
+
127
150
  # control
128
151
  pid_file = id_tmp_dir.join("qemu.pid").to_s
129
152
  cmd += %W(-chardev socket,id=mon0,#{control_socket},server=on,wait=off)
@@ -197,7 +220,26 @@ module VagrantPlugins
197
220
  # Create image
198
221
  options[:image_path].each_with_index do |img, i|
199
222
  suffix_index = i > 0 ? "-#{i}" : ''
200
- execute("qemu-img", "create", "-f", "qcow2", "-F", "qcow2", "-b", img.to_s, id_dir.join("linked-box#{suffix_index}.img").to_s)
223
+
224
+ linked_image = id_dir.join("linked-box#{suffix_index}.img").to_s
225
+ args = ["create", "-f", "qcow2", "-F", "qcow2", "-b", img.to_s]
226
+
227
+ if !options[:extra_image_opts].nil?
228
+ options[:extra_image_opts].each do |opt|
229
+ args.push("-o")
230
+ args.push(opt)
231
+ end
232
+ end
233
+
234
+ args.push(linked_image)
235
+
236
+ if i == 0
237
+ if !options[:disk_resize].nil?
238
+ args.push(options[:disk_resize])
239
+ end
240
+ end
241
+
242
+ execute("qemu-img", *args)
201
243
  end
202
244
 
203
245
  server = {
@@ -309,6 +351,18 @@ module VagrantPlugins
309
351
  end
310
352
  end
311
353
  end
354
+
355
+ def attach_dvd(disk)
356
+ @attached_drives[:dvd] << disk
357
+ end
358
+
359
+ def attach_disk(disk)
360
+ @attached_drives[:disk] << disk
361
+ end
362
+
363
+ def disk_dir
364
+ @data_dir.join(@vm_id)
365
+ end
312
366
  end
313
367
  end
314
368
  end
@@ -24,6 +24,31 @@ module VagrantPlugins
24
24
  Config
25
25
  end
26
26
 
27
+ provider_capability(:qemu, :set_default_disk_ext) do
28
+ require File.expand_path("../cap/disk", __FILE__)
29
+ Cap::Disk
30
+ end
31
+
32
+ provider_capability(:qemu, :default_disk_exts) do
33
+ require File.expand_path("../cap/disk", __FILE__)
34
+ Cap::Disk
35
+ end
36
+
37
+ provider_capability(:qemu, :configure_disks) do
38
+ require File.expand_path("../cap/disk", __FILE__)
39
+ Cap::Disk
40
+ end
41
+
42
+ provider_capability(:qemu, :cleanup_disks) do
43
+ require File.expand_path("../cap/disk", __FILE__)
44
+ Cap::Disk
45
+ end
46
+
47
+ provider_capability(:qemu, :validate_disk_ext) do
48
+ require File.expand_path("../cap/disk", __FILE__)
49
+ Cap::Disk
50
+ end
51
+
27
52
  provider(:qemu, box_format: "libvirt", box_optional: true, parallel: true) do
28
53
  # Setup logging and i18n
29
54
  setup_logging
@@ -1,5 +1,5 @@
1
1
  module VagrantPlugins
2
2
  module QEMU
3
- VERSION = '0.3.11'
3
+ VERSION = '0.3.12'
4
4
  end
5
5
  end
data/lib/vagrant-qemu.rb CHANGED
@@ -6,6 +6,7 @@ module VagrantPlugins
6
6
  module QEMU
7
7
  lib_path = Pathname.new(File.expand_path("../vagrant-qemu", __FILE__))
8
8
  autoload :Action, lib_path.join("action")
9
+ autoload :Cap, lib_path.join("cap")
9
10
  autoload :Errors, lib_path.join("errors")
10
11
 
11
12
  # This returns the path to the source of this plugin.
data/locales/en.yml CHANGED
@@ -58,3 +58,5 @@ en:
58
58
  Invalid config.
59
59
 
60
60
  Error: %{err}
61
+ floppy_unsupported: |-
62
+ Floppy disks not supported
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: vagrant-qemu
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.3.11
4
+ version: 0.3.12
5
5
  platform: ruby
6
6
  authors:
7
7
  - ppggff
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2025-05-06 00:00:00.000000000 Z
11
+ date: 2025-05-20 00:00:00.000000000 Z
12
12
  dependencies: []
13
13
  description: Enables Vagrant to manage machines with QEMU.
14
14
  email: pgf00a@gmail.com
@@ -34,6 +34,8 @@ files:
34
34
  - lib/vagrant-qemu/action/start_instance.rb
35
35
  - lib/vagrant-qemu/action/stop_instance.rb
36
36
  - lib/vagrant-qemu/action/warn_networks.rb
37
+ - lib/vagrant-qemu/cap.rb
38
+ - lib/vagrant-qemu/cap/disk.rb
37
39
  - lib/vagrant-qemu/config.rb
38
40
  - lib/vagrant-qemu/driver.rb
39
41
  - lib/vagrant-qemu/errors.rb