vagrant-ovirt4 1.2.2 → 1.2.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
- SHA1:
3
- metadata.gz: 39542385ebe4d052d2162d780c224872b24b7078
4
- data.tar.gz: 8b5d7423e508a64525d10e4d0f267d4748d254fc
2
+ SHA256:
3
+ metadata.gz: 7f0791674c10129bc4c799c0edc0a69688c5afad9bf97d5330c8dbfd804fc303
4
+ data.tar.gz: ff664c4cf2241450255854076a784cade3b519143e27c96cfe202f1af8bbb456
5
5
  SHA512:
6
- metadata.gz: fee43b803b78e337acafe857b8e1924fc548f6ed572b71d668eb3d1b5714b74e3ff4d5d013135459bbf37f63d0515d64ee05a66c3a8b0e682756641a2cf6ff7a
7
- data.tar.gz: 313e552a891fa6a0f01380782c28857a6c0168b052b45bd4befea2491ca03f3f2b06fec7b9b3201d57cb6e1bc213b2f12179131d5d49d65f5b1707265dfaf352
6
+ metadata.gz: 462531777be650d20de06a80c170d435733e62b42e60aa52600e9f52a72a36dd407be247682b68dccc8fad93b8b7d71c42c0f89f2734637be7e79c996f63fc9b
7
+ data.tar.gz: 7d5c64d01517722e218f6aed6110c47fcb60aa50fc6f00d2b66e5c1e55f5e84494bd961255524b9fe950b4dbd77e0356075069e0d78b0afe5ddedaf46da25571
@@ -41,3 +41,43 @@ suites:
41
41
  runcmd:
42
42
  - ifdown eth0
43
43
  - service network restart
44
+ - name: bios_serial
45
+ driver_config:
46
+ vm_hostname: bios-serial
47
+ network:
48
+ - ["private_network", {ovirt__network_name: 'ovirtmgmt'}]
49
+ customize:
50
+ template: vagrant-centos7
51
+ bios_serial: 'banana-hammock'
52
+ cloud_init: |
53
+ runcmd:
54
+ - ifdown eth0
55
+ - service network restart
56
+ - name: optimized_for_default
57
+ verifier:
58
+ name: shell
59
+ command: curl --silent -k -L --user "${OVIRT_USERNAME}:${OVIRT_PASSWORD}" --header 'Content-Type: application/xml' --header 'Accept: application/xml' ${OVIRT_URL}/vms/d3f659e1-21ff-42a0-b5fa-7c2f74a36c2b | xmllint --xpath '/vm/type/text()' - | grep desktop
60
+ driver_config:
61
+ vm_hostname: optimized-for
62
+ network:
63
+ - ["private_network", {ovirt__network_name: 'ovirtmgmt'}]
64
+ customize:
65
+ template: vagrant-centos7
66
+ cloud_init: |
67
+ runcmd:
68
+ - ifdown eth0
69
+ - service network restart
70
+ - name: optimized_for_set
71
+ verifier:
72
+ name: shell
73
+ command: test/integration/optimized_for.sh
74
+ driver_config:
75
+ vm_hostname: optimized-for
76
+ network:
77
+ - ["private_network", {ovirt__network_name: 'ovirtmgmt'}]
78
+ customize:
79
+ template: vagrant-centos7
80
+ cloud_init: |
81
+ runcmd:
82
+ - ifdown eth0
83
+ - service network restart
@@ -24,7 +24,7 @@ GIT
24
24
  PATH
25
25
  remote: .
26
26
  specs:
27
- vagrant-ovirt4 (1.2.2)
27
+ vagrant-ovirt4 (1.2.1)
28
28
  filesize (~> 0)
29
29
  ovirt-engine-sdk (~> 4.0.1)
30
30
 
@@ -45,10 +45,10 @@ GEM
45
45
  domain_name (0.5.20170223)
46
46
  unf (>= 0.0.5, < 1.0.0)
47
47
  erubis (2.7.0)
48
- excon (0.55.0)
48
+ excon (0.71.0)
49
49
  faraday (0.11.0)
50
50
  multipart-post (>= 1.2, < 3)
51
- ffi (1.9.17)
51
+ ffi (1.11.1)
52
52
  filesize (0.1.1)
53
53
  gssapi (1.2.0)
54
54
  ffi (>= 1.0.1)
@@ -132,7 +132,7 @@ GEM
132
132
  byebug (~> 9.0)
133
133
  pry (~> 0.10)
134
134
  rainbow (2.2.1)
135
- rake (0.9.6)
135
+ rake (13.0.1)
136
136
  rb-fsevent (0.9.8)
137
137
  rb-inotify (0.9.8)
138
138
  ffi (>= 0.5.0)
@@ -163,7 +163,7 @@ GEM
163
163
  rspec-core (>= 2, < 4, != 2.12.0)
164
164
  ruby_dep (1.3.1)
165
165
  rubyntlm (0.6.1)
166
- rubyzip (1.2.1)
166
+ rubyzip (1.3.0)
167
167
  safe_yaml (1.0.4)
168
168
  slop (3.6.0)
169
169
  sslshake (1.0.13)
data/README.md CHANGED
@@ -56,7 +56,7 @@ $ vagrant up --provider=ovirt4
56
56
  ```
57
57
  Vagrant.configure("2") do |config|
58
58
  config.vm.box = 'ovirt4'
59
- config.vm.hostname = "foo"
59
+ config.vm.hostname = "foo"
60
60
  config.vm.box_url = 'https://github.com/myoung34/vagrant-ovirt4/blob/master/example_box/dummy.box?raw=true'
61
61
 
62
62
  config.vm.network :private_network,
@@ -70,14 +70,18 @@ Vagrant.configure("2") do |config|
70
70
  ovirt.password = "password"
71
71
  ovirt.insecure = true
72
72
  ovirt.debug = true
73
+ ovirt.filtered_api = true #see http://www.ovirt.org/develop/release-management/features/infra/user-portal-permissions/
73
74
  ovirt.cluster = 'Default'
74
75
  ovirt.template = 'Vagrant-Centos7-test'
75
76
  ovirt.console = 'vnc'
77
+ ovirt.disk_size = '15 GB' # only growing is supported. works the same way as below memory settings
76
78
  ovirt.memory_size = '1 GiB' #see https://github.com/dominikh/filesize for usage
77
79
  ovirt.memory_guaranteed = '256 MB' #see https://github.com/dominikh/filesize for usage
78
80
  ovirt.cpu_cores = 2
79
81
  ovirt.cpu_sockets = 2
80
82
  ovirt.cpu_threads = 2
83
+ ovirt.bios_serial = aaabbbb-ccc-dddd
84
+ ovirt.optimized_for = 'server'
81
85
  ovirt.cloud_init =<<EOF
82
86
  write_files:
83
87
  - content: |
@@ -86,6 +90,8 @@ write_files:
86
90
  permissions: '0644'
87
91
  EOF
88
92
 
93
+ # additional disks
94
+ ovirt.storage :file, size: "8 GiB", type: 'qcow2', storage_domain: "mystoragedomain"
89
95
  end
90
96
  end
91
97
  ```
@@ -107,7 +113,6 @@ end
107
113
  1. `password` => The password for the API. Required. String. No default value.
108
114
  1. `insecure` => Allow connecting to SSL sites without certificates. Optional. Bool. Default is `false`
109
115
  1. `debug` => Turn on additional log statements. Optional. Bool. Default is `false`.
110
- 1. `datacenter` => The name of the ovirt datacenter to create within. Required. String. No Default value.
111
116
  1. `template` => The name of the template to use for creation. Required. String. No Default value.
112
117
  1. `cluster` => The name of the ovirt cluster to create within. Required. String. No Default value.
113
118
  1. `console` => The type of remote viewing protocol to use. Required. String. No Default value.
@@ -119,12 +124,18 @@ end
119
124
  1. `cloud_init` => The cloud-init data to pass. Must be properly formatted as yaml. [Docs here](http://cloudinit.readthedocs.io/en/latest/topics/examples.html)
120
125
  1. `affinity` => The affinity to use. [See this for possible uses](http://www.rubydoc.info/gems/ovirt-engine-sdk/OvirtSDK4/VmAffinity). Optional. Invalid will cause a `RuntimeError`
121
126
  1. `placement_host` => The host to start the VM on. Optional.
127
+ 1. `bios_serial` => The BIOS serial number to assign. Optional.
128
+ 1. `optimized_for` => The "optimized for" setting. Can be one of 'Desktop' or 'Server' (case insensitive). Optional.
129
+ 1. `storage` => adds a new storage disk to the VM
130
+ a. `size`: the size of the disk
131
+ a. `type`: the type of disk. It can be either `qcow2` or `raw`
132
+ a. `storage_domain`: the storage domain where the disk should be created
122
133
 
123
134
 
124
135
  ## Testing
125
136
 
126
137
  Currently pull-requests are tested via [test-kitchen using kitchen-vagrant](https://github.com/test-kitchen/kitchen-vagrant).
127
- See [Jenkinsfile](Jenkinsfile) for more information.
138
+ See [Jenkinsfile](Jenkinsfile) for more information.
128
139
  If you'd like to run them yourself, however, they make not work in all setups. For example they assume `192.168.2.0/24`, host pinning will probably not have a host that's in all set ups, and the template names might not match.
129
140
 
130
141
  To run Unit tests: `bundle install; bundle exec rspec`
@@ -9,6 +9,7 @@ module VagrantPlugins
9
9
  # This action is called to bring the box up from nothing.
10
10
  def self.action_up
11
11
  Vagrant::Action::Builder.new.tap do |b|
12
+ b.use HandleBox
12
13
  b.use ConfigValidate
13
14
  b.use ConnectOVirt
14
15
  b.use Call, ReadState do |env, b2|
@@ -26,7 +27,7 @@ module VagrantPlugins
26
27
  if env[:machine_state_id] == :not_created
27
28
  b2.use SetNameOfDomain
28
29
  b2.use CreateVM
29
- #b2.use ResizeDisk
30
+ b2.use ResizeDisk
30
31
 
31
32
  b2.use Provision
32
33
  b2.use CreateNetworkInterfaces
@@ -38,6 +39,7 @@ module VagrantPlugins
38
39
  b2.use WaitTillUp
39
40
  b2.use SyncFolders
40
41
  end
42
+ b.use DisconnectOVirt
41
43
  end
42
44
  end
43
45
 
@@ -55,6 +57,7 @@ module VagrantPlugins
55
57
  b2.use HaltVM
56
58
  b2.use WaitTillDown
57
59
  b2.use DestroyVM
60
+ b2.use DisconnectOVirt
58
61
  end
59
62
  end
60
63
  end
@@ -77,9 +80,11 @@ module VagrantPlugins
77
80
  # state is expected to be put into the `:machine_state_id` key.
78
81
  def self.action_read_state
79
82
  Vagrant::Action::Builder.new.tap do |b|
83
+ b.use HandleBox
80
84
  b.use ConfigValidate
81
85
  b.use ConnectOVirt
82
86
  b.use ReadState
87
+ b.use DisconnectOVirt
83
88
  end
84
89
  end
85
90
 
@@ -91,6 +96,7 @@ module VagrantPlugins
91
96
  b.use ConfigValidate
92
97
  b.use ConnectOVirt
93
98
  b.use ReadSSHInfo
99
+ b.use DisconnectOVirt
94
100
  end
95
101
  end
96
102
 
@@ -111,6 +117,7 @@ module VagrantPlugins
111
117
  raise Errors::NoIPError if env[:ip_address].nil?
112
118
  b2.use SSHExec
113
119
  end
120
+ b.use DisconnectOVirt
114
121
  end
115
122
  end
116
123
 
@@ -131,6 +138,7 @@ module VagrantPlugins
131
138
  raise Errors::NoIPError if env[:ip_address].nil?
132
139
  b2.use SSHRun
133
140
  end
141
+ b.use DisconnectOVirt
134
142
  end
135
143
  end
136
144
 
@@ -210,6 +218,7 @@ module VagrantPlugins
210
218
 
211
219
  action_root = Pathname.new(File.expand_path("../action", __FILE__))
212
220
  autoload :ConnectOVirt, action_root.join("connect_ovirt")
221
+ autoload :DisconnectOVirt, action_root.join("disconnect_ovirt")
213
222
  autoload :CreateNetworkInterfaces, action_root.join("create_network_interfaces")
214
223
  autoload :CreateVM, action_root.join("create_vm")
215
224
  autoload :DestroyVM, action_root.join("destroy_vm")
@@ -218,6 +227,7 @@ module VagrantPlugins
218
227
  autoload :IsRunning, action_root.join("is_running")
219
228
  autoload :ReadSSHInfo, action_root.join("read_ssh_info")
220
229
  autoload :ReadState, action_root.join("read_state")
230
+ autoload :ResizeDisk, action_root.join("resize_disk")
221
231
  autoload :SetNameOfDomain, action_root.join("set_name_of_domain")
222
232
  autoload :SnapshotDelete, action_root.join("snapshot_delete")
223
233
  autoload :SnapshotList, action_root.join("snapshot_list")
@@ -248,6 +258,7 @@ module VagrantPlugins
248
258
  end
249
259
  yield env, b2
250
260
  end
261
+ b.use DisconnectOVirt
251
262
  end
252
263
  end
253
264
  end
@@ -21,6 +21,7 @@ module VagrantPlugins
21
21
  conn_attr[:password] = config.password if config.password
22
22
  conn_attr[:debug] = config.debug if config.debug
23
23
  conn_attr[:insecure] = true if config.insecure
24
+ conn_attr[:headers] = {'Filter' => true} if config.filtered_api
24
25
 
25
26
  @logger.info("Connecting to oVirt (#{config.url}) ...")
26
27
  OVirtProvider.ovirt_connection = OvirtSDK4::Connection.new(conn_attr)
@@ -16,58 +16,72 @@ module VagrantPlugins
16
16
 
17
17
  def call(env)
18
18
 
19
- iface_options = nil
20
19
  config = env[:machine].provider_config
21
- env[:machine].config.vm.networks.each do |config|
22
- type, options = config
23
- # We support private networks only. They mean both the same right now.
24
- next unless [:private_network].include? type
25
20
 
26
- iface_options = scoped_hash_override(options, :ovirt)
21
+ # FIX MULTIPLE NETWORK INTERFACES
22
+ vagrantfile_networks = []
23
+ @logger.info("Found next configured networks in Vagrantfile:")
24
+ env[:machine].config.vm.networks.each do |network|
25
+ type, options = network
26
+
27
+ # We support private networks only
28
+ next unless type == :private_network
29
+ @logger.info("#{network}")
30
+
31
+ vagrantfile_networks << [type, options]
27
32
  end
28
33
 
29
- begin
30
- nics_service = env[:vms_service].vm_service(env[:machine].id).nics_service
31
- if iface_options.nil?
32
- # throw an error if they didn't provide any sort of information on interfaces _and_ the VM has none
33
- raise Errors::NoNetworkError if nics_service.list.count == 0
34
- else
35
- # provided a network block of some sort. Search oVirt for the corresponding network_profile_ids
36
- @logger.info("Finding network #{iface_options[:network_name]} for given cluster #{config.cluster}")
37
- clusters_service = env[:connection].system_service.clusters_service
38
- cluster = clusters_service.list(search: "name=#{config.cluster}").first
39
- profiles_service = env[:connection].system_service.vnic_profiles_service
40
- network_profile_ids = profiles_service.list.map do |profile|
41
- if env[:connection].follow_link(profile.network).data_center.id == cluster.data_center.id and
42
- profile.name == iface_options[:network_name]
43
- profile.id
34
+ @logger.info("Processing each found configured network")
35
+ vagrantfile_networks.each do |network|
36
+ type, options = network
37
+
38
+ iface_options = scoped_hash_override(options, :ovirt)
39
+ @logger.info("Interface options: #{iface_options}")
40
+
41
+ begin
42
+ nics_service = env[:vms_service].vm_service(env[:machine].id).nics_service
43
+ if iface_options.nil?
44
+ # throw an error if they didn't provide any sort of information on interfaces _and_ the VM has none
45
+ raise Errors::NoNetworkError if nics_service.list.count == 0
46
+ else
47
+ # provided a network block of some sort. Search oVirt for the corresponding network_profile_ids
48
+ @logger.info("Finding network #{iface_options[:network_name]} for given cluster #{config.cluster}")
49
+ clusters_service = env[:connection].system_service.clusters_service
50
+ cluster = clusters_service.list(search: "name=#{config.cluster}").first
51
+ profiles_service = env[:connection].system_service.vnic_profiles_service
52
+ network_profile_ids = profiles_service.list.map do |profile|
53
+ if env[:connection].follow_link(profile.network).data_center.id == cluster.data_center.id and
54
+ profile.name == iface_options[:network_name]
55
+ profile.id
56
+ end
44
57
  end
45
- end
46
- network_profile_id = network_profile_ids.compact.first
47
- # error if they provided a 'network name' but it could not be located in the previous search
48
- raise Errors::NetworkNotFoundError, :network_name => iface_options[:network_name] if network_profile_id.nil? and !iface_options[:network_name].nil?
58
+ network_profile_id = network_profile_ids.compact.first
59
+ # error if they provided a 'network name' but it could not be located in the previous search
60
+ raise Errors::NetworkNotFoundError, :network_name => iface_options[:network_name] if network_profile_id.nil? and !iface_options[:network_name].nil?
49
61
 
50
- # quick and dirty way to look for a 'nic#' that is not already attached to the machine
51
- iface = (("nic1".."nic8").flat_map { |x| x } - env[:vms_service].vm_service(env[:machine].id).nics_service.list.map(&:name)).first rescue "vagrant_nic1"
52
- @logger.info("Creating network interface #{iface}")
53
- nics_service.add(
54
- OvirtSDK4::Nic.new(
55
- name: iface,
56
- vnic_profile: {
57
- id: network_profile_id
58
- }
62
+ # quick and dirty way to look for a 'nic#' that is not already attached to the machine
63
+ iface = (("nic1".."nic8").flat_map { |x| x } - env[:vms_service].vm_service(env[:machine].id).nics_service.list.map(&:name)).first rescue "vagrant_nic1"
64
+ @logger.info("Creating network interface #{iface}")
65
+ nics_service.add(
66
+ OvirtSDK4::Nic.new(
67
+ name: iface,
68
+ vnic_profile: {
69
+ id: network_profile_id
70
+ }
71
+ )
59
72
  )
60
- )
61
- end
62
- rescue => e
63
- if config.debug
64
- raise e
65
- else
66
- fault_message = /Fault detail is \"\[?(.+?)\]?\".*/.match(e.message)[1] rescue e.message
67
- raise Errors::AddInterfaceError,
68
- :error_message => fault_message
73
+ end
74
+ rescue => e
75
+ if config.debug
76
+ raise e
77
+ else
78
+ fault_message = /Fault detail is \"\[?(.+?)\]?\".*/.match(e.message)[1] rescue e.message
79
+ raise Errors::AddInterfaceError,
80
+ :error_message => fault_message
81
+ end
69
82
  end
70
83
  end
84
+ # END FIX MULTIPLE NETWORK INTERFACES
71
85
 
72
86
  # Continue the middleware chain.
73
87
  @app.call(env)
@@ -25,6 +25,15 @@ module VagrantPlugins
25
25
  env[:ui].info(" -- Cluster: #{config.cluster}")
26
26
  env[:ui].info(" -- Template: #{config.template}")
27
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('GB').to_i} GB") 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('GB').to_i} GB")
36
+ end
28
37
  env[:ui].info(" -- Memory: ")
29
38
  env[:ui].info(" ---- Memory: #{Filesize.from("#{config.memory_size} B").to_f('MB').to_i} MB")
30
39
  env[:ui].info(" ---- Maximum: #{Filesize.from("#{config.memory_maximum} B").to_f('MB').to_i} MB")
@@ -38,6 +47,8 @@ module VagrantPlugins
38
47
  # Create oVirt VM.
39
48
  attr = {
40
49
  :name => hostname,
50
+ :description => config.description,
51
+ :comment => config.comment,
41
52
  :cpu => {
42
53
  :architecture => 'x86_64',
43
54
  :topology => {
@@ -61,10 +72,11 @@ 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
82
  retry if e.message =~ /Related operation is currently in progress/
@@ -89,6 +101,9 @@ module VagrantPlugins
89
101
  disk_attachments = disk_attachments_service.list
90
102
  disk_attachments.each do |disk_attachment|
91
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
92
107
  if disk.status != 'ok'
93
108
  disk_ready = false
94
109
  break
@@ -103,6 +118,67 @@ module VagrantPlugins
103
118
  raise Errors::WaitForReadyVmTimeout
104
119
  end
105
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
+
106
182
  @app.call(env)
107
183
  end
108
184
 
@@ -116,6 +192,7 @@ module VagrantPlugins
116
192
  destroy_env[:config_validate] = false
117
193
  destroy_env[:force_confirm_destroy] = true
118
194
  env[:action_runner].run(Action.action_destroy, destroy_env)
195
+ env[:connection].close()
119
196
  end
120
197
  end
121
198
  end
@@ -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
@@ -36,7 +36,7 @@ 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
+ 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
40
40
 
41
41
  # Return the info
42
42
  # TODO: Some info should be configurable in Vagrantfile
@@ -33,7 +33,7 @@ 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
+ 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
37
37
  unless ip_addr.nil?
38
38
  env[:ip_address] = ip_addr
39
39
  @logger.debug("Got output #{env[:ip_address]}")
@@ -24,35 +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
29
  raise Errors::NoVMError, :vm_id => env[:machine].id
31
30
  end
32
31
 
32
+ disk_attachments_service = vm_service.disk_attachments_service
33
+ disk_attachments = disk_attachments_service.list
34
+ disk = disk_attachments.first.disk
35
+
33
36
  # Extend disk size if necessary
34
37
  begin
35
- machine.update_volume(
36
- :id => machine.volumes.first.id,
37
- :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})
38
41
  )
39
42
  rescue => e
40
43
  raise Errors::UpdateVolumeError,
41
44
  :error_message => e.message
42
45
  end
43
46
 
44
- # 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)
45
50
  env[:ui].info(I18n.t("vagrant_ovirt4.wait_for_ready_volume"))
46
- for i in 0..10
47
- ready = true
48
- machine = env[:ovirt_compute].servers.get(env[:machine].id.to_s)
49
- machine.volumes.each do |volume|
50
- if volume.status != 'ok'
51
- ready = false
52
- break
53
- 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
54
57
  end
55
- break if ready
56
58
  sleep 2
57
59
  end
58
60
 
@@ -25,22 +25,30 @@ module VagrantPlugins
25
25
  :vm_name => env[:machine].id.to_s
26
26
  end
27
27
 
28
- iface_options = nil
29
- env[:machine].config.vm.networks.each do |config|
30
- type, options = config
31
- 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
+ }
32
37
 
33
- 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)
34
44
  end
35
45
 
36
- hostname = env[:machine].config.vm.hostname
37
- hostname = 'vagrant' if hostname.nil?
46
+ (0...configured_ifaces_options.length()).each do |iface_index|
47
+ iface_options = configured_ifaces_options[iface_index]
38
48
 
39
- nic_configuration = nil
40
- unless iface_options.nil?
41
49
  if iface_options[:ip] then
42
50
  nic_configuration = {
43
- name: 'eth0',
51
+ name: "eth#{iface_index}",
44
52
  on_boot: true,
45
53
  boot_protocol: OvirtSDK4::BootProtocol::STATIC,
46
54
  ip: {
@@ -52,21 +60,17 @@ module VagrantPlugins
52
60
  }
53
61
  else
54
62
  nic_configuration = {
55
- name: 'eth0',
63
+ name: "eth#{iface_index}",
56
64
  on_boot: true,
57
65
  boot_protocol: OvirtSDK4::BootProtocol::DHCP,
58
66
  }
59
67
  end
60
68
 
61
- initialization = {
62
- host_name: hostname,
63
- nic_configurations: [nic_configuration],
64
- custom_script: config.cloud_init,
65
- }
66
-
69
+ initialization[:nic_configurations] << nic_configuration
67
70
  initialization[:dns_servers] = iface_options[:dns_servers] unless iface_options[:dns_servers].nil?
68
71
  initialization[:dns_search] = iface_options[:dns_search] unless iface_options[:dns_search].nil?
69
72
  end
73
+ # END FIX MULTIPLE NETWORK INTERFACES
70
74
 
71
75
  vm_configuration = {
72
76
  initialization: initialization,
@@ -1,6 +1,8 @@
1
1
  require 'log4r'
2
2
  require 'vagrant-ovirt4/util/timer'
3
3
  require 'vagrant/util/retryable'
4
+ require 'socket'
5
+ require 'timeout'
4
6
 
5
7
  module VagrantPlugins
6
8
  module OVirtProvider
@@ -16,6 +18,23 @@ module VagrantPlugins
16
18
  @app = app
17
19
  end
18
20
 
21
+ def port_open?(ip, port, seconds=10)
22
+ # => checks if a port is open or not on a remote host
23
+ Timeout::timeout(seconds) do
24
+ begin
25
+ TCPSocket.new(ip, port).close
26
+ @logger.info("SSH Check OK for IP: #{ip}")
27
+ true
28
+ rescue Errno::ECONNREFUSED, Errno::EHOSTUNREACH, SocketError => e
29
+ @logger.info("SSH Connection Failed for IP #{ip}: #{e}")
30
+ false
31
+ end
32
+ end
33
+ rescue Timeout::Error
34
+ @logger.info("SSH Connection Failed: Timeout for IP: #{ip}" )
35
+ false
36
+ end
37
+
19
38
  def call(env)
20
39
  # Initialize metrics if they haven't been
21
40
  env[:metrics] ||= {}
@@ -38,11 +57,15 @@ module VagrantPlugins
38
57
 
39
58
  nics_service = server.nics_service
40
59
  nics = nics_service.list
41
- 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
60
+ 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
42
61
  unless ip_addr.nil?
43
- env[:ip_address] = ip_addr
44
- break
45
- @logger.debug("Got output #{env[:ip_address]}")
62
+ env[:ui].info("Got IP: #{ip_addr}")
63
+ # Check if SSH-Server is up
64
+ if port_open?(ip_addr, 22)
65
+ env[:ip_address] = ip_addr
66
+ break
67
+ @logger.debug("Got output #{env[:ip_address]}")
68
+ end
46
69
  end
47
70
  sleep 5
48
71
  end
@@ -11,6 +11,8 @@ module VagrantPlugins
11
11
  attr_accessor :password
12
12
  attr_accessor :insecure
13
13
  attr_accessor :debug
14
+ attr_accessor :disk_size
15
+ attr_accessor :filtered_api
14
16
  attr_accessor :cpu_cores
15
17
  attr_accessor :cpu_sockets
16
18
  attr_accessor :cpu_threads
@@ -23,6 +25,11 @@ module VagrantPlugins
23
25
  attr_accessor :cloud_init
24
26
  attr_accessor :affinity
25
27
  attr_accessor :placement_host
28
+ attr_accessor :bios_serial
29
+ attr_accessor :optimized_for
30
+ attr_accessor :description
31
+ attr_accessor :comment
32
+ attr_accessor :disks
26
33
 
27
34
  def initialize
28
35
  @url = UNSET_VALUE
@@ -30,6 +37,8 @@ module VagrantPlugins
30
37
  @password = UNSET_VALUE
31
38
  @insecure = UNSET_VALUE
32
39
  @debug = UNSET_VALUE
40
+ @disk_size = UNSET_VALUE
41
+ @filtered_api = UNSET_VALUE
33
42
  @cpu_cores = UNSET_VALUE
34
43
  @cpu_sockets = UNSET_VALUE
35
44
  @cpu_threads = UNSET_VALUE
@@ -42,15 +51,48 @@ module VagrantPlugins
42
51
  @cloud_init = UNSET_VALUE
43
52
  @affinity = UNSET_VALUE
44
53
  @placement_host = UNSET_VALUE
54
+ @bios_serial = UNSET_VALUE
55
+ @optimized_for = UNSET_VALUE
56
+ @description = UNSET_VALUE
57
+ @comment = UNSET_VALUE
58
+ @disks = []
45
59
 
46
60
  end
47
61
 
62
+ def storage(storage_type, options = {})
63
+ if storage_type == :file
64
+ _handle_disk_storage(options)
65
+ end
66
+ end
67
+
68
+ def _handle_disk_storage(options ={})
69
+ options = {
70
+ name: "storage_disk_#{@disks.length + 1}",
71
+ type: 'qcow2',
72
+ size: Filesize.from('8G').to_f('B').to_i,
73
+ bus: 'virtio'
74
+ }.merge(options)
75
+
76
+ disk = {
77
+ name: options[:name],
78
+ device: options[:device],
79
+ type: options[:type],
80
+ size: Filesize.from(options[:size]).to_f('B').to_i,
81
+ storage_domain: options[:storage_domain],
82
+ bus: options[:bus]
83
+ }
84
+
85
+ @disks << disk # append
86
+ end
87
+
48
88
  def finalize!
49
89
  @url = nil if @url == UNSET_VALUE
50
90
  @username = nil if @username == UNSET_VALUE
51
91
  @password = nil if @password == UNSET_VALUE
52
92
  @insecure = false if @insecure == UNSET_VALUE
53
93
  @debug = false if @debug == UNSET_VALUE
94
+ @disk_size = nil if @disk_size == UNSET_VALUE
95
+ @filtered_api = false if @filtered_api == UNSET_VALUE
54
96
  @cpu_cores = 1 if @cpu_cores == UNSET_VALUE
55
97
  @cpu_sockets = 1 if @cpu_sockets == UNSET_VALUE
56
98
  @cpu_threads = 1 if @cpu_threads == UNSET_VALUE
@@ -63,16 +105,32 @@ module VagrantPlugins
63
105
  @cloud_init = nil if @cloud_init == UNSET_VALUE
64
106
  @affinity = nil if @affinity == UNSET_VALUE
65
107
  @placement_host = nil if @placement_host == UNSET_VALUE
108
+ @bios_serial = nil if @bios_serial == UNSET_VALUE
109
+ @optimized_for = nil if @optimized_for == UNSET_VALUE
110
+ @description = '' if @description == UNSET_VALUE
111
+ @comment = '' if @comment == UNSET_VALUE
112
+
113
+ unless optimized_for.nil?
114
+ raise "Invalid 'optimized_for'. Must be one of #{OvirtSDK4::VmType.constants.map { |s| "'#{s.downcase}'" }.join(' ')}" unless OvirtSDK4::VmType.constants.include? optimized_for.upcase.to_sym
115
+ end
66
116
 
67
117
  unless affinity.nil?
68
118
  raise "Invalid affinity. Must be one of #{OvirtSDK4::VmAffinity.constants.map { |s| "'#{s.downcase}'" }.join(' ')}" unless OvirtSDK4::VmAffinity.constants.include? affinity.upcase.to_sym
69
119
  end
70
120
 
121
+ unless disk_size.nil?
122
+ begin
123
+ @disk_size = Filesize.from(@disk_size).to_f('B').to_i
124
+ rescue ArgumentError
125
+ raise "Not able to parse 'disk_size'. Please verify and check again."
126
+ end
127
+ end
128
+
71
129
  begin
72
130
  @memory_size = Filesize.from(@memory_size).to_f('B').to_i
73
131
  @memory_maximum = Filesize.from(@memory_maximum).to_f('B').to_i
74
132
  @memory_guaranteed = Filesize.from(@memory_guaranteed).to_f('B').to_i
75
- rescue ArgumentError
133
+ rescue ArgumentError
76
134
  raise "Not able to parse either `memory_size` or `memory_guaranteed`. Please verify and check again."
77
135
  end
78
136
  end
@@ -7,6 +7,10 @@ module VagrantPlugins
7
7
  error_namespace("vagrant_ovirt4.errors")
8
8
  end
9
9
 
10
+ class RsyncError < VagrantOVirtError
11
+ error_key(:rsync_error)
12
+ end
13
+
10
14
  class NoVMError < VagrantOVirtError
11
15
  error_key(:no_vm_error)
12
16
  end
@@ -47,9 +51,17 @@ module VagrantPlugins
47
51
  error_key(:remove_snapshot_error)
48
52
  end
49
53
 
54
+ class UpdateVolumeError < VagrantOVirtError
55
+ error_key(:resize_disk_error)
56
+ end
57
+
50
58
  class RemoveVMError < VagrantOVirtError
51
59
  error_key(:remove_vm_error)
52
60
  end
61
+
62
+ class UpdateBiosError < VagrantOVirtError
63
+ error_key(:update_bios_error)
64
+ end
53
65
  end
54
66
  end
55
67
  end
@@ -1,6 +1,6 @@
1
1
  module VagrantPlugins
2
2
  module OVirtProvider
3
- VERSION = '1.2.2'
3
+ VERSION = '1.2.3'
4
4
  end
5
5
  end
6
6
 
@@ -14,6 +14,8 @@ en:
14
14
  VM is currently powering up. Please run `vagrant halt` to abort or wait until its status is 'up'.
15
15
  wait_for_ready_vm: |-
16
16
  Waiting for VM to become "ready" to start...
17
+ wait_for_ready_volume: |-
18
+ Waiting for disk resize to finish...
17
19
  error_recovering: |-
18
20
  An error occured. Recovering..
19
21
  waiting_for_ip: |-
@@ -58,8 +60,12 @@ en:
58
60
  Error removing VM '%{vm_name}'. oVirt error message was '%{error_message}'
59
61
  no_vm_error: |-
60
62
  No VM found with id '%{vm_id}'
63
+ rsync_error: |-
64
+ An rsync error occurred. oVirt error message was '%{error_message}'
61
65
  create_vm_error: |-
62
66
  Creation failed. oVirt error message was '%{error_message}'
67
+ update_bios_error: |-
68
+ BIOS update failed. oVirt error message was '%{error_message}'
63
69
  start_vm_error: |-
64
70
  Unable to start VM: %{error_message}
65
71
  no_network_error: |-
@@ -76,3 +82,5 @@ en:
76
82
  Snapshot with id %{id} is the active snapshot which cannot be removed.
77
83
  remove_snapshot_error: |-
78
84
  Snapshot with id %{id} Could not be removed. Details: %{error_message}.
85
+ resize_disk_error: |-
86
+ Disk resize failed. oVirt error message was '%{error_message}'
@@ -33,6 +33,7 @@ describe VagrantPlugins::OVirtProvider::Config do
33
33
  its("password") { should be_nil }
34
34
  its("insecure") { should == false }
35
35
  its("debug") { should == false }
36
+ its("filtered_api") { should == false }
36
37
  its("cpu_cores") { should == 1 }
37
38
  its("cpu_sockets") { should == 1 }
38
39
  its("cpu_threads") { should == 1 }
@@ -45,11 +46,15 @@ describe VagrantPlugins::OVirtProvider::Config do
45
46
  its("cloud_init") { should be_nil }
46
47
  its("affinity") { should be_nil }
47
48
  its("placement_host") { should be_nil }
49
+ its("bios_serial") { should be_nil }
50
+ its("optimized_for") { should be_nil }
51
+ its("description") { should == '' }
52
+ its("comment") { should == '' }
48
53
 
49
54
  end
50
55
 
51
56
  describe "overriding defaults" do
52
- [:url, :username, :password, :insecure, :debug, :cpu_cores, :cpu_sockets, :cpu_threads, :cluster, :console, :template, :cloud_init, :placement_host].each do |attribute|
57
+ [:url, :username, :password, :insecure, :debug, :filtered_api, :cpu_cores, :cpu_sockets, :cpu_threads, :cluster, :console, :template, :cloud_init, :placement_host, :bios_serial, :optimized_for, :description, :comment].each do |attribute|
53
58
 
54
59
  it "should not default #{attribute} if overridden" do
55
60
  instance.send("#{attribute}=".to_sym, "foo")
@@ -0,0 +1,6 @@
1
+ describe command('dmidecode -s system-serial-number') do
2
+ its(:exit_status) { should eq 0 }
3
+ its(:stderr) { should be_empty }
4
+ its(:stdout) { should match(/^banana-hammock$/) }
5
+ end
6
+
@@ -0,0 +1,4 @@
1
+ #!/bin/bash
2
+ bios_serial=$(vagrant ssh -c 'sudo dmidecode -s system-serial-number' 2>/dev/null | tail -n 1 | sed 's/[\r\n]//g')
3
+ vm_id=$(curl --silent -k -L --user "${OVIRT_USERNAME}:${OVIRT_PASSWORD}" --header 'Content-Type: application/xml' --header 'Accept: application/xml' ${OVIRT_URL}/vms | xmllint --xpath 'string(./vms/vm[./serial_number/value/text() = "'$bios_serial'"]/@id)' -)
4
+ curl --silent -k -L --user "${OVIRT_USERNAME}:${OVIRT_PASSWORD}" --header 'Content-Type: application/xml' --header 'Accept: application/xml' ${OVIRT_URL}/vms/${vm_id} | xmllint --xpath './vm/type/text()' - | grep server
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: vagrant-ovirt4
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.2.2
4
+ version: 1.2.3
5
5
  platform: ruby
6
6
  authors:
7
7
  - Marcus Young
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2017-03-09 00:00:00.000000000 Z
11
+ date: 2020-05-05 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: ovirt-engine-sdk
@@ -65,6 +65,7 @@ files:
65
65
  - lib/vagrant-ovirt4/action/create_network_interfaces.rb
66
66
  - lib/vagrant-ovirt4/action/create_vm.rb
67
67
  - lib/vagrant-ovirt4/action/destroy_vm.rb
68
+ - lib/vagrant-ovirt4/action/disconnect_ovirt.rb
68
69
  - lib/vagrant-ovirt4/action/halt_vm.rb
69
70
  - lib/vagrant-ovirt4/action/is_created.rb
70
71
  - lib/vagrant-ovirt4/action/is_running.rb
@@ -112,8 +113,9 @@ files:
112
113
  - spec/vagrant-ovirt4/action/read_state_spec.rb
113
114
  - spec/vagrant-ovirt4/config_spec.rb
114
115
  - templates/Vagrantfile.erb
115
- - test/Vagrantfile
116
+ - test/integration/bios_serial/bios_serial_spec.rb
116
117
  - test/integration/dynamic_network/network_spec.rb
118
+ - test/integration/optimized_for.sh
117
119
  - test/integration/singleton-static_network/network_spec.rb
118
120
  - tools/prepare_redhat_for_box.sh
119
121
  - vagrant-ovirt4.gemspec
@@ -136,8 +138,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
136
138
  - !ruby/object:Gem::Version
137
139
  version: '0'
138
140
  requirements: []
139
- rubyforge_project:
140
- rubygems_version: 2.4.8
141
+ rubygems_version: 3.0.1
141
142
  signing_key:
142
143
  specification_version: 4
143
144
  summary: This vagrant plugin provides the ability to create, control, and destroy
@@ -155,6 +156,7 @@ test_files:
155
156
  - spec/vagrant-ovirt4/action/read_ssh_info_spec.rb
156
157
  - spec/vagrant-ovirt4/action/read_state_spec.rb
157
158
  - spec/vagrant-ovirt4/config_spec.rb
158
- - test/Vagrantfile
159
+ - test/integration/bios_serial/bios_serial_spec.rb
159
160
  - test/integration/dynamic_network/network_spec.rb
161
+ - test/integration/optimized_for.sh
160
162
  - test/integration/singleton-static_network/network_spec.rb
@@ -1,19 +0,0 @@
1
- Vagrant.configure("2") do |config|
2
- config.vm.box = 'ovirt4'
3
- config.vm.hostname = "testing"
4
- config.vm.box_url = 'https://github.com/myoung34/vagrant-ovirt4/blob/master/example_box/dummy.box?raw=true'
5
-
6
- config.vm.network :private_network,
7
- :ovirt__ip => '192.168.2.254', :ovirt__network_name => 'ovirtmgmt', :ovirt__gateway => '192.168.2.1',
8
- :ovirt__netmask => '255.255.255.0', :ovirt__dns_servers => '192.168.2.1'
9
-
10
-
11
- config.vm.provider :ovirt4 do |ovirt|
12
- ovirt.url = 'https://ovirt/ovirt-engine/api'
13
- ovirt.username = "#{ENV['OVIRT_TEST_USER']}"
14
- ovirt.password = "#{ENV['OVIRT_TEST_PASS']}"
15
- ovirt.insecure = true
16
- ovirt.cluster = 'Default'
17
- ovirt.template = 'vagrant-centos7'
18
- end
19
- end