vagrant-ovirt4 1.2.2 → 1.2.3

Sign up to get free protection for your applications and to get access to all the features.
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