summaryrefslogblamecommitdiffstats
path: root/config-db/config-demuxer.pl
blob: dccbea7bf0738c5e02dd30e81bde39fe35657103 (plain) (tree)
1
2
3
4
5
6
7
8
9
                
           




                                                                        
                              
                   
                                          
                    
                                                        
 

                                                       

           
                

              



                                                            

                
                                             
                         


                                                                           

  





                                                                                  
              
 
                                  
 
                                                             


                                                                   
                                                              




                                                                                 
 
                                                              
               
                                                                     



                                                                                     

 


                                                 


                                                    
                                                                                                                   
 
                               
 
                                                                                 

                        
 




                                                                                



























                                                                                                                                                                                                 




                             

                                   



                                                                                      

                                                                               




                     
                            




                                                                            

                                   


                                                                                




















                                                                 

                                                  


                                   








                                                                                    



                                                     










                                                                                  


                                                                    
                                                           
                                                             

                                                                                     


                                                                                 
                                                                    





                                                                        

                           






                           
                                        





                                                                                       



                                                                                       

 





                                      


                                                                         
                                                                                      
                                         
 




                                                                                    
 



                                                                     
                                                                      
                                                                                             


         

                             



                                                       
                                                                                      
                                   
 
                                                  
                                                                      

                                                                    
                                                                      

                                                          




                                                                             


                                                                                   
                                                                       


         
                       
 
                                                      
                                    
                        

 
#! /usr/bin/perl
use strict;

# add the folder this script lives in to perl's search path for modules:
use FindBin;
use lib $FindBin::Bin;

use Fcntl qw(:DEFAULT :flock);
use File::Basename;
use Getopt::Long qw(:config pass_through);
use OpenSLX::Basics;
use OpenSLX::ConfigDB qw(:access :aggregation :support);

my $pxeConfigDefaultTemplate = q[# generated by openslx
NOESCAPE 0
PROMPT 0
TIMEOUT 100
DEFAULT menu.c32
IMPLICIT 1
ALLOWOPTIONS 1
MENU TITLE What would you like to do? (use cursor to select)
MENU MASTER PASSWD secret
];

my (
	$dryRun,
		# dryRun won't touch any file
	$systemConfCount,
		# number of system configurations written
	$clientSystemConfCount,
		# number of (system-specific) client configurations written
);

GetOptions(
	'dry-run' => \$dryRun
		# dry-run doesn't write anything, just prints statistic about what
		# would have been written
);

openslxInit();

my $openslxDB = connectConfigDB();

my $configPath = "$openslxConfig{'private-basepath'}/config";
if (!-d $configPath) {
	die _tr("Unable to access config-path '%s'!", $configPath);
}
my $tempPath = "$openslxConfig{'temp-basepath'}/oslx-demuxer";
if (!$dryRun) {
	mkdir $tempPath;
	if (!-d $tempPath) {
		die _tr("Unable to create or access temp-path '%s'!", $tempPath);
	}
}
my $exportPath = "$openslxConfig{'public-basepath'}/tftpboot";
if (!$dryRun) {
	system("rm -rf $exportPath/client-conf/* $exportPath/pxe/*");
	system("mkdir -p $exportPath/client-conf $exportPath/pxe/pxelinux.cfg");
	if (!-d $exportPath) {
		die _tr("Unable to create or access export-path '%s'!", $exportPath);
	}
}

my $lockFile = "$exportPath/config-demuxer.lock";
lockScript($lockFile);

writeConfigurations();

my $wr = ($dryRun ? "would have written" : "wrote");
print "$wr $systemConfCount systems and $clientSystemConfCount client-configurations to $exportPath/client-conf\n";

disconnectConfigDB($openslxDB);

system("rm -rf $tempPath")		unless $dryRun || length($tempPath) < 12;

unlockScript($lockFile);

exit;

################################################################################
###
################################################################################
sub lockScript
{
	my $lockFile = shift;

	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) {
			# existing lock file is older than 15 minutes, wipe it:
			unlink $lockFile;
		}
	}
	sysopen(LOCKFILE, $lockFile, O_RDWR|O_CREAT|O_EXCL)
		or die _tr(qq[Lock-file <%s> exists, script is already running.\nPlease remove the logfile and try again if you are sure that no one else is executing this script.], $lockFile);
}

sub unlockScript
{
	my $lockFile = shift;

	return		if $dryRun;

	unlink $lockFile;
}

sub writeAttributesToFile
{
	my $attrHash = shift;
	my $fileName = shift;

	return		if $dryRun;

	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 $externalAttrName = externalAttrName($attr);
			print ATTRS "$externalAttrName = $attrHash->{$attr}\n";
		}
	}
	close(ATTRS);
}

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;

	return		if $dryRun;

	if ($targetPath !~ m[$tempPath]) {
		die _tr("system-error: illegal target-path <%s>!", $targetPath);
	}
	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;

	my $tarFile = "$destinationPath/$tarName";
	vlog 1, _tr('creating tar %s', $tarFile);
	return		if $dryRun;

	mkdir $destinationPath;
	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 writePXEMenus
{
	my $pxePath = "$exportPath/pxe/pxelinux.cfg";

	if (!-e "$exportPath/pxe/pxelinux.0") {
		my $pxelinux0Path
			= "$openslxConfig{'shared-basepath'}/tftpboot/pxelinux.0";
		system(qq[cp -a "$pxelinux0Path" $exportPath/pxe/]);
	}
	if (!-e "$exportPath/pxe/menu.c32") {
		my $menuc32Path
			= "$openslxConfig{'shared-basepath'}/tftpboot/menu.c32";
		system(qq[cp -a "$menuc32Path" $exportPath/pxe/]);
	}

	my @clients = fetchClientsByFilter($openslxDB);
	foreach my $client (@clients) {
		my $externalClientID = externalIDForClient($client);
		my $pxeFile = "$pxePath/$externalClientID";
		vlog 1, _tr("writing PXE-file %s", $pxeFile);
		open(PXE, "> $pxeFile")		or die "unable to write to $pxeFile";
		print PXE $pxeConfigDefaultTemplate;
		my @systemIDs = aggregatedSystemIDsOfClient($openslxDB, $client);
		my @systems = fetchSystemsByID($openslxDB, \@systemIDs);
		foreach my $system (@systems) {
			print PXE "LABEL openslx-$system->{name}\n";
#			print PXE "\tMENU DEFAULT\n";
			print PXE "\tMENU LABEL ^$system->{label}\n";
			my $kernel = basename($system->{kernel});
			print PXE "\tKERNEL $kernel\n";
			print PXE "\tAPPEND $system->{kernel_params}\n";
			print PXE "\tIPAPPEND 1\n";
		}
		close(PXE);
 	}
}

sub writeSystemPXEFiles
{
	my $system = shift;

	my $pxePath = "$exportPath/pxe";

	my @kernelFiles = aggregatedKernelFilesOfSystem($openslxDB, $system);
	foreach my $kernelFile (@kernelFiles) {
		vlog 1, _tr('copying kernel %s to %s/', $kernelFile, $pxePath);
		system(qq[cp -a "$kernelFile" $pxePath/])		unless $dryRun;
	}
#	foreach my $initramFile (aggregatedInitramFilesOfSystem($openslxDB, $system)) {
#		vlog 1, _tr('copying initramfs %s to %s/', $initramFile, $pxePath);
#		system(qq[cp -a "$initramFile" $pxePath/])		unless $dryRun;
#	}
}

sub writeClientConfigurationsForSystem
{
	my $system = shift;
	my $buildPath = shift;
	my $attrFile = shift;

	my @clientIDs = aggregatedClientIDsOfSystem($openslxDB, $system);
	my @clients = fetchClientsByID($openslxDB, \@clientIDs);
	foreach my $client (@clients) {
		vlog 2, _tr("exporting client %d:%s", $client->{id}, $client->{name});
		$clientSystemConfCount++;

		# merge configurations of client, it's groups, default client and
		# system and write the resulting attributes to a configuration file:
		mergeDefaultAndGroupAttributesIntoClient($openslxDB, $client);
		mergeAttributes($client, $system);
		writeAttributesToFile($client, $attrFile);

		# create tar containing external system configuration
		# and client attribute file:
		my $externalClientID = externalIDForClient($client);
		my $externalSystemID = externalIDForSystem($system);
		createTarOfPath($buildPath, "${externalClientID}.tgz",
						"$exportPath/client-conf/$externalSystemID");
	}
}

sub writeSystemConfigurations
{
	my @systems = fetchSystemsByFilter($openslxDB);
	foreach my $system (@systems) {
		next 	unless $system->{id} > 0;

		vlog 2, _tr('exporting system %d:%s', $system->{id}, $system->{name});
		$systemConfCount++;

		my $buildPath = "$tempPath/build";
		copyExternalSystemConfig($system->{name}, $buildPath);

		my $attrFile = "$buildPath/initramfs/machine-setup";
		mergeDefaultAttributesIntoSystem($openslxDB, $system);
		writeAttributesToFile($system, $attrFile);

		my $externalSystemID = externalIDForSystem($system);
		my $systemPath = "$exportPath/client-conf/$externalSystemID";
		createTarOfPath($buildPath, "default.tgz", $systemPath);

		writeSystemPXEFiles($system);

		writeClientConfigurationsForSystem($system, $buildPath, $attrFile);

		system("rm -rf $buildPath")		unless $dryRun;
	}
}

sub writeConfigurations
{
	$systemConfCount = $clientSystemConfCount = 0;
	writeSystemConfigurations();
	writePXEMenus();
}