foreman_fog_proxmox 0.16.1 → 0.16.2

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 (24) hide show
  1. checksums.yaml +4 -4
  2. data/app/helpers/proxmox_vm_attrs_helper.rb +2 -2
  3. data/app/models/foreman_fog_proxmox/proxmox_interfaces.rb +1 -1
  4. data/app/models/foreman_fog_proxmox/proxmox_volumes.rb +1 -1
  5. data/app/views/compute_resources_vms/form/proxmox/_add_react_component_to_host_form.html.erb +0 -1
  6. data/app/views/templates/provisioning/user_data/proxmox_user_data.erb +119 -0
  7. data/db/seeds.d/71_provisioning_templates.rb +7 -0
  8. data/lib/foreman_fog_proxmox/version.rb +1 -1
  9. data/test/unit/foreman_fog_proxmox/proxmox_interfaces_test.rb +2 -2
  10. data/test/unit/foreman_fog_proxmox/proxmox_vm_commands_server_update_cdrom_test.rb +3 -0
  11. data/webpack/components/GeneralTabContent.js +3 -3
  12. data/webpack/components/ProxmoxComputeSelectors.js +64 -20
  13. data/webpack/components/ProxmoxContainer/MountPoint.js +5 -8
  14. data/webpack/components/ProxmoxContainer/ProxmoxContainerOptions.js +3 -2
  15. data/webpack/components/ProxmoxContainer/ProxmoxContainerStorage.js +1 -1
  16. data/webpack/components/ProxmoxContainer/components/NetworkInterface.js +14 -13
  17. data/webpack/components/ProxmoxServer/ProxmoxServerHardware.js +22 -22
  18. data/webpack/components/ProxmoxServer/ProxmoxServerNetwork.js +1 -1
  19. data/webpack/components/ProxmoxServer/ProxmoxServerOptions.js +3 -3
  20. data/webpack/components/ProxmoxServer/components/HardDisk.js +13 -5
  21. data/webpack/components/ProxmoxServer/components/NetworkInterface.js +2 -2
  22. data/webpack/components/ProxmoxVmType.js +24 -21
  23. data/webpack/components/common/FormInputs.js +10 -2
  24. metadata +19 -17
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 54d5a9b1f9b4ed97380a0fa47196d61bb4ca3b95761eeb81430332166b18cfcd
4
- data.tar.gz: ff6784567daf69fc12818289768a1c8e080655dcdd5b25934ef67950701eb7e0
3
+ metadata.gz: e541fe564b88ed46c9acdce0a10b75bfd963a9d7382004aab237c1ee07eef3c2
4
+ data.tar.gz: 1037763c9e114f76150bfbd5359f9b981f376b4f645d8e71d9195615381d6920
5
5
  SHA512:
6
- metadata.gz: d5746802f2ca998ce4d516c35bb472b52e76d5c248307faf035eb7a46c1bf9b6eb31feffc7236509f7c0cf15a7af672601537c51b00fff3aff3babf2d4501231
7
- data.tar.gz: 82127d47aa58601018263e066ea5149926cc4a6bdab14f54917175f5762f87d246410ea90050cca5e7021393b73c097a638df17e9a4531f7a75754991e4e7f61
6
+ metadata.gz: 33ec2b5af76f6492fb9e5712f1d27689200a4defba3bc4d0e7cef3e76d1e7724943f53c714ca885b2b2d58388e14a60f48b99ef16c0497e819e17592470e417d
7
+ data.tar.gz: dfdc69e48e4992631feab480c4a5b2b159abd59f537927d5169934f647bd72c82bdc4644fab12240a37bd6b65a6302b051bae37bf6df886daff50b7288fc299e
@@ -114,11 +114,11 @@ module ProxmoxVmAttrsHelper
114
114
  start_after_create: vms.start_after_create,
115
115
  templated: vms.templated,
116
116
  }
117
- vms_keys = [:pool, :start_after_create]
117
+ vms_keys = [:cpu_type, :nameserver, :searchdomain, :hostname]
118
118
  extra_attrs = ActiveSupport::HashWithIndifferentAccess.new
119
119
  attributes.each do |key, value|
120
120
  camel_key = key.to_s.include?('_') ? snake_to_camel(key.to_s).to_sym : key
121
- nested_key = vms_keys.include?(key) ? key : "config_attributes[#{key}]"
121
+ nested_key = vms_keys.include?(key) ? "config_attributes[#{key}]" : key
122
122
  value = start_checked if key == :start_after_create
123
123
  extra_attrs[camel_key] = { name: "#{param_scope}[#{nested_key}]", value: value }
124
124
  end
@@ -118,7 +118,7 @@ module ForemanFogProxmox
118
118
  def set_mac(nic_compute_attributes, mac, type)
119
119
  mac_attr_name = { 'qemu' => :macaddr, 'lxc' => :hwaddr }
120
120
  mac_key = mac_attr_name[type] || 'mac'
121
- nic_compute_attributes[mac_key] = Net::Validations.normalize_mac(mac)
121
+ nic_compute_attributes[mac_key] = Net::Validations.normalize_mac(mac).upcase
122
122
  end
123
123
 
124
124
  def host_interfaces_attrs(host)
@@ -107,7 +107,7 @@ module ForemanFogProxmox
107
107
  return false unless disk
108
108
 
109
109
  # Return boolean if disk of type hard_disk, cloud_init, cdrom or rootfs(LXC container) exists
110
- if disk.hard_disk? || disk.cloud_init? || disk.rootfs?
110
+ if disk.hard_disk? || disk.cloud_init? || disk.rootfs? || disk.mount_point?
111
111
  volume_attributes['volid'].present?
112
112
  elsif disk.cdrom?
113
113
  volume_attributes['cdrom'].present?
@@ -1,5 +1,4 @@
1
1
  <% content_for(:javascripts) do %>
2
2
  <%= webpacked_plugins_js_for :foreman_fog_proxmox %>
3
- <%= javascript_include_tag 'foreman_fog_proxmox/proxmox_vm', "data-turbolinks-track" => true %>
4
3
  <% end %>
5
4
  <%= react_component('ProxmoxVmType', { registerComp: true }) unless @host.managed %>
@@ -0,0 +1,119 @@
1
+ <%#
2
+ kind: user_data
3
+ name: Proxmox UserData
4
+ model: ProvisioningTemplate
5
+ require:
6
+ - plugin: foreman_fog_proxmox
7
+ version: 0.16.1
8
+ oses:
9
+ - AlmaLinux
10
+ - Amazon
11
+ - CentOS
12
+ - CentOS_Stream
13
+ - Debian
14
+ - Rocky
15
+ - Ubuntu
16
+ description: |
17
+ This template is used during image based provisioning with Proxmox Compute Resource, when
18
+ the image is configured to use user-data and network config. The output is a list of
19
+ cloud-init directives that cloud-init parses to configures the VM booted from the image.
20
+ The image must have cloud-init installed in order for this to work.
21
+
22
+ This template accepts the following parameters:
23
+ - ssh_pwauth: boolean (default=true unless ssh_authorized_keys)
24
+ - ssh_authorized_keys: string w newline seperated keys (default="")
25
+ - package_upgrade: boolean (default=false)
26
+ - reboot: boolean (default=false)
27
+ - skip-puppet-setup: boolean (default=false)
28
+ -%>
29
+ <%
30
+ ssh_pwauth = host_param('ssh_pwauth') ? host_param_true?('ssh_pwauth') : !host_param('ssh_authorized_keys')
31
+ rhel_compatible = @host.operatingsystem.family == 'Redhat' && @host.operatingsystem.name != 'Fedora'
32
+ # safemode renderer does not support unary negation
33
+ puppet_enabled = !host_param_true?('skip-puppet-setup') && (host_puppet_server.present? || host_param_true?('force-puppet'))
34
+ salt_enabled = host_param('salt_master') ? true : false
35
+ chef_enabled = @host.respond_to?(:chef_proxy) && @host.chef_proxy
36
+ -%>
37
+ <%
38
+ username_to_create = host_param('username_to_create', 'root')
39
+ password_to_create = host_param('password_to_create') || @host.root_pass
40
+ -%>
41
+ #cloud-config
42
+ hostname: <%= @host.shortname %>
43
+ fqdn: <%= @host %>
44
+ manage_etc_hosts: true
45
+ <% if ssh_pwauth -%>
46
+ <%# Don't enable this in production. It is very insecure! Use ssh_authorized_keys instead...
47
+ http://cloudinit.readthedocs.io/en/latest/topics/examples.html#including-users-and-groups -%>
48
+ ssh_pwauth: true
49
+ users:
50
+ - name: <%= username_to_create %>
51
+ shell: /bin/bash
52
+ sudo: ALL=(ALL) ALL
53
+ lock_passwd: false
54
+ hashed_passwd: <%= password_to_create %>
55
+ <% end -%>
56
+ <% if host_param('ssh_authorized_keys') -%>
57
+ ssh_authorized_keys:
58
+ <% host_param('ssh_authorized_keys').split("\n").each do |ssh_key| -%>
59
+ - <%= ssh_key %>
60
+ <% end -%>
61
+ <% end -%>
62
+
63
+ <% if host_param_true?('package_upgrade') -%>
64
+ package_upgrade: true
65
+ <% end -%>
66
+
67
+ runcmd:
68
+ <% if rhel_compatible -%>
69
+ - |
70
+ <%= indent(2) { snippet('epel') } %>
71
+ <% end -%>
72
+ - |
73
+ <%= indent(2) { snippet('remote_execution_ssh_keys') } %>
74
+ <% if chef_enabled -%>
75
+ - |
76
+ <%= indent(2) { snippet('chef_client') } %>
77
+ <% end -%>
78
+ <% if puppet_enabled -%>
79
+ - |
80
+ <%= indent(2) { snippet('puppetlabs_repo') } %>
81
+ - |
82
+ <%= indent(2) { snippet('puppet_setup') } %>
83
+ <% end -%>
84
+ <% if salt_enabled -%>
85
+ - |
86
+ <%= indent(2) { snippet('saltstack_setup') } %>
87
+ <% end -%>
88
+
89
+ <%# Contact Foreman to confirm instance is built -%>
90
+ phone_home:
91
+ url: <%= foreman_url('built') %>
92
+ post: []
93
+ tries: 10
94
+
95
+ <% if host_param_true?('reboot') -%>
96
+ power_state:
97
+ mode: reboot
98
+ timeout: 30
99
+ condition: true
100
+ <% end -%>
101
+
102
+ #network-config
103
+ version: 2
104
+ ethernets:
105
+ eth0:
106
+ match:
107
+ name: e*
108
+ dhcp4: false
109
+ dhcp6: false
110
+ addresses:
111
+ - <%= @host.ip %>/<%= @host.subnet.cidr %>
112
+ routes:
113
+ - to: 0.0.0.0
114
+ via: <%= @host.subnet.gateway %>
115
+ nameservers:
116
+ addresses:
117
+ - <%= @host.subnet.dns_primary%>
118
+ search:
119
+ - <%= @host.domain.name %>
@@ -0,0 +1,7 @@
1
+ # frozen_string_literal: true
2
+
3
+ ProvisioningTemplate.without_auditing do
4
+ SeedHelper.import_templates(
5
+ Dir[File.join("#{ForemanFogProxmox::Engine.root}/app/views/templates/provisioning/**/*.erb")]
6
+ )
7
+ 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.16.1'
21
+ VERSION = '0.16.2'
22
22
  end
@@ -54,7 +54,7 @@ module ForemanFogProxmox
54
54
 
55
55
  it 'sets interface identifier with server compute id, ip and ip6 and mac adress' do
56
56
  ip = '192.168.56.100'
57
- mac_address = '36:25:8c:53:0c:50'
57
+ mac_address = '36:25:8C:53:0C:50'
58
58
  ip6 = Array.new(4) { format('%<x>s', x: rand(16**4)) }.join(':') + '::1'
59
59
  compute_attributes = ActiveSupport::HashWithIndifferentAccess.new({ 'id' => 'net0' })
60
60
  physical_nic = FactoryBot.build(:nic_base_empty, :identifier => 'net0', :ip => ip, :ip6 => ip6,
@@ -131,7 +131,7 @@ module ForemanFogProxmox
131
131
 
132
132
  it 'sets container compute ip DHCP, mac adress and firewall' do
133
133
  ip = '192.168.56.100'
134
- mac_address = '36:25:8c:53:0c:50'
134
+ mac_address = '36:25:8C:53:0C:50'
135
135
  ip6 = '2001:0:1234::c1c0:abcd:876'
136
136
  firewall = '1'
137
137
  compute_attributes = ActiveSupport::HashWithIndifferentAccess.new({ 'id' => 'net0', 'dhcp' => '1',
@@ -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')
@@ -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);
@@ -1,5 +1,6 @@
1
1
  import React, { Fragment } from 'react';
2
2
  import { FieldLevelHelp } from 'patternfly-react';
3
+ import { Tooltip } from '@patternfly/react-core';
3
4
  import PropTypes from 'prop-types';
4
5
  import CommonForm from 'foremanReact/components/common/forms/CommonForm';
5
6
 
@@ -15,6 +16,7 @@ const InputField = ({
15
16
  options,
16
17
  checked,
17
18
  error,
19
+ tooltip,
18
20
  }) => {
19
21
  const renderOptions = opts =>
20
22
  opts.map(option => <option value={option.value}>{option.label}</option>);
@@ -39,7 +41,7 @@ const InputField = ({
39
41
  <select
40
42
  disabled={disabled}
41
43
  name={name}
42
- className="form-control"
44
+ className="without_select2 form-control"
43
45
  value={value}
44
46
  onChange={onChange}
45
47
  >
@@ -88,7 +90,11 @@ const InputField = ({
88
90
  )
89
91
  }
90
92
  >
91
- {renderComponent}
93
+ {tooltip ? (
94
+ <Tooltip content={tooltip}>{renderComponent}</Tooltip>
95
+ ) : (
96
+ renderComponent
97
+ )}
92
98
  {error && (
93
99
  <div style={{ color: 'red', marginTop: '0.5rem' }}>{error}</div>
94
100
  )}
@@ -125,6 +131,7 @@ InputField.propTypes = {
125
131
  })
126
132
  ),
127
133
  error: PropTypes.string,
134
+ tooltip: PropTypes.string,
128
135
  };
129
136
 
130
137
  InputField.defaultProps = {
@@ -138,6 +145,7 @@ InputField.defaultProps = {
138
145
  checked: false,
139
146
  options: [],
140
147
  error: '',
148
+ tooltip: '',
141
149
  };
142
150
 
143
151
  export default InputField;
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: foreman_fog_proxmox
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.16.1
4
+ version: 0.16.2
5
5
  platform: ruby
6
6
  authors:
7
7
  - Tristan Robert
@@ -9,7 +9,7 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2024-07-24 00:00:00.000000000 Z
12
+ date: 2024-10-02 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: deface
@@ -204,8 +204,10 @@ files:
204
204
  - app/views/compute_resources_vms/show/_proxmox.html.erb
205
205
  - app/views/dashboard/_foreman_fog_proxmox_widget.erb
206
206
  - app/views/images/form/_proxmox.html.erb
207
+ - app/views/templates/provisioning/user_data/proxmox_user_data.erb
207
208
  - config/routes.rb
208
209
  - db/migrate/20210312105013_update_proxmox_uuid_host.rb
210
+ - db/seeds.d/71_provisioning_templates.rb
209
211
  - lib/foreman_fog_proxmox.rb
210
212
  - lib/foreman_fog_proxmox/engine.rb
211
213
  - lib/foreman_fog_proxmox/hash_collection.rb
@@ -291,29 +293,29 @@ signing_key:
291
293
  specification_version: 4
292
294
  summary: Foreman plugin that adds Proxmox VE compute resource using fog-proxmox
293
295
  test_files:
294
- - test/unit/foreman_fog_proxmox/proxmox_vm_new_test.rb
295
- - test/unit/foreman_fog_proxmox/proxmox_compute_attributes_test.rb
296
- - test/unit/foreman_fog_proxmox/proxmox_interfaces_test.rb
297
- - test/unit/foreman_fog_proxmox/proxmox_test.rb
296
+ - test/functional/compute_resources_controller_test.rb
297
+ - test/unit/foreman_fog_proxmox/semver_test.rb
298
298
  - test/unit/foreman_fog_proxmox/proxmox_vm_commands_server_update_hard_disk_test.rb
299
- - test/unit/foreman_fog_proxmox/helpers/proxmox_server_helper_test.rb
299
+ - test/unit/foreman_fog_proxmox/proxmox_vm_commands_test.rb
300
300
  - test/unit/foreman_fog_proxmox/helpers/proxmox_container_helper_test.rb
301
301
  - test/unit/foreman_fog_proxmox/helpers/proxmox_vm_volumes_helper_test.rb
302
302
  - test/unit/foreman_fog_proxmox/helpers/proxmox_vm_uuid_helper_test.rb
303
303
  - test/unit/foreman_fog_proxmox/helpers/proxmox_vm_helper_test.rb
304
- - test/unit/foreman_fog_proxmox/proxmox_vm_commands_server_update_test.rb
305
- - test/unit/foreman_fog_proxmox/proxmox_vm_commands_server_create_test.rb
306
- - test/unit/foreman_fog_proxmox/proxmox_vm_commands_container_test.rb
307
- - test/unit/foreman_fog_proxmox/proxmox_images_test.rb
308
- - test/unit/foreman_fog_proxmox/proxmox_vm_commands_test.rb
304
+ - test/unit/foreman_fog_proxmox/helpers/proxmox_server_helper_test.rb
309
305
  - test/unit/foreman_fog_proxmox/proxmox_version_test.rb
306
+ - test/unit/foreman_fog_proxmox/proxmox_interfaces_test.rb
307
+ - test/unit/foreman_fog_proxmox/proxmox_vm_commands_container_test.rb
308
+ - test/unit/foreman_fog_proxmox/proxmox_vm_commands_server_update_test.rb
309
+ - test/unit/foreman_fog_proxmox/proxmox_compute_attributes_test.rb
310
310
  - test/unit/foreman_fog_proxmox/proxmox_vm_queries_test.rb
311
- - test/unit/foreman_fog_proxmox/semver_test.rb
312
- - test/unit/foreman_fog_proxmox/proxmox_vm_commands_server_update_cloudinit_test.rb
311
+ - test/unit/foreman_fog_proxmox/proxmox_images_test.rb
312
+ - test/unit/foreman_fog_proxmox/proxmox_test.rb
313
313
  - test/unit/foreman_fog_proxmox/proxmox_vm_commands_server_update_cdrom_test.rb
314
+ - test/unit/foreman_fog_proxmox/proxmox_vm_commands_server_update_cloudinit_test.rb
315
+ - test/unit/foreman_fog_proxmox/proxmox_vm_new_test.rb
316
+ - test/unit/foreman_fog_proxmox/proxmox_vm_commands_server_create_test.rb
314
317
  - test/test_plugin_helper.rb
318
+ - test/factories/proxmox_factory.rb
315
319
  - test/factories/foreman_fog_proxmox/proxmox_server_mock_factory.rb
316
- - test/factories/foreman_fog_proxmox/proxmox_node_mock_factory.rb
317
320
  - test/factories/foreman_fog_proxmox/proxmox_container_mock_factory.rb
318
- - test/factories/proxmox_factory.rb
319
- - test/functional/compute_resources_controller_test.rb
321
+ - test/factories/foreman_fog_proxmox/proxmox_node_mock_factory.rb