foreman_fog_proxmox 0.19.1 → 0.20.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/app/controllers/foreman_fog_proxmox/compute_resources_controller.rb +61 -0
- data/app/helpers/proxmox_vm_attrs_helper.rb +13 -2
- data/app/helpers/proxmox_vm_cloudinit_helper.rb +1 -1
- data/app/helpers/proxmox_vm_config_helper.rb +1 -1
- data/app/helpers/proxmox_vm_efidisk_helper.rb +54 -0
- data/app/helpers/proxmox_vm_helper.rb +2 -0
- data/app/models/concerns/fog_extensions/proxmox/server.rb +5 -0
- data/app/models/foreman_fog_proxmox/proxmox_efidisks.rb +29 -0
- data/app/models/foreman_fog_proxmox/proxmox_images.rb +10 -3
- data/app/models/foreman_fog_proxmox/proxmox_vm_commands.rb +10 -1
- data/app/views/compute_resources_vms/form/proxmox/_base.html.erb +34 -16
- data/app/views/compute_resources_vms/show/_proxmox.html.erb +1 -0
- data/config/routes.rb +6 -0
- data/lib/foreman_fog_proxmox/engine.rb +4 -1
- data/lib/foreman_fog_proxmox/version.rb +1 -1
- data/package.json +3 -3
- data/test/functional/compute_resources_controller_test.rb +52 -4
- data/test/unit/foreman_fog_proxmox/proxmox_vm_commands_container_test.rb +5 -0
- data/test/unit/foreman_fog_proxmox/proxmox_vm_commands_server_update_cdrom_test.rb +3 -0
- data/test/unit/foreman_fog_proxmox/proxmox_vm_commands_server_update_cloudinit_test.rb +2 -0
- data/test/unit/foreman_fog_proxmox/proxmox_vm_commands_server_update_hard_disk_test.rb +5 -0
- data/test/unit/foreman_fog_proxmox/proxmox_vm_commands_server_update_test.rb +6 -0
- data/webpack/components/ProxmoxBiosContext.js +33 -0
- data/webpack/components/ProxmoxComputeSelectors.js +2 -2
- data/webpack/components/ProxmoxContainer/ProxmoxContainerNetwork.js +15 -14
- data/webpack/components/ProxmoxContainer/ProxmoxContainerOptions.js +86 -16
- data/webpack/components/ProxmoxContainer/ProxmoxContainerStorage.js +61 -21
- data/webpack/components/ProxmoxServer/ProxmoxServerNetwork.js +3 -3
- data/webpack/components/ProxmoxServer/ProxmoxServerOptions.js +13 -1
- data/webpack/components/ProxmoxServer/ProxmoxServerStorage.js +150 -22
- data/webpack/components/ProxmoxServer/components/CDRom.js +106 -31
- data/webpack/components/ProxmoxServer/components/EFIDisk.js +153 -0
- data/webpack/components/ProxmoxStoragesUtils.js +14 -10
- data/webpack/components/ProxmoxVmType.js +201 -117
- data/webpack/components/ProxmoxVmUtils.js +11 -1
- data/webpack/components/__tests__/ProxmoxComputeSelectors.test.js +40 -0
- data/webpack/components/__tests__/ProxmoxVmType.test.js +54 -0
- data/webpack/components/__tests__/ProxmoxVmUtils.test.js +8 -0
- data/webpack/components/common/FormInputs.js +5 -1
- data/webpack/components/hooks/useVolumes.js +65 -0
- data/webpack/global_test_setup.js +11 -0
- data/webpack/test_setup.js +13 -0
- metadata +12 -2
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: b9245dbe8083dfb0dc96195feaafd9aed1aa448956c2fc497ec5c2c4333bfd2e
|
|
4
|
+
data.tar.gz: 80631b0e56427938aef3a14a08d47f61a0355d9e1928791d362fdf1ba8fcd3bc
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 2c0d7df8aa1b9fe9e7efd370e3356abf6331c93ee291d0b3d8698cfc413b50383ef190ae62fe69076a83f42426cdeca1c83649c64558ec956d92e330462bf527
|
|
7
|
+
data.tar.gz: c920739b5e891307d620234cd667c481b1ab3a5fd6913b4847d87e9d344340a2cd787ba069959d7429b5847a0f30782cee907df399e98ce3aecfecc74ac290cc
|
|
@@ -78,8 +78,69 @@ module ForemanFogProxmox
|
|
|
78
78
|
end
|
|
79
79
|
end
|
|
80
80
|
|
|
81
|
+
# GET foreman_fog_proxmox/volumes/:compute_resource_id/:node_id/:storage
|
|
82
|
+
def volumes_by_node_and_storage
|
|
83
|
+
cr = ComputeResource.find(params[:compute_resource_id])
|
|
84
|
+
node_id = params[:node_id]
|
|
85
|
+
storage = params[:storage]
|
|
86
|
+
|
|
87
|
+
vols = cr.storages(node_id).find { |s| s.storage == storage }&.volumes || []
|
|
88
|
+
|
|
89
|
+
render json: Array(vols).map { |v|
|
|
90
|
+
h = v.respond_to?(:as_json) ? v.as_json : v
|
|
91
|
+
{ volid: (h[:volid] || h['volid']), content: (h[:content] || h['content']) }
|
|
92
|
+
}
|
|
93
|
+
end
|
|
94
|
+
|
|
95
|
+
# GET foreman_fog_proxmox/metadata/:compute_resource_id
|
|
96
|
+
def metadata
|
|
97
|
+
cr = ComputeResource.find(params[:compute_resource_id])
|
|
98
|
+
|
|
99
|
+
render json: {
|
|
100
|
+
nodes: extract_nodes(cr),
|
|
101
|
+
pools: extract_pools(cr),
|
|
102
|
+
storages: extract_storages(cr),
|
|
103
|
+
bridges: extract_bridges(cr),
|
|
104
|
+
}
|
|
105
|
+
end
|
|
106
|
+
|
|
81
107
|
private
|
|
82
108
|
|
|
109
|
+
def extract_nodes(compute_resource)
|
|
110
|
+
Array(compute_resource.nodes).map { |n| { node: n.node } }
|
|
111
|
+
end
|
|
112
|
+
|
|
113
|
+
def extract_pools(compute_resource)
|
|
114
|
+
Array(compute_resource.pools).map do |p|
|
|
115
|
+
poolid = p.respond_to?(:poolid) ? p.poolid : (p[:poolid] || p['poolid'])
|
|
116
|
+
{ poolid: poolid }
|
|
117
|
+
end
|
|
118
|
+
end
|
|
119
|
+
|
|
120
|
+
def extract_storages(compute_resource)
|
|
121
|
+
Array(compute_resource.storages).map do |s|
|
|
122
|
+
h = s.respond_to?(:as_json) ? s.as_json : s
|
|
123
|
+
{
|
|
124
|
+
storage: (h[:storage] || h['storage']),
|
|
125
|
+
node_id: (h[:node_id] || h['node_id']),
|
|
126
|
+
content: (h[:content] || h['content']),
|
|
127
|
+
avail: (h[:avail] || h['avail']),
|
|
128
|
+
used: (h[:used] || h['used']),
|
|
129
|
+
total: (h[:total] || h['total']),
|
|
130
|
+
}
|
|
131
|
+
end
|
|
132
|
+
end
|
|
133
|
+
|
|
134
|
+
def extract_bridges(compute_resource)
|
|
135
|
+
Array(compute_resource.bridges).map do |b|
|
|
136
|
+
h = b.respond_to?(:as_json) ? b.as_json : b
|
|
137
|
+
{
|
|
138
|
+
node_id: (h[:node_id] || h['node_id']),
|
|
139
|
+
iface: (h[:iface] || h['iface']),
|
|
140
|
+
}
|
|
141
|
+
end
|
|
142
|
+
end
|
|
143
|
+
|
|
83
144
|
def load_compute_resource(compute_resource_id)
|
|
84
145
|
ComputeResource.find(compute_resource_id)
|
|
85
146
|
end
|
|
@@ -28,7 +28,7 @@ module ProxmoxVMAttrsHelper
|
|
|
28
28
|
def object_to_attributes_hash(vms, from_profile, start_checked)
|
|
29
29
|
param_scope = from_profile ? "compute_attribute[vm_attrs]" : "host[compute_attributes]"
|
|
30
30
|
vm_h = ActiveSupport::HashWithIndifferentAccess.new
|
|
31
|
-
keys = [:vmid, :node_id, :type, :pool]
|
|
31
|
+
keys = [:vmid, :node_id, :type, :pool, :efidisk]
|
|
32
32
|
main = vms.attributes.select { |key, _value| keys.include? key }
|
|
33
33
|
vms.config.all_attributes.each do |key, value|
|
|
34
34
|
camel_key = key.to_s.include?('_') ? snake_to_camel(key.to_s).to_sym : key
|
|
@@ -42,7 +42,9 @@ module ProxmoxVMAttrsHelper
|
|
|
42
42
|
vm_h.merge!(additional_attrs(vms, param_scope, start_checked))
|
|
43
43
|
vm_h[:interfaces] = network_attrs(param_scope, vms.interfaces)
|
|
44
44
|
vm_h[:disks] = volumes_attrs(param_scope, vms.volumes)
|
|
45
|
-
vm_h
|
|
45
|
+
vm_h[:efidisk] = efidisk_attrs(param_scope, vms.efidisk) if vms.efidisk.present?
|
|
46
|
+
vm_h.merge!(cpu_flags_attrs(param_scope, vms.config))
|
|
47
|
+
vm_h
|
|
46
48
|
end
|
|
47
49
|
|
|
48
50
|
def cpu_flags_attrs(param_scope, config)
|
|
@@ -53,6 +55,15 @@ module ProxmoxVMAttrsHelper
|
|
|
53
55
|
flag_attrs
|
|
54
56
|
end
|
|
55
57
|
|
|
58
|
+
def efidisk_attrs(param_scope, efidisk)
|
|
59
|
+
attrs = ActiveSupport::HashWithIndifferentAccess.new
|
|
60
|
+
keys = ['id', 'volid', 'size', 'storage', 'format', 'efitype', 'pre_enrolled_keys']
|
|
61
|
+
keys.each do |key|
|
|
62
|
+
attrs[key] = { :name => "#{param_scope}[efidisk_attributes][#{key}]", :value => efidisk.public_send(key) }
|
|
63
|
+
end
|
|
64
|
+
attrs
|
|
65
|
+
end
|
|
66
|
+
|
|
56
67
|
def volumes_attrs(param_scope, volumes)
|
|
57
68
|
vol_attrs = []
|
|
58
69
|
volumes.each_with_index do |vol, id|
|
|
@@ -48,7 +48,7 @@ module ProxmoxVMCloudinitHelper
|
|
|
48
48
|
wd = create_temp_directory(ssh)
|
|
49
49
|
|
|
50
50
|
configs.each do |config|
|
|
51
|
-
config_file = ssh.run(
|
|
51
|
+
config_file = ssh.run("cat <<'EOF' > '#{wd}/#{config[0]}'\n#{config[1]}\nEOF")
|
|
52
52
|
unless config_file.first.status.zero?
|
|
53
53
|
delete_temp_dir(ssh, wd)
|
|
54
54
|
raise ::Foreman::Exception, "Failed to create file #{config[0]}: #{config_file.first.stdout}"
|
|
@@ -40,7 +40,7 @@ module ProxmoxVMConfigHelper
|
|
|
40
40
|
end
|
|
41
41
|
|
|
42
42
|
def general_a(type)
|
|
43
|
-
general_a = ['node_id', 'type', 'config_attributes', 'volumes_attributes', 'interfaces_attributes', 'image_id']
|
|
43
|
+
general_a = ['node_id', 'type', 'config_attributes', 'efidisk_attributes', 'volumes_attributes', 'interfaces_attributes', 'image_id']
|
|
44
44
|
general_a += ['firmware_type', 'provision_method', 'container_volumes', 'server_volumes', 'start_after_create']
|
|
45
45
|
general_a += ['name'] if type == 'lxc'
|
|
46
46
|
general_a
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
# Copyright 2026 ATIX AG
|
|
4
|
+
|
|
5
|
+
# This file is part of ForemanFogProxmox.
|
|
6
|
+
|
|
7
|
+
# ForemanFogProxmox is free software: you can redistribute it and/or modify
|
|
8
|
+
# it under the terms of the GNU General Public License as published by
|
|
9
|
+
# the Free Software Foundation, either version 3 of the License, or
|
|
10
|
+
# (at your option) any later version.
|
|
11
|
+
|
|
12
|
+
# ForemanFogProxmox is distributed in the hope that it will be useful,
|
|
13
|
+
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
14
|
+
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
15
|
+
# GNU General Public License for more details.
|
|
16
|
+
|
|
17
|
+
# You should have received a copy of the GNU General Public License
|
|
18
|
+
# along with ForemanFogProxmox. If not, see <http://www.gnu.org/licenses/>.
|
|
19
|
+
|
|
20
|
+
require 'fog/proxmox/helpers/efidisk_helper'
|
|
21
|
+
require 'foreman_fog_proxmox/value'
|
|
22
|
+
require 'foreman_fog_proxmox/hash_collection'
|
|
23
|
+
|
|
24
|
+
# Convert a foreman form server hash into a fog-proxmox server attributes hash
|
|
25
|
+
module ProxmoxVMEfidiskHelper
|
|
26
|
+
def parsed_typed_efidisk(args, type, parsed_vm)
|
|
27
|
+
attrs = args['efidisk_attributes']
|
|
28
|
+
|
|
29
|
+
# we need the vmid to create the volid if not present
|
|
30
|
+
vmid = args['vmid'] if args.key?('vmid')
|
|
31
|
+
# fallback to a dummy vmid for new vms
|
|
32
|
+
vmid ||= 'no_vmid_yet'
|
|
33
|
+
|
|
34
|
+
logger.debug("parsed_typed_efidisk(#{type}): attrs=#{attrs} with #{vmid}")
|
|
35
|
+
unless ForemanFogProxmox::Value.empty?(args['efidisk_attributes'])
|
|
36
|
+
efidisk = parse_typed_efidisk(attrs, vmid, type)
|
|
37
|
+
logger.debug("parsed_typed_efidisk(#{type}): efidisk=#{efidisk}")
|
|
38
|
+
parsed_vm = parsed_vm.merge(efidisk)
|
|
39
|
+
end
|
|
40
|
+
parsed_vm
|
|
41
|
+
end
|
|
42
|
+
|
|
43
|
+
def parse_typed_efidisk(args, _vmid, _type)
|
|
44
|
+
logger.debug(format(_('parse_efidisk(): args=%<args>s'), args: args))
|
|
45
|
+
efidisk = {}
|
|
46
|
+
efidisk[:id] = args['id'] if args.key?('id')
|
|
47
|
+
efidisk[:volid] = args['volid']
|
|
48
|
+
efidisk[:size] = args['size'].to_i if args.key?('size') && !args['size'].empty?
|
|
49
|
+
efidisk[:format] = args['format']
|
|
50
|
+
efidisk[:efitype] = args['efitype'] if args.key?('efitype') && !args['efitype'].empty?
|
|
51
|
+
efidisk[:pre_enrolled_keys] = args['pre_enrolled_keys'] if args.key?('pre_enrolled_keys')
|
|
52
|
+
Fog::Proxmox::EfidiskHelper.flatten(efidisk)
|
|
53
|
+
end
|
|
54
|
+
end
|
|
@@ -26,6 +26,7 @@ module ProxmoxVMHelper
|
|
|
26
26
|
include ProxmoxVMVolumesHelper
|
|
27
27
|
include ProxmoxVMConfigHelper
|
|
28
28
|
include ProxmoxVMOsTemplateHelper
|
|
29
|
+
include ProxmoxVMEfidiskHelper
|
|
29
30
|
|
|
30
31
|
def vm_collection(type)
|
|
31
32
|
collection = :servers
|
|
@@ -42,6 +43,7 @@ module ProxmoxVMHelper
|
|
|
42
43
|
|
|
43
44
|
logger.debug("parse_typed_vm(#{type}): args=#{args}")
|
|
44
45
|
parsed_vm = parsed_typed_config(args, type)
|
|
46
|
+
parsed_vm = parsed_typed_efidisk(args, type, parsed_vm)
|
|
45
47
|
parsed_vm = parsed_typed_interfaces(args, type, parsed_vm)
|
|
46
48
|
parsed_vm = parsed_typed_volumes(args, type, parsed_vm)
|
|
47
49
|
logger.debug("parse_typed_vm(#{type}): parsed_vm=#{parsed_vm}")
|
|
@@ -44,6 +44,10 @@ module FogExtensions
|
|
|
44
44
|
reboot
|
|
45
45
|
end
|
|
46
46
|
|
|
47
|
+
def poweroff
|
|
48
|
+
stop
|
|
49
|
+
end
|
|
50
|
+
|
|
47
51
|
def mac
|
|
48
52
|
config.mac_addresses.first
|
|
49
53
|
end
|
|
@@ -81,6 +85,7 @@ module FogExtensions
|
|
|
81
85
|
config.disks.collect(&:to_s)
|
|
82
86
|
end
|
|
83
87
|
|
|
88
|
+
delegate :efidisk, to: :config
|
|
84
89
|
delegate :vga, to: :config
|
|
85
90
|
delegate :pool, to: :config
|
|
86
91
|
delegate :cloud_init?, to: :config
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
# Copyright 2019 ATIX AG
|
|
4
|
+
|
|
5
|
+
# This file is part of ForemanFogProxmox.
|
|
6
|
+
|
|
7
|
+
# ForemanFogProxmox is free software: you can redistribute it and/or modify
|
|
8
|
+
# it under the terms of the GNU General Public License as published by
|
|
9
|
+
# the Free Software Foundation, either version 3 of the License, or
|
|
10
|
+
# (at your option) any later version.
|
|
11
|
+
|
|
12
|
+
# ForemanFogProxmox is distributed in the hope that it will be useful,
|
|
13
|
+
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
14
|
+
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
15
|
+
# GNU General Public License for more details.
|
|
16
|
+
|
|
17
|
+
# You should have received a copy of the GNU General Public License
|
|
18
|
+
# along with ForemanFogProxmox. If not, see <http://www.gnu.org/licenses/>.
|
|
19
|
+
|
|
20
|
+
module ForemanFogProxmox
|
|
21
|
+
module ProxmoxEfidisks
|
|
22
|
+
include ProxmoxVMHelper
|
|
23
|
+
|
|
24
|
+
def delete_efidisk(vmobj)
|
|
25
|
+
logger.info("vm #{vmobj.identity} delete efidisk0")
|
|
26
|
+
vmobj.detach('efidisk0')
|
|
27
|
+
end
|
|
28
|
+
end
|
|
29
|
+
end
|
|
@@ -48,11 +48,18 @@ module ForemanFogProxmox
|
|
|
48
48
|
volumes = []
|
|
49
49
|
nodes.each do |node|
|
|
50
50
|
storages(node.node).each do |storage|
|
|
51
|
-
#
|
|
52
|
-
|
|
51
|
+
# Skip disabled storages (enabled == 0 or nil)
|
|
52
|
+
unless storage.enabled.to_i == 1
|
|
53
|
+
logger.warn("Skipping disabled storage #{storage.identity} on #{node.node}")
|
|
54
|
+
next
|
|
55
|
+
end
|
|
53
56
|
|
|
54
|
-
#
|
|
57
|
+
# Fetch QEMU and LXC template images
|
|
58
|
+
volumes += storage.volumes.list_by_content_type('images')
|
|
55
59
|
volumes += storage.volumes.list_by_content_type('rootdir')
|
|
60
|
+
rescue StandardError => e
|
|
61
|
+
logger.error("Failed to fetch volumes for storage #{storage.identity} on #{node.node}: #{e.message}")
|
|
62
|
+
next
|
|
56
63
|
end
|
|
57
64
|
end
|
|
58
65
|
# for creating image, only list volumes which are templated
|
|
@@ -22,6 +22,7 @@ require 'foreman_fog_proxmox/hash_collection'
|
|
|
22
22
|
module ForemanFogProxmox
|
|
23
23
|
module ProxmoxVMCommands
|
|
24
24
|
include ProxmoxVolumes
|
|
25
|
+
include ProxmoxEfidisks
|
|
25
26
|
include ProxmoxPools
|
|
26
27
|
include ProxmoxVMHelper
|
|
27
28
|
|
|
@@ -72,7 +73,7 @@ module ForemanFogProxmox
|
|
|
72
73
|
vm = find_vm_by_uuid(uuid)
|
|
73
74
|
return true if vm.nil?
|
|
74
75
|
vm.stop if vm.ready?
|
|
75
|
-
vm.destroy
|
|
76
|
+
vm.ha&.dig("managed").to_i == 1 ? vm.destroy(query: { purge: 1 }) : vm.destroy
|
|
76
77
|
rescue ActiveRecord::RecordNotFound
|
|
77
78
|
# if the VM does not exists, we don't really care.
|
|
78
79
|
true
|
|
@@ -109,9 +110,17 @@ module ForemanFogProxmox
|
|
|
109
110
|
['volumes_attributes']).merge(type: vm.type), vm.type
|
|
110
111
|
)
|
|
111
112
|
config_attributes = compute_config_attributes(parsed_attr)
|
|
113
|
+
|
|
112
114
|
volumes_attributes = new_attributes['volumes_attributes']
|
|
113
115
|
logger.debug("save_vm(#{uuid}) volumes_attributes=#{volumes_attributes}")
|
|
114
116
|
volumes_attributes&.each_value { |volume_attributes| save_volume(vm, volume_attributes) }
|
|
117
|
+
|
|
118
|
+
efidisk_attributes = new_attributes['efidisk_attributes']
|
|
119
|
+
if vm.config.efidisk.present? && efidisk_attributes.empty?
|
|
120
|
+
logger.debug("Removing efidisk from VM #{vm}")
|
|
121
|
+
delete_efidisk(vm)
|
|
122
|
+
end
|
|
123
|
+
|
|
115
124
|
vm.update(config_attributes[:config_attributes])
|
|
116
125
|
poolid = new_attributes['pool'] if new_attributes.key?('pool')
|
|
117
126
|
update_pool(vm, poolid) if poolid
|
|
@@ -14,25 +14,43 @@ GNU General Public License for more details.
|
|
|
14
14
|
|
|
15
15
|
You should have received a copy of the GNU General Public License
|
|
16
16
|
along with ForemanFogProxmox. If not, see <http://www.gnu.org/licenses/>. %>
|
|
17
|
-
|
|
17
|
+
|
|
18
18
|
<% unless local_assigns[:hide_image] && !new_vm %>
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
<%= select_f f, :image_id, images, :uuid, :name, { :
|
|
25
|
-
:
|
|
26
|
-
:
|
|
27
|
-
:
|
|
28
|
-
:
|
|
29
|
-
:
|
|
30
|
-
:
|
|
31
|
-
|
|
19
|
+
<%
|
|
20
|
+
arch ||= nil ; os ||= nil
|
|
21
|
+
images = possible_images(compute_resource, arch, os)
|
|
22
|
+
-%>
|
|
23
|
+
<div id='image_selection'>
|
|
24
|
+
<%= select_f f, :image_id, images, :uuid, :name, { include_blank: true },
|
|
25
|
+
disabled: true,
|
|
26
|
+
help_inline: :indicator,
|
|
27
|
+
class: ("without_select2 #{'hide' if from_profile}"),
|
|
28
|
+
label: _('Image'),
|
|
29
|
+
no_label: from_profile,
|
|
30
|
+
label_size: "col-md-2" %>
|
|
31
|
+
</div>
|
|
32
32
|
<% end %>
|
|
33
|
+
|
|
33
34
|
<% untemplatable = new_vm || f.object.templated? %>
|
|
34
|
-
<% checked = params
|
|
35
|
+
<% checked = (params.dig(:host, :compute_attributes, :start_after_create) || '1') %>
|
|
36
|
+
|
|
35
37
|
<% content_for(:javascripts) do %>
|
|
36
38
|
<%= webpacked_plugins_js_for :foreman_fog_proxmox %>
|
|
37
39
|
<% end %>
|
|
38
|
-
|
|
40
|
+
|
|
41
|
+
<%
|
|
42
|
+
vm_attrs = object_to_attributes_hash(f.object, from_profile, checked)
|
|
43
|
+
|
|
44
|
+
props = {
|
|
45
|
+
vmAttrs: vm_attrs,
|
|
46
|
+
computeResourceId: compute_resource.id,
|
|
47
|
+
propsLoaded: false,
|
|
48
|
+
fromProfile: from_profile,
|
|
49
|
+
newVm: new_vm,
|
|
50
|
+
untemplatable: untemplatable,
|
|
51
|
+
registerComp: local_assigns[:registerComp] || false,
|
|
52
|
+
images: (defined?(images) && images ? images.as_json : [])
|
|
53
|
+
}
|
|
54
|
+
%>
|
|
55
|
+
|
|
56
|
+
<%= react_component('ProxmoxVmType', props) %>
|
data/config/routes.rb
CHANGED
|
@@ -30,5 +30,11 @@ Rails.application.routes.draw do
|
|
|
30
30
|
match 'isostorages/:compute_resource_id/:node_id', :to => 'compute_resources#iso_storages_by_id_and_node',
|
|
31
31
|
:via => 'get'
|
|
32
32
|
match 'bridges/:compute_resource_id/:node_id', :to => 'compute_resources#bridges_by_id_and_node', :via => 'get'
|
|
33
|
+
match 'volumes/:compute_resource_id/:node_id/:storage',
|
|
34
|
+
:to => 'compute_resources#volumes_by_node_and_storage',
|
|
35
|
+
:via => 'get'
|
|
36
|
+
match 'metadata/:compute_resource_id',
|
|
37
|
+
:to => 'compute_resources#metadata',
|
|
38
|
+
:via => 'get'
|
|
33
39
|
end
|
|
34
40
|
end
|
|
@@ -49,7 +49,9 @@ module ForemanFogProxmox
|
|
|
49
49
|
:isos_by_id_and_node,
|
|
50
50
|
:storages_by_id_and_node,
|
|
51
51
|
:iso_storages_by_id_and_node,
|
|
52
|
-
:bridges_by_id_and_node
|
|
52
|
+
:bridges_by_id_and_node,
|
|
53
|
+
:volumes_by_node_and_storage,
|
|
54
|
+
:metadata] }
|
|
53
55
|
end
|
|
54
56
|
end
|
|
55
57
|
end
|
|
@@ -92,6 +94,7 @@ module ForemanFogProxmox
|
|
|
92
94
|
require 'fog/proxmox/compute/models/server'
|
|
93
95
|
require 'fog/proxmox/compute/models/server_config'
|
|
94
96
|
require 'fog/proxmox/compute/models/disk'
|
|
97
|
+
require 'fog/proxmox/compute/models/efidisk'
|
|
95
98
|
require 'fog/proxmox/compute/models/interface'
|
|
96
99
|
require 'fog/proxmox/compute/models/volume'
|
|
97
100
|
require 'fog/proxmox/compute/models/node'
|
data/package.json
CHANGED
|
@@ -5,9 +5,9 @@
|
|
|
5
5
|
"main": "index.js",
|
|
6
6
|
"scripts": {
|
|
7
7
|
"lint": "tfm-lint --plugin -d webpack",
|
|
8
|
-
"test": "tfm-test --
|
|
9
|
-
"test:watch": "tfm-test --plugin --watchAll",
|
|
10
|
-
"test:current": "tfm-test --plugin --watch",
|
|
8
|
+
"test": "tfm-test --config jest.config.js",
|
|
9
|
+
"test:watch": "tfm-test --config jest.config.js --plugin --watchAll",
|
|
10
|
+
"test:current": "tfm-test --config jest.config.js --plugin --watch",
|
|
11
11
|
"publish-coverage": "tfm-publish-coverage",
|
|
12
12
|
"stories": "tfm-stories --plugin",
|
|
13
13
|
"stories:build": "tfm-build-stories --plugin",
|
|
@@ -20,31 +20,79 @@ require 'test_plugin_helper'
|
|
|
20
20
|
|
|
21
21
|
module ForemanFogProxmox
|
|
22
22
|
class ComputeResourcesControllerTest < ActionController::TestCase
|
|
23
|
+
tests ForemanFogProxmox::ComputeResourcesController
|
|
24
|
+
|
|
25
|
+
setup do
|
|
26
|
+
@compute_resource = FactoryBot.create(:proxmox_cr)
|
|
27
|
+
mock_storage = mock('storage')
|
|
28
|
+
mock_storage.stubs(:storage).returns('local')
|
|
29
|
+
mock_storage.stubs(:volumes).returns([])
|
|
30
|
+
|
|
31
|
+
@compute_resource.stubs(:images_by_storage).returns([])
|
|
32
|
+
@compute_resource.stubs(:nodes).returns([])
|
|
33
|
+
@compute_resource.stubs(:pools).returns([])
|
|
34
|
+
@compute_resource.stubs(:storages).with('proxmox').returns([mock_storage])
|
|
35
|
+
@compute_resource.stubs(:storages).with('proxmox', 'vztmpl').returns([])
|
|
36
|
+
@compute_resource.stubs(:storages).with('proxmox', 'iso').returns([])
|
|
37
|
+
@compute_resource.stubs(:storages).with(nil).returns([])
|
|
38
|
+
@compute_resource.stubs(:bridges).returns([])
|
|
39
|
+
|
|
40
|
+
# Stub ComputeResource.find to return our stubbed instance
|
|
41
|
+
ComputeResource.stubs(:find).with(@compute_resource.id).returns(@compute_resource)
|
|
42
|
+
ComputeResource.stubs(:find).with(@compute_resource.id.to_s).returns(@compute_resource)
|
|
43
|
+
end
|
|
44
|
+
|
|
23
45
|
test 'should get isos by node and storage' do
|
|
24
46
|
get :isos_by_id_and_node_and_storage,
|
|
25
|
-
params: { :compute_resource_id =>
|
|
47
|
+
params: { :compute_resource_id => @compute_resource.id, :node_id => 'proxmox', :storage => 'local' }
|
|
26
48
|
assert_response :found
|
|
27
49
|
show_response = @response.body
|
|
28
50
|
assert_not show_response.empty?
|
|
29
51
|
end
|
|
30
52
|
test 'should get ostemplates by node and storage' do
|
|
31
53
|
get :ostemplates_by_id_and_node_and_storage,
|
|
32
|
-
params: { :compute_resource_id =>
|
|
54
|
+
params: { :compute_resource_id => @compute_resource.id, :node_id => 'proxmox', :storage => 'local' }
|
|
33
55
|
assert_response :found
|
|
34
56
|
show_response = @response.body
|
|
35
57
|
assert_not show_response.empty?
|
|
36
58
|
end
|
|
37
59
|
test 'should get isos by node' do
|
|
38
|
-
get :isos_by_id_and_node, params: { :compute_resource_id =>
|
|
60
|
+
get :isos_by_id_and_node, params: { :compute_resource_id => @compute_resource.id, :node_id => 'proxmox' }
|
|
39
61
|
assert_response :found
|
|
40
62
|
show_response = @response.body
|
|
41
63
|
assert_not show_response.empty?
|
|
42
64
|
end
|
|
43
65
|
test 'should get ostemplates by node' do
|
|
44
|
-
get :ostemplates_by_id_and_node, params: { :compute_resource_id =>
|
|
66
|
+
get :ostemplates_by_id_and_node, params: { :compute_resource_id => @compute_resource.id, :node_id => 'proxmox' }
|
|
45
67
|
assert_response :found
|
|
46
68
|
show_response = @response.body
|
|
47
69
|
assert_not show_response.empty?
|
|
48
70
|
end
|
|
71
|
+
test 'should get volumes by node and storage' do
|
|
72
|
+
get :volumes_by_node_and_storage,
|
|
73
|
+
params: { :compute_resource_id => @compute_resource.id, :node_id => 'proxmox', :storage => 'local' },
|
|
74
|
+
session: set_session_user
|
|
75
|
+
assert_response :success
|
|
76
|
+
show_response = @response.body
|
|
77
|
+
assert_not show_response.empty?
|
|
78
|
+
json_response = JSON.parse(show_response)
|
|
79
|
+
assert_instance_of Array, json_response
|
|
80
|
+
end
|
|
81
|
+
test 'should get metadata' do
|
|
82
|
+
get :metadata, params: { :compute_resource_id => @compute_resource.id }, session: set_session_user
|
|
83
|
+
assert_response :success
|
|
84
|
+
show_response = @response.body
|
|
85
|
+
assert_not show_response.empty?
|
|
86
|
+
json_response = JSON.parse(show_response)
|
|
87
|
+
assert_instance_of Hash, json_response
|
|
88
|
+
assert json_response.key?('nodes')
|
|
89
|
+
assert json_response.key?('pools')
|
|
90
|
+
assert json_response.key?('storages')
|
|
91
|
+
assert json_response.key?('bridges')
|
|
92
|
+
assert_instance_of Array, json_response['nodes']
|
|
93
|
+
assert_instance_of Array, json_response['pools']
|
|
94
|
+
assert_instance_of Array, json_response['storages']
|
|
95
|
+
assert_instance_of Array, json_response['bridges']
|
|
96
|
+
end
|
|
49
97
|
end
|
|
50
98
|
end
|
|
@@ -39,6 +39,7 @@ module ForemanFogProxmox
|
|
|
39
39
|
uuid = '100'
|
|
40
40
|
config = mock('config')
|
|
41
41
|
config.stubs(:attributes).returns(:cores => '')
|
|
42
|
+
config.stubs(:efidisk).returns(nil)
|
|
42
43
|
vm = mock('vm')
|
|
43
44
|
vm.stubs(:config).returns(config)
|
|
44
45
|
vm.stubs(:container?).returns(true)
|
|
@@ -59,6 +60,7 @@ module ForemanFogProxmox
|
|
|
59
60
|
uuid = '100'
|
|
60
61
|
config = mock('config')
|
|
61
62
|
config.stubs(:attributes).returns(:cores => '')
|
|
63
|
+
config.stubs(:efidisk).returns(nil)
|
|
62
64
|
vm = mock('vm')
|
|
63
65
|
vm.stubs(:config).returns(config)
|
|
64
66
|
vm.stubs(:container?).returns(true)
|
|
@@ -87,6 +89,7 @@ module ForemanFogProxmox
|
|
|
87
89
|
disk.stubs(:id).returns('mp0')
|
|
88
90
|
disks.stubs(:get).returns
|
|
89
91
|
config.stubs(:disks).returns(disks)
|
|
92
|
+
config.stubs(:efidisk).returns(nil)
|
|
90
93
|
config.stubs(:attributes).returns(:cores => '')
|
|
91
94
|
vm = mock('vm')
|
|
92
95
|
vm.stubs(:identity).returns(uuid)
|
|
@@ -148,6 +151,7 @@ module ForemanFogProxmox
|
|
|
148
151
|
disk.stubs(:attributes).returns(id: 'rootfs', storage: 'local-lvm', size: '1')
|
|
149
152
|
disks.stubs(:get).returns(disk)
|
|
150
153
|
config.stubs(:disks).returns(disks)
|
|
154
|
+
config.stubs(:efidisk).returns(nil)
|
|
151
155
|
config.stubs(:attributes).returns(:cores => '')
|
|
152
156
|
vm = mock('vm')
|
|
153
157
|
vm.stubs(:identity).returns(uuid)
|
|
@@ -207,6 +211,7 @@ module ForemanFogProxmox
|
|
|
207
211
|
disk.stubs(:attributes).returns(id: 'mp0', storage: 'local-lvm', size: '1', volid: 'local-lvm:vm-100-disk-0')
|
|
208
212
|
disks.stubs(:get).returns(disk)
|
|
209
213
|
config.stubs(:disks).returns(disks)
|
|
214
|
+
config.stubs(:efidisk).returns(nil)
|
|
210
215
|
config.stubs(:attributes).returns(:cores => '')
|
|
211
216
|
vm = mock('vm')
|
|
212
217
|
vm.stubs(:identity).returns(uuid)
|
|
@@ -48,6 +48,7 @@ module ForemanFogProxmox
|
|
|
48
48
|
disk.stubs(:mount_point?).returns(false)
|
|
49
49
|
disks.stubs(:get).returns
|
|
50
50
|
config.stubs(:disks).returns(disks)
|
|
51
|
+
config.stubs(:efidisk).returns(nil)
|
|
51
52
|
config.stubs(:attributes).returns(:cores => '')
|
|
52
53
|
vm = mock('vm')
|
|
53
54
|
vm.stubs(:identity).returns(uuid)
|
|
@@ -104,6 +105,7 @@ module ForemanFogProxmox
|
|
|
104
105
|
disk.stubs(:id).returns('ide2')
|
|
105
106
|
disks.stubs(:get).returns(disk)
|
|
106
107
|
config.stubs(:disks).returns(disks)
|
|
108
|
+
config.stubs(:efidisk).returns(nil)
|
|
107
109
|
config.stubs(:attributes).returns(:cores => '1', :cpulimit => '1')
|
|
108
110
|
vm = mock('vm')
|
|
109
111
|
vm.stubs(:identity).returns(uuid)
|
|
@@ -159,6 +161,7 @@ module ForemanFogProxmox
|
|
|
159
161
|
disk.stubs(:attributes).returns(id: 'ide2', storage: 'local-lvm', volid: 'local-lvm:vm-100-disk-0', size: '1')
|
|
160
162
|
disks.stubs(:get).returns(disk)
|
|
161
163
|
config.stubs(:disks).returns(disks)
|
|
164
|
+
config.stubs(:efidisk).returns(nil)
|
|
162
165
|
config.stubs(:attributes).returns(:cores => '')
|
|
163
166
|
vm = mock('vm')
|
|
164
167
|
vm.stubs(:identity).returns(uuid)
|
|
@@ -44,6 +44,7 @@ module ForemanFogProxmox
|
|
|
44
44
|
disk.stubs(:id).returns('ide0')
|
|
45
45
|
disks.stubs(:get).returns
|
|
46
46
|
config.stubs(:disks).returns(disks)
|
|
47
|
+
config.stubs(:efidisk).returns(nil)
|
|
47
48
|
config.stubs(:attributes).returns(:cores => '')
|
|
48
49
|
vm = mock('vm')
|
|
49
50
|
vm.stubs(:identity).returns(uuid)
|
|
@@ -96,6 +97,7 @@ module ForemanFogProxmox
|
|
|
96
97
|
disk.stubs(:cloud_init?).returns(true)
|
|
97
98
|
disks.stubs(:get).returns(disk)
|
|
98
99
|
config.stubs(:disks).returns(disks)
|
|
100
|
+
config.stubs(:efidisk).returns(nil)
|
|
99
101
|
config.stubs(:attributes).returns(:cores => '1')
|
|
100
102
|
vm = mock('vm')
|
|
101
103
|
vm.stubs(:identity).returns(uuid)
|
|
@@ -50,6 +50,7 @@ module ForemanFogProxmox
|
|
|
50
50
|
disk.stubs(:attributes).returns(id: 'scsi0', storage: 'local-lvm', size: '1')
|
|
51
51
|
disks.stubs(:get).returns
|
|
52
52
|
config.stubs(:disks).returns(disks)
|
|
53
|
+
config.stubs(:efidisk).returns(nil)
|
|
53
54
|
config.stubs(:attributes).returns(:cores => '')
|
|
54
55
|
vm = mock('vm')
|
|
55
56
|
vm.stubs(:identity).returns(uuid)
|
|
@@ -101,6 +102,7 @@ module ForemanFogProxmox
|
|
|
101
102
|
disk.stubs(:id).returns('virtio0')
|
|
102
103
|
disks.stubs(:get).returns(disk)
|
|
103
104
|
config.stubs(:disks).returns(disks)
|
|
105
|
+
config.stubs(:efidisk).returns(nil)
|
|
104
106
|
config.stubs(:attributes).returns(:cores => '')
|
|
105
107
|
vm = mock('vm')
|
|
106
108
|
vm.stubs(:identity).returns(uuid)
|
|
@@ -157,6 +159,7 @@ module ForemanFogProxmox
|
|
|
157
159
|
disk.stubs(:attributes).returns(id: 'scsi0', storage: 'local-lvm', size: 1)
|
|
158
160
|
disks.stubs(:get).returns(disk)
|
|
159
161
|
config.stubs(:disks).returns(disks)
|
|
162
|
+
config.stubs(:efidisk).returns(nil)
|
|
160
163
|
config.stubs(:attributes).returns(:cores => '')
|
|
161
164
|
vm = mock('vm')
|
|
162
165
|
vm.stubs(:identity).returns(uuid)
|
|
@@ -264,6 +267,7 @@ module ForemanFogProxmox
|
|
|
264
267
|
disk.stubs(:attributes).returns(id: 'scsi0', storage: 'local-lvm', size: '1', volid: 'local-lvm:vm-100-disk-0')
|
|
265
268
|
disks.stubs(:get).returns(disk)
|
|
266
269
|
config.stubs(:disks).returns(disks)
|
|
270
|
+
config.stubs(:efidisk).returns(nil)
|
|
267
271
|
config.stubs(:attributes).returns(:cores => '')
|
|
268
272
|
vm = mock('vm')
|
|
269
273
|
vm.stubs(:identity).returns(uuid)
|
|
@@ -318,6 +322,7 @@ module ForemanFogProxmox
|
|
|
318
322
|
disk.stubs(:attributes).returns(id: 'scsi0', storage: 'local-lvm', volid: 'local-lvm:vm-100-disk-0', size: '1')
|
|
319
323
|
disks.stubs(:get).returns(disk)
|
|
320
324
|
config.stubs(:disks).returns(disks)
|
|
325
|
+
config.stubs(:efidisk).returns(nil)
|
|
321
326
|
config.stubs(:attributes).returns(:cores => '')
|
|
322
327
|
vm = mock('vm')
|
|
323
328
|
vm.stubs(:identity).returns(uuid)
|