From 9ea51ff3a921926264a821f282e60239ac7c5e1b Mon Sep 17 00:00:00 2001 From: Oliver Tappe Date: Sun, 24 Jun 2007 12:12:42 +0000 Subject: * implemented support for generating a separate initramfs-setup as part of the initramfs, machine-setup is now transported via Conf-TGZ only. N.B.: Couldn't apply this to the 4.1.0 branch since init has diverted a little too much for my liking! Will look into this next week. git-svn-id: http://svn.openslx.org/svn/openslx/trunk@1189 95ad53e4-c205-0410-b2fa-d234c58c8868 --- config-db/slxconfig-demuxer | 306 ++++++++++++++++++++++++-------------------- 1 file changed, 169 insertions(+), 137 deletions(-) (limited to 'config-db/slxconfig-demuxer') diff --git a/config-db/slxconfig-demuxer b/config-db/slxconfig-demuxer index bb54f718..d3b53541 100755 --- a/config-db/slxconfig-demuxer +++ b/config-db/slxconfig-demuxer @@ -39,15 +39,14 @@ use Pod::Usage; use FindBin; use lib "$FindBin::RealBin/../lib"; use lib "$FindBin::RealBin"; - # development path to config-db stuff +# development path to config-db stuff use OpenSLX::Basics; use OpenSLX::ConfigDB qw(:support); use OpenSLX::ConfigFolder; use OpenSLX::Utils; -my $pxeDefaultTemplate = -q[NOESCAPE 0 +my $pxeDefaultTemplate = q[NOESCAPE 0 PROMPT 0 TIMEOUT 10 DEFAULT menu.c32 @@ -59,16 +58,16 @@ MENU MASTER PASSWD secret my ( $dhcpType, - # type of DHCP export format + # type of DHCP export format $dryRun, - # dryRun won't touch any file + # dryRun won't touch any file $systemConfCount, - # number of system configurations written + # number of system configurations written $clientSystemConfCount, - # number of (system-specific) client configurations written + # number of (system-specific) client configurations written %vendorOSInitramfsMap, - # keeping note of how many initramFSs have been created for a - # specific vendor-OS. + # keeping note of how many initramFSs have been created for a + # specific vendor-OS. $helpReq, $manReq, $versionReq, @@ -76,24 +75,27 @@ my ( GetOptions( 'dhcp-export-type=s' => \$dhcpType, - 'dry-run' => \$dryRun, - 'help|?' => \$helpReq, - 'man' => \$manReq, - 'version' => \$versionReq, -) or pod2usage(2); + 'dry-run' => \$dryRun, + 'help|?' => \$helpReq, + 'man' => \$manReq, + 'version' => \$versionReq, + ) + or pod2usage(2); pod2usage(-msg => $abstract, -verbose => 0, -exitval => 1) if $helpReq; if ($manReq) { $ENV{LANG} = 'en_EN'; - # avoid dubious problem with perldoc in combination with UTF-8 that - # leads to strange dashes and single-quotes being used - pod2usage(-verbose => 2) + # avoid dubious problem with perldoc in combination with UTF-8 that + # leads to strange dashes and single-quotes being used + pod2usage(-verbose => 2); } if ($versionReq) { slxsystem('slxversion'); exit 1; } -my ($sec, $min, $hour, $day, $mon, $year) = (localtime); $mon++; $year+=1900; +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); @@ -107,8 +109,10 @@ my $clientConfigPath = "$openslxConfig{'private-path'}/config"; 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); + warn _tr( + "Completed client-config-folder '%s', since at least some parts of it didn't exist!", + $clientConfigPath + ); } my $lockFile = "$openslxConfig{'private-path'}/config-demuxer.lock"; @@ -127,20 +131,23 @@ if (!$dryRun) { my $tftpbootPath = "$openslxConfig{'public-path'}/tftpboot"; if (!$dryRun) { slxsystem("rm -rf $tftpbootPath/client-config/* $tftpbootPath/pxe/*"); - slxsystem("mkdir -p $tftpbootPath/client-config $tftpbootPath/pxe/pxelinux.cfg"); + slxsystem( + "mkdir -p $tftpbootPath/client-config $tftpbootPath/pxe/pxelinux.cfg"); if (!-d $tftpbootPath) { - die _tr("Unable to create or access tftpboot-path '%s'!", $tftpbootPath); + die _tr("Unable to create or access tftpboot-path '%s'!", + $tftpbootPath); } } writeConfigurations(); my $wr = ($dryRun ? "would have written" : "wrote"); -print "$wr $systemConfCount system- and $clientSystemConfCount client-specific configurations to $tftpbootPath/client-config\n"; +print + "$wr $systemConfCount system- and $clientSystemConfCount client-specific configurations to $tftpbootPath/client-config\n"; $openslxDB->disconnect(); -slxsystem("rm -rf $tempPath") unless $dryRun || length($tempPath) < 12; +slxsystem("rm -rf $tempPath") unless $dryRun || length($tempPath) < 12; exit; @@ -151,24 +158,26 @@ sub lockScript { my $lockFile = shift; - return if $dryRun; + return if $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) { + 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 (!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. + 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); +is executing this script.\n], $lockFile + ); } } } @@ -177,8 +186,8 @@ sub unlockScript { my $lockFile = shift; - return if $dryRun; - + return if $dryRun; + close(LOCKFILE); unlink $lockFile; @@ -187,7 +196,7 @@ sub unlockScript sub folderContainsFiles { my $folder = shift; - + return 0 unless -d $folder; my $result = 0; @@ -198,21 +207,19 @@ sub folderContainsFiles } $result = 1 if -f; }; - find({ wanted => $wanted, follow_fast => 1 }, $folder); + 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. +{ # returns a digest-string for the given attribute hash, in order to + # facilitate comparing different attribute hashes. my $attrs = shift; - my $attrsAsString - = join ';', - map { "$_=$attrs->{$_}"; } - sort { $a cmp $b } - grep { isAttribute($_) } keys %$attrs; + my $attrsAsString = join ';', map { "$_=$attrs->{$_}"; } + sort { $a cmp $b } + grep { isAttribute($_) } keys %$attrs; vlog(3, "Attribute-string: $attrsAsString"); use Digest::MD5 qw(md5_hex); @@ -221,16 +228,21 @@ sub digestAttributes sub writeAttributesToFile { - my $attrHash = shift; - my $fileName = shift; - - return if $dryRun; - - # append to attribute file if it exists, in order to make use of any - # settings that have been added by the user (unless, of course, these - # settings are overruled by the DB): - open(ATTRS, ">> $fileName") or die "unable to write to $fileName"; - my @attrs = sort grep { isAttribute($_) } keys %$attrHash; + my $attrHash = shift; + my $fileName = shift; + my $grepForAttributes = shift; + + return if $dryRun; + + # 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. + open(ATTRS, "> $fileName") or die "unable to write to $fileName"; + my @attrs = ( + $grepForAttributes + ? sort grep { isAttribute($_) } keys %$attrHash + : keys %$attrHash + ); print ATTRS "# attributes set by slxconfig-demuxer:\n"; foreach my $attr (@attrs) { if (length($attrHash->{$attr}) > 0) { @@ -240,20 +252,20 @@ sub writeAttributesToFile } close(ATTRS); if ($openslxConfig{'verbose-level'} > 2) { - print "--- START OF MACHINE-SETUP ---\n"; + print "--- START OF $fileName ---\n"; system("cat $fileName"); - print "--- END OF MACHINE-SETUP --- \n"; + print "--- END OF $fileName --- \n"; } } sub writeSlxConfigToFile { - my $slxConf = shift; + my $slxConf = shift; my $fileName = shift; - return if $dryRun; + return if $dryRun; - open(SLXCONF, "> $fileName") or die "unable to write to $fileName"; + open(SLXCONF, "> $fileName") or die "unable to write to $fileName"; foreach my $key (sort keys %$slxConf) { print SLXCONF qq[$key="$slxConf->{$key}"\n]; } @@ -261,18 +273,18 @@ sub writeSlxConfigToFile } sub copyExternalSystemConfig -{ # copies local configuration extensions of given system from private - # config folder (var/lib/openslx/config/...) into a temporary folder +{ # 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 + 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 $dryRun; + return if $dryRun; slxsystem("rm -rf $targetPath"); mkdir $targetPath; @@ -284,8 +296,7 @@ sub copyExternalSystemConfig slxsystem("cp -a $defaultConfigPath/* $targetPath"); } # ... now pour system-specific configuration on top (if any): - my $systemSpecConfigPath - = "$clientConfigPath/$systemName/default"; + my $systemSpecConfigPath = "$clientConfigPath/$systemName/default"; vlog(2, "checking $systemSpecConfigPath for system config..."); if (folderContainsFiles($systemSpecConfigPath)) { slxsystem("cp -a $systemSpecConfigPath/* $targetPath"); @@ -293,24 +304,23 @@ sub copyExternalSystemConfig if (defined $clientName) { # client has been given, so we finally pour client-specific # configuration on top (if any): - my $clientSpecConfigPath - = "$clientConfigPath/$systemName/$clientName"; + my $clientSpecConfigPath = "$clientConfigPath/$systemName/$clientName"; vlog(2, "checking $clientSpecConfigPath for client config..."); if (folderContainsFiles($clientSpecConfigPath)) { - slxsystem("cp -a $clientSpecConfigPath/* $targetPath") + slxsystem("cp -a $clientSpecConfigPath/* $targetPath"); } } } sub createTarOfPath { - my $buildPath = shift; - my $tarName = shift; + my $buildPath = shift; + my $tarName = shift; my $destinationPath = shift; my $tarFile = "$destinationPath/$tarName"; vlog(1, _tr('creating tar %s', $tarFile)); - return if $dryRun; + return if $dryRun; mkdir $destinationPath; my $tarCmd = "cd $buildPath && tar czf $tarFile *"; @@ -326,27 +336,27 @@ sub writePXEMenus { my @infos = @_; - my $pxePath = "$tftpbootPath/pxe"; + my $pxePath = "$tftpbootPath/pxe"; my $pxeConfigPath = "$tftpbootPath/pxe/pxelinux.cfg"; if (!-e "$pxePath/pxelinux.0") { - my $pxelinux0Path - = "$openslxConfig{'base-path'}/share/tftpboot/pxelinux.0"; - slxsystem(qq[cp -p "$pxelinux0Path" $pxePath/]) unless $dryRun; + my $pxelinux0Path = + "$openslxConfig{'base-path'}/share/tftpboot/pxelinux.0"; + slxsystem(qq[cp -p "$pxelinux0Path" $pxePath/]) unless $dryRun; } if (!-e "$pxePath/menu.c32") { - my $menuc32Path - = "$openslxConfig{'base-path'}/share/tftpboot/menu.c32"; - slxsystem(qq[cp -p "$menuc32Path" $pxePath/]) unless $dryRun; + my $menuc32Path = "$openslxConfig{'base-path'}/share/tftpboot/menu.c32"; + slxsystem(qq[cp -p "$menuc32Path" $pxePath/]) unless $dryRun; } if (!-e "$pxePath/vesamenu.c32") { - my $vesamenuc32Path - = "$openslxConfig{'base-path'}/share/tftpboot/vesamenu.c32"; - slxsystem(qq[cp -p "$vesamenuc32Path" $pxePath/]) unless $dryRun; + my $vesamenuc32Path = + "$openslxConfig{'base-path'}/share/tftpboot/vesamenu.c32"; + slxsystem(qq[cp -p "$vesamenuc32Path" $pxePath/]) unless $dryRun; } # fetch PXE-template, if any: - my $pxeTemplate = "# generated by slxconfig-demuxer (on $callDate at $callTime)\n"; + my $pxeTemplate = + "# generated by slxconfig-demuxer (on $callDate at $callTime)\n"; my $pxeTemplateFile = "$openslxConfig{'config-path'}/PXE-template"; if (-e $pxeTemplateFile) { $pxeTemplate .= slurpFile($pxeTemplateFile); @@ -361,23 +371,22 @@ sub writePXEMenus my @clients = $openslxDB->fetchClientByFilter(); foreach my $client (@clients) { my $externalClientID = externalIDForClient($client); - my $pxeFile = "$pxeConfigPath/$externalClientID"; - my $clientAppend = $client->{kernel_params}; + my $pxeFile = "$pxeConfigPath/$externalClientID"; + my $clientAppend = $client->{kernel_params}; vlog(1, _tr("writing PXE-file %s", $pxeFile)); - next if $dryRun; - open(PXE, ">$pxeFile") or die "unable to write to $pxeFile"; + next if $dryRun; + open(PXE, ">$pxeFile") or die "unable to write to $pxeFile"; print PXE $pxeTemplate; my %systemIDs; @systemIDs{$openslxDB->aggregatedSystemIDsOfClient($client)} = (); my @systemInfos = grep { exists $systemIDs{$_->{id}} } @infos; - # now @systemInfos holds all infos relevant to this client + # now @systemInfos holds all infos relevant to this client foreach my $info (@systemInfos) { - my $extID = $info->{'vendor-os'}->{name}; + my $extID = $info->{'vendor-os'}->{name}; my $kernelName = basename($info->{'kernel-file'}); - my $append = $info->{kernel_params}; + my $append = $info->{kernel_params}; $append .= " initrd=$extID/$info->{'initramfs-name'}"; $append .= " $clientAppend"; - $append .= " rootfs=$info->{'export-uri'} file"; print PXE "LABEL openslx-$info->{'external-id'}\n"; print PXE "\tMENU LABEL ^$info->{label}\n"; print PXE "\tKERNEL $extID/$kernelName\n"; @@ -385,14 +394,13 @@ sub writePXEMenus print PXE "\tIPAPPEND 1\n"; } close(PXE); - } + } } sub generateInitalRamFS { - my $info = shift; + my $info = shift; my $pxeVendorOSPath = shift; - my $attrFile = shift; my $vendorOS = $info->{'vendor-os'}; @@ -405,23 +413,31 @@ sub generateInitalRamFS $cmd .= qq[-n "$info->{attr_ramfs_nicmods}" ]; } my $fsMods = $info->{attr_ramfs_fsmods}; - $fsMods .= ' '.$osExportEngine->requiredFSMods(); + $fsMods .= ' ' . $osExportEngine->requiredFSMods(); if (length($fsMods) > 0) { $cmd .= qq[-f "$fsMods" ]; } - my $rootPath - = "$openslxConfig{'private-path'}/stage1/$vendorOS->{name}"; + my $rootPath = "$openslxConfig{'private-path'}/stage1/$vendorOS->{name}"; $cmd .= "-i $pxeVendorOSPath/$info->{'initramfs-name'} -r $rootPath "; $cmd .= "-S $info->{name} "; - # pass in system name + # pass in system name $cmd .= "-s openslx "; - # use theme 'openslx' + # use theme 'openslx' $cmd .= "-d "; - # always use dhclient instead of the busybox-provided dhcp-client - # (since the latter is unable to fetch NIS-stuff). - - # pass in machine-setup file (the one contained in system's conf-TGZ): - $cmd .= "-c $attrFile "; + # always use dhclient instead of the busybox-provided dhcp-client + # (since the latter is unable to fetch NIS-stuff). + + # generate initramfs-setup file (with settings relevant for initramfs only): + my $initramfsAttrFile = "$tempPath/initramfs-setup"; + my $initramfsAttrs = { + 'ramfs_fsmods' => "$info->{'attr_ramfs_fsmods'}", + 'ramfs_nicmods' => "$info->{'attr_ramfs_nicmods'}", + 'ramfs_screen' => "$info->{'attr_ramfs_screen'}", + 'rootfs' => "$info->{'export-uri'}", + }; + writeAttributesToFile($initramfsAttrs, $initramfsAttrFile, 0); + # and pass it to mkdxsinitrd: + $cmd .= "-c $initramfsAttrFile "; # ...set kernel version... my $kernelFile = basename(followLink($info->{'kernel-file'})); @@ -432,60 +448,60 @@ sub generateInitalRamFS my $slxver = `slxversion`; chomp $slxver; $ENV{'SLX_VERSION'} = $slxver; - slxsystem($cmd) unless $dryRun; + slxsystem($cmd) unless $dryRun; } sub writeSystemPXEFiles { my $info = shift; - my $attrFile = shift; my $kernelFile = $info->{'kernel-file'}; my $kernelName = basename($kernelFile); - my $pxePath = "$tftpbootPath/pxe"; + my $pxePath = "$tftpbootPath/pxe"; my $pxeVendorOSPath = "$pxePath/$info->{'vendor-os'}->{name}"; - mkdir $pxeVendorOSPath unless -e $pxeVendorOSPath || $dryRun; + mkdir $pxeVendorOSPath unless -e $pxeVendorOSPath || $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 $dryRun; + slxsystem(qq[cp -p "$kernelFile" "$targetKernel"]) unless $dryRun; } $vendorOSInitramfsMap{$info->{'vendor-os'}->{id}}++; - $info->{'initramfs-name'} - = sprintf "initramfs-%d", - $vendorOSInitramfsMap{$info->{'vendor-os'}->{id}}; - generateInitalRamFS($info, $pxeVendorOSPath, $attrFile); + $info->{'initramfs-name'} = + sprintf("initramfs-%d", + $vendorOSInitramfsMap{$info->{'vendor-os'}->{id}}); + generateInitalRamFS($info, $pxeVendorOSPath); } sub writeDhcpConfig { -vlog(0, _tr("sorry, exporting dhcp data is not implemented yet!")); + vlog(0, _tr("sorry, exporting dhcp data is not implemented yet!")); my $dhcpModule = "OpenSLX::Export::DHCP::$dhcpType"; if (!eval "require $dhcpModule") { - die _tr("unable to load DHCP-Export backend '%s'! (%s)\n", $dhcpModule, $@); + die _tr("unable to load DHCP-Export backend '%s'! (%s)\n", + $dhcpModule, $@); } my $dhcpBackend = $dhcpModule->new(); - my @clients = $openslxDB->fetchClientByFilter(); + my @clients = $openslxDB->fetchClientByFilter(); $dhcpBackend->execute(\@clients); } sub writeClientConfigurationsForSystem { - my $info = shift; + my $info = shift; my $buildPath = shift; - my $attrFile = shift; + my $attrFile = shift; my @clientIDs = $openslxDB->aggregatedClientIDsOfSystem($info); - my @clients = $openslxDB->fetchClientByID(\@clientIDs); + my @clients = $openslxDB->fetchClientByID(\@clientIDs); foreach my $client (@clients) { next if $client->{id} == 0; - # skip default client, as it doesn't need any config-tgz - my $externalSystemID = externalIDForSystem($info); + # 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: @@ -493,23 +509,34 @@ sub writeClientConfigurationsForSystem mergeAttributes($client, $info); my $clientAttrDigest = digestAttributes($client); - vlog(2, _tr("attribute-digest for client '%s' is '%s'", $client->{name}, - $clientAttrDigest)); + 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})); + || -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); + $externalClientName); - writeAttributesToFile($client, $attrFile); + writeAttributesToFile($client, $attrFile, 1); # create tar containing external system configuration # and client attribute file, this time referring to the client @@ -518,7 +545,7 @@ sub writeClientConfigurationsForSystem # name it is referred to in the openslx-config-DB: my $externalClientID = externalIDForClient($client); createTarOfPath($buildPath, "${externalClientID}.tgz", - "$tftpbootPath/client-config/$info->{'external-id'}"); + "$tftpbootPath/client-config/$info->{'external-id'}"); } } } @@ -532,19 +559,24 @@ sub writeSystemConfiguration $openslxDB->mergeDefaultAttributesIntoSystem($info); $info->{'attr-digest'} = digestAttributes($info); - vlog(2, _tr("attribute-digest for system '%s' is '%s'", $info->{name}, - $info->{'attr-digest'})); + vlog( + 2, + _tr( + "attribute-digest for system '%s' is '%s'", $info->{name}, + $info->{'attr-digest'} + ) + ); my $attrFile = "$buildPath/initramfs/machine-setup"; - writeAttributesToFile($info, $attrFile); + writeAttributesToFile($info, $attrFile, 1); my $systemPath = "$tftpbootPath/client-config/$info->{'external-id'}"; createTarOfPath($buildPath, "default.tgz", $systemPath); - writeSystemPXEFiles($info, $attrFile); + writeSystemPXEFiles($info); writeClientConfigurationsForSystem($info, $buildPath, $attrFile); - slxsystem("rm -rf $buildPath") unless $dryRun; + slxsystem("rm -rf $buildPath") unless $dryRun; } sub writeConfigurations @@ -553,9 +585,10 @@ sub writeConfigurations my @systems = $openslxDB->fetchSystemByFilter(); my @infos; foreach my $system (@systems) { - next unless $system->{id} > 0; + next unless $system->{id} > 0; - vlog(0, _tr('exporting system %d : %s', $system->{id}, $system->{name})); + vlog(0, + _tr('exporting system %d : %s', $system->{id}, $system->{name})); $systemConfCount++; my $info = $openslxDB->aggregatedSystemFileInfoFor($system); @@ -571,8 +604,6 @@ sub writeConfigurations } } - - =head1 NAME slxconfig-demuxer - OpenSLX configuration demultiplexer @@ -743,3 +774,4 @@ Please refer to the C-manpage for a more detailed description of these options. =cut + -- cgit v1.2.3-55-g7522