diff --git a/README.md b/README.md index fdcf3f5f3168fe1dfe76f589ef9552405520694c..a46284ca1c10ea7a4c16aa7ee16a2b9c98ed4b6e 100644 --- a/README.md +++ b/README.md @@ -7,10 +7,6 @@ Example iPXE boot URLs; `http://foreman.example.com/unattended/iPXE?uuid=${uuid}` `http://template-proxy.example.com:8000/unattended/iPXE?mac=${netX/mac}&uuid=${uuid}` -### TODO: - -- Support booting machines in build mode (facts are wiped when machines are in build) - ## Installation See the [Plugins install instructions, advanced installation from gems](https://theforeman.org/plugins/#2.3AdvancedInstallationfromGems) for information on how to install this plugins. diff --git a/app/models/foreman_uuid_boot/uuidboot_host_facet.rb b/app/models/foreman_uuid_boot/uuidboot_host_facet.rb new file mode 100644 index 0000000000000000000000000000000000000000..202a0038960a25b2f73a1496135f28dd696c7690 --- /dev/null +++ b/app/models/foreman_uuid_boot/uuidboot_host_facet.rb @@ -0,0 +1,13 @@ +# frozen_string_literal: true + +module ForemanUuidBoot + class UuidbootHostFacet < ApplicationRecord + include Facets::Base + + def self.populate_fields_from_facts(host, parser, _type, _proxy) + facet = host.uuidboot_facet || host.build_uuidboot_facet + facet.uuid = parser.facts.dig('dmi', 'product', 'uuid') || parser.facts['uuid'] + facet.save if facet.changed? + end + end +end diff --git a/app/services/foreman/unattended_installation/concerns/host_finder_extensions.rb b/app/services/foreman/unattended_installation/concerns/host_finder_extensions.rb index 20e6ffb9b9ac1b53f121c9d64ffd570faf8e339a..01a31930a52adf7a32f792be9ec7474dd1ed12b4 100644 --- a/app/services/foreman/unattended_installation/concerns/host_finder_extensions.rb +++ b/app/services/foreman/unattended_installation/concerns/host_finder_extensions.rb @@ -13,6 +13,14 @@ module HostFinderExtensions def find_host_by_uuid return unless (uuid = query_params['uuid']) + facet = ForemanUuidBoot::UuidbootHostFacet.where(uuid: uuid).order(:created_at) + if facet.any? + Rails.logger.warn("Multiple hosts found with #{uuid}, picking up the most recent") if facet.count > 1 + + return facet.last.host.reload + end + + # Fallback fact search fact_name_id = FactName.where(name: 'uuid').map(&:id) return unless fact_name_id.any? diff --git a/db/migrate/20230120100100_add_uuidboot_facet.rb b/db/migrate/20230120100100_add_uuidboot_facet.rb new file mode 100644 index 0000000000000000000000000000000000000000..a9950434a56cbc36759799248ef819d31e133581 --- /dev/null +++ b/db/migrate/20230120100100_add_uuidboot_facet.rb @@ -0,0 +1,12 @@ +# frozen_string_literal: true + +class AddUuidbootFacet < ActiveRecord::Migration[5.1] + def change + create_table :uuidboot_host_facets do |t| + t.references :host, type: :integer, foreign_key: true, index: { unique: true } + t.uuid :uuid, null: false + + t.timestamps + end + end +end diff --git a/foreman_uuid_boot.gemspec b/foreman_uuid_boot.gemspec index 3948bb07ade91c967b2f075683c27d25b7ada614..1cd89d0f76fc2a37b6404fac4de6af9ef6c12c33 100644 --- a/foreman_uuid_boot.gemspec +++ b/foreman_uuid_boot.gemspec @@ -15,7 +15,7 @@ Gem::Specification.new do |spec| spec.homepage = 'https://github.com/ananace/foreman_uuid_boot' spec.license = 'GPL-3.0' - spec.files = Dir['{app,lib}/**/*.{rake,rb}'] + %w[LICENSE.txt Rakefile README.md] + spec.files = Dir['{app,db,lib}/**/*.{rake,rb}'] + %w[LICENSE.txt Rakefile README.md] spec.metadata['rubygems_mfa_required'] = 'true' diff --git a/lib/foreman_uuid_boot/engine.rb b/lib/foreman_uuid_boot/engine.rb index 768ab1084994c03eec1473df1eb425a372a27bfa..8d4a2e6aaca289a4ac57d8b6dab6c71d9bcfe4f2 100644 --- a/lib/foreman_uuid_boot/engine.rb +++ b/lib/foreman_uuid_boot/engine.rb @@ -6,9 +6,19 @@ module ForemanUuidBoot config.autoload_paths += Dir["#{config.root}/app/services/foreman/unattended_installation/concerns"] + initializer 'foreman_uuid_boot.load_app_instance_data' do |app| + ForemanUuidBoot::Engine.paths['db/migrate'].existent.each do |path| + app.config.paths['db/migrate'] << path + end + end + initializer 'foreman_uuid_boot.register_plugin', before: :finisher_hook do |_app| Foreman::Plugin.register :foreman_uuid_boot do - requires_foreman '>= 1.14' + requires_foreman '>= 2.5' + + register_facet ForemanUuidBoot::UuidbootHostFacet, :uuidboot_facet do + set_dependent_action :destroy + end end end