Skip to content

Commit

Permalink
aii-core: add new options to support Grub2-based PXE loader
Browse files Browse the repository at this point in the history
- nbpdir_grub, installation-kernel-root, grub2_efi_linux_cmd
- Options added commented-out in the default aii-shellfe.conf
- aii-core now has a dependency on aii-pxelinux constants: build order
  modified in pom.xml
- Contributes to quattor#216
  • Loading branch information
jouvin committed Mar 2, 2017
1 parent 2810a18 commit 786c11c
Show file tree
Hide file tree
Showing 10 changed files with 188 additions and 26 deletions.
21 changes: 21 additions & 0 deletions aii-core/src/main/eg/aii-shellfe.conf
Original file line number Diff line number Diff line change
Expand Up @@ -15,3 +15,24 @@
# The default is profile_ for backward compatibility
# Comment this out when not prefix is needed
profile_prefix = profile_

# Directory on TFTP server where PXELINUX configuration files are.
# Must be an absolute path or 'none' to disable PXELINUX configuration.
# nbpdir = /osinstall/nbp/pxelinux.cfg

# Directory on TFTP server where Grub2 PXE configuration files are.
# Must be an absolute path or none to disable Grub2 PXE configuration.
# Default value is based on 'npbdir' option (used for PXELINUX) if defined,
# with last path token replaced by 'grub-efi'. If 'nbpdir' is not defined
# (or 'none') the default value is '/osinstall/nbp/grub-efi'.
# nbpdir_grub2 =


# Parent directory for the installation kernel/initrd to use with Grub2 EFI.
# Must be an absolute path (starting with /), relative to TFTP server root directory.
# Default value is based on 'nbpdir_grub2' with first and last path tokens removed
# (if 'nbpdir_grub2' is /a/b/c/d, 'grub2_efi_kernel_root' will be '/b/c').
# grub2_efi_kernel_root =

# Grub2 command to use to load the installation kernel.
# grub2_efi_linux_cmd = linuxefi
102 changes: 77 additions & 25 deletions aii-core/src/main/perl/Shellfe.pm
Original file line number Diff line number Diff line change
Expand Up @@ -27,12 +27,14 @@ use XML::Simple;
use EDG::WP4::CCM::Fetch;
use EDG::WP4::CCM::CCfg;
use File::Path qw(mkpath rmtree);
use File::Basename qw(basename);
use File::Basename qw(basename dirname);
use DB_File;
use Readonly;
use Parallel::ForkManager 0.7.6;

our $profiles_info = undef;
use AII::DHCP;
use NCM::Component::PXELINUX::constants qw(:pxe_constants);
use 5.10.1;

use constant MODULEBASE => 'NCM::Component::';
Expand All @@ -54,28 +56,28 @@ use constant TIMEOUT => 60;
use constant PARTERR_ST => 16;
use constant COMMANDS => qw (remove configure install boot rescue firmware livecd status);
use constant INCLUDE => 'include';
use constant NBPDIR => 'nbpdir';
use constant CONFIGURE => 'Configure';
use constant INSTALLMETHOD => 'Install';
use constant BOOTMETHOD => 'Boot';
use constant REMOVEMETHOD => 'Unconfigure';
use constant STATUSMETHOD => 'Status';
use constant RESCUEMETHOD => 'Rescue';
use constant FIRMWAREMETHOD => 'Firmware';
use constant LIVECDMETHOD => 'Livecd';
use constant CAFILE => 'ca_file';
use constant CADIR => 'ca_dir';
use constant KEY => 'key_file';
use constant CERT => 'cert_file';

use constant HWCARDS => '/hardware/cards/nic';
use constant DHCPCFG => "/usr/sbin/aii-dhcp";
use constant HWCARDS => '/hardware/cards/nic';
use constant DHCPCFG => "/usr/sbin/aii-dhcp";
use constant DHCPOPTION => '/system/aii/dhcp/options';
use constant DHCPPATH => '/system/aii/dhcp';
use constant MAC => '--mac';
use constant DHCPPATH => '/system/aii/dhcp';
use constant MAC => '--mac';

# Actual method associated with various actions
use constant CONFIGURE => 'Configure';
use constant INSTALLMETHOD => 'Install';
use constant BOOTMETHOD => 'Boot';
use constant REMOVEMETHOD => 'Unconfigure';
use constant STATUSMETHOD => 'Status';
use constant RESCUEMETHOD => 'Rescue';
use constant FIRMWAREMETHOD => 'Firmware';
use constant LIVECDMETHOD => 'Livecd';

# Keep in sync with the help string of $PROTECTED_OPTION
Readonly our $PROTECTED_COMMANDS => 'remove|configure|(re)?install';
Readonly our $PROTECTED_COMMANDS => 'remove|configure|(re)?install';
Readonly our $PROTECTED_OPTION => 'confirm';

use parent qw (CAF::Application CAF::Reporter);
Expand Down Expand Up @@ -250,18 +252,33 @@ sub app_options
DEFAULT => '/etc/aii/aii-dhcp.conf' },

# Options for NBP plug-ins
{ NAME => 'nbpdir=s',
HELP => 'Directory where files for NBP should be stored',
DEFAULT => '/osinstall/nbp/pxelinux.cfg' },
{ NAME => NBPDIR_PXELINUX.'=s',
HELP => 'Directory where files for PXELINUX NBP should be stored',
DEFAULT => OSINSTALL_DEF_ROOT_PATH . OSINSTALL_DEF_PXELINUX_DIR },

{ NAME => 'bootconfig=s',
# Default value for nbpdir_grub2 will be computed based on nbpdir
{ NAME => NBPDIR_GRUB2.'=s',
HELP => 'Directory where files for Grub2 NBP should be stored',
DEFAULT => undef },

{ NAME => LOCALBOOT.'=s',
HELP => 'Generic "boot from local disk" file',
DEFAULT => 'localboot.cfg' },
DEFAULT => LOCAL_BOOT_CONFIG_FILE },

{ NAME => GRUB2_EFI_LINUX_CMD.'=s',
HELP => 'Grub2 command to use for loading the kernel',
DEFAULT => GRUB2_EFI_LINUX_CMD_DEFAULT },

{ NAME => 'rescueconfig=s',
HELP => 'Generic "boot from rescue image" file',
DEFAULT => 'rescue.cfg' },
# Options for HTTPS
# Default value for grub2_efi_kernel_root will be computed based on nbpdir
{ NAME => GRUB2_EFI_KERNEL_ROOT.'=s',
HELP => 'Parent path for the directories containing installation kernel/initrd',
DEFAULT => undef },

{ NAME => 'rescueconfig=s',
HELP => 'Generic "boot from rescue image" file',
DEFAULT => 'rescue.cfg' },

# Options for HTTPS
{ NAME => CAFILE.'=s',
HELP => 'Certificate file for the CA' },

Expand Down Expand Up @@ -323,6 +340,41 @@ sub _initialize
if ($self->option(INCLUDE)) {
unshift(@INC, split(/:+/, $self->option(INCLUDE)));
}

# Initialization and validation of some options whose default values are based on other options
if ( $self->option(NBPDIR_PXELINUX) ) {
$self->{CONFIG}->set(NBPDIR_PXELINUX, undef) if $self->option(NBPDIR_PXELINUX) eq NBPDIR_VARIANT_DISABLED;
}
if ( $self->option(NBPDIR_GRUB2) ) {
$self->{CONFIG}->set(NBPDIR_GRUB2, undef) if $self->option(NBPDIR_GRUB2) eq NBPDIR_VARIANT_DISABLED;
} else {
if ( $self->option(NBPDIR_PXELINUX) ) {
my $efi_dir = dirname($self->option(NBPDIR_PXELINUX)) . OSINSTALL_DEF_GRUB2_DIR;
$self->{CONFIG}->set(NBPDIR_GRUB2, $efi_dir);
} else {
$self->{CONFIG}->set(NBPDIR_GRUB2, OSINSTALL_DEF_ROOT_PATH . OSINSTALL_DEF_GRUB2_DIR);
}
}
if ( !$self->option(GRUB2_EFI_KERNEL_ROOT) ) {
if ( $self->option(NBPDIR_GRUB2) ) {
my $kernel_root = dirname($self->option(NBPDIR_GRUB2));
$kernel_root =~ s/^\/\w+//;
$kernel_root = '' if ( $kernel_root eq '/' );
$self->{CONFIG}->set(GRUB2_EFI_KERNEL_ROOT, $kernel_root);
}
}
# GRUB2_EFI_INITRD_CMD is always derived from GRUB2_EFI_LINUX_CMD as
# Grub2 has a set of linux/initrd command pairs that must match together.
if ( $self->option(GRUB2_EFI_LINUX_CMD) ) {
my $initrd_cmd = $self->option(GRUB2_EFI_LINUX_CMD);
$initrd_cmd =~ s/linux/initrd/;
if ( $initrd_cmd eq $self->option(GRUB2_EFI_LINUX_CMD) ) {
$self->error("Commands to load the kernel and initrd are identical ($initrd_cmd)");
}
$self->{CONFIG}->define(GRUB2_EFI_INITRD_CMD);
$self->{CONFIG}->set(GRUB2_EFI_INITRD_CMD, $initrd_cmd);
}

return $self;
}

Expand Down
1 change: 1 addition & 0 deletions aii-core/src/test/perl/NCM/Component/PXELINUX/constants.pm
79 changes: 79 additions & 0 deletions aii-core/src/test/perl/grub2_efi_options.t
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
use strict;
use warnings;
use CAF::Application;
use Test::Quattor;
use Test::More;
use NCM::Component::PXELINUX::constants qw(:pxe_constants);
use AII::Shellfe;
use Readonly;
use File::Basename qw(basename);

my $logfile_name = basename(__FILE__);
$logfile_name =~ s/\.t$//;

Readonly my $AII_CONFIG_EMPTY => 'src/test/resources/aii-empty.conf';
Readonly my $AII_CONFIG_NBPDIR => 'src/test/resources/aii-nbpdir.conf';
Readonly my $AII_CONFIG_GRUB2_ONLY => 'src/test/resources/aii-grub2_only.conf';
Readonly my $AII_CONFIG_PXELINUX_GRUB2 => 'src/test/resources/aii-pxelinux_grub2.conf';
Readonly my $AII_CONFIG_PXELINUX_ONLY => 'src/test/resources/aii-pxelinux_only.conf';
Readonly my $AII_LOG_FILE => "target/test/$logfile_name.log";
Readonly::Array my @SHELLFE_DEFAULT_OPTIONS => ('--logfile', $AII_LOG_FILE);

sub check_option_values {
my ($config_file, $test_name, $nbdir_grub2_expected, $grub2_efi_linux_cmd_expected, $grub2_efi_kernel_root_expected) = @_;

my @opts = (@SHELLFE_DEFAULT_OPTIONS, '--cfgfile', $config_file);
our $this_app = AII::Shellfe->new ($0, @opts);

is($this_app->option("nbpdir_grub2"),
$nbdir_grub2_expected,
"expected default value for option nbpdir_grub2 ($test_name)");
is($this_app->option("grub2_efi_linux_cmd"),
$grub2_efi_linux_cmd_expected,
"expected default value for option grub2_efi_linux_cmd ($test_name)");
if ( defined($grub2_efi_linux_cmd_expected) ) {
# Value derived from $grub2_efi_linux_cmd_expected (copied from Shellfe.pm)
my $grub2_efi_initrd_cmd_expected = $grub2_efi_linux_cmd_expected;
$grub2_efi_initrd_cmd_expected =~ s/linux/initrd/;
# If both are identical, it means that $grub2_efi_linux_cmd_expected is not a valid kernel (linux) command
isnt($grub2_efi_initrd_cmd_expected, $grub2_efi_linux_cmd_expected, "kernel and initrd commands are different");
is($this_app->option("grub2_efi_initrd_cmd"),
$grub2_efi_initrd_cmd_expected,
"expected default value for option grub2_efi_initrd_cmd ($test_name)");
}
is($this_app->option("grub2_efi_kernel_root"),
$grub2_efi_kernel_root_expected,
"expected default value for option grub2_efi_kernel_root ($test_name)");

}

# Be sure that the directory for logs exists
mkdir 'target/test';

check_option_values ($AII_CONFIG_EMPTY,
'empty config file',
OSINSTALL_DEF_ROOT_PATH.OSINSTALL_DEF_GRUB2_DIR,
GRUB2_EFI_LINUX_CMD_DEFAULT,
'/nbp');
check_option_values ($AII_CONFIG_NBPDIR,
'nbpdir defined',
'/tftp/boot/quattor/grub-efi',
GRUB2_EFI_LINUX_CMD_DEFAULT,
'/boot/quattor');
check_option_values ($AII_CONFIG_GRUB2_ONLY,
'Grub2 only',
OSINSTALL_DEF_ROOT_PATH.OSINSTALL_DEF_GRUB2_DIR,
GRUB2_EFI_LINUX_CMD_DEFAULT,
'/nbp');
check_option_values ($AII_CONFIG_PXELINUX_GRUB2,
'PXELINUX + Grub2',
'/tftp/boot/quattor/grub.config',
'linux',
'/tftp/boot/kernels');
check_option_values ($AII_CONFIG_PXELINUX_ONLY,
'PXELINUX only',
undef,
GRUB2_EFI_LINUX_CMD_DEFAULT,
undef);

done_testing();
Empty file.
1 change: 1 addition & 0 deletions aii-core/src/test/resources/aii-grub2_only.conf
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
nbpdir = none
1 change: 1 addition & 0 deletions aii-core/src/test/resources/aii-nbpdir.conf
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
nbpdir = /tftp/boot/quattor/pxelinux-config
4 changes: 4 additions & 0 deletions aii-core/src/test/resources/aii-pxelinux_grub2.conf
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
nbpdir = /tftp/boot/quattor/pxelinux-config
nbpdir_grub2 = /tftp/boot/quattor/grub.config
grub2_efi_linux_cmd = linux
grub2_efi_kernel_root = /tftp/boot/kernels
2 changes: 2 additions & 0 deletions aii-core/src/test/resources/aii-pxelinux_only.conf
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
nbpdir = /tftp/boot/quattor/pxelinux-config
nbpdir_grub2 = none
3 changes: 2 additions & 1 deletion pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -16,10 +16,11 @@
<url>https://github.com/quattor/aii</url>
</scm>
<modules>
<!-- aii-pxelinux must be built first as aii-core has a dependency on its contants -->
<module>aii-pxelinux</module>
<module>aii-core</module>
<module>aii-dhcp</module>
<module>aii-ks</module>
<module>aii-pxelinux</module>
</modules>
<build>
<pluginManagement>
Expand Down

0 comments on commit 786c11c

Please sign in to comment.