foreman_fog_proxmox 0.13.4 → 0.14.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (78) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +63 -52
  3. data/app/assets/javascripts/foreman_fog_proxmox/proxmox_compute_resource.js +0 -2
  4. data/app/assets/javascripts/foreman_fog_proxmox/proxmox_vm.js +0 -1
  5. data/app/assets/javascripts/foreman_fog_proxmox/proxmox_vm_server.js +0 -2
  6. data/app/assets/javascripts/foreman_fog_proxmox/proxmox_volume_cloudinit.js +0 -1
  7. data/app/controllers/concerns/foreman_fog_proxmox/compute_resources_vms_controller.rb +17 -7
  8. data/app/controllers/concerns/foreman_fog_proxmox/controller/parameters/compute_resource.rb +1 -1
  9. data/app/controllers/concerns/foreman_fog_proxmox/hosts_controller.rb +58 -0
  10. data/app/controllers/foreman_fog_proxmox/compute_resources_controller.rb +6 -3
  11. data/app/helpers/proxmox_compute_controllers_helper.rb +2 -1
  12. data/app/helpers/proxmox_compute_resources_helper.rb +3 -3
  13. data/app/helpers/proxmox_compute_resources_vms_helper.rb +16 -7
  14. data/app/helpers/proxmox_form_helper.rb +10 -6
  15. data/app/helpers/proxmox_vm_config_helper.rb +16 -25
  16. data/app/helpers/proxmox_vm_interfaces_helper.rb +19 -6
  17. data/app/helpers/proxmox_vm_os_template_helper.rb +2 -5
  18. data/app/helpers/proxmox_vm_uuid_helper.rb +1 -1
  19. data/app/helpers/proxmox_vm_volumes_helper.rb +22 -25
  20. data/app/models/concerns/fog_extensions/proxmox/node.rb +2 -2
  21. data/app/models/concerns/fog_extensions/proxmox/server.rb +10 -6
  22. data/app/models/concerns/host_ext/proxmox/associator.rb +3 -2
  23. data/app/models/concerns/host_ext/proxmox/for_vm.rb +1 -1
  24. data/app/models/concerns/host_ext/proxmox/interfaces.rb +7 -3
  25. data/app/models/concerns/orchestration/proxmox/compute.rb +11 -4
  26. data/app/models/foreman_fog_proxmox/options_select.rb +1 -3
  27. data/app/models/foreman_fog_proxmox/proxmox.rb +12 -10
  28. data/app/models/foreman_fog_proxmox/proxmox_compute_attributes.rb +15 -3
  29. data/app/models/foreman_fog_proxmox/proxmox_connection.rb +6 -2
  30. data/app/models/foreman_fog_proxmox/proxmox_console.rb +3 -1
  31. data/app/models/foreman_fog_proxmox/proxmox_images.rb +2 -2
  32. data/app/models/foreman_fog_proxmox/proxmox_interfaces.rb +37 -14
  33. data/app/models/foreman_fog_proxmox/proxmox_operating_systems.rb +6 -1
  34. data/app/models/foreman_fog_proxmox/proxmox_pools.rb +4 -4
  35. data/app/models/foreman_fog_proxmox/proxmox_version.rb +7 -3
  36. data/app/models/foreman_fog_proxmox/proxmox_vm_commands.rb +9 -7
  37. data/app/models/foreman_fog_proxmox/proxmox_vm_new.rb +37 -24
  38. data/app/models/foreman_fog_proxmox/proxmox_vm_queries.rb +4 -5
  39. data/app/models/foreman_fog_proxmox/proxmox_volumes.rb +23 -12
  40. data/app/models/foreman_fog_proxmox/vms.rb +2 -2
  41. data/app/overrides/compute_resources_vms/form/add_clone_to_new_vm_compute_detail.rb +1 -1
  42. data/app/views/compute_resources_vms/form/proxmox/_add_from_profile_to_compute_form.html.erb +2 -2
  43. data/app/views/compute_resources_vms/form/proxmox/_add_from_profile_to_hosts_compute_detail_form.html.erb +4 -2
  44. data/app/views/compute_resources_vms/form/proxmox/_base.html.erb +0 -1
  45. data/app/views/compute_resources_vms/form/proxmox/container/_config.html.erb +2 -2
  46. data/app/views/compute_resources_vms/form/proxmox/container/_network.html.erb +1 -1
  47. data/app/views/compute_resources_vms/form/proxmox/container/_volume_mp.html.erb +1 -1
  48. data/app/views/compute_resources_vms/form/proxmox/container/_volume_rootfs.html.erb +1 -1
  49. data/app/views/compute_resources_vms/form/proxmox/server/_config.html.erb +3 -3
  50. data/app/views/compute_resources_vms/form/proxmox/server/_network.html.erb +2 -2
  51. data/app/views/compute_resources_vms/form/proxmox/server/_volume_hard_disk.html.erb +1 -1
  52. data/config/routes.rb +8 -4
  53. data/db/migrate/20210312105013_update_proxmox_uuid_host.rb +1 -2
  54. data/lib/foreman_fog_proxmox/engine.rb +5 -3
  55. data/lib/foreman_fog_proxmox/semver.rb +1 -4
  56. data/lib/foreman_fog_proxmox/version.rb +1 -1
  57. data/locale/en/foreman_fog_proxmox.po +140 -47
  58. data/locale/foreman_fog_proxmox.pot +300 -137
  59. data/locale/fr/foreman_fog_proxmox.po +145 -52
  60. data/test/factories/foreman_fog_proxmox/proxmox_container_mock_factory.rb +6 -7
  61. data/test/factories/foreman_fog_proxmox/proxmox_server_mock_factory.rb +6 -7
  62. data/test/functional/compute_resources_controller_test.rb +4 -2
  63. data/test/test_plugin_helper.rb +12 -7
  64. data/test/unit/foreman_fog_proxmox/helpers/proxmox_container_helper_test.rb +38 -47
  65. data/test/unit/foreman_fog_proxmox/helpers/proxmox_server_helper_test.rb +49 -34
  66. data/test/unit/foreman_fog_proxmox/helpers/proxmox_vm_helper_test.rb +29 -65
  67. data/test/unit/foreman_fog_proxmox/helpers/proxmox_vm_volumes_helper_test.rb +3 -3
  68. data/test/unit/foreman_fog_proxmox/proxmox_compute_attributes_test.rb +22 -13
  69. data/test/unit/foreman_fog_proxmox/proxmox_interfaces_test.rb +48 -37
  70. data/test/unit/foreman_fog_proxmox/proxmox_vm_commands_container_test.rb +45 -35
  71. data/test/unit/foreman_fog_proxmox/proxmox_vm_commands_server_create_test.rb +0 -4
  72. data/test/unit/foreman_fog_proxmox/proxmox_vm_commands_server_update_cdrom_test.rb +34 -22
  73. data/test/unit/foreman_fog_proxmox/proxmox_vm_commands_server_update_cloudinit_test.rb +20 -14
  74. data/test/unit/foreman_fog_proxmox/proxmox_vm_commands_server_update_hard_disk_test.rb +76 -54
  75. data/test/unit/foreman_fog_proxmox/proxmox_vm_commands_server_update_test.rb +26 -15
  76. data/test/unit/foreman_fog_proxmox/proxmox_vm_queries_test.rb +1 -1
  77. data/test/unit/foreman_fog_proxmox/semver_test.rb +2 -1
  78. metadata +36 -21
@@ -27,8 +27,14 @@ module ForemanFogProxmox
27
27
  end
28
28
 
29
29
  def set_nic_identifier(nic, index)
30
- nic.identifier = format('net%<index>s', index: index) if nic.identifier.empty?
31
- raise ::Foreman::Exception, _(format('Invalid identifier interface[%<index>s]. Must be net[n] with n integer >= 0', index: index)) unless Fog::Proxmox::NicHelper.nic?(nic.identifier)
30
+ nic.compute_attributes[:id] = format('net%<index>s', index: index) if nic.compute_attributes[:id].empty?
31
+ unless Fog::Proxmox::NicHelper.nic?(nic.compute_attributes[:id])
32
+ raise ::Foreman::Exception,
33
+ _(format('Invalid proxmox NIC id on interface[%<index>s]. Must be net[n] with n integer >= 0',
34
+ index: index))
35
+ end
36
+
37
+ nic.identifier = nic.compute_attributes['id'] if nic.identifier.empty?
32
38
  end
33
39
 
34
40
  def vm_type(host)
@@ -47,7 +53,11 @@ module ForemanFogProxmox
47
53
 
48
54
  def set_container_interface_name(_host, nic, index)
49
55
  nic.compute_attributes['name'] = format('eth%<index>s', index: index) if nic.compute_attributes['name'].empty?
50
- raise ::Foreman::Exception, _(format('Invalid name interface[%<index>s]. Must be eth[n] with n integer >= 0', index: index)) unless container_nic_name_valid?(nic)
56
+ unless container_nic_name_valid?(nic)
57
+ raise ::Foreman::Exception,
58
+ _(format('Invalid name interface[%<index>s]. Must be eth[n] with n integer >= 0',
59
+ index: index))
60
+ end
51
61
  end
52
62
 
53
63
  def cidr_prefix(nic_compute_attributes, v6 = false)
@@ -64,7 +74,9 @@ module ForemanFogProxmox
64
74
  ipv = "IPv#{v6 ? '6' : '4'}"
65
75
  max = v6 ? 128 : 32
66
76
  checked = valid || ForemanFogProxmox::Value.empty?(ip)
67
- message = format('Invalid Interface Proxmox CIDR %<ip>s. If %<ip>s is not empty, Proxmox CIDR prefix must be an integer between 0 and %<max>i.', ip: ipv, max: max)
77
+ message = format(
78
+ 'Invalid Interface Proxmox CIDR %<ip>s. If %<ip>s is not empty, Proxmox CIDR prefix must be an integer between 0 and %<max>i.', ip: ipv, max: max
79
+ )
68
80
  raise ::Foreman::Exception, _(message) unless checked
69
81
  end
70
82
 
@@ -87,7 +99,10 @@ module ForemanFogProxmox
87
99
  ip = 'dhcp'
88
100
  elsif !ForemanFogProxmox::Value.empty?(cidr_prefix(nic_compute_attributes, v6))
89
101
  check_cidr(nic_compute_attributes, v6, ip)
90
- ip = Fog::Proxmox::IpHelper.send(to_cidr_method(v6), nic.send(ip_s(v6).to_sym), cidr_prefix(nic_compute_attributes, v6)) if ip
102
+ if ip
103
+ ip = Fog::Proxmox::IpHelper.send(to_cidr_method(v6), nic.send(ip_s(v6).to_sym),
104
+ cidr_prefix(nic_compute_attributes, v6))
105
+ end
91
106
  end
92
107
  end
93
108
  nic_compute_attributes[ip_s(v6).to_sym] = ip
@@ -112,17 +127,25 @@ module ForemanFogProxmox
112
127
  host.interfaces.select(&:physical?).each.with_index.reduce({}) do |hash, (nic, index)|
113
128
  set_nic_identifier(nic, index)
114
129
  set_container_interface_name(host, nic, index) if container?(host)
115
- nic_compute_attributes = nic.compute_attributes.merge(id: nic.identifier)
116
- ForemanFogProxmox::HashCollection.remove_empty_values(nic_compute_attributes)
130
+ ForemanFogProxmox::HashCollection.remove_empty_values(nic.compute_attributes)
117
131
  mac = nic.mac
118
132
  mac ||= nic.attributes['mac']
119
- set_mac(nic_compute_attributes, mac, vm_type(host)) if mac.present?
120
- interface_compute_attributes = host.compute_attributes['interfaces_attributes'] ? host.compute_attributes['interfaces_attributes'].select { |_k, v| v['id'] == nic.identifier } : {}
121
- nic_compute_attributes.store(:_delete, interface_compute_attributes[interface_compute_attributes.keys[0]]['_delete']) unless interface_compute_attributes.empty?
122
- set_ip(host, nic, nic_compute_attributes)
123
- set_ip(host, nic, nic_compute_attributes, true)
124
- ForemanFogProxmox::HashCollection.remove_keys(nic_compute_attributes, ['dhcp', 'dhcp6', 'cidr', 'cidr6'])
125
- hash.merge(index.to_s => nic_compute_attributes)
133
+ set_mac(nic.compute_attributes, mac, vm_type(host)) if mac.present?
134
+ interface_compute_attributes = if host.compute_attributes['interfaces_attributes']
135
+ host.compute_attributes['interfaces_attributes'].select do |_k, v|
136
+ v['id'] == nic.compute_attributes[:id]
137
+ end
138
+ else
139
+ {}
140
+ end
141
+ unless interface_compute_attributes.empty?
142
+ nic.compute_attributes.store(:_delete,
143
+ interface_compute_attributes[interface_compute_attributes.keys[0]]['_delete'])
144
+ end
145
+ set_ip(host, nic, nic.compute_attributes)
146
+ set_ip(host, nic, nic.compute_attributes, true)
147
+ ForemanFogProxmox::HashCollection.remove_keys(nic.compute_attributes, ['dhcp', 'dhcp6', 'cidr', 'cidr6'])
148
+ hash.merge(index.to_s => nic.compute_attributes)
126
149
  end
127
150
  end
128
151
  end
@@ -39,7 +39,12 @@ module ForemanFogProxmox
39
39
  end
40
40
 
41
41
  def os_linux_types_mapping(host)
42
- ['Debian', 'Redhat', 'Suse', 'Altlinux', 'Archlinux', 'Coreos', 'Rancheros', 'Gentoo'].include?(host.operatingsystem.type) ? available_linux_operating_systems : []
42
+ if ['Debian', 'Redhat', 'Suse', 'Altlinux', 'Archlinux', 'Coreos', 'Rancheros',
43
+ 'Gentoo'].include?(host.operatingsystem.type)
44
+ available_linux_operating_systems
45
+ else
46
+ []
47
+ end
43
48
  end
44
49
 
45
50
  def os_windows_types_mapping(host)
@@ -25,21 +25,21 @@ module ForemanFogProxmox
25
25
  end
26
26
 
27
27
  def pool_owner(vm)
28
- logger.debug(format(_('pool_owner(%<vmid>s)'), vmid: vm&.vmid))
28
+ logger.debug("pool_owner(#{vm&.vmid})")
29
29
  pools_owners = pools.select { |pool| pool.has_server?(vm&.vmid) }
30
30
  pool = pools_owners.first
31
- logger.debug(format(_('found vm: %<vmid>s member of pool: %<poolid>s'), vmid: vm&.vmid, poolid: pool&.poolid))
31
+ logger.debug("found vm: #{vm&.vmid} member of pool: #{pool&.poolid}")
32
32
  vm&.config&.pool = pool&.poolid
33
33
  end
34
34
 
35
35
  def add_vm_to_pool(poolid, vmid)
36
- logger.debug(format(_('add_vm_to_pool(%<poolid>s, %<vmid>s)'), poolid: poolid, vmid: vmid))
36
+ logger.debug("add_vm_to_pool(#{poolid}, #{vmid})")
37
37
  pool = identity_client.pools.get poolid
38
38
  pool&.add_server vmid
39
39
  end
40
40
 
41
41
  def remove_vm_from_pool(poolid, vmid)
42
- logger.debug(format(_('remove_vm_from_pool(%<poolid>s, %<vmid>s)'), poolid: poolid, vmid: vmid))
42
+ logger.debug("remove_vm_from_pool(#{poolid}, #{vmid})")
43
43
  pool = identity_client.pools.get poolid
44
44
  pool&.remove_server vmid
45
45
  end
@@ -22,8 +22,12 @@ require 'foreman_fog_proxmox/semver'
22
22
  module ForemanFogProxmox
23
23
  module ProxmoxVersion
24
24
  def version_suitable?
25
- logger.debug(format(_('Proxmox compute resource version is %<version>s'), version: version))
26
- raise ::Foreman::Exception, format(_('Proxmox version %<version>s is not semver suitable'), version: version) unless ForemanFogProxmox::Semver.semver?(version)
25
+ logger.debug("Proxmox compute resource version is #{version}")
26
+ unless ForemanFogProxmox::Semver.semver?(version)
27
+ raise ::Foreman::Exception,
28
+ format(_('Proxmox version %<version>s is not semver suitable'),
29
+ version: version)
30
+ end
27
31
 
28
32
  ForemanFogProxmox::Semver.to_semver(version) >= ForemanFogProxmox::Semver.to_semver('5.3.0')
29
33
  end
@@ -34,7 +38,7 @@ module ForemanFogProxmox
34
38
  rescue ::Foreman::Exception => e
35
39
  return 'Unkown' if e.message == 'User token expired'
36
40
  rescue StandardError => e
37
- logger.warn(format(_('failed to get identity client version: %<e>s'), e: e))
41
+ logger.warn("failed to get identity client version: #{e}")
38
42
  raise e
39
43
  end
40
44
  end
@@ -42,14 +42,13 @@ module ForemanFogProxmox
42
42
  if image_id
43
43
  clone_from_image(image_id, args, vmid)
44
44
  else
45
- convert_sizes(args)
46
45
  remove_volume_keys(args)
47
- logger.warn(format(_('create vm: args=%<args>s'), args: args))
46
+ logger.warn("create vm: args=#{args}")
48
47
  vm = node.send(vm_collection(type)).create(parse_typed_vm(args, type))
49
48
  start_on_boot(vm, args)
50
49
  end
51
50
  rescue StandardError => e
52
- logger.warn(format(_('failed to create vm: %<e>s'), e: e))
51
+ logger.warn("failed to create vm: #{e}")
53
52
  destroy_vm client.identity + '_' + vm.id if vm
54
53
  raise e
55
54
  end
@@ -74,7 +73,8 @@ module ForemanFogProxmox
74
73
  end
75
74
 
76
75
  def compute_config_attributes(parsed_attr)
77
- excluded_keys = [:vmid, :templated, :ostemplate, :ostemplate_file, :ostemplate_storage, :volumes_attributes, :pool]
76
+ excluded_keys = [:vmid, :templated, :ostemplate, :ostemplate_file, :ostemplate_storage, :volumes_attributes,
77
+ :pool]
78
78
  config_attributes = parsed_attr.reject { |key, _value| excluded_keys.include? key.to_sym }
79
79
  ForemanFogProxmox::HashCollection.remove_empty_values(config_attributes)
80
80
  config_attributes = config_attributes.reject { |key, _value| Fog::Proxmox::DiskHelper.disk?(key) }
@@ -90,11 +90,13 @@ module ForemanFogProxmox
90
90
  elsif vm.node_id != node_id
91
91
  vm.migrate(node_id)
92
92
  else
93
- convert_memory_sizes(new_attributes)
94
- parsed_attr = parse_typed_vm(ForemanFogProxmox::HashCollection.new_hash_reject_keys(new_attributes, ['volumes_attributes']).merge(type: vm.type), vm.type)
93
+ parsed_attr = parse_typed_vm(
94
+ ForemanFogProxmox::HashCollection.new_hash_reject_keys(new_attributes,
95
+ ['volumes_attributes']).merge(type: vm.type), vm.type
96
+ )
95
97
  config_attributes = compute_config_attributes(parsed_attr)
96
98
  volumes_attributes = new_attributes['volumes_attributes']
97
- logger.debug(format(_('save_vm(%<vmid>s) volumes_attributes=%<volumes_attributes>s'), vmid: uuid, volumes_attributes: volumes_attributes))
99
+ logger.debug("save_vm(#{uuid}) volumes_attributes=#{volumes_attributes}")
98
100
  volumes_attributes&.each_value { |volume_attributes| save_volume(vm, volume_attributes) }
99
101
  vm.update(config_attributes[:config_attributes])
100
102
  poolid = new_attributes['pool'] if new_attributes.key?('pool')
@@ -36,7 +36,7 @@ module ForemanFogProxmox
36
36
 
37
37
  def hard_disk_typed_defaults(vm_type)
38
38
  options = {}
39
- volume_attributes_h = { storage: storages.first.identity.to_s, size: (8 * GIGA) }
39
+ volume_attributes_h = { storage: storages.first.identity.to_s, size: '8' }
40
40
  case vm_type
41
41
  when 'qemu'
42
42
  controller = 'virtio'
@@ -74,8 +74,14 @@ module ForemanFogProxmox
74
74
 
75
75
  def interface_typed_defaults(type)
76
76
  interface_attributes_h = { id: 'net0', compute_attributes: {} }
77
- interface_attributes_h[:compute_attributes] = { model: 'virtio', bridge: bridges.first.identity.to_s } if type == 'qemu'
78
- interface_attributes_h[:compute_attributes] = { name: 'eth0', bridge: bridges.first.identity.to_s, dhcp: 1, dhcp6: 1 } if type == 'lxc'
77
+ if type == 'qemu'
78
+ interface_attributes_h[:compute_attributes] =
79
+ { model: 'virtio', bridge: bridges.first.identity.to_s }
80
+ end
81
+ if type == 'lxc'
82
+ interface_attributes_h[:compute_attributes] =
83
+ { name: 'eth0', bridge: bridges.first.identity.to_s, dhcp: 1, dhcp6: 1 }
84
+ end
79
85
  interface_attributes_h
80
86
  end
81
87
 
@@ -106,7 +112,7 @@ module ForemanFogProxmox
106
112
  interfaces_attributes = []
107
113
  interfaces_attributes.push(interface_typed_defaults(type))
108
114
  new_attr = new_attr.merge(interfaces_attributes: interfaces_attributes.map.with_index.to_h.invert)
109
- logger.debug(format(_('add_default_typed_interface(%<type>s) to new_attr=%<new_attr>s'), type: type, new_attr: new_attr))
115
+ logger.debug("add_default_typed_interface(#{type}) to new_attr=#{new_attr}")
110
116
  new_attr
111
117
  end
112
118
 
@@ -115,7 +121,7 @@ module ForemanFogProxmox
115
121
  volumes_attributes.push(hard_disk_typed_defaults('qemu'))
116
122
  volumes_attributes.push(hard_disk_typed_defaults('lxc'))
117
123
  new_attr = new_attr.merge(volumes_attributes: volumes_attributes.map.with_index.to_h.invert)
118
- logger.debug(format(_('add_default_typed_volume(%<type>s) to new_attr=%<new_attr>s'), type: type, new_attr: new_attr))
124
+ logger.debug("add_default_typed_volume(#{type}) to new_attr=#{new_attr}")
119
125
  new_attr
120
126
  end
121
127
 
@@ -127,29 +133,28 @@ module ForemanFogProxmox
127
133
  defaults = vm_instance_defaults
128
134
  defaults = defaults.merge(config_attributes: config_attributes(type))
129
135
  defaults = add_default_typed_volume(defaults)
130
- defaults = add_default_typed_interface(type, defaults)
131
- defaults
136
+ add_default_typed_interface(type, defaults)
132
137
  end
133
138
 
134
139
  def config_attributes(type = 'qemu')
135
140
  case type
136
141
  when 'qemu'
137
142
  config_attributes = {
138
- cores: 1,
139
- sockets: 1,
140
- kvm: 0,
143
+ cores: '1',
144
+ sockets: '1',
145
+ kvm: '0',
141
146
  vga: 'std',
142
- memory: 512 * MEGA,
147
+ memory: '1024',
143
148
  ostype: 'l26',
144
149
  cpu: 'cputype=kvm64',
145
150
  scsihw: 'virtio-scsi-pci',
146
- templated: 0
151
+ templated: '0',
147
152
  }
148
153
  config_attributes = config_attributes
149
154
  when 'lxc'
150
155
  config_attributes = {
151
- memory: 512 * MEGA,
152
- templated: 0
156
+ memory: '1024',
157
+ templated: '0',
153
158
  }
154
159
  end
155
160
  config_attributes
@@ -159,14 +164,21 @@ module ForemanFogProxmox
159
164
  new_attr = ActiveSupport::HashWithIndifferentAccess.new(new_attr)
160
165
  type = new_attr['type']
161
166
  type ||= 'qemu'
162
- vm = new_typed_vm(new_attr, type)
163
- vm
167
+ new_typed_vm(new_attr, type)
164
168
  end
165
169
 
166
170
  def convert_config_attributes(new_attr)
167
171
  config_attributes = new_attr[:config_attributes]
168
- config_attributes[:volumes_attributes] = Hash[config_attributes[:disks].each_with_index.map { |disk, idx| [idx.to_s, disk.attributes] }] if config_attributes.key?(:disks)
169
- config_attributes[:interfaces_attributes] = Hash[config_attributes[:interfaces].each_with_index.map { |interface, idx| [idx.to_s, interface_compute_attributes(interface.attributes)] }] if config_attributes.key?(:interfaces)
172
+ if config_attributes.key?(:disks)
173
+ config_attributes[:volumes_attributes] = Hash[config_attributes[:disks].each_with_index.map do |disk, idx|
174
+ [idx.to_s, disk.attributes]
175
+ end ]
176
+ end
177
+ if config_attributes.key?(:interfaces)
178
+ config_attributes[:interfaces_attributes] = Hash[config_attributes[:interfaces].each_with_index.map do |interface, idx|
179
+ [idx.to_s, interface_compute_attributes(interface.attributes)]
180
+ end ]
181
+ end
170
182
  config_attributes.delete_if { |key, _value| ['disks', 'interfaces'].include?(key) }
171
183
  end
172
184
 
@@ -177,14 +189,15 @@ module ForemanFogProxmox
177
189
  new_attr_type = new_attr['type']
178
190
  new_attr_type ||= new_attr['config_attributes']['type'] if new_attr.key?('config_attributes')
179
191
  new_attr_type ||= type
180
- logger.debug(format(_('new_typed_vm(%<type>s): new_attr_type=%<new_attr_type>s'), type: type, new_attr_type: new_attr_type))
181
- logger.debug(format(_('new_typed_vm(%<type>s): new_attr=%<new_attr>s'), type: type, new_attr: new_attr))
192
+ logger.debug("new_typed_vm(#{type}): new_attr_type=#{new_attr_type}")
193
+ logger.debug("new_typed_vm(#{type}): new_attr=#{new_attr}'")
182
194
  options = !new_attr.key?('vmid') || ForemanFogProxmox::Value.empty?(new_attr['vmid']) ? vm_typed_instance_defaults(type).merge(new_attr).merge(type: type) : new_attr
183
- logger.debug(format(_('new_typed_vm(%<type>s): options=%<options>s'), type: type, options: options))
195
+ logger.debug("new_typed_vm(#{type}): options=#{options}")
184
196
  vm_h = parse_typed_vm(options, type).deep_symbolize_keys
185
- logger.debug(format(_('new_typed_vm(%<type>s): vm_h=%<vm_h>s'), type: type, vm_h: vm_h))
186
- vm = node.send(vm_collection(type)).new(vm_h)
187
- vm
197
+ logger.debug("new_typed_vm(#{type}): vm_h=#{vm_h}")
198
+ vm_h = vm_h.merge(vm_typed_instance_defaults(type)) if vm_h.empty?
199
+ logger.debug(format(_('new_typed_vm(%<type>s) with vm_typed_instance_defaults: vm_h=%<vm_h>s'), type: type, vm_h: vm_h))
200
+ node.send(vm_collection(type)).new(vm_h)
188
201
  end
189
202
  end
190
203
  end
@@ -31,7 +31,7 @@ module ForemanFogProxmox
31
31
  node = client.nodes.get node_id
32
32
  node ||= default_node
33
33
  storages = node.storages.list_by_content_type type
34
- logger.debug(format(_('storages(): node_id %<node_id>s type %<type>s'), node_id: node_id, type: type))
34
+ logger.debug("storages(): node_id #{node_id} type #{type}")
35
35
  storages.sort_by(&:storage)
36
36
  end
37
37
 
@@ -61,10 +61,9 @@ module ForemanFogProxmox
61
61
  nodes.each do |node|
62
62
  vm = find_vm_in_servers_by_vmid(node.servers, vmid)
63
63
  vm ||= find_vm_in_servers_by_vmid(node.containers, vmid)
64
- unless vm.nil?
65
- logger.debug("found vm #{vmid} on node #{node.node}")
66
- break
67
- end
64
+ next if vm.nil?
65
+ logger.debug("found vm #{vmid} on node #{node.node}")
66
+ break
68
67
  end
69
68
  vm
70
69
  end
@@ -25,7 +25,7 @@ module ForemanFogProxmox
25
25
  include ProxmoxVmHelper
26
26
 
27
27
  def delete_volume(vm, id, volume_attributes)
28
- logger.info(format(_('vm %<vmid>s delete volume %<volume_id>s'), vmid: vm.identity, volume_id: id))
28
+ logger.info("vm #{vm.identity} delete volume #{id}")
29
29
  vm.detach(id)
30
30
  return unless volume_type?(volume_attributes, 'hard_disk')
31
31
 
@@ -36,7 +36,7 @@ module ForemanFogProxmox
36
36
  def volume_options(vm, id, volume_attributes)
37
37
  options = {}
38
38
  options.store(:mp, volume_attributes['mp']) if vm.container? && id != 'rootfs'
39
- options.store(:cache, volume_attributes['cache']) unless vm.container?
39
+ options.store(:cache, volume_attributes['cache']) unless vm.container? || volume_attributes['cache'].empty?
40
40
  options
41
41
  end
42
42
 
@@ -59,19 +59,19 @@ module ForemanFogProxmox
59
59
  end
60
60
 
61
61
  def extend_volume(vm, id, diff_size)
62
- extension = '+' + (diff_size / GIGA).to_s + 'G'
63
- logger.info(format(_('vm %<vmid>s extend volume %<volume_id>s to %<extension>s'), vmid: vm.identity, volume_id: id, extension: extension))
62
+ extension = "+#{diff_size}G"
63
+ logger.info("vm #{vm.identity} extend volume #{id} to #{extension}")
64
64
  vm.extend(id, extension)
65
65
  end
66
66
 
67
67
  def move_volume(id, vm, new_storage)
68
- logger.info(format(_('vm %<vmid>s move volume %<volume_id>s into %<new_storage>s'), vmid: vm.identity, volume_id: id, new_storage: new_storage))
68
+ logger.info("vm #{vm.identity} move volume #{id} into #{new_storage}")
69
69
  vm.move(id, new_storage)
70
70
  end
71
71
 
72
72
  def update_options(disk, vm, volume_attributes)
73
73
  options = volume_options(vm, disk.id, volume_attributes) if volume_type?(volume_attributes, 'hard_disk')
74
- logger.info(format(_('vm %<vmid>s update volume %<volume_id>s to %<options>s'), vmid: vm.identity, volume_id: disk.id, options: options))
74
+ logger.info("vm #{vm.identity} update volume #{disk.id} to #{options}")
75
75
  new_disk = { id: disk.id }
76
76
  new_disk[:volid] = disk.volid
77
77
  vm.attach(new_disk, options)
@@ -82,7 +82,12 @@ module ForemanFogProxmox
82
82
  if volume_type?(volume_attributes, 'cdrom')
83
83
  update_cdrom(vm, disk, volume_attributes)
84
84
  elsif volume_type?(volume_attributes, 'hard_disk')
85
- diff_size = volume_attributes['size'].to_i - disk.size if volume_attributes['size'] && disk.size
85
+ diff_size = volume_attributes['size'].to_i - disk.size.to_i if volume_attributes['size'] && disk.size
86
+ unless diff_size >= 0
87
+ raise ::Foreman::Exception,
88
+ format(_('Unable to shrink %<id>s size. Proxmox allows only increasing size.'), id: id)
89
+ end
90
+ diff_size = volume_attributes['size'].to_i - disk.size.to_i if volume_attributes['size'] && disk.size
86
91
  raise ::Foreman::Exception, format(_('Unable to shrink %<id>s size. Proxmox allows only increasing size.'), id: id) unless diff_size >= 0
87
92
 
88
93
  new_storage = volume_attributes['storage']
@@ -98,7 +103,13 @@ module ForemanFogProxmox
98
103
  end
99
104
 
100
105
  def volume_exists?(vm, volume_attributes)
101
- vm.attributes.key?(volume_attributes['id'])
106
+ disk = vm.config.disks.get(volume_attributes['id'])
107
+ exists = false
108
+ return exists unless disk
109
+
110
+ exists = !volume_attributes['volid'].empty? if disk.hard_disk? || disk.cloud_init?
111
+ exists = !volume_attributes['cdrom'].empty? if disk.cdrom?
112
+ exists
102
113
  end
103
114
 
104
115
  def volume_to_delete?(volume_attributes)
@@ -121,20 +132,20 @@ module ForemanFogProxmox
121
132
  if volume_type?(volume_attributes, 'hard_disk')
122
133
  options = volume_options(vm, id, volume_attributes)
123
134
  disk_attributes[:storage] = volume_attributes['storage']
124
- disk_attributes[:size] = (volume_attributes['size'].to_i / GIGA).to_s
135
+ disk_attributes[:size] = volume_attributes['size']
125
136
  elsif volume_type?(volume_attributes, 'cdrom')
126
137
  disk_attributes[:volid] = volume_attributes[:iso]
127
138
  elsif volume_type?(volume_attributes, 'cloud_init')
128
139
  disk_attributes[:storage] = volume_attributes['storage']
129
140
  disk_attributes[:volid] = "#{volume_attributes['storage']}:cloudinit"
130
141
  end
131
- logger.info(format(_('vm %<vmid>s add volume %<volume_id>s'), vmid: vm.identity, volume_id: id))
132
- logger.debug(format(_('add_volume(%<vmid>s) disk_attributes=%<disk_attributes>s'), vmid: vm.identity, disk_attributes: disk_attributes))
142
+ logger.info("vm #{vm.identity} add volume #{id}")
143
+ logger.debug("add_volume(#{vm.identity}) disk_attributes=#{disk_attributes}")
133
144
  vm.attach(disk_attributes, options)
134
145
  end
135
146
 
136
147
  def save_volume(vm, volume_attributes)
137
- logger.debug(format(_('save_volume(%<vmid>s) volume_attributes=%<volume_attributes>s'), vmid: vm.identity, volume_attributes: volume_attributes))
148
+ logger.debug("save_volume(#{vm.identity}) volume_attributes=#{volume_attributes}")
138
149
  id = extract_id(vm, volume_attributes)
139
150
  if volume_exists?(vm, volume_attributes)
140
151
  if volume_to_delete?(volume_attributes)
@@ -21,8 +21,8 @@ module ForemanFogProxmox
21
21
  class Vms
22
22
  attr_reader :items
23
23
 
24
- def each
25
- @items.each { |item| yield item }
24
+ def each(&block)
25
+ @items.each(&block)
26
26
  end
27
27
 
28
28
  # TODO: Pagination with filters
@@ -20,6 +20,6 @@ Deface::Override.new(
20
20
  :name => 'add_from_profile_to_compute_detail',
21
21
  :replace => "erb[loud]:contains('provider_partial')",
22
22
  :partial => 'compute_resources_vms/form/proxmox/add_from_profile_to_hosts_compute_detail_form',
23
- :original => '448e3b265e4dc1789f0efbbc6076e32216ac3a24',
23
+ :original => '8902a49136f750d781dcaa44e7ffa8a29c1a94df',
24
24
  :namespaced => true
25
25
  )
@@ -16,8 +16,8 @@ You should have received a copy of the GNU General Public License
16
16
  along with ForemanFogProxmox. If not, see <http://www.gnu.org/licenses/>. %>
17
17
  <% if compute_resource.class == ForemanFogProxmox::Proxmox %>
18
18
  <%= render :partial => provider_partial(compute_resource, 'base'),
19
- :locals => { :f => f, :compute_resource => compute_resource, :new_host => true, :new_vm => true, :hide_image => true, :from_profile => from_profile }.merge(args_for_compute_resource_partial(@host)) %>
19
+ :locals => { :f => f, :host => nil, :compute_resource => compute_resource, :new_host => true, :new_vm => true, :from_profile => from_profile } %>
20
20
  <% else %>
21
21
  <%= render :partial => provider_partial(compute_resource, 'base'),
22
- :locals => { :f => f, :compute_resource => compute_resource, :new_host => true, :new_vm => true, :hide_image => true }.merge(args_for_compute_resource_partial(@host)) %>
22
+ :locals => { :f => f, :host => nil, :compute_resource => compute_resource, :new_host => true, :new_vm => true } %>
23
23
  <% end %>
@@ -17,8 +17,10 @@ along with ForemanFogProxmox. If not, see <http://www.gnu.org/licenses/>. %>
17
17
 
18
18
  <% if compute_resource.class == ForemanFogProxmox::Proxmox %>
19
19
  <%= render :partial => provider_partial(compute_resource, 'base'),
20
- :locals => { :f => f, :compute_resource => compute_resource, :new_host => new_vm, :new_vm => new_vm, :from_profile => false }.merge(args_for_compute_resource_partial(@host)) %>
20
+ locals: { f: f, host: host, compute_resource: compute_resource, new_host: host.new_record?, new_vm: new_vm,
21
+ arch: host.architecture_id, os: host.operatingsystem_id, from_profile: false } %>
21
22
  <% else %>
22
23
  <%= render :partial => provider_partial(compute_resource, 'base'),
23
- :locals => { :f => f, :compute_resource => compute_resource, :new_host => new_vm, :new_vm => new_vm }.merge(args_for_compute_resource_partial(@host)) %>
24
+ locals: { f: f, host: host, compute_resource: compute_resource, new_host: host.new_record?, new_vm: new_vm,
25
+ arch: host.architecture_id, os: host.operatingsystem_id } %>
24
26
  <% end %>
@@ -16,7 +16,6 @@ You should have received a copy of the GNU General Public License
16
16
  along with ForemanFogProxmox. If not, see <http://www.gnu.org/licenses/>. %>
17
17
 
18
18
  <%= javascript_include_tag 'foreman_fog_proxmox/proxmox_vm', "data-turbolinks-track" => true %>
19
- <%= javascript_tag("$(document).on('ContentLoad', tfm.numFields.initAll)"); %>
20
19
 
21
20
  <%= select_f f, :type, proxmox_types_map, :id, :name, { }, :label => _('Type'), :label_size => "col-md-2", :required => true, :onchange => "vmTypeSelected()", :disabled => !new_vm %>
22
21
 
@@ -28,8 +28,8 @@ along with ForemanFogProxmox. If not, see <http://www.gnu.org/licenses/>. %>
28
28
  <%= counter_f f, :cpuunits, :class => "input-mini", :label => _('CPU units'), :label_size => "col-md-2" %>
29
29
  <% end %>
30
30
  <%= field_set_tag _("Memory"), :id => "container_config_memory", :class => 'hide', :disabled => !container do %>
31
- <%= byte_size_f f, :memory, :class => "input-mini", :label => _('Memory'), :label_size => "col-md-2" %>
32
- <%= byte_size_f f, :swap, :class => "input-mini", :label => _('Swap'), :label_size => "col-md-2" %>
31
+ <%= text_f f, :memory, :class => "input-mini", :label => _('Memory (MB)'), :label_size => "col-md-2" %>
32
+ <%= text_f f, :swap, :class => "input-mini", :label => _('Swap (MB)'), :label_size => "col-md-2" %>
33
33
  <% end %>
34
34
  <%= field_set_tag _("DNS"), :id => "container_config_dns", :class => 'hide', :disabled => !container do %>
35
35
  <%= text_f f, :hostname, :label => _('Hostname'), :label_size => "col-md-2", :disabled => true %>
@@ -19,7 +19,7 @@ along with ForemanFogProxmox. If not, see <http://www.gnu.org/licenses/>. %>
19
19
  <% index = f.index ? f.index.present? : 0 %>
20
20
 
21
21
  <%= field_set_tag _("Nic"), :id => "container_network_#{index}", :style => ('display: none;' unless container), :disabled => !container do %>
22
- <%= f.hidden_field :id if !new_vm %>
22
+ <%= text_f f, :id, :label => _('Identifier'), :label_size => "col-md-2", :required => true, :label_help => _("net[n] with n integer >= 0, e.g. net0") %>
23
23
  <%= text_f f, :name, :label => _('Name'), :label_size => "col-md-2", :required => true, :label_help => _("eth[n] with n integer >= 0, e.g. eth0") %>
24
24
  <%= checkbox_f f, :dhcp, :label => _('DHCP IPv4') %>
25
25
  <%= text_f f, :cidr, :label => _('CIDR IPv4'), :label_size => "col-md-2", :label_help => _("integer within [0..32]") %>
@@ -23,5 +23,5 @@ along with ForemanFogProxmox. If not, see <http://www.gnu.org/licenses/>. %>
23
23
  <%= select_f f, :storage, compute_resource.storages(node_id), :storage, :storage, { }, :label => _('Storage'), :label_size => "col-md-2" %>
24
24
  <%= text_f f, :mp, :label => _('Path'), :label_size => "col-md-2", :required => true, :help_inline => _("e.g. /path/to/") %>
25
25
  <%= text_f f, :device, :label => _('Device'), :label_size => "col-md-2", :class => ('hide' if f.object.rootfs?), :disabled => (!new_volume || f.object.rootfs?), :'data-soft-max' => 10 %>
26
- <%= byte_size_f f, :size, :class => "input-mini", :label => _("Size"), :label_size => "col-md-2" %>
26
+ <%= text_f f, :size, :class => "input-mini", :label => _("Size (GB)"), :label_size => "col-md-2" %>
27
27
  <% end %>
@@ -20,5 +20,5 @@ along with ForemanFogProxmox. If not, see <http://www.gnu.org/licenses/>. %>
20
20
  <%= field_set_tag _("Rootfs"), :id => "container_volume_rootfs", :class => ('hide' unless container), :disabled => !container do %>
21
21
  <%= f.hidden_field :volid if !new_vm %>
22
22
  <%= select_f f, :storage, compute_resource.storages(node_id), :storage, :storage, { }, :label => _('Storage'), :label_size => "col-md-2" %>
23
- <%= byte_size_f f, :size, :class => "input-mini", :label => _("Size"), :label_size => "col-md-2" %>
23
+ <%= text_f f, :size, :class => "input-mini", :label => _("Size (GB)"), :label_size => "col-md-2" %>
24
24
  <% end %>
@@ -45,9 +45,9 @@ along with ForemanFogProxmox. If not, see <http://www.gnu.org/licenses/>. %>
45
45
  <% end %>
46
46
  <% end %>
47
47
  <%= field_set_tag _("Memory"), :id => "server_config_memory", :class => 'hide', :disabled => !server do %>
48
- <%= byte_size_f f, :memory, :class => "input-mini", :label => _('Memory'), :label_size => "col-md-2" %>
49
- <%= byte_size_f f, :balloon, :class => "input-mini", :label => _('Minimum memory'), :label_size => "col-md-2" %>
50
- <%= counter_f f, :shares, :class => "input-mini", :label => _('Shares'), :label_size => "col-md-2" %>
48
+ <%= text_f f, :memory, :class => "input-mini", :label => _('Memory (MB)'), :label_size => "col-md-2" %>
49
+ <%= text_f f, :balloon, :class => "input-mini", :label => _('Minimum memory (MB)'), :label_size => "col-md-2" %>
50
+ <%= text_f f, :shares, :class => "input-mini", :label => _('Shares (MB)'), :label_size => "col-md-2" %>
51
51
  <% end %>
52
52
  <%= field_set_tag _("Operating System"), :id => "server_config_os", :class => 'hide', :disabled => !server do %>
53
53
  <%= select_f f, :ostype, proxmox_operating_systems_map, :id, :name, { :include_blank => true }, :label => _('OS type'), :label_size => "col-md-2" %>
@@ -18,8 +18,8 @@ along with ForemanFogProxmox. If not, see <http://www.gnu.org/licenses/>. %>
18
18
  <% server = vm_type == 'qemu' %>
19
19
  <% index = f.index ? f.index.present? : 0 %>
20
20
 
21
- <%= field_set_tag _("Nic"), :id => "server_network_#{index}", :style => ('display: none;' unless server), :disabled => !server do %>
22
- <%= f.hidden_field :id if !new_vm %>
21
+ <%= field_set_tag _("Nic"), :id => "server_network_#{index}", :style => ('display: none;' unless server), :disabled => !server do %>
22
+ <%= text_f f, :id, :label => _('Identifier'), :label_size => "col-md-2", :required => true, :label_help => _("net[n] with n integer >= 0, e.g. net0") %>
23
23
  <%= select_f f, :model, proxmox_networkcards_map, :id, :name, { }, :label => _('Card'), :label_size => "col-md-2" %>
24
24
  <%= select_f f, :bridge, compute_resource.bridges(node_id), :iface, :iface, { }, :label => _('Bridge'), :label_size => "col-md-2" %>
25
25
  <%= counter_f f, :tag, :class => "input-mini", :label => _('VLAN tag'), :label_size => "col-md-2" %>
@@ -28,5 +28,5 @@ along with ForemanFogProxmox. If not, see <http://www.gnu.org/licenses/>. %>
28
28
  <%= select_f f, :controller, proxmox_controllers_map, :id, :name, { }, :label => _('Controller'), :label_size => "col-md-2", :disabled => !new_volume, :onchange => 'controllerSelected(this)' %>
29
29
  <%= text_f f, :device, :label => _('Device'), :label_size => "col-md-2", :disabled => !new_volume, :'data-min' => 0, :'data-soft-max' => proxmox_max_device(f.object.controller), :onchange => 'deviceSelected(this)' %>
30
30
  <%= select_f f, :cache, proxmox_caches_map, :id, :name, { include_blank: true }, :label => _('Cache'), :label_size => "col-md-2" %>
31
- <%= byte_size_f f, :size, :class => "input-mini", :label => _("Size"), :label_size => "col-md-2" %>
31
+ <%= text_f f, :size, :class => "input-mini", :label => _("Size (GB)"), :label_size => "col-md-2", :disabled => !hard_disk %>
32
32
  <% end %>
data/config/routes.rb CHANGED
@@ -19,12 +19,16 @@
19
19
 
20
20
  Rails.application.routes.draw do
21
21
  namespace :foreman_fog_proxmox do
22
- match 'isos/:compute_resource_id/:node_id/:storage', :to => 'compute_resources#isos_by_id_and_node_and_storage', :via => 'get'
23
- match 'ostemplates/:compute_resource_id/:node_id/:storage', :to => 'compute_resources#ostemplates_by_id_and_node_and_storage', :via => 'get'
22
+ match 'isos/:compute_resource_id/:node_id/:storage', :to => 'compute_resources#isos_by_id_and_node_and_storage',
23
+ :via => 'get'
24
+ match 'ostemplates/:compute_resource_id/:node_id/:storage',
25
+ :to => 'compute_resources#ostemplates_by_id_and_node_and_storage', :via => 'get'
24
26
  match 'isos/:compute_resource_id/:node_id', :to => 'compute_resources#isos_by_id_and_node', :via => 'get'
25
- match 'ostemplates/:compute_resource_id/:node_id', :to => 'compute_resources#ostemplates_by_id_and_node', :via => 'get'
27
+ match 'ostemplates/:compute_resource_id/:node_id', :to => 'compute_resources#ostemplates_by_id_and_node',
28
+ :via => 'get'
26
29
  match 'storages/:compute_resource_id/:node_id', :to => 'compute_resources#storages_by_id_and_node', :via => 'get'
27
- match 'isostorages/:compute_resource_id/:node_id', :to => 'compute_resources#iso_storages_by_id_and_node', :via => 'get'
30
+ match 'isostorages/:compute_resource_id/:node_id', :to => 'compute_resources#iso_storages_by_id_and_node',
31
+ :via => 'get'
28
32
  match 'bridges/:compute_resource_id/:node_id', :to => 'compute_resources#bridges_by_id_and_node', :via => 'get'
29
33
  end
30
34
  end
@@ -1,6 +1,5 @@
1
1
  include ProxmoxVmUuidHelper
2
2
  class UpdateProxmoxUuidHost < ActiveRecord::Migration[6.0]
3
-
4
3
  def up
5
4
  execute(sql(:concat))
6
5
  end
@@ -9,7 +8,7 @@ class UpdateProxmoxUuidHost < ActiveRecord::Migration[6.0]
9
8
  execute(sql(:substring))
10
9
  end
11
10
 
12
- private
11
+ private
13
12
 
14
13
  def concat
15
14
  "concat(h.compute_resource_id, '_', h.uuid) "