Skip to content

Commit

Permalink
pxelinux: add kernel parameters in Grub2 config
Browse files Browse the repository at this point in the history
- Includes some code refactoring/cleanup
- Unit tests adjusted to test PXELINUX and Grub2 variants, including
  - pxelinux_no_append_block.t removed (superseded by write_pxelinux_config.t)
  - Several pxelinux_ks_xxx tests merged for easier maintenance (coverage
    and regexps tests are identical)
- Fixes quattor#258 (caused by a typo in the initial version of this commit)
  • Loading branch information
jouvin committed Mar 8, 2017
1 parent 995f2ee commit d83621e
Show file tree
Hide file tree
Showing 15 changed files with 426 additions and 342 deletions.
70 changes: 38 additions & 32 deletions aii-pxelinux/src/main/perl/pxelinux.pm
Original file line number Diff line number Diff line change
Expand Up @@ -40,11 +40,11 @@ use NCM::Component::PXELINUX::constants qw(:all);
Readonly my %GRUB2_VARIANT_PARAMS => (name => 'Grub2',
nbpdir_opt => NBPDIR_GRUB2,
kernel_root_path => GRUB2_EFI_KERNEL_ROOT,
format_method => \&_write_grub2_config);
format_method => '_write_grub2_config');
Readonly my %PXELINUX_VARIANT_PARAMS => (name => 'PXELINUX',
nbpdir_opt => NBPDIR_PXELINUX,
kernel_root_path => '',
format_method => \&_write_pxelinux_config);
format_method => '_write_pxelinux_config');
# Element in @VARIANT_PARAMS must be in the same order as enum PXE_VARIANT_xxx
Readonly my @VARIANT_PARAMS => (\%PXELINUX_VARIANT_PARAMS, \%GRUB2_VARIANT_PARAMS);

Expand Down Expand Up @@ -300,10 +300,10 @@ sub _pxe_network_bonding {
}


# create a list with all append options for kickstart installations
sub _pxe_ks_append
# create a list with all kernel parameters for the kickstart installation
sub _kernel_params_ks
{
my ($self, $cfg) = @_;
my ($self, $cfg, $variant) = @_;

my $pxe_config = $cfg->getElement (PXEROOT)->getTree;

Expand All @@ -329,12 +329,12 @@ sub _pxe_ks_append
my $server = hostname();
$ksloc =~ s{LOCALHOST}{$server};

my @append;
push(@append,
"ramdisk=32768",
"initrd=$pxe_config->{initrd}",
"${keyprefix}ks=$ksloc",
);
# With PXELINUX, initrd path is specified with a kernel parameter
# Parameter order is not important but is kept as "ramdisk, initrd, ks" for compatibility
# with previous AII versions for easier comparisons.
my @kernel_params = ("ramdisk=32768");
push (@kernel_params, "initrd=$pxe_config->{initrd}") if ( $variant == PXE_VARIANT_PXELINUX );
push (@kernel_params, "${keyprefix}ks=$ksloc");

my $ksdev = $pxe_config->{ksdevice};
if ($version >= ANACONDA_VERSION_EL_6_0) {
Expand All @@ -343,35 +343,35 @@ sub _pxe_ks_append
my ($bonddev, $bondingtxt) = $self->_pxe_network_bonding($cfg, $kst, $ksdev);
if ($bonddev) {
$ksdev = $bonddev;
push (@append, $bondingtxt);
push (@kernel_params, $bondingtxt);
}
}

push(@append, "$ksdevicename=$ksdev");
push(@kernel_params, "$ksdevicename=$ksdev");

if ($pxe_config->{updates}) {
push(@append,"${keyprefix}updates=$pxe_config->{updates}");
push(@kernel_params,"${keyprefix}updates=$pxe_config->{updates}");
};

if ($kst->{logging} && $kst->{logging}->{host}) {
push(@append, "${keyprefix}syslog=$kst->{logging}->{host}:$kst->{logging}->{port}");
push(@append, "${keyprefix}loglevel=$kst->{logging}->{level}") if $kst->{logging}->{level};
push(@kernel_params, "${keyprefix}syslog=$kst->{logging}->{host}:$kst->{logging}->{port}");
push(@kernel_params, "${keyprefix}loglevel=$kst->{logging}->{level}") if $kst->{logging}->{level};
}

if ($version >= ANACONDA_VERSION_EL_7_0) {
if ($kst->{enable_sshd}) {
push(@append, "${keyprefix}sshd");
push(@kernel_params, "${keyprefix}sshd");
};

if ($kst->{cmdline}) {
push(@append, "${keyprefix}cmdline");
push(@kernel_params, "${keyprefix}cmdline");
};

if ($pxe_config->{setifnames}) {
# set all interfaces names to the configured macaddress
my $nics = $cfg->getElement ("/hardware/cards/nic")->getTree;
foreach my $nic (keys %$nics) {
push (@append, "ifname=$nic:".$nics->{$nic}->{hwaddr}) if ($nics->{$nic}->{hwaddr});
push (@kernel_params, "ifname=$nic:".$nics->{$nic}->{hwaddr}) if ($nics->{$nic}->{hwaddr});
}
}

Expand All @@ -380,36 +380,36 @@ sub _pxe_ks_append
$self->error("Invalid ksdevice $ksdev for static ks configuration.");
} else {
my $static = $self->_pxe_ks_static_network($cfg, $ksdev);
push(@append,"ip=$static") if ($static);
push(@kernel_params,"ip=$static") if ($static);
}
} elsif ($kst->{bootproto} =~ m/^(dhcp6?|auto6|ibft)$/) {
push(@append,"ip=$kst->{bootproto}");
push(@kernel_params,"ip=$kst->{bootproto}");
}

my $nms = $cfg->getElement("/system/network/nameserver")->getTree;
foreach my $ns (@$nms) {
push(@append,"nameserver=$ns");
push(@kernel_params,"nameserver=$ns");
}
}

my $custom_append = $pxe_config->{append};
if ($custom_append) {
$custom_append =~ s/LOCALHOST/$server/g;
push @append, $custom_append;
push @kernel_params, $custom_append;
}

return @append;
return @kernel_params;
}

# create a list with all append options
sub _pxe_append
# create a list with all required kernel parameters, based on the configuration
sub _kernel_params
{
my ($self, $cfg) = @_;
my ($self, $cfg, $variant) = @_;

if ($cfg->elementExists(KS)) {
return $self->_pxe_ks_append($cfg);
return $self->_kernel_params_ks($cfg, $variant);
} else {
$self->error("Unclear how to create the append options. Not using any options.");
$self->error("No Kickstart-related parameters in configuration: no kernel parameters added.");
return;
}
}
Expand All @@ -423,7 +423,7 @@ sub _write_pxelinux_config
log => $self, mode => 0644);

my $appendtxt = '';
my @appendoptions = $self->_pxe_append($cfg);
my @appendoptions = $self->_kernel_params($cfg, PXE_VARIANT_PXELINUX);
$appendtxt = join(" ", "append", @appendoptions) if @appendoptions;

my $entry_label = "Install $pxe_config->{label}";
Expand Down Expand Up @@ -468,6 +468,11 @@ sub _write_grub2_config
my $kernel_path = "$kernel_root/$pxe_config->{kernel}";
my $initrd_path = "$kernel_root/$pxe_config->{initrd}";

my @kernel_params = $self->_kernel_params($cfg, PXE_VARIANT_PXELINUX);
@kernel_params = () unless @kernel_params;
my $kernel_params_text = join(' ', @kernel_params);
$kernel_params_text = ' ' . $kernel_params_text if $kernel_params_text;

my $fh = CAF::FileWriter->open ($self->_filepath ($cfg, PXE_VARIANT_GRUB2),
log => $self, mode => 0644);
print $fh <<EOF;
Expand All @@ -477,7 +482,7 @@ set default=0
set timeout=2
menuentry "Install $pxe_config->{label}" {
set root=(pxe)
$linux_cmd $kernel_path ks=$pxe_config->{kslocation} ksdevice=$pxe_config->{ksdevice}
$linux_cmd $kernel_path$kernel_params_text
$initrd_cmd $initrd_path
}
}
Expand Down Expand Up @@ -687,7 +692,8 @@ foreach my $operation (qw(configure boot rescue livecd firmware install)) {
my $variant = __PACKAGE__->$variant_constant;
if ( $self->_variant_enabled($variant) ) {
$self->verbose("Executing action '$operation' for variant ", $self->_variant_attribute('name', $variant));
$self->_variant_attribute('format_method', $variant)->($self, $cfg) if ($operation eq 'configure');
my $method = $self->_variant_attribute('format_method', $variant);
$self->$method($cfg) if ($operation eq 'configure');

unless ( $self->_pxelink ($cfg, &$cmd(), $variant) ) {
my $fqdn = $self->_get_fqdn($cfg);
Expand Down
52 changes: 52 additions & 0 deletions aii-pxelinux/src/test/perl/main_methods.t
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
use strict;
use warnings;
use Test::More;
use Test::Quattor qw(pxelinux_base_config);
use NCM::Component::PXELINUX::constants qw(:pxe_constants :pxe_commands);
use NCM::Component::pxelinux;
use CAF::FileWriter;
use CAF::Object;
use Sys::Hostname;
use Readonly;


=pod
=head1 SYNOPSIS
Tests for the public methods.
This test only assess that internal methods to be called exists (they are all mocked in the test).
Testing of internal methods called by public methods are covered by other unit tests.
Errors (undefined methods) raise exceptions that cause the test to fail.
=cut

Readonly my $NBPDIR_PXELINUX_VALUE => '/pxe/linux/conf.files';
Readonly my $NBPDIR_GRUB2_VALUE => '/grub/config_files';

# Define a few required AII options
# Normally done by aii-shellfe
our $this_app = $main::this_app;
$this_app->{CONFIG}->define(NBPDIR_PXELINUX);
$this_app->{CONFIG}->set(NBPDIR_PXELINUX, $NBPDIR_PXELINUX_VALUE);
$this_app->{CONFIG}->define(NBPDIR_GRUB2);
$this_app->{CONFIG}->set(NBPDIR_GRUB2, $NBPDIR_GRUB2_VALUE);

my $comp = NCM::Component::pxelinux->new('grub2_config');
my $cfg = get_config_for_profile('pxelinux_base_config');

# Mock methods called by public methods
my $mockpxe = Test::MockModule->new('NCM::Component::pxelinux');
$mockpxe->mock('_pxelink', 1);
$mockpxe->mock('_write_grub2_config', 1);
$mockpxe->mock('_write_pxelinux_config', 1);
$mockpxe->mock('cleanup', 1);

for my $action (@PXE_COMMANDS, 'UNCONFIGURE', 'STATUS') {
my $method = ucfirst(lc($action));
my $status = $comp->Configure($cfg);
ok($status, "$method can call the internal methods");
};

done_testing();
63 changes: 63 additions & 0 deletions aii-pxelinux/src/test/perl/pxelinux_ks_base_options.t
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
use strict;
use warnings;
use Test::More;
use Test::Quattor qw(pxelinux_ks_block);
use NCM::Component::PXELINUX::constants qw(:pxe_variants :pxe_constants);
use NCM::Component::pxelinux;
use CAF::FileWriter;
use CAF::Object;
use Sys::Hostname;
use Readonly;

=pod
=head1 SYNOPSIS
Tests for the C<_write_xxx_config> methods with the basic KS options.
=cut

Readonly my $TEST_EFI_LINUX_CMD => GRUB2_EFI_LINUX_CMD_DEFAULT;
my $test_efi_initrd_cmd = $TEST_EFI_LINUX_CMD;
$test_efi_initrd_cmd =~ s/linux/initrd/;

# Must be in the same order as variants in @PXE_VARIANTS
Readonly my @KERNEL_PARAMS_CMDS => ('append', GRUB2_EFI_LINUX_CMD_DEFAULT);
Readonly my @PXE_VARIANT_METHODS => ('_write_pxelinux_config', '_write_grub2_config');
Readonly my @VARIANT_NAMES => ('PXELINUX', 'Grub2');

our $this_app = $main::this_app;
$this_app->{CONFIG}->define(GRUB2_EFI_LINUX_CMD);
$this_app->{CONFIG}->set(GRUB2_EFI_LINUX_CMD, $TEST_EFI_LINUX_CMD);
$this_app->{CONFIG}->define(GRUB2_EFI_INITRD_CMD);
$this_app->{CONFIG}->set(GRUB2_EFI_INITRD_CMD, $test_efi_initrd_cmd);

# mock _filepath, it has this_app->option
my $fp = "target/test/pxelinux";
my $mockpxe = Test::MockModule->new('NCM::Component::pxelinux');
$mockpxe->mock('_filepath', $fp);

my $comp = NCM::Component::pxelinux->new('pxelinux_ks');
my $cfg = get_config_for_profile('pxelinux_ks_block');
my $hostname = hostname();

for my $variant_constant (@PXE_VARIANTS) {
my $variant = __PACKAGE__->$variant_constant;
my $variant_name = $VARIANT_NAMES[$variant];
my $config_method = $PXE_VARIANT_METHODS[$variant];
my $kernel_params_cmd = $KERNEL_PARAMS_CMDS[$variant];

$comp->$config_method($cfg);
my $fh = get_file($fp);

like($fh, qr{^\s{4}$kernel_params_cmd.*?\sramdisk=32768(\s|$)}m, "append ramdisk (variant=$variant_name)");
if ( $variant == PXE_VARIANT_PXELINUX ) {
like($fh, qr{^\s{4}$kernel_params_cmd.*?\sinitrd=path/to/initrd(\s|$)}m, "append initrd (variant=$variant_name)");
};
like($fh, qr{^\s{4}$kernel_params_cmd.*?\sks=http://server/ks(\s|$)}m, "append ks url(variant=$variant_name)");
like($fh, qr{^\s{4}$kernel_params_cmd.*?\sksdevice=eth0(\s|$)}m, "append ksdevice(variant=$variant_name)");
like($fh, qr{^\s{4}$kernel_params_cmd.*?\supdates=http://somewhere/somthing/updates.img(\s|$)}m, "append ksdevice(variant=$variant_name)");
like($fh, qr{^\s{4}$kernel_params_cmd.*?\sinst.stage2=http://$hostname/stage2.img}m, "hostname substitution in append(variant=$variant_name)");
};

done_testing();
42 changes: 0 additions & 42 deletions aii-pxelinux/src/test/perl/pxelinux_ks_block.t

This file was deleted.

Loading

0 comments on commit d83621e

Please sign in to comment.