foreman_fog_proxmox 0.16.1 → 0.17.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (57) hide show
  1. checksums.yaml +4 -4
  2. data/app/controllers/concerns/foreman_fog_proxmox/hosts_controller.rb +1 -1
  3. data/app/helpers/proxmox_vm_attrs_helper.rb +3 -3
  4. data/app/helpers/proxmox_vm_cdrom_helper.rb +1 -1
  5. data/app/helpers/proxmox_vm_cloudinit_helper.rb +1 -1
  6. data/app/helpers/proxmox_vm_config_helper.rb +1 -1
  7. data/app/helpers/proxmox_vm_helper.rb +5 -5
  8. data/app/helpers/proxmox_vm_interfaces_helper.rb +1 -1
  9. data/app/helpers/proxmox_vm_os_template_helper.rb +1 -1
  10. data/app/helpers/proxmox_vm_uuid_helper.rb +1 -1
  11. data/app/helpers/proxmox_vm_volumes_helper.rb +3 -3
  12. data/app/models/concerns/host_ext/proxmox/for_vm.rb +1 -1
  13. data/app/models/foreman_fog_proxmox/proxmox.rb +4 -4
  14. data/app/models/foreman_fog_proxmox/proxmox_interfaces.rb +1 -1
  15. data/app/models/foreman_fog_proxmox/proxmox_vm_commands.rb +2 -2
  16. data/app/models/foreman_fog_proxmox/proxmox_vm_new.rb +2 -2
  17. data/app/models/foreman_fog_proxmox/proxmox_vm_queries.rb +2 -2
  18. data/app/models/foreman_fog_proxmox/proxmox_volumes.rb +2 -2
  19. data/app/views/compute_resources_vms/form/proxmox/_add_react_component_to_host_form.html.erb +0 -1
  20. data/app/views/templates/provisioning/user_data/proxmox_user_data.erb +119 -0
  21. data/db/migrate/20210312105013_update_proxmox_uuid_host.rb +1 -1
  22. data/db/seeds.d/71_provisioning_templates.rb +7 -0
  23. data/lib/foreman_fog_proxmox/engine.rb +22 -27
  24. data/lib/foreman_fog_proxmox/version.rb +1 -1
  25. data/test/unit/foreman_fog_proxmox/helpers/proxmox_container_helper_test.rb +1 -1
  26. data/test/unit/foreman_fog_proxmox/helpers/proxmox_server_helper_test.rb +1 -1
  27. data/test/unit/foreman_fog_proxmox/helpers/proxmox_vm_helper_test.rb +2 -2
  28. data/test/unit/foreman_fog_proxmox/helpers/proxmox_vm_uuid_helper_test.rb +2 -2
  29. data/test/unit/foreman_fog_proxmox/helpers/proxmox_vm_volumes_helper_test.rb +2 -2
  30. data/test/unit/foreman_fog_proxmox/proxmox_compute_attributes_test.rb +1 -1
  31. data/test/unit/foreman_fog_proxmox/proxmox_images_test.rb +1 -1
  32. data/test/unit/foreman_fog_proxmox/proxmox_interfaces_test.rb +3 -3
  33. data/test/unit/foreman_fog_proxmox/proxmox_test.rb +1 -1
  34. data/test/unit/foreman_fog_proxmox/proxmox_version_test.rb +1 -1
  35. data/test/unit/foreman_fog_proxmox/proxmox_vm_commands_container_test.rb +2 -2
  36. data/test/unit/foreman_fog_proxmox/proxmox_vm_commands_server_create_test.rb +2 -2
  37. data/test/unit/foreman_fog_proxmox/proxmox_vm_commands_server_update_cdrom_test.rb +5 -2
  38. data/test/unit/foreman_fog_proxmox/proxmox_vm_commands_server_update_cloudinit_test.rb +2 -2
  39. data/test/unit/foreman_fog_proxmox/proxmox_vm_commands_server_update_hard_disk_test.rb +2 -2
  40. data/test/unit/foreman_fog_proxmox/proxmox_vm_commands_server_update_test.rb +2 -2
  41. data/test/unit/foreman_fog_proxmox/proxmox_vm_commands_test.rb +2 -2
  42. data/test/unit/foreman_fog_proxmox/proxmox_vm_new_test.rb +2 -2
  43. data/test/unit/foreman_fog_proxmox/proxmox_vm_queries_test.rb +2 -2
  44. data/webpack/components/GeneralTabContent.js +3 -3
  45. data/webpack/components/ProxmoxComputeSelectors.js +64 -20
  46. data/webpack/components/ProxmoxContainer/MountPoint.js +5 -8
  47. data/webpack/components/ProxmoxContainer/ProxmoxContainerOptions.js +3 -2
  48. data/webpack/components/ProxmoxContainer/ProxmoxContainerStorage.js +1 -1
  49. data/webpack/components/ProxmoxContainer/components/NetworkInterface.js +14 -13
  50. data/webpack/components/ProxmoxServer/ProxmoxServerHardware.js +22 -22
  51. data/webpack/components/ProxmoxServer/ProxmoxServerNetwork.js +1 -1
  52. data/webpack/components/ProxmoxServer/ProxmoxServerOptions.js +3 -3
  53. data/webpack/components/ProxmoxServer/components/HardDisk.js +13 -5
  54. data/webpack/components/ProxmoxServer/components/NetworkInterface.js +2 -2
  55. data/webpack/components/ProxmoxVmType.js +24 -21
  56. data/webpack/components/common/FormInputs.js +10 -2
  57. metadata +19 -17
@@ -24,11 +24,11 @@ require 'factories/foreman_fog_proxmox/proxmox_server_mock_factory'
24
24
  require 'active_support/core_ext/hash/indifferent_access'
25
25
 
26
26
  module ForemanFogProxmox
27
- class ProxmoxVmCommandsServerUpdateCdromTest < ActiveSupport::TestCase
27
+ class ProxmoxVMCommandsServerUpdateCdromTest < ActiveSupport::TestCase
28
28
  include ComputeResourceTestHelpers
29
29
  include ProxmoxNodeMockFactory
30
30
  include ProxmoxServerMockFactory
31
- include ProxmoxVmHelper
31
+ include ProxmoxVMHelper
32
32
 
33
33
  describe 'save_vm' do
34
34
  before do
@@ -45,6 +45,7 @@ module ForemanFogProxmox
45
45
  disk.stubs(:hard_disk?).returns(false)
46
46
  disk.stubs(:cdrom?).returns(true)
47
47
  disk.stubs(:rootfs?).returns(false)
48
+ disk.stubs(:mount_point?).returns(false)
48
49
  disks.stubs(:get).returns
49
50
  config.stubs(:disks).returns(disks)
50
51
  config.stubs(:attributes).returns(:cores => '')
@@ -95,6 +96,7 @@ module ForemanFogProxmox
95
96
  disk.stubs(:hard_disk?).returns(false)
96
97
  disk.stubs(:cdrom?).returns(true)
97
98
  disk.stubs(:rootfs?).returns(false)
99
+ disk.stubs(:mount_point?).returns(false)
98
100
  disk.stubs(:cloud_init?).returns(false)
99
101
  disk.stubs(:storage).returns('local-lvm')
100
102
  disk.stubs(:volid).returns('local-lvm:iso/ubuntu-20_4.iso')
@@ -148,6 +150,7 @@ module ForemanFogProxmox
148
150
  disk.stubs(:hard_disk?).returns(false)
149
151
  disk.stubs(:cdrom?).returns(true)
150
152
  disk.stubs(:rootfs?).returns(false)
153
+ disk.stubs(:mount_point?).returns(false)
151
154
  disk.stubs(:cloud_init?).returns(false)
152
155
  disk.stubs(:storage).returns('local-lvm')
153
156
  disk.stubs(:volid).returns('local-lvm:iso/ubuntu-20_4.iso')
@@ -24,11 +24,11 @@ require 'factories/foreman_fog_proxmox/proxmox_server_mock_factory'
24
24
  require 'active_support/core_ext/hash/indifferent_access'
25
25
 
26
26
  module ForemanFogProxmox
27
- class ProxmoxVmCommandsServerUpdateCloudinitTest < ActiveSupport::TestCase
27
+ class ProxmoxVMCommandsServerUpdateCloudinitTest < ActiveSupport::TestCase
28
28
  include ComputeResourceTestHelpers
29
29
  include ProxmoxNodeMockFactory
30
30
  include ProxmoxServerMockFactory
31
- include ProxmoxVmHelper
31
+ include ProxmoxVMHelper
32
32
 
33
33
  describe 'save_vm' do
34
34
  before do
@@ -24,11 +24,11 @@ require 'factories/foreman_fog_proxmox/proxmox_server_mock_factory'
24
24
  require 'active_support/core_ext/hash/indifferent_access'
25
25
 
26
26
  module ForemanFogProxmox
27
- class ProxmoxVmCommandsServerUpdateHardDiskTest < ActiveSupport::TestCase # rubocop:disable Metrics/ClassLength
27
+ class ProxmoxVMCommandsServerUpdateHardDiskTest < ActiveSupport::TestCase # rubocop:disable Metrics/ClassLength
28
28
  include ComputeResourceTestHelpers
29
29
  include ProxmoxNodeMockFactory
30
30
  include ProxmoxServerMockFactory
31
- include ProxmoxVmHelper
31
+ include ProxmoxVMHelper
32
32
 
33
33
  # rubocop:disable Metrics/BlockLength
34
34
  describe 'save_vm' do
@@ -24,11 +24,11 @@ require 'factories/foreman_fog_proxmox/proxmox_server_mock_factory'
24
24
  require 'active_support/core_ext/hash/indifferent_access'
25
25
 
26
26
  module ForemanFogProxmox
27
- class ProxmoxVmCommandsServerUpdateTest < ActiveSupport::TestCase
27
+ class ProxmoxVMCommandsServerUpdateTest < ActiveSupport::TestCase
28
28
  include ComputeResourceTestHelpers
29
29
  include ProxmoxNodeMockFactory
30
30
  include ProxmoxServerMockFactory
31
- include ProxmoxVmHelper
31
+ include ProxmoxVMHelper
32
32
 
33
33
  describe 'save_vm' do
34
34
  before do
@@ -25,12 +25,12 @@ require 'factories/foreman_fog_proxmox/proxmox_container_mock_factory'
25
25
  require 'active_support/core_ext/hash/indifferent_access'
26
26
 
27
27
  module ForemanFogProxmox
28
- class ProxmoxVmCommandsServerTest < ActiveSupport::TestCase
28
+ class ProxmoxVMCommandsServerTest < ActiveSupport::TestCase
29
29
  include ComputeResourceTestHelpers
30
30
  include ProxmoxNodeMockFactory
31
31
  include ProxmoxServerMockFactory
32
32
  include ProxmoxContainerMockFactory
33
- include ProxmoxVmHelper
33
+ include ProxmoxVMHelper
34
34
 
35
35
  describe 'destroy_vm' do
36
36
  it 'handles situation when vm is not present' do
@@ -25,12 +25,12 @@ require 'factories/foreman_fog_proxmox/proxmox_container_mock_factory'
25
25
  require 'active_support/core_ext/hash/indifferent_access'
26
26
 
27
27
  module ForemanFogProxmox
28
- class ProxmoxVmNewTest < ActiveSupport::TestCase
28
+ class ProxmoxVMNewTest < ActiveSupport::TestCase
29
29
  include ComputeResourceTestHelpers
30
30
  include ProxmoxNodeMockFactory
31
31
  include ProxmoxServerMockFactory
32
32
  include ProxmoxContainerMockFactory
33
- include ProxmoxVmHelper
33
+ include ProxmoxVMHelper
34
34
 
35
35
  describe 'new_vm' do
36
36
  before do
@@ -25,12 +25,12 @@ require 'factories/foreman_fog_proxmox/proxmox_container_mock_factory'
25
25
  require 'active_support/core_ext/hash/indifferent_access'
26
26
 
27
27
  module ForemanFogProxmox
28
- class ProxmoxVmQueriesTest < ActiveSupport::TestCase
28
+ class ProxmoxVMQueriesTest < ActiveSupport::TestCase
29
29
  include ComputeResourceTestHelpers
30
30
  include ProxmoxNodeMockFactory
31
31
  include ProxmoxServerMockFactory
32
32
  include ProxmoxContainerMockFactory
33
- include ProxmoxVmHelper
33
+ include ProxmoxVMHelper
34
34
 
35
35
  describe 'find_vm_by_uuid' do
36
36
  it 'returns nil when the uuid does not match' do
@@ -22,7 +22,7 @@ const GeneralTabContent = ({
22
22
  required
23
23
  type="number"
24
24
  value={general?.vmid?.value}
25
- disabled={fromProfile}
25
+ disabled={!newVm || fromProfile}
26
26
  onChange={handleChange}
27
27
  />
28
28
  <InputField
@@ -48,7 +48,7 @@ const GeneralTabContent = ({
48
48
  label={__('Start after creation?')}
49
49
  type="checkbox"
50
50
  value={general?.startAfterCreate?.value}
51
- checked={general?.startAfterCreate?.value === '1'}
51
+ checked={String(general?.startAfterCreate?.value) === '1'}
52
52
  onChange={handleChange}
53
53
  />
54
54
  )}
@@ -58,7 +58,7 @@ const GeneralTabContent = ({
58
58
  label={__('Create image?')}
59
59
  type="checkbox"
60
60
  value={general?.templated?.value}
61
- checked={general?.templated?.value === '1'}
61
+ checked={String(general?.templated?.value) === '1'}
62
62
  disabled={untemplatable}
63
63
  onChange={handleChange}
64
64
  />
@@ -52,6 +52,7 @@ const ProxmoxComputeSelectors = {
52
52
  ],
53
53
 
54
54
  proxmoxVgasMap: [
55
+ { value: '', labal: '' },
55
56
  { value: 'std', label: 'Standard VGA' },
56
57
  { value: 'vmware', label: 'Vmware compatible' },
57
58
  { value: 'qxl', label: 'SPICE' },
@@ -74,34 +75,77 @@ const ProxmoxComputeSelectors = {
74
75
  ],
75
76
 
76
77
  proxmoxCpusMap: [
77
- { value: '486', label: '486' },
78
78
  { value: 'athlon', label: 'athlon' },
79
+ { value: 'EPYC', label: 'EPYC' },
80
+ { value: 'EPYC-IBPB', label: 'EPYC-IBPB' },
81
+ { value: 'EPYC-Milan', label: 'EPYC-Milan' },
82
+ { value: 'EPYC-Rome', label: 'EPYC-Rome' },
83
+ { value: 'EPYC-Rome-v2', label: 'EPYC-Rome-v2' },
84
+ { value: 'EPYC-v3', label: 'EPYC-v3' },
85
+ { value: 'Opteron_G1', label: 'Opteron_G1' },
86
+ { value: 'Opteron_G2', label: 'Opteron_G2' },
87
+ { value: 'Opteron_G3', label: 'Opteron_G3' },
88
+ { value: 'Opteron_G4', label: 'Opteron_G4' },
89
+ { value: 'Opteron_G5', label: 'Opteron_G5' },
90
+ { value: 'phenom', label: 'phenom' },
91
+ { value: '486', label: '486' },
92
+ { value: 'Broadwell', label: 'Broadwell' },
93
+ { value: 'Broadwell-IBRS', label: 'Broadwell-IBRS' },
94
+ { value: 'Broadwell-noTSX', label: 'Broadwell-noTSX' },
95
+ { value: 'Broadwell-noTSX-IBRS', label: 'Broadwell-noTSX-IBRS' },
96
+ { value: 'Cascadelake-Server', label: 'Cascadelake-Server' },
97
+ { value: 'Cascadelake-Server-noTSX', label: 'Cascadelake-Server-noTSX' },
98
+ { value: 'Cascadelake-Server-v2', label: 'Cascadelake-Server-v2' },
99
+ { value: 'Cascadelake-Server-v4', label: 'Cascadelake-Server-v4' },
100
+ { value: 'Cascadelake-Server-v5', label: 'Cascadelake-Server-v5' },
101
+ { value: 'Conroe', label: 'Conroe' },
102
+ { value: 'Cooperlake', label: 'Cooperlake' },
103
+ { value: 'Cooperlake-v2', label: 'Cooperlake-v2' },
79
104
  { value: 'core2duo', label: 'core2duo' },
80
105
  { value: 'coreduo', label: 'coreduo' },
81
- { value: 'kvm32', label: 'kvm32' },
82
- { value: 'kvm64', label: '(Default) kvm64' },
106
+ { value: 'Haswell', label: 'Haswell' },
107
+ { value: 'Haswell-IBRS', label: 'Haswell-IBRS' },
108
+ { value: 'Haswell-noTSX', label: 'Haswell-noTSX' },
109
+ { value: 'Haswell-noTSX-IBRS', label: 'Haswell-noTSX-IBRS' },
110
+ { value: 'Icelake-Client', label: 'Icelake-Client' },
111
+ { value: 'Icelake-Client-noTSX', label: 'Icelake-Client-noTSX' },
112
+ { value: 'Icelake-Server', label: 'Icelake-Server' },
113
+ { value: 'Icelake-Server-noTSX', label: 'Icelake-Server-noTSX' },
114
+ { value: 'Icelake-Server-v3', label: 'Icelake-Server-v3' },
115
+ { value: 'Icelake-Server-v4', label: 'Icelake-Server-v4' },
116
+ { value: 'Icelake-Server-v5', label: 'Icelake-Server-v5' },
117
+ { value: 'Icelake-Server-v6', label: 'Icelake-Server-v6' },
118
+ { value: 'IvyBridge', label: 'IvyBridge' },
119
+ { value: 'IvyBridge-IBRS', label: 'IvyBridge-IBRS' },
120
+ { value: 'KnightsMill', label: 'KnightsMill' },
121
+ { value: 'Nehalem', label: 'Nehalem' },
122
+ { value: 'Nehalem-IBRS', label: 'Nehalem-IBRS' },
123
+ { value: 'Penryn', label: 'Penryn' },
83
124
  { value: 'pentium', label: 'pentium' },
84
125
  { value: 'pentium2', label: 'pentium2' },
85
126
  { value: 'pentium3', label: 'pentium3' },
86
- { value: 'phenom', label: 'phenom' },
87
- { value: 'qemu32', label: 'qemu32' },
88
- { value: 'qemu64', label: 'qemu64' },
89
- { value: 'Conroe', label: 'Conroe' },
90
- { value: 'Penryn', label: 'Penryn' },
91
- { value: 'Nehalem', label: 'Nehalem' },
92
- { value: 'Westmere', label: 'Westmere' },
93
127
  { value: 'SandyBridge', label: 'SandyBridge' },
94
- { value: 'IvyBridge', label: 'IvyBridge' },
95
- { value: 'Haswell', label: 'Haswell' },
96
- { value: 'Haswell-noTSX', label: 'Haswell-noTSX' },
97
- { value: 'Broadwell', label: 'Broadwell' },
98
- { value: 'Broadwell-noTSX', label: 'Broadwell-noTSX' },
128
+ { value: 'SandyBridge-IBRS', label: 'SandyBridge-IBRS' },
99
129
  { value: 'Skylake-Client', label: 'Skylake-Client' },
100
- { value: 'Opteron_G1', label: 'Opteron_G1' },
101
- { value: 'Opteron_G2', label: 'Opteron_G2' },
102
- { value: 'Opteron_G3', label: 'Opteron_G3' },
103
- { value: 'Opteron_G4', label: 'Opteron_G4' },
104
- { value: 'Opteron_G5', label: 'Opteron_G5' },
130
+ { value: 'Skylake-Client-IBRS', label: 'Skylake-Client-IBRS' },
131
+ { value: 'Skylake-Client-noTSX-IBRS', label: 'Skylake-Client-noTSX-IBRS' },
132
+ { value: 'Skylake-Client-v4', label: 'Skylake-Client-v4' },
133
+ { value: 'Skylake-Server', label: 'Skylake-Server' },
134
+ { value: 'Skylake-Server-IBRS', label: 'Skylake-Server-IBRS' },
135
+ { value: 'Skylake-Server-noTSX-IBRS', label: 'Skylake-Server-noTSX-IBRS' },
136
+ { value: 'Skylake-Server-v4', label: 'Skylake-Server-v4' },
137
+ { value: 'Skylake-Server-v5', label: 'Skylake-Server-v5' },
138
+ { value: 'Westmere', label: 'Westmere' },
139
+ { value: 'Westmere-IBRS', label: 'Westmere-IBRS' },
140
+ { value: 'kvm32', label: 'kvm32' },
141
+ { value: 'kvm64', label: '(Default) kvm64' },
142
+ { value: 'max', label: 'max' },
143
+ { value: 'qemu32', label: 'qemu32' },
144
+ { value: 'qemu64', label: 'qemu64' },
145
+ { value: 'x86-64-v2', label: 'x86-64-v2' },
146
+ { value: 'x86-64-v2-AES', label: 'x86-64-v2-AES' },
147
+ { value: 'x86-64-v3', label: 'x86-64-v3' },
148
+ { value: 'x86-64-v4', label: 'x86-64-v4' },
105
149
  { value: 'host', label: 'host' },
106
150
  ],
107
151
 
@@ -45,16 +45,18 @@ const MountPoint = ({ id, data, storagesMap }) => {
45
45
  />
46
46
  <InputField
47
47
  name={mp?.size?.name}
48
- label={__('Size')}
48
+ label={__('Size (GB)')}
49
49
  type="number"
50
50
  value={mp?.size?.value}
51
51
  onChange={handleChange}
52
52
  />
53
- <input
53
+ <InputField
54
+ label={__('Device')}
54
55
  name={mp?.device?.name}
55
- type="hidden"
56
+ disabled
56
57
  value={mp?.device?.value}
57
58
  onChange={handleChange}
59
+ tooltip={__('Device value is set automatically.')}
58
60
  />
59
61
  <input
60
62
  name={mp?.id?.name}
@@ -68,11 +70,6 @@ const MountPoint = ({ id, data, storagesMap }) => {
68
70
  value={mp?.volid?.value}
69
71
  onChange={handleChange}
70
72
  />
71
- <input
72
- name={mp?.storageType?.name}
73
- type="hidden"
74
- value={mp?.storageType?.value}
75
- />
76
73
  </div>
77
74
  );
78
75
  };
@@ -56,14 +56,14 @@ const ProxmoxContainerOptions = ({ options, storages, nodeId }) => {
56
56
  label={__('Start at boot')}
57
57
  type="checkbox"
58
58
  value={opts?.onboot?.value}
59
- checked={opts?.onboot?.value === '1'}
59
+ checked={String(opts?.onboot?.value) === '1'}
60
60
  onChange={handleChange}
61
61
  />
62
62
  <InputField
63
63
  name={opts?.ostype?.name}
64
64
  label={__('OS Type')}
65
65
  type="select"
66
- options={ProxmoxComputeSelectors.proxmoxOperatingSystemsMap}
66
+ options={ProxmoxComputeSelectors.proxmoxOstypesMap}
67
67
  value={opts?.ostype?.value}
68
68
  onChange={handleChange}
69
69
  />
@@ -71,6 +71,7 @@ const ProxmoxContainerOptions = ({ options, storages, nodeId }) => {
71
71
  name={opts?.hostname?.name}
72
72
  label={__('Hostname')}
73
73
  value={opts?.hostname?.value}
74
+ disabled
74
75
  onChange={handleChange}
75
76
  />
76
77
  <InputField
@@ -124,7 +124,7 @@ const ProxmoxContainerStorage = ({ storage, storages, nodeId, paramScope }) => {
124
124
  />
125
125
  <InputField
126
126
  name={rootfs?.size?.name}
127
- label={__('Size')}
127
+ label={__('Size (GB)')}
128
128
  type="number"
129
129
  value={rootfs?.size?.value}
130
130
  onChange={handleChange}
@@ -13,7 +13,8 @@ const NetworkInterface = ({
13
13
  existingInterfaces,
14
14
  }) => {
15
15
  const [network, setNetwork] = useState(data);
16
- const [error, setError] = useState('');
16
+ const [idError, setIdError] = useState('');
17
+ const [nameError, setNameError] = useState('');
17
18
  useEffect(() => {
18
19
  const currentNetData = JSON.stringify(network);
19
20
  const parentNetData = JSON.stringify(data);
@@ -48,23 +49,23 @@ const NetworkInterface = ({
48
49
  net.data.id.value !== network.id.value
49
50
  )
50
51
  ) {
51
- setError(__('Error: Duplicate ID found.'));
52
+ setIdError(__('Error: Duplicate ID found.'));
52
53
  return;
53
54
  }
54
- setError('');
55
+ setIdError('');
55
56
  }
56
57
  if (updatedKey === 'name') {
57
- const idValue = value;
58
+ const nameValue = value;
58
59
  if (
59
60
  Object.values(existingInterfaces).some(
60
61
  net =>
61
- net.data.id.value === idValue &&
62
- net.data.id.value !== network.id.value
62
+ net.data.name.value === nameValue &&
63
+ net.data.name.value !== network.name.value
63
64
  )
64
65
  ) {
65
- setError(__('Error: Duplicate Name found.'));
66
+ setNameError(__('Error: Duplicate Name found.'));
66
67
  } else {
67
- setError('');
68
+ setNameError('');
68
69
  }
69
70
  }
70
71
  };
@@ -83,7 +84,7 @@ const NetworkInterface = ({
83
84
  type="text"
84
85
  value={network?.id?.value}
85
86
  onChange={handleChange}
86
- error={error}
87
+ error={idError}
87
88
  />
88
89
  <InputField
89
90
  name={network?.name?.name}
@@ -92,7 +93,7 @@ const NetworkInterface = ({
92
93
  type="text"
93
94
  value={network?.name?.value}
94
95
  onChange={handleChange}
95
- error={error}
96
+ error={nameError}
96
97
  />
97
98
  <InputField
98
99
  name={network?.bridge?.name}
@@ -107,7 +108,7 @@ const NetworkInterface = ({
107
108
  label={__('DHCP IPv4')}
108
109
  type="checkbox"
109
110
  value={network?.dhcp?.value}
110
- checked={network?.dhcp?.value === '1'}
111
+ checked={String(network?.dhcp?.value) === '1'}
111
112
  onChange={handleChange}
112
113
  />
113
114
  <InputField
@@ -130,7 +131,7 @@ const NetworkInterface = ({
130
131
  label={__('DHCP IPv6')}
131
132
  type="checkbox"
132
133
  value={network?.dhcp6?.value}
133
- checked={network?.dhcp6?.value === '1'}
134
+ checked={String(network?.dhcp6?.value) === '1'}
134
135
  onChange={handleChange}
135
136
  />
136
137
  <InputField
@@ -167,7 +168,7 @@ const NetworkInterface = ({
167
168
  label={__('Firewall')}
168
169
  type="checkbox"
169
170
  value={network?.firewall?.value}
170
- checked={network?.firewall?.value === '1'}
171
+ checked={String(network?.firewall?.value) === '1'}
171
172
  onChange={handleChange}
172
173
  />
173
174
  </div>
@@ -6,19 +6,19 @@ import InputField from '../common/FormInputs';
6
6
  import ProxmoxComputeSelectors from '../ProxmoxComputeSelectors';
7
7
  import CPUFlagsModal from './components/CPUFlagsModal';
8
8
 
9
- const cpuFlagNames = [
10
- 'md_clear',
11
- 'pcid',
12
- 'spec_ctrl',
13
- 'ssbd',
14
- 'ibpb',
15
- 'virt_ssbd',
16
- 'amd_ssbd',
17
- 'amd_no_ssb',
18
- 'pdpe1gb',
19
- 'hv_tlbflush',
20
- 'hv_evmcs',
21
- 'aes',
9
+ const cpuFlagsHash = [
10
+ { key: 'md_clear', label: 'md-clear' },
11
+ { key: 'pcid', label: 'pcid' },
12
+ { key: 'spectre', label: 'spec-ctrl' },
13
+ { key: 'ssbd', label: 'ssbd' },
14
+ { key: 'ibpb', label: 'ibpb' },
15
+ { key: 'virt_ssbd', label: 'virt-ssbd' },
16
+ { key: 'amd_ssbd', label: 'amd-ssbd' },
17
+ { key: 'amd_no_ssb', label: 'amd-no-ssb' },
18
+ { key: 'pdpe1gb', label: 'pdpe1gb' },
19
+ { key: 'hv_tlbflush', label: 'hv-tlbflush' },
20
+ { key: 'hv_evmcs', label: 'hv-evmcs' },
21
+ { key: 'aes', label: 'aes' },
22
22
  ];
23
23
 
24
24
  const cpuFlagDescriptions = {
@@ -28,7 +28,7 @@ const cpuFlagDescriptions = {
28
28
  pcid: __(
29
29
  'Meltdown fix cost reduction on Westmere, Sandy-, and IvyBridge Intel CPUs'
30
30
  ),
31
- spec_ctrl: __('Allows improved Spectre mitigation with Intel CPUs'),
31
+ spectre: __('Allows improved Spectre mitigation with Intel CPUs'),
32
32
  ssbd: __('Protection for "Speculative Store Bypass" for Intel models'),
33
33
  ibpb: __('Allows improved Spectre mitigation with AMD CPUs'),
34
34
  virt_ssbd: __(
@@ -47,20 +47,20 @@ const cpuFlagDescriptions = {
47
47
  hv_evmcs: __(
48
48
  'Improve performance for nested virtualization. Only supported on Intel CPUs.'
49
49
  ),
50
- aes: __('Activate AES instruction set for HW instruction'),
50
+ aes: __('Activate AES instruction set for HW accelaration.'),
51
51
  };
52
52
 
53
53
  const filterAndAddDescriptions = hardware =>
54
- Object.keys(hardware)
55
- .filter(key => cpuFlagNames.includes(key))
56
- .reduce((acc, key) => {
54
+ cpuFlagsHash.reduce((acc, { key, label }) => {
55
+ if (key in hardware) {
57
56
  acc[key] = {
58
57
  ...hardware[key],
59
58
  description: cpuFlagDescriptions[key] || '',
60
- label: key,
59
+ label,
61
60
  };
62
- return acc;
63
- }, {});
61
+ }
62
+ return acc;
63
+ }, {});
64
64
 
65
65
  const ProxmoxServerHardware = ({ hardware }) => {
66
66
  const [hw, setHw] = useState(hardware);
@@ -141,7 +141,7 @@ const ProxmoxServerHardware = ({ hardware }) => {
141
141
  label={__('Enable NUMA')}
142
142
  type="checkbox"
143
143
  value={hw?.numa?.value}
144
- checked={hw?.numa?.value === '1'}
144
+ checked={String(hw?.numa?.value) === '1'}
145
145
  onChange={handleChange}
146
146
  />
147
147
  <div style={{ marginLeft: '5%', display: 'inline-block' }}>
@@ -63,7 +63,7 @@ const ProxmoxServerNetwork = ({ network, bridges, paramScope }) => {
63
63
  name: `${paramScope}[interfaces_attributes][${nextId}][firewall]`,
64
64
  value: '0',
65
65
  },
66
- link_down: {
66
+ linkDown: {
67
67
  name: `${paramScope}[interfaces_attributes][${nextId}][link_down]`,
68
68
  value: '0',
69
69
  },
@@ -38,7 +38,7 @@ const ProxmoxServerOptions = ({ options }) => {
38
38
  label={__('Start at boot')}
39
39
  type="checkbox"
40
40
  value={opts?.onboot?.value}
41
- checked={opts?.onboot?.value === '1'}
41
+ checked={String(opts?.onboot?.value) === '1'}
42
42
  onChange={handleChange}
43
43
  />
44
44
  <InputField
@@ -46,7 +46,7 @@ const ProxmoxServerOptions = ({ options }) => {
46
46
  label={__('Qemu Agent')}
47
47
  type="checkbox"
48
48
  value={opts?.agent?.value}
49
- checked={opts?.agent?.value === '1'}
49
+ checked={String(opts?.agent?.value) === '1'}
50
50
  onChange={handleChange}
51
51
  />
52
52
  <InputField
@@ -55,7 +55,7 @@ const ProxmoxServerOptions = ({ options }) => {
55
55
  info={__('Enable/disable KVM hardware virtualization')}
56
56
  type="checkbox"
57
57
  value={opts?.kvm?.value}
58
- checked={opts?.kvm?.value === '1'}
58
+ checked={String(opts?.kvm?.value) === '1'}
59
59
  onChange={handleChange}
60
60
  />
61
61
  <InputField
@@ -74,15 +74,15 @@ const HardDisk = ({
74
74
  onChange={handleChange}
75
75
  />
76
76
  <input
77
- name={hdd?.device?.name}
77
+ name={hdd?.id?.name}
78
78
  type="hidden"
79
- value={hdd?.device?.value}
79
+ value={hdd?.id?.value}
80
80
  onChange={handleChange}
81
81
  />
82
82
  <input
83
- name={hdd?.id?.name}
83
+ name={hdd?.volid?.name}
84
84
  type="hidden"
85
- value={hdd?.id?.value}
85
+ value={hdd?.volid?.value}
86
86
  onChange={handleChange}
87
87
  />
88
88
  <InputField
@@ -102,6 +102,14 @@ const HardDisk = ({
102
102
  onChange={handleChange}
103
103
  error={error}
104
104
  />
105
+ <InputField
106
+ label={__('Device')}
107
+ name={hdd?.device?.name}
108
+ value={hdd?.device?.value}
109
+ onChange={handleChange}
110
+ disabled
111
+ tooltip={__('Device value is set automatically.')}
112
+ />
105
113
  <InputField
106
114
  name={hdd?.cache?.name}
107
115
  label={__('Cache')}
@@ -112,7 +120,7 @@ const HardDisk = ({
112
120
  />
113
121
  <InputField
114
122
  name={hdd?.size?.name}
115
- label={__('Size')}
123
+ label={__('Size (GB)')}
116
124
  type="number"
117
125
  value={hdd?.size?.value}
118
126
  onChange={handleChange}
@@ -115,7 +115,7 @@ const NetworkInterface = ({
115
115
  label={__('Firewall')}
116
116
  type="checkbox"
117
117
  value={network?.firewall?.value}
118
- checked={network?.firewall?.value === '1'}
118
+ checked={String(network?.firewall?.value) === '1'}
119
119
  onChange={handleChange}
120
120
  />
121
121
  <InputField
@@ -123,7 +123,7 @@ const NetworkInterface = ({
123
123
  label={__('Disconnect')}
124
124
  type="checkbox"
125
125
  value={network?.linkDown?.value}
126
- checked={network?.linkDown?.value === '1'}
126
+ checked={String(network?.linkDown?.value) === '1'}
127
127
  onChange={handleChange}
128
128
  />
129
129
  </div>
@@ -33,27 +33,30 @@ const ProxmoxVmType = ({
33
33
  registerComp,
34
34
  untemplatable,
35
35
  }) => {
36
- const nodesMap = nodes
37
- ? nodes.map(node => ({ value: node.node, label: node.node }))
38
- : [];
39
- const imagesMap = images
40
- ? [
41
- { value: '', label: '' },
42
- ...images.map(image => ({
43
- value: image.uuid,
44
- label: image.name,
45
- })),
46
- ]
47
- : [];
48
- const poolsMap = pools
49
- ? [
50
- { value: '', label: '' },
51
- ...pools.map(pool => ({
52
- value: pool.poolid,
53
- label: pool.poolid,
54
- })),
55
- ]
56
- : [];
36
+ const nodesMap =
37
+ nodes.length > 0
38
+ ? nodes.map(node => ({ value: node.node, label: node.node }))
39
+ : [];
40
+ const imagesMap =
41
+ images.length > 0
42
+ ? [
43
+ { value: '', label: '' },
44
+ ...images.map(image => ({
45
+ value: image.uuid,
46
+ label: image.name,
47
+ })),
48
+ ]
49
+ : [];
50
+ const poolsMap =
51
+ pools.length > 0
52
+ ? [
53
+ { value: '', label: '' },
54
+ ...pools.map(pool => ({
55
+ value: pool.poolid,
56
+ label: pool.poolid,
57
+ })),
58
+ ]
59
+ : [];
57
60
  const [activeTabKey, setActiveTabKey] = useState(0);
58
61
  const handleTabClick = (event, tabIndex) => {
59
62
  setActiveTabKey(tabIndex);