foreman_fog_proxmox 0.16.1 → 0.16.2

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