summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--Makefile2
-rw-r--r--boot-env/OpenSLX/BootEnvironment/Base.pm51
-rw-r--r--boot-env/OpenSLX/BootEnvironment/PXE.pm181
-rwxr-xr-xconfig-db/slxconfig-demuxer193
4 files changed, 284 insertions, 143 deletions
diff --git a/Makefile b/Makefile
index d63b3f3d..52c16bc4 100644
--- a/Makefile
+++ b/Makefile
@@ -159,6 +159,8 @@ supported."; \
cp os-plugins/slx* $(SLX_BUILD_PATH)$(SLX_BASE_PATH)/bin/; \
tar --exclude=.svn -cp -C lib OpenSLX \
| tar -xp -C $(SLX_BUILD_PATH)$(SLX_BASE_PATH)/lib; \
+ tar --exclude=.svn -cp -C boot-env OpenSLX \
+ | tar -xp -C $(SLX_BUILD_PATH)$(SLX_BASE_PATH)/lib; \
tar --exclude=.svn -cp -C config-db OpenSLX \
| tar -xp -C $(SLX_BUILD_PATH)$(SLX_BASE_PATH)/lib; \
tar --exclude=.svn -cp -C initramfs OpenSLX \
diff --git a/boot-env/OpenSLX/BootEnvironment/Base.pm b/boot-env/OpenSLX/BootEnvironment/Base.pm
new file mode 100644
index 00000000..3fa22666
--- /dev/null
+++ b/boot-env/OpenSLX/BootEnvironment/Base.pm
@@ -0,0 +1,51 @@
+# Copyright (c) 2008 - OpenSLX GmbH
+#
+# This program is free software distributed under the GPL version 2.
+# See http://openslx.org/COPYING
+#
+# If you have any feedback please consult http://openslx.org/feedback and
+# send your suggestions, praise, or complaints to feedback@openslx.org
+#
+# General information about OpenSLX can be found at http://openslx.org/
+# -----------------------------------------------------------------------------
+# BootEnvironment::Base.pm
+# - provides empty base of the BootEnvironment API.
+# -----------------------------------------------------------------------------
+package OpenSLX::BootEnvironment::Base;
+
+use strict;
+use warnings;
+
+our $VERSION = 1.01; # API-version . implementation-version
+
+use OpenSLX::Basics;
+use OpenSLX::ConfigDB;
+
+sub new
+{
+ my $class = shift;
+
+ my $self = {};
+
+ return bless $self, $class;
+}
+
+sub initialize
+{
+ my $self = shift;
+ my $params = shift;
+
+ $self->{'build-path'} = $params->{'build-path'};
+ $self->{'dry-run'} = $params->{'dry-run'};
+
+ return 1;
+}
+
+sub prepareBootloaderConfigFolder
+{
+ my $self = shift;
+
+ return;
+}
+
+1;
diff --git a/boot-env/OpenSLX/BootEnvironment/PXE.pm b/boot-env/OpenSLX/BootEnvironment/PXE.pm
new file mode 100644
index 00000000..dde9c29d
--- /dev/null
+++ b/boot-env/OpenSLX/BootEnvironment/PXE.pm
@@ -0,0 +1,181 @@
+# Copyright (c) 2008 - OpenSLX GmbH
+#
+# This program is free software distributed under the GPL version 2.
+# See http://openslx.org/COPYING
+#
+# If you have any feedback please consult http://openslx.org/feedback and
+# send your suggestions, praise, or complaints to feedback@openslx.org
+#
+# General information about OpenSLX can be found at http://openslx.org/
+# -----------------------------------------------------------------------------
+# BootEnvironment::PXE.pm
+# - provides PXE-specific implementation of the BootEnvironment API.
+# -----------------------------------------------------------------------------
+package OpenSLX::BootEnvironment::PXE;
+
+use strict;
+use warnings;
+
+use base qw(OpenSLX::BootEnvironment::Base);
+
+use File::Basename;
+use File::Path;
+
+use OpenSLX::Basics;
+use OpenSLX::Utils;
+
+sub prepareBootloaderConfigFolder
+{
+ my $self = shift;
+
+ my $basePath = $openslxConfig{'base-path'};
+ my $pxePath = $self->{'build-path'};
+ my $pxeConfigPath = "$pxePath/pxelinux.cfg";
+
+ if (!$self->{'dry-run'}) {
+ rmtree($pxeConfigPath);
+ mkpath($pxeConfigPath);
+
+ for my $file ('pxelinux.0', 'menu.c32', 'vesamenu.c32') {
+ if (!-e "$pxePath/$file") {
+ slxsystem(qq[cp -p "$basePath/share/tftpboot/$file" $pxePath/]);
+ }
+ }
+ }
+
+ return 1;
+}
+
+sub writeBootloaderMenuFor
+{
+ my $self = shift;
+ my $client = shift;
+ my $externalClientID = shift;
+ my $systemInfos = shift;
+
+ my $pxePath = $self->{'build-path'};
+ my $pxeConfigPath = "$pxePath/pxelinux.cfg";
+
+ my $pxeConfig = $self->_getTemplate();
+ my $pxeFile = "$pxeConfigPath/$externalClientID";
+ my $clientAppend = $client->{kernel_params} || '';
+ vlog(1, _tr("writing PXE-file %s", $pxeFile));
+
+ my $slxLabels = '';
+ foreach my $info (@$systemInfos) {
+ my $vendorOSName = $info->{'vendor-os'}->{name};
+ my $kernelName = basename($info->{'kernel-file'});
+ my $append = $info->{kernel_params};
+ $append .= " initrd=$vendorOSName/$info->{'initramfs-name'}";
+ $append .= " $clientAppend";
+ $slxLabels .= "LABEL openslx-$info->{'external-id'}\n";
+ my $label = $info->{label} || '';
+ if (!length($label) || $label eq $info->{name}) {
+ if ($info->{name} =~ m{^(.+)::(.+)$}) {
+ my $system = $1;
+ my $exportType = $2;
+ $label = $system . ' ' x (40-length($system)) . $exportType;
+ } else {
+ $label = $info->{name};
+ }
+ }
+ $slxLabels .= "\tMENU LABEL ^$label\n";
+ $slxLabels .= "\tKERNEL $vendorOSName/$kernelName\n";
+ $slxLabels .= "\tAPPEND $append\n";
+ $slxLabels .= "\tIPAPPEND 1\n";
+ my $helpText = $info->{description} || '';
+ if (length($helpText)) {
+ # make sure that text matches the given margin
+ my $margin = $openslxConfig{'pxe-theme-menu-margin'} || 0;
+ my $marginAsText = ' ' x $margin;
+ $helpText =~ s{^}{$marginAsText}gms;
+ $slxLabels .= "\tTEXT HELP\n$helpText\n\tENDTEXT\n";
+ }
+ }
+ # now add the slx-labels (inline or appended) and write the config file
+ if (!($pxeConfig =~ s{\@\@\@SLX_LABELS\@\@\@}{$slxLabels})) {
+ $pxeConfig .= $slxLabels;
+ }
+
+ # PXE uses 'cp850' (codepage 850) but our string is in utf-8, we have
+ # to convert in order to avoid showing gibberish on the client side...
+ spitFile($pxeFile, $pxeConfig, { 'io-layer' => 'encoding(cp850)' } );
+
+ return 1;
+}
+
+sub _getTemplate
+{
+ my $self = shift;
+
+ return $self->{'pxe-template'} if $self->{'pxe-template'};
+
+ my $pxeDefaultTemplate = unshiftHereDoc(<<' End-of-Here');
+ NOESCAPE 0
+ PROMPT 0
+ TIMEOUT 10
+ DEFAULT menu.c32
+ IMPLICIT 1
+ ALLOWOPTIONS 1
+ MENU TITLE Was möchten Sie tun (Auswahl mittels Cursortasten)?
+ MENU MASTER PASSWD secret
+ End-of-Here
+ utf8::decode($pxeDefaultTemplate);
+
+ my ($sec, $min, $hour, $day, $mon, $year) = (localtime);
+ $mon++;
+ $year += 1900;
+ my $callDate = sprintf('%04d-%02d-%02d', $year, $mon, $day);
+ my $callTime = sprintf('%02d:%02d:%02d', $hour, $min, $sec);
+
+ # fetch PXE-template, if any
+ my $pxeTemplate =
+ "# generated by slxconfig-demuxer (on $callDate at $callTime)\n";
+ my $pxeTemplateFile = "$openslxConfig{'config-path'}/PXE-template";
+ if (-e $pxeTemplateFile) {
+ $pxeTemplate .= slurpFile($pxeTemplateFile);
+ } else {
+ $pxeTemplate .= $pxeDefaultTemplate;
+ }
+
+ # now append (and thus override) the PXE-template with the settings of the
+ # selected PXE-theme, if any
+ my $basePath = $openslxConfig{'base-path'};
+ my $pxeTheme = $openslxConfig{'pxe-theme'};
+ if (defined $pxeTheme) {
+ my $pxeThemeConfig
+ = "$basePath/share/themes/${pxeTheme}/pxe/theme.conf";
+ if (-e $pxeThemeConfig) {
+ $pxeTemplate .= slurpFile($pxeThemeConfig);
+ }
+ }
+
+ # fetch info about margin and replace the corresponding placeholders
+ my $margin = $openslxConfig{'pxe-theme-menu-margin'} || 0;
+ my $marginAsText = ' ' x $margin;
+ $pxeTemplate =~ s{\@\@\@MENU_MARGIN\@\@\@}{$margin}g;
+ my $separatorLine = '-' x (78 - 4 - 2 * $margin);
+ $pxeTemplate =~ s{\@\@\@SEPARATOR_LINE\@\@\@}{$separatorLine}g;
+
+ # pick out the last background picture and copy it over
+ my $pic;
+ while ($pxeTemplate =~ m{^\s*MENU BACKGROUND (\S+?)\s*$}gims) {
+ chomp($pic = $1);
+ }
+ if (defined $pic) {
+ my $pxeBackground
+ = defined $pxeTheme
+ ? "$basePath/share/themes/${pxeTheme}/pxe/$pic"
+ : $pic;
+ if (-e $pxeBackground && !$self->{'dry-run'}) {
+ slxsystem(qq[cp "$pxeBackground" $self->{'build-path'}/]);
+ }
+ }
+
+ $self->{'pxe-template'} = $pxeTemplate;
+
+ return $pxeTemplate;
+}
+
+
+1;
diff --git a/config-db/slxconfig-demuxer b/config-db/slxconfig-demuxer
index 5d0928ae..3510757e 100755
--- a/config-db/slxconfig-demuxer
+++ b/config-db/slxconfig-demuxer
@@ -53,18 +53,6 @@ use OpenSLX::ConfigFolder;
use OpenSLX::MakeInitRamFS::Engine;
use OpenSLX::Utils;
-my $pxeDefaultTemplate = unshiftHereDoc(<<'End-of-Here');
- NOESCAPE 0
- PROMPT 0
- TIMEOUT 10
- DEFAULT menu.c32
- IMPLICIT 1
- ALLOWOPTIONS 1
- MENU TITLE Was möchten Sie tun (Auswahl mittels Cursortasten)?
- MENU MASTER PASSWD secret
-End-of-Here
-utf8::decode($pxeDefaultTemplate);
-
my (
$systemConfCount,
# number of system configurations written
@@ -76,6 +64,8 @@ my (
# number of initramfs that were created
@targetSystems,
# systems to create initramfs for, defaults to all systems
+ %bootEnvMap,
+ # objects encapsulating the bootloader specific configurations
%option,
# cmdline option hash
);
@@ -104,12 +94,6 @@ if ($option{versionReq}) {
exit 1;
}
-my ($sec, $min, $hour, $day, $mon, $year) = (localtime);
-$mon++;
-$year += 1900;
-my $callDate = sprintf('%04d-%02d-%02d', $year, $mon, $day);
-my $callTime = sprintf('%02d:%02d:%02d', $hour, $min, $sec);
-
openslxInit();
my $openslxDB = OpenSLX::ConfigDB->new();
@@ -149,8 +133,7 @@ my $tftpbootPath = "$openslxConfig{'public-path'}/tftpboot";
my $tftpbuildPath = "$openslxConfig{'public-path'}/tftpboot.new";
if (!$option{dryRun}) {
mkpath([$tftpbootPath]);
- rmtree("$tftpbuildPath/pxelinux.cfg");
- mkpath(["$tftpbuildPath/client-config", "$tftpbuildPath/pxelinux.cfg"]);
+ mkpath("$tftpbuildPath/client-config");
}
my $rsyncDeleteClause;
@@ -279,7 +262,7 @@ sub digestAttributes
my $attrs = $object->{attrs} || {};
my $attrsAsString
- = join ';',
+ = join ';',
map { "$_=$attrs->{$_}" }
sort
grep { defined $attrs->{$_} }
@@ -391,133 +374,55 @@ sub createTarOfPath
}
}
-################################################################################
-###
-################################################################################
-sub writePXEMenus
+sub bootEnvironmentForType
{
- my @infos = @_;
-
- my $pxePath = "$tftpbuildPath";
- my $pxeConfigPath = "$tftpbuildPath/pxelinux.cfg";
-
- if (!-e "$pxePath/pxelinux.0") {
- my $pxelinux0Path =
- "$openslxConfig{'base-path'}/share/tftpboot/pxelinux.0";
- slxsystem(qq[cp -p "$pxelinux0Path" $pxePath/]) unless $option{dryRun};
- }
- if (!-e "$pxePath/menu.c32") {
- my $menuc32Path = "$openslxConfig{'base-path'}/share/tftpboot/menu.c32";
- slxsystem(qq[cp -p "$menuc32Path" $pxePath/]) unless $option{dryRun};
- }
- if (!-e "$pxePath/vesamenu.c32") {
- my $vesamenuc32Path =
- "$openslxConfig{'base-path'}/share/tftpboot/vesamenu.c32";
- slxsystem(qq[cp -p "$vesamenuc32Path" $pxePath/]) unless $option{dryRun};
+ my $bootType = uc(shift || 'pxe');
+
+ if (!$bootEnvMap{$bootType}) {
+ my $bootEnv = instantiateClass("OpenSLX::BootEnvironment::$bootType");
+ $bootEnv->initialize( {
+ 'build-path' => $tftpbuildPath,
+ 'dry-run' => $option{dryRun},
+ } );
+ $bootEnv->prepareBootloaderConfigFolder();
+ $bootEnvMap{$bootType} = $bootEnv;
}
+
+ return $bootEnvMap{$bootType};
+}
- # fetch PXE-template, if any
- my $pxeTemplate =
- "# generated by slxconfig-demuxer (on $callDate at $callTime)\n";
- my $pxeTemplateFile = "$openslxConfig{'config-path'}/PXE-template";
- if (-e $pxeTemplateFile) {
- $pxeTemplate .= slurpFile($pxeTemplateFile);
- } else {
- $pxeTemplate .= $pxeDefaultTemplate;
- }
- # now append (and thus override) the PXE-template with the settings of the
- # selected PXE-theme, if any
- my $pxeTheme = $openslxConfig{'pxe-theme'};
- if (defined $pxeTheme) {
- my $pxeThemeConfig
- = "$openslxConfig{'base-path'}/share/themes/${pxeTheme}/pxe/theme.conf";
- if (-e $pxeThemeConfig) {
- $pxeTemplate .= slurpFile($pxeThemeConfig);
- }
- }
- # fetch info about margin and replace the corresponding placeholders
- my $margin = $openslxConfig{'pxe-theme-menu-margin'} || 0;
- my $marginAsText = ' ' x $margin;
- $pxeTemplate =~ s{\@\@\@MENU_MARGIN\@\@\@}{$margin}g;
- my $separatorLine = '-' x (78 - 4 - 2 * $margin);
- $pxeTemplate =~ s{\@\@\@SEPARATOR_LINE\@\@\@}{$separatorLine}g;
-
- # pick out the last background picture and copy it over
- my $pic;
- while ($pxeTemplate =~ m{^\s*MENU BACKGROUND (\S+?)\s*$}gims) {
- chomp($pic = $1);
- }
- if (defined $pic) {
- my $pxeBackground
- = defined $pxeTheme
- ? "$openslxConfig{'base-path'}/share/themes/${pxeTheme}/pxe/$pic"
- : $pic;
- if (-e $pxeBackground) {
- slxsystem(qq[cp "$pxeBackground" $pxePath/]) unless $option{dryRun};
- }
- }
+################################################################################
+###
+################################################################################
+sub writeBootloaderMenus
+{
+ my @infos = @_;
+ # iterate over all clients and write a bootloader configuration for each
my @clients = $openslxDB->fetchClientByFilter();
foreach my $client (@clients) {
- my $pxeConfig = $pxeTemplate;
- my $externalClientID = externalIDForClient($client);
- my $pxeFile = "$pxeConfigPath/$externalClientID";
- my $clientAppend = $client->{kernel_params} || '';
- vlog(1, _tr("writing PXE-file %s", $pxeFile));
- next if $option{dryRun};
+ # fetch all infos relevant to this client (including the bootable
+ # systems)
my %systemIDs;
@systemIDs{$openslxDB->aggregatedSystemIDsOfClient($client)} = ();
my @systemInfos = grep { exists $systemIDs{$_->{id}} } @infos;
- # now @systemInfos holds all infos relevant to this client
- my $slxLabels = '';
- foreach my $info (@systemInfos) {
- my $extID = $info->{'vendor-os'}->{name};
- my $kernelName = basename($info->{'kernel-file'});
- my $append = $info->{kernel_params};
- $append .= " initrd=$extID/$info->{'initramfs-name'}";
- $append .= " $clientAppend";
- $slxLabels .= "LABEL openslx-$info->{'external-id'}\n";
- my $label = $info->{label} || '';
- if (!length($label) || $label eq $info->{name}) {
- if ($info->{name} =~ m{^(.+)::(.+)$}) {
- my $system = $1;
- my $exportType = $2;
- $label = $system . ' ' x (40-length($system)) . $exportType;
- } else {
- $label = $info->{name};
- }
- }
- $slxLabels .= "\tMENU LABEL ^$label\n";
- $slxLabels .= "\tKERNEL $extID/$kernelName\n";
- $slxLabels .= "\tAPPEND $append\n";
- $slxLabels .= "\tIPAPPEND 1\n";
- my $helpText = $info->{description} || '';
- if (length($helpText)) {
- # make sure that text matches the given margin
- $helpText =~ s{^}{$marginAsText}gms;
- $slxLabels .= "\tTEXT HELP\n$helpText\n\tENDTEXT\n";
- }
- }
- # now add the slx-labels (inline or appended) and write the config file
- if (!($pxeConfig =~ s{\@\@\@SLX_LABELS\@\@\@}{$slxLabels})) {
- $pxeConfig .= $slxLabels;
- }
- # PXE uses 'cp850' (codepage 850) but our string is in utf-8, we have
- # to convert in order to avoid showing gibberish on the client side...
- spitFile($pxeFile, $pxeConfig, { 'io-layer' => 'encoding(cp850)' } );
+ # now write bootloader menu with all bootable systems for this client
+ my $bootEnv = bootEnvironmentForType($client->{boot_type});
+ my $externalID = externalIDForClient($client);
+ $bootEnv->writeBootloaderMenuFor($client, $externalID, \@systemInfos);
}
return;
}
sub makeInitRamFS
{
- my $info = shift;
- my $pxeVendorOSPath = shift;
+ my $info = shift;
+ my $initramfs = shift;
- vlog(1, _tr('generating initialramfs %s/initramfs', $pxeVendorOSPath));
+ vlog(1, _tr('generating initialramfs %s', $initramfs));
my $vendorOS = $info->{'vendor-os'};
my $kernelFile = basename(followLink($info->{'kernel-file'}));
@@ -528,7 +433,7 @@ sub makeInitRamFS
'attrs' => $attrs,
'export-name' => $info->{export}->{name},
'export-uri' => $info->{'export-uri'},
- 'initramfs' => "$pxeVendorOSPath/$info->{'initramfs-name'}",
+ 'initramfs' => $initramfs,
'kernel-params' => [ split ' ', ($info->{kernel_params} || '') ],
'kernel-version' => $kernelFile =~ m[-(.+)$] ? $1 : '',
'plugins' => $info->{'active-plugins'},
@@ -554,7 +459,7 @@ sub makeInitRamFS
return;
}
-sub writeSystemPXEFiles
+sub writeKernelAndInitramfsForSystem
{
my $info = shift;
@@ -563,17 +468,18 @@ sub writeSystemPXEFiles
my $kernelFile = $info->{'kernel-file'};
my $kernelName = basename($kernelFile);
- my $pxePath = "$tftpbuildPath";
- my $pxeVendorOSPath = "$pxePath/$info->{'vendor-os'}->{name}";
- mkpath $pxeVendorOSPath unless -e $pxeVendorOSPath || $option{dryRun};
+ my $vendorOSPath = "$tftpbuildPath/$info->{'vendor-os'}->{name}";
+ mkpath $vendorOSPath unless -e $vendorOSPath || $option{dryRun};
- my $targetKernel = "$pxeVendorOSPath/$kernelName";
+ my $targetKernel = "$vendorOSPath/$kernelName";
if (!-e $targetKernel) {
vlog(1, _tr('copying kernel %s to %s', $kernelFile, $targetKernel));
- slxsystem(qq[cp -p "$kernelFile" "$targetKernel"]) unless $option{dryRun};
+ slxsystem(qq[cp -p "$kernelFile" "$targetKernel"])
+ unless $option{dryRun};
}
- makeInitRamFS($info, $pxeVendorOSPath);
+ makeInitRamFS($info, "$vendorOSPath/$info->{'initramfs-name'}");
$initramfsCount++;
+
return;
}
@@ -599,14 +505,15 @@ sub writeClientConfigurationsForSystem
my @clientIDs = $openslxDB->aggregatedClientIDsOfSystem($info);
my @clients = $openslxDB->fetchClientByID(\@clientIDs);
+
foreach my $client (@clients) {
next if $client->{name} eq '<<<default>>>';
# skip default client, as it doesn't need any config-tgz
my $externalSystemID = externalIDForSystem($info);
my $externalClientName = externalConfigNameForClient($client);
- my $clientConfigPath =
- "$clientConfigPath/$externalSystemID/$externalClientName";
+ my $clientConfigPath
+ = "$clientConfigPath/$externalSystemID/$externalClientName";
# merge configurations of client, it's groups, default client and
# system and write the resulting attributes to a configuration file:
@@ -765,7 +672,7 @@ sub writeSystemConfiguration
createTarOfPath($buildPath, "default.tgz", $systemPath);
$info->{'initramfs-name'} = "initramfs-$info->{id}";
- writeSystemPXEFiles($info);
+ writeKernelAndInitramfsForSystem($info);
writeClientConfigurationsForSystem($info, $buildPath, $attrFile);
@@ -794,7 +701,7 @@ sub writeConfigurations
vlog(
0,
_tr(
- "\nlinking demuxed system %d : %s into PXE menu",
+ "\nlinking demuxed system %d : %s into bootloader menu",
$system->{id}, $system->{name}
)
);
@@ -814,7 +721,7 @@ sub writeConfigurations
$systemErrCount++;
}
}
- writePXEMenus(@infos);
+ writeBootloaderMenus(@infos);
if (defined $option{dhcpType}) {
writeDhcpConfig();
}
@@ -849,7 +756,7 @@ during boot to find out which systems to offer for booting.
If you invoke the script with one or more system names, only these systems
will be demuxed. All other systems (which are expected to have been demuxed
-before) will just be linked into the PXE menu.
+before) will just be linked into the bootloader menu.
The resulting files will be put into the OpenSLX-tftpboot-path.