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