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.
- checksums.yaml +4 -4
- data/README.md +42 -9
- data/app/assets/javascripts/foreman_fog_proxmox/proxmox_compute_resource.js +25 -13
- data/app/assets/javascripts/foreman_fog_proxmox/proxmox_vm.js +62 -60
- data/app/assets/javascripts/foreman_fog_proxmox/proxmox_vm_server.js +2 -2
- data/app/assets/javascripts/foreman_fog_proxmox/proxmox_volume.js +10 -10
- data/app/controllers/concerns/foreman_fog_proxmox/compute_resources_vms_controller.rb +80 -0
- data/app/controllers/foreman_fog_proxmox/compute_resources_controller.rb +23 -25
- data/app/helpers/proxmox_compute_resources_vms_helper.rb +99 -0
- data/app/helpers/proxmox_vm_config_helper.rb +5 -4
- data/app/helpers/proxmox_vm_uuid_helper.rb +34 -0
- data/app/models/concerns/fog_extensions/proxmox/server.rb +4 -0
- data/app/models/concerns/host_ext/proxmox/associator.rb +46 -0
- data/app/models/concerns/host_ext/proxmox/for_vm.rb +33 -0
- data/app/models/concerns/orchestration/proxmox/compute.rb +65 -7
- data/app/models/foreman_fog_proxmox/proxmox.rb +4 -0
- data/app/models/foreman_fog_proxmox/proxmox_compute_attributes.rb +3 -6
- data/app/models/foreman_fog_proxmox/proxmox_images.rb +13 -4
- data/app/models/foreman_fog_proxmox/proxmox_interfaces.rb +2 -1
- data/app/models/foreman_fog_proxmox/proxmox_vm_commands.rb +5 -3
- data/app/models/foreman_fog_proxmox/proxmox_vm_new.rb +2 -4
- data/app/models/foreman_fog_proxmox/proxmox_vm_queries.rb +14 -7
- data/app/models/foreman_fog_proxmox/vms.rb +1 -1
- data/app/services/concerns/foreman_fog_proxmox/compute_resource_host_associator.rb +34 -0
- data/app/services/foreman_fog_proxmox/node_dashboard/data.rb +6 -2
- data/app/views/api/v2/compute_resources/proxmox.json.rabl +1 -1
- data/app/views/compute_resources_vms/form/proxmox/server/_volume_cdrom.html.erb +1 -1
- data/app/views/compute_resources_vms/index/_proxmox.html.erb +2 -2
- data/config/routes.rb +7 -7
- data/db/migrate/20210312105013_update_proxmox_uuid_host.rb +29 -0
- data/lib/foreman_fog_proxmox/engine.rb +13 -2
- data/lib/foreman_fog_proxmox/version.rb +1 -1
- data/test/functional/compute_resources_controller_test.rb +4 -4
- data/test/unit/foreman_fog_proxmox/helpers/proxmox_container_helper_test.rb +4 -3
- data/test/unit/foreman_fog_proxmox/helpers/proxmox_server_helper_test.rb +3 -1
- data/test/unit/foreman_fog_proxmox/helpers/proxmox_vm_uuid_helper_test.rb +38 -0
- data/test/unit/foreman_fog_proxmox/proxmox_images_test.rb +3 -3
- data/test/unit/foreman_fog_proxmox/proxmox_interfaces_test.rb +2 -2
- data/test/unit/foreman_fog_proxmox/proxmox_vm_queries_test.rb +3 -3
- metadata +12 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: e42832dc77d338bb20585f27678bc2207c23a610f7c7b478f24f3791ca65a414
|
4
|
+
data.tar.gz: 1385bea7eed802496ae7ab85ca013e75dc0343a8a433a347d8811b59fd620cd0
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
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
|
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/
|
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-
|
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](
|
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
|
-
###
|
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
|
-
|
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
|
-
|
43
|
-
|
44
|
-
|
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(
|
43
|
-
return $("a[data-association='" +
|
42
|
+
function volumeButtonAddId(item){
|
43
|
+
return $("a[data-association='" + item + "_volumes']");
|
44
44
|
}
|
45
45
|
|
46
|
-
function volumeFieldsetId(
|
47
|
-
return $("fieldset[id^='" + type + "_volume_"+
|
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(
|
51
|
-
|
52
|
-
return
|
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
|
-
|
62
|
-
if (
|
63
|
-
|
64
|
-
|
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
|
-
|
73
|
-
if (
|
74
|
-
|
75
|
-
|
76
|
-
|
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
|
-
|
78
|
+
var isImage = checked === 'image';
|
79
79
|
if (isImage) {
|
80
|
-
|
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(
|
88
|
-
return
|
87
|
+
function cloudinit(item){
|
88
|
+
return item === 'cloud_init' && hasCloudinit();
|
89
89
|
}
|
90
90
|
|
91
|
-
function cdrom(
|
92
|
-
return
|
91
|
+
function cdrom(item){
|
92
|
+
return item === 'cdrom' && hasCdrom();
|
93
93
|
}
|
94
94
|
|
95
|
-
function enableVolume(
|
96
|
-
volumeFieldsetId(
|
97
|
-
volumeButtonAddId(
|
98
|
-
if (cloudinit(
|
99
|
-
volumeButtonAddId(
|
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(
|
101
|
+
volumeFieldsetId(volume_id, type).removeAttr('disabled');
|
102
102
|
}
|
103
103
|
|
104
|
-
function disableVolume(
|
105
|
-
volumeFieldsetId(
|
106
|
-
volumeButtonAddId(
|
107
|
-
volumeFieldsetId(
|
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(
|
119
|
-
type1 === type2 ? enableVolume(
|
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(
|
125
|
-
toggleVolume(
|
124
|
+
volumes(type).forEach(function(volume_id){
|
125
|
+
toggleVolume(volume_id, selected, type);
|
126
126
|
});
|
127
127
|
});
|
128
128
|
}
|
129
129
|
|
130
|
-
function enableFieldset(
|
130
|
+
function enableFieldset(fieldsetId, fieldset) {
|
131
131
|
if (fieldset.toggle && fieldset.new_vm){
|
132
|
-
fieldset_id(
|
132
|
+
fieldset_id(fieldsetId, fieldset).show();
|
133
133
|
}
|
134
|
-
fieldset_id(
|
135
|
-
input_hidden_id(
|
134
|
+
fieldset_id(fieldsetId, fieldset).removeAttr('disabled');
|
135
|
+
input_hidden_id(fieldsetId).removeAttr('disabled');
|
136
136
|
}
|
137
137
|
|
138
|
-
function disableFieldset(
|
138
|
+
function disableFieldset(fieldsetId, fieldset) {
|
139
139
|
if (fieldset.toggle && fieldset.new_vm){
|
140
|
-
fieldset_id(
|
140
|
+
fieldset_id(fieldsetId, fieldset).hide();
|
141
141
|
}
|
142
|
-
fieldset_id(
|
143
|
-
input_hidden_id(
|
142
|
+
fieldset_id(fieldsetId, fieldset).attr('disabled','disabled');
|
143
|
+
input_hidden_id(fieldsetId).attr('disabled','disabled');
|
144
144
|
}
|
145
145
|
|
146
|
-
function toggleFieldset(
|
147
|
-
type1 === type2 ? enableFieldset(
|
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(
|
151
|
-
return $("div[id^='"+
|
150
|
+
function input_hidden_id(volume_id){
|
151
|
+
return $("div[id^='"+ volume_id +"_volumes']" + " + input:hidden");
|
152
152
|
}
|
153
153
|
|
154
|
-
function fieldset_id(
|
155
|
-
return $("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(
|
167
|
-
toggleFieldset(
|
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(
|
194
|
-
$(
|
195
|
-
$(
|
196
|
-
$(
|
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(
|
203
|
-
$(
|
204
|
-
$(
|
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
|
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
|
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(
|
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
|
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(
|
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
|
-
|
28
|
-
return
|
27
|
+
var volume_id = '#volume_' + type + '_' + index;
|
28
|
+
return volume_id;
|
29
29
|
}
|
30
30
|
|
31
|
-
function enableField(
|
32
|
-
$(
|
33
|
-
$(
|
31
|
+
function enableField(item) {
|
32
|
+
$(item).show();
|
33
|
+
$(item).removeAttr('disabled');
|
34
34
|
}
|
35
35
|
|
36
|
-
function disableField(
|
37
|
-
$(
|
38
|
-
$(
|
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
|