diff --git a/app/models/concerns/foreman_bootdisk/compute_resources/libvirt.rb b/app/models/concerns/foreman_bootdisk/compute_resources/libvirt.rb new file mode 100644 index 00000000..d7681137 --- /dev/null +++ b/app/models/concerns/foreman_bootdisk/compute_resources/libvirt.rb @@ -0,0 +1,44 @@ +# frozen_string_literal: true + +module ForemanBootdisk + module ComputeResources + module Libvirt + def capabilities + super + [:bootdisk] + end + + def set_boot_order(attr = {}) + order = super(attr) + order.unshift 'cdrom' if attr[:provision_method] == 'bootdisk' + order + end + + def iso_upload(iso, _vm_uuid) + client.upload_iso(libvirt_iso_pool_name, File.basename(iso), iso) + end + + def iso_attach(iso, vm_uuid) + client.attach_iso(vm_uuid, File.basename(iso)) + end + + def iso_detach(vm_uuid) + client.detach_iso(vm_uuid) + end + + def iso_delete(iso, _vm_uuid = nil) + client.destroy_iso(libvirt_iso_pool_name, File.basename(iso)) + end + + private + + def libvirt_iso_pool_name + if respond_to?(:volumes) && volumes.present? + pool = volumes.first.try(:pool_name) || volumes.first.try(:[], 'pool_name') + return pool if pool.present? + end + + 'default' + end + end + end +end diff --git a/app/models/concerns/foreman_bootdisk/orchestration/compute.rb b/app/models/concerns/foreman_bootdisk/orchestration/compute.rb index ebed5be8..0b2499d0 100644 --- a/app/models/concerns/foreman_bootdisk/orchestration/compute.rb +++ b/app/models/concerns/foreman_bootdisk/orchestration/compute.rb @@ -31,7 +31,7 @@ def queue_bootdisk_compute action: [self, :setGenerateIsoImage]) queue.create(name: _('Upload ISO image to datastore for %s') % self, priority: 6, action: [self, :setIsoImage]) - queue.create(name: _('Attach ISO image to CDROM drive for %s') % self, priority: 1001, + queue.create(name: _('Attach ISO image to CDROM drive for %s') % self, priority: 30, action: [self, :setAttachIsoImage]) # Detach ISO image when host sends 'built' HTTP POST request elsif old&.build? && !build? diff --git a/lib/foreman_bootdisk/engine.rb b/lib/foreman_bootdisk/engine.rb index dac83195..500f985f 100644 --- a/lib/foreman_bootdisk/engine.rb +++ b/lib/foreman_bootdisk/engine.rb @@ -140,6 +140,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? + Foreman::Model::Libvirt.prepend ForemanBootdisk::ComputeResources::Libvirt if Foreman::Model::Libvirt.available? ForemanFogProxmox::Proxmox.prepend ForemanBootdisk::ComputeResources::Proxmox if ForemanBootdisk.with_proxmox? rescue StandardError => e Rails.logger.warn "#{ForemanBootdisk::ENGINE_NAME}: skipping engine hook (#{e})" diff --git a/test/unit/concerns/compute_resources/libvirt_test.rb b/test/unit/concerns/compute_resources/libvirt_test.rb new file mode 100644 index 00000000..ce6caded --- /dev/null +++ b/test/unit/concerns/compute_resources/libvirt_test.rb @@ -0,0 +1,81 @@ +# frozen_string_literal: true + +require 'test_plugin_helper' + +module ForemanBootdisk + class LibvirtTest < ActiveSupport::TestCase + class DummyLibvirtComputeResource + prepend ForemanBootdisk::ComputeResources::Libvirt + + attr_reader :client + + def initialize(client, volumes = []) + @client = client + @volumes = volumes + end + + def capabilities + [:image] + end + + def volumes + @volumes + end + + def set_boot_order(_attr = {}) + %w[hd] + end + end + + setup do + @client = mock('client') + @cr = DummyLibvirtComputeResource.new(@client, [OpenStruct.new(pool_name: 'bootdisk')]) + end + + describe '#capabilities' do + test 'should include bootdisk' do + assert_includes @cr.capabilities, :bootdisk + end + end + + describe '#iso_upload' do + test 'calls fog-libvirt upload_iso' do + @client.expects(:upload_iso).with('bootdisk', 'test.iso', '/tmp/test.iso') + @cr.iso_upload('/tmp/test.iso', '1234') + end + end + + describe '#iso_attach' do + test 'calls fog-libvirt attach_iso' do + @client.expects(:attach_iso).with('1234', 'test.iso') + @cr.iso_attach('test.iso', '1234') + end + end + + describe '#iso_detach' do + test 'calls fog-libvirt detach_iso' do + @client.expects(:detach_iso).with('1234', nil) + @cr.iso_detach('1234') + end + end + + describe '#iso_delete' do + test 'calls fog-libvirt destroy_iso' do + @client.expects(:destroy_iso).with('bootdisk', 'test.iso') + @cr.iso_delete('test.iso') + end + end + + describe '#set_boot_order' do + test 'prepends cdrom when provision_method is bootdisk' do + order = @cr.set_boot_order(provision_method: 'bootdisk') + assert_equal %w[cdrom network hd], order + end + + test 'returns base order when provision_method is not bootdisk' do + order = @cr.set_boot_order(provision_method: 'image') + assert_equal %w[hd], order + end + end + end +end