diff --git a/manifests/drivers/pxe.pp b/manifests/drivers/pxe.pp index 03bf07d7..e9395654 100644 --- a/manifests/drivers/pxe.pp +++ b/manifests/drivers/pxe.pp @@ -71,8 +71,11 @@ # Defaults to $::os_service_default. # # [*uefi_pxe_bootfile_name*] -# (optional) Bootfile DHCP parameter for UEFI boot mode. -# Defaults to $::os_service_default. +# (optional) Bootfile DHCP parameter for UEFI boot mode for the +# pxe boot interface. No separate configuration template is required +# when using ipxe. +# Defaults to bootx64.efi, which will be the signed shim that loads +# grub for a network boot. # # [*uefi_pxe_config_template*] # (optional) Template file for PXE configuration for UEFI boot loader. @@ -137,7 +140,7 @@ class ironic::drivers::pxe ( $images_path = $::os_service_default, $tftp_master_path = $::os_service_default, $instance_master_path = $::os_service_default, - $uefi_pxe_bootfile_name = $::os_service_default, + $uefi_pxe_bootfile_name = 'bootx64.efi', $uefi_pxe_config_template = $::os_service_default, $uefi_ipxe_bootfile_name = 'snponly.efi', $ipxe_timeout = $::os_service_default, @@ -156,6 +159,7 @@ class ironic::drivers::pxe ( $tftp_root_real = pick($::ironic::pxe::common::tftp_root, $tftp_root) $ipxe_timeout_real = pick($::ironic::pxe::common::ipxe_timeout, $ipxe_timeout) $uefi_ipxe_bootfile_name_real = pick($::ironic::pxe::common::uefi_ipxe_bootfile_name, $uefi_ipxe_bootfile_name) + $uefi_pxe_bootfile_name_real = pick($::ironic::pxe::common::uefi_pxe_bootfile_name, $uefi_pxe_bootfile_name) if $ip_version != undef { warning('The ironic::drivers::pxe:ip_version parameter is deprecated and will be removed in the future.') @@ -174,7 +178,7 @@ class ironic::drivers::pxe ( 'pxe/images_path': value => $images_path; 'pxe/tftp_master_path': value => $tftp_master_path; 'pxe/instance_master_path': value => $instance_master_path; - 'pxe/uefi_pxe_bootfile_name': value => $uefi_pxe_bootfile_name; + 'pxe/uefi_pxe_bootfile_name': value => $uefi_pxe_bootfile_name_real; 'pxe/uefi_pxe_config_template': value => $uefi_pxe_config_template; 'pxe/uefi_ipxe_bootfile_name': value => $uefi_ipxe_bootfile_name_real; 'pxe/ipxe_timeout': value => $ipxe_timeout_real; diff --git a/manifests/params.pp b/manifests/params.pp index 82b4fc07..c24322cf 100644 --- a/manifests/params.pp +++ b/manifests/params.pp @@ -66,6 +66,10 @@ class ironic::params { $syslinux_package = 'syslinux-tftpboot' $syslinux_path = '/tftpboot' $syslinux_files = ['pxelinux.0', 'chain.c32', 'ldlinux.c32'] + $grub_efi_package = 'grub2-efi-x64' + $grub_efi_file = '/boot/efi/EFI/centos/grubx64.efi' + $shim_package = 'shim' + $shim_file = '/boot/efi/EFI/centos/shimx64.efi' } 'Debian': { $common_package_name = 'ironic-common' @@ -98,6 +102,10 @@ class ironic::params { $syslinux_path = '/var/lib/tftpboot' } $syslinux_files = ['pxelinux.0', 'chain.c32', 'libcom32.c32', 'libutil.c32'] + $grub_efi_package = 'grub-efi-amd64-signed' + $grub_efi_file = '/usr/lib/grub/x86_64-efi-signed/grubnetx64.efi.signed' + $shim_package = 'shim-signed' + $shim_file = '/usr/lib/shim/shimx64.efi.signed' } default: { fail("Unsupported osfamily: ${::osfamily} operatingsystem: ${::operatingsystem}, \ diff --git a/manifests/pxe.pp b/manifests/pxe.pp index 04c060ed..4e43a026 100644 --- a/manifests/pxe.pp +++ b/manifests/pxe.pp @@ -59,6 +59,12 @@ # driver. # Defaults to 'snponly.efi' # +# [*uefi_pxe_bootfile_name*] +# (optional) Name of efi file used to boot servers with PXE + UEFI. This +# should be consistent with the uefi_pxe_bootfile_name parameter in pxe +# driver. +# Defaults to 'bootx64.efi' +# # [*tftp_use_xinetd*] # (optional) Override wheter to use xinetd instead of dnsmasq as the tftp # service facilitator. @@ -78,6 +84,7 @@ class ironic::pxe ( $tftp_bind_host = undef, $ipxe_name_base = 'ipxe-snponly', $uefi_ipxe_bootfile_name = 'snponly.efi', + $uefi_pxe_bootfile_name = 'bootx64.efi', $tftp_use_xinetd = $::ironic::params::xinetd_available, $dnsmasq_log_facility = undef, ) inherits ironic::params { @@ -89,6 +96,7 @@ class ironic::pxe ( $http_root_real = pick($::ironic::pxe::common::http_root, $http_root) $http_port_real = pick($::ironic::pxe::common::http_port, $http_port) $uefi_ipxe_bootfile_name_real = pick($::ironic::pxe::common::uefi_ipxe_bootfile_name, $uefi_ipxe_bootfile_name) + $uefi_pxe_bootfile_name_real = pick($::ironic::pxe::common::uefi_pxe_bootfile_name, $uefi_pxe_bootfile_name) if $::os['family'] == 'RedHat' { $arch = "-${::os['architecture']}" @@ -246,6 +254,44 @@ class ironic::pxe ( tag => 'ironic-tftp-file', } + ensure_resource( 'package', 'grub-efi', { + ensure => $package_ensure, + name => $::ironic::params::grub_efi_package, + tag => ['openstack', 'ironic-support-package'], + }) + + file { "${tftp_root_real}/grubx64.efi": + ensure => 'file', + seltype => 'tftpdir_t', + owner => $::ironic::params::user, + group => $::ironic::params::group, + mode => '0744', + source => "${::ironic::params::grub_efi_file}", + backup => false, + show_diff => false, + require => Anchor['ironic-inspector::install::end'], + tag => 'ironic-tftp-file', + } + + ensure_resource( 'package', 'shim', { + ensure => $package_ensure, + name => $::ironic::params::shim_package, + tag => ['openstack', 'ironic-support-package'], + }) + + file { "${tftp_root_real}/${uefi_pxe_bootfile_name_real}": + ensure => 'file', + seltype => 'tftpdir_t', + owner => $::ironic::params::user, + group => $::ironic::params::group, + mode => '0744', + source => "${::ironic::params::shim_file}", + backup => false, + show_diff => false, + require => Anchor['ironic-inspector::install::end'], + tag => 'ironic-tftp-file', + } + File["${tftp_root_real}"] -> File<| tag == 'ironic-tftp-file' |> include apache diff --git a/manifests/pxe/common.pp b/manifests/pxe/common.pp index 712b0b71..afd0b6aa 100644 --- a/manifests/pxe/common.pp +++ b/manifests/pxe/common.pp @@ -41,12 +41,17 @@ # (optional) Name of efi file used to boot servers with iPXE + UEFI. # Defaults to undef. # +# [*uefi_pxe_bootfile_name*] +# (optional) Name of efi file used to boot servers with PXE + UEFI. +# Defaults to undef. +# class ironic::pxe::common ( $tftp_root = undef, $http_root = undef, $http_port = undef, $ipxe_timeout = undef, $uefi_ipxe_bootfile_name = undef, + $uefi_pxe_bootfile_name = undef, ) { include ironic::deps } diff --git a/releasenotes/notes/uefi_pxe_bootfile_name-eb2244dc9b9fd954.yaml b/releasenotes/notes/uefi_pxe_bootfile_name-eb2244dc9b9fd954.yaml new file mode 100644 index 00000000..bd68665d --- /dev/null +++ b/releasenotes/notes/uefi_pxe_bootfile_name-eb2244dc9b9fd954.yaml @@ -0,0 +1,12 @@ +--- +features: + - | + The pxe parameter `uefi_pxe_bootfile_name` is now managed by puppet, keeping + the ironic default of `bootx64.efi`. + + The shim EFI binary is copied to the TFTP root directory, to a file named + the value of `uefi_pxe_bootfile_name`. The grub EFI binary is copied to + the TFTP root directory to a file named `grubx64.efi`. + + With these changes, using the pxe boot driver with UEFI boot will result in + a grub network boot which is Secure Boot capable. \ No newline at end of file diff --git a/spec/classes/ironic_drivers_pxe_spec.rb b/spec/classes/ironic_drivers_pxe_spec.rb index 39ae78ae..455e7bb7 100644 --- a/spec/classes/ironic_drivers_pxe_spec.rb +++ b/spec/classes/ironic_drivers_pxe_spec.rb @@ -24,6 +24,7 @@ describe 'ironic::drivers::pxe' do let :default_params do { :uefi_ipxe_bootfile_name => 'snponly.efi', + :uefi_pxe_bootfile_name => 'bootx64.efi', } end @@ -47,9 +48,9 @@ describe 'ironic::drivers::pxe' do is_expected.to contain_ironic_config('pxe/images_path').with_value('') is_expected.to contain_ironic_config('pxe/tftp_master_path').with_value('') is_expected.to contain_ironic_config('pxe/instance_master_path').with_value('') - is_expected.to contain_ironic_config('pxe/uefi_pxe_bootfile_name').with_value('') is_expected.to contain_ironic_config('pxe/uefi_pxe_config_template').with_value('') is_expected.to contain_ironic_config('pxe/uefi_ipxe_bootfile_name').with_value('snponly.efi') + is_expected.to contain_ironic_config('pxe/uefi_pxe_bootfile_name').with_value('bootx64.efi') is_expected.to contain_ironic_config('pxe/dir_permission').with_value('') is_expected.to contain_ironic_config('pxe/file_permission').with_value('') is_expected.to contain_ironic_config('pxe/loader_file_paths').with_value('') @@ -79,8 +80,8 @@ describe 'ironic::drivers::pxe' do :images_path => '/mnt/images', :tftp_master_path => '/mnt/master_images', :instance_master_path => '/mnt/ironic/master_images', - :uefi_pxe_bootfile_name => 'bootx64.efi', :uefi_ipxe_bootfile_name => 'ipxe.efi', + :uefi_pxe_bootfile_name => 'shim-x64.efi', :uefi_pxe_config_template => 'foo-uefi', :ipxe_timeout => '60', :pxe_bootfile_name => 'bootx64', diff --git a/spec/classes/ironic_pxe_spec.rb b/spec/classes/ironic_pxe_spec.rb index 7e81d5b7..8bbb42d7 100644 --- a/spec/classes/ironic_pxe_spec.rb +++ b/spec/classes/ironic_pxe_spec.rb @@ -76,6 +76,43 @@ describe 'ironic::pxe' do ) end + it 'should contain grub-efi package' do + is_expected.to contain_package('grub-efi').with( + :ensure => 'present', + :name => platform_params[:grub_efi_package], + :tag => ['openstack', 'ironic-support-package'], + ) + end + it 'should contain PXE UEFI shim image' do + is_expected.to contain_file('/tftpboot/bootx64.efi').with( + 'owner' => 'ironic', + 'group' => 'ironic', + 'require' => 'Anchor[ironic-inspector::install::end]', + 'seltype' => 'tftpdir_t', + 'ensure' => 'file', + 'show_diff' => false, + 'backup' => false, + ) + end + it 'should contain shim package' do + is_expected.to contain_package('shim').with( + :ensure => 'present', + :name => platform_params[:shim_package], + :tag => ['openstack', 'ironic-support-package'], + ) + end + it 'should contain PXE UEFI grub image' do + is_expected.to contain_file('/tftpboot/grubx64.efi').with( + 'owner' => 'ironic', + 'group' => 'ironic', + 'require' => 'Anchor[ironic-inspector::install::end]', + 'seltype' => 'tftpdir_t', + 'ensure' => 'file', + 'show_diff' => false, + 'backup' => false, + ) + end + context 'when overriding parameters' do before :each do params.merge!( @@ -128,6 +165,29 @@ describe 'ironic::pxe' do 'backup' => false, ) end + + it 'should contain PXE UEFI shim image' do + is_expected.to contain_file('/var/lib/tftpboot/bootx64.efi').with( + 'owner' => 'ironic', + 'group' => 'ironic', + 'require' => 'Anchor[ironic-inspector::install::end]', + 'seltype' => 'tftpdir_t', + 'ensure' => 'file', + 'show_diff' => false, + 'backup' => false, + ) + end + it 'should contain PXE UEFI grub image' do + is_expected.to contain_file('/var/lib/tftpboot/grubx64.efi').with( + 'owner' => 'ironic', + 'group' => 'ironic', + 'require' => 'Anchor[ironic-inspector::install::end]', + 'seltype' => 'tftpdir_t', + 'ensure' => 'file', + 'show_diff' => false, + 'backup' => false, + ) + end end context 'when excluding syslinux' do @@ -252,14 +312,18 @@ describe 'ironic::pxe' do case facts[:osfamily] when 'Debian' { + :grub_efi_package => 'grub-efi-amd64-signed', :ipxe_package => 'ipxe', + :shim_package => 'shim-signed', :syslinux_package => 'syslinux-common', } when 'RedHat' { :dnsmasq_tftp_package => 'openstack-ironic-dnsmasq-tftp-server', :dnsmasq_tftp_service => 'openstack-ironic-dnsmasq-tftp-server', + :grub_efi_package => 'grub2-efi-x64', :ipxe_package => 'ipxe-bootimgs', + :shim_package => 'shim', :syslinux_package => 'syslinux-tftpboot', } end