From 78517bfcae78ecaeeeb536c48553cc31fd869e12 Mon Sep 17 00:00:00 2001 From: Oliver Tappe Date: Fri, 18 Aug 2006 18:16:40 +0000 Subject: * largish step towards a working demuxer: demuxing and packing of tars works now, but PXE-stuff is still missing git-svn-id: http://svn.openslx.org/svn/openslx/trunk@316 95ad53e4-c205-0410-b2fa-d234c58c8868 --- config-db/config-demuxer.pl | 223 ++++++++++++++++++++++++++++++++++++++------ 1 file changed, 194 insertions(+), 29 deletions(-) (limited to 'config-db/config-demuxer.pl') diff --git a/config-db/config-demuxer.pl b/config-db/config-demuxer.pl index 8b9708ad..c5fe2c39 100755 --- a/config-db/config-demuxer.pl +++ b/config-db/config-demuxer.pl @@ -4,77 +4,232 @@ use FindBin; use lib $FindBin::Bin; -use Getopt::Long; +use Getopt::Long qw(:config pass_through); use ODLX::Basics; use ODLX::ConfigDB; my ( $dryRun, + $defaultSystem, + $defaultClient, %systemConf, - %sytemClientConf, + %clientConf, %clientPXE, ); -odlxInit(); - GetOptions( 'dry-run' => \$dryRun # dry-run doesn't write anything, just prints statistic about what # would have been written ); -print "dry-run...\n" if $dryRun; +odlxInit(); my $odlxDB = connectConfigDB(); +my $configPath = "$odlxConfig{'private-basepath'}/config"; +if (!-d $configPath) { + die _tr("Unable to access config-path '%s'!", $configPath); +} +my $tempPath = "$odlxConfig{'temp-basepath'}/oslx-demuxer"; +mkdir $tempPath; +if (!-d $tempPath) { + die _tr("Unable to create or access temp-path '%s'!", $tempPath); +} +my $exportPath = "$odlxConfig{'public-basepath'}/tftpboot"; +system("rm -rf $exportPath/client-conf/* $exportPath/pxe/pxelinux.cfg/*"); +system("mkdir -p $exportPath/client-conf $exportPath/pxe/pxelinux.cfg"); +if (!-d $exportPath) { + die _tr("Unable to create or access export-path '%s'!", $exportPath); +} + demuxConfigurations(); +if (!$dryRun) { + writeConfigurations(); +} + disconnectConfigDB($odlxDB); +system("rm -rf $tempPath"); + exit; ################################################################################ ### ################################################################################ -sub initSystemConfigurations -{ - foreach my $s (fetchSystemsByFilter($odlxDB)) { - vlog 3, _tr('system %d:%s...', $s->{id}, $s->{name}); - $systemConf{$s->{id}} = $s; - } +sub isAttribute +{ # returns whether or not the given key is an exportable attribute + my $key = shift; + + return $key =~ m[^attr]; } sub mergeConfigAttributes -{ # copies all attributes of source that do not exists in target over +{ # copies all attributes of source that are unset in target over my $target = shift; my $source = shift; - foreach my $key (grep { $_ =~ m[^attr] } keys %$source) { + foreach my $key (grep { isAttribute($_) } keys %$source) { if (length($source->{$key}) > 0 && length($target->{$key}) == 0) { + vlog 3, _tr("\tmerging %s (val=%s)", $key, $source->{$key}); $target->{$key} = $source->{$key}; } } } +sub writeAttributesToFile +{ + my $attrHash = shift; + my $fileName = shift; + + open(ATTRS, "> $fileName") or die "unable to write to $fileName"; + my @attrs = sort grep { isAttribute($_) } keys %$attrHash; + foreach my $attr (@attrs) { + if (length($attrHash->{$attr}) > 0) { + my $shellVar = $attr; + # convert 'attrExampleName' to 'example_name': + $shellVar =~ s[([A-Z])]['_'.lc($1)]ge; + $shellVar = substr($shellVar, 5); + print SYSCONF "$shellVar = $attrHash->{$attr}\n"; + } + } + close(ATTRS); +} + +sub copySystemConfig +{ # 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; + + system("rm -rf $targetPath"); + mkdir $targetPath; + + # first copy default files... + my $defaultConfigPath = "$configPath/default"; + if (-d $defaultConfigPath) { + system("cp -r $defaultConfigPath/* $targetPath"); + } + # now pour system-specific configuration on top (if any): + my $systemConfigPath = "$configPath/$systemName"; + if (-d $systemConfigPath) { + system("cp -r $systemConfigPath/* $targetPath"); + } +} + +sub createTarOfPath +{ + my $buildPath = shift; + my $tarName = shift; + my $destinationPath = shift; + + mkdir $destinationPath; + my $tarFile = "$destinationPath/$tarName"; + vlog 1, _tr('creating tar %s', $tarFile); + my $tarCmd = "cd $buildPath && tar czf $tarFile *"; + if (system("$tarCmd") != 0) { + die _tr("unable to execute shell-command:\n\t%s \n\t($!)", $tarCmd); + } +} + +################################################################################ +### +################################################################################ +sub writeClientConfigurationsForSystem +{ + my $system = shift; + my $buildPath = shift; + my $attrFile = shift; + + foreach my $client (values %{$system->{clients}}) { + vlog 2, _tr("exporting client %d:%s", $client->{id}, $client->{name}); + + writeAttributesToFile($client, $attrFile); + + my $mac = $client->{mac}; + $mac =~ tr[:][-]; + createTarOfPath($buildPath, "01-$mac.tgz", + "$exportPath/client-conf/$system->{name}"); + } +} + + +sub writeSystemConfigurations +{ + foreach my $system (values %systemConf) { + vlog 2, _tr('exporting system %d:%s', $system->{id}, $system->{name}); + my $buildPath = "$tempPath/build"; + + copySystemConfig($system->{name}, $buildPath); + + my $attrFile = "$buildPath/initramfs/machine-setup"; + writeAttributesToFile($system, $attrFile); + + createTarOfPath($buildPath, "default.tgz", + "$exportPath/client-conf/$system->{name}"); + + writeClientConfigurationsForSystem($system, $buildPath, $attrFile); + + system("rm -rf $buildPath"); + } +} + +sub initSystemConfigurations +{ + $defaultSystem = fetchSystemsByID($odlxDB, 0); + + foreach my $s (fetchSystemsByFilter($odlxDB)) { + next unless $s->{id} > 0; + vlog 2, _tr('read system %d:%s...', $s->{id}, $s->{name}); + + # replace any whitespace in name, as we will use it as a + # directory name later: + $s->{name} =~ s[\s+][_]g; + + mergeConfigAttributes($s, $defaultSystem); + $systemConf{$s->{id}} = $s; + } +} + +sub linkClientToSystems +{ + my ($client, @systemIDs) = @_; + + my $clientID = $client->{id}; + foreach my $sysID (@systemIDs) { + my $sysConf = $systemConf{$sysID}; + next if !defined $sysConf; + $sysConf->{clients} = {} unless exists $sysConf->{clients}; + if (!exists $sysConf->{clients}->{$clientID} + && !$sysConf->{unbootable}) { + vlog 2, _tr('linking client %d:%s to system %d:%s', + $client->{id}, $client->{name}, + $sysID, $sysConf->{name}); + $sysConf->{clients}->{$clientID} = $client; + } + } +} + sub demuxClientConfigurations { my %groups; foreach my $g (fetchGroupsByFilter($odlxDB)) { - vlog 3, _tr('group %d:%s...', $g->{id}, $g->{name}); + vlog 2, _tr('read group %d:%s...', $g->{id}, $g->{name}); $groups{$g->{id}} = $g; } + $defaultClient = fetchClientsByID($odlxDB, 0); + foreach my $client (fetchClientsByFilter($odlxDB)) { - vlog 3, _tr('client %d:%s...', $client->{id}, $client->{name}); + next unless $client->{id} > 0; + vlog 2, _tr('read client %d:%s...', $client->{id}, $client->{name}); # add all systems directly linked to client: - $client->{systems} = {}; - foreach my $s (fetchSystemIDsOfClient($odlxDB, $client->{id})) { - if (!exists $client->{systems}->{$s->{id}}) { - $client->{systems}->{$s->{id}} = $systems{$s->{id}}; - } - } +my @sysIDs = fetchSystemIDsOfClient($odlxDB, $client->{id}); + linkClientToSystems($client, @sysIDs + ); # now fetch and step over all groups this client belongs to # (ordered by priority from highest to lowest): @@ -87,18 +242,23 @@ sub demuxClientConfigurations foreach my $group (@clientGroups) { # fetch and add all systems that the client inherits from # the current group: - foreach my $s (fetchSystemIDsOfGroup($odlxDB, $group->{id})) { - if (!exists $client->{systems}->{$s->{id}}) { - $client->{systems}->{$s->{id}} = $systems{$s->{id}}; - } - mergeConfigAttributes($client, $group); - } + linkClientToSystems($client, + fetchSystemIDsOfGroup($odlxDB, $group->{id})); + + # merge configuration from this group into the current client: + vlog 3, _tr('merging from group %d:%s...', $group->{id}, $group->{name}); + mergeConfigAttributes($client, $group); } - # finally demux client-config to system-specific configuration + # merge configuration from default client: + vlog 3, _tr('merging from default client...'); + mergeConfigAttributes($client, $defaultClient); + + # finally demux client-config to systems bootable by that client # and merge system-specific attributes into that: foreach my $s (values %{$client->{systems}}) { - $systemClientConf{$client->{id}} = { %$client }; + $clientConf{$client->{id}} = { %$client }; + vlog 3, _tr('merging from system %d:%s...', $system->{id}, $system->{name}); mergeConfigAttributes($systemClientConf{$client->{id}}, $system); } } @@ -110,3 +270,8 @@ sub demuxConfigurations() demuxClientConfigurations(); } +sub writeConfigurations() +{ + writeSystemConfigurations(); +} + -- cgit v1.2.3-55-g7522