diff options
Diffstat (limited to 'src/lib/OpenSLX/DistroUtils/Base.pm')
-rw-r--r-- | src/lib/OpenSLX/DistroUtils/Base.pm | 429 |
1 files changed, 429 insertions, 0 deletions
diff --git a/src/lib/OpenSLX/DistroUtils/Base.pm b/src/lib/OpenSLX/DistroUtils/Base.pm new file mode 100644 index 00000000..f9e6b13b --- /dev/null +++ b/src/lib/OpenSLX/DistroUtils/Base.pm @@ -0,0 +1,429 @@ +# 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/ +# ----------------------------------------------------------------------------- +# DistroUtils.pm +# - provides base for distro based utils for OpenSLX +# ----------------------------------------------------------------------------- +package OpenSLX::DistroUtils::Base; + +use Data::Dumper; +use OpenSLX::Utils; +use Clone qw(clone); +use Switch; + +use strict; +use warnings; + +sub new +{ + my $class = shift; + my $self = {}; + return bless $self, $class; +} + +sub dumpInit +{ + my $self = shift; + my $initFile = shift; + + print Dumper($initFile->{'configHash'}); + + print $self->generateInitFile($initFile); +} + +sub _concatContent +{ + my $self = shift; + my $block = shift; + + my $output; + + $output = "#"; + $output .= $block->{'blockDesc'}; + $output .= "\n"; + + my $content = $block->{'content'}; + while ( my ($priority, $contentArray) = each %$content ) + { + $output .= join("\n", @$contentArray); + $output .= "\n"; + } + + return $output; +} + +sub _renderInfoBlock +{ + my $self = shift; + my $config = shift; + + my $tpl = unshiftHereDoc(<<' End-of-Here'); + ### BEGIN INIT INFO + # Provides: %s + # Required-Start: %s + # Required-Stop: %s + # Default-Start: %s + # Default-Stop: %s + # Short-Description: %s + ### END INIT INFO + + End-of-Here + + return sprintf( + $tpl, + $config->{'name'}, + $config->{'requiredStart'}, + $config->{'requiredStop'}, + $config->{'defaultStart'}, + $config->{'defaultStop'}, + $config->{'shortDesc'} + ); +} + +sub _insertSystemHelperFunctions +{ + my $self = shift; + my $content = shift; + + # do some regex + + # ubuntu: + # log_end_msg + # log_progress_msg + # log_daemon_msg + # log_action_msg + + # start-stop-daemon + + # suse http://de.opensuse.org/Paketbau/SUSE-Paketkonventionen/Init-Skripte + + return $content; +} + +sub _renderHighlevelConfig +{ + my $self = shift; + my $initFile = shift; + + my $element; + my $hlc = $initFile->{'configHash'}->{'highlevelConfig'}; + + while ( $element = shift(@$hlc)){ + switch ($element->{type}) { + case 'daemon' { + my $tpl; + $tpl = "%s_BIN=%s \n"; + $tpl .= "[ -x %s_BIN ] || exit 5\n\n"; + $tpl .= "%s_OPTS=\"%s\" \n"; + $tpl .= "[ -f /etc/sysconfig/%s ] . /etc/sysconfig/%s \n\n"; + $tpl .= "[ -f /etc/default/%s ] . /etc/default/%s \n\n"; + $tpl .= "%s_PIDFILE=\"/var/run/%s.init.pid\" \n\n"; + $initFile->addToBlock('head', + sprintf( + $tpl, + uc($element->{shortname}), + $element->{binary}, + uc($element->{shortname}), + uc($element->{shortname}), + $element->{parameters}, + $element->{shortname}, + $element->{shortname}, + $element->{shortname}, + $element->{shortname}, + uc($element->{shortname}), + $element->{shortname} + ), + $element->{priority} + ); + + $tpl = "echo -n \"Starting %s \"\n"; + $tpl .= "startproc -f -p \$%s_PIDFILE \$%s_BIN \$%s_OPTS\n"; + $tpl .= "rc_status -v"; + $initFile->addToCase('start', + sprintf( + $tpl, + $element->{desc}, + uc($element->{shortname}), + uc($element->{shortname}), + uc($element->{shortname}) + ), + $element->{priority} + ); + + $tpl = "echo -n \"Shutting down %s\" \n"; + $tpl .= "killproc -p \$%s_PIDFILE -TERM \$%s_BIN\n"; + $tpl .= "rc_status -v"; + $initFile->addToCase('stop', + sprintf( + $tpl, + $element->{desc}, + uc($element->{shortname}), + uc($element->{shortname}) + ), + 10 - $element->{priority} + ); + + $tpl = "## Stop the service and if this succeeds (i.e. the \n"; + $tpl .= "## service was running before), start it again.\n"; + $tpl .= "\$0 status >/dev/null && \$0 restart\n\n"; + $tpl .= "# Remember status and be quiet\n"; + $tpl .= "rc_status"; + $initFile->addToCase('try-restart', + $tpl, + $element->{priority} + ); + + $tpl = "## Stop the service and regardless of whether it was \n"; + $tpl .= "## running or not, start it again.\n"; + $tpl .= "\$0 stop\n"; + $tpl .= "\$0 start\n\n"; + $tpl .= "# Remember status and be quiet\n"; + $tpl .= "rc_status"; + $initFile->addToCase('restart', + $tpl, + $element->{priority} + ); + + $tpl = "echo -n \"Reload service %s\"\n"; + $tpl .= "killproc -p \$%s_PIDFILE -HUP \$%s_BIN\n"; + $tpl .= "rc_status -v"; + $initFile->addToCase('reload', + sprintf( + $tpl, + $element->{desc}, + uc($element->{shortname}), + uc($element->{shortname}), + uc($element->{shortname}) + ), + $element->{priority} + ); + + $tpl = "echo -n \"Checking for service %s\"\n"; + $tpl .= "checkproc -p \$%s_PIDFILE \$%s_BIN\n"; + $tpl .= "rc_status -v"; + $initFile->addToCase('status', + sprintf( + $tpl, + $element->{desc}, + uc($element->{shortname}), + uc($element->{shortname}) + ), + $element->{priority} + ); + + + } + case 'function' { + my $tpl; + $tpl = "%s () { \n"; + $tpl .= "%s"; + $tpl .= "\n}\n"; + $initFile->addToBlock('functions', + sprintf( + $tpl, + $element->{name}, + $element->{script} + ) + ); + + } + case 'functionCall' { + my $tpl; + $tpl = "%s %s\n"; + #$tpl .= "%s\n "; + $initFile->addToCase($element->{block}, + sprintf( + $tpl, + $element->{function}, + $element->{parameters}, + "" + ), + $element->{priority} + ); + + } + } + } + +} + + +sub _getInitsystemIncludes +{ + return "\n"; +} + +sub _renderCasePrefix +{ + return "\n"; +} + +sub _renderFooter +{ + return "exit 0\n"; +} + +sub _generateUsage +{ + my $self = shift; + my $usage = shift; + my $tpl; + + $tpl = "## print out usage \n"; + $tpl .= "echo \"Usage: \$0 {%s}\" >&2 \n"; + $tpl .= "exit 1"; + + return sprintf( + $tpl, + $usage + ); +} + +sub _getAuthorBlock +{ + my $tpl; + + $tpl = "# Copyright (c) 2009 - OpenSLX GmbH \n"; + $tpl .= "# \n"; + $tpl .= "# This program is free software distributed under the GPL version 2. \n"; + $tpl .= "# See http://openslx.org/COPYING \n"; + $tpl .= "# \n"; + $tpl .= "# If you have any feedback please consult http://openslx.org/feedback and \n"; + $tpl .= "# send your suggestions, praise, or complaints to feedback\@openslx.org \n"; + $tpl .= "# \n"; + $tpl .= "# General information about OpenSLX can be found at http://openslx.org/ \n"; + $tpl .= "# -----------------------------------------------------------------------------\n"; + $tpl .= "# §filename§ \n"; + $tpl .= "# - §desc§ \n"; + $tpl .= "# §generated§ \n"; + $tpl .= "# -----------------------------------------------------------------------------\n\n"; + + return sprintf( + $tpl + ); +} + +sub generateInitFile +{ + my $self = shift; + my $initFile = shift; + my $content; + my @usage; + + # get a copy of initFile object before modifying it.. + my $initFileCopy = clone($initFile); + + $self->_renderHighlevelConfig($initFileCopy); + + my $config = $initFileCopy->{'configHash'}; + my $output; + + # head + $output = "#!/bin/sh\n"; + $output .= $self->_getAuthorBlock(); + $output .= $self->_renderInfoBlock($config); + $output .= $self->_getInitsystemIncludes(); + + if (keys(%{$config->{'blocks'}->{'head'}->{'content'}}) > 0) { + $output .= $self->_concatContent($config->{'blocks'}->{'head'}); + } + + # functions + if (keys(%{$config->{'blocks'}->{'functions'}->{'content'}}) > 0) { + $output .= $self->_concatContent($config->{'blocks'}->{'functions'}); + } + + # case block + $output .= $self->_renderCasePrefix(); + $output .= "\ncase \"\$1\" in \n"; + + # get caseBlocks in defined order + my @blocks = sort{ + $config->{'caseBlocks'}->{$a}->{'order'} <=> + $config->{'caseBlocks'}->{$b}->{'order'} + } + keys(%{$config->{'caseBlocks'}}); + + # case block + while (@blocks) + { + my $block= shift(@blocks); + if (keys(%{$config->{'caseBlocks'}->{$block}->{'content'}}) > 0) { + push(@usage, $block); + $output .= " $block)\n"; + $content = $self->_concatContent($config->{'caseBlocks'}->{$block}); + $content =~ s/^/ /mg; + $output .= $content; + $output .= " ;;\n"; + } else { + if ($config->{'caseBlocks'}->{$block}->{'required'}) { + print "required block $block undefined"; + } + } + } + + # autogenerate usage + if (scalar(grep(/usage/, @usage)) == 0) { + $initFileCopy->addToCase( + 'usage', + $self->_generateUsage(join(', ',@usage)) + ); + + $output .= " *)\n"; + $content = $self->_concatContent($config->{'caseBlocks'}->{'usage'}); + $content =~ s/^/ /mg; + $output .= $content; + $output .= " ;;\n"; + + } + + # footer + $output .= "esac\n\n"; + $output .= $self->_renderFooter(); + + return $output; + +} + +sub getKernelVersion +{ + my $self = shift; + my $kernelPath = shift; + + + my $newestKernelFile; + my $newestKernelFileSortKey = ''; + my $kernelPattern = '{vmlinuz,kernel-genkernel-x86}-*'; + foreach my $kernelFile (glob("$kernelPath/$kernelPattern")) { + next unless $kernelFile =~ m{ + (?:vmlinuz|x86)-(\d+)\.(\d+)\.(\d+)(?:\.(\d+))?-(\d+(?:\.\d+)?) + }x; + my $sortKey + = sprintf("%02d.%02d.%02d.%02d-%2.1f", $1, $2, $3, $4||0, $5); + if ($newestKernelFileSortKey lt $sortKey) { + $newestKernelFile = $kernelFile; + $newestKernelFileSortKey = $sortKey; + } + } + + if (!defined $newestKernelFile) { + die; #_tr("unable to pick a kernel-file from path '%s'!", $kernelPath); + } + + $newestKernelFile =~ /.*?-([.\-0-9]*)-([a-zA-Z]*?)$/; + my $kernel = {}; + $kernel->{'version'} = $1; + $kernel->{'suffix'} = $2; + return $kernel; + +} + + +1; |