Skip to content

Commit 1724acc

Browse files
Manisha15stejskalleos
authored andcommitted
Proxmox extention for foreman_bootdisk
1 parent 65676f4 commit 1724acc

File tree

5 files changed

+148
-0
lines changed

5 files changed

+148
-0
lines changed
Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
# frozen_string_literal: true
2+
3+
module ForemanBootdisk
4+
module ComputeResources
5+
module Proxmox
6+
CDROM_VOLUME = 'ide2'
7+
8+
def capabilities
9+
super + [:bootdisk]
10+
end
11+
12+
def iso_upload(iso, vm_uuid)
13+
server = find_vm_by_uuid(vm_uuid)
14+
server.ssh_options = { password: fog_credentials[:proxmox_password] }
15+
server.ssh_ip_address = proxmox_host
16+
server.username = client.credentials[:current_user].split('@').first
17+
server.scp_upload(iso, '/var/lib/vz/template/iso/')
18+
server.reload
19+
storage = storages(server.node_id, 'iso')[0]
20+
storage.volumes.any? { |v| v.volid.include? File.basename(iso) }
21+
end
22+
23+
def iso_attach(iso, vm_uuid)
24+
server = find_vm_by_uuid(vm_uuid)
25+
storage = storages(server.node_id, 'iso')[0]
26+
volume = storage.volumes.detect { |v| v.volid.include? File.basename(iso) }
27+
disks = server.disks.map { |disk| disk.split(":")[0] }.join(";")
28+
server.update({ ide2: "#{volume.volid},media=cdrom" })
29+
server.update({ boot: "order=ide2;#{disks}" })
30+
server.reboot
31+
end
32+
33+
def iso_detach(vm_uuid)
34+
server = find_vm_by_uuid(vm_uuid)
35+
36+
# get volid to delete iso after detaching from vm
37+
volid = server.volumes.get(CDROM_VOLUME).volid
38+
server.update({ ide2: "none,media=cdrom" })
39+
40+
# cdrom will be ejected on next power off
41+
server.detach(CDROM_VOLUME)
42+
43+
# delete the iso file from proxmox server
44+
storage = storages(server.node_id, 'iso')[0]
45+
volume = storage.volumes.detect { |v| v.volid.include? volid }
46+
volume.destroy
47+
end
48+
end
49+
end
50+
end

lib/foreman_bootdisk/engine.rb

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -140,6 +140,7 @@ class Engine < ::Rails::Engine
140140
Host::Managed.prepend ForemanBootdisk::HostExt
141141
Host::Managed.include ForemanBootdisk::Orchestration::Compute
142142
Foreman::Model::Vmware.prepend ForemanBootdisk::ComputeResources::Vmware if Foreman::Model::Vmware.available?
143+
ForemanFogProxmox::Proxmox.prepend ForemanBootdisk::ComputeResources::Proxmox if ForemanBootdisk.with_proxmox?
143144
rescue StandardError => e
144145
Rails.logger.warn "#{ForemanBootdisk::ENGINE_NAME}: skipping engine hook (#{e})"
145146
end
@@ -149,4 +150,8 @@ class Engine < ::Rails::Engine
149150
def self.logger
150151
Foreman::Logging.logger('foreman_bootdisk')
151152
end
153+
154+
def self.with_proxmox?
155+
Foreman::Plugin.installed?('foreman_fog_proxmox')
156+
end
152157
end

test/test_plugin_helper.rb

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,10 @@
22

33
require 'test_helper'
44

5+
FactoryBot.definition_file_paths << File.join(ForemanFogProxmox::Engine.root, 'test', 'factories') if defined?(ForemanFogProxmox::Engine)
6+
FactoryBot.definition_file_paths << File.join(__dir__, 'factories')
7+
FactoryBot.reload
8+
59
module ForemanBootdiskTestHelper
610
def create_tempfile
711
file = Tempfile.new('bootdisk-test', '/tmp')
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
# frozen_string_literal: true
2+
3+
require 'test_plugin_helper'
4+
5+
module ForemanBootdisk
6+
class ProxmoxTest < ActiveSupport::TestCase
7+
8+
describe '#capabilities' do
9+
setup do
10+
skip unless ForemanBootdisk.with_proxmox?
11+
@cr = FactoryBot.build(:proxmox_cr)
12+
end
13+
14+
test 'should include bootdisk' do
15+
assert_includes @cr.capabilities, :bootdisk
16+
end
17+
end
18+
end
19+
end
Lines changed: 70 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,70 @@
1+
# frozen_string_literal: true
2+
3+
require 'test_plugin_helper'
4+
5+
module ForemanBootdisk
6+
class OrchestrationProxmoxComputeTest < ActiveSupport::TestCase
7+
setup do
8+
disable_orchestration
9+
skip unless ForemanBootdisk.with_proxmox?
10+
@proxmox_cr = FactoryBot.build(:proxmox_cr)
11+
@proxmox_host = FactoryBot.build(:host, :managed,
12+
compute_resource: @proxmox_cr,
13+
provision_method: 'bootdisk')
14+
end
15+
16+
test 'provisioning a host with provision method bootdisk in proxmox should upload iso' do
17+
@proxmox_cr.expects(:iso_upload)
18+
@proxmox_host.send(:setIsoImage)
19+
end
20+
21+
test 'provisioning a host with provision method bootdisk in proxmox should attach iso' do
22+
@proxmox_cr.expects(:iso_attach)
23+
@proxmox_host.send(:setAttachIsoImage)
24+
end
25+
26+
test 'provisioning a host with provision method bootdisk in proxmox should detach iso' do
27+
@proxmox_cr.expects(:iso_detach)
28+
@proxmox_host.send(:setDetachIsoImage)
29+
end
30+
31+
test 'provisioning a new proxmox host with provision method bootdisk should queue bootdisk tasks' do
32+
@proxmox_host.stubs(:compute?).returns(true)
33+
@proxmox_host.stubs(:build?).returns(true)
34+
@proxmox_host.send(:queue_bootdisk_compute)
35+
tasks = @proxmox_host.queue.all.map(&:name)
36+
assert_includes tasks, "Generating ISO image for #{@proxmox_host.name}"
37+
assert_includes tasks, "Upload ISO image to datastore for #{@proxmox_host.name}"
38+
assert_includes tasks, "Attach ISO image to CDROM drive for #{@proxmox_host.name}"
39+
assert_not_includes tasks, "Detach ISO image from CDROM drive for #{@proxmox_host.name}"
40+
end
41+
42+
test 'rebuilding a proxmox host with provision method bootdisk should queue bootdisk tasks' do
43+
@proxmox_host.stubs(:compute?).returns(true)
44+
old = stub()
45+
old.stubs(:build?).returns(false)
46+
@proxmox_host.stubs(:old).returns(old)
47+
@proxmox_host.stubs(:build?).returns(true)
48+
@proxmox_host.send(:queue_bootdisk_compute)
49+
tasks = @proxmox_host.queue.all.map(&:name)
50+
assert_includes tasks, "Generating ISO image for #{@proxmox_host.name}"
51+
assert_includes tasks, "Upload ISO image to datastore for #{@proxmox_host.name}"
52+
assert_includes tasks, "Attach ISO image to CDROM drive for #{@proxmox_host.name}"
53+
assert_not_includes tasks, "Detach ISO image from CDROM drive for #{@proxmox_host.name}"
54+
end
55+
56+
test 'the iso should be detached when the proxmox host leaves build mode' do
57+
@proxmox_host.stubs(:compute?).returns(true)
58+
old = stub()
59+
old.stubs(:build?).returns(true)
60+
@proxmox_host.stubs(:old).returns(old)
61+
@proxmox_host.stubs(:build?).returns(false)
62+
@proxmox_host.send(:queue_bootdisk_compute)
63+
tasks = @proxmox_host.queue.all.map(&:name)
64+
assert_not_includes tasks, "Generating ISO image for #{@proxmox_host.name}"
65+
assert_not_includes tasks, "Upload ISO image to datastore for #{@proxmox_host.name}"
66+
assert_not_includes tasks, "Attach ISO image to CDROM drive for #{@proxmox_host.name}"
67+
assert_includes tasks, "Detach ISO image from CDROM drive for #{@proxmox_host.name}"
68+
end
69+
end
70+
end

0 commit comments

Comments
 (0)