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.

Files changed (34) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +28 -18
  3. data/app/controllers/concerns/foreman_fog_proxmox/controller/parameters/compute_resource.rb +1 -1
  4. data/app/helpers/proxmox_container_helper.rb +4 -3
  5. data/app/helpers/proxmox_server_helper.rb +3 -2
  6. data/app/helpers/proxmox_vm_helper.rb +6 -4
  7. data/app/models/concerns/fog_extensions/proxmox/{container_config.rb → node.rb} +6 -11
  8. data/app/models/concerns/fog_extensions/proxmox/server.rb +2 -13
  9. data/app/models/concerns/fog_extensions/proxmox/server_config.rb +18 -4
  10. data/app/models/foreman_fog_proxmox/proxmox.rb +104 -66
  11. data/app/overrides/compute_resources_vms/form/add_clone_to_new_vm_compute_detail.rb +0 -9
  12. data/app/overrides/compute_resources_vms/form/add_vm_type_to_networks_form.rb +1 -1
  13. data/app/overrides/compute_resources_vms/form/add_vm_type_to_nic_provider_specific_form.rb +1 -1
  14. data/app/services/foreman_fog_proxmox/node_dashboard/data.rb +3 -3
  15. data/app/views/compute_resources/form/_proxmox.html.erb +2 -2
  16. data/app/views/compute_resources/show/_proxmox.html.erb +4 -0
  17. data/app/views/compute_resources_vms/form/proxmox/_add_vm_type_to_networks_form.html.erb +2 -1
  18. data/app/views/compute_resources_vms/form/proxmox/_add_vm_type_to_networks_new_childs_form.html.erb +1 -0
  19. data/app/views/compute_resources_vms/form/proxmox/_add_vm_type_to_nic_provider_specific_form.html.erb +2 -1
  20. data/app/views/compute_resources_vms/form/proxmox/_add_vm_type_to_volumes_edit.html.erb +0 -1
  21. data/app/views/compute_resources_vms/form/proxmox/_general.html.erb +1 -1
  22. data/app/views/compute_resources_vms/form/proxmox/server/_network.html.erb +0 -1
  23. data/app/views/compute_resources_vms/show/_proxmox.html.erb +1 -1
  24. data/app/views/dashboard/_foreman_fog_proxmox_widget.erb +2 -2
  25. data/lib/foreman_fog_proxmox/engine.rb +3 -5
  26. data/lib/foreman_fog_proxmox/version.rb +1 -1
  27. data/test/factories/proxmox_factory.rb +9 -2
  28. data/test/unit/foreman_fog_proxmox/helpers/proxmox_container_helper_test.rb +5 -5
  29. data/test/unit/foreman_fog_proxmox/helpers/proxmox_server_helper_test.rb +2 -1
  30. data/test/unit/foreman_fog_proxmox/helpers/proxmox_vm_helper_test.rb +22 -14
  31. data/test/unit/foreman_fog_proxmox/proxmox_test.rb +22 -31
  32. data/test/unit/foreman_fog_proxmox/proxmox_test_helpers.rb +18 -4
  33. metadata +8 -9
  34. 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: b867a431af383a2d626127ab2f79f996bbcc72a8cd770bd94ff48db315270e56
4
- data.tar.gz: 38e71818548bea80b97801e50a7153a48cbbc94a17d07f9d555c296c78cccd2c
3
+ metadata.gz: 1304ab366464cb132705a6d4b31dc6473d52c30e44dd50118d14eb2ef1f64ed6
4
+ data.tar.gz: 8d3791c5a478031da10323c24fd9f90c2d23dcda0d185dbece4649b5896b26dc
5
5
  SHA512:
6
- metadata.gz: edf8d6c9b5fb1aa5c1fe4107108435036752a6bd7170545b6ff85d78f086f80c9f6af2dc53c6bca1e0c34418963586f492a5e249a25907c6cc3818e74b8ad6d7
7
- data.tar.gz: 6a1ec0442155b270f08ea1fc9ec97e08fff473e624404fd2078c05533f3629bac0bbbafd0ee617ef03732917f378c872bec629c60372d91710d4a6627109b8e5
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
- Tested with:
18
-
19
- * Foreman >= 1.17 and <= 1.20
20
- * Fog-proxmox >= 0.5.3
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.17.3 or later on your machine:
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.17.3
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/database.yaml.example config/database.yaml
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 sholud write tests and you can execute those specific to this plugin:
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). This project is intended to be a safe, welcoming space for collaboration, and contributors are expected to adhere to the [Contributor Covenant](http://contributor-covenant.org) code of conduct.
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).
@@ -27,7 +27,7 @@ module ForemanFogProxmox
27
27
  def compute_resource_params_filter
28
28
  super.tap do |filter|
29
29
  filter.permit :ssl_verify_peer,
30
- :ssl_certs, :node_name, :disable_proxy
30
+ :ssl_certs, :node_id, :disable_proxy, :cr_id
31
31
  end
32
32
  end
33
33
 
@@ -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 node vmid]
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[node name type config_attributes volumes_attributes interfaces_attributes firmware_type provision_method container_volumes server_volumes]
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.container_flatten(nic)
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 node vmid]
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[node type config_attributes volumes_attributes interfaces_attributes firmware_type provision_method container_volumes server_volumes]
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 type node vmid]
32
+ main_a = %w[hostname name vmid]
33
33
  type = vm.config.attributes['type']
34
34
  type = vm.type unless type
35
- main = vm.config.attributes.select { |key,_value| main_a.include? key }
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
- config_hash.store(key, (config_hash[key].to_i / MEGA).to_s) unless ForemanFogProxmox::Value.empty?(config_hash[key])
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 ContainerConfig
22
+ module Node
25
23
  extend ActiveSupport::Concern
26
-
27
- def rootfs_storage
28
- mount_points.rootfs.storage
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
- def to_s
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
- %w[none cdrom].include?(disks.cdrom.volid) ? disks.cdrom.volid : 'image'
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
- %w[none cdrom].include?(disks.cdrom.volid) ? disks.cdrom.volid : 'image'
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 :node_name, :presence => true
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[:node_name].empty?
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.find_by_id storage_id if storage_id
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.find_by_id node_name
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
- vm = find_vm_by_uuid("qemu_#{vmid}")
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
- case host.compute_attributes['type']
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,:mount_points,:interfaces].include?(key) || value.to_s.empty?}
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
- volumes = vm.container? ? vm.config.mount_points : vm.config.disks || []
184
- vm_attrs[:volumes_attributes] = Hash[volumes.each_with_index.map { |volume, idx| [idx.to_s, volume.attributes] }]
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.servers
222
+ node
198
223
  end
199
224
 
200
- def new_vm(attr = {})
201
- attr = ActiveSupport::HashWithIndifferentAccess.new(attr)
202
- type = attr['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(attr)
231
+ vm = new_container_vm(new_attr)
207
232
  when 'qemu'
208
- vm = new_server_vm(attr)
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(attr = {})
215
- vm = node.containers.new(vm_container_instance_defaults.merge(parse_container_vm(attr.merge(type: 'lxc'))))
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(attr = {})
221
- vm = node.servers.new(vm_server_instance_defaults.merge(parse_server_vm(attr.merge(type: 'qemu'))))
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
- type, vmid = parse_type_and_vmid(uuid)
260
- case type
261
- when 'qemu'
262
- node.servers.get(vmid)
263
- when 'lxc'
264
- node.containers.get(vmid)
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
- rescue Fog::Errors::Error => e
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
- vm = find_vm_by_uuid("qemu_#{image}")
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, attr)
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
- logger.debug(N_("save_vm(): %{attr}") % { attr: attr })
308
- templated = attr[:templated]
334
+ templated = new_attributes[:templated]
309
335
  if (templated == '1' && !vm.templated?)
310
- vm.template
336
+ vm.create_template
311
337
  else
312
- parsed_attr = vm.container? ? parse_container_vm(attr) : parse_server_vm(attr)
313
- merged = vm.config.attributes.merge(parsed_attr.symbolize_keys).deep_symbolize_keys
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 node_name
324
- self.attrs[:node_name]
348
+ def node_id
349
+ self.attrs[:node_id]
325
350
  end
326
351
 
327
- def node_name=(value)
328
- self.attrs[:node_name] = value
352
+ def node_id=(value)
353
+ self.attrs[:node_id] = value
329
354
  end
330
355
 
331
356
  def node
332
- client.nodes.find_by_id node_name
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
- options.store(:websocket, 1) if type_console == 'vnc'
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
- node: node.to_s,
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(interface_server_defaults))
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
- node: node.to_s,
473
+ node_id: node_id,
440
474
  memory: 512 * MEGA,
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))
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, node: node.to_s)
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)