foreman_fog_proxmox 0.5.6 → 0.6.0
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 +28 -18
- data/app/controllers/concerns/foreman_fog_proxmox/controller/parameters/compute_resource.rb +1 -1
- data/app/helpers/proxmox_container_helper.rb +4 -3
- data/app/helpers/proxmox_server_helper.rb +3 -2
- data/app/helpers/proxmox_vm_helper.rb +6 -4
- data/app/models/concerns/fog_extensions/proxmox/{container_config.rb → node.rb} +6 -11
- data/app/models/concerns/fog_extensions/proxmox/server.rb +2 -13
- data/app/models/concerns/fog_extensions/proxmox/server_config.rb +18 -4
- data/app/models/foreman_fog_proxmox/proxmox.rb +104 -66
- data/app/overrides/compute_resources_vms/form/add_clone_to_new_vm_compute_detail.rb +0 -9
- data/app/overrides/compute_resources_vms/form/add_vm_type_to_networks_form.rb +1 -1
- data/app/overrides/compute_resources_vms/form/add_vm_type_to_nic_provider_specific_form.rb +1 -1
- data/app/services/foreman_fog_proxmox/node_dashboard/data.rb +3 -3
- data/app/views/compute_resources/form/_proxmox.html.erb +2 -2
- data/app/views/compute_resources/show/_proxmox.html.erb +4 -0
- data/app/views/compute_resources_vms/form/proxmox/_add_vm_type_to_networks_form.html.erb +2 -1
- data/app/views/compute_resources_vms/form/proxmox/_add_vm_type_to_networks_new_childs_form.html.erb +1 -0
- data/app/views/compute_resources_vms/form/proxmox/_add_vm_type_to_nic_provider_specific_form.html.erb +2 -1
- data/app/views/compute_resources_vms/form/proxmox/_add_vm_type_to_volumes_edit.html.erb +0 -1
- data/app/views/compute_resources_vms/form/proxmox/_general.html.erb +1 -1
- data/app/views/compute_resources_vms/form/proxmox/server/_network.html.erb +0 -1
- data/app/views/compute_resources_vms/show/_proxmox.html.erb +1 -1
- data/app/views/dashboard/_foreman_fog_proxmox_widget.erb +2 -2
- data/lib/foreman_fog_proxmox/engine.rb +3 -5
- data/lib/foreman_fog_proxmox/version.rb +1 -1
- data/test/factories/proxmox_factory.rb +9 -2
- data/test/unit/foreman_fog_proxmox/helpers/proxmox_container_helper_test.rb +5 -5
- data/test/unit/foreman_fog_proxmox/helpers/proxmox_server_helper_test.rb +2 -1
- data/test/unit/foreman_fog_proxmox/helpers/proxmox_vm_helper_test.rb +22 -14
- data/test/unit/foreman_fog_proxmox/proxmox_test.rb +22 -31
- data/test/unit/foreman_fog_proxmox/proxmox_test_helpers.rb +18 -4
- metadata +8 -9
- data/app/models/concerns/fog_extensions/proxmox/container.rb +0 -57
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 1304ab366464cb132705a6d4b31dc6473d52c30e44dd50118d14eb2ef1f64ed6
|
4
|
+
data.tar.gz: 8d3791c5a478031da10323c24fd9f90c2d23dcda0d185dbece4649b5896b26dc
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 9ef6e0f3b3670c18bc5e23d5a467df1df14e041e5036c1bca1bf8de10eb699ffa705e5934da287f6cb42e2baf2730d6a3994fecc396abcbe067941b142e5cf71
|
7
|
+
data.tar.gz: 49d98f70077f0382b046f5763f12fa169c12c5e9e1b57aed84f44b4be18194a5924a75f9ab1f4c46297a400281dfd3036b16e9a8f4df3ff3db0178f41549376f
|
data/README.md
CHANGED
@@ -12,14 +12,12 @@ It is intended to satisfy this [feature](http://projects.theforeman.org/issues/2
|
|
12
12
|
|
13
13
|
If you like it and need more features you can [support](SUPPORT.md) it.
|
14
14
|
|
15
|
-
## Compatibility
|
15
|
+
## Compatibility versions
|
16
16
|
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
* Proxmox >= 5.1
|
22
|
-
* Ruby >= 2.3
|
17
|
+
|Fog-proxmox|Proxmox|Foreman-fog-proxmox|Foreman|Ruby|
|
18
|
+
|--|--|--|--|--|
|
19
|
+
|<0.6|<5.3|<0.6|<=1.20|>=2.3|
|
20
|
+
|>=0.6|=5.3|>=0.6|=1.21|>=2.3|
|
23
21
|
|
24
22
|
## Installation
|
25
23
|
|
@@ -109,11 +107,11 @@ Redhat, CentOS or Fedora users should also [setup Selinux](https://projects.thef
|
|
109
107
|
|
110
108
|
* Fork this github repo.
|
111
109
|
* Clone it on your local machine
|
112
|
-
* Install foreman v1.
|
110
|
+
* Install foreman v1.21.1 on your machine:
|
113
111
|
|
114
112
|
```shell
|
115
113
|
git clone https://github.com/theforeman/foreman
|
116
|
-
git checkout tags/1.
|
114
|
+
git checkout tags/1.21.1
|
117
115
|
```
|
118
116
|
|
119
117
|
* Create a Gemfile.local.rb file in foreman/bundler.d/
|
@@ -142,7 +140,8 @@ cp config/settings.yaml.test config/settings.yaml
|
|
142
140
|
* Install foreman database (sqlite is default in rails development):
|
143
141
|
|
144
142
|
```shell
|
145
|
-
cp config/
|
143
|
+
cp config/model.mappings.example config/model.mappings
|
144
|
+
cp config/database.yml.example config/database.yml
|
146
145
|
bundle exec bin/rake db:migrate
|
147
146
|
bundle exec bin/rake db:seed
|
148
147
|
```
|
@@ -153,13 +152,22 @@ bundle exec bin/rake db:seed
|
|
153
152
|
bundle exec bin/rake permissions:reset
|
154
153
|
```
|
155
154
|
|
156
|
-
* You
|
155
|
+
* You should write tests and you can execute those specific to this plugin:
|
156
|
+
|
157
|
+
all:
|
157
158
|
|
158
159
|
```shell
|
159
160
|
export DISABLE_SPRING=true
|
160
161
|
bundle exec bin/rake test:foreman_fog_proxmox
|
161
162
|
```
|
162
163
|
|
164
|
+
or just one:
|
165
|
+
|
166
|
+
```shell
|
167
|
+
export DISABLE_SPRING=true
|
168
|
+
bundle exec bin/rake test TEST=test/functional/compute_resources_controller_test.rb
|
169
|
+
```
|
170
|
+
|
163
171
|
* In foreman directory, after you modify foreman_fog_proxmox specific assets (proxmox.js, etc) you have to precompile it:
|
164
172
|
|
165
173
|
```shell
|
@@ -175,7 +183,7 @@ bundle exec bin/rake plugin:gettext[foreman_fog_proxmox]
|
|
175
183
|
* In foreman directory, run rails server:
|
176
184
|
|
177
185
|
```shell
|
178
|
-
rails server
|
186
|
+
bundle exec bin/rails server
|
179
187
|
```
|
180
188
|
|
181
189
|
* In foreman directory, run in a new terminal the webpack-dev-server:
|
@@ -184,19 +192,21 @@ rails server
|
|
184
192
|
./node_modules/.bin/webpack-dev-server --config config/webpack.config.js
|
185
193
|
```
|
186
194
|
|
195
|
+
* Or you can launch all together:
|
196
|
+
|
197
|
+
```shell
|
198
|
+
bundle exec foreman start
|
199
|
+
```
|
200
|
+
|
187
201
|
See details in [foreman plugin development](https://projects.theforeman.org/projects/foreman/wiki/How_to_Create_a_Plugin)
|
188
202
|
|
189
203
|
## Contributing
|
190
204
|
|
191
205
|
You can reach the [contributors](CONTRIBUTORS.md).
|
192
|
-
Bug reports and pull requests are welcome on GitHub at [ForemanFogProxmox](https://github.com/theforeman/foreman_fog_proxmox).
|
206
|
+
Bug reports and pull requests are welcome on GitHub at [ForemanFogProxmox](https://github.com/theforeman/foreman_fog_proxmox).
|
193
207
|
|
194
|
-
Please read [how to contribute](CONTRIBUTING.md).
|
208
|
+
Please read more information about [how to contribute](CONTRIBUTING.md).
|
195
209
|
|
196
210
|
## License
|
197
211
|
|
198
212
|
The code is available as open source under the terms of the [GNU Public License v3](LICENSE).
|
199
|
-
|
200
|
-
## Code of Conduct
|
201
|
-
|
202
|
-
Everyone interacting in the ForemanProxmox project’s codebases, issue trackers, chat rooms and mailing lists is expected to follow the [code of conduct](CODE_OF_CONDUCT.md).
|
@@ -28,12 +28,13 @@ module ProxmoxContainerHelper
|
|
28
28
|
GIGA = KILO * MEGA
|
29
29
|
|
30
30
|
def parse_container_vm(args)
|
31
|
+
logger.debug("parse_container_vm args=#{args}")
|
31
32
|
args = ActiveSupport::HashWithIndifferentAccess.new(args)
|
32
33
|
return {} unless args
|
33
34
|
return {} if args.empty?
|
34
35
|
return {} unless args['type'] == 'lxc'
|
35
36
|
config = args['config_attributes']
|
36
|
-
main_a = %w[name type
|
37
|
+
main_a = %w[name type node_id vmid interfaces mount_points disks]
|
37
38
|
config = args.reject { |key,_value| main_a.include? key } unless config
|
38
39
|
ostemplate_a = %w[ostemplate ostemplate_storage ostemplate_file]
|
39
40
|
ostemplate = parse_container_ostemplate(args.select { |key,_value| ostemplate_a.include? key })
|
@@ -45,7 +46,7 @@ module ProxmoxContainerHelper
|
|
45
46
|
memory = parse_container_memory(config.select { |key,_value| memory_a.include? key })
|
46
47
|
interfaces_attributes = args['interfaces_attributes']
|
47
48
|
networks = parse_container_interfaces(interfaces_attributes)
|
48
|
-
general_a = %w[
|
49
|
+
general_a = %w[node_id name type config_attributes volumes_attributes interfaces_attributes firmware_type provision_method container_volumes server_volumes]
|
49
50
|
logger.debug("general_a: #{general_a}")
|
50
51
|
parsed_vm = args.reject { |key,value| general_a.include?(key) || ostemplate_a.include?(key) || ForemanFogProxmox::Value.empty?(value) }
|
51
52
|
config_a = []
|
@@ -151,7 +152,7 @@ module ProxmoxContainerHelper
|
|
151
152
|
nic.store(:rate, args['rate'].to_i) if args['rate']
|
152
153
|
nic.store(:tag, args['tag'].to_i) if args['tag']
|
153
154
|
logger.debug("parse_container_interface(): add nic=#{nic}")
|
154
|
-
Fog::Proxmox::NicHelper.
|
155
|
+
Fog::Proxmox::NicHelper.flatten(nic)
|
155
156
|
end
|
156
157
|
end
|
157
158
|
|
@@ -28,12 +28,13 @@ module ProxmoxServerHelper
|
|
28
28
|
GIGA = KILO * MEGA
|
29
29
|
|
30
30
|
def parse_server_vm(args)
|
31
|
+
logger.debug("parse_server_vm args=#{args}")
|
31
32
|
args = ActiveSupport::HashWithIndifferentAccess.new(args)
|
32
33
|
return {} unless args
|
33
34
|
return {} if args.empty?
|
34
35
|
return {} unless args['type'] == 'qemu'
|
35
36
|
config = args['config_attributes']
|
36
|
-
main_a = %w[name type
|
37
|
+
main_a = %w[name type node_id vmid interfaces mount_points disks]
|
37
38
|
config = args.reject { |key,_value| main_a.include? key } unless config
|
38
39
|
cdrom_a = %w[cdrom cdrom_storage cdrom_iso]
|
39
40
|
cdrom = parse_server_cdrom(config.select { |key,_value| cdrom_a.include? key })
|
@@ -45,7 +46,7 @@ module ProxmoxServerHelper
|
|
45
46
|
memory = parse_server_memory(config.select { |key,_value| memory_a.include? key })
|
46
47
|
interfaces_attributes = args['interfaces_attributes']
|
47
48
|
networks = parse_server_interfaces(interfaces_attributes)
|
48
|
-
general_a = %w[
|
49
|
+
general_a = %w[node_id type config_attributes volumes_attributes interfaces_attributes firmware_type provision_method container_volumes server_volumes]
|
49
50
|
logger.debug("general_a: #{general_a}")
|
50
51
|
parsed_vm = args.reject { |key,value| general_a.include?(key) || ForemanFogProxmox::Value.empty?(value) }
|
51
52
|
config_a = []
|
@@ -29,10 +29,10 @@ module ProxmoxVmHelper
|
|
29
29
|
|
30
30
|
def object_to_config_hash(vm,type)
|
31
31
|
vm_h = ActiveSupport::HashWithIndifferentAccess.new
|
32
|
-
main_a = %w[hostname name
|
32
|
+
main_a = %w[hostname name vmid]
|
33
33
|
type = vm.config.attributes['type']
|
34
34
|
type = vm.type unless type
|
35
|
-
main = vm.
|
35
|
+
main = vm.attributes.select { |key,_value| main_a.include? key }
|
36
36
|
disks_regexp = /^(scsi|sata|mp|rootfs|virtio|ide)(\d+){0,1}$/
|
37
37
|
nics_regexp = /^(net)(\d+)/
|
38
38
|
main_a += %w[templated]
|
@@ -71,11 +71,13 @@ module ProxmoxVmHelper
|
|
71
71
|
end
|
72
72
|
|
73
73
|
def remove_deletes(args)
|
74
|
-
args['volumes_attributes'].delete_if { |_key,value| value.has_key? '_delete' }
|
74
|
+
args['volumes_attributes'].delete_if { |_key,value| value.has_key? '_delete' } if args['volumes_attributes']
|
75
75
|
end
|
76
76
|
|
77
77
|
def convert_memory_size(config_hash, key)
|
78
|
-
|
78
|
+
# default unit memory size is Mb
|
79
|
+
memory = (config_hash[key].to_i / MEGA).to_s == '0' ? config_hash[key] : (config_hash[key].to_i / MEGA).to_s
|
80
|
+
config_hash.store(key, memory)
|
79
81
|
end
|
80
82
|
|
81
83
|
def parse_type_and_vmid(uuid)
|
@@ -17,20 +17,15 @@
|
|
17
17
|
# You should have received a copy of the GNU General Public License
|
18
18
|
# along with ForemanFogProxmox. If not, see <http://www.gnu.org/licenses/>.
|
19
19
|
|
20
|
-
require 'fog/proxmox/helpers/disk_helper'
|
21
|
-
|
22
20
|
module FogExtensions
|
23
21
|
module Proxmox
|
24
|
-
module
|
22
|
+
module Node
|
25
23
|
extend ActiveSupport::Concern
|
26
|
-
|
27
|
-
|
28
|
-
|
24
|
+
def all(options = {})
|
25
|
+
vms = servers.all
|
26
|
+
vms += containers.all
|
27
|
+
vms
|
29
28
|
end
|
30
|
-
def rootfs_file
|
31
|
-
mount_points.rootfs.volid
|
32
|
-
end
|
33
|
-
|
34
29
|
end
|
35
30
|
end
|
36
|
-
end
|
31
|
+
end
|
@@ -21,19 +21,8 @@ module FogExtensions
|
|
21
21
|
module Proxmox
|
22
22
|
module Server
|
23
23
|
extend ActiveSupport::Concern
|
24
|
-
attr_accessor :image_id, :templated, :ostemplate_storage, :ostemplate_file
|
25
|
-
|
26
|
-
name
|
27
|
-
end
|
28
|
-
def identity
|
29
|
-
"#{type}_#{vmid}"
|
30
|
-
end
|
31
|
-
def container?
|
32
|
-
type == 'lxc'
|
33
|
-
end
|
34
|
-
def persisted?
|
35
|
-
!!identity && !!uptime
|
36
|
-
end
|
24
|
+
attr_accessor :image_id, :templated, :ostemplate_storage, :ostemplate_file, :password
|
25
|
+
|
37
26
|
def start
|
38
27
|
action('start')
|
39
28
|
end
|
@@ -33,16 +33,30 @@ module FogExtensions
|
|
33
33
|
Fog::Proxmox::CpuHelper.extract_pcid(cpu)
|
34
34
|
end
|
35
35
|
def cdrom
|
36
|
-
|
36
|
+
if disks.cdrom
|
37
|
+
%w[none cdrom].include?(disks.cdrom.volid) ? disks.cdrom.volid : 'image'
|
38
|
+
else
|
39
|
+
'none'
|
40
|
+
end
|
37
41
|
end
|
38
42
|
def cdrom_storage
|
39
|
-
disks.cdrom.storage
|
43
|
+
disks.cdrom ? disks.cdrom.storage : ''
|
40
44
|
end
|
41
45
|
def cdrom_iso
|
42
|
-
disks.cdrom.volid
|
46
|
+
disks.cdrom ? disks.cdrom.volid : ''
|
43
47
|
end
|
44
48
|
def cdrom_image
|
45
|
-
|
49
|
+
if disks.cdrom
|
50
|
+
%w[none cdrom].include?(disks.cdrom.volid) ? disks.cdrom.volid : 'image'
|
51
|
+
else
|
52
|
+
'none'
|
53
|
+
end
|
54
|
+
end
|
55
|
+
def rootfs_storage
|
56
|
+
disks.rootfs.storage if disks.rootfs
|
57
|
+
end
|
58
|
+
def rootfs_file
|
59
|
+
disks.rootfs.volid if disks.rootfs
|
46
60
|
end
|
47
61
|
end
|
48
62
|
end
|
@@ -27,7 +27,7 @@ module ForemanFogProxmox
|
|
27
27
|
validates :url, :format => { :with => URI::DEFAULT_PARSER.make_regexp }, :presence => true
|
28
28
|
validates :user, :format => { :with => /(\w+)[@]{1}(\w+)/ }, :presence => true
|
29
29
|
validates :password, :presence => true
|
30
|
-
validates :
|
30
|
+
validates :node_id, :presence => true
|
31
31
|
before_create :test_connection
|
32
32
|
|
33
33
|
def provided_attributes
|
@@ -49,12 +49,17 @@ module ForemanFogProxmox
|
|
49
49
|
end
|
50
50
|
|
51
51
|
def credentials_valid?
|
52
|
-
errors[:url].empty? && errors[:user].empty? && errors[:user].include?('@') && errors[:password].empty? && errors[:
|
52
|
+
errors[:url].empty? && errors[:user].empty? && errors[:user].include?('@') && errors[:password].empty? && errors[:node_id].empty?
|
53
|
+
end
|
54
|
+
|
55
|
+
def version_suitable?
|
56
|
+
version == '5.3'
|
53
57
|
end
|
54
58
|
|
55
59
|
def test_connection(options = {})
|
56
60
|
super
|
57
61
|
credentials_valid?
|
62
|
+
version_suitable?
|
58
63
|
rescue => e
|
59
64
|
errors[:base] << e.message
|
60
65
|
errors[:url] << e.message
|
@@ -76,7 +81,7 @@ module ForemanFogProxmox
|
|
76
81
|
end
|
77
82
|
|
78
83
|
def images_by_storage(type = 'iso', storage_id)
|
79
|
-
storage = node.storages.
|
84
|
+
storage = node.storages.get storage_id if storage_id
|
80
85
|
storage.volumes.list_by_content_type(type).sort_by(&:volid) if storage
|
81
86
|
end
|
82
87
|
|
@@ -85,7 +90,7 @@ module ForemanFogProxmox
|
|
85
90
|
end
|
86
91
|
|
87
92
|
def bridges
|
88
|
-
node = network_client.nodes.
|
93
|
+
node = network_client.nodes.get node_id
|
89
94
|
bridges = node.networks.all(type: 'any_bridge')
|
90
95
|
bridges.sort_by(&:iface)
|
91
96
|
end
|
@@ -101,15 +106,14 @@ module ForemanFogProxmox
|
|
101
106
|
end
|
102
107
|
|
103
108
|
def template(vmid)
|
104
|
-
|
105
|
-
vm = find_vm_by_uuid("lxc_#{vmid}") unless vm
|
106
|
-
vm
|
109
|
+
find_vm_by_uuid(vmid)
|
107
110
|
end
|
108
111
|
|
109
112
|
def host_compute_attrs(host)
|
110
113
|
super.tap do |attrs|
|
111
114
|
ostype = host.compute_attributes['config_attributes']['ostype']
|
112
|
-
|
115
|
+
type = host.compute_attributes['type']
|
116
|
+
case type
|
113
117
|
when 'lxc'
|
114
118
|
host.compute_attributes['config_attributes'].store('hostname',host.name)
|
115
119
|
when 'qemu'
|
@@ -158,13 +162,32 @@ module ForemanFogProxmox
|
|
158
162
|
Fog::Compute::Proxmox::Disk.new(opts)
|
159
163
|
end
|
160
164
|
|
161
|
-
def new_interface(attr = {})
|
165
|
+
def new_interface(attr = {})
|
166
|
+
type = attr['type']
|
167
|
+
type = 'qemu' unless type
|
168
|
+
case type
|
169
|
+
when 'lxc'
|
170
|
+
return new_container_interface(attr)
|
171
|
+
when 'qemu'
|
172
|
+
return new_server_interface(attr)
|
173
|
+
end
|
174
|
+
end
|
175
|
+
|
176
|
+
def new_server_interface(attr = {})
|
177
|
+
logger.debug("new_server_interface")
|
162
178
|
opts = interface_server_defaults.merge(attr.to_h).deep_symbolize_keys
|
163
179
|
Fog::Compute::Proxmox::Interface.new(opts)
|
164
180
|
end
|
165
181
|
|
182
|
+
def new_container_interface(attr = {})
|
183
|
+
logger.debug("new_container_interface")
|
184
|
+
opts = interface_container_defaults.merge(attr.to_h).deep_symbolize_keys
|
185
|
+
Fog::Compute::Proxmox::Interface.new(opts)
|
186
|
+
end
|
187
|
+
|
188
|
+
# used by host.clone
|
166
189
|
def vm_compute_attributes(vm)
|
167
|
-
vm_attrs = vm.attributes.reject { |key,value| [:config].include?(key) || value.to_s.empty? }
|
190
|
+
vm_attrs = vm.attributes.reject { |key,value| [:config, :vmid].include?(key.to_sym) || value.to_s.empty? }
|
168
191
|
vm_attrs = set_vm_config_attributes(vm, vm_attrs)
|
169
192
|
vm_attrs = set_vm_volumes_attributes(vm, vm_attrs)
|
170
193
|
vm_attrs = set_vm_interfaces_attributes(vm, vm_attrs)
|
@@ -173,15 +196,17 @@ module ForemanFogProxmox
|
|
173
196
|
|
174
197
|
def set_vm_config_attributes(vm, vm_attrs)
|
175
198
|
if vm.respond_to?(:config)
|
176
|
-
config = vm.config.attributes.reject { |key,value| [:disks
|
199
|
+
config = vm.config.attributes.reject { |key,value| [:disks, :interfaces, :vmid].include?(key) || value.to_s.empty?}
|
177
200
|
vm_attrs[:config_attributes] = config
|
178
201
|
end
|
179
202
|
vm_attrs
|
180
203
|
end
|
181
204
|
|
182
205
|
def set_vm_volumes_attributes(vm, vm_attrs)
|
183
|
-
|
184
|
-
|
206
|
+
if vm.config.respond_to?(:disks)
|
207
|
+
volumes = vm.config.disks || []
|
208
|
+
vm_attrs[:volumes_attributes] = Hash[volumes.each_with_index.map { |volume, idx| [idx.to_s, volume.attributes] }]
|
209
|
+
end
|
185
210
|
vm_attrs
|
186
211
|
end
|
187
212
|
|
@@ -194,31 +219,33 @@ module ForemanFogProxmox
|
|
194
219
|
end
|
195
220
|
|
196
221
|
def vms(opts = {})
|
197
|
-
node
|
222
|
+
node
|
198
223
|
end
|
199
224
|
|
200
|
-
def new_vm(
|
201
|
-
|
202
|
-
type =
|
225
|
+
def new_vm(new_attr = {})
|
226
|
+
new_attr = ActiveSupport::HashWithIndifferentAccess.new(new_attr)
|
227
|
+
type = new_attr['type']
|
203
228
|
type = 'qemu' unless type
|
204
229
|
case type
|
205
230
|
when 'lxc'
|
206
|
-
vm = new_container_vm(
|
231
|
+
vm = new_container_vm(new_attr)
|
207
232
|
when 'qemu'
|
208
|
-
vm = new_server_vm(
|
233
|
+
vm = new_server_vm(new_attr)
|
209
234
|
end
|
210
235
|
logger.debug(_("new_vm() vm.config=%{config}") % { config: vm.config.inspect })
|
211
236
|
vm
|
212
237
|
end
|
213
238
|
|
214
|
-
def new_container_vm(
|
215
|
-
|
239
|
+
def new_container_vm(new_attr = {})
|
240
|
+
new_attr.merge(node_id: node_id)
|
241
|
+
vm = node.containers.new(parse_container_vm(vm_container_instance_defaults.merge(new_attr.merge(type: 'lxc'))).deep_symbolize_keys)
|
216
242
|
logger.debug(_("new_container_vm() vm.config=%{config}") % { config: vm.config.inspect })
|
217
243
|
vm
|
218
244
|
end
|
219
245
|
|
220
|
-
def new_server_vm(
|
221
|
-
|
246
|
+
def new_server_vm(new_attr = {})
|
247
|
+
new_attr.merge(node_id: node_id)
|
248
|
+
vm = node.servers.new(parse_server_vm(vm_server_instance_defaults.merge(new_attr.merge(type: 'qemu'))).deep_symbolize_keys)
|
222
249
|
logger.debug(_("new_server_vm() vm.config=%{config}") % { config: vm.config.inspect })
|
223
250
|
vm
|
224
251
|
end
|
@@ -235,20 +262,17 @@ module ForemanFogProxmox
|
|
235
262
|
clone = node.servers.get vmid
|
236
263
|
clone.update(name: args[:name])
|
237
264
|
else
|
238
|
-
logger.debug(_("create_vm(): %{args}") % { args: args })
|
239
265
|
convert_sizes(args)
|
240
266
|
remove_deletes(args)
|
241
267
|
case type
|
242
268
|
when 'qemu'
|
243
|
-
node.servers.create(parse_server_vm(args))
|
269
|
+
vm = node.servers.create(parse_server_vm(args))
|
244
270
|
when 'lxc'
|
245
271
|
hash = parse_container_vm(args)
|
246
272
|
hash = hash.merge(vmid: vmid)
|
247
|
-
node.containers.create(hash.reject { |key,_value| %w[ostemplate_storage ostemplate_file].include? key })
|
273
|
+
vm = node.containers.create(hash.reject { |key,_value| %w[ostemplate_storage ostemplate_file].include? key })
|
248
274
|
end
|
249
275
|
end
|
250
|
-
vm = find_vm_by_uuid("#{type}_#{vmid}")
|
251
|
-
vm
|
252
276
|
rescue => e
|
253
277
|
logger.warn(_("failed to create vm: %{e}") % { e: e })
|
254
278
|
destroy_vm vm.id if vm
|
@@ -256,16 +280,23 @@ module ForemanFogProxmox
|
|
256
280
|
end
|
257
281
|
|
258
282
|
def find_vm_by_uuid(uuid)
|
259
|
-
|
260
|
-
|
261
|
-
|
262
|
-
|
263
|
-
|
264
|
-
|
283
|
+
begin
|
284
|
+
vm = node.servers.get(uuid)
|
285
|
+
rescue Fog::Errors::NotFound
|
286
|
+
vm = nil
|
287
|
+
rescue Fog::Errors::Error => e
|
288
|
+
Foreman::Logging.exception(_("Failed retrieving proxmox server vm by vmid=%{uuid}") % { vmid: uuid }, e)
|
289
|
+
raise(ActiveRecord::RecordNotFound)
|
290
|
+
end
|
291
|
+
begin
|
292
|
+
vm = node.containers.get(uuid) unless vm
|
293
|
+
rescue Fog::Errors::NotFound
|
294
|
+
vm = nil
|
295
|
+
rescue Fog::Errors::Error => e
|
296
|
+
Foreman::Logging.exception(_("Failed retrieving proxmox container vm by vmid=%{uuid}") % { vmid: uuid }, e)
|
297
|
+
raise(ActiveRecord::RecordNotFound)
|
265
298
|
end
|
266
|
-
|
267
|
-
Foreman::Logging.exception(_("Failed retrieving proxmox vm by vmid=%{vmid} and type=%{type}") % { vmid: vmid, type: type }, e)
|
268
|
-
raise(ActiveRecord::RecordNotFound)
|
299
|
+
vm
|
269
300
|
end
|
270
301
|
|
271
302
|
def supports_update?
|
@@ -295,41 +326,35 @@ module ForemanFogProxmox
|
|
295
326
|
end
|
296
327
|
|
297
328
|
def image_exists?(image)
|
298
|
-
|
299
|
-
vm = find_vm_by_uuid("lxc_#{image}") unless vm
|
300
|
-
vm!=nil
|
329
|
+
!find_vm_by_uuid(image).nil?
|
301
330
|
end
|
302
331
|
|
303
|
-
def save_vm(uuid,
|
304
|
-
type, vmid = parse_type_and_vmid(uuid)
|
305
|
-
attr = attr.merge(type: type, vmid: vmid)
|
332
|
+
def save_vm(uuid, new_attributes)
|
306
333
|
vm = find_vm_by_uuid(uuid)
|
307
|
-
|
308
|
-
templated = attr[:templated]
|
334
|
+
templated = new_attributes[:templated]
|
309
335
|
if (templated == '1' && !vm.templated?)
|
310
|
-
vm.
|
336
|
+
vm.create_template
|
311
337
|
else
|
312
|
-
parsed_attr = vm.container? ? parse_container_vm(
|
313
|
-
|
314
|
-
filtered = merged.reject { |key,value| [:node,:vmid,:type,:templated,:image_id].include?(key) || value.to_s.empty? }
|
315
|
-
vm.update(filtered)
|
338
|
+
parsed_attr = vm.container? ? parse_container_vm(new_attributes.merge(type: vm.type)) : parse_server_vm(new_attributes.merge(type: vm.type))
|
339
|
+
vm.update(parsed_attr.reject { |key,value| [:templated,:ostemplate,:ostemplate_file,:ostemplate_storage].include? key.to_sym || ForemanFogProxmox::Value.empty?(value) })
|
316
340
|
end
|
341
|
+
vm = find_vm_by_uuid(uuid)
|
317
342
|
end
|
318
343
|
|
319
344
|
def next_vmid
|
320
345
|
node.servers.next_id
|
321
346
|
end
|
322
347
|
|
323
|
-
def
|
324
|
-
self.attrs[:
|
348
|
+
def node_id
|
349
|
+
self.attrs[:node_id]
|
325
350
|
end
|
326
351
|
|
327
|
-
def
|
328
|
-
self.attrs[:
|
352
|
+
def node_id=(value)
|
353
|
+
self.attrs[:node_id] = value
|
329
354
|
end
|
330
355
|
|
331
356
|
def node
|
332
|
-
client.nodes.
|
357
|
+
client.nodes.get node_id
|
333
358
|
end
|
334
359
|
|
335
360
|
def ssl_certs
|
@@ -370,9 +395,14 @@ module ForemanFogProxmox
|
|
370
395
|
|
371
396
|
def console(uuid)
|
372
397
|
vm = find_vm_by_uuid(uuid)
|
373
|
-
type_console = vm.config.type_console
|
374
398
|
options = {}
|
375
|
-
|
399
|
+
if vm.container?
|
400
|
+
type_console = 'vnc'
|
401
|
+
options.store(:console, type_console)
|
402
|
+
else
|
403
|
+
type_console = vm.config.type_console
|
404
|
+
end
|
405
|
+
options.store(:websocket, 1) if type_console == 'vnc'
|
376
406
|
begin
|
377
407
|
vnc_console = vm.start_console(options)
|
378
408
|
WsProxy.start(:host => host, :host_port => vnc_console['port'], :password => vnc_console['ticket']).merge(:name => vm.name, :type => type_console)
|
@@ -382,6 +412,10 @@ module ForemanFogProxmox
|
|
382
412
|
end
|
383
413
|
end
|
384
414
|
|
415
|
+
def version
|
416
|
+
identity_client.read_version
|
417
|
+
end
|
418
|
+
|
385
419
|
private
|
386
420
|
|
387
421
|
def fog_credentials
|
@@ -417,7 +451,7 @@ module ForemanFogProxmox
|
|
417
451
|
name: "foreman_#{Time.now.to_i}",
|
418
452
|
vmid: next_vmid,
|
419
453
|
type: 'qemu',
|
420
|
-
|
454
|
+
node_id: node_id,
|
421
455
|
cores: 1,
|
422
456
|
sockets: 1,
|
423
457
|
kvm: 0,
|
@@ -428,7 +462,7 @@ module ForemanFogProxmox
|
|
428
462
|
cpu: 'kvm64',
|
429
463
|
scsihw: 'virtio-scsi-pci',
|
430
464
|
ide2: "none,media=cdrom",
|
431
|
-
templated: 0).merge(Fog::Proxmox::DiskHelper.flatten(volume_server_defaults)).merge(Fog::Proxmox::DiskHelper.flatten(volume_container_defaults)).merge(Fog::Proxmox::NicHelper.flatten(
|
465
|
+
templated: 0).merge(Fog::Proxmox::DiskHelper.flatten(volume_server_defaults)).merge(Fog::Proxmox::DiskHelper.flatten(volume_container_defaults)).merge(Fog::Proxmox::NicHelper.flatten(interface_defaults))
|
432
466
|
end
|
433
467
|
|
434
468
|
def vm_container_instance_defaults
|
@@ -436,30 +470,34 @@ module ForemanFogProxmox
|
|
436
470
|
name: "foreman_#{Time.now.to_i}",
|
437
471
|
vmid: next_vmid,
|
438
472
|
type: 'lxc',
|
439
|
-
|
473
|
+
node_id: node_id,
|
440
474
|
memory: 512 * MEGA,
|
441
|
-
templated: 0).merge(Fog::Proxmox::DiskHelper.flatten(
|
475
|
+
templated: 0).merge(Fog::Proxmox::DiskHelper.flatten(volume_container_defaults)).merge(Fog::Proxmox::DiskHelper.flatten(volume_server_defaults)).merge(Fog::Proxmox::NicHelper.flatten(interface_defaults))
|
442
476
|
end
|
443
477
|
|
444
478
|
def vm_instance_defaults
|
445
|
-
super.merge(vmid: next_vmid,
|
479
|
+
super.merge(vmid: next_vmid, node_id: node_id)
|
446
480
|
end
|
447
481
|
|
448
482
|
def volume_server_defaults(controller = 'scsi', device = 0)
|
449
483
|
id = "#{controller}#{device}"
|
450
|
-
{ id: id, storage: storages.first.to_s, size: (8 * GIGA), options: { cache: 'none' } }
|
484
|
+
{ id: id, storage: storages.first.identity.to_s, size: (8 * GIGA), options: { cache: 'none' } }
|
451
485
|
end
|
452
486
|
|
453
487
|
def volume_container_defaults(id='rootfs')
|
454
|
-
{ id: id, storage: storages.first.to_s, size: (8 * GIGA), options: { } }
|
488
|
+
{ id: id, storage: storages.first.identity.to_s, size: (8 * GIGA), options: { } }
|
489
|
+
end
|
490
|
+
|
491
|
+
def interface_defaults(id = 'net0')
|
492
|
+
{ id: id, model: 'virtio', name: 'eth0', bridge: bridges.first.identity.to_s }
|
455
493
|
end
|
456
494
|
|
457
495
|
def interface_server_defaults(id = 'net0')
|
458
|
-
{ id: id, model: 'virtio', bridge: bridges.first.to_s }
|
496
|
+
{ id: id, model: 'virtio', bridge: bridges.first.identity.to_s }
|
459
497
|
end
|
460
498
|
|
461
499
|
def interface_container_defaults(id = 'net0')
|
462
|
-
{ id: id, name: 'eth0', bridge: bridges.first.to_s }
|
500
|
+
{ id: id, name: 'eth0', bridge: bridges.first.identity.to_s }
|
463
501
|
end
|
464
502
|
|
465
503
|
def compute_os_types(host)
|