From 416ab8a37f1b07dc9f6c0fb3ff1a8ff2036510b5 Mon Sep 17 00:00:00 2001 From: Sebastian Schmelzer Date: Thu, 2 Sep 2010 17:50:49 +0200 Subject: change dir structure --- src/boot-env/OpenSLX/BootEnvironment/Preboot.pm | 209 ++++++++++++++++++++++++ 1 file changed, 209 insertions(+) create mode 100644 src/boot-env/OpenSLX/BootEnvironment/Preboot.pm (limited to 'src/boot-env/OpenSLX/BootEnvironment/Preboot.pm') diff --git a/src/boot-env/OpenSLX/BootEnvironment/Preboot.pm b/src/boot-env/OpenSLX/BootEnvironment/Preboot.pm new file mode 100644 index 00000000..b06de7d2 --- /dev/null +++ b/src/boot-env/OpenSLX/BootEnvironment/Preboot.pm @@ -0,0 +1,209 @@ +# 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::Preboot.pm +# - provides general preboot implementation of the BootEnvironment API. +# ----------------------------------------------------------------------------- +package OpenSLX::BootEnvironment::Preboot; + +use strict; +use warnings; + +use base qw(OpenSLX::BootEnvironment::Base); + +use Clone qw(clone); +use File::Basename; +use File::Path; + +use OpenSLX::Basics; +use OpenSLX::ConfigDB qw(:support); +use OpenSLX::Utils; + +sub initialize +{ + my $self = shift; + my $params = shift; + + return if !$self->SUPER::initialize($params); + + $self->{'original-path'} = "$openslxConfig{'public-path'}/preboot"; + $self->{'target-path'} = "$openslxConfig{'public-path'}/preboot.new"; + + $self->{'requires-default-client-config'} = 0; + # we do not need a default.tgz since there's always an explicit client + + if (!$self->{'dry-run'}) { + mkpath([$self->{'original-path'}]); + rmtree($self->{'target-path'}); + mkpath("$self->{'target-path'}/client-config"); + } + + return 1; +} + +sub writeBootloaderMenuFor +{ + my $self = shift; + my $client = shift; + my $externalClientID = shift; + my $systemInfos = shift || []; + + $self->_prepareBootloaderConfigFolder() + unless $self->{preparedBootloaderConfigFolder}; + + my $prebootSystemInfo + = clone($self->_pickSystemWithNewestKernel($systemInfos)); + + $self->_createImages($client, $prebootSystemInfo); + + my $externalClientName = externalConfigNameForClient($client); + my $bootloaderPath = "$self->{'target-path'}/bootloader"; + my $bootloaderConfigPath = "$bootloaderPath/$externalClientName"; + mkpath($bootloaderConfigPath) unless $self->{'dry-run'}; + my $menuFile = "$bootloaderConfigPath/bootmenu.dialog"; + + my $clientAppend = $client->{attrs}->{kernel_params_client} || ''; + vlog(1, _tr("writing bootmenu %s", $menuFile)); + + # set label for each system + foreach my $info (@$systemInfos) { + my $label = $info->{label} || ''; + if (!length($label) || $label eq $info->{name}) { + $label = $info->{name}; + } + $info->{label} = $label; + } + my $bootmenuEntries = ''; + my $entryState = 'on'; + my $counter = 1; + foreach my $info (sort { $a->{label} cmp $b->{label} } @$systemInfos) { + my $vendorOSName = $info->{'vendor-os'}->{name}; + my $kernelName = basename($info->{'kernel-file'}); + my $append = $info->{attrs}->{kernel_params} || ''; + $append .= " $clientAppend"; + $bootmenuEntries .= qq{ "$counter" "$info->{label}" }; + $entryState = 'off'; + + # create a file containing the boot-configuration for this system + my $systemDescr = unshiftHereDoc(<<" End-of-Here"); + label="$info->{label}" + kernel="$vendorOSName/$kernelName" + initramfs="$vendorOSName/$info->{'initramfs-name'}" + append="$append" + End-of-Here + my $systemFile = "$bootloaderConfigPath/$info->{name}"; + spitFile( + $systemFile, $systemDescr, { 'io-layer' => 'encoding(iso8859-1)' } + ) unless $self->{'dry-run'}; + slxsystem(qq{ln -sf $info->{name} $bootloaderConfigPath/$counter}); + $counter++; + } + + my $entryCount = @$systemInfos; + my $bootmenu = unshiftHereDoc(<<" End-of-Here"); + --no-cancel --menu "OpenSLX Boot Menu" 20 65 $entryCount $bootmenuEntries + End-of-Here + + if (!$self->{'dry-run'}) { + # default to iso encoding, let's see how uclibc copes with it ... + spitFile($menuFile, $bootmenu, { 'io-layer' => 'encoding(iso8859-1)' }); + + # copy the preboot script into the folder to be tared + my $prebootBasePath + = "$openslxConfig{'base-path'}/share/boot-env/preboot"; + slxsystem(qq{cp $prebootBasePath/preboot.sh $bootloaderConfigPath/}); + slxsystem(qq{cp -r $prebootBasePath/preboot-scripts $bootloaderConfigPath/}); + slxsystem(qq{chmod a+x $bootloaderConfigPath/preboot.sh}); + + # create a tar which can/will be downloaded by prebooting clients + my $tarCMD + = qq{cd $bootloaderConfigPath; tar -czf "${bootloaderConfigPath}.env" *}; + slxsystem($tarCMD); + rmtree($bootloaderConfigPath); + } + + return 1; +} + +sub _createImages +{ + my $self = shift; + my $client = shift; + my $info = shift; + + my %mediaMap = ( + 'cd' => 'CD', + ); + my $prebootMedia = $client->{attrs}->{preboot_media} || ''; + if (!$prebootMedia) { + warn _tr( + "no preboot-media defined for client %s, no images will be generated!", + $client->{name} + ); + return 0; + } + foreach my $mediumName (split m{, }, $prebootMedia) { + my $moduleName = $mediaMap{$mediumName} + or die _tr( + "'%s' is not one of the supported preboot-medias (cd)", + $mediumName + ); + + my $prebootMedium = instantiateClass( + "OpenSLX::BootEnvironment::Preboot::$moduleName" + ); + $prebootMedium->initialize($self); + $prebootMedium->createImage($client, $info); + } + + return 1; +} + +sub _prepareBootloaderConfigFolder +{ + my $self = shift; + + my $bootloaderPath = "$self->{'target-path'}/bootloader"; + if (!$self->{'dry-run'}) { + rmtree($bootloaderPath); + mkpath($bootloaderPath); + } + + $self->{preparedBootloaderConfigFolder} = 1; + + return 1; +} + +sub _pickSystemWithNewestKernel +{ + my $self = shift; + my $systemInfos = shift; + + my $systemWithNewestKernel; + my $newestKernelFileSortKey = ''; + foreach my $system (@$systemInfos) { + next unless $system->{'kernel-file'} =~ m{ + (?:vmlinuz|x86)-(\d+)\.(\d+)\.(\d+)(?:\.(\d+))?-(\d+(?:\.\d+)?) + }x; + my $sortKey + = sprintf("%02d.%02d.%02d.%02d-%2.1f", $1, $2, $3, $4||0, $5); + if ($newestKernelFileSortKey lt $sortKey) { + $systemWithNewestKernel = $system; + $newestKernelFileSortKey = $sortKey; + } + } + + if (!defined $systemWithNewestKernel) { + die _tr("unable to pick a system to be used for preboot!"); + } + return $systemWithNewestKernel; +} + +1; -- cgit v1.2.3-55-g7522