From c44835d6a46e2febe548a522881f70254ad20db8 Mon Sep 17 00:00:00 2001 From: Oliver Tappe Date: Wed, 3 Jun 2009 21:56:14 +0000 Subject: Refactored implementation of preboot evironment to support the creation of several preboot media from a single preboot client: * added new client attribute preboot_media which holds the list of media that shall be created for that preboot client (currently, only 'cd' is known) * the boot_type value 'preboot_cd' has been renamed to 'preboot' * db-schema has been bumped to 0.36 to adjust the db-contents to the new expectations * adjusted config-demuxer accordingly git-svn-id: http://svn.openslx.org/svn/openslx/openslx/trunk@2929 95ad53e4-c205-0410-b2fa-d234c58c8868 --- boot-env/OpenSLX/BootEnvironment/Preboot.pm | 92 ++++++++----------- boot-env/OpenSLX/BootEnvironment/Preboot/Base.pm | 100 +++++++++++++++++++++ boot-env/OpenSLX/BootEnvironment/Preboot/CD.pm | 108 ++++++++++++++++++++++ boot-env/OpenSLX/BootEnvironment/PrebootCD.pm | 109 ----------------------- config-db/OpenSLX/AttributeRoster.pm | 25 ++++-- config-db/OpenSLX/DBSchema.pm | 19 +++- config-db/slxconfig-demuxer | 14 +-- 7 files changed, 291 insertions(+), 176 deletions(-) create mode 100644 boot-env/OpenSLX/BootEnvironment/Preboot/Base.pm create mode 100644 boot-env/OpenSLX/BootEnvironment/Preboot/CD.pm delete mode 100644 boot-env/OpenSLX/BootEnvironment/PrebootCD.pm diff --git a/boot-env/OpenSLX/BootEnvironment/Preboot.pm b/boot-env/OpenSLX/BootEnvironment/Preboot.pm index 84853777..888e32ba 100644 --- a/boot-env/OpenSLX/BootEnvironment/Preboot.pm +++ b/boot-env/OpenSLX/BootEnvironment/Preboot.pm @@ -24,7 +24,6 @@ use File::Path; use OpenSLX::Basics; use OpenSLX::ConfigDB qw(:support); -use OpenSLX::MakeInitRamFS::Engine::Preboot; use OpenSLX::Utils; sub initialize @@ -61,7 +60,8 @@ sub writeBootloaderMenuFor my $prebootSystemInfo = clone($self->_pickSystemWithNewestKernel($systemInfos)); - $self->_createImage($client, $prebootSystemInfo); + + $self->_createImages($client, $prebootSystemInfo); my $externalClientName = externalConfigNameForClient($client); my $bootloaderPath = "$self->{'target-path'}/bootloader"; @@ -131,6 +131,40 @@ sub writeBootloaderMenuFor 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; @@ -171,58 +205,4 @@ sub _pickSystemWithNewestKernel return $systemWithNewestKernel; } -sub _makePrebootInitRamFS -{ - my $self = shift; - my $info = shift; - my $initramfs = shift; - my $client = shift; - - my $vendorOS = $info->{'vendor-os'}; - my $kernelFile = basename(followLink($info->{'kernel-file'})); - - my $attrs = clone($info->{attrs} || {}); - - my $bootURI = $client->{attrs}->{boot_uri}; - if (!$bootURI) { - die _tr("client $client->{name} needs an URI in attribute 'boot_uri' to be used for preboot!"); - } - - chomp(my $slxVersion = qx{slxversion}); - - my $params = { - 'attrs' => $attrs, - 'export-name' => undef, - 'export-uri' => undef, - 'initramfs' => $initramfs, - 'kernel-params' - => [ split ' ', ($info->{attrs}->{kernel_params} || '') ], - 'kernel-version' => $kernelFile =~ m[-(.+)$] ? $1 : '', - 'plugins' => '', - 'root-path' - => "$openslxConfig{'private-path'}/stage1/$vendorOS->{name}", - 'slx-version' => $slxVersion, - 'system-name' => $info->{name}, - 'preboot-id' => $client->{name}, - 'boot-uri' => $bootURI, - }; - - # TODO: make debug-level an explicit attribute, it's used in many places! - my $kernelParams = $info->{attrs}->{kernel_params} || ''; - if ($kernelParams =~ m{debug(?:=(\d+))?}) { - my $debugLevel = defined $1 ? $1 : '1'; - $params->{'debug-level'} = $debugLevel; - } - - my $makeInitRamFSEngine - = OpenSLX::MakeInitRamFS::Engine::Preboot->new($params); - $makeInitRamFSEngine->execute($self->{'dry-run'}); - - # copy back kernel-params, as they might have been changed (by plugins) - $info->{attrs}->{kernel_params} - = join ' ', $makeInitRamFSEngine->kernelParams(); - - return; -} - 1; diff --git a/boot-env/OpenSLX/BootEnvironment/Preboot/Base.pm b/boot-env/OpenSLX/BootEnvironment/Preboot/Base.pm new file mode 100644 index 00000000..359561e3 --- /dev/null +++ b/boot-env/OpenSLX/BootEnvironment/Preboot/Base.pm @@ -0,0 +1,100 @@ +# Copyright (c) 2008-2009 - 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::Base.pm +# - base of the Preboot-BootEnvironment API. +# ----------------------------------------------------------------------------- +package OpenSLX::BootEnvironment::Preboot::Base; + +use strict; +use warnings; + +use Clone qw(clone); + +use OpenSLX::Basics; +use OpenSLX::MakeInitRamFS::Engine::Preboot; +use OpenSLX::Utils; + +sub initialize +{ + my $self = shift; + my $params = shift; + + $self->{'dry-run'} = $params->{'dry-run'}; + + return 1; +} + +sub makePrebootInitRamFS +{ + my $self = shift; + my $info = shift; + my $initramfs = shift; + my $client = shift; + + my $vendorOS = $info->{'vendor-os'}; + my $kernelFile = basename(followLink($info->{'kernel-file'})); + + my $attrs = clone($info->{attrs} || {}); + + my $bootURI = $client->{attrs}->{boot_uri}; + if (!$bootURI) { + die _tr("client $client->{name} needs an URI in attribute 'boot_uri' to be used for preboot!"); + } + + chomp(my $slxVersion = qx{slxversion}); + + my $params = { + 'attrs' => $attrs, + 'export-name' => undef, + 'export-uri' => undef, + 'initramfs' => $initramfs, + 'kernel-params' + => [ split ' ', ($info->{attrs}->{kernel_params} || '') ], + 'kernel-version' => $kernelFile =~ m[-(.+)$] ? $1 : '', + 'plugins' => '', + 'root-path' + => "$openslxConfig{'private-path'}/stage1/$vendorOS->{name}", + 'slx-version' => $slxVersion, + 'system-name' => $info->{name}, + 'preboot-id' => $client->{name}, + 'boot-uri' => $bootURI, + }; + + # TODO: make debug-level an explicit attribute, it's used in many places! + my $kernelParams = $info->{attrs}->{kernel_params} || ''; + if ($kernelParams =~ m{debug(?:=(\d+))?}) { + my $debugLevel = defined $1 ? $1 : '1'; + $params->{'debug-level'} = $debugLevel; + } + + my $makeInitRamFSEngine + = OpenSLX::MakeInitRamFS::Engine::Preboot->new($params); + $makeInitRamFSEngine->execute($self->{'dry-run'}); + + # copy back kernel-params, as they might have been changed (by plugins) + $info->{attrs}->{kernel_params} + = join ' ', $makeInitRamFSEngine->kernelParams(); + + return; +} + +sub createImage +{ + my $self = shift; + my $client = shift; + my $info = shift; + + # override in subclasses! + + return 1; +} + +1; diff --git a/boot-env/OpenSLX/BootEnvironment/Preboot/CD.pm b/boot-env/OpenSLX/BootEnvironment/Preboot/CD.pm new file mode 100644 index 00000000..7fc61875 --- /dev/null +++ b/boot-env/OpenSLX/BootEnvironment/Preboot/CD.pm @@ -0,0 +1,108 @@ +# Copyright (c) 2008-2009 - 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::CD.pm +# - provides CD-specific implementation of the Preboot-BootEnvironment API. +# ----------------------------------------------------------------------------- +package OpenSLX::BootEnvironment::Preboot::CD; + +use strict; +use warnings; + +use base qw(OpenSLX::BootEnvironment::Preboot::Base); + +use File::Basename; +use File::Path; + +use OpenSLX::Basics; +use OpenSLX::Utils; + +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}/cd"; + mkpath($imageDir) unless $self->{'dry-run'}; + + # copy static data + my $dataDir = "$openslxConfig{'base-path'}/share/boot-env/preboot/cd"; + slxsystem(qq{rsync -rlpt $dataDir/iso "$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, $client); + + # write trivial isolinux config + my $isolinuxConfig = unshiftHereDoc(<<" End-of-Here"); + PROMPT 0 + TIMEOUT 100 + DEFAULT menu.c32 + MENU TITLE Welcome to OpenSLX PreBoot ISO/CD (Mini Linux/Kexec) + LABEL SLXSTDBOOT + MENU LABEL OpenSLX PreBoot - Stateless Netboot Linux ... + MENU DEFAULT + KERNEL vmlinuz + APPEND initrd=initramfs vga=0x317 + TEXT HELP + Use this (default) entry if you have configured your client. + You have chance to edit the kernel commandline by hitting the + TAB key (e.g. for adding debug=3 to it for bug hunting) ... + ENDTEXT + LABEL LOCALBOOT + MENU LABEL Boot locally (skip OpenSLX PreBoot) ... + LOCALBOOT -1 + TEXT HELP + Gets you out of here by booting from next device in BIOS boot + order. + ENDTEXT + End-of-Here + spitFile("$imageDir/iso/isolinux/isolinux.cfg", $isolinuxConfig); + + 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 BootISO" + -volset "OpenSLX Project - PreBoot ISO/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; +} + +1; diff --git a/boot-env/OpenSLX/BootEnvironment/PrebootCD.pm b/boot-env/OpenSLX/BootEnvironment/PrebootCD.pm deleted file mode 100644 index cd99de09..00000000 --- a/boot-env/OpenSLX/BootEnvironment/PrebootCD.pm +++ /dev/null @@ -1,109 +0,0 @@ -# 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::PrebootCD.pm -# - provides CD-specific implementation of the BootEnvironment API. -# ----------------------------------------------------------------------------- -package OpenSLX::BootEnvironment::PrebootCD; - -use strict; -use warnings; - -use base qw(OpenSLX::BootEnvironment::Preboot); - -use Clone qw(clone); -use File::Basename; -use File::Path; - -use OpenSLX::Basics; -use OpenSLX::Utils; - -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 - my $dataDir = "$openslxConfig{'base-path'}/share/boot-env/preboot/cd"; - slxsystem(qq{rsync -rlpt $dataDir/iso "$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, $client); - - # write trivial isolinux config - my $isolinuxConfig = unshiftHereDoc(<<" End-of-Here"); - PROMPT 0 - TIMEOUT 100 - DEFAULT menu.c32 - MENU TITLE Welcome to OpenSLX PreBoot ISO/CD (Mini Linux/Kexec) - LABEL SLXSTDBOOT - MENU LABEL OpenSLX PreBoot - Stateless Netboot Linux ... - MENU DEFAULT - KERNEL vmlinuz - APPEND initrd=initramfs vga=0x317 - TEXT HELP - Use this (default) entry if you have configured your client. - You have chance to edit the kernel commandline by hitting the - TAB key (e.g. for adding debug=3 to it for bug hunting) ... - ENDTEXT - LABEL LOCALBOOT - MENU LABEL Boot locally (skip OpenSLX PreBoot) ... - LOCALBOOT -1 - TEXT HELP - Gets you out of here by booting from next device in BIOS boot - order. - ENDTEXT - End-of-Here - spitFile("$imageDir/iso/isolinux/isolinux.cfg", $isolinuxConfig); - - 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 BootISO" - -volset "OpenSLX Project - PreBoot ISO/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; -} - -1; diff --git a/config-db/OpenSLX/AttributeRoster.pm b/config-db/OpenSLX/AttributeRoster.pm index 3c359e82..89fe6577 100644 --- a/config-db/OpenSLX/AttributeRoster.pm +++ b/config-db/OpenSLX/AttributeRoster.pm @@ -67,12 +67,13 @@ sub _init Currently the following boot types are supported: pxe (is the default) uses PXE to boot client over LAN - preboot-cd - generates a bootable CD-image that can be used to - remotely boot the systems referred to by this client + preboot + generates a set of images (see preboot_media) that can + be used to remotely boot the systems referred to by + this client End-of-Here - content_regex => qr{^(pxe|preboot-cd)$}, - content_descr => '"pxe" or "preboot-cd"', + content_regex => qr{^(pxe|preboot)$}, + content_descr => '"pxe" or "preboot"', default => 'pxe', }, 'boot_uri' => { @@ -126,6 +127,20 @@ sub _init content_descr => 'kernel cmdline fragment', default => '', }, + 'preboot_media' => { + applies_to_systems => 0, + applies_to_clients => 1, + description => unshiftHereDoc(<<' End-of-Here'), + List of preboot media supported by this client. + Currently the following preboot media are supported: + cd + generates a bootable CD-image that can be used to + remotely boot the systems referred to by this client + End-of-Here + content_regex => undef, + content_descr => undef, + default => '', + }, 'ramfs_fsmods' => { applies_to_systems => 1, applies_to_clients => 0, diff --git a/config-db/OpenSLX/DBSchema.pm b/config-db/OpenSLX/DBSchema.pm index f11ced10..b4130e15 100644 --- a/config-db/OpenSLX/DBSchema.pm +++ b/config-db/OpenSLX/DBSchema.pm @@ -34,7 +34,7 @@ use OpenSLX::Basics; ### fk => foreign key (integer) ################################################################################ -my $VERSION = 0.35; +my $VERSION = 0.36; my $DbSchema = { 'version' => $VERSION, @@ -805,6 +805,23 @@ sub _schemaUpgradeDBFrom undef ); + return 1; + }, + 0.36 => sub { + my $metaDB = shift; + + # value 'preboot-cd' in client-attr 'boot_type' has been changed + # to 'preboot', and a separate attribute 'preboot_media' has been + # introduced: + foreach my $client ($metaDB->fetchClientByFilter()) { + my $attrs = $metaDB->fetchClientAttrs($client->{id}); + if ($attrs->{boot_type} eq 'preboot-cd') { + $attrs->{boot_type} = 'preboot'; + $attrs->{preboot_media} = 'cd'; + $metaDB->setClientAttrs($client->{id}, $attrs); + } + } + return 1; }, ); diff --git a/config-db/slxconfig-demuxer b/config-db/slxconfig-demuxer index 9cbc03c1..e812dd93 100755 --- a/config-db/slxconfig-demuxer +++ b/config-db/slxconfig-demuxer @@ -324,13 +324,17 @@ sub createTarOfPath sub bootEnvironmentForType { - my $bootType = shift || 'pxe'; + my $bootTypeIn = shift || 'pxe'; my %bootTypeMap = ( - 'pxe' => 'PXE', - 'preboot-cd' => 'PrebootCD', + 'pxe' => 'PXE', + 'preboot' => 'Preboot', ); - $bootType = $bootTypeMap{lc($bootType)}; + my $bootType = $bootTypeMap{lc($bootTypeIn)} + or die _tr( + "'%s' is not one of the supported boot-types (pxe,preboot)", + $bootTypeIn + ); if (!$bootEnvMap{$bootType}) { my $bootEnv = instantiateClass("OpenSLX::BootEnvironment::$bootType"); @@ -494,7 +498,7 @@ sub writeClientConfigurationsForSystem "$bootEnv->{'target-path'}/client-config/$externalSystemID" ); } - case 'preboot-cd' { + case 'preboot' { # for preboot types my $cname = $client->{name}; createTarOfPath( -- cgit v1.2.3-55-g7522