From b979de76b67cd80d87e032dbbcb49ac5022d9240 Mon Sep 17 00:00:00 2001 From: immarvin <yangsbj@cn.ibm.com> Date: Sun, 8 Jun 2014 05:42:23 -0700 Subject: [PATCH] add generic subroutine and functions for service management --- perl-xCAT/xCAT/Utils.pm | 463 +++++++++++++++++++++++++++++++++++- xCAT/postscripts/xcatlib.sh | 204 ++++++++++++++++ 2 files changed, 665 insertions(+), 2 deletions(-) diff --git a/perl-xCAT/xCAT/Utils.pm b/perl-xCAT/xCAT/Utils.pm index f9f454b10..4264e7e74 100644 --- a/perl-xCAT/xCAT/Utils.pm +++ b/perl-xCAT/xCAT/Utils.pm @@ -16,7 +16,6 @@ if ($^O =~ /^aix/i) { use lib "$::XCATROOT/lib/perl"; # do not put a use or require for xCAT::Table here. Add to each new routine # needing it to avoid reprocessing of user tables ( ExtTab.pm) for each command call -# use POSIX qw(ceil); use File::Path; use Socket; @@ -3426,10 +3425,11 @@ sub version_cmp { string of the bin file name Returns: string of the full path name of the binary executable file + string of the bin file name in the argument if failed Globals: none Error: - string of the bin file name in the argument + none Example: my $CHKCONFIG = xCAT::Utils->fullpathbin("chkconfig"); Comments: @@ -3517,4 +3517,463 @@ sub gettimezone } +#-------------------------------------------------------------------------------- + +=head3 servicemap + returns the name of service unit(for systemd) or service daemon(for SYSVinit). + Arguments: + $svcname: the name of the service + $svcmgrtype: the service manager type: + 0: SYSVinit + 1: systemd + Returns: + the name of service unit or service daemon + undef on fail + Globals: + none + Error: + None + Example: + my $svc = xCAT::Utils->servicemap($svcname,1); + Comments: + none +=cut + +#-------------------------------------------------------------------------------- +sub servicemap{ + my $svcname=shift; + if( $svcname =~ /xCAT::Utils/) + { + $svcname=shift; + } + + my $svcmgrtype=shift; + + + #hash structure: + #"service name $svcname" =>{ + #"service manager name(SYSVinit/systemd) $svcmgrtype" + #=> ["list of possible service file names for the specified $svcname under the specified $svcmgrtype "] + # } + my %svchash=( + "dhcp" => { + 0=>["dhcpd","isc-dhcp-server"], + 1=>["dhcpd.service"], + }, + "nfs" => { + 0=>["nfsserver","nfs","nfs-kernel-server"], + 1=>["nfs-server.service"], + }, + "named" => { + 0=>["named","bind9"], + 1=>["named.service"], + }, + "syslog" => { + 0=>["syslog","syslogd","rsyslog"], + 1=>["rsyslog.service"], + }, + "firewall" => { + 0=>["iptables","firewalld","SuSEfirewall2_setup"], + 1=>["firewalld.service"], + }, + "http" => { + 0=>["apache2","httpd"], + 1=>["httpd.service"], + }, + ); + + my $path=undef; + my $retdefault=$svcname; + if($svcmgrtype == 0){ + $path="/etc/init.d/"; + }elsif ($svcmgrtype == 1){ + $path="/usr/lib/systemd/system/"; + $retdefault=$svcname.".service"; + } + + + my $ret=undef; + if($svchash{$svcname} and $svchash{$svcname}{$svcmgrtype}){ + foreach my $file (@{$svchash{$svcname}{$svcmgrtype}}){ + if(-e $path.$file ){ + $ret=$file; + last; + } + } + }else{ + if(-e $path.$retdefault){ + $ret=$retdefault; + } + } + + return $ret; + +} + + +#-------------------------------------------------------------------------------- + +=head3 startservice + start a service + Arguments: + service name + Returns: + 0 on success + nonzero otherwise + Globals: + none + Error: + none + Example: + xCAT::Utils->startservice("nfs"); + Comments: + none +=cut + +#-------------------------------------------------------------------------------- +sub startservice{ + my $svcname=shift; + if( $svcname =~ /xCAT::Utils/) + { + $svcname=shift; + } + + my $cmd=""; + my $svcunit=undef; + my $svcd=undef; + + $svcunit=servicemap($svcname,1); + $svcd=servicemap($svcname,0); + if($svcunit) + { + $cmd="systemctl start $svcunit"; + } + elsif( $svcd ) + { + $cmd="service $svcd start"; + } + print "$cmd\n"; + if( $cmd eq "" ) + { + return -1; + } + + xCAT::Utils->runcmd($cmd, -1); + return $::RUNCMD_RC; +} + + +#-------------------------------------------------------------------------------- + +=head3 stopservice + stop a service + Arguments: + service name + Returns: + 0 on success + nonzero otherwise + Globals: + none + Error: + none + Example: + xCAT::Utils->stopservice("nfs"); + Comments: + none +=cut + +#-------------------------------------------------------------------------------- +sub stopservice{ + my $svcname=shift; + if( $svcname =~ /xCAT::Utils/) + { + $svcname=shift; + } + + my $cmd=""; + my $svcunit=undef; + my $svcd=undef; + + $svcunit=servicemap($svcname,1); + $svcd=servicemap($svcname,0); + if($svcunit) + { + $cmd="systemctl stop $svcunit"; + } + elsif( $svcd ) + { + $cmd="service $svcd stop"; + } + print "$cmd\n"; + if( $cmd eq "" ) + { + return -1; + } + + xCAT::Utils->runcmd($cmd, -1); + return $::RUNCMD_RC; +} + + +#-------------------------------------------------------------------------------- + +=head3 restartservice + restart a service + Arguments: + service name + Returns: + 0 on success + nonzero otherwise + Globals: + none + Error: + none + Example: + xCAT::Utils->restartservice("nfs"); + Comments: + none +=cut + +#-------------------------------------------------------------------------------- +sub restartservice{ + my $svcname=shift; + if( $svcname =~ /xCAT::Utils/) + { + $svcname=shift; + } + + my $cmd=""; + my $svcunit=undef; + my $svcd=undef; + + $svcunit=servicemap($svcname,1); + $svcd=servicemap($svcname,0); + if($svcunit) + { + $cmd="systemctl restart $svcunit"; + } + elsif( $svcd ) + { + $cmd="service $svcd restart"; + } + print "$cmd\n"; + if( $cmd eq "" ) + { + return -1; + } + + xCAT::Utils->runcmd($cmd, -1); + return $::RUNCMD_RC; +} + +#-------------------------------------------------------------------------------- + +=head3 checkservicestatus + returns theservice status. + Arguments: + $svcname: the name of the service + $outputoption[optional]: + the output option + 1: return a hashref with the keys:"retcode","retmsg" + otherwise: return retcode only + Returns: + undef on fail + a hashref if $outputoption is 1,the hash structure is: + {"retcode"=>(status code, 0 for running/active,1 for stopped/inactive,2 for failed) + "retmsg" =>(status string, running/active/stopped/inactive/failed) + } + the status code otherwise + + Globals: + none + Error: + None + Example: + my $ret = xCAT::Utils-checkservicestatus($svcname,1); + my $retcode = xCAT::Utils-checkservicestatus($svcname); + Comments: + none +=cut + +#-------------------------------------------------------------------------------- +sub checkservicestatus{ + my $svcname=shift; + if( $svcname =~ /xCAT::Utils/) + { + $svcname=shift; + } + + my $outputoption=shift; + + my $cmd=""; + my $svcunit=undef; + my $svcd=undef; + my %ret; + + $svcunit=servicemap($svcname,1); + $svcd=servicemap($svcname,0); + my $output=undef; + + if($svcunit) + { + #for systemd, parse the output since it is formatted + $cmd="systemctl show --property=ActiveState $svcunit|awk -F '=' '{print \$2}'"; + $output=xCAT::Utils->runcmd($cmd, -1); + if($output =~ /^active$/i){ + $ret{retcode}=0; + print "xxx$output\n"; + }elsif($output =~ /^failed$/i){ + $ret{retcode}=2; + + }elsif($output =~ /^inactive$/i){ + $ret{retcode}=1; + } + } + elsif( $svcd ) + { + #for SYSVinit, check the return value since the "service" command output is confused + $cmd="service $svcd status"; + $output=xCAT::Utils->runcmd($cmd, -1); + $ret{retcode}=$::RUNCMD_RC; +# if($output =~ /stopped|not running/i){ +# $ret{retcode}=1; +# }elsif($output =~ /running/i){ +# $ret{retcode}=0; +# } + } + if($output) + { + $ret{retmsg}=$output; + } + + + if(defined $outputoption and $outputoption == 1 ){ + return \%ret; + }elsif(exists $ret{retcode}){ + return $ret{retcode}; + } + + return undef; + +} + + +#-------------------------------------------------------------------------------- + +=head3 enableservice + enable a service to start it on the system bootup + Arguments: + service name + Returns: + 0 on success + nonzero otherwise + Globals: + none + Error: + none + Example: + xCAT::Utils->enableservice("nfs"); + Comments: + none +=cut + +#-------------------------------------------------------------------------------- +sub enableservice{ + my $svcname=shift; + if( $svcname =~ /xCAT::Utils/) + { + $svcname=shift; + + } + my $cmd=""; + my $svcunit=undef; + my $svcd=undef; + + $svcunit=servicemap($svcname,1); + $svcd=servicemap($svcname,0); + if($svcunit) + { + $cmd="systemctl enable $svcunit"; + } + elsif( $svcd ) + { + my $CHKCONFIG = xCAT::Utils->fullpathbin("chkconfig"); + if($CHKCONFIG ne "chkconfig"){ + $cmd="$CHKCONFIG $svcd on"; + }else{ + $CHKCONFIG = xCAT::Utils->fullpathbin("update-rc.d"); + if($CHKCONFIG ne "update-rc.d"){ + $cmd="$CHKCONFIG $svcd defaults"; + } + } + } + print "$cmd\n"; + if( $cmd eq "" ) + { + return -1; + } + + xCAT::Utils->runcmd($cmd, -1); + return $::RUNCMD_RC; +} + + +#-------------------------------------------------------------------------------- + +=head3 disableservice + disable a service to prevent it from starting on system bootup + Arguments: + service name + Returns: + 0 on success + nonzero otherwise + Globals: + none + Error: + none + Example: + xCAT::Utils->disableservice("nfs"); + Comments: + none +=cut + +#-------------------------------------------------------------------------------- +sub disableservice{ + my $svcname=shift; + if( $svcname =~ /xCAT::Utils/) + { + $svcname=shift; + + } + my $cmd=""; + my $svcunit=undef; + my $svcd=undef; + + $svcunit=servicemap($svcname,1); + $svcd=servicemap($svcname,0); + if($svcunit) + { + $cmd="systemctl disable $svcunit"; + } + elsif( $svcd ) + { + my $CHKCONFIG = xCAT::Utils->fullpathbin("chkconfig"); + if($CHKCONFIG ne "chkconfig"){ + $cmd="$CHKCONFIG $svcd off"; + }else{ + $CHKCONFIG = xCAT::Utils->fullpathbin("update-rc.d"); + if($CHKCONFIG ne "update-rc.d"){ + $cmd="$CHKCONFIG -f $svcd remove"; + } + } + } + print "$cmd\n"; + if( $cmd eq "" ) + { + return -1; + } + + xCAT::Utils->runcmd($cmd, -1); + return $::RUNCMD_RC; +} 1; diff --git a/xCAT/postscripts/xcatlib.sh b/xCAT/postscripts/xcatlib.sh index ee532258d..6bac5d0d5 100644 --- a/xCAT/postscripts/xcatlib.sh +++ b/xCAT/postscripts/xcatlib.sh @@ -266,3 +266,207 @@ function v6calcnet(){ str_v6net=`echo $str_v6net | sed 's/.$//'` echo "$str_v6net" } + + +function servicemap { + local svcname=$1 + local svcmgrtype=$2 + local svclistname= + + INIT_dhcp="dhcpd isc-dhcp-server"; + SYSTEMD_dhcp="dhcpd.service"; + + INIT_nfs="nfsserver nfs nfs-kernel-server"; + SYSTEMD_nfs="nfs-server.service"; + + INIT_named="named bind9"; + SYSTEMD_named="named.service"; + + INIT_syslog="syslog syslogd rsyslog"; + SYSTEMD_syslog="rsyslog.service"; + + INIT_firewall="iptables firewalld SuSEfirewall2_setup"; + SYSTEMD_firewall="firewalld.service"; + + INIT_http="apache2 httpd"; + SYSTEMD_http="httpd.service"; + + local path= + local retdefault=$svcname + local svcvar=${svcname//[-.]/_} + if [ "$svcmgrtype" = "0" ];then + svclistname=INIT_$svcvar + path="/etc/init.d/" + elif [ "$svcmgrtype" = "1" ];then + svclistname=SYSTEMD_$svcvar + retdefault=$svcname.service + path="/usr/lib/systemd/system/" + fi + + + local svclist=$(eval echo \$$svclistname) + + if [ -z "$svclist" ];then + svclist="$retdefault" + fi + + for name in `echo $svclist` + do + if [ -e "$path$name" ];then + echo $name + break + fi + done + +} + +function startservice { + local svcname=$1 + local cmd= + local svcunit=`servicemap $svcname 1` + local svcd=`servicemap $svcname 0` + + if [ -n "$svcunit" ];then + cmd="systemctl start $svcunit" + elif [ -n "$svcd" ];then + cmd="service $svcd start"; + fi + + if [ -z "$cmd" ];then + return 127 + fi + + eval $cmd +} + + + +function stopservice { + local svcname=$1 + local cmd= + local svcunit=`servicemap $svcname 1` + local svcd=`servicemap $svcname 0` + + if [ -n "$svcunit" ];then + cmd="systemctl stop $svcunit" + elif [ -n "$svcd" ];then + cmd="service $svcd stop"; + fi + + if [ -z "$cmd" ];then + return 127 + fi + + eval $cmd +} + + +function restartservice { + local svcname=$1 + local cmd= + local svcunit=`servicemap $svcname 1` + local svcd=`servicemap $svcname 0` + + if [ -n "$svcunit" ];then + cmd="systemctl restart $svcunit" + elif [ -n "$svcd" ];then + cmd="service $svcd restart"; + fi + + if [ -z "$cmd" ];then + return 127 + fi + + eval $cmd +} + + +function checkservicestatus { + local svcname=$1 + + local svcunit=`servicemap $svcname 1` + local svcd=`servicemap $svcname 0` + + local output= + local retcode=3 + + if [ -n "$svcunit" ];then + output=$(systemctl show --property=ActiveState $svcunit|awk -F '=' '{print $2}') + if echo $output|grep -E -i "^active$";then + retcode=0 + elif echo $output|grep -E -i "^inactive$";then + retcode=1 + elif echo $output|grep -E -i "^failed$";then + retcode=2 + fi + elif [ -n "$svcd" ];then + output=$(service $svcd status) + retcode=$? + echo $output +# if echo $output|grep -E -i "(stopped|not running)";then +# retcode=1 +# elif echo $output|grep -E -i "running";then +# retcode=0 +# fi + else + retcode=127 + fi + + return $retcode + +} + +function enableservice { + local svcname=$1 + local cmd= + local svcunit=`servicemap $svcname 1` + local svcd=`servicemap $svcname 0` + + if [ -n "$svcunit" ];then + cmd="systemctl enable $svcunit" + elif [ -n "$svcd" ];then + command -v chkconfig >/dev/null 2>&1 + if [ $? -eq 0 ];then + cmd="chkconfig $svcd on"; + else + command -v update-rc.d >/dev/null 2>&1 + if [ $? -eq 0 ];then + cmd="update-rc.d $svcd defaults" + fi + fi + fi + + if [ -z "$cmd" ];then + return 127 + fi + + eval $cmd +} + + +function disableservice { + local svcname=$1 + local cmd= + local svcunit=`servicemap $svcname 1` + local svcd=`servicemap $svcname 0` + + if [ -n "$svcunit" ];then + cmd="systemctl disable $svcunit" + elif [ -n "$svcd" ];then + command -v chkconfig >/dev/null 2>&1 + if [ $? -eq 0 ];then + cmd="chkconfig $svcd off"; + else + command -v update-rc.d >/dev/null 2>&1 + if [ $? -eq 0 ];then + cmd="update-rc.d -f $svcd remove" + fi + fi + fi + + if [ -z "$cmd" ];then + return 127 + fi + + eval $cmd +}