Support use of dnsmasq as tftp service

Switches to using the new ironic-dnsmasq-tftp-server service[1], which
manages the dnsmasq process in order to facilitate standalone usage and
testing of puppet-ironic outside with Centos-Stream 9 where package
changes are anticipated.

On Centos-Stream 9, users should effectively be forced over to using
dnsmasq automatically.

The higher level controls for defaults can also be changed for
the purpose of backporting such that prior releases are not
automatically switch to using dnsmasq unless they have to be run with
dnsmasq based upon known package availability.

Note that just setting tftp_use_xinetd=false in an existing deployment
doesn't remove the xinetd service completely, because of limitation
caused by current implementation of puppet-xinetd, and users are
responsible to remove service, package and etc properly before
switching to the new service.

[1] https://review.rdoproject.org/r/c/openstack/ironic-distgit/+/34691

Change-Id: I5d388acfb96fa3e3a555a119ff72feabdd1cdf87
This commit is contained in:
Julia Kreger 2021-06-23 07:56:24 -07:00 committed by Takashi Kajinami
parent c5e8504355
commit f2dd0d3cc5
5 changed files with 177 additions and 29 deletions

View File

@ -41,6 +41,8 @@ class ironic::params {
$api_service = 'openstack-ironic-api' $api_service = 'openstack-ironic-api'
$conductor_package = 'openstack-ironic-conductor' $conductor_package = 'openstack-ironic-conductor'
$conductor_service = 'openstack-ironic-conductor' $conductor_service = 'openstack-ironic-conductor'
$dnsmasq_tftp_package = 'openstack-ironic-dnsmasq-tftp-server'
$dnsmasq_tftp_service = 'openstack-ironic-dnsmasq-tftp-server'
$inspector_package = 'openstack-ironic-inspector' $inspector_package = 'openstack-ironic-inspector'
$inspector_dnsmasq_package = 'openstack-ironic-inspector-dnsmasq' $inspector_dnsmasq_package = 'openstack-ironic-inspector-dnsmasq'
$inspector_service = 'openstack-ironic-inspector' $inspector_service = 'openstack-ironic-inspector'
@ -50,7 +52,13 @@ class ironic::params {
$ipxe_rom_dir = '/usr/share/ipxe' $ipxe_rom_dir = '/usr/share/ipxe'
$ironic_wsgi_script_path = '/var/www/cgi-bin/ironic' $ironic_wsgi_script_path = '/var/www/cgi-bin/ironic'
$ironic_wsgi_script_source = '/usr/bin/ironic-api-wsgi' $ironic_wsgi_script_source = '/usr/bin/ironic-api-wsgi'
if (Integer.new($::os['release']['major']) > 8) {
$xinetd_available = false
$tftpd_package = false
} else {
$xinetd_available = true
$tftpd_package = 'tftp-server' $tftpd_package = 'tftp-server'
}
$ipxe_package = 'ipxe-bootimgs' $ipxe_package = 'ipxe-bootimgs'
$syslinux_package = 'syslinux-tftpboot' $syslinux_package = 'syslinux-tftpboot'
$syslinux_path = '/tftpboot' $syslinux_path = '/tftpboot'
@ -62,6 +70,8 @@ class ironic::params {
$api_package = 'ironic-api' $api_package = 'ironic-api'
$conductor_service = 'ironic-conductor' $conductor_service = 'ironic-conductor'
$conductor_package = 'ironic-conductor' $conductor_package = 'ironic-conductor'
$dnsmasq_tftp_package = false
$dnsmasq_tftp_service = false
$inspector_package = 'ironic-inspector' $inspector_package = 'ironic-inspector'
$inspector_dnsmasq_package = false $inspector_dnsmasq_package = false
$inspector_service = 'ironic-inspector' $inspector_service = 'ironic-inspector'
@ -75,6 +85,7 @@ class ironic::params {
$ipxe_rom_dir = '/usr/lib/ipxe' $ipxe_rom_dir = '/usr/lib/ipxe'
$ironic_wsgi_script_path = '/usr/lib/cgi-bin/ironic' $ironic_wsgi_script_path = '/usr/lib/cgi-bin/ironic'
$ironic_wsgi_script_source = '/usr/bin/ironic-api-wsgi' $ironic_wsgi_script_source = '/usr/bin/ironic-api-wsgi'
$xinetd_available = true
$tftpd_package = 'tftpd' $tftpd_package = 'tftpd'
$ipxe_package = 'ipxe' $ipxe_package = 'ipxe'
$syslinux_package = 'syslinux-common' $syslinux_package = 'syslinux-common'

View File

@ -44,7 +44,7 @@
# Defaults to '$::ironic::params::syslinux_files' # Defaults to '$::ironic::params::syslinux_files'
# #
# [*tftp_bind_host*] # [*tftp_bind_host*]
# (optional) The IP address xinetd will listen on for TFTP. # (optional) The IP address TFTP server will listen on for TFTP.
# Defaults to undef (listen on all ip addresses). # Defaults to undef (listen on all ip addresses).
# #
# [*enable_ppc64le*] # [*enable_ppc64le*]
@ -63,6 +63,11 @@
# driver. # driver.
# Defaults to 'snponly.efi' # Defaults to 'snponly.efi'
# #
# [*tftp_use_xinetd*]
# (optional) Override wheter to use xinetd instead of dnsmasq as the tftp
# service facilitator.
# Defaults to ironic::params::xinetd_available
#
class ironic::pxe ( class ironic::pxe (
$package_ensure = 'present', $package_ensure = 'present',
$tftp_root = '/tftpboot', $tftp_root = '/tftpboot',
@ -73,7 +78,8 @@ class ironic::pxe (
$tftp_bind_host = undef, $tftp_bind_host = undef,
$enable_ppc64le = false, $enable_ppc64le = false,
$ipxe_name_base = 'ipxe-snponly', $ipxe_name_base = 'ipxe-snponly',
$uefi_ipxe_bootfile_name = 'snponly.efi' $uefi_ipxe_bootfile_name = 'snponly.efi',
$tftp_use_xinetd = $::ironic::params::xinetd_available
) inherits ironic::params { ) inherits ironic::params {
include ironic::deps include ironic::deps
@ -101,7 +107,8 @@ class ironic::pxe (
ensure_resource( 'package', 'ironic-common', { ensure_resource( 'package', 'ironic-common', {
ensure => $package_ensure, ensure => $package_ensure,
name => $::ironic::params::common_package_name, name => $::ironic::params::common_package_name,
tag => ['openstack', 'ironic-package'],}) tag => ['openstack', 'ironic-package'],
})
file { "${tftp_root_real}/pxelinux.cfg": file { "${tftp_root_real}/pxelinux.cfg":
ensure => 'directory', ensure => 'directory',
@ -132,6 +139,11 @@ class ironic::pxe (
before => Anchor['ironic::config::end'], before => Anchor['ironic::config::end'],
} }
if $tftp_use_xinetd {
if ! $::ironic::params::xinetd_available {
fail('xinetd is not available in this distro. Please use tftp_use_xinetd=false')
}
ensure_resource( 'package', 'tftp-server', { ensure_resource( 'package', 'tftp-server', {
'ensure' => $package_ensure, 'ensure' => $package_ensure,
'name' => $::ironic::params::tftpd_package, 'name' => $::ironic::params::tftpd_package,
@ -139,6 +151,7 @@ class ironic::pxe (
}) })
$options = "--map-file ${tftp_root_real}/map-file" $options = "--map-file ${tftp_root_real}/map-file"
include xinetd include xinetd
xinetd::service { 'tftp': xinetd::service { 'tftp':
@ -157,7 +170,43 @@ class ironic::pxe (
file { "${tftp_root_real}/map-file": file { "${tftp_root_real}/map-file":
ensure => 'present', ensure => 'present',
content => "r ^([^/]) ${tftp_root_real}/\\1", content => "r ^([^/]) ${tftp_root_real}/\\1",
tag => 'ironic-tftp-file', }
} else {
if ! $::ironic::params::dnsmasq_tftp_package {
fail('ironic-dnsmasq-tftp-server is not available in this distro. Please use tftp_use_xnetd=true')
}
# NOTE(tkajinam): We can't use puppet-xinetd for cleanup because the xinetd
# class forcefully installs the xinetd package.
warning('Any prior xinetd based tftp server should be disabled and removed from the system.')
file { "${tftp_root_real}/map-file":
ensure => 'absent',
}
package { 'dnsmasq-tftp-server':
ensure => $package_ensure,
name => $::ironic::params::dnsmasq_tftp_package,
tag => ['openstack', 'ironic-ipxe', 'ironic-support-package'],
}
file { '/etc/ironic/dnsmasq-tftp-server.conf':
ensure => 'present',
mode => '0644',
owner => 'root',
group => 'root',
content => template('ironic/dnsmasq_tftp_server.erb'),
}
service { 'dnsmasq-tftp-server':
ensure => 'running',
name => $::ironic::params::dnsmasq_tftp_service,
enable => true,
hasstatus => true,
subscribe => File['/etc/ironic/dnsmasq-tftp-server.conf'],
}
Package['dnsmasq-tftp-server'] ~> Service['dnsmasq-tftp-server']
} }
if $syslinux_path { if $syslinux_path {

View File

@ -0,0 +1,8 @@
---
features:
- |
The new ``ironic::pxe::tftp_use_xinetd`` parameter has been added. When
this parameter is set to ``false``, the ironic-dnsmasq-tftp-server service,
which actually manages a dnsmasq process, is used instead of xinetd, to
implement TFTP server. Note that the dnsmasq service is currently available
only in RDO.

View File

@ -120,12 +120,28 @@ describe 'ironic::pxe' do
'backup' => false, 'backup' => false,
) )
end end
it 'should setup tftp xinetd service' do
is_expected.to contain_class('xinetd')
is_expected.to contain_xinetd__service('tftp').with(
'port' => '69',
'protocol' => 'udp',
'server_args' => '--map-file /var/lib/tftpboot/map-file /var/lib/tftpboot',
'server' => '/usr/sbin/in.tftpd',
'socket_type' => 'dgram',
'cps' => '100 2',
'per_source' => '11',
'wait' => 'yes',
'subscribe' => 'Anchor[ironic::install::end]',
)
end
it 'should setup tftp xinetd service' do it 'should setup tftp xinetd service' do
is_expected.to contain_xinetd__service('tftp').with( is_expected.to contain_xinetd__service('tftp').with(
'bind' => '1.2.3.4', 'bind' => '1.2.3.4',
) )
end end
end end
context 'when excluding syslinux' do context 'when excluding syslinux' do
before :each do before :each do
params.merge!( params.merge!(
@ -158,6 +174,47 @@ describe 'ironic::pxe' do
end end
end end
shared_examples_for 'ironic pxe in RedHat' do
let :p do
default_params.merge(params)
end
context 'when xinetd is disabled' do
before :each do
params.merge!(
:tftp_use_xinetd => false,
)
end
it 'should configure dnsmasq-tftp-server' do
is_expected.to contain_file('/etc/ironic/dnsmasq-tftp-server.conf').with(
'ensure' => 'present',
'mode' => '0644',
'owner' => 'root',
'group' => 'root',
)
is_expected.to contain_package('dnsmasq-tftp-server').with(
'ensure' => 'present',
'name' => platform_params[:dnsmasq_tftp_package],
'tag' => ['openstack', 'ironic-ipxe', 'ironic-support-package'],
)
is_expected.to contain_service('dnsmasq-tftp-server').with(
'ensure' => 'running',
'name' => platform_params[:dnsmasq_tftp_service],
'enable' => true,
'hasstatus' => true,
)
end
it 'should not enable xinetd' do
is_expected.to_not contain_package('tftp-server')
is_expected.to_not contain_class('xinetd')
is_expected.to_not contain_xinetd__service('tftp')
is_expected.to contain_file('/tftpboot/map-file').with_ensure('absent')
end
end
end
on_supported_os({ on_supported_os({
:supported_os => OSDefaults.get_supported_os :supported_os => OSDefaults.get_supported_os
}).each do |os,facts| }).each do |os,facts|
@ -166,8 +223,23 @@ describe 'ironic::pxe' do
facts.merge!(OSDefaults.get_facts()) facts.merge!(OSDefaults.get_facts())
end end
let(:platform_params) do
case facts[:osfamily]
when 'Debian'
{}
when 'RedHat'
{ :dnsmasq_tftp_package => 'openstack-ironic-dnsmasq-tftp-server',
:dnsmasq_tftp_service => 'openstack-ironic-dnsmasq-tftp-server' }
end
end
# TODO(tkajinam): This should be refactored before we add support for
# CentOS9, because xinetd is not available in CentOS9
it_behaves_like 'ironic pxe' it_behaves_like 'ironic pxe'
if facts[:osfamily] == 'RedHat'
it_behaves_like 'ironic pxe in RedHat'
end
end end
end end

View File

@ -0,0 +1,8 @@
# Configuration for a dnsmasq based TFTP service
port=0
bind-interfaces
enable-tftp
tftp-root=<%= @tftp_root_real %>
<% if @tftp_bind_host -%>
listen-address=<%= @tftp_bind_host %>
<% end -%>