foreman_fog_proxmox 0.5.4 → 0.5.5
Sign up to get free protection for your applications and to get access to all the features.
Potentially problematic release.
This version of foreman_fog_proxmox might be problematic. Click here for more details.
- checksums.yaml +4 -4
- data/README.md +10 -6
- data/app/assets/javascripts/foreman_fog_proxmox/proxmox_vm.js +10 -4
- data/app/assets/javascripts/foreman_fog_proxmox/proxmox_vm_server.js +60 -45
- data/app/helpers/proxmox_container_helper.rb +2 -1
- data/app/helpers/proxmox_form_helper.rb +19 -14
- data/app/helpers/proxmox_server_helper.rb +5 -5
- data/app/helpers/proxmox_vm_helper.rb +12 -0
- data/app/models/foreman_fog_proxmox/proxmox.rb +9 -3
- data/app/views/compute_resources_vms/form/proxmox/_add_vm_type_to_volumes_edit.html.erb +22 -35
- data/app/views/compute_resources_vms/form/proxmox/container/_volume_mp.html.erb +1 -0
- data/app/views/compute_resources_vms/form/proxmox/server/_config.html.erb +1 -0
- data/app/views/compute_resources_vms/form/proxmox/server/_volume.html.erb +1 -1
- data/lib/foreman_fog_proxmox/version.rb +1 -1
- data/test/unit/foreman_fog_proxmox/helpers/proxmox_server_helper_test.rb +12 -1
- metadata +6 -6
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: ca619ec359deaafb7ae8d9226bd0db7213a8f8276b27c24e39d3f4549744d759
|
4
|
+
data.tar.gz: 674603da5a60bf493462eaff2f9ac55637b908ee557cb2d026cdba006f17d1df
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: a5bc188c202ac4c0a067c001949ae64666c914000a2d2eff3bd49554f0be033bc5b5bcafddcfa9aeaebc9f282c7d0908237c3dfed801bbd8109fa7a5f79a757f
|
7
|
+
data.tar.gz: 044cc2a7d66fb8cddb3332d0fe98160e77a6bb0a71aec979334692197e4e406d2866bb84c8e1dde032797541c96f267a3126024e9520d28f87ceb0eb4f09a4a3
|
data/README.md
CHANGED
@@ -17,7 +17,7 @@ If you like it and need more features you can [support](SUPPORT.md) it.
|
|
17
17
|
Tested with:
|
18
18
|
|
19
19
|
* Foreman >= 1.17 and < 1.20
|
20
|
-
* Fog-proxmox >= 0.5.
|
20
|
+
* Fog-proxmox >= 0.5.3
|
21
21
|
* Proxmox >= 5.1
|
22
22
|
* Ruby >= 2.3
|
23
23
|
|
@@ -101,9 +101,9 @@ Please see the Foreman manual for complete instructions:
|
|
101
101
|
|
102
102
|
### Prerequisites
|
103
103
|
|
104
|
-
You need a Proxmox VE >= 5.1 server running.
|
105
|
-
|
106
|
-
You also need nodejs in your dev machine to run webpack-dev-server.
|
104
|
+
* You need a Proxmox VE >= 5.1 server running.
|
105
|
+
* You need ruby >= 2.3. You can install it with [rbenv](https://github.com/rbenv/rbenv).
|
106
|
+
* You also need nodejs in your dev machine to run webpack-dev-server. You can install it with [nvm](https://github.com/creationix/nvm).
|
107
107
|
|
108
108
|
### Platform
|
109
109
|
|
@@ -121,18 +121,22 @@ git checkout tags/1.17.3
|
|
121
121
|
|
122
122
|
```ruby
|
123
123
|
gem 'foreman_fog_proxmox', :path => '/your_path_to/foreman_fog_proxmox'
|
124
|
+
gem 'fog-proxmox', :path => '/your_path_to/fog-proxmox' # optional if you need to modify fog-proxmox code too
|
125
|
+
gem 'ruby-debug-ide' # dev
|
126
|
+
gem 'debase' # dev
|
127
|
+
gem 'simplecov' # test
|
124
128
|
```
|
125
129
|
|
126
130
|
* In foreman directory, install dependencies:
|
127
131
|
|
128
132
|
```shell
|
129
|
-
bundle install
|
133
|
+
bundle install --without libvirt postgresql mysql2
|
130
134
|
```
|
131
135
|
|
132
136
|
* Configure foreman settings:
|
133
137
|
|
134
138
|
```shell
|
135
|
-
cp config/settings.yaml.
|
139
|
+
cp config/settings.yaml.test config/settings.yaml
|
136
140
|
```
|
137
141
|
|
138
142
|
* Install foreman database (sqlite is default in rails development):
|
@@ -50,21 +50,26 @@ function toggleVolumes(selected){
|
|
50
50
|
div_server.show();
|
51
51
|
a_container.hide();
|
52
52
|
a_server.show();
|
53
|
-
|
53
|
+
break;
|
54
54
|
case 'lxc':
|
55
55
|
div_container.show();
|
56
56
|
div_server.hide();
|
57
57
|
a_container.show();
|
58
58
|
a_server.hide();
|
59
|
-
|
59
|
+
break;
|
60
|
+
default:
|
61
|
+
console.log("unkown type="+selected);
|
62
|
+
break;
|
60
63
|
}
|
61
64
|
}
|
62
65
|
|
63
66
|
function toggleFieldset(fieldset, index, fieldsets){
|
64
|
-
var server_input_hidden = $("div[id^='server_volumes']" + "
|
65
|
-
var container_input_hidden = $("div[id^='container_volumes']" + "
|
67
|
+
var server_input_hidden = $("div[id^='server_volumes']" + " + input:hidden");
|
68
|
+
var container_input_hidden = $("div[id^='container_volumes']" + " + input:hidden");
|
69
|
+
var removable_input_hidden = $("div.removable-item[style='display: none;']" + " + input:hidden");
|
66
70
|
var server_fieldset = $("fieldset[id^='server_"+fieldset.id+"']");
|
67
71
|
var container_fieldset = $("fieldset[id^='container_"+fieldset.id+"']");
|
72
|
+
removable_input_hidden.attr('disabled','disabled');
|
68
73
|
switch (fieldset.selected) {
|
69
74
|
case 'qemu':
|
70
75
|
if (fieldset.toggle && fieldset.new_vm){
|
@@ -87,6 +92,7 @@ function toggleFieldset(fieldset, index, fieldsets){
|
|
87
92
|
server_input_hidden.attr('disabled','disabled');
|
88
93
|
break;
|
89
94
|
default:
|
95
|
+
console.log("unkown type="+fieldset.selected);
|
90
96
|
break;
|
91
97
|
}
|
92
98
|
}
|
@@ -41,75 +41,90 @@ function cdromSelected(item) {
|
|
41
41
|
return false;
|
42
42
|
}
|
43
43
|
|
44
|
-
function initCdromStorage(){
|
44
|
+
function initCdromStorage() {
|
45
45
|
var select = '#host_compute_attributes_config_attributes_cdrom_storage';
|
46
|
-
$(select + ' option:selected').prop('selected',false);
|
46
|
+
$(select + ' option:selected').prop('selected', false);
|
47
47
|
$(select).val('');
|
48
48
|
}
|
49
49
|
|
50
|
-
function initCdromOptions(name){
|
51
|
-
var select = '#host_compute_attributes_config_attributes_cdrom_'+name;
|
50
|
+
function initCdromOptions(name) {
|
51
|
+
var select = '#host_compute_attributes_config_attributes_cdrom_' + name;
|
52
52
|
$(select).empty();
|
53
53
|
$(select).append($("<option></option>").val('').text(''));
|
54
54
|
$(select).val('');
|
55
55
|
}
|
56
56
|
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
}
|
57
|
+
function storageIsoSelected(item) {
|
58
|
+
var storage = $(item).val();
|
59
|
+
if (storage != '') {
|
60
|
+
tfm.tools.showSpinner();
|
61
|
+
$.getJSON({
|
62
|
+
type: 'get',
|
63
|
+
url: '/foreman_fog_proxmox/isos/' + storage,
|
64
|
+
complete: function () {
|
65
|
+
tfm.tools.hideSpinner();
|
66
|
+
},
|
67
|
+
error: function (j, status, error) {
|
68
|
+
console.log("Error=" + error + ", status=" + status + " loading isos for storage=" + storage);
|
69
|
+
},
|
70
|
+
success: function (isos) {
|
71
|
+
initCdromOptions('iso');
|
72
|
+
$.each(isos, function (i, iso) {
|
73
|
+
$('#host_compute_attributes_config_attributes_cdrom_iso').append($("<option></option>").val(iso.volid).text(iso.volid));
|
74
|
+
});
|
75
|
+
}
|
76
|
+
});
|
77
|
+
} else {
|
78
|
+
initCdromOptions('iso');
|
80
79
|
}
|
80
|
+
}
|
81
81
|
|
82
|
-
function controllerSelected(item){
|
82
|
+
function controllerSelected(item) {
|
83
83
|
var controller = $(item).val();
|
84
|
-
var
|
85
|
-
var pattern = /(\w+)(\d+)(\w+)/i;
|
86
|
-
var index = pattern.exec(id)[2];
|
84
|
+
var index = getIndex(item);
|
87
85
|
var max = computeControllerMaxDevice(controller);
|
88
|
-
|
86
|
+
var device_selector = '#host_compute_attributes_volumes_attributes_' + index + '_device';
|
87
|
+
$(device_selector).attr('data-soft-max', max);
|
88
|
+
var device = $(device_selector).limitedSpinner('value');
|
89
|
+
$('#host_compute_attributes_volumes_attributes_' + index + '_id').val(controller + device);
|
89
90
|
tfm.numFields.initAll();
|
90
91
|
}
|
91
92
|
|
92
|
-
function
|
93
|
+
function deviceSelected(item) {
|
94
|
+
var device = $(item).limitedSpinner('value');
|
95
|
+
console.log("device=" + device);
|
96
|
+
var index = getIndex(item);
|
97
|
+
var controller_selector = '#host_compute_attributes_volumes_attributes_' + index + '_controller';
|
98
|
+
var controller = $(controller_selector).val();
|
99
|
+
$('#host_compute_attributes_volumes_attributes_' + index + '_id').val(controller + device);
|
100
|
+
tfm.numFields.initAll();
|
101
|
+
}
|
102
|
+
|
103
|
+
function getIndex(item) {
|
104
|
+
var id = $(item).attr('id');
|
105
|
+
var pattern = /(host_compute_attributes_volumes_attributes_)(\d+)[_](.*)/i;
|
106
|
+
pattern_a = pattern.exec(id);
|
107
|
+
var index = pattern_a[2];
|
108
|
+
console.log("index=" + index);
|
109
|
+
return index;
|
110
|
+
}
|
111
|
+
|
112
|
+
function computeControllerMaxDevice(controller) {
|
93
113
|
switch (controller) {
|
94
114
|
case 'ide':
|
95
115
|
return 3;
|
96
|
-
break;
|
97
116
|
case 'sata':
|
98
117
|
return 5;
|
99
|
-
break;
|
100
118
|
case 'scsi':
|
101
119
|
return 13;
|
102
|
-
break;
|
103
120
|
case 'virtio':
|
104
121
|
return 15;
|
105
|
-
break;
|
106
122
|
default:
|
107
123
|
return 1;
|
108
|
-
break;
|
109
124
|
}
|
110
125
|
}
|
111
126
|
|
112
|
-
function balloonSelected(item){
|
127
|
+
function balloonSelected(item) {
|
113
128
|
var ballooned = $(item).is(':checked');
|
114
129
|
var memory_f = $("input[name$='[config_attributes][memory]']:hidden");
|
115
130
|
var min_memory_f = $("input[id$='config_attributes_min_memory']");
|
@@ -120,13 +135,13 @@ function balloonSelected(item){
|
|
120
135
|
min_memory_f.removeAttr('disabled');
|
121
136
|
shares_f.removeAttr('disabled');
|
122
137
|
var max = memory_f.val();
|
123
|
-
console.log("max="+max);
|
124
|
-
min_memory_f.attr('data-soft-max',max);
|
138
|
+
console.log("max=" + max);
|
139
|
+
min_memory_f.attr('data-soft-max', max);
|
125
140
|
} else {
|
126
|
-
min_memory_f.attr('disabled','disabled');
|
127
|
-
min_memory_hidden_f.attr('value','');
|
128
|
-
shares_f.attr('disabled','disabled');
|
129
|
-
shares_hidden_f.attr('value','');
|
141
|
+
min_memory_f.attr('disabled', 'disabled');
|
142
|
+
min_memory_hidden_f.attr('value', '');
|
143
|
+
shares_f.attr('disabled', 'disabled');
|
144
|
+
shares_hidden_f.attr('value', '');
|
130
145
|
}
|
131
146
|
tfm.numFields.initAll();
|
132
147
|
}
|
@@ -96,9 +96,10 @@ module ProxmoxContainerHelper
|
|
96
96
|
def parse_container_volume(args)
|
97
97
|
disk = {}
|
98
98
|
id = args['id']
|
99
|
-
id = "mp#{args['device']}"
|
99
|
+
id = "mp#{args['device']}" if args.has_key?('device') && !id
|
100
100
|
delete = args['_delete'].to_i == 1
|
101
101
|
logger.debug("parse_container_volume() args=#{args}")
|
102
|
+
return args if ForemanFogProxmox::Value.empty?(id) || server_disk?(id)
|
102
103
|
args.delete_if { |_key,value| ForemanFogProxmox::Value.empty?(value) }
|
103
104
|
if delete
|
104
105
|
logger.debug("parse_container_volume(): delete id=#{id}")
|
@@ -46,22 +46,27 @@ end
|
|
46
46
|
pass = obj.attributes.has_key?(attr)
|
47
47
|
pass ? "********" : ''
|
48
48
|
end
|
49
|
+
|
50
|
+
def new_child_fields_template_typed(form_builder, association, options = { })
|
51
|
+
unless options[:object].present?
|
52
|
+
association_object = form_builder.object.class.reflect_on_association(association)
|
53
|
+
options[:object] = association_object.klass.new(association_object.foreign_key => form_builder.object.id)
|
54
|
+
end
|
55
|
+
options[:partial] ||= association.to_s.singularize
|
56
|
+
options[:form_builder_local] ||= :f
|
57
|
+
options[:form_builder_attrs] ||= {}
|
49
58
|
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
end
|
55
|
-
options[:partial] ||= association.to_s.singularize
|
56
|
-
options[:form_builder_local] ||= :f
|
57
|
-
options[:form_builder_attrs] ||= {}
|
58
|
-
|
59
|
-
content_tag(:div, :id => "#{options[:type]}_#{association}", :style => 'display: none') do
|
60
|
-
form_builder.fields_for(association, options[:object], :child_index => "0") do |f|
|
61
|
-
render(:partial => options[:partial], :layout => options[:layout],
|
62
|
-
:locals => { options[:form_builder_local] => f }.merge(options[:form_builder_attrs]))
|
63
|
-
end
|
59
|
+
content_tag(:div, :class => "#{options[:type]}_#{association}_fields_template form_template #{}", :style => "display: none;") do
|
60
|
+
form_builder.fields_for(association, options[:object], :child_index => "new_#{options[:type]}_#{association}") do |f|
|
61
|
+
render(:partial => options[:partial], :layout => options[:layout],
|
62
|
+
:locals => { options[:form_builder_local] => f }.merge(options[:form_builder_attrs]))
|
64
63
|
end
|
65
64
|
end
|
65
|
+
end
|
66
66
|
|
67
|
+
def add_child_link_typed(name, association, type, opts = {})
|
68
|
+
opts[:class] = [opts[:class], "add_nested_fields btn btn-primary"].compact.join(" ")
|
69
|
+
opts[:"data-association"] = (type + '_' + association.to_s).to_sym
|
70
|
+
link_to_function(name.to_s, "add_child_node(this);tfm.numFields.initAll();", opts)
|
71
|
+
end
|
67
72
|
end
|
@@ -103,8 +103,8 @@ module ProxmoxServerHelper
|
|
103
103
|
def parse_server_volume(args)
|
104
104
|
disk = {}
|
105
105
|
id = args['id']
|
106
|
-
id = "#{args['controller']}#{args['device']}"
|
107
|
-
return args if ForemanFogProxmox::Value.empty?(id)
|
106
|
+
id = "#{args['controller']}#{args['device']}" if args.has_key?('controller') && args.has_key?('device') && !id
|
107
|
+
return args if ForemanFogProxmox::Value.empty?(id) || id == 'rootfs'
|
108
108
|
delete = args['_delete'].to_i == 1
|
109
109
|
args.delete_if { |_key,value| ForemanFogProxmox::Value.empty?(value) }
|
110
110
|
if delete
|
@@ -113,9 +113,9 @@ module ProxmoxServerHelper
|
|
113
113
|
disk
|
114
114
|
else
|
115
115
|
disk.store(:id, id)
|
116
|
-
disk.store(:volid, args['volid'])
|
117
|
-
disk.store(:storage, args['storage'].to_s)
|
118
|
-
disk.store(:size, args['size'].to_i)
|
116
|
+
disk.store(:volid, args['volid']) if args.has_key?('volid')
|
117
|
+
disk.store(:storage, args['storage'].to_s) if args.has_key?('storage')
|
118
|
+
disk.store(:size, args['size'].to_i) if args.has_key?('size')
|
119
119
|
options = args.reject { |key,_value| %w[id volid controller device storage size _delete].include? key}
|
120
120
|
disk.store(:options, options)
|
121
121
|
logger.debug("parse_server_volume(): add disk=#{disk}")
|
@@ -70,6 +70,10 @@ module ProxmoxVmHelper
|
|
70
70
|
args['volumes_attributes'].each_value { |value| value['size'] = (value['size'].to_i / GIGA).to_s unless ForemanFogProxmox::Value.empty?(value['size']) }
|
71
71
|
end
|
72
72
|
|
73
|
+
def remove_deletes(args)
|
74
|
+
args['volumes_attributes'].delete_if { |_key,value| value.has_key? '_delete' }
|
75
|
+
end
|
76
|
+
|
73
77
|
def convert_memory_size(config_hash, key)
|
74
78
|
config_hash.store(key, (config_hash[key].to_i / MEGA).to_s) unless ForemanFogProxmox::Value.empty?(config_hash[key])
|
75
79
|
end
|
@@ -83,4 +87,12 @@ module ProxmoxVmHelper
|
|
83
87
|
return type, vmid
|
84
88
|
end
|
85
89
|
|
90
|
+
def mount_point_disk?(id)
|
91
|
+
/^(mp)(\d+)$/.match?(id)
|
92
|
+
end
|
93
|
+
|
94
|
+
def server_disk?(id)
|
95
|
+
/^(scsi|sata|virtio|ide)(\d+)$/.match?(id)
|
96
|
+
end
|
97
|
+
|
86
98
|
end
|
@@ -120,8 +120,13 @@ module ForemanFogProxmox
|
|
120
120
|
|
121
121
|
def host_interfaces_attrs(host)
|
122
122
|
host.interfaces.select(&:physical?).each.with_index.reduce({}) do |hash, (nic, index)|
|
123
|
-
|
123
|
+
# Set default interface identifier to net[n]
|
124
|
+
nic.identifier = "net%{index}" % {index: index} if nic.identifier.empty?
|
124
125
|
raise ::Foreman::Exception.new _("Invalid identifier interface[%{index}]. Must be net[n] with n integer >= 0" % { index: index }) unless Fog::Proxmox::NicHelper.valid?(nic.identifier)
|
126
|
+
# Set default container interface name to eth[n]
|
127
|
+
container = host.compute_attributes['type'] == 'lxc'
|
128
|
+
nic.compute_attributes['name'] = "eth%{index}" % {index: index} if container && nic.compute_attributes['name'].empty?
|
129
|
+
raise ::Foreman::Exception.new _("Invalid name interface[%{index}]. Must be eth[n] with n integer >= 0" % { index: index }) if container && !/^(eth)(\d+)$/.match?(nic.compute_attributes['name'])
|
125
130
|
nic_compute_attributes = nic.compute_attributes.merge(id: nic.identifier)
|
126
131
|
nic_compute_attributes.store(:ip, nic.ip) if (nic.ip && !nic.ip.empty?)
|
127
132
|
nic_compute_attributes.store(:ip6, nic.ip6) if (nic.ip6 && !nic.ip6.empty?)
|
@@ -232,6 +237,7 @@ module ForemanFogProxmox
|
|
232
237
|
else
|
233
238
|
logger.debug(_("create_vm(): %{args}") % { args: args })
|
234
239
|
convert_sizes(args)
|
240
|
+
remove_deletes(args)
|
235
241
|
case type
|
236
242
|
when 'qemu'
|
237
243
|
node.servers.create(parse_server_vm(args))
|
@@ -422,7 +428,7 @@ module ForemanFogProxmox
|
|
422
428
|
cpu: 'kvm64',
|
423
429
|
scsihw: 'virtio-scsi-pci',
|
424
430
|
ide2: "none,media=cdrom",
|
425
|
-
templated: 0).merge(Fog::Proxmox::DiskHelper.flatten(volume_server_defaults)).merge(Fog::Proxmox::NicHelper.flatten(interface_server_defaults))
|
431
|
+
templated: 0).merge(Fog::Proxmox::DiskHelper.flatten(volume_server_defaults)).merge(Fog::Proxmox::DiskHelper.flatten(volume_container_defaults)).merge(Fog::Proxmox::NicHelper.flatten(interface_server_defaults))
|
426
432
|
end
|
427
433
|
|
428
434
|
def vm_container_instance_defaults
|
@@ -432,7 +438,7 @@ module ForemanFogProxmox
|
|
432
438
|
type: 'lxc',
|
433
439
|
node: node.to_s,
|
434
440
|
memory: 512 * MEGA,
|
435
|
-
templated: 0).merge(Fog::Proxmox::DiskHelper.flatten(volume_container_defaults)).merge(Fog::Proxmox::NicHelper.container_flatten(interface_container_defaults))
|
441
|
+
templated: 0).merge(Fog::Proxmox::DiskHelper.flatten(volume_server_defaults)).merge(Fog::Proxmox::DiskHelper.flatten(volume_container_defaults)).merge(Fog::Proxmox::NicHelper.container_flatten(interface_container_defaults))
|
436
442
|
end
|
437
443
|
|
438
444
|
def vm_instance_defaults
|
@@ -20,53 +20,40 @@ along with ForemanFogProxmox. If not, see <http://www.gnu.org/licenses/>. %>
|
|
20
20
|
<% server = type == 'qemu' %>
|
21
21
|
<% container = type == 'lxc' %>
|
22
22
|
|
23
|
-
<%=
|
23
|
+
<%= new_child_fields_template_typed(f, :volumes, {
|
24
|
+
:type => 'server',
|
24
25
|
:object => compute_resource.new_volume_server,
|
25
26
|
:partial => provider_partial(compute_resource, 'server/volume'),
|
26
27
|
:form_builder_attrs => { :type => type, :compute_resource => compute_resource, :new_host => new_vm, :new_vm => new_vm, :remove_title => _('remove storage volume') },
|
27
28
|
:layout => "compute_resources_vms/form/#{item_layout}_layout" }) %>
|
28
|
-
<%=
|
29
|
+
<%= new_child_fields_template_typed(f, :volumes, {
|
30
|
+
:type => 'container',
|
29
31
|
:object => compute_resource.new_volume_container(id: 'mp0'),
|
30
32
|
:partial => provider_partial(compute_resource, 'container/volume_mp'),
|
31
33
|
:form_builder_attrs => { :type => type, :compute_resource => compute_resource, :new_host => new_vm, :new_vm => new_vm, :remove_title => _('remove storage volume') },
|
32
34
|
:layout => "compute_resources_vms/form/#{item_layout}_layout" }) %>
|
33
35
|
|
34
36
|
|
35
|
-
|
36
|
-
<div id="server_volumes">
|
37
|
-
<%= f.fields_for :volumes do |i| %>
|
38
|
-
<%= render :partial => provider_partial(compute_resource, 'server/volume'), :locals => { :f => i, :type => type, :compute_resource => compute_resource, :new_host => new_vm, :new_vm => new_vm, :remove_title => _('remove storage volume') }, :layout => "compute_resources_vms/form/#{item_layout}_layout" %>
|
39
|
-
<% end %>
|
40
|
-
</div>
|
41
|
-
<%= second_child_fields_template(f, :volumes, {
|
42
|
-
:object => compute_resource.new_volume_container(id: 'rootfs'),
|
43
|
-
:partial => provider_partial(compute_resource, 'container/volume_rootfs'),
|
44
|
-
:type => 'container',
|
45
|
-
:form_builder_attrs => { :type => type, :compute_resource => compute_resource, :new_host => new_vm, :new_vm => new_vm, :remove_title => _('remove storage volume') },
|
46
|
-
:layout => "compute_resources_vms/form/#{item_layout}_layout" }) %>
|
47
|
-
<% end %>
|
48
|
-
<% if container %>
|
49
|
-
<div id="container_volumes">
|
37
|
+
|
50
38
|
<%= f.fields_for :volumes do |i| %>
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
<% end %>
|
65
|
-
|
66
|
-
<%= add_child_link '+ ' + _("Add Volume"), :server_volumes, { :class => "info", :style => ("display: none;" unless server), :title => _('add new storage volume') } %>
|
67
|
-
<% end %>
|
39
|
+
<% if i.object.id == 'rootfs' %>
|
40
|
+
<div id="container_volumes_rootfs" style="<%= 'display: ' + (container ? 'block' : 'none') + ';' %>">
|
41
|
+
<%= render :partial => provider_partial(compute_resource, 'container/volume_rootfs'), :locals => { :f => i, :type => type, :compute_resource => compute_resource, :new_host => new_vm, :new_vm => new_vm, :remove_title => _('remove storage volume'), :disabled => !container }, :layout => "compute_resources_vms/form/#{item_layout}_layout" %>
|
42
|
+
</div>
|
43
|
+
<% elsif mount_point_disk?(i.object.id) %>
|
44
|
+
<div id="container_volumes_mp" style="<%= 'display: ' + (container ? 'block' : 'none') + ';' %>">
|
45
|
+
<%= render :partial => provider_partial(compute_resource, 'container/volume_mp'), :locals => { :f => i, :type => type, :compute_resource => compute_resource, :new_host => new_vm, :new_vm => new_vm, :remove_title => _('remove storage volume'), :disabled => !container }, :layout => "compute_resources_vms/form/#{item_layout}_layout" %>
|
46
|
+
</div>
|
47
|
+
<% elsif server_disk?(i.object.id) %>
|
48
|
+
<div id="server_volumes" style="<%= 'display: ' + (server ? 'block' : 'none') + ';' %>">
|
49
|
+
<%= render :partial => provider_partial(compute_resource, 'server/volume'), :locals => { :f => i, :type => type, :compute_resource => compute_resource, :new_host => new_vm, :new_vm => new_vm, :remove_title => _('remove storage volume'), :disabled => !server }, :layout => "compute_resources_vms/form/#{item_layout}_layout" %>
|
50
|
+
</div>
|
51
|
+
<% end %>
|
52
|
+
<% end %>
|
53
|
+
|
68
54
|
<% if new_vm %>
|
69
|
-
<%=
|
55
|
+
<%= add_child_link_typed '+ ' + _("Add Volume"), :volumes, 'server', { :class => "info #{'hide' unless server}", :title => _('add new storage volume') } %>
|
56
|
+
<%= add_child_link_typed '+ ' + _("Add Volume"), :volumes, 'container', { :class => "info #{'hide' unless container}", :title => _('add new storage volume') } %>
|
70
57
|
<% end %>
|
71
58
|
|
72
59
|
|
@@ -20,6 +20,7 @@ along with ForemanFogProxmox. If not, see <http://www.gnu.org/licenses/>. %>
|
|
20
20
|
<%= field_set_tag _("Mount point"), :id => "container_volume_#{f.index}", :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, :storage, :storage, { }, :label => _('Storage'), :label_size => "col-md-2", :disabled => !new_vm %>
|
23
|
+
<%= text_f f, :mp, :label => _('Mount point'), :label_size => "col-md-2", :disabled => !new_vm, :required => true %>
|
23
24
|
<%= counter_f f, :device, :label => _('Device'), :label_size => "col-md-2", :class => ('hide' if f.object.rootfs?), :disabled => (!new_vm || f.object.rootfs?), :'data-soft-max' => 10 %>
|
24
25
|
<%= byte_size_f f, :size, :class => "input-mini", :label => _("Size"), :label_size => "col-md-2", :disabled => !new_vm %>
|
25
26
|
<% end %>
|
@@ -16,6 +16,7 @@ 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_server', "data-turbolinks-track" => true %>
|
19
|
+
|
19
20
|
<% server = type == 'qemu' %>
|
20
21
|
|
21
22
|
<%= field_set_tag n_("Main option", "Main options", 2), :id => "server_config_options", :class => 'hide', :disabled => !server do %>
|
@@ -21,7 +21,7 @@ along with ForemanFogProxmox. If not, see <http://www.gnu.org/licenses/>. %>
|
|
21
21
|
<%= f.hidden_field :volid if !new_vm %>
|
22
22
|
<%= select_f f, :storage, compute_resource.storages, :storage, :storage, { }, :label => _('Storage'), :label_size => "col-md-2", :disabled => !new_vm %>
|
23
23
|
<%= select_f f, :controller, proxmox_controllers_map, :id, :name, { }, :label => _('Controller'), :label_size => "col-md-2", :disabled => !new_vm, :onchange => 'controllerSelected(this)' %>
|
24
|
-
<%= counter_f f, :device, :label => _('Device'), :label_size => "col-md-2", :disabled => !new_vm, :'data-soft-max' => proxmox_max_device(f.object.controller) %>
|
24
|
+
<%= counter_f f, :device, :label => _('Device'), :label_size => "col-md-2", :disabled => !new_vm, :'data-soft-max' => proxmox_max_device(f.object.controller), :onchange => 'deviceSelected(this)' %>
|
25
25
|
<%= select_f f, :cache, proxmox_caches_map, :id, :name, { }, :label => _('Cache'), :label_size => "col-md-2" %>
|
26
26
|
<%= byte_size_f f, :size, :class => "input-mini", :label => _("Size"), :label_size => "col-md-2", :disabled => !new_vm %>
|
27
27
|
<% end %>
|
@@ -45,7 +45,8 @@ class ProxmoxServerHelperTest < ActiveSupport::TestCase
|
|
45
45
|
'sockets' => '1'
|
46
46
|
},
|
47
47
|
'volumes_attributes' => {
|
48
|
-
'0'=> { 'controller' => 'scsi', 'device' => '0', 'storage' => 'local-lvm', 'size' => '1073741824', 'cache' => 'none' }
|
48
|
+
'0'=> { 'controller' => 'scsi', 'device' => '0', 'storage' => 'local-lvm', 'size' => '1073741824', 'cache' => 'none' },
|
49
|
+
'1'=> { 'controller' => 'virtio', 'device' => '0', 'storage' => 'local-lvm', 'size' => '1073741824', 'cache' => 'none' }
|
49
50
|
},
|
50
51
|
'interfaces_attributes' => {
|
51
52
|
'0' => { 'id' => 'net0', 'model' => 'virtio', 'bridge' => 'vmbr0', 'firewall' => '0', 'link_down' => '0', 'rate' => nil },
|
@@ -92,10 +93,20 @@ class ProxmoxServerHelperTest < ActiveSupport::TestCase
|
|
92
93
|
test '#volume with scsi 1Gb' do
|
93
94
|
volumes = parse_server_volumes(host['volumes_attributes'])
|
94
95
|
assert !volumes.empty?
|
96
|
+
assert volumes.size, 2
|
95
97
|
assert volume = volumes.first
|
96
98
|
assert volume.has_key?(:scsi0)
|
97
99
|
assert_equal 'local-lvm:1073741824,cache=none', volume[:scsi0]
|
98
100
|
end
|
101
|
+
|
102
|
+
test '#volume with virtio 1Gb' do
|
103
|
+
volumes = parse_server_volumes(host['volumes_attributes'])
|
104
|
+
assert !volumes.empty?
|
105
|
+
assert volumes.size, 2
|
106
|
+
assert volume = volumes[1]
|
107
|
+
assert volume.has_key?(:virtio0)
|
108
|
+
assert_equal 'local-lvm:1073741824,cache=none', volume[:virtio0]
|
109
|
+
end
|
99
110
|
|
100
111
|
test '#volume delete scsi0' do
|
101
112
|
volumes = parse_server_volumes(host_delete['volumes_attributes'])
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: foreman_fog_proxmox
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.5.
|
4
|
+
version: 0.5.5
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Tristan Robert
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2018-11-
|
11
|
+
date: 2018-11-27 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: fog-proxmox
|
@@ -189,11 +189,11 @@ signing_key:
|
|
189
189
|
specification_version: 4
|
190
190
|
summary: Foreman plugin that adds Proxmox VE compute resource using fog-proxmox
|
191
191
|
test_files:
|
192
|
-
- test/functional/compute_resources_controller_test.rb
|
193
|
-
- test/factories/proxmox_factory.rb
|
194
192
|
- test/unit/foreman_fog_proxmox/proxmox_test_helpers.rb
|
195
|
-
- test/unit/foreman_fog_proxmox/
|
193
|
+
- test/unit/foreman_fog_proxmox/helpers/proxmox_vm_helper_test.rb
|
196
194
|
- test/unit/foreman_fog_proxmox/helpers/proxmox_container_helper_test.rb
|
197
195
|
- test/unit/foreman_fog_proxmox/helpers/proxmox_server_helper_test.rb
|
198
|
-
- test/unit/foreman_fog_proxmox/
|
196
|
+
- test/unit/foreman_fog_proxmox/proxmox_test.rb
|
197
|
+
- test/factories/proxmox_factory.rb
|
198
|
+
- test/functional/compute_resources_controller_test.rb
|
199
199
|
- test/test_plugin_helper.rb
|