foreman_fog_proxmox 0.13.0 → 0.13.4

Sign up to get free protection for your applications and to get access to all the features.
Files changed (40) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +42 -9
  3. data/app/assets/javascripts/foreman_fog_proxmox/proxmox_compute_resource.js +25 -13
  4. data/app/assets/javascripts/foreman_fog_proxmox/proxmox_vm.js +62 -60
  5. data/app/assets/javascripts/foreman_fog_proxmox/proxmox_vm_server.js +2 -2
  6. data/app/assets/javascripts/foreman_fog_proxmox/proxmox_volume.js +10 -10
  7. data/app/controllers/concerns/foreman_fog_proxmox/compute_resources_vms_controller.rb +80 -0
  8. data/app/controllers/foreman_fog_proxmox/compute_resources_controller.rb +23 -25
  9. data/app/helpers/proxmox_compute_resources_vms_helper.rb +99 -0
  10. data/app/helpers/proxmox_vm_config_helper.rb +5 -4
  11. data/app/helpers/proxmox_vm_uuid_helper.rb +34 -0
  12. data/app/models/concerns/fog_extensions/proxmox/server.rb +4 -0
  13. data/app/models/concerns/host_ext/proxmox/associator.rb +46 -0
  14. data/app/models/concerns/host_ext/proxmox/for_vm.rb +33 -0
  15. data/app/models/concerns/orchestration/proxmox/compute.rb +65 -7
  16. data/app/models/foreman_fog_proxmox/proxmox.rb +4 -0
  17. data/app/models/foreman_fog_proxmox/proxmox_compute_attributes.rb +3 -6
  18. data/app/models/foreman_fog_proxmox/proxmox_images.rb +13 -4
  19. data/app/models/foreman_fog_proxmox/proxmox_interfaces.rb +2 -1
  20. data/app/models/foreman_fog_proxmox/proxmox_vm_commands.rb +5 -3
  21. data/app/models/foreman_fog_proxmox/proxmox_vm_new.rb +2 -4
  22. data/app/models/foreman_fog_proxmox/proxmox_vm_queries.rb +14 -7
  23. data/app/models/foreman_fog_proxmox/vms.rb +1 -1
  24. data/app/services/concerns/foreman_fog_proxmox/compute_resource_host_associator.rb +34 -0
  25. data/app/services/foreman_fog_proxmox/node_dashboard/data.rb +6 -2
  26. data/app/views/api/v2/compute_resources/proxmox.json.rabl +1 -1
  27. data/app/views/compute_resources_vms/form/proxmox/server/_volume_cdrom.html.erb +1 -1
  28. data/app/views/compute_resources_vms/index/_proxmox.html.erb +2 -2
  29. data/config/routes.rb +7 -7
  30. data/db/migrate/20210312105013_update_proxmox_uuid_host.rb +29 -0
  31. data/lib/foreman_fog_proxmox/engine.rb +13 -2
  32. data/lib/foreman_fog_proxmox/version.rb +1 -1
  33. data/test/functional/compute_resources_controller_test.rb +4 -4
  34. data/test/unit/foreman_fog_proxmox/helpers/proxmox_container_helper_test.rb +4 -3
  35. data/test/unit/foreman_fog_proxmox/helpers/proxmox_server_helper_test.rb +3 -1
  36. data/test/unit/foreman_fog_proxmox/helpers/proxmox_vm_uuid_helper_test.rb +38 -0
  37. data/test/unit/foreman_fog_proxmox/proxmox_images_test.rb +3 -3
  38. data/test/unit/foreman_fog_proxmox/proxmox_interfaces_test.rb +2 -2
  39. data/test/unit/foreman_fog_proxmox/proxmox_vm_queries_test.rb +3 -3
  40. metadata +12 -3
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 6101f16731ab275d2adfb1b0abc8fd25690688e34569b7f63c360fb6442da5ec
4
- data.tar.gz: 62bfd05f02a526de1a4decc27d5a8c6ee5539b58316fb0bc29338dc26f4c0a04
3
+ metadata.gz: e42832dc77d338bb20585f27678bc2207c23a610f7c7b478f24f3791ca65a414
4
+ data.tar.gz: 1385bea7eed802496ae7ab85ca013e75dc0343a8a433a347d8811b59fd620cd0
5
5
  SHA512:
6
- metadata.gz: d46aa0181a540105670a8b4cc988f791cde9ac05d8323c2eec250d53ee44c1b1eaea581619276f21cc7a433931470007019e2e3028ece8f750b4fcef704398ac
7
- data.tar.gz: ce879270338d08b684991184079b8106519de9394c4e85b8cfcc74e5e30620a75d217eefa8ce8301711b30fbcd20ef051925a3190ae5b8b34e4c4157a1a3895c
6
+ metadata.gz: 91a262ffeb2b720fae01136cdcd158cd8c577702fafbea36d550eae859c6734f7a7ec1c390b39077852100d4507d9b3502bb7f3f1cb5c7d22c02cd7b012c51cf
7
+ data.tar.gz: 25512a916934966d9b5e66494f1b294c5b13d69ba326ed61170e330bff616111103984701a6311b150fb444dab3f0a48920c8debe193b7698a2ec43a0110cdd1
data/README.md CHANGED
@@ -32,7 +32,9 @@ You can support the plugin development via the following methods:
32
32
  |>=0.10 |>=5.4|>=0.9.4|>=1.22|>=2.5|
33
33
  |>=0.11 |>=5.4|>=0.10|>=1.22|>=2.5|
34
34
  |>=0.12 |>=6.1|>=0.11|>=2.0|>=2.5|
35
- |>=0.14 |>=6.2|>=0.13|>=2.0|>=2.5|
35
+ |>=0.14 |>=6.2|=0.13.0|>=2.4|>=2.7|
36
+ |>=0.14 |>=6.2|>=0.13.1|>=2.3|>=2.5|
37
+ |>=0.14 |>=6.2|>=0.14.0|>=2.5|>=2.5|
36
38
 
37
39
  ## Installation
38
40
 
@@ -46,10 +48,10 @@ See complete details in [plugin installation from gem](https://theforeman.org/pl
46
48
 
47
49
  Here is a Debian sample:
48
50
 
49
- * Install foreman [from OS packages](https://theforeman.org/manuals/1.19/index.html#3.3InstallFromPackages):
51
+ * Install foreman [from OS packages](https://theforeman.org/manuals/latest/index.html#3.3InstallFromPackages):
50
52
 
51
53
  ```shell
52
- sudo apt install -y foreman foreman-compute foreman-sqlite3 foreman-assets
54
+ sudo apt install -y foreman foreman-pgsql
53
55
  ```
54
56
 
55
57
  * Use only foreman user (**not root!**) `sudo -u foreman ...`
@@ -101,7 +103,21 @@ Then you can check plugin installation after login into your new foreman server
101
103
 
102
104
  Please see the Foreman manual for complete instructions:
103
105
 
104
- * [Foreman: How to Install a Plugin](http://theforeman.org/manuals/latest/index.html#6.1InstallaPlugin)
106
+ * [Foreman: How to Install a Plugin from package](https://theforeman.org/plugins/#2.Installation)
107
+
108
+ [Install from package](https://theforeman.org/plugins/#2.2Packageinstallation) is the easiest way to install the plugin. Choose the latest release plugins repository. If you don't find it in the same foreman release repository, get it from the `nightly` repository.
109
+
110
+ Then you can install it with the package manager, in Debian/Ubuntu:
111
+
112
+ ```shell
113
+ sudo apt-get install ruby-foreman-fog-proxmox
114
+ ```
115
+
116
+ and in Fedora/Redhat Linux:
117
+
118
+ ```shell
119
+ sudo dnf install rubygem-foreman_fog_proxmox
120
+ ```
105
121
 
106
122
  Redhat, CentOS or Fedora users should also [setup Selinux](https://projects.theforeman.org/projects/foreman/wiki/SELinux) to allow foreman and all its plugins to work.
107
123
 
@@ -112,7 +128,7 @@ Redhat, CentOS or Fedora users should also [setup Selinux](https://projects.thef
112
128
 
113
129
  ## Development
114
130
 
115
- ### Prerequisites
131
+ ### Dev prerequisites
116
132
 
117
133
  * You need a Proxmox VE 5.4+ server running.
118
134
  * You need ruby >= 2.5. You can install it with [asdf-vm](https://asdf-vm.com).
@@ -136,6 +152,7 @@ gem 'foreman_fog_proxmox', :path => '../../theforeman/foreman_fog_proxmox'
136
152
  gem 'fog-proxmox', :path => '../../fog/fog-proxmox' # optional if you need to modify fog-proxmox code too
137
153
  gem 'ruby-debug-ide' # dev
138
154
  gem 'debase' # dev
155
+ gem 'solargraph' # dev
139
156
  gem 'simplecov' # test
140
157
  ```
141
158
 
@@ -143,8 +160,9 @@ gem 'simplecov' # test
143
160
 
144
161
  ```shell
145
162
  gem install bundler
146
- # prerequisites postgresql-client library on OS
163
+ # prerequisites postgresql-XX-client library on OS (XX=major release installed in OS)
147
164
  bundle config set without 'libvirt ovirt mysql2'
165
+ bundle config build.pg --with-pg-config=/usr/pgsql-XX/bin/pg_config
148
166
  bundle install
149
167
  ```
150
168
 
@@ -177,7 +195,7 @@ cp config/model.mappings.example config/model.mappings
177
195
  cp config/database.yml.example config/database.yml
178
196
  ```
179
197
 
180
- add these lines to config/database.yml:
198
+ add these lines to each environment in config/database.yml:
181
199
 
182
200
  ```yaml
183
201
  username: foreman
@@ -186,8 +204,9 @@ add these lines to config/database.yml:
186
204
 
187
205
  ```shell
188
206
  cp config/ignored_environments.yml.sample config/ignored_environments.yml
189
- docker run --name foreman-db -e POSTGRES_DB=foreman -e POSTGRES_USER=foreman -e POSTGRES_PASSWORD=foreman -p 5432:5432 -d postgres
207
+ docker run --name foreman-db -v foreman_data:/var/lib/postgresql/data -e POSTGRES_DB=foreman -e POSTGRES_USER=foreman -e POSTGRES_PASSWORD=foreman -p 5432:5432 -d postgres
190
208
  bundle exec bin/rake db:migrate
209
+ # reboot if settings.NAME error in schema
191
210
  bundle exec bin/rake db:seed assets:precompile locale:pack webpack:compile
192
211
  ```
193
212
 
@@ -206,7 +225,15 @@ docker exec -it foreman-db psql -U foreman
206
225
  foreman=# create database "foreman-test";
207
226
  ```
208
227
 
209
- all:
228
+ then add test schema and seeds:
229
+
230
+ ```shell
231
+ RAILS_ENV=test bundle exec bin/rake db:migrate
232
+ # reboot if error: "ActiveRecord::RecordNotFound: Couldn't find Setting with [WHERE "settings"."name" = $1]"
233
+ RAILS_ENV=test bundle exec bin/rake db:seed
234
+ ```
235
+
236
+ Finally you can test all:
210
237
 
211
238
  ```shell
212
239
  export DISABLE_SPRING=true
@@ -274,6 +301,12 @@ bundle exec bin/rails server
274
301
  bundle exec foreman start
275
302
  ```
276
303
 
304
+ If you want to delete vm on host destroy, add this line in config/settings.yml:
305
+
306
+ ```yml
307
+ :destroy_vm_on_host_delete: false
308
+ ```
309
+
277
310
  See details in [foreman plugin development](https://projects.theforeman.org/projects/foreman/wiki/How_to_Create_a_Plugin)
278
311
 
279
312
  ## Contributing
@@ -36,20 +36,32 @@ function sslVerifyPeerSelected() {
36
36
  }
37
37
  }
38
38
 
39
+ function enableField(item) {
40
+ $(item).show();
41
+ $(item).removeAttr('disabled');
42
+ }
43
+
44
+ function disableField(item) {
45
+ $(item).hide();
46
+ $(item).attr('disabled','disabled');
47
+ }
48
+
49
+ function toggleFieldset(method, selected){
50
+ return method === selected ? enableField(authMethodFieldsetId(method)) : disableField(authMethodFieldsetId(method));
51
+ }
52
+
53
+ function authMethods(){
54
+ return ['user_token', 'access_ticket'];
55
+ }
56
+
57
+ function authMethodFieldsetId(method){
58
+ return '#compute_ressource_' + method + '_field_set';
59
+ }
60
+
39
61
  function authMethodSelected() {
40
62
  var selected = $("#compute_resource_auth_method").val();
41
63
  console.log("auth_method="+selected);
42
- var compute_ressource_user_token_field_set = $('#compute_ressource_user_token_field_set');
43
- var compute_ressource_access_ticket_field_set = $('#compute_ressource_access_ticket_field_set');
44
- if (selected == 'user_token') {
45
- compute_ressource_user_token_field_set.show();
46
- compute_ressource_user_token_field_set.removeAttr('disabled');
47
- compute_ressource_access_ticket_field_set.hide();
48
- compute_ressource_access_ticket_field_set.attr('disabled','disabled');
49
- } else {
50
- compute_ressource_access_ticket_field_set.show();
51
- compute_ressource_access_ticket_field_set.removeAttr('disabled');
52
- compute_ressource_user_token_field_set.hide();
53
- compute_ressource_user_token_field_set.attr('disabled','disabled');
54
- }
64
+ authMethods().forEach(function(method){
65
+ toggleFieldset(method, selected);
66
+ });
55
67
  }
@@ -39,17 +39,17 @@ function vmTypeSelected() {
39
39
  return false;
40
40
  }
41
41
 
42
- function volumeButtonAddId(id){
43
- return $("a[data-association='" + id + "_volumes']");
42
+ function volumeButtonAddId(item){
43
+ return $("a[data-association='" + item + "_volumes']");
44
44
  }
45
45
 
46
- function volumeFieldsetId(id, type){
47
- return $("fieldset[id^='" + type + "_volume_"+ id +"']").not("fieldset[id$='_new_" + id +"_volumes']");
46
+ function volumeFieldsetId(item, type){
47
+ return $("fieldset[id^='" + type + "_volume_"+ item +"']").not("fieldset[id$='_new_" + item +"_volumes']");
48
48
  }
49
49
 
50
- function indexByIdAndType(id, storage_type, vm_type){
51
- let regex = new RegExp(`${vm_type}_volume_${storage_type}_(\\d+)`);
52
- return id.match(regex)[1];
50
+ function indexByIdAndType(item, storage_type, vm_type){
51
+ var regex = new RegExp(vm_type +"_volume_" + storage_type +"_(\\d+)");
52
+ return item.match(regex)[1];
53
53
  }
54
54
 
55
55
  function volidByIndexAndTag(index, tag){
@@ -58,10 +58,10 @@ function volidByIndexAndTag(index, tag){
58
58
 
59
59
  function hasCloudinit(){
60
60
  result = false;
61
- let id = volumeFieldsetId('cloud_init', 'server').attr('id');
62
- if (id !== undefined){
63
- let index = indexByIdAndType(id, 'cloud_init', 'server');
64
- let volid = volidByIndexAndTag(index, 'input');
61
+ var volume_id = volumeFieldsetId('cloud_init', 'server').attr('id');
62
+ if (volume_id !== undefined){
63
+ var index = indexByIdAndType(volume_id, 'cloud_init', 'server');
64
+ var volid = volidByIndexAndTag(index, 'input');
65
65
  result = volid.includes("cloudinit");
66
66
  }
67
67
  return result;
@@ -69,42 +69,42 @@ function hasCloudinit(){
69
69
 
70
70
  function hasCdrom(){
71
71
  result = false;
72
- let id = volumeFieldsetId('cdrom', 'server').attr('id');
73
- if (id !== undefined){
74
- let index = indexByIdAndType(id, 'cdrom', 'server');
75
- let checked = $("input[id^='host_compute_attributes_volumes_attributes_" + index + "_cdrom']:checked").val();
76
- let isCdrom = checked === 'cdrom';
72
+ var volume_id = volumeFieldsetId('cdrom', 'server').attr('id');
73
+ if (volume_id !== undefined){
74
+ var index = indexByIdAndType(volume_id, 'cdrom', 'server');
75
+ var checked = $("input[id^='host_compute_attributes_volumes_attributes_" + index + "_cdrom']:checked").val();
76
+ var isCdrom = checked === 'cdrom';
77
77
  result = isCdrom;
78
- let isImage = checked === 'image';
78
+ var isImage = checked === 'image';
79
79
  if (isImage) {
80
- let volid = volidByIndexAndTag(index, 'select');
80
+ var volid = volidByIndexAndTag(index, 'select');
81
81
  result = volid.includes("iso");
82
82
  }
83
83
  }
84
84
  return result;
85
85
  }
86
86
 
87
- function cloudinit(id){
88
- return id === 'cloud_init' && hasCloudinit();
87
+ function cloudinit(item){
88
+ return item === 'cloud_init' && hasCloudinit();
89
89
  }
90
90
 
91
- function cdrom(id){
92
- return id === 'cdrom' && hasCdrom();
91
+ function cdrom(item){
92
+ return item === 'cdrom' && hasCdrom();
93
93
  }
94
94
 
95
- function enableVolume(id, type){
96
- volumeFieldsetId(id, type).show();
97
- volumeButtonAddId(id).show();
98
- if (cloudinit(id) || cdrom(id)){
99
- volumeButtonAddId(id).hide();
95
+ function enableVolume(volume_id, type){
96
+ volumeFieldsetId(volume_id, type).show();
97
+ volumeButtonAddId(volume_id).show();
98
+ if (cloudinit(volume_id) || cdrom(volume_id)){
99
+ volumeButtonAddId(volume_id).hide();
100
100
  }
101
- volumeFieldsetId(id, type).removeAttr('disabled');
101
+ volumeFieldsetId(volume_id, type).removeAttr('disabled');
102
102
  }
103
103
 
104
- function disableVolume(id, type){
105
- volumeFieldsetId(id, type).hide();
106
- volumeButtonAddId(id).hide();
107
- volumeFieldsetId(id, type).attr('disabled','disabled');
104
+ function disableVolume(volume_id, type){
105
+ volumeFieldsetId(volume_id, type).hide();
106
+ volumeButtonAddId(volume_id).hide();
107
+ volumeFieldsetId(volume_id, type).attr('disabled','disabled');
108
108
  }
109
109
 
110
110
  function volumes(type){
@@ -115,44 +115,44 @@ function volume(type){
115
115
  return type === 'qemu' ? 'server' : 'container';
116
116
  }
117
117
 
118
- function toggleVolume(id, type1, type2){
119
- type1 === type2 ? enableVolume(id, volume(type1)) : disableVolume(id, volume(type1));
118
+ function toggleVolume(volume_id, type1, type2){
119
+ type1 === type2 ? enableVolume(volume_id, volume(type1)) : disableVolume(volume_id, volume(type1));
120
120
  }
121
121
 
122
122
  function toggleVolumes(selected){
123
123
  ['qemu', 'lxc'].forEach(function(type){
124
- volumes(type).forEach(function(id){
125
- toggleVolume(id, selected, type);
124
+ volumes(type).forEach(function(volume_id){
125
+ toggleVolume(volume_id, selected, type);
126
126
  });
127
127
  });
128
128
  }
129
129
 
130
- function enableFieldset(id, fieldset) {
130
+ function enableFieldset(fieldsetId, fieldset) {
131
131
  if (fieldset.toggle && fieldset.new_vm){
132
- fieldset_id(id, fieldset).show();
132
+ fieldset_id(fieldsetId, fieldset).show();
133
133
  }
134
- fieldset_id(id, fieldset).removeAttr('disabled');
135
- input_hidden_id(id).removeAttr('disabled');
134
+ fieldset_id(fieldsetId, fieldset).removeAttr('disabled');
135
+ input_hidden_id(fieldsetId).removeAttr('disabled');
136
136
  }
137
137
 
138
- function disableFieldset(id, fieldset) {
138
+ function disableFieldset(fieldsetId, fieldset) {
139
139
  if (fieldset.toggle && fieldset.new_vm){
140
- fieldset_id(id, fieldset).hide();
140
+ fieldset_id(fieldsetId, fieldset).hide();
141
141
  }
142
- fieldset_id(id, fieldset).attr('disabled','disabled');
143
- input_hidden_id(id).attr('disabled','disabled');
142
+ fieldset_id(fieldsetId, fieldset).attr('disabled','disabled');
143
+ input_hidden_id(fieldsetId).attr('disabled','disabled');
144
144
  }
145
145
 
146
- function toggleFieldset(id, fieldset, type1, type2) {
147
- type1 === type2 ? enableFieldset(id, fieldset) : disableFieldset(id, fieldset);
146
+ function toggleFieldset(fieldsetId, fieldset, type1, type2) {
147
+ type1 === type2 ? enableFieldset(fieldsetId, fieldset) : disableFieldset(fieldsetId, fieldset);
148
148
  }
149
149
 
150
- function input_hidden_id(id){
151
- return $("div[id^='"+ id +"_volumes']" + " + input:hidden");
150
+ function input_hidden_id(volume_id){
151
+ return $("div[id^='"+ volume_id +"_volumes']" + " + input:hidden");
152
152
  }
153
153
 
154
- function fieldset_id(id, fieldset){
155
- return $("fieldset[id^='" + id + "_"+fieldset.id+"']");
154
+ function fieldset_id(fieldsetId, fieldset){
155
+ return $("fieldset[id^='" + fieldsetId + "_"+fieldset.id+"']");
156
156
  }
157
157
 
158
158
  function fieldsets(type){
@@ -163,8 +163,8 @@ function toggleFieldsets(fieldset){
163
163
  var removable_input_hidden = $("div.removable-item[style='display: none;']" + " + input:hidden");
164
164
  removable_input_hidden.attr('disabled','disabled');
165
165
  ['qemu', 'lxc'].forEach(function(type){
166
- fieldsets(type).forEach(function(id){
167
- toggleFieldset(id, fieldset, fieldset.selected, type);
166
+ fieldsets(type).forEach(function(fieldsetId){
167
+ toggleFieldset(fieldsetId, fieldset, fieldset.selected, type);
168
168
  });
169
169
  });
170
170
  }
@@ -190,18 +190,18 @@ function nodeSelected(item) {
190
190
  }
191
191
  }
192
192
 
193
- function emptySelect(select){
194
- $(select).empty();
195
- $(select).append($("<option></option>").val('').text(''));
196
- $(select).val('');
193
+ function emptySelect(select_id){
194
+ $(select_id).empty();
195
+ $(select_id).append($("<option></option>").val('').text(''));
196
+ $(select_id).val('');
197
197
  }
198
198
 
199
199
  function initOptions(select_ids){
200
200
  console.log('initOptions(' + select_ids[0] + ')');
201
201
  select_ids.forEach(emptySelect);
202
- select_ids.forEach(function(select){
203
- $(select + ' option:selected').prop('selected',false);
204
- $(select).val('');
202
+ select_ids.forEach(function(select_id){
203
+ $(select_id + ' option:selected').prop('selected',false);
204
+ $(select_id).val('');
205
205
  });
206
206
  }
207
207
 
@@ -228,7 +228,9 @@ function updateOptions(options_path, start_options_id, end_options_id, start_sec
228
228
  if ( start_second_options_id != undefined && end_second_options_id != undefined) {
229
229
  select_second_ids = selectIds(start_second_options_id, end_second_options_id);
230
230
  }
231
- var url = '/foreman_fog_proxmox/' + options_path + '/' + node_id;
231
+ var compute_resource_id = $("#host_compute_resource_id").val();
232
+ if (compute_resource_id == undefined) compute_resource_id = $("#compute_attribute_compute_resource_id").val(); // profil
233
+ var url = '/foreman_fog_proxmox/' + options_path + '/' + compute_resource_id + '/' + node_id;
232
234
  if (second_id != undefined) url += '/' + second_id;
233
235
  tfm.tools.showSpinner();
234
236
  $.getJSON({
@@ -24,9 +24,9 @@ function volumesAttributesSelector(profile,index,selector) {
24
24
  }
25
25
 
26
26
  function getIndex(item) {
27
- var id = $(item).attr('id');
27
+ var index_id = $(item).attr('id');
28
28
  var pattern = /(host_compute_attributes_volumes_attributes_||compute_attribute_vm_attrs_volumes_attributes_)(\d+)[_](.*)/i;
29
- pattern_a = pattern.exec(id);
29
+ pattern_a = pattern.exec(index_id);
30
30
  var index = pattern_a[2];
31
31
  return index;
32
32
  }
@@ -16,24 +16,24 @@
16
16
  // along with ForemanFogProxmox. If not, see <http://www.gnu.org/licenses/>.
17
17
 
18
18
  function getIndex(item) {
19
- var id = $(item).attr('id');
19
+ var index_id = $(item).attr('id');
20
20
  var pattern = /(host_compute_attributes_volumes_attributes_||compute_attribute_vm_attrs_volumes_attributes_)(\d+)[_](.*)/i;
21
- pattern_a = pattern.exec(id);
21
+ pattern_a = pattern.exec(index_id);
22
22
  var index = pattern_a[2];
23
23
  return index;
24
24
  }
25
25
 
26
26
  function volumeId(type,index){
27
- let id = '#volume_' + type + '_' + index;
28
- return id;
27
+ var volume_id = '#volume_' + type + '_' + index;
28
+ return volume_id;
29
29
  }
30
30
 
31
- function enableField(id) {
32
- $(id).show();
33
- $(id).removeAttr('disabled');
31
+ function enableField(item) {
32
+ $(item).show();
33
+ $(item).removeAttr('disabled');
34
34
  }
35
35
 
36
- function disableField(id) {
37
- $(id).hide();
38
- $(id).attr('disabled','disabled');
36
+ function disableField(item) {
37
+ $(item).hide();
38
+ $(item).attr('disabled','disabled');
39
39
  }
@@ -0,0 +1,80 @@
1
+ # frozen_string_literal: true
2
+
3
+ # Copyright 2021 Tristan Robert
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 ComputeResourcesVmsController
22
+ extend ActiveSupport::Concern
23
+ included do
24
+ prepend Overrides
25
+ end
26
+ module Overrides
27
+ def associate
28
+ if Host.for_vm_uuid(@compute_resource, @vm).any?
29
+ process_error(:error_msg => _("VM already associated with a host"), :redirect => compute_resource_vm_path(:compute_resource_id => params[:compute_resource_id], :id => proxmox_vm_id(@compute_resource, @vm)))
30
+ return
31
+ end
32
+ host = @compute_resource.associated_host(@vm) if @compute_resource.respond_to?(:associated_host)
33
+ if host.present?
34
+ host.associate!(@compute_resource, @vm)
35
+ process_success(:success_msg => _("VM associated to host %s") % host.name, :success_redirect => host_path(host))
36
+ else
37
+ process_error(:error_msg => _("No host found to associate this VM with"), :redirect => compute_resource_vm_path(:compute_resource_id => params[:compute_resource_id], :id => proxmox_vm_id(@compute_resource, @vm)))
38
+ end
39
+ end
40
+
41
+ def console
42
+ @console = @compute_resource.console proxmox_vm_id(@compute_resource, @vm)
43
+ render case @console[:type]
44
+ when 'spice'
45
+ 'hosts/console/spice'
46
+ when 'vnc'
47
+ 'hosts/console/vnc'
48
+ when 'vmrc'
49
+ 'hosts/console/vmrc'
50
+ else
51
+ 'hosts/console/log'
52
+ end
53
+ rescue StandardError => e
54
+ process_error :redirect => compute_resource_vm_path(@compute_resource, proxmox_vm_id(@compute_resource, @vm)), :error_msg => (_("Failed to set console: %s") % e), :object => @vm
55
+ end
56
+
57
+ private
58
+
59
+ def proxmox_vm_id(compute_resource, vm)
60
+ id = vm.identity
61
+ id = vm.unique_cluster_identity(compute_resource) if compute_resource.class == ForemanFogProxmox::Proxmox
62
+ id
63
+ end
64
+
65
+ def run_vm_action(action)
66
+ if @vm.send(action)
67
+ @vm.reload
68
+ success format(_("%<vm>s is now %<vm_state>s"), { :vm => @vm, :vm_state => @vm.state.capitalize })
69
+ else
70
+ error format(_("failed to %<action>s %<vm>s"), { :action => _(action), :vm => @vm })
71
+ end
72
+ redirect_back(:fallback_location => compute_resource_vm_path(:compute_resource_id => params[:compute_resource_id], :id => proxmox_vm_id(@compute_resource, @vm)))
73
+ # This should only rescue Fog::Errors, but Fog returns all kinds of errors...
74
+ rescue StandardError => e
75
+ error format(_("Error - %<message>s"), { :message => _(e.message) })
76
+ redirect_back(:fallback_location => compute_resource_vm_path(:compute_resource_id => params[:compute_resource_id], :id => proxmox_vm_id(@compute_resource, @vm)))
77
+ end
78
+ end
79
+ end
80
+ end