Sunday, June 15, 2014

Unix Shell Example: Software Builds Automation(3)

 build_one()  
 {  
   #Usage: build_one [user@]host[:build_directory][,envfile]  
   
   arg="`eval echo $1`"  
   
   #remove everything after ":", to extract the userhost  
   userhost="`echo $arg | sed -e 's/:.*$//'`"  
   
   #For userhost, remove everything after(including) "@", to  
   #extract user  
   user="`echo $userhost | sed -e s'/@.*$//'`"  
   
   #Test if the extraction is successful, if there is no "@"  
   #in userhost, meaning that the entire string is host  
   test "$user" = "$userhost" && user=$USER   
   
   #For userhost, remove everything before(including)"@", to  
   #extract host  
   host="`echo $userhost | sed -e s'/^[^@]*@//'`"  
   
   #For input argument, remove everything before ",", to extract  
   #envfile  
   envfile="`echo $arg | sed -e 's/^[^,]*,//'`"  
   
   #If extraction failed, then there is no "," in input string  
   #meaning that user doesn't provide the envfile, at this time  
   #we should make envfile as "/dev/null"  
   test "$envfile" = "$arg" && envfile=/dev/null  
   builddir="`echo $arg | sed -e s'/^.*://' -e 's/,.*//'`"  
   test "$buildir" = "$arg" && builddir=/tmp  
   
   #We use sed to remove the suffix of package name  
   package="`echo $parbase | \  
        sed -e 's/[.]jar$//' \  
          -e 's/[.]tar[.]bz2$//' \  
          -e 's/[.]tar[.]gz$//' \  
          -e 's/[.]tar[.]Z$//' \  
          -e 's/[.]tar$//' \  
          -e 's/[.]tgz$//' \  
          -e 's/[.]zip$//'`"  
   
   #SSH is used to connect to user host and run command  
   #"test -f $PARFILE" there, we are testing if the file  
   #is already there. If not, we use SCP to copy the file  
   #to userhost's build directory  
   if $SSH $SSHFLAGS $userhost "test -f $PARFILE"  
   then  
     parbaselocal=$PARFILE  
   else  
     parbaselocal=$parbase  
     $SCP $PARFILE $userhost:$builddir  
   fi  
   
   #In order to ensure that we have unique log name for   
   #every logfile, we use the current date time as part  
   #of log file name. Sleep 1 making sure every time we   
   #create the log file name, we sleep for 1 second, then  
   #generated date time is distinct   
   sleep 1  
   now="`date $DATEFLAGS`"  
   logfile="$package.$host.$now.log"  
   
   #Following statements are run at remote user host, we use  
   #nice command to lower the priority to give more resources  
   #to interactive applications  
   
   #. and source command is used to run the given script here  
   #In some systems, if . or source command fail, the entire execution  
   #fail, we add the existance check before . and source command  
   #We add both commands here for portability issue, some system supports  
   #., some system supports source  
   
   #uname command is used to output current host system information  
   #uname -a command is used to output detailed host system information  
   
   #Before building the package, we need to put enough information into   
   #logs, including the host, user, directory, configure file, environment  
   #disk space, etc.  
   nice $SSH $SSHFLAGS $userhost "  
     test -f $BUILDBEGIN && . $BUILDBEGIN || \  
       test -f $BUILDBEGIN && source $BUILDBEGIN || true;  
     echo 'Package:       $package';  
     echo 'Archive:       $PARFILE';  
     echo 'Date:        $now';  
     echo 'Local User:     $USER';  
     echo 'Local Host:     `hostname`';  
     echo 'Local log directory: $LOGDIR';  
     echo 'Local log file:   $logfile';  
     echo 'Remote User:     $user';  
     echo 'Remote Host:     $host';  
     echo 'Remote Directory:  $builddir';  
     printf 'Remote date:        ';  
     date $DATEFLAGS;  
     printf 'Remote uname:        ';  
     uname -a || true;  
     printf 'Remote gcc version:     ';  
     gcc --version | head -n 1 || echo ;  
     printf 'Remote g++ version:     ';  
     g++ --version | head -n 1 || echo ;    
     echo 'Configure environment: `$STRIPCOMMENTS $envfile | $JOINLINE`';  
     echo 'Extra environment:   $EXTRAENVIRONMENT';  
     echo 'Configure directory:  $CONFIGUREDIR';  
     echo 'Extra environment:   $EXTRAENVIRONMENT';  
     echo 'Configure directory:  $CONFIGUREDIR';  
     echo 'Configure flags:    $CONFIGUREFLAGS';  
     echo 'Make all targets:   $ALLTARGETS';  
     echo 'Make check targets:  $CHECKTARGETS';  
     echo 'Disk free report for: $builddir/$package';  
     df $builddir | $INDENT;      
     echo 'Environment:';  
     env | env LC_ALL=C sort | $INDENT;  
   
     umask $UMASK; #setup the default file permission  
     cd $builddir || exit 1; #enter the build directory, package is already there  
     /bin/rm -rf $builddir/$package;  
   
     $PAR $parbaselocal; #unpack the package  
     test "$parbase" = "$parbaselocal" && /bin/rm -f $parbase;  
     #parbase shall be removed in this case, since it is not needed anymore  
   
     cd $package/$CONFIGUREDIR || exit 1  
    
     #Configure the environment before really building package  
     test -f configure && chmod a+x configure && \  
       env `$STRIPCOMMENTS $envfile | $JOINLINES` \  
         $EXTRAENVIRONMENT \  
           nice time./configure $CONFIGUREFLAGS  
   
     #build the package  
     nice time make $ALLTARGETS && nice time make $CHECKTARGETS;  
   
     #print the disk space after building the package  
     df $builddir | $INDENT  
     printf 'Remote date:  ';  
     date $DATEFLAGS;  
   
     #BUILDEND script will do wrap-up job, like final additional log-file  
     #reporting  
     test -f $BUILDEND && . $BUILDEND || \  
       test -f $BUILDEND && source $BUILDEND || \  
         true;  
     " < /dev/null > "$LOGDIR/$logfile" 2>&1 &  
 }  
   

No comments:

Post a Comment