vagrant-ovirt4 1.1.0 → 2.0.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.
Files changed (37) hide show
  1. checksums.yaml +5 -5
  2. data/.github/FUNDING.yml +3 -0
  3. data/.github/workflows/release.yml +20 -0
  4. data/.gitignore +2 -0
  5. data/Dockerfile +11 -0
  6. data/Gemfile +5 -11
  7. data/Gemfile.lock +31 -37
  8. data/README.md +26 -12
  9. data/Rakefile +1 -7
  10. data/lib/vagrant-ovirt4/action.rb +29 -9
  11. data/lib/vagrant-ovirt4/action/connect_ovirt.rb +1 -0
  12. data/lib/vagrant-ovirt4/action/create_network_interfaces.rb +62 -26
  13. data/lib/vagrant-ovirt4/action/create_vm.rb +98 -14
  14. data/lib/vagrant-ovirt4/action/destroy_vm.rb +14 -1
  15. data/lib/vagrant-ovirt4/action/disconnect_ovirt.rb +25 -0
  16. data/lib/vagrant-ovirt4/action/halt_vm.rb +11 -0
  17. data/lib/vagrant-ovirt4/action/read_ssh_info.rb +6 -1
  18. data/lib/vagrant-ovirt4/action/read_state.rb +7 -1
  19. data/lib/vagrant-ovirt4/action/resize_disk.rb +18 -17
  20. data/lib/vagrant-ovirt4/action/start_vm.rb +76 -34
  21. data/lib/vagrant-ovirt4/action/wait_til_suspended.rb +1 -1
  22. data/lib/vagrant-ovirt4/action/wait_till_down.rb +13 -2
  23. data/lib/vagrant-ovirt4/action/wait_till_up.rb +35 -6
  24. data/lib/vagrant-ovirt4/config.rb +81 -1
  25. data/lib/vagrant-ovirt4/errors.rb +20 -0
  26. data/lib/vagrant-ovirt4/plugin.rb +3 -3
  27. data/lib/vagrant-ovirt4/version.rb +1 -1
  28. data/locales/en.yml +17 -1
  29. data/spec/vagrant-ovirt4/config_spec.rb +53 -3
  30. data/templates/Vagrantfile.erb +199 -0
  31. data/tools/prepare_redhat_for_box.sh +18 -2
  32. data/vagrant-ovirt4.gemspec +3 -1
  33. metadata +35 -13
  34. data/docker-compose.yml +0 -9
  35. data/lib/vagrant-ovirt4/action/sync_folders.rb +0 -69
  36. data/lib/vagrant-ovirt4/cap/nic_mac_addresses.rb +0 -15
  37. data/test.rb +0 -3
@@ -20,16 +20,24 @@ module VagrantPlugins
20
20
  hostname = 'vagrant' if hostname.nil?
21
21
 
22
22
  # Output the settings we're going to use to the user
23
- memory_size = config.memory_size*1024*1024
24
- memory_guaranteed = config.memory_guaranteed*1024*1024
25
23
  env[:ui].info(I18n.t("vagrant_ovirt4.creating_vm"))
26
24
  env[:ui].info(" -- Name: #{hostname}")
27
25
  env[:ui].info(" -- Cluster: #{config.cluster}")
28
26
  env[:ui].info(" -- Template: #{config.template}")
29
27
  env[:ui].info(" -- Console Type: #{config.console}")
28
+ env[:ui].info(" -- BIOS Serial: #{config.bios_serial}")
29
+ env[:ui].info(" -- Optimized For: #{config.optimized_for}")
30
+ env[:ui].info(" -- Description: #{config.description}")
31
+ env[:ui].info(" -- Comment: #{config.comment}")
32
+ env[:ui].info(" -- Disk: #{Filesize.from("#{config.disk_size} B").to_f('GiB').to_i} GiB") unless config.disk_size.nil?
33
+ env[:ui].info(" -- Additional Disks:") unless config.disks.empty?
34
+ config.disks.each do |disk|
35
+ env[:ui].info(" ---- name=#{disk[:name]} size=#{Filesize.from("#{disk[:size]} B").to_f('GiB').to_i} GiB")
36
+ end
30
37
  env[:ui].info(" -- Memory: ")
31
- env[:ui].info(" ---- Memory: #{config.memory_size}")
32
- env[:ui].info(" ---- Guaranteed: #{config.memory_guaranteed}")
38
+ env[:ui].info(" ---- Memory: #{Filesize.from("#{config.memory_size} B").to_f('MiB').to_i} MiB")
39
+ env[:ui].info(" ---- Maximum: #{Filesize.from("#{config.memory_maximum} B").to_f('MiB').to_i} MiB")
40
+ env[:ui].info(" ---- Guaranteed: #{Filesize.from("#{config.memory_guaranteed} B").to_f('MiB').to_i} MiB")
33
41
  env[:ui].info(" -- Cpu: ")
34
42
  env[:ui].info(" ---- Cores: #{config.cpu_cores}")
35
43
  env[:ui].info(" ---- Sockets: #{config.cpu_sockets}")
@@ -39,6 +47,8 @@ module VagrantPlugins
39
47
  # Create oVirt VM.
40
48
  attr = {
41
49
  :name => hostname,
50
+ :description => config.description,
51
+ :comment => config.comment,
42
52
  :cpu => {
43
53
  :architecture => 'x86_64',
44
54
  :topology => {
@@ -47,11 +57,12 @@ module VagrantPlugins
47
57
  :threads => config.cpu_threads,
48
58
  },
49
59
  },
50
- :memory => memory_size,
51
- :memory_policy => {
52
- :ballooning => true,
53
- :guaranteed => memory_guaranteed,
54
- },
60
+ :memory_policy => OvirtSDK4::MemoryPolicy.new(
61
+ ballooning: true,
62
+ guaranteed: config.memory_guaranteed,
63
+ max: config.memory_maximum,
64
+ ),
65
+ :memory => config.memory_size,
55
66
  :cluster => {
56
67
  :name => config.cluster,
57
68
  },
@@ -61,14 +72,21 @@ module VagrantPlugins
61
72
  :display => {
62
73
  :type => config.console,
63
74
  },
75
+ :type => config.optimized_for,
64
76
  }
65
77
 
66
78
  begin
67
- server = env[:vms_service].add(attr)
79
+ server = env[:vms_service].add(attr)
68
80
  rescue OvirtSDK4::Error => e
69
81
  fault_message = /Fault detail is \"\[?(.+?)\]?\".*/.match(e.message)[1] rescue e.message
70
- raise Errors::CreateVMError,
71
- :error_message => fault_message
82
+ retry if e.message =~ /Related operation is currently in progress/
83
+
84
+ if config.debug
85
+ raise e
86
+ else
87
+ raise Errors::CreateVMError,
88
+ :error_message => fault_message
89
+ end
72
90
  end
73
91
 
74
92
  # Immediately save the ID since it is created at this point.
@@ -77,17 +95,21 @@ module VagrantPlugins
77
95
  # Wait till all volumes are ready.
78
96
  env[:ui].info(I18n.t("vagrant_ovirt4.wait_for_ready_vm"))
79
97
  for i in 0..300
80
- ready = true
98
+ disk_ready = true
81
99
  vm_service = env[:vms_service].vm_service(env[:machine].id)
82
100
  disk_attachments_service = vm_service.disk_attachments_service
83
101
  disk_attachments = disk_attachments_service.list
84
102
  disk_attachments.each do |disk_attachment|
85
103
  disk = env[:connection].follow_link(disk_attachment.disk)
104
+ if config.debug
105
+ env[:ui].info("Checking disk status id=#{disk.id} name=#{disk.name} status=#{disk.status}")
106
+ end
86
107
  if disk.status != 'ok'
87
- ready = false
108
+ disk_ready = false
88
109
  break
89
110
  end
90
111
  end
112
+ ready = (disk_ready and env[:vms_service].vm_service(server.id).get.status.to_sym == :down)
91
113
  break if ready
92
114
  sleep 2
93
115
  end
@@ -96,6 +118,67 @@ module VagrantPlugins
96
118
  raise Errors::WaitForReadyVmTimeout
97
119
  end
98
120
 
121
+ # add storage disks
122
+ vm_service = env[:vms_service].vm_service(env[:machine].id)
123
+ disk_attachments_service = vm_service.disk_attachments_service
124
+ storage_disks = []
125
+ config.disks.each do |disk|
126
+ disk_attachment = disk_attachments_service.add(
127
+ OvirtSDK4::DiskAttachment.new(
128
+ disk: {
129
+ name: disk[:name],
130
+ description: '#{hostname} storage disk',
131
+ format: disk[:type] == 'qcow2' ? OvirtSDK4::DiskFormat::COW : OvirtSDK4::DiskFormat::RAW,
132
+ provisioned_size: disk[:size],
133
+ storage_domains: [{
134
+ name: disk[:storage_domain]
135
+ }]
136
+ },
137
+ interface: disk[:bus] == 'virtio' ? OvirtSDK4::DiskInterface::VIRTIO : OvirtSDK4::DiskInterface::IDE,
138
+ bootable: false,
139
+ active: true
140
+ )
141
+ )
142
+ storage_disks << disk_attachment
143
+ env[:ui].info("Added storage disk id=#{disk_attachment.disk.id} name=#{disk[:name]} size=#{disk[:size]}")
144
+ end
145
+
146
+ disks_service = env[:connection].system_service.disks_service
147
+ storage_disks.each do |s_disk|
148
+ disk_service = disks_service.disk_service(s_disk.disk.id)
149
+ loop do
150
+ sleep(5)
151
+ disk = disk_service.get
152
+ if config.debug
153
+ env[:ui].info("Checking disk status id=#{disk.id} name=#{disk.name} status=#{disk.status}")
154
+ end
155
+ break if disk.status == OvirtSDK4::DiskStatus::OK
156
+ end
157
+ end
158
+
159
+ begin
160
+ if config.bios_serial
161
+ vm_service = env[:vms_service].vm_service(env[:machine].id)
162
+ vm_service.update(
163
+ serial_number: {
164
+ policy: OvirtSDK4::SerialNumberPolicy::CUSTOM,
165
+ value: config.bios_serial,
166
+ }
167
+ )
168
+ end
169
+ rescue OvirtSDK4::Error => e
170
+ fault_message = /Fault detail is \"\[?(.+?)\]?\".*/.match(e.message)[1] rescue e.message
171
+ retry if e.message =~ /Related operation is currently in progress/
172
+
173
+ if config.debug
174
+ raise e
175
+ else
176
+ raise Errors::UpdateBiosError,
177
+ :error_message => fault_message
178
+ end
179
+ end
180
+
181
+
99
182
  @app.call(env)
100
183
  end
101
184
 
@@ -109,6 +192,7 @@ module VagrantPlugins
109
192
  destroy_env[:config_validate] = false
110
193
  destroy_env[:force_confirm_destroy] = true
111
194
  env[:action_runner].run(Action.action_destroy, destroy_env)
195
+ env[:connection].close()
112
196
  end
113
197
  end
114
198
  end
@@ -14,7 +14,20 @@ module VagrantPlugins
14
14
  env[:ui].info(I18n.t("vagrant_ovirt4.destroy_vm"))
15
15
 
16
16
  vm_service = env[:vms_service].vm_service(env[:machine].id)
17
- vm_service.remove
17
+ begin
18
+ vm_service.remove
19
+ rescue OvirtSDK4::Error => e
20
+ fault_message = /Fault detail is \"\[?(.+?)\]?\".*/.match(e.message)[1] rescue e.message
21
+ retry if e.message =~ /Please try again/
22
+
23
+ if config.debug
24
+ raise e
25
+ else
26
+ raise Errors::RemoveVMError,
27
+ :error_message => fault_message
28
+ end
29
+ end
30
+
18
31
  env[:machine].id = nil
19
32
 
20
33
  @app.call(env)
@@ -0,0 +1,25 @@
1
+ require 'log4r'
2
+ require 'ovirtsdk4'
3
+
4
+ module VagrantPlugins
5
+ module OVirtProvider
6
+ module Action
7
+ class DisconnectOVirt
8
+ def initialize(app, env)
9
+ @logger = Log4r::Logger.new("vagrant_ovirt4::action::disconnect_ovirt")
10
+ @app = app
11
+ end
12
+
13
+ def call(env)
14
+
15
+ # Get config options for ovirt provider.
16
+ @logger.info("Disconnecting oVirt connection")
17
+ env[:connection].close()
18
+
19
+ @app.call(env)
20
+ end
21
+
22
+ end
23
+ end
24
+ end
25
+ end
@@ -12,6 +12,17 @@ module VagrantPlugins
12
12
  def call(env)
13
13
  env[:ui].info(I18n.t("vagrant_ovirt4.halt_vm"))
14
14
 
15
+ # Halt via OS capability
16
+ begin
17
+ if env[:machine].guest.capability?(:halt)
18
+ env[:machine].guest.capability(:halt)
19
+ # Give the VM a chance to shutdown gracefully..."
20
+ sleep 10
21
+ end
22
+ rescue
23
+ env[:ui].info("Failed to shutdown guest gracefully.")
24
+ end
25
+
15
26
  machine = env[:vms_service].vm_service(env[:machine].id)
16
27
  machine.stop rescue nil #todo dont rescue
17
28
 
@@ -36,7 +36,12 @@ module VagrantPlugins
36
36
 
37
37
  nics_service = server.nics_service
38
38
  nics = nics_service.list
39
- ip_addr = nics.collect { |nic_attachment| env[:connection].follow_link(nic_attachment).reported_devices.collect { |dev| dev.ips.collect { |ip| ip.address if ip.version == 'v4' } } }.flatten.reject { |ip| ip.nil? }.first rescue nil
39
+ begin
40
+ ip_addr = nics.collect { |nic_attachment| env[:connection].follow_link(nic_attachment.reported_devices).collect { |dev| dev.ips.collect { |ip| ip.address if ip.version == 'v4' } unless dev.ips.nil? } }.flatten.reject { |ip| ip.nil? }.first
41
+ rescue
42
+ # for backwards compatibility with ovirt 4.3
43
+ ip_addr = nics.collect { |nic_attachment| env[:connection].follow_link(nic_attachment).reported_devices.collect { |dev| dev.ips.collect { |ip| ip.address if ip.version == 'v4' } unless dev.ips.nil? } }.flatten.reject { |ip| ip.nil? }.first rescue nil
44
+ end
40
45
 
41
46
  # Return the info
42
47
  # TODO: Some info should be configurable in Vagrantfile
@@ -33,7 +33,13 @@ module VagrantPlugins
33
33
  end
34
34
  nics_service = server.nics_service
35
35
  nics = nics_service.list
36
- ip_addr = nics.collect { |nic_attachment| env[:connection].follow_link(nic_attachment).reported_devices.collect { |dev| dev.ips.collect { |ip| ip.address if ip.version == 'v4' } } }.flatten.reject { |ip| ip.nil? }.first rescue nil
36
+ begin
37
+ ip_addr = nics.collect { |nic_attachment| env[:connection].follow_link(nic_attachment.reported_devices).collect { |dev| dev.ips.collect { |ip| ip.address if ip.version == 'v4' } unless dev.ips.nil? } }.flatten.reject { |ip| ip.nil? }.first
38
+ rescue
39
+ # for backwards compatibility with ovirt 4.3
40
+ ip_addr = nics.collect { |nic_attachment| env[:connection].follow_link(nic_attachment).reported_devices.collect { |dev| dev.ips.collect { |ip| ip.address if ip.version == 'v4' } unless dev.ips.nil? } }.flatten.reject { |ip| ip.nil? }.first rescue nil
41
+ end
42
+
37
43
  unless ip_addr.nil?
38
44
  env[:ip_address] = ip_addr
39
45
  @logger.debug("Got output #{env[:ip_address]}")
@@ -24,36 +24,37 @@ module VagrantPlugins
24
24
 
25
25
  # Get machine first.
26
26
  begin
27
- machine = OVirtProvider::Util::Collection.find_matching(
28
- env[:ovirt_compute].servers.all, env[:machine].id.to_s)
27
+ vm_service = env[:vms_service].vm_service(env[:machine].id.to_s)
29
28
  rescue => e
30
- raise Errors::NoVMError,
31
- :vm_name => env[:machine].id.to_s
29
+ raise Errors::NoVMError, :vm_id => env[:machine].id
32
30
  end
33
31
 
32
+ disk_attachments_service = vm_service.disk_attachments_service
33
+ disk_attachments = disk_attachments_service.list
34
+ disk = disk_attachments.first.disk
35
+
34
36
  # Extend disk size if necessary
35
37
  begin
36
- machine.update_volume(
37
- :id => machine.volumes.first.id,
38
- :size => config.disk_size*1024*1024*1024,
38
+ disk_attachment_service = disk_attachments_service.attachment_service(disk.id)
39
+ disk_attachment = disk_attachment_service.update(
40
+ OvirtSDK4::DiskAttachment.new(disk: {provisioned_size: config.disk_size})
39
41
  )
40
42
  rescue => e
41
43
  raise Errors::UpdateVolumeError,
42
44
  :error_message => e.message
43
45
  end
44
46
 
45
- # Wait till all volumes are ready.
47
+ # Wait until resize operation has finished.
48
+ disks_service = env[:connection].system_service.disks_service
49
+ disk_service = disks_service.disk_service(disk.id)
46
50
  env[:ui].info(I18n.t("vagrant_ovirt4.wait_for_ready_volume"))
47
- for i in 0..10
48
- ready = true
49
- machine = env[:ovirt_compute].servers.get(env[:machine].id.to_s)
50
- machine.volumes.each do |volume|
51
- if volume.status != 'ok'
52
- ready = false
53
- break
54
- end
51
+ ready = false
52
+ for i in 0..120
53
+ disk = disk_service.get
54
+ if disk.status == OvirtSDK4::DiskStatus::OK
55
+ ready = true
56
+ break
55
57
  end
56
- break if ready
57
58
  sleep 2
58
59
  end
59
60
 
@@ -15,6 +15,8 @@ module VagrantPlugins
15
15
  end
16
16
 
17
17
  def call(env)
18
+ config = env[:machine].provider_config
19
+
18
20
  env[:ui].info(I18n.t("vagrant_ovirt4.starting_vm"))
19
21
 
20
22
  machine = env[:vms_service].vm_service(env[:machine].id)
@@ -23,49 +25,89 @@ module VagrantPlugins
23
25
  :vm_name => env[:machine].id.to_s
24
26
  end
25
27
 
26
- iface_options = nil
27
- env[:machine].config.vm.networks.each do |config|
28
- type, options = config
29
- next unless [:private_network].include? type
28
+ # FIX MULTIPLE NETWORK INTERFACES
29
+ hostname = env[:machine].config.vm.hostname
30
+ hostname = 'vagrant' if hostname.nil?
31
+
32
+ initialization = {
33
+ host_name: hostname,
34
+ nic_configurations: [],
35
+ custom_script: config.cloud_init,
36
+ }
30
37
 
31
- iface_options = scoped_hash_override(options, :ovirt)
38
+ configured_ifaces_options = []
39
+ env[:machine].config.vm.networks.each do |network|
40
+ type, options = network
41
+ next unless type == :private_network
42
+
43
+ configured_ifaces_options << scoped_hash_override(options, :ovirt)
32
44
  end
33
45
 
34
- hostname = env[:machine].config.vm.hostname
35
- hostname = 'vagrant' if hostname.nil?
46
+ (0...configured_ifaces_options.length()).each do |iface_index|
47
+ iface_options = configured_ifaces_options[iface_index]
48
+
49
+ if iface_options[:interface_name] != nil then
50
+ iface_name = iface_options[:interface_name]
51
+ else
52
+ iface_name = "eth#{iface_index}"
53
+ end
36
54
 
37
- nic_configuration = nil
38
- if iface_options[:ip] then
39
- nic_configuration = {
40
- name: 'eth0',
41
- on_boot: true,
42
- boot_protocol: OvirtSDK4::BootProtocol::STATIC,
43
- ip: {
44
- version: OvirtSDK4::IpVersion::V4,
45
- address: iface_options[:ip],
46
- gateway: iface_options[:gateway],
55
+ if iface_options[:ip] then
56
+ nic_configuration = {
57
+ name: iface_name,
58
+ on_boot: true,
59
+ boot_protocol: OvirtSDK4::BootProtocol::STATIC,
60
+ ip: {
61
+ version: OvirtSDK4::IpVersion::V4,
62
+ address: iface_options[:ip],
63
+ gateway: iface_options[:gateway],
64
+ netmask: iface_options[:netmask],
65
+ }
47
66
  }
48
- }
49
- else
50
- nic_configuration = {
51
- name: 'eth0',
52
- on_boot: true,
53
- boot_protocol: OvirtSDK4::BootProtocol::DYNAMIC,
54
- }
67
+ else
68
+ nic_configuration = {
69
+ name: iface_name,
70
+ on_boot: true,
71
+ boot_protocol: OvirtSDK4::BootProtocol::DHCP,
72
+ }
73
+ end
74
+
75
+ initialization[:nic_configurations] << nic_configuration
76
+ initialization[:dns_servers] = iface_options[:dns_servers] unless iface_options[:dns_servers].nil?
77
+ initialization[:dns_search] = iface_options[:dns_search] unless iface_options[:dns_search].nil?
55
78
  end
79
+ # END FIX MULTIPLE NETWORK INTERFACES
56
80
 
57
81
  vm_configuration = {
58
- initialization: {
59
- host_name: hostname,
60
- nic_configurations: [nic_configuration],
61
- custom_script: env[:machine].provider_config.cloud_init,
62
- }
82
+ initialization: initialization,
83
+ placement_policy: {},
63
84
  }
64
-
65
- machine.start(
66
- use_cloud_init: true,
67
- vm: vm_configuration
68
- )
85
+
86
+ vm_configuration[:placement_policy][:hosts] = [{ :name => config.placement_host }] unless config.placement_host.nil?
87
+ vm_configuration[:placement_policy][:affinity] = config.affinity unless config.affinity.nil?
88
+
89
+ vm_configuration.delete(:placement_policy) if vm_configuration[:placement_policy].empty?
90
+ vm_configuration.delete(:nic_configurations) if vm_configuration[:nic_configurations].nil? or vm_configuration[:nic_configurations].empty?
91
+
92
+ begin
93
+ machine.start(
94
+ use_cloud_init: true,
95
+ vm: vm_configuration
96
+ )
97
+ rescue OvirtSDK4::Error => e
98
+ fault_message = /Fault detail is \"\[?(.+?)\]?\".*/.match(e.message)[1] rescue e.message
99
+ retry if e.message =~ /Please try again/
100
+
101
+ if e.message !~ /VM is running/
102
+ if config.debug
103
+ raise e
104
+ else
105
+ raise Errors::StartVMError,
106
+ :error_message => fault_message
107
+ end
108
+ end
109
+
110
+ end
69
111
 
70
112
  @app.call(env)
71
113
  end