mirror of
https://github.com/xcat2/xcat-core.git
synced 2026-05-06 00:59:13 +00:00
Preserve OPAL conf-file handling for Kea
This commit is contained in:
@@ -660,10 +660,12 @@ sub _render_subnet4 {
|
||||
$rendered{'next-server'} = _first_defined( $subnet->{'next-server'}, $subnet->{next_server} );
|
||||
$rendered{'boot-file-name'} = _first_defined( $subnet->{'boot-file-name'}, $subnet->{boot_file_name} );
|
||||
$rendered{'option-data'} = _first_defined( $subnet->{'option-data'}, $subnet->{option_data} );
|
||||
$rendered{'require-client-classes'} = _first_defined( $subnet->{'require-client-classes'}, $subnet->{require_client_classes} );
|
||||
$rendered{reservations} = $subnet->{reservations} if $subnet->{reservations};
|
||||
delete $rendered{'next-server'} unless defined $rendered{'next-server'};
|
||||
delete $rendered{'boot-file-name'} unless defined $rendered{'boot-file-name'};
|
||||
delete $rendered{'option-data'} unless defined $rendered{'option-data'};
|
||||
delete $rendered{'require-client-classes'} unless defined $rendered{'require-client-classes'};
|
||||
|
||||
if ( $subnet->{pools} ) {
|
||||
$rendered{pools} = $subnet->{pools};
|
||||
|
||||
@@ -37,7 +37,7 @@ sub kea_client_classes {
|
||||
},
|
||||
{
|
||||
name => 'xcat-ppc64',
|
||||
test => '(option[93].hex == 0x000c or option[93].hex == 0x000e)',
|
||||
test => 'option[93].hex == 0x000c',
|
||||
'boot-file-name' => '/boot/grub2/grub2.ppc',
|
||||
},
|
||||
{
|
||||
|
||||
@@ -2388,6 +2388,7 @@ sub kea_build_dhcp4_intent
|
||||
|
||||
my @routes = kea_ipv4_routes(@vnets);
|
||||
my @subnets;
|
||||
my @opal_classes;
|
||||
my $id = 1;
|
||||
foreach my $route (@routes) {
|
||||
my ( $net, $netif, $mask, $flags ) = @$route;
|
||||
@@ -2406,6 +2407,7 @@ sub kea_build_dhcp4_intent
|
||||
|
||||
my $subnet = kea_subnet4_intent($nettab, $net, $mask, $interface, $remote, $id, $httpport);
|
||||
return $subnet if $subnet->{error};
|
||||
push @opal_classes, @{ delete $subnet->{client_classes} || [] };
|
||||
push @subnets, $subnet;
|
||||
$id++;
|
||||
}
|
||||
@@ -2416,7 +2418,7 @@ sub kea_build_dhcp4_intent
|
||||
valid_lifetime => kea_dhcp_lease_time(),
|
||||
'option-def' => kea_option_defs(),
|
||||
'option-data' => kea_global_option_data(),
|
||||
'client-classes' => kea_boot_client_classes(),
|
||||
'client-classes' => [ @{ kea_boot_client_classes() }, @opal_classes ],
|
||||
subnets => \@subnets,
|
||||
};
|
||||
|
||||
@@ -2765,6 +2767,7 @@ sub kea_subnet4_intent
|
||||
push @option_data, { name => 'domain-search', data => $domainstring } if $domainstring;
|
||||
|
||||
my $prefix = kea_mask_to_prefix($mask);
|
||||
my $opal_class = kea_opal_client_class($net, $prefix, $tftp, $httpport);
|
||||
my %subnet = (
|
||||
id => $id,
|
||||
subnet => "$net/$prefix",
|
||||
@@ -2773,10 +2776,36 @@ sub kea_subnet4_intent
|
||||
next_server => $tftp,
|
||||
);
|
||||
$subnet{interface} = $interface unless $remote;
|
||||
if ($opal_class) {
|
||||
$subnet{'require-client-classes'} = [ $opal_class->{name} ];
|
||||
$subnet{client_classes} = [$opal_class];
|
||||
}
|
||||
|
||||
return \%subnet;
|
||||
}
|
||||
|
||||
sub kea_opal_client_class
|
||||
{
|
||||
my ( $net, $prefix, $tftp, $httpport ) = @_;
|
||||
|
||||
return unless $net && defined($prefix) && $tftp;
|
||||
|
||||
my $class_name = "xcat-opal-v3-$net-$prefix";
|
||||
$class_name =~ s/[^A-Za-z0-9_.-]/_/g;
|
||||
|
||||
return {
|
||||
name => $class_name,
|
||||
test => 'option[93].hex == 0x000e',
|
||||
'only-if-required' => JSON::true,
|
||||
'option-data' => [
|
||||
{
|
||||
name => 'conf-file',
|
||||
data => "http://$tftp:$httpport/tftpboot/pxelinux.cfg/p/" . $net . "_" . $prefix,
|
||||
},
|
||||
],
|
||||
};
|
||||
}
|
||||
|
||||
sub kea_expand_request_nodes
|
||||
{
|
||||
my ( $req, $opt ) = @_;
|
||||
|
||||
@@ -19,6 +19,8 @@ sub usage{
|
||||
print " dhcphelper -r|--rm -m|--mac <mac address> [ -a|--ip <ip address>] [ -n|--name <node name>]\n";
|
||||
print " delete the dhcp lease of specified <mac>,<ip address> and <node name>\n";
|
||||
print "\n";
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
my $help;
|
||||
@@ -46,7 +48,7 @@ if($help){
|
||||
}
|
||||
|
||||
mkdir "/tmp/xcat" unless -d "/tmp/xcat";
|
||||
open(my $dhcplockfd, ">", "/tmp/xcat/dhcplock") or die "Unable to lock DHCP state: $!";
|
||||
open(my $dhcplockfd, ">", "/tmp/xcat/dhcplock") or die "Unable to lock DHCP state: $!"; ## no critic (InputOutput::RequireBriefOpen)
|
||||
flock($dhcplockfd, LOCK_EX);
|
||||
|
||||
my $config4 = $backend->load_dhcp4_config();
|
||||
@@ -103,41 +105,38 @@ if($help){
|
||||
exit 1;
|
||||
}
|
||||
|
||||
my $omshell;
|
||||
open($omshell, '|-', '/bin/sh', '-c', '/usr/bin/omshell >/dev/null')
|
||||
or die "Unable to start omshell: $!";
|
||||
print $omshell "key "
|
||||
. $id . " \""
|
||||
. $passwd . "\"\n";
|
||||
print $omshell "connect\n";
|
||||
my $omshell_commands = "key " . $id . " \"" . $passwd . "\"\n";
|
||||
$omshell_commands .= "connect\n";
|
||||
|
||||
if($hostname){
|
||||
print $omshell "new host\n";
|
||||
print $omshell
|
||||
"set name = \"$hostname\"\n"; #Find and destroy conflict name
|
||||
print $omshell "open\n";
|
||||
print $omshell "remove\n";
|
||||
print $omshell "close\n";
|
||||
$omshell_commands .= "new host\n";
|
||||
$omshell_commands .= "set name = \"$hostname\"\n"; #Find and destroy conflict name
|
||||
$omshell_commands .= "open\n";
|
||||
$omshell_commands .= "remove\n";
|
||||
$omshell_commands .= "close\n";
|
||||
}
|
||||
|
||||
if ($mac)
|
||||
{
|
||||
print $omshell "new host\n";
|
||||
print $omshell "set hardware-address = " . $mac
|
||||
. "\n"; #find and destroy mac conflict
|
||||
print $omshell "open\n";
|
||||
print $omshell "remove\n";
|
||||
print $omshell "close\n";
|
||||
$omshell_commands .= "new host\n";
|
||||
$omshell_commands .= "set hardware-address = " . $mac . "\n"; #find and destroy mac conflict
|
||||
$omshell_commands .= "open\n";
|
||||
$omshell_commands .= "remove\n";
|
||||
$omshell_commands .= "close\n";
|
||||
}
|
||||
|
||||
if($ip){
|
||||
print $omshell "new host\n";
|
||||
print $omshell
|
||||
"set ip-address = $ip\n"; #find and destroy ip conflict
|
||||
print $omshell "open\n";
|
||||
print $omshell "remove\n";
|
||||
print $omshell "close\n";
|
||||
$omshell_commands .= "new host\n";
|
||||
$omshell_commands .= "set ip-address = $ip\n"; #find and destroy ip conflict
|
||||
$omshell_commands .= "open\n";
|
||||
$omshell_commands .= "remove\n";
|
||||
$omshell_commands .= "close\n";
|
||||
}
|
||||
|
||||
my $omshell;
|
||||
open($omshell, '|-', '/bin/sh', '-c', '/usr/bin/omshell >/dev/null')
|
||||
or die "Unable to start omshell: $!";
|
||||
print $omshell $omshell_commands;
|
||||
close($omshell);
|
||||
}else{
|
||||
&usage;
|
||||
|
||||
@@ -13,7 +13,6 @@ is( scalar @$fallback_classes, 4, 'Kea boot policy omits xNBA classes when xNBA
|
||||
my %fallback_by_name = map { $_->{name} => $_ } @$fallback_classes;
|
||||
is( $fallback_by_name{'xcat-bios'}{'boot-file-name'}, 'pxelinux.0', 'BIOS clients fall back to pxelinux.0 without xNBA loaders' );
|
||||
ok( !exists $fallback_by_name{'xcat-xnba-bios'}, 'xNBA user-class is not advertised without xNBA kpxe' );
|
||||
like( $fallback_by_name{'xcat-ppc64'}{test}, qr/0x000e/, 'POWER class covers OPAL-v3 client architecture' );
|
||||
|
||||
my $classes = xCAT::DHCP::BootPolicy->kea_client_classes(xnba_kpxe => 1, xnba_efi => 1);
|
||||
is( scalar @$classes, 5, 'Kea boot policy renders expected xNBA client classes' );
|
||||
@@ -26,8 +25,7 @@ like( $by_name{'xcat-uefi-x64'}{test}, qr/0x0009/, 'UEFI x64 class matches archi
|
||||
like( $by_name{'xcat-uefi-x64'}{test}, qr/not \(\(option\[77\]\.exists/, 'generic UEFI class excludes xNBA second-stage clients' );
|
||||
is( $by_name{'xcat-aarch64'}{'boot-file-name'}, 'boot/grub2/grub2.aarch64', 'AArch64 clients receive grub2 boot file' );
|
||||
is( $by_name{'xcat-ppc64'}{'boot-file-name'}, '/boot/grub2/grub2.ppc', 'POWER clients receive grub2 Open Firmware boot file' );
|
||||
like( $by_name{'xcat-ppc64'}{test}, qr/0x000c/, 'POWER class matches existing POWER architecture id' );
|
||||
like( $by_name{'xcat-ppc64'}{test}, qr/0x000e/, 'POWER class matches OPAL-v3 architecture id' );
|
||||
is( $by_name{'xcat-ppc64'}{test}, 'option[93].hex == 0x000c', 'POWER class keeps existing POWER architecture id' );
|
||||
|
||||
my $xnba_classes = xCAT::DHCP::BootPolicy->kea_xnba_node_classes(
|
||||
xnba_efi => 1,
|
||||
|
||||
@@ -32,6 +32,14 @@ my $json = $backend->render_dhcp4_config(
|
||||
test => "(option[77].exists and (option[77].text == 'xNBA' or option[77].hex == 0x784e4241 or substring(option[77].hex,1,4) == 'xNBA')) and option[93].hex == 0x0000 and pkt4.mac == 0x525400123456",
|
||||
'boot-file-name' => 'http://192.168.122.1:80/tftpboot/xcat/xnba/nodes/node01',
|
||||
},
|
||||
{
|
||||
name => 'xcat-opal-v3-192.168.122.0-24',
|
||||
test => 'option[93].hex == 0x000e',
|
||||
'only-if-required' => JSON::true,
|
||||
'option-data' => [
|
||||
{ name => 'conf-file', data => 'http://192.168.122.1:80/tftpboot/pxelinux.cfg/p/192.168.122.0_24' },
|
||||
],
|
||||
},
|
||||
{
|
||||
name => 'xcat-uefi-x64',
|
||||
test => "(option[93].hex == 0x0007 or option[93].hex == 0x0009) and not ((option[77].exists and (option[77].text == 'xNBA' or option[77].hex == 0x784e4241 or substring(option[77].hex,1,4) == 'xNBA')))",
|
||||
@@ -56,6 +64,7 @@ my $json = $backend->render_dhcp4_config(
|
||||
subnet => '192.168.122.0/24',
|
||||
dynamicrange => '192.168.122.100-192.168.122.120',
|
||||
next_server => '192.168.122.1',
|
||||
'require-client-classes' => ['xcat-opal-v3-192.168.122.0-24'],
|
||||
option_data => [
|
||||
{ name => 'routers', data => '192.168.122.1' },
|
||||
{ name => 'domain-name', data => 'cluster.test' },
|
||||
|
||||
@@ -22,6 +22,7 @@ my $json = $backend->render_dhcp4_config(
|
||||
interface => 'eth0',
|
||||
dynamicrange => '10.0.0.100-10.0.0.120;10.0.0.130,10.0.0.140',
|
||||
next_server => '10.0.0.1',
|
||||
'require-client-classes' => ['xcat-opal-v3-10.0.0.0-24'],
|
||||
option_data => [
|
||||
{ name => 'routers', data => '10.0.0.1' },
|
||||
{ name => 'domain-name-servers', data => '10.0.0.2, 10.0.0.3' },
|
||||
@@ -42,6 +43,14 @@ my $json = $backend->render_dhcp4_config(
|
||||
test => 'option[93].hex == 0x0007',
|
||||
'boot-file-name' => 'xcat/xnba.efi',
|
||||
},
|
||||
{
|
||||
name => 'xcat-opal-v3-10.0.0.0-24',
|
||||
test => 'option[93].hex == 0x000e',
|
||||
'only-if-required' => JSON::true,
|
||||
'option-data' => [
|
||||
{ name => 'conf-file', data => 'http://10.0.0.1/tftpboot/pxelinux.cfg/p/10.0.0.0_24' },
|
||||
],
|
||||
},
|
||||
],
|
||||
}
|
||||
);
|
||||
@@ -76,6 +85,11 @@ is_deeply(
|
||||
],
|
||||
'subnet option-data is preserved'
|
||||
);
|
||||
is_deeply(
|
||||
$subnet->{'require-client-classes'},
|
||||
['xcat-opal-v3-10.0.0.0-24'],
|
||||
'subnet requests second-pass OPAL class evaluation for subnet-specific conf-file'
|
||||
);
|
||||
|
||||
is_deeply(
|
||||
$subnet->{reservations},
|
||||
@@ -97,8 +111,16 @@ is_deeply(
|
||||
test => 'option[93].hex == 0x0007',
|
||||
'boot-file-name' => 'xcat/xnba.efi',
|
||||
},
|
||||
{
|
||||
name => 'xcat-opal-v3-10.0.0.0-24',
|
||||
test => 'option[93].hex == 0x000e',
|
||||
'only-if-required' => JSON::true,
|
||||
'option-data' => [
|
||||
{ name => 'conf-file', data => 'http://10.0.0.1/tftpboot/pxelinux.cfg/p/10.0.0.0_24' },
|
||||
],
|
||||
},
|
||||
],
|
||||
'client classes are preserved'
|
||||
'client classes are preserved, including subnet-specific OPAL conf-file class'
|
||||
);
|
||||
|
||||
my $empty_boot_json = $backend->render_dhcp4_config(
|
||||
|
||||
Reference in New Issue
Block a user