From a0ce0340d0f95514008cfac751fe58748bbadd88 Mon Sep 17 00:00:00 2001 From: Oliver Tappe Date: Thu, 20 Mar 2008 00:04:16 +0000 Subject: * Switched indent used in Perl-code and settings files from tabs to 4 spaces. May need some manual corrections here and there, but should basically be ok. git-svn-id: http://svn.openslx.org/svn/openslx/openslx/trunk@1658 95ad53e4-c205-0410-b2fa-d234c58c8868 --- config-db/slxconfig-demuxer | 1184 +++++++++++++++++++++---------------------- 1 file changed, 592 insertions(+), 592 deletions(-) (limited to 'config-db/slxconfig-demuxer') diff --git a/config-db/slxconfig-demuxer b/config-db/slxconfig-demuxer index 03d2ca2e..f6592b88 100755 --- a/config-db/slxconfig-demuxer +++ b/config-db/slxconfig-demuxer @@ -11,7 +11,7 @@ # General information about OpenSLX can be found at http://openslx.org/ # ----------------------------------------------------------------------------- # slxconfig-demuxer -# - OpenSLX configuration demultiplexer +# - OpenSLX configuration demultiplexer # ----------------------------------------------------------------------------- use strict; use warnings; @@ -54,54 +54,54 @@ 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 + 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 - $systemErrCount, - # number of systems that had errors - $clientSystemConfCount, - # number of (system-specific) client configurations written - $initramfsCount, - # number of initramfs that were created - @targetSystems, - # systems to create initramfs for, defaults to all systems - %option, - # cmdline option hash + $systemConfCount, + # number of system configurations written + $systemErrCount, + # number of systems that had errors + $clientSystemConfCount, + # number of (system-specific) client configurations written + $initramfsCount, + # number of initramfs that were created + @targetSystems, + # systems to create initramfs for, defaults to all systems + %option, + # cmdline option hash ); if ($> != 0) { - die _tr("Sorry, this script can only be executed by the superuser!\n"); + die _tr("Sorry, this script can only be executed by the superuser!\n"); } GetOptions( - 'dhcp-export-type=s' => \$option{dhcpType}, - 'dry-run' => \$option{dryRun}, - 'help|?' => \$option{helpReq}, - 'man' => \$option{manReq}, - 'version' => \$option{versionReq}, + 'dhcp-export-type=s' => \$option{dhcpType}, + 'dry-run' => \$option{dryRun}, + 'help|?' => \$option{helpReq}, + 'man' => \$option{manReq}, + 'version' => \$option{versionReq}, ) or pod2usage(2); pod2usage(-msg => $abstract, -verbose => 0, -exitval => 1) if $option{helpReq}; if ($option{manReq}) { - # avoid dubious problem with perldoc in combination with UTF-8 that - # leads to strange dashes and single-quotes being used - $ENV{LC_ALL} = 'POSIX'; - pod2usage(-verbose => 2); + # avoid dubious problem with perldoc in combination with UTF-8 that + # leads to strange dashes and single-quotes being used + $ENV{LC_ALL} = 'POSIX'; + pod2usage(-verbose => 2); } if ($option{versionReq}) { - slxsystem('slxversion'); - exit 1; + slxsystem('slxversion'); + exit 1; } my ($sec, $min, $hour, $day, $mon, $year) = (localtime); @@ -118,12 +118,12 @@ $openslxDB->connect(); my $clientConfigPath = "$openslxConfig{'private-path'}/config"; # make sure that the default config folders exist: if (createConfigFolderForDefaultSystem()) { - # this path should have been generated by earlier stage (slxsettings), so - # we indicate that there is some kind of problem: - warn _tr( - "Completed client-config-folder '%s', since at least some parts of it didn't exist!", - $clientConfigPath - ); + # this path should have been generated by earlier stage (slxsettings), so + # we indicate that there is some kind of problem: + warn _tr( + "Completed client-config-folder '%s', since at least some parts of it didn't exist!", + $clientConfigPath + ); } chomp(my $slxVersion = qx{slxversion}); @@ -133,55 +133,55 @@ my $haveLock = lockScript($lockFile); END { - unlockScript($lockFile) if $haveLock; + unlockScript($lockFile) if $haveLock; } my $tempPath = "$openslxConfig{'temp-path'}/slxconfig-demuxer"; if (!$option{dryRun}) { - rmtree($tempPath); - mkpath($tempPath); - if (!-d $tempPath) { - die _tr("Unable to create or access temp-path '%s'!", $tempPath); - } + rmtree($tempPath); + mkpath($tempPath); + if (!-d $tempPath) { + die _tr("Unable to create or access temp-path '%s'!", $tempPath); + } } 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([$tftpbootPath]); + rmtree("$tftpbuildPath/pxelinux.cfg"); + mkpath(["$tftpbuildPath/client-config", "$tftpbuildPath/pxelinux.cfg"]); } my $rsyncDeleteClause; my @demuxableSystems - = grep { $_->{name} ne '<<>>' } $openslxDB->fetchSystemByFilter(); + = grep { $_->{name} ne '<<>>' } $openslxDB->fetchSystemByFilter(); if (@ARGV) { - # create initramfs only for systems given on cmdline - for my $systemName (@ARGV) { - if ($systemName eq '<<>>') { - warn _tr( - 'The default-system can not be demuxed - it will be skipped.' - ); - next; - } - my $system = first { $_->{name} eq $systemName } @demuxableSystems; - if (!$system) { - warn _tr( - 'The system "%s" is unknown and will be ignored.', $systemName - ); - next; - } - push @targetSystems, $system; - } - $rsyncDeleteClause = ''; + # create initramfs only for systems given on cmdline + for my $systemName (@ARGV) { + if ($systemName eq '<<>>') { + warn _tr( + 'The default-system can not be demuxed - it will be skipped.' + ); + next; + } + my $system = first { $_->{name} eq $systemName } @demuxableSystems; + if (!$system) { + warn _tr( + 'The system "%s" is unknown and will be ignored.', $systemName + ); + next; + } + push @targetSystems, $system; + } + $rsyncDeleteClause = ''; } else { - # create initramfs for all systems - @targetSystems = @demuxableSystems; - # let rsync delete old files - $rsyncDeleteClause = '--delete'; + # create initramfs for all systems + @targetSystems = @demuxableSystems; + # let rsync delete old files + $rsyncDeleteClause = '--delete'; } writeConfigurations(); @@ -189,22 +189,22 @@ writeConfigurations(); my $wr = $option{dryRun} ? 'would have written' : 'wrote'; my $errCount = $systemErrCount ? $systemErrCount : 'no'; print "\n", unshiftHereDoc(<<"End-of-Here"); - $wr $systemConfCount system- and $clientSystemConfCount client-specific configurations to $tftpbootPath/client-config - $initramfsCount initramfs were created - $errCount system(s) had errors + $wr $systemConfCount system- and $clientSystemConfCount client-specific configurations to $tftpbootPath/client-config + $initramfsCount initramfs were created + $errCount system(s) had errors End-of-Here $openslxDB->disconnect(); if (!$option{dryRun}) { - rmtree([$tempPath]); - my $rsyncCmd = "rsync -a $rsyncDeleteClause --delay-updates $tftpbuildPath/ $tftpbootPath/"; - slxsystem($rsyncCmd) == 0 - or die _tr( - "unable to rsync files from '%s' to '%s'! (%s)", - $tftpbuildPath, $tftpbootPath, $! - ); - rmtree([$tftpbuildPath]); + rmtree([$tempPath]); + my $rsyncCmd = "rsync -a $rsyncDeleteClause --delay-updates $tftpbuildPath/ $tftpbootPath/"; + slxsystem($rsyncCmd) == 0 + or die _tr( + "unable to rsync files from '%s' to '%s'! (%s)", + $tftpbuildPath, $tftpbootPath, $! + ); + rmtree([$tftpbuildPath]); } exit; @@ -214,181 +214,181 @@ exit; ################################################################################ sub lockScript { - my $lockFile = shift; - - return if $option{dryRun}; - - # use a lock-file to singularize execution of this script: - if (-e $lockFile) { - my $ctime = (stat($lockFile))[10]; - my $now = time(); - if ($now - $ctime > 15 * 60) { - # existing lock file is older than 15 minutes, wipe it: - unlink $lockFile; - } - } - if (!sysopen(LOCKFILE, $lockFile, O_RDWR | O_CREAT | O_EXCL)) { - if ($! == 13) { - die _tr(qq[Unable to create lock-file <%s>, exiting!\n], $lockFile); - } else { - die _tr( - qq[Lock-file <%s> exists, script is already running. + my $lockFile = shift; + + return if $option{dryRun}; + + # use a lock-file to singularize execution of this script: + if (-e $lockFile) { + my $ctime = (stat($lockFile))[10]; + my $now = time(); + if ($now - $ctime > 15 * 60) { + # existing lock file is older than 15 minutes, wipe it: + unlink $lockFile; + } + } + if (!sysopen(LOCKFILE, $lockFile, O_RDWR | O_CREAT | O_EXCL)) { + if ($! == 13) { + die _tr(qq[Unable to create lock-file <%s>, exiting!\n], $lockFile); + } else { + die _tr( + qq[Lock-file <%s> exists, script is already running. Please remove the logfile and try again if you are sure that no one else is executing this script.\n], $lockFile - ); - } - } - return 1; + ); + } + } + return 1; } sub unlockScript { - my $lockFile = shift; + my $lockFile = shift; - return if $option{dryRun}; + return if $option{dryRun}; - close(LOCKFILE); - unlink $lockFile; + close(LOCKFILE); + unlink $lockFile; - return; + return; } sub folderContainsFiles { - my $folder = shift; - - return 0 unless -d $folder; - - my $result = 0; - my $wanted = sub { - if ($result) { - # skip anything else if we have found a file already - $File::Find::prune = 1; - } - $result = 1 if -f; - }; - find({wanted => $wanted, follow_fast => 1}, $folder); - vlog(2, "result for folderContainsFiles($folder): $result\n"); - return $result; + my $folder = shift; + + return 0 unless -d $folder; + + my $result = 0; + my $wanted = sub { + if ($result) { + # skip anything else if we have found a file already + $File::Find::prune = 1; + } + $result = 1 if -f; + }; + find({wanted => $wanted, follow_fast => 1}, $folder); + vlog(2, "result for folderContainsFiles($folder): $result\n"); + return $result; } sub digestAttributes -{ # returns a digest-string for the given attribute hash, in order to - # facilitate comparing different attribute hashes. - my $object = shift; - - my $attrs = $object->{attrs} || {}; - my $attrsAsString - = join ';', - map { "$_=$attrs->{$_}" } - sort - grep { defined $attrs->{$_} } - keys %$attrs; - - vlog(3, "Attribute-string: $attrsAsString"); - return md5_hex($attrsAsString); +{ # returns a digest-string for the given attribute hash, in order to + # facilitate comparing different attribute hashes. + my $object = shift; + + my $attrs = $object->{attrs} || {}; + my $attrsAsString + = join ';', + map { "$_=$attrs->{$_}" } + sort + grep { defined $attrs->{$_} } + keys %$attrs; + + vlog(3, "Attribute-string: $attrsAsString"); + return md5_hex($attrsAsString); } sub writeAttributesToFile { - my $object = shift; - my $fileName = shift; - - return if $option{dryRun}; - - my $content = "# attributes set by slxconfig-demuxer:\n"; - my $attrs = $object->{attrs} || {}; - # filter out any plugin-specific attributes (we only want to handle - # the attributes relevant to the core here) - my @attrs = sort grep { index($_, '::') == -1 } keys %$attrs; - foreach my $attr (@attrs) { - my $attrVal = $attrs->{$attr}; - next if !defined $attrVal; - $content .= qq[$attr="$attrVal"\n]; - } - # Overwrite attribute file even if it exists, to make sure that our users - # will never again try to fiddle with machine-setup directly the - # file-system. From now on the DB is the keeper of that info. - spitFile($fileName, $content); - if ($openslxConfig{'verbose-level'} > 2) { - vlog(0, "--- START OF $fileName ---"); - vlog(0, $content); - vlog(0, "--- END OF $fileName --- "); - } - return; + my $object = shift; + my $fileName = shift; + + return if $option{dryRun}; + + my $content = "# attributes set by slxconfig-demuxer:\n"; + my $attrs = $object->{attrs} || {}; + # filter out any plugin-specific attributes (we only want to handle + # the attributes relevant to the core here) + my @attrs = sort grep { index($_, '::') == -1 } keys %$attrs; + foreach my $attr (@attrs) { + my $attrVal = $attrs->{$attr}; + next if !defined $attrVal; + $content .= qq[$attr="$attrVal"\n]; + } + # Overwrite attribute file even if it exists, to make sure that our users + # will never again try to fiddle with machine-setup directly the + # file-system. From now on the DB is the keeper of that info. + spitFile($fileName, $content); + if ($openslxConfig{'verbose-level'} > 2) { + vlog(0, "--- START OF $fileName ---"); + vlog(0, $content); + vlog(0, "--- END OF $fileName --- "); + } + return; } sub writeSlxConfigToFile { - my $slxConf = shift; - my $fileName = shift; + my $slxConf = shift; + my $fileName = shift; - return if $option{dryRun}; + return if $option{dryRun}; - my $content = ''; - foreach my $key (sort keys %$slxConf) { - $content .= qq[$key="$slxConf->{$key}"\n]; - } - spitFile($fileName, $content); - return; + my $content = ''; + foreach my $key (sort keys %$slxConf) { + $content .= qq[$key="$slxConf->{$key}"\n]; + } + spitFile($fileName, $content); + return; } sub copyExternalSystemConfig { # copies local configuration extensions of given system from private # config folder (var/lib/openslx/config/...) into a temporary folder - my $systemName = shift; - my $targetPath = shift; - my $clientName = shift; # optional - - if ($targetPath !~ m[$tempPath]) { - # bail if target-path isn't within temp folder, as we do not dare - # executing 'rm -rf' in that case! - die _tr("system-error: illegal target-path <%s>!", $targetPath); - } - return if $option{dryRun}; - - slxsystem("rm -rf $targetPath"); - mkpath $targetPath; - - # first copy default files ... - my $defaultConfigPath = "$clientConfigPath/default"; - vlog(2, "checking $defaultConfigPath for default config..."); - if (-d $defaultConfigPath) { - slxsystem("cp -a $defaultConfigPath/* $targetPath"); - } - # ... now pour system-specific configuration on top (if any): - my $systemSpecConfigPath = "$clientConfigPath/$systemName/default"; - vlog(2, "checking $systemSpecConfigPath for system config..."); - if (folderContainsFiles($systemSpecConfigPath)) { - slxsystem("cp -a $systemSpecConfigPath/* $targetPath"); - } - if (defined $clientName) { - # client has been given, so we finally pour client-specific - # configuration on top (if any): - my $clientSpecConfigPath = "$clientConfigPath/$systemName/$clientName"; - vlog(2, "checking $clientSpecConfigPath for client config..."); - if (folderContainsFiles($clientSpecConfigPath)) { - slxsystem("cp -a $clientSpecConfigPath/* $targetPath"); - } - } - return; + my $systemName = shift; + my $targetPath = shift; + my $clientName = shift; # optional + + if ($targetPath !~ m[$tempPath]) { + # bail if target-path isn't within temp folder, as we do not dare + # executing 'rm -rf' in that case! + die _tr("system-error: illegal target-path <%s>!", $targetPath); + } + return if $option{dryRun}; + + slxsystem("rm -rf $targetPath"); + mkpath $targetPath; + + # first copy default files ... + my $defaultConfigPath = "$clientConfigPath/default"; + vlog(2, "checking $defaultConfigPath for default config..."); + if (-d $defaultConfigPath) { + slxsystem("cp -a $defaultConfigPath/* $targetPath"); + } + # ... now pour system-specific configuration on top (if any): + my $systemSpecConfigPath = "$clientConfigPath/$systemName/default"; + vlog(2, "checking $systemSpecConfigPath for system config..."); + if (folderContainsFiles($systemSpecConfigPath)) { + slxsystem("cp -a $systemSpecConfigPath/* $targetPath"); + } + if (defined $clientName) { + # client has been given, so we finally pour client-specific + # configuration on top (if any): + my $clientSpecConfigPath = "$clientConfigPath/$systemName/$clientName"; + vlog(2, "checking $clientSpecConfigPath for client config..."); + if (folderContainsFiles($clientSpecConfigPath)) { + slxsystem("cp -a $clientSpecConfigPath/* $targetPath"); + } + } + return; } sub createTarOfPath { - my $buildPath = shift; - my $tarName = shift; - my $destinationPath = shift; - - my $tarFile = "$destinationPath/$tarName"; - vlog(1, _tr('creating tar %s', $tarFile)); - return if $option{dryRun}; - - mkpath $destinationPath; - my $tarCmd = "cd $buildPath && tar czf $tarFile *"; - if (slxsystem("$tarCmd") != 0) { - die _tr("unable to execute shell-command:\n\t%s \n\t(%s)", $tarCmd, $!); - } + my $buildPath = shift; + my $tarName = shift; + my $destinationPath = shift; + + my $tarFile = "$destinationPath/$tarName"; + vlog(1, _tr('creating tar %s', $tarFile)); + return if $option{dryRun}; + + mkpath $destinationPath; + my $tarCmd = "cd $buildPath && tar czf $tarFile *"; + if (slxsystem("$tarCmd") != 0) { + die _tr("unable to execute shell-command:\n\t%s \n\t(%s)", $tarCmd, $!); + } } ################################################################################ @@ -396,408 +396,408 @@ sub createTarOfPath ################################################################################ sub writePXEMenus { - 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}; - } - - # 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}; - } - } - - 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}; - 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)' } ); - } - return; + 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}; + } + + # 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}; + } + } + + 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}; + 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)' } ); + } + return; } sub makeInitRamFS { - my $info = shift; - my $pxeVendorOSPath = shift; - - vlog(1, _tr('generating initialramfs %s/initramfs', $pxeVendorOSPath)); - - my $vendorOS = $info->{'vendor-os'}; - my $kernelFile = basename(followLink($info->{'kernel-file'})); - - my $attrs = dclone($info->{attrs} || {}); - - my $params = { - 'attrs' => $attrs, - 'export-name' => $info->{export}->{name}, - 'export-uri' => $info->{'export-uri'}, - 'initramfs' => "$pxeVendorOSPath/$info->{'initramfs-name'}", - 'kernel-params' => [ split ' ', ($info->{kernel_params} || '') ], - 'kernel-version' => $kernelFile =~ m[-(.+)$] ? $1 : '', - 'plugins' => $info->{'active-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->new($params); - $makeInitRamFSEngine->execute($option{dryRun}); - - # copy back kernel-params, as they might have been changed (by plugins) - $info->{kernel_params} = join ' ', $makeInitRamFSEngine->kernelParams(); - - return; + my $info = shift; + my $pxeVendorOSPath = shift; + + vlog(1, _tr('generating initialramfs %s/initramfs', $pxeVendorOSPath)); + + my $vendorOS = $info->{'vendor-os'}; + my $kernelFile = basename(followLink($info->{'kernel-file'})); + + my $attrs = dclone($info->{attrs} || {}); + + my $params = { + 'attrs' => $attrs, + 'export-name' => $info->{export}->{name}, + 'export-uri' => $info->{'export-uri'}, + 'initramfs' => "$pxeVendorOSPath/$info->{'initramfs-name'}", + 'kernel-params' => [ split ' ', ($info->{kernel_params} || '') ], + 'kernel-version' => $kernelFile =~ m[-(.+)$] ? $1 : '', + 'plugins' => $info->{'active-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->new($params); + $makeInitRamFSEngine->execute($option{dryRun}); + + # copy back kernel-params, as they might have been changed (by plugins) + $info->{kernel_params} = join ' ', $makeInitRamFSEngine->kernelParams(); + + return; } sub writeSystemPXEFiles { - my $info = shift; + my $info = shift; - vlog(0, _tr('copying kernel and creating initramfs')); + vlog(0, _tr('copying kernel and creating initramfs')); - my $kernelFile = $info->{'kernel-file'}; - my $kernelName = basename($kernelFile); + 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 $pxePath = "$tftpbuildPath"; + my $pxeVendorOSPath = "$pxePath/$info->{'vendor-os'}->{name}"; + mkpath $pxeVendorOSPath unless -e $pxeVendorOSPath || $option{dryRun}; - my $targetKernel = "$pxeVendorOSPath/$kernelName"; - if (!-e $targetKernel) { - vlog(1, _tr('copying kernel %s to %s', $kernelFile, $targetKernel)); - slxsystem(qq[cp -p "$kernelFile" "$targetKernel"]) unless $option{dryRun}; - } - makeInitRamFS($info, $pxeVendorOSPath); - $initramfsCount++; - return; + my $targetKernel = "$pxeVendorOSPath/$kernelName"; + if (!-e $targetKernel) { + vlog(1, _tr('copying kernel %s to %s', $kernelFile, $targetKernel)); + slxsystem(qq[cp -p "$kernelFile" "$targetKernel"]) unless $option{dryRun}; + } + makeInitRamFS($info, $pxeVendorOSPath); + $initramfsCount++; + return; } sub writeDhcpConfig { - vlog(0, _tr("sorry, exporting dhcp data is not implemented yet!")); - my $dhcpModule = "OpenSLX::ConfigExport::DHCP::$option{dhcpType}"; - if (!eval { require $dhcpModule } ) { - die _tr("unable to load DHCP-Export backend '%s'! (%s)\n", - $dhcpModule, $@); - } - my $dhcpBackend = $dhcpModule->new(); - my @clients = $openslxDB->fetchClientByFilter(); - $dhcpBackend->execute(\@clients); - return; + vlog(0, _tr("sorry, exporting dhcp data is not implemented yet!")); + my $dhcpModule = "OpenSLX::ConfigExport::DHCP::$option{dhcpType}"; + if (!eval { require $dhcpModule } ) { + die _tr("unable to load DHCP-Export backend '%s'! (%s)\n", + $dhcpModule, $@); + } + my $dhcpBackend = $dhcpModule->new(); + my @clients = $openslxDB->fetchClientByFilter(); + $dhcpBackend->execute(\@clients); + return; } sub writeClientConfigurationsForSystem { - my $info = shift; - my $buildPath = shift; - my $attrFile = shift; - - my @clientIDs = $openslxDB->aggregatedClientIDsOfSystem($info); - my @clients = $openslxDB->fetchClientByID(\@clientIDs); - foreach my $client (@clients) { - next if $client->{name} eq '<<>>'; - # skip default client, as it doesn't need any config-tgz - - my $externalSystemID = externalIDForSystem($info); - my $externalClientName = externalConfigNameForClient($client); - 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: - $openslxDB->mergeDefaultAndGroupAttributesIntoClient($client); - mergeAttributes($client, $info); - - my $clientAttrDigest = digestAttributes($client); - vlog( - 2, - _tr( - "attribute-digest for client '%s' is '%s'", $client->{name}, - $clientAttrDigest - ) - ); - # export client-specific config only if attributes are different - # from system and/or a client-specific config-folder exists: - if ($clientAttrDigest ne $info->{'attr-digest'} - || -d $clientConfigPath) - { - vlog( - 1, - _tr( - "creating config-tgz for client %d:%s", $client->{id}, - $client->{name} - ) - ); - $clientSystemConfCount++; - - # merge default, system and client configuration files into - # the system configuration for the current client: - copyExternalSystemConfig( - $externalSystemID, $buildPath, $externalClientName - ); - - writeAttributesToFile($client, $attrFile); - - # create tar containing external system configuration - # and client attribute file, this time referring to the client - # via its external ID (the PXE-style MAC), as the TGZ needs to - # be accessed from the client-PC, which doesn't know about the - # name it is referred to in the openslx-config-DB: - my $externalClientID = externalIDForClient($client); - createTarOfPath( - $buildPath, "${externalClientID}.tgz", - "$tftpbuildPath/client-config/$info->{'external-id'}" - ); - } - } - return; + my $info = shift; + my $buildPath = shift; + my $attrFile = shift; + + my @clientIDs = $openslxDB->aggregatedClientIDsOfSystem($info); + my @clients = $openslxDB->fetchClientByID(\@clientIDs); + foreach my $client (@clients) { + next if $client->{name} eq '<<>>'; + # skip default client, as it doesn't need any config-tgz + + my $externalSystemID = externalIDForSystem($info); + my $externalClientName = externalConfigNameForClient($client); + 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: + $openslxDB->mergeDefaultAndGroupAttributesIntoClient($client); + mergeAttributes($client, $info); + + my $clientAttrDigest = digestAttributes($client); + vlog( + 2, + _tr( + "attribute-digest for client '%s' is '%s'", $client->{name}, + $clientAttrDigest + ) + ); + # export client-specific config only if attributes are different + # from system and/or a client-specific config-folder exists: + if ($clientAttrDigest ne $info->{'attr-digest'} + || -d $clientConfigPath) + { + vlog( + 1, + _tr( + "creating config-tgz for client %d:%s", $client->{id}, + $client->{name} + ) + ); + $clientSystemConfCount++; + + # merge default, system and client configuration files into + # the system configuration for the current client: + copyExternalSystemConfig( + $externalSystemID, $buildPath, $externalClientName + ); + + writeAttributesToFile($client, $attrFile); + + # create tar containing external system configuration + # and client attribute file, this time referring to the client + # via its external ID (the PXE-style MAC), as the TGZ needs to + # be accessed from the client-PC, which doesn't know about the + # name it is referred to in the openslx-config-DB: + my $externalClientID = externalIDForClient($client); + createTarOfPath( + $buildPath, "${externalClientID}.tgz", + "$tftpbuildPath/client-config/$info->{'external-id'}" + ); + } + } + return; } sub writePluginConfigurationsForSystem { - my $info = shift || confess 'need to pass in info-hash!'; - my $buildPath = shift || confess 'need to pass in build-path!'; - - my $pluginConfPath = "$buildPath/initramfs/plugin-conf"; - - my $attrs = $info->{attrs} || {}; - - my @activePlugins; - foreach my $pluginInfo (@{$info->{'installed-plugins'}}) { - my $pluginName = $pluginInfo->{plugin_name}; - vlog(2, _tr("checking configuration of plugin '%s'", $pluginName)); - - # skip inactive plugins - next unless $attrs->{"${pluginName}::active"}; - - push @activePlugins, $pluginName; - - next if $option{dryRun}; - - mkpath([ $pluginConfPath ]); - - vlog(2, _tr("writing configuration file for plugin '%s'", $pluginName)); - # write plugin configuration to a file: - my $content; - my @pluginAttrs = grep { $_ =~ m{^${pluginName}::} } keys %$attrs; - foreach my $attr (sort @pluginAttrs) { - my $attrVal = $attrs->{$attr}; - if (!defined $attrVal) { - $attrVal = ''; - } - my $attrName = substr($attr, index($attr, '::')+2); - $content .= qq[${pluginName}_$attrName="$attrVal"\n]; - } - my $fileName = "$pluginConfPath/${pluginName}.conf"; - spitFile($fileName, $content); - if ($openslxConfig{'verbose-level'} > 2) { - vlog(0, "--- START OF $fileName ---"); - vlog(0, $content); - vlog(0, "--- END OF $fileName --- "); - } - } - $info->{'active-plugins'} = \@activePlugins; - my $activePluginStr = @activePlugins ? join ',', @activePlugins : ''; - vlog(0, _tr("active plugins: %s", $activePluginStr)); - return; + my $info = shift || confess 'need to pass in info-hash!'; + my $buildPath = shift || confess 'need to pass in build-path!'; + + my $pluginConfPath = "$buildPath/initramfs/plugin-conf"; + + my $attrs = $info->{attrs} || {}; + + my @activePlugins; + foreach my $pluginInfo (@{$info->{'installed-plugins'}}) { + my $pluginName = $pluginInfo->{plugin_name}; + vlog(2, _tr("checking configuration of plugin '%s'", $pluginName)); + + # skip inactive plugins + next unless $attrs->{"${pluginName}::active"}; + + push @activePlugins, $pluginName; + + next if $option{dryRun}; + + mkpath([ $pluginConfPath ]); + + vlog(2, _tr("writing configuration file for plugin '%s'", $pluginName)); + # write plugin configuration to a file: + my $content; + my @pluginAttrs = grep { $_ =~ m{^${pluginName}::} } keys %$attrs; + foreach my $attr (sort @pluginAttrs) { + my $attrVal = $attrs->{$attr}; + if (!defined $attrVal) { + $attrVal = ''; + } + my $attrName = substr($attr, index($attr, '::')+2); + $content .= qq[${pluginName}_$attrName="$attrVal"\n]; + } + my $fileName = "$pluginConfPath/${pluginName}.conf"; + spitFile($fileName, $content); + if ($openslxConfig{'verbose-level'} > 2) { + vlog(0, "--- START OF $fileName ---"); + vlog(0, $content); + vlog(0, "--- END OF $fileName --- "); + } + } + $info->{'active-plugins'} = \@activePlugins; + my $activePluginStr = @activePlugins ? join ',', @activePlugins : ''; + vlog(0, _tr("active plugins: %s", $activePluginStr)); + return; } sub writeSystemConfiguration { - my $info = shift; - my $isTargetSystem = shift; - - # if this is not a target system, we shall not write any configurations, - # but we simply incorporate inherited attributes - if (!$isTargetSystem) { - $openslxDB->mergeDefaultAttributesIntoSystem($info); - $info->{'initramfs-name'} = "initramfs-$info->{id}"; - return; - } - - # write configuration files for this system - my $buildPath = "$tempPath/build"; - copyExternalSystemConfig(externalIDForSystem($info), $buildPath); - - $openslxDB->mergeDefaultAttributesIntoSystem( - $info, $info->{'installed-plugins'} - ); - $info->{'attr-digest'} = digestAttributes($info); - vlog( - 2, - _tr( - "attribute-digest for system '%s' is '%s'", $info->{name}, - $info->{'attr-digest'} - ) - ); - my $attrFile = "$buildPath/initramfs/machine-setup"; - writeAttributesToFile($info, $attrFile); - - writePluginConfigurationsForSystem($info, $buildPath); - - my $systemPath = "$tftpbuildPath/client-config/$info->{'external-id'}"; - createTarOfPath($buildPath, "default.tgz", $systemPath); - - $info->{'initramfs-name'} = "initramfs-$info->{id}"; - writeSystemPXEFiles($info); - - writeClientConfigurationsForSystem($info, $buildPath, $attrFile); - - slxsystem("rm -rf $buildPath") unless $option{dryRun}; - - $systemConfCount++; - - return; + my $info = shift; + my $isTargetSystem = shift; + + # if this is not a target system, we shall not write any configurations, + # but we simply incorporate inherited attributes + if (!$isTargetSystem) { + $openslxDB->mergeDefaultAttributesIntoSystem($info); + $info->{'initramfs-name'} = "initramfs-$info->{id}"; + return; + } + + # write configuration files for this system + my $buildPath = "$tempPath/build"; + copyExternalSystemConfig(externalIDForSystem($info), $buildPath); + + $openslxDB->mergeDefaultAttributesIntoSystem( + $info, $info->{'installed-plugins'} + ); + $info->{'attr-digest'} = digestAttributes($info); + vlog( + 2, + _tr( + "attribute-digest for system '%s' is '%s'", $info->{name}, + $info->{'attr-digest'} + ) + ); + my $attrFile = "$buildPath/initramfs/machine-setup"; + writeAttributesToFile($info, $attrFile); + + writePluginConfigurationsForSystem($info, $buildPath); + + my $systemPath = "$tftpbuildPath/client-config/$info->{'external-id'}"; + createTarOfPath($buildPath, "default.tgz", $systemPath); + + $info->{'initramfs-name'} = "initramfs-$info->{id}"; + writeSystemPXEFiles($info); + + writeClientConfigurationsForSystem($info, $buildPath, $attrFile); + + slxsystem("rm -rf $buildPath") unless $option{dryRun}; + + $systemConfCount++; + + return; } sub writeConfigurations { - $initramfsCount = $systemConfCount = $systemErrCount - = $clientSystemConfCount = 0; - my @infos; - foreach my $system (@demuxableSystems) { - my $isTargetSystem - = first { $_->{name} eq $system->{name} } @targetSystems; - if ($isTargetSystem) { - vlog( - 0, - _tr("\ndemuxing system %d : %s", $system->{id}, $system->{name}) - ); - } - else { - vlog( - 0, - _tr( - "\nlinking demuxed system %d : %s into PXE menu", - $system->{id}, $system->{name} - ) - ); - } - - my $success = eval { - my $info = $openslxDB->aggregatedSystemFileInfoFor($system); - $info->{'external-id'} = externalIDForSystem($system); - - writeSystemConfiguration($info, $isTargetSystem); - - push @infos, $info; - 1; - }; - if (!$success) { - print STDERR $@; - $systemErrCount++; - } - } - writePXEMenus(@infos); - if (defined $option{dhcpType}) { - writeDhcpConfig(); - } - return; + $initramfsCount = $systemConfCount = $systemErrCount + = $clientSystemConfCount = 0; + my @infos; + foreach my $system (@demuxableSystems) { + my $isTargetSystem + = first { $_->{name} eq $system->{name} } @targetSystems; + if ($isTargetSystem) { + vlog( + 0, + _tr("\ndemuxing system %d : %s", $system->{id}, $system->{name}) + ); + } + else { + vlog( + 0, + _tr( + "\nlinking demuxed system %d : %s into PXE menu", + $system->{id}, $system->{name} + ) + ); + } + + my $success = eval { + my $info = $openslxDB->aggregatedSystemFileInfoFor($system); + $info->{'external-id'} = externalIDForSystem($system); + + writeSystemConfiguration($info, $isTargetSystem); + + push @infos, $info; + 1; + }; + if (!$success) { + print STDERR $@; + $systemErrCount++; + } + } + writePXEMenus(@infos); + if (defined $option{dhcpType}) { + writeDhcpConfig(); + } + return; } =head1 NAME -- cgit v1.2.3-55-g7522