Skip to content

Commit

Permalink
Proxmox extention for foreman_bootdisk
Browse files Browse the repository at this point in the history
  • Loading branch information
Manisha15 committed Dec 5, 2023
1 parent 95947b2 commit 8b1a5e2
Show file tree
Hide file tree
Showing 7 changed files with 151 additions and 0 deletions.
1 change: 1 addition & 0 deletions .github/workflows/ruby_ci.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,7 @@ jobs:
- name: Setup Bundler
run: |
echo "gem 'foreman_bootdisk', path: './foreman_bootdisk'" > bundler.d/foreman_bootdisk.local.rb
echo "gem 'foreman_fog_proxmox'" >> bundler.d/foreman_bootdisk.local.rb
- name: Setup Ruby
uses: ruby/setup-ruby@v1
with:
Expand Down
4 changes: 4 additions & 0 deletions Gemfile
Original file line number Diff line number Diff line change
Expand Up @@ -4,4 +4,8 @@ source 'http://rubygems.org'

gem 'theforeman-rubocop', '~> 0.1.0.pre', groups: %i[development rubocop]

group :test do
eval_gemfile 'gemfile.d/proxmox.rb'
end

gemspec
48 changes: 48 additions & 0 deletions app/models/concerns/foreman_bootdisk/compute_resources/proxmox.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
# frozen_string_literal: true

module ForemanBootdisk
module ComputeResources
module Proxmox
def capabilities
super + [:bootdisk]
end

def iso_upload(iso, vm_uuid)
server = find_vm_by_uuid(vm_uuid)
server.ssh_options = { password: fog_credentials[:proxmox_password] }
server.ssh_ip_address = server.node_id
server.username = client.credentials[:current_user].split('@').first
server.scp_upload(iso, '/var/lib/vz/template/iso/')
server.reload
storage = storages(server.node_id, 'iso')[0]
storage.volumes.any? { |v| v.volid.include? File.basename(iso) }
end

def iso_attach(iso, vm_uuid)
server = find_vm_by_uuid(vm_uuid)
storage = storages(server.node_id, 'iso')[0]
volume = storage.volumes.detect { |v| v.volid.include? File.basename(iso) }
disks = server.disks.map { |disk| disk.split(":")[0] }.join(";")
server.update({ ide2: "#{volume.volid},media=cdrom" })
server.update({ boot: "order=ide2;#{disks}" })
server.reboot
end

def iso_detach(vm_uuid)
server = find_vm_by_uuid(vm_uuid)

# get volid to delete iso after detaching from vm
volid = server.volumes.get("ide2").volid
server.update({ ide2: "none,media=cdrom" })

# cdrom will be ejected on next power off
server.detach('ide2')

# delete the iso file from proxmox server
storage = storages(server.node_id, 'iso')[0]
volume = storage.volumes.detect { |v| v.volid.include? volid }
volume.destroy
end
end
end
end
5 changes: 5 additions & 0 deletions lib/foreman_bootdisk/engine.rb
Original file line number Diff line number Diff line change
Expand Up @@ -145,6 +145,7 @@ class Engine < ::Rails::Engine
Host::Managed.prepend ForemanBootdisk::HostExt
Host::Managed.include ForemanBootdisk::Orchestration::Compute
Foreman::Model::Vmware.prepend ForemanBootdisk::ComputeResources::Vmware if Foreman::Model::Vmware.available?
ForemanFogProxmox::Proxmox.prepend ForemanBootdisk::ComputeResources::Proxmox if ForemanBootdisk.with_proxmox?
rescue StandardError => e
Rails.logger.warn "#{ForemanBootdisk::ENGINE_NAME}: skipping engine hook (#{e})"
end
Expand All @@ -154,4 +155,8 @@ class Engine < ::Rails::Engine
def self.logger
Foreman::Logging.logger('foreman_bootdisk')
end

def self.with_proxmox?
Foreman::Plugin.installed?('foreman_fog_proxmox')
end
end
4 changes: 4 additions & 0 deletions test/test_plugin_helper.rb
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,10 @@

require 'test_helper'

FactoryBot.definition_file_paths << File.join(ForemanFogProxmox::Engine.root, 'test', 'factories') if defined?(ForemanFogProxmox::Engine)
FactoryBot.definition_file_paths << File.join(__dir__, 'factories')
FactoryBot.reload

module ForemanBootdiskTestHelper
def create_tempfile
file = Tempfile.new('bootdisk-test', '/tmp')
Expand Down
19 changes: 19 additions & 0 deletions test/unit/concerns/compute_resources/proxmox_test.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
# frozen_string_literal: true

require 'test_plugin_helper'

module ForemanBootdisk
class ProxmoxTest < ActiveSupport::TestCase

describe '#capabilities' do
setup do
skip unless ForemanBootdisk.with_proxmox?
@cr = FactoryBot.build(:proxmox_cr)
end

test 'should include bootdisk' do
assert_includes @cr.capabilities, :bootdisk
end
end
end
end
70 changes: 70 additions & 0 deletions test/unit/concerns/orchestration/proxmox_compute_test.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
# frozen_string_literal: true

require 'test_plugin_helper'

module ForemanBootdisk
class OrchestrationProxmoxComputeTest < ActiveSupport::TestCase
setup do
disable_orchestration
skip unless ForemanBootdisk.with_proxmox?
@proxmox_cr = FactoryBot.build(:proxmox_cr)
@proxmox_host = FactoryBot.build(:host, :managed,
compute_resource: @proxmox_cr,
provision_method: 'bootdisk')
end

test 'provisioning a host with provision method bootdisk in proxmox should upload iso' do
@proxmox_cr.expects(:iso_upload)
@proxmox_host.send(:setIsoImage)
end

test 'provisioning a host with provision method bootdisk in proxmox should attach iso' do
@proxmox_cr.expects(:iso_attach)
@proxmox_host.send(:setAttachIsoImage)
end

test 'provisioning a host with provision method bootdisk in proxmox should detach iso' do
@proxmox_cr.expects(:iso_detach)
@proxmox_host.send(:setDetachIsoImage)
end

test 'provisioning a new proxmox host with provision method bootdisk should queue bootdisk tasks' do
@proxmox_host.stubs(:compute?).returns(true)
@proxmox_host.stubs(:build?).returns(true)
@proxmox_host.send(:queue_bootdisk_compute)
tasks = @proxmox_host.queue.all.map(&:name)
assert_includes tasks, "Generating ISO image for #{@proxmox_host.name}"
assert_includes tasks, "Upload ISO image to datastore for #{@proxmox_host.name}"
assert_includes tasks, "Attach ISO image to CDROM drive for #{@proxmox_host.name}"
assert_not_includes tasks, "Detach ISO image from CDROM drive for #{@proxmox_host.name}"
end

test 'rebuilding a proxmox host with provision method bootdisk should queue bootdisk tasks' do
@proxmox_host.stubs(:compute?).returns(true)
old = stub()
old.stubs(:build?).returns(false)
@proxmox_host.stubs(:old).returns(old)
@proxmox_host.stubs(:build?).returns(true)
@proxmox_host.send(:queue_bootdisk_compute)
tasks = @proxmox_host.queue.all.map(&:name)
assert_includes tasks, "Generating ISO image for #{@proxmox_host.name}"
assert_includes tasks, "Upload ISO image to datastore for #{@proxmox_host.name}"
assert_includes tasks, "Attach ISO image to CDROM drive for #{@proxmox_host.name}"
assert_not_includes tasks, "Detach ISO image from CDROM drive for #{@proxmox_host.name}"
end

test 'the iso should be detached when the proxmox host leaves build mode' do
@proxmox_host.stubs(:compute?).returns(true)
old = stub()
old.stubs(:build?).returns(true)
@proxmox_host.stubs(:old).returns(old)
@proxmox_host.stubs(:build?).returns(false)
@proxmox_host.send(:queue_bootdisk_compute)
tasks = @proxmox_host.queue.all.map(&:name)
assert_not_includes tasks, "Generating ISO image for #{@proxmox_host.name}"
assert_not_includes tasks, "Upload ISO image to datastore for #{@proxmox_host.name}"
assert_not_includes tasks, "Attach ISO image to CDROM drive for #{@proxmox_host.name}"
assert_includes tasks, "Detach ISO image from CDROM drive for #{@proxmox_host.name}"
end
end
end

0 comments on commit 8b1a5e2

Please sign in to comment.