foreman_fog_proxmox 0.7.0 → 0.8.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.

Potentially problematic release.


This version of foreman_fog_proxmox might be problematic. Click here for more details.

Files changed (34) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +5 -4
  3. data/app/assets/javascripts/foreman_fog_proxmox/proxmox_compute_resource.js +12 -5
  4. data/app/assets/javascripts/foreman_fog_proxmox/proxmox_vm_server.js +33 -14
  5. data/app/helpers/proxmox_container_helper.rb +32 -38
  6. data/app/helpers/proxmox_server_helper.rb +34 -39
  7. data/app/helpers/proxmox_vm_helper.rb +1 -20
  8. data/app/models/concerns/fog_extensions/proxmox/interface.rb +29 -0
  9. data/app/models/concerns/fog_extensions/proxmox/node.rb +13 -0
  10. data/app/models/concerns/fog_extensions/proxmox/server.rb +4 -1
  11. data/app/models/concerns/host_ext/proxmox/interfaces.rb +37 -0
  12. data/app/models/concerns/orchestration/proxmox/compute.rb +38 -0
  13. data/app/models/foreman_fog_proxmox/proxmox.rb +71 -36
  14. data/app/overrides/compute_resources_vms/form/remove_new_vm_from_removable_layout.rb +24 -0
  15. data/app/views/compute_resources/form/_proxmox.html.erb +1 -1
  16. data/app/views/compute_resources_vms/form/proxmox/_add_vm_type_to_networks_form.html.erb +0 -1
  17. data/app/views/compute_resources_vms/form/proxmox/_add_vm_type_to_networks_new_childs_form.html.erb +0 -1
  18. data/app/views/compute_resources_vms/form/proxmox/_add_vm_type_to_nic_provider_specific_form.html.erb +0 -1
  19. data/app/views/compute_resources_vms/form/proxmox/_add_vm_type_to_volumes_edit.html.erb +3 -6
  20. data/app/views/compute_resources_vms/form/proxmox/_removable_layout.html.erb +22 -0
  21. data/app/views/compute_resources_vms/form/proxmox/container/_network.html.erb +2 -1
  22. data/app/views/compute_resources_vms/form/proxmox/container/_volume_mp.html.erb +6 -5
  23. data/app/views/compute_resources_vms/form/proxmox/container/_volume_rootfs.html.erb +3 -3
  24. data/app/views/compute_resources_vms/form/proxmox/server/_network.html.erb +2 -1
  25. data/app/views/compute_resources_vms/form/proxmox/server/_volume.html.erb +5 -4
  26. data/app/views/compute_resources_vms/show/_proxmox.html.erb +1 -1
  27. data/lib/foreman_fog_proxmox/engine.rb +4 -0
  28. data/lib/foreman_fog_proxmox/version.rb +1 -1
  29. data/test/unit/foreman_fog_proxmox/helpers/proxmox_container_helper_test.rb +28 -29
  30. data/test/unit/foreman_fog_proxmox/helpers/proxmox_server_helper_test.rb +28 -27
  31. data/test/unit/foreman_fog_proxmox/helpers/proxmox_vm_helper_test.rb +0 -25
  32. data/test/unit/foreman_fog_proxmox/proxmox_test.rb +215 -5
  33. data/test/unit/foreman_fog_proxmox/proxmox_test_helpers.rb +10 -2
  34. metadata +9 -4
@@ -82,15 +82,19 @@ module ForemanFogProxmox
82
82
  require 'fog/compute/proxmox/models/server'
83
83
  require 'fog/compute/proxmox/models/server_config'
84
84
  require 'fog/compute/proxmox/models/disk'
85
+ require 'fog/compute/proxmox/models/interface'
85
86
  require 'fog/compute/proxmox/models/volume'
86
87
  require 'fog/compute/proxmox/models/node'
87
88
 
88
89
  Fog::Proxmox::Compute::Server.send :include, FogExtensions::Proxmox::Server
89
90
  Fog::Proxmox::Compute::ServerConfig.send :include, FogExtensions::Proxmox::ServerConfig
90
91
  Fog::Proxmox::Compute::Disk.send :include, FogExtensions::Proxmox::Disk
92
+ Fog::Proxmox::Compute::Interface.send :include, FogExtensions::Proxmox::Interface
91
93
  Fog::Proxmox::Compute::Volume.send :include, FogExtensions::Proxmox::Volume
92
94
  ::ComputeResourcesController.send :include, ForemanFogProxmox::Controller::Parameters::ComputeResource
93
95
  Fog::Proxmox::Compute::Node.send :include, FogExtensions::Proxmox::Node
96
+ ::Host::Managed.send :include, Orchestration::Proxmox::Compute
97
+ ::Host::Managed.send :include, HostExt::Proxmox::Interfaces
94
98
  end
95
99
 
96
100
  end
@@ -18,5 +18,5 @@
18
18
  # along with ForemanFogProxmox. If not, see <http://www.gnu.org/licenses/>.
19
19
 
20
20
  module ForemanFogProxmox
21
- VERSION = '0.7.0'.freeze
21
+ VERSION = '0.8.0'.freeze
22
22
  end
@@ -53,11 +53,11 @@ class ProxmoxContainerHelperTest < ActiveSupport::TestCase
53
53
 
54
54
  },
55
55
  'volumes_attributes' => {
56
- '0'=> { 'id' => 'rootfs', 'storage' => 'local-lvm', 'size' => '1073741824', 'cache' => nil },
56
+ '0'=> { 'id' => 'rootfs', 'storage' => 'local-lvm', 'size' => '1073741824', 'cache' => '' },
57
57
  '1'=> { 'id' => 'mp0', 'storage' => 'local-lvm', 'size' => '1073741824', 'mp' => '/opt/path' }
58
58
  },
59
59
  'interfaces_attributes' => {
60
- '0' => { 'id' => 'net0', 'name' => 'eth0', 'bridge' => 'vmbr0', 'ip' => 'dhcp', 'ip6' => 'dhcp', 'rate' => nil },
60
+ '0' => { 'id' => 'net0', 'name' => 'eth0', 'bridge' => 'vmbr0', 'ip' => 'dhcp', 'ip6' => 'dhcp', 'rate' => '' },
61
61
  '1' => { 'id' => 'net1', 'name' => 'eth1', 'bridge' => 'vmbr0', 'ip' => 'dhcp', 'ip6' => 'dhcp' }
62
62
  }
63
63
  }
@@ -94,7 +94,7 @@ class ProxmoxContainerHelperTest < ActiveSupport::TestCase
94
94
  'name' => 'test',
95
95
  'type' => 'lxc',
96
96
  'node_id' => 'pve',
97
- 'volumes_attributes' => { '0' => { '_delete' => '1', 'device' => '0', 'storage' => 'local-lvm', 'size' => '1073741824' }},
97
+ 'volumes_attributes' => { '0' => { '_delete' => '1', 'device' => '0', 'storage' => 'local-lvm', 'size' => '1073741824', 'mp' => '/opt/path' }},
98
98
  'interfaces_attributes' => { '0' => { '_delete' => '1', 'id' => 'net0', 'name' => 'eth0' } }
99
99
  }
100
100
  end
@@ -168,40 +168,39 @@ class ProxmoxContainerHelperTest < ActiveSupport::TestCase
168
168
  assert_equal 'local-lvm:1073741824,mp=/opt/path', mp0[:mp0]
169
169
  end
170
170
 
171
- test '#volume delete mp0' do
172
- volumes = parse_container_volumes(host_delete['volumes_attributes'])
173
- assert !volumes.empty?
174
- assert_equal 1, volumes.length
175
- assert volume = volumes.first
176
- assert volume.has_key?(:delete)
177
- assert_equal 'mp0', volume[:delete]
178
- end
179
-
180
171
  test '#interface with name eth0 and bridge' do
181
- interface = parse_container_interface(host['interfaces_attributes']['0'])
182
- assert interface.has_key?(:net0)
183
- assert_equal 'name=eth0,bridge=vmbr0,ip=dhcp,ip6=dhcp', interface[:net0]
172
+ deletes = []
173
+ nics = []
174
+ add_container_interface(host['interfaces_attributes']['0'], deletes, nics)
175
+ assert 1, nics.length
176
+ assert nics[0].has_key?(:net0)
177
+ assert_equal 'name=eth0,bridge=vmbr0,ip=dhcp,ip6=dhcp', nics[0][:net0]
184
178
  end
185
179
 
186
- test '#interface with name eth1 and bridge' do
187
- interface = parse_container_interface(host['interfaces_attributes']['1'])
188
- assert interface.has_key?(:net1)
189
- assert_equal 'name=eth1,bridge=vmbr0,ip=dhcp,ip6=dhcp', interface[:net1]
180
+ test '#interface with name eth1 and bridge' do
181
+ deletes = []
182
+ nics = []
183
+ add_container_interface(host['interfaces_attributes']['1'], deletes, nics)
184
+ assert 1, nics.length
185
+ assert nics[0].has_key?(:net1)
186
+ assert_equal 'name=eth1,bridge=vmbr0,ip=dhcp,ip6=dhcp', nics[0][:net1]
190
187
  end
191
188
 
192
- test '#interface delete net0' do
193
- interface = parse_container_interface(host_delete['interfaces_attributes']['0'])
194
- assert interface.has_key?(:delete)
195
- assert_equal interface[:delete], 'net0'
196
- assert_equal 1, interface.length
189
+ test '#interface delete net0' do
190
+ deletes = []
191
+ nics = []
192
+ add_container_interface(host_delete['interfaces_attributes']['0'], deletes, nics)
193
+ assert nics.empty?
194
+ assert_equal 1, deletes.length
195
+ assert_equal 'net0', deletes[0]
197
196
  end
198
197
 
199
198
  test '#interfaces' do
200
- interfaces = parse_container_interfaces(host['interfaces_attributes'])
201
- assert !interfaces.empty?
202
- assert_equal 2, interfaces.length
203
- assert interfaces.include?({ net0: 'name=eth0,bridge=vmbr0,ip=dhcp,ip6=dhcp'})
204
- assert interfaces.include?({ net1: 'name=eth1,bridge=vmbr0,ip=dhcp,ip6=dhcp'})
199
+ interfaces_to_add, interfaces_to_delete = parse_container_interfaces(host['interfaces_attributes'])
200
+ assert interfaces_to_delete.empty?
201
+ assert_equal 2, interfaces_to_add.length
202
+ assert interfaces_to_add.include?({ net0: 'name=eth0,bridge=vmbr0,ip=dhcp,ip6=dhcp'})
203
+ assert interfaces_to_add.include?({ net1: 'name=eth1,bridge=vmbr0,ip=dhcp,ip6=dhcp'})
205
204
  end
206
205
 
207
206
  end
@@ -107,42 +107,43 @@ class ProxmoxServerHelperTest < ActiveSupport::TestCase
107
107
  assert volume = volumes[1]
108
108
  assert volume.has_key?(:virtio0)
109
109
  assert_equal 'local-lvm:1073741824,cache=none', volume[:virtio0]
110
- end
111
-
112
- test '#volume delete scsi0' do
113
- volumes = parse_server_volumes(host_delete['volumes_attributes'])
114
- assert !volumes.empty?
115
- assert_equal volumes.length, 1
116
- assert volume = volumes.first
117
- assert volume.has_key?(:delete)
118
- assert_match(/(net0,){0,1}scsi0(,net0){0,1}/, volume[:delete])
119
- end
110
+ end
120
111
 
121
- test '#interface with model virtio and bridge' do
122
- interface = parse_server_interface(host['interfaces_attributes']['0'])
123
- assert interface.has_key?(:net0)
124
- assert_equal 'model=virtio,bridge=vmbr0,firewall=0,link_down=0', interface[:net0]
112
+ test '#interface with model virtio and bridge' do
113
+ interfaces_to_delete = []
114
+ interfaces_to_add = []
115
+ add_server_interface(host['interfaces_attributes']['0'],interfaces_to_delete,interfaces_to_add)
116
+ assert interfaces_to_delete.empty?
117
+ assert_equal 1, interfaces_to_add.length
118
+ assert interfaces_to_add[0].has_key?(:net0)
119
+ assert_equal 'model=virtio,bridge=vmbr0,firewall=0,link_down=0', interfaces_to_add[0][:net0]
125
120
  end
126
121
 
127
- test '#interface with model e1000 and bridge' do
128
- interface = parse_server_interface(host['interfaces_attributes']['1'])
129
- assert interface.has_key?(:net1)
130
- assert_equal 'model=e1000,bridge=vmbr0,firewall=0,link_down=0', interface[:net1]
122
+ test '#interface with model e1000 and bridge' do
123
+ interfaces_to_delete = []
124
+ interfaces_to_add = []
125
+ interface = add_server_interface(host['interfaces_attributes']['1'],interfaces_to_delete,interfaces_to_add)
126
+ assert interfaces_to_delete.empty?
127
+ assert_equal 1, interfaces_to_add.length
128
+ assert interfaces_to_add[0].has_key?(:net1)
129
+ assert_equal 'model=e1000,bridge=vmbr0,firewall=0,link_down=0', interfaces_to_add[0][:net1]
131
130
  end
132
131
 
133
132
  test '#interface delete net0' do
134
- interface = parse_server_interface(host_delete['interfaces_attributes']['0'])
135
- assert interface.has_key?(:delete)
136
- assert_match(/(scsi0,){0,1}net0(,scsi0){0,1}/, interface[:delete])
137
- assert_equal interface.length, 1
133
+ interfaces_to_delete = []
134
+ interfaces_to_add = []
135
+ add_server_interface(host_delete['interfaces_attributes']['0'],interfaces_to_delete,interfaces_to_add)
136
+ assert interfaces_to_add.empty?
137
+ assert_equal 1, interfaces_to_delete.length
138
+ assert_equal 'net0', interfaces_to_delete[0]
138
139
  end
139
140
 
140
141
  test '#interfaces' do
141
- interfaces = parse_server_interfaces(host['interfaces_attributes'])
142
- assert !interfaces.empty?
143
- assert_equal interfaces.length, 2
144
- assert interfaces.include?({ net0: 'model=virtio,bridge=vmbr0,firewall=0,link_down=0'})
145
- assert interfaces.include?({ net1: 'model=e1000,bridge=vmbr0,firewall=0,link_down=0'})
142
+ interfaces_to_add, interfaces_to_delete = parse_server_interfaces(host['interfaces_attributes'])
143
+ assert interfaces_to_delete.empty?
144
+ assert_equal 2, interfaces_to_add.length
145
+ assert interfaces_to_add.include?({ net0: 'model=virtio,bridge=vmbr0,firewall=0,link_down=0'})
146
+ assert interfaces_to_add.include?({ net1: 'model=e1000,bridge=vmbr0,firewall=0,link_down=0'})
146
147
  end
147
148
 
148
149
  end
@@ -219,30 +219,5 @@ class ProxmoxVmHelperTest < ActiveSupport::TestCase
219
219
  end
220
220
  end
221
221
 
222
- describe 'parse_type_and_vmid' do
223
-
224
- setup { Fog.mock! }
225
- teardown { Fog.unmock! }
226
-
227
- it "raises Foreman::Exception when the uuid does not match" do
228
- err = assert_raises Foreman::Exception do
229
- parse_type_and_vmid('100')
230
- end
231
- assert err.message.end_with?('Invalid uuid=[100].')
232
- end
233
-
234
- it '#server' do
235
- type, vmid = parse_type_and_vmid('qemu_100')
236
- assert_equal 'qemu', type
237
- assert_equal '100', vmid
238
- end
239
-
240
- it '#container' do
241
- type, vmid = parse_type_and_vmid('lxc_100')
242
- assert_equal 'lxc', type
243
- assert_equal '100', vmid
244
- end
245
- end
246
-
247
222
  end
248
223
  end
@@ -26,6 +26,7 @@ module ForemanFogProxmox
26
26
  class ProxmoxTest < ActiveSupport::TestCase
27
27
  include ComputeResourceTestHelpers
28
28
  include ForemanFogProxmox::ProxmoxTestHelpers
29
+ include ProxmoxVmHelper
29
30
 
30
31
  should validate_presence_of(:url)
31
32
  should validate_presence_of(:user)
@@ -92,7 +93,7 @@ module ForemanFogProxmox
92
93
  ip = IPAddr.new(1, Socket::AF_INET).to_s
93
94
  ip6 = Array.new(4) { '%x' % rand(16**4) }.join(':') + '::1'
94
95
  physical_nic = FactoryBot.build(:nic_base_empty, :identifier => 'net0', :ip => ip, :ip6 => ip6)
95
- host = FactoryBot.build(:host_empty, :interfaces => [physical_nic], :compute_attributes => {'type' => 'qemu'})
96
+ host = FactoryBot.build(:host_empty, :interfaces => [physical_nic], :compute_attributes => {'type' => 'qemu', 'interfaces_attributes' => { '0' => physical_nic }})
96
97
  nic_attributes = @cr.host_interfaces_attrs(host).values.select(&:present?)
97
98
  nic_attr = nic_attributes.first
98
99
  assert_equal 'net0', nic_attr[:id]
@@ -109,7 +110,7 @@ module ForemanFogProxmox
109
110
  it "raises Foreman::Exception when server ostype does not match os family" do
110
111
  operatingsystem = FactoryBot.build(:solaris)
111
112
  physical_nic = FactoryBot.build(:nic_base_empty, :identifier => 'net0', :primary => true)
112
- host = FactoryBot.build(:host_empty, :interfaces => [physical_nic], :operatingsystem => operatingsystem, :compute_attributes => { 'type' => 'qemu', 'config_attributes' => { 'ostype' => 'l26' } })
113
+ host = FactoryBot.build(:host_empty, :interfaces => [physical_nic], :operatingsystem => operatingsystem, :compute_attributes => { 'type' => 'qemu', 'config_attributes' => { 'ostype' => 'l26' }, 'interfaces_attributes' => { '0' => physical_nic } })
113
114
  err = assert_raises Foreman::Exception do
114
115
  @cr.host_compute_attrs(host)
115
116
  end
@@ -118,7 +119,7 @@ module ForemanFogProxmox
118
119
 
119
120
  it "sets container hostname with host name" do
120
121
  physical_nic = FactoryBot.build(:nic_base_empty, :identifier => 'net0', :primary => true)
121
- host = FactoryBot.build(:host_empty, :interfaces => [physical_nic], :compute_attributes => { 'type' => 'lxc', 'config_attributes' => { 'hostname' => '' } })
122
+ host = FactoryBot.build(:host_empty, :interfaces => [physical_nic], :compute_attributes => { 'type' => 'lxc', 'config_attributes' => { 'hostname' => '' }, 'interfaces_attributes' => { '0' => {} } })
122
123
  @cr.host_compute_attrs(host)
123
124
  assert_equal host.name, host.compute_attributes['config_attributes']['hostname']
124
125
  end
@@ -164,7 +165,7 @@ module ForemanFogProxmox
164
165
  @cr = FactoryBot.build_stubbed(:proxmox_cr)
165
166
  end
166
167
 
167
- it 'saves modified server config' do
168
+ it 'saves modified server config with same volumes' do
168
169
  uuid = '100'
169
170
  config = mock('config')
170
171
  config.stubs(:attributes).returns({ :cores => '' })
@@ -180,6 +181,165 @@ module ForemanFogProxmox
180
181
  @cr.save_vm(uuid,attr)
181
182
  end
182
183
 
184
+ it 'saves server as template' do
185
+ uuid = '100'
186
+ config = mock('config')
187
+ config.stubs(:attributes).returns({ :cores => '' })
188
+ vm = mock('vm')
189
+ vm.stubs(:config).returns(config)
190
+ vm.stubs(:container?).returns(false)
191
+ vm.stubs(:templated?).returns(false)
192
+ vm.stubs(:type).returns('qemu')
193
+ @cr.stubs(:find_vm_by_uuid).returns(vm)
194
+ attr = { 'templated' => '1' }
195
+ vm.expects(:create_template)
196
+ @cr.save_vm(uuid,attr)
197
+ end
198
+
199
+ it 'saves modified server config with added volumes' do
200
+ uuid = '100'
201
+ config = mock('config')
202
+ disks = mock('disks')
203
+ disk = mock('disk')
204
+ disk.stubs(:size).returns(1073741824)
205
+ disk.stubs(:storage).returns('local-lvm')
206
+ disk.stubs(:id).returns('virtio0')
207
+ disks.stubs(:get).returns()
208
+ config.stubs(:disks).returns(disks)
209
+ config.stubs(:attributes).returns({ :cores => '' })
210
+ vm = mock('vm')
211
+ vm.stubs(:config).returns(config)
212
+ vm.stubs(:container?).returns(false)
213
+ vm.stubs(:type).returns('qemu')
214
+ @cr.stubs(:find_vm_by_uuid).returns(vm)
215
+ new_attributes = { 'templated' => '0', 'config_attributes' => { 'cores' => '1', 'cpulimit' => '1' }, 'volumes_attributes' => { '0'=> { 'id' => 'scsi0', 'storage' => 'local-lvm', 'size' => '2147483648', 'cache' => 'none' } } }
216
+ @cr.stubs(:parse_server_vm).returns({ 'vmid' => '100', 'type' => 'qemu', 'cores' => '1', 'cpulimit' => '1' })
217
+ expected_config_attr = { :cores => '1', :cpulimit => '1' }
218
+ expected_volume_attr = { id: 'scsi0', storage: 'local:lvm', size: (2147483648 / GIGA).to_s }
219
+ vm.expects(:attach, expected_volume_attr)
220
+ vm.expects(:update, expected_config_attr)
221
+ @cr.save_vm(uuid,new_attributes)
222
+ end
223
+
224
+ it 'saves modified server config with removed volumes' do
225
+ uuid = '100'
226
+ config = mock('config')
227
+ disks = mock('disks')
228
+ disk = mock('disk')
229
+ disk.stubs(:size).returns(1073741824)
230
+ disk.stubs(:storage).returns('local-lvm')
231
+ disk.stubs(:id).returns('virtio0')
232
+ disks.stubs(:get).returns(disk)
233
+ config.stubs(:disks).returns(disks)
234
+ config.stubs(:attributes).returns({ :cores => '' })
235
+ vm = mock('vm')
236
+ vm.stubs(:config).returns(config)
237
+ vm.stubs(:container?).returns(false)
238
+ vm.stubs(:type).returns('qemu')
239
+ @cr.stubs(:find_vm_by_uuid).returns(vm)
240
+ new_attributes = { 'templated' => '0', 'config_attributes' => { 'cores' => '1', 'cpulimit' => '1' }, 'volumes_attributes' => { '0'=> { '_delete' => '1', 'id' => 'scsi0', 'storage' => 'local-lvm', 'size' => '2147483648', 'cache' => 'none' } } }
241
+ @cr.stubs(:parse_server_vm).returns({ 'vmid' => '100', 'type' => 'qemu', 'cores' => '1', 'cpulimit' => '1' })
242
+ expected_config_attr = { :cores => '1', :cpulimit => '1' }
243
+ expected_volume_attr = 'scsi0'
244
+ vm.expects(:detach, expected_volume_attr)
245
+ vm.expects(:detach, 'unused0')
246
+ vm.expects(:update, expected_config_attr)
247
+ @cr.save_vm(uuid,new_attributes)
248
+ end
249
+
250
+ it 'saves modified server config with removed interfaces' do
251
+ uuid = '100'
252
+ config = mock('config')
253
+ interfaces = mock('interfaces')
254
+ interface = mock('interface')
255
+ interface.stubs(:id).returns('net0')
256
+ interfaces.stubs(:get).returns(interface)
257
+ config.stubs(:interfaces).returns(interfaces)
258
+ config.stubs(:attributes).returns({ :cores => '' })
259
+ vm = mock('vm')
260
+ vm.stubs(:config).returns(config)
261
+ vm.stubs(:container?).returns(false)
262
+ vm.stubs(:type).returns('qemu')
263
+ @cr.stubs(:find_vm_by_uuid).returns(vm)
264
+ new_attributes = { 'templated' => '0', 'config_attributes' => { 'cores' => '1', 'cpulimit' => '1' }, 'interfaces_attributes' => { '0'=> { '_delete' => '1', 'id' => 'net0' } } }
265
+ @cr.stubs(:parse_server_vm).returns({ 'vmid' => '100', 'type' => 'qemu', 'cores' => '1', 'cpulimit' => '1', 'delete' => 'net0' })
266
+ expected_config_attr = { :cores => '1', :cpulimit => '1', :delete => 'net0' }
267
+ vm.expects(:update, expected_config_attr)
268
+ @cr.save_vm(uuid,new_attributes)
269
+ end
270
+
271
+ it 'saves modified server config with resized volumes' do
272
+ uuid = '100'
273
+ config = mock('config')
274
+ disks = mock('disks')
275
+ disk = mock('disk')
276
+ disk.stubs(:size).returns(1073741824)
277
+ disk.stubs(:storage).returns('local-lvm')
278
+ disks.stubs(:get).returns(disk)
279
+ config.stubs(:disks).returns(disks)
280
+ config.stubs(:attributes).returns({ :cores => '' })
281
+ vm = mock('vm')
282
+ vm.stubs(:config).returns(config)
283
+ vm.stubs(:container?).returns(false)
284
+ vm.stubs(:type).returns('qemu')
285
+ @cr.stubs(:find_vm_by_uuid).returns(vm)
286
+ new_attributes = { 'templated' => '0', 'config_attributes' => { 'cores' => '1', 'cpulimit' => '1' }, 'volumes_attributes' => { '0'=> { 'id' => 'scsi0', 'storage' => 'local-lvm', 'size' => '2147483648', 'cache' => 'none' } } }
287
+ @cr.stubs(:parse_server_vm).returns({ 'vmid' => '100', 'type' => 'qemu', 'cores' => '1', 'cpulimit' => '1' })
288
+ expected_config_attr = { :cores => '1', :cpulimit => '1' }
289
+ expected_volume_attr = ['scsi0', '+1G']
290
+ vm.expects(:extend, expected_volume_attr)
291
+ vm.expects(:update, expected_config_attr)
292
+ @cr.save_vm(uuid,new_attributes)
293
+ end
294
+
295
+ it 'raises error unable to shrink volumes' do
296
+ uuid = '100'
297
+ config = mock('config')
298
+ disks = mock('disks')
299
+ disk = mock('disk')
300
+ disk.stubs(:size).returns(1073741824)
301
+ disk.stubs(:storage).returns('local-lvm')
302
+ disks.stubs(:get).returns(disk)
303
+ config.stubs(:disks).returns(disks)
304
+ config.stubs(:attributes).returns({ :cores => '' })
305
+ vm = mock('vm')
306
+ vm.stubs(:config).returns(config)
307
+ vm.stubs(:container?).returns(false)
308
+ vm.stubs(:type).returns('qemu')
309
+ @cr.stubs(:find_vm_by_uuid).returns(vm)
310
+ new_attributes = { 'templated' => '0', 'config_attributes' => { 'cores' => '1', 'cpulimit' => '1' }, 'volumes_attributes' => { '0'=> { 'id' => 'scsi0', 'storage' => 'local-lvm', 'size' => '2', 'cache' => 'none' } } }
311
+ @cr.stubs(:parse_server_vm).returns({ 'vmid' => '100', 'type' => 'qemu', 'cores' => '1', 'cpulimit' => '1' })
312
+ expected_config_attr = { :cores => '1', :cpulimit => '1' }
313
+ err = assert_raises Foreman::Exception do
314
+ @cr.save_vm(uuid,new_attributes)
315
+ end
316
+ assert err.message.end_with?('Unable to shrink scsi0 size. Proxmox allows only increasing size.')
317
+ end
318
+
319
+ it 'saves modified server config with moved volumes' do
320
+ uuid = '100'
321
+ config = mock('config')
322
+ disks = mock('disks')
323
+ disk = mock('disk')
324
+ disk.stubs(:size).returns(1073741824)
325
+ disk.stubs(:storage).returns('local-lvm')
326
+ disks.stubs(:get).returns(disk)
327
+ config.stubs(:disks).returns(disks)
328
+ config.stubs(:attributes).returns({ :cores => '' })
329
+ vm = mock('vm')
330
+ vm.stubs(:config).returns(config)
331
+ vm.stubs(:container?).returns(false)
332
+ vm.stubs(:type).returns('qemu')
333
+ @cr.stubs(:find_vm_by_uuid).returns(vm)
334
+ new_attributes = { 'templated' => '0', 'config_attributes' => { 'cores' => '1', 'cpulimit' => '1' }, 'volumes_attributes' => { '0'=> { 'id' => 'scsi0', 'storage' => 'local-lvm2', 'size' => '1073741824', 'cache' => 'none' } } }
335
+ @cr.stubs(:parse_server_vm).returns({ 'vmid' => '100', 'type' => 'qemu', 'cores' => '1', 'cpulimit' => '1' })
336
+ expected_config_attr = { :cores => '1', :cpulimit => '1' }
337
+ expected_volume_attr = ['scsi0', 'local-lvm2']
338
+ vm.expects(:move, expected_volume_attr)
339
+ vm.expects(:update, expected_config_attr)
340
+ @cr.save_vm(uuid,new_attributes)
341
+ end
342
+
183
343
  it 'saves modified container config' do
184
344
  uuid = '100'
185
345
  config = mock('config')
@@ -190,11 +350,61 @@ module ForemanFogProxmox
190
350
  vm.stubs(:type).returns('lxc')
191
351
  @cr.stubs(:find_vm_by_uuid).returns(vm)
192
352
  attr = { 'templated' => '0', 'config_attributes' => { 'cores' => '1', 'cpulimit' => '1' } }
193
- @cr.stubs(:parse_container_vm).returns({ 'vmid' => '100', 'type' => 'qemu', 'cores' => '1', 'cpulimit' => '1' })
353
+ @cr.stubs(:parse_container_vm).returns({ 'vmid' => '100', 'type' => 'lxc', 'cores' => '1', 'cpulimit' => '1' })
194
354
  expected_attr = { :cores => '1', :cpulimit => '1' }
195
355
  vm.expects(:update, expected_attr)
196
356
  @cr.save_vm(uuid,attr)
197
357
  end
358
+
359
+ it 'saves modified container config with added volumes' do
360
+ uuid = '100'
361
+ config = mock('config')
362
+ disks = mock('disks')
363
+ disk = mock('disk')
364
+ disk.stubs(:size).returns(1073741824)
365
+ disk.stubs(:storage).returns('local-lvm')
366
+ disk.stubs(:id).returns('rootfs')
367
+ disks.stubs(:get).returns()
368
+ config.stubs(:disks).returns(disks)
369
+ config.stubs(:attributes).returns({ :cores => '' })
370
+ vm = mock('vm')
371
+ vm.stubs(:config).returns(config)
372
+ vm.stubs(:container?).returns(false)
373
+ vm.stubs(:type).returns('lxc')
374
+ @cr.stubs(:find_vm_by_uuid).returns(vm)
375
+ new_attributes = { 'templated' => '0', 'config_attributes' => { 'cores' => '1', 'cpulimit' => '1' }, 'volumes_attributes' => { '0'=> { 'id' => 'mp0', 'storage' => 'local-lvm', 'size' => '2147483648', 'cache' => 'none', 'mp' => '/opt/path' } } }
376
+ @cr.stubs(:parse_container_vm).returns({ 'vmid' => '100', 'type' => 'lxc', 'cores' => '1', 'cpulimit' => '1' })
377
+ expected_config_attr = { :cores => '1', :cpulimit => '1' }
378
+ expected_volume_attr = [{ id: 'mp0', storage: 'local:lvm', size: (2147483648 / GIGA).to_s }, { mp: '/opt/path' }]
379
+ vm.expects(:attach, expected_volume_attr)
380
+ vm.expects(:update, expected_config_attr)
381
+ @cr.save_vm(uuid,new_attributes)
382
+ end
383
+
384
+ it 'saves modified container config with resized volumes' do
385
+ uuid = '100'
386
+ config = mock('config')
387
+ disks = mock('disks')
388
+ disk = mock('disk')
389
+ disk.stubs(:size).returns(1073741824)
390
+ disk.stubs(:storage).returns('local-lvm')
391
+ disk.stubs(:id).returns('rootfs')
392
+ disks.stubs(:get).returns(disk)
393
+ config.stubs(:disks).returns(disks)
394
+ config.stubs(:attributes).returns({ :cores => '' })
395
+ vm = mock('vm')
396
+ vm.stubs(:config).returns(config)
397
+ vm.stubs(:container?).returns(false)
398
+ vm.stubs(:type).returns('lxc')
399
+ @cr.stubs(:find_vm_by_uuid).returns(vm)
400
+ new_attributes = { 'templated' => '0', 'config_attributes' => { 'cores' => '1', 'cpulimit' => '1' }, 'volumes_attributes' => { '0'=> { 'id' => 'rootfs', 'storage' => 'local-lvm', 'size' => '2147483648', 'cache' => 'none' } } }
401
+ @cr.stubs(:parse_container_vm).returns({ 'vmid' => '100', 'type' => 'lxc', 'cores' => '1', 'cpulimit' => '1' })
402
+ expected_config_attr = { :cores => '1', :cpulimit => '1' }
403
+ expected_volume_attr = ['rootfs', '+1G']
404
+ vm.expects(:extend, expected_volume_attr)
405
+ vm.expects(:update, expected_config_attr)
406
+ @cr.save_vm(uuid,new_attributes)
407
+ end
198
408
  end
199
409
 
200
410
  describe 'create_vm' do