From 7043bffef52e7f7404a09d4de3919de915e5de70 Mon Sep 17 00:00:00 2001 From: Oliver Tappe Date: Mon, 1 Sep 2008 21:51:20 +0000 Subject: * implemented PREBOOT_CD boot environment that creates an appropriate ISO image git-svn-id: http://svn.openslx.org/svn/openslx/openslx/trunk@2181 95ad53e4-c205-0410-b2fa-d234c58c8868 --- Makefile | 4 +- boot-env/OpenSLX/BootEnvironment/Base.pm | 6 +- boot-env/OpenSLX/BootEnvironment/PREBOOT_CD.pm | 179 +++++++++++++++++++++ boot-env/OpenSLX/MakeInitRamFS/Engine/PrebootCD.pm | 103 ++++++++++++ config-db/slxconfig-demuxer | 9 +- 5 files changed, 291 insertions(+), 10 deletions(-) create mode 100644 boot-env/OpenSLX/MakeInitRamFS/Engine/PrebootCD.pm diff --git a/Makefile b/Makefile index b65dc377..e96086db 100644 --- a/Makefile +++ b/Makefile @@ -192,8 +192,8 @@ supported."; \ tar -xp -C $(SLX_BUILD_PATH)$(SLX_BASE_PATH)/share; \ tar --exclude=.svn -cp -C initramfs uclib-rootfs | \ tar -xp -C $(SLX_BUILD_PATH)$(SLX_BASE_PATH)/share; \ - tar --exclude=.svn --exclude *.example -cp -C boot-env pxe | \ - tar -xp -C $(SLX_BUILD_PATH)$(SLX_BASE_PATH)/share/boot-env; \ + tar --exclude=.svn --exclude *.example --exclude OpenSLX -cp boot-env | \ + tar -xp -C $(SLX_BUILD_PATH)$(SLX_BASE_PATH)/share/; \ cp -p boot-env/pxe/menu-template.example \ $(SLX_BUILD_PATH)$(SLX_CONFIG_PATH)/boot-env/pxe/; \ cp -a installer/default_files/machine-setup.default \ diff --git a/boot-env/OpenSLX/BootEnvironment/Base.pm b/boot-env/OpenSLX/BootEnvironment/Base.pm index 50969f26..5e966374 100644 --- a/boot-env/OpenSLX/BootEnvironment/Base.pm +++ b/boot-env/OpenSLX/BootEnvironment/Base.pm @@ -83,7 +83,6 @@ sub writeFilesRequiredForBooting my $self = shift; my $info = shift; my $buildPath = shift; - my $slxVersion = shift; my $kernelFile = $info->{'kernel-file'}; my $kernelName = basename($kernelFile); @@ -112,7 +111,7 @@ sub writeFilesRequiredForBooting } else { vlog(1, _tr('generating initialramfs %s', $initramfsName)); - $self->_makeInitRamFS($info, $initramfsName, $slxVersion); + $self->_makeInitRamFS($info, $initramfsName); $initramfsMap{$initramfsID} = { file => $initramfsName, kernel_params => $info->{kernel_params}, @@ -126,13 +125,14 @@ sub _makeInitRamFS my $self = shift; my $info = shift; my $initramfs = shift; - my $slxVersion = shift; my $vendorOS = $info->{'vendor-os'}; my $kernelFile = basename(followLink($info->{'kernel-file'})); my $attrs = clone($info->{attrs} || {}); + chomp(my $slxVersion = qx{slxversion}); + my $params = { 'attrs' => $attrs, 'export-name' => $info->{export}->{name}, diff --git a/boot-env/OpenSLX/BootEnvironment/PREBOOT_CD.pm b/boot-env/OpenSLX/BootEnvironment/PREBOOT_CD.pm index 84c43d06..994e6dd0 100644 --- a/boot-env/OpenSLX/BootEnvironment/PREBOOT_CD.pm +++ b/boot-env/OpenSLX/BootEnvironment/PREBOOT_CD.pm @@ -18,10 +18,12 @@ use warnings; use base qw(OpenSLX::BootEnvironment::Base); +use Clone qw(clone); use File::Basename; use File::Path; use OpenSLX::Basics; +use OpenSLX::MakeInitRamFS::Engine::PrebootCD; use OpenSLX::Utils; sub initialize @@ -43,4 +45,181 @@ sub initialize return 1; } +sub finalize +{ + my $self = shift; + my $delete = shift; + + return if !$self->{prebootSystemInfo}; + + return $self->SUPER::finalize($delete); +} + +sub writeBootloaderMenuFor +{ + my $self = shift; + my $client = shift; + my $externalClientID = shift; + my $systemInfos = shift || []; + + my $prebootSystemInfo = clone($systemInfos->[0]); + $self->_createImage($client, $prebootSystemInfo); + +# $self->_prepareBootloaderConfigFolder() +# unless $self->{preparedBootloaderConfigFolder}; +# +# my $pxePath = $self->{'target-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)); +# +# # set label for each system +# foreach my $info (@$systemInfos) { +# 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}; +# } +# } +# $info->{label} = $label; +# } +# my $slxLabels = ''; +# 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->{kernel_params}; +# $append .= " initrd=$vendorOSName/$info->{'initramfs-name'}"; +# $append .= " $clientAppend"; +# $slxLabels .= "LABEL openslx-$info->{'external-id'}\n"; +# $slxLabels .= "\tMENU LABEL ^$info->{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 _createImage +{ + my $self = shift; + my $client = shift; + my $info = shift; + + vlog( + 0, + _tr( + "\ncreating CD-image for client %s (based on %s) ...", + $client->{name}, $info->{name} + ) + ); + + my $imageDir = "$openslxConfig{'public-path'}/images/$client->{name}"; + mkpath($imageDir) unless $self->{'dry-run'}; + + # copy static data and init script + my $dataDir = "$openslxConfig{'base-path'}/share/boot-env/preboot-cd"; + slxsystem(qq{rsync -rlpt $dataDir/ "$imageDir/"}) + unless $self->{'dry-run'}; + + # copy kernel (take the one from the given system info) + my $kernelFile = $info->{'kernel-file'}; + my $kernelName = basename($kernelFile); + slxsystem(qq{cp -p "$kernelFile" "$imageDir/iso/isolinux/vmlinuz"}) + unless $self->{'dry-run'}; + + # create initramfs + my $initramfsName = qq{"$imageDir/iso/isolinux/initramfs"}; + $self->_makePrebootInitRamFS($info, $initramfsName); + + my $mkisoCmd = unshiftHereDoc(<<" End-of-Here"); + mkisofs + -o "$imageDir/../$client->{name}.iso" + -b isolinux/isolinux.bin -no-emul-boot -boot-load-size 4 + -r -J -l -boot-info-table -joliet-long + -publisher "OpenSLX Project - http://www.openslx.org" + -p "OpenSLX Project - openslx-devel\@openslx.org" + -V "OpenSLX BootCD" + -volset "OpenSLX Project - PreBoot CD for non PXE/TFTP start of a Linux Stateless Client" + -c isolinux/boot.cat "$imageDir/iso" + End-of-Here + $mkisoCmd =~ s{\n\s*}{ }gms; + my $logFile = "$imageDir/../$client->{name}.iso.log"; + if (slxsystem(qq{$mkisoCmd 2>"$logFile"})) { + my $log = slurpFile($logFile); + die _tr("unable to create ISO-image - log follows:\n%s", $log); + } + + rmtree($imageDir); + + return 1; +} + +sub _makePrebootInitRamFS +{ + my $self = shift; + my $info = shift; + my $initramfs = shift; + + my $vendorOS = $info->{'vendor-os'}; + my $kernelFile = basename(followLink($info->{'kernel-file'})); + + my $attrs = clone($info->{attrs} || {}); + + chomp(my $slxVersion = qx{slxversion}); + + my $params = { + 'attrs' => $attrs, + 'export-name' => undef, + 'export-uri' => undef, + 'initramfs' => $initramfs, + 'kernel-params' => [ split ' ', ($info->{kernel_params} || '') ], + 'kernel-version' => $kernelFile =~ m[-(.+)$] ? $1 : '', + 'plugins' => '', + 'root-path' + => "$openslxConfig{'private-path'}/stage1/$vendorOS->{name}", + 'slx-version' => $slxVersion, + 'system-name' => $info->{name}, + }; + + # TODO: make debug-level an explicit attribute, it's used in many places! + my $kernelParams = $info->{kernel_params} || ''; + if ($kernelParams =~ m{debug(?:=(\d+))?}) { + my $debugLevel = defined $1 ? $1 : '1'; + $params->{'debug-level'} = $debugLevel; + } + + my $makeInitRamFSEngine + = OpenSLX::MakeInitRamFS::Engine::PrebootCD->new($params); + $makeInitRamFSEngine->execute($self->{'dry-run'}); + + # copy back kernel-params, as they might have been changed (by plugins) + $info->{kernel_params} = join ' ', $makeInitRamFSEngine->kernelParams(); + + return; +} + 1; diff --git a/boot-env/OpenSLX/MakeInitRamFS/Engine/PrebootCD.pm b/boot-env/OpenSLX/MakeInitRamFS/Engine/PrebootCD.pm new file mode 100644 index 00000000..72d9087d --- /dev/null +++ b/boot-env/OpenSLX/MakeInitRamFS/Engine/PrebootCD.pm @@ -0,0 +1,103 @@ +# Copyright (c) 2006-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/ +# ----------------------------------------------------------------------------- +# MakeInitialRamFS::Engine::PrebootCD.pm +# - provides driver engine for MakeInitialRamFS API, implementing the +# preboot behaviour applicable for CDs. +# ----------------------------------------------------------------------------- +package OpenSLX::MakeInitRamFS::Engine::PrebootCD; + +use strict; +use warnings; + +use base qw(OpenSLX::MakeInitRamFS::Engine::Base); + +use File::Find; + +use OpenSLX::Basics; +use OpenSLX::Utils; + +################################################################################ +### implementation methods +################################################################################ +sub _collectCMDs +{ + my $self = shift; + + $self->{CMDs} = []; + + $self->_setupBuildPath(); + + $self->_writeInitramfsSetup(); + $self->_writeSlxSystemConf(); + + $self->_copyUclibcRootfs(); + + $self->{distro}->applyChanges($self); + + $self->_copyKernelModules(); + + $self->_createInitRamFS(); + + return; +} + +sub _setupBuildPath +{ + my $self = shift; + + my $buildPath = "$openslxConfig{'temp-path'}/slx-initramfs"; + $self->addCMD("rm -rf $buildPath"); + + my @stdFolders = qw( + bin + dev + etc + lib + mnt + proc + root + sbin + sys + tmp + var/lib + var/run + ); + $self->addCMD( + 'mkdir -p ' . join(' ', map { "$buildPath/$_"; } @stdFolders) + ); + + $self->{'build-path'} = $buildPath; + + return; +} + +sub _copyUclibcRootfs +{ + my $self = shift; + + my $uclibcRootfs = "$openslxConfig{'base-path'}/share/uclib-rootfs"; + + my @excludes = qw( + ); + + # exclude strace unless this system is in debug mode + if (!$self->{'debug-level'}) { + push @excludes, 'strace'; + } + + my $exclOpts = join ' ', map { "--exclude $_" } @excludes; + + $self->addCMD("rsync $exclOpts -rlpt $uclibcRootfs/ $self->{'build-path'}"); + + return 1; +} + +1; diff --git a/config-db/slxconfig-demuxer b/config-db/slxconfig-demuxer index 3803a65c..7234b762 100755 --- a/config-db/slxconfig-demuxer +++ b/config-db/slxconfig-demuxer @@ -110,8 +110,6 @@ if (createConfigFolderForDefaultSystem()) { ); } -chomp(my $slxVersion = qx{slxversion}); - # protect against parallel executions of this script my $criticalSection = OpenSLX::ScopedResource->new({ name => 'osplugin::session', @@ -575,9 +573,8 @@ sub createBootEnvironmentsForSystem vlog(0, _tr("creating boot environment for $bootType")); my $bootEnv = bootEnvironmentForType($bootType); - $initramfsCount += $bootEnv->writeFilesRequiredForBooting( - $info, $buildPath, $slxVersion - ); + $initramfsCount + += $bootEnv->writeFilesRequiredForBooting($info, $buildPath); my $systemPath = "$bootEnv->{'target-path'}/client-config/$info->{'external-id'}"; @@ -686,6 +683,8 @@ sub writeConfigurations $systemErrCount++; } } + my $imageBaseDir = "$openslxConfig{'public-path'}/images"; + rmtree($imageBaseDir) unless $option{dryRun}; writeBootloaderMenus(@infos); if (defined $option{dhcpType}) { writeDhcpConfig(); -- cgit v1.2.3-55-g7522