#!/bin/bash #============================================================================== # Copyright and license info is available in the LICENSE file included with # the Server Deployment Package (SDP), and also available online: # https://swarm.workshop.perforce.com/projects/vdsl/files/main/src/LICENSE #------------------------------------------------------------------------------ set -u #============================================================================== # Declarations and Environment export VCC2P4_HOME=${VCC2P4_HOME:-$(dirname $PWD)} # Allow override of P4U_HOME, which is set only when testing P4U scripts. export P4U_HOME=${P4U_HOME:-$VCC2P4_HOME/utils} export P4U_LIB=${P4U_LIB:-$P4U_HOME} export P4U_ENV=$P4U_LIB/p4u_env.sh Timestamp=$(date +'%Y%m%d-%H%M%S') export P4U_LOG="$PWD/logs/vdsl.${Timestamp}.log" export VERBOSITY=${VERBOSITY:-3} # Environment isolation. For stability and security reasons, prepend # PATH to include dirs where known-good scripts exist. # known/tested PATH and, by implication, executables on the PATH. export PATH=$P4U_HOME:$PATH:~/bin:. export P4CONFIG=${P4CONFIG:-.p4config} export CT=$(which cleartool 2>/dev/null) [[ -r "$P4U_ENV" ]] || { echo -e "\nError: Cannot load environment from: $P4U_ENV\n\n" exit 1 } declare BASH_LIBS=$P4U_ENV BASH_LIBS+=" $P4U_LIB/libcore.sh" BASH_LIBS+=" $P4U_LIB/libp4u.sh" for bash_lib in $BASH_LIBS; do source $bash_lib ||\ { echo -e "\nFATAL: Failed to load bash lib [$bash_lib]. Aborting.\n"; exit 1; } done declare Version=1.2.0 DefaultCfgFile=ACTIONS.cfg declare KeyboardInputYes=$PWD/KeyboardInputYes.txt declare -i SilentMode=0 declare -i OverallReturnStatus=0 #============================================================================== # Local Functions #------------------------------------------------------------------------------ # Function: terminate function terminate { # Disable signal trapping. trap - EXIT SIGINT SIGTERM # Don't litter. cleanTrash vvmsg "$THISSCRIPT: EXITCODE: $OverallReturnStatus" # Stop logging. [[ "${P4U_LOG}" == off ]] || stoplog # With the trap removed, exit. exit $OverallReturnStatus } #------------------------------------------------------------------------------ # Function: usage (required function) # # Input: # $1 - style, either -h (for short form) or -man (for man-page like format). #------------------------------------------------------------------------------ function usage { declare style=${1:--h} echo "USAGE for $THISSCRIPT v$Version: $THISSCRIPT [-c <cfg_file>] [-L <log>] [-si] [-v<n>] [-n] [-D] or $THISSCRIPT [-h|-man] " if [[ $style == -man ]]; then echo -e " DESCRIPTION: VOB Data Set Loader (vdsl) This parses a special config file that is essentially a language for executing an ordered sequence of ClearCase actions, such as creating VOBs and views, and executing custom scripts to execute various file actions such as adds, edits, renames, deletes, etc.. This enables simulation of history or loading of history into ClearCase. CONFIG FILE FORMAT: See the *.cfg files in this directory for samples of format. The format allows for variable definitions and verbs. For example, the VOBSTORE variable defines where VOBs are store, and CS defines the config spec of the next view to be created. Some Verbs included are: * TITLE - Defines a title * SCRIPT - Defines a custom action script to run in a view. * RUN - Runs an action script in a view. * RMVOB - Removes a VOB. * MKVOB - Makes a VOB. * RMVIEW - Removes a view. * MKVIEW - Makes a view. * EXTRACT - Call the VCC2P4 tool to extract history. * CAPTURE - Capture extracted history results. * END - Stop processing. The language includes a verb to capture the state of the resulting file structure from any view (e.g. from the perspective of different branches). The language includes a verb to run a VCC2P4 Extraction Phase, capturing resulting data. OPTIONS: -c <cfg_file> Specify the config file to use. Default is: $DefaultCfgFile. -v<n> Set verbosity 1-5 (-v1 = quiet, -v5 = highest). -L <log> Specify the path to a log file, or the special value 'off' to disable logging. By default, all output (stdout and stderr) goes to: $(dirname ${P4U_LOG}). NOTE: This script is self-logging. That is, output displayed on the screen is simultaneously captured in a log file. Do not run this script with redirection operators like '> log' or '2>&1', and do not use 'tee.' -si Operate silently. All output (stdout and stderr) is redirected to the log only; no output appears on the terminal. This cannot be used with '-L off'. -n No-Op. Prints commands instead of running them. -D Set extreme debugging verbosity. HELP OPTIONS: -h Display short help message -man Display man-style help message DEPENDENCIES: This tool requires that the following software be installed: * IBM Rational ClearCase, with cleartool in the PATH. * VCC2P4 (VIZIM ClearCase to Perforce detailed history import tool), with VCC2P4_HOME variable defined. This implies other dependencies, including Perl and a few Perl modules available from CPAN, the Contributed Perl Archive Network (a freely available repository of open source Perl modules). * Bash shell and a Unix/Linux environment. " fi exit 1 } #============================================================================== # Command Line Processing declare CfgFile=$DefaultCfgFile declare -i shiftArgs=0 set +u while [[ $# -gt 0 ]]; do case $1 in (-c) CfgFile=$2; shiftArgs=1;; (-h) usage -h;; (-man) usage -man;; (-V) show_versions; exit 1;; (-v1) export VERBOSITY=1;; (-v2) export VERBOSITY=2;; (-v3) export VERBOSITY=3;; (-v4) export VERBOSITY=4;; (-v5) export VERBOSITY=5;; (-L) export P4U_LOG=$2; shiftArgs=1;; (-si) SilentMode=1;; (-n) export NO_OP=1;; (-D) set -x;; # Debug; use 'set -x' mode. (*) usageError "Unknown arg ($1).";; esac # Shift (modify $#) the appropriate number of times. shift; while [[ $shiftArgs -gt 0 ]]; do [[ $# -eq 0 ]] && usageError "Bad usage." shiftArgs=$shiftArgs-1 shift done done set -u #============================================================================== # Command Line Verification [[ $SilentMode -eq 1 && $P4U_LOG == off ]] && \ usageError "Cannot use '-si' with '-L off'." [[ ! -r $CfgFile ]] && \ usageError "Cannot find config file [$CfgFile]. Aborting." #============================================================================== # Main Program trap terminate EXIT SIGINT SIGTERM if [[ "${P4U_LOG}" != off ]]; then touch ${P4U_LOG} || bail "Couldn't touch log file [${P4U_LOG}]." # Redirect stdout and stderr to a log file. if [[ $SilentMode -eq 0 ]]; then exec > >(tee ${P4U_LOG}) exec 2>&1 else exec >${P4U_LOG} exec 2>&1 fi initlog fi export CC_VOB_PREFIX=UNDEFINED export CC_TEST_MODE=UNDEFINED export CC_LINK_VOB=UNDEFINED export VOBSTORE=UNDEFINED export VOBEXT=UNDEFINED export VOBBASE=UNDEFINED export VOB=UNDEFINED export TITLE=UNDEFINED export VIEW=UNDEFINED export VIEWSTORE=UNDEFINED export VIEWEXT=UNDEFINED export CS=UNDEFINED export TOPDIR=UNDEFINED export ACTION_ID=0 ActionScript=UNDEFINED ExtractScript=UNDEFINED CSFile=/tmp/tmp.config_spec.$$ GARBAGE+=$CSFile if [[ -z "$CT" ]]; then if [[ $NO_OP -eq 1 ]]; then warnmsg "The cleartool utility was not found on the PATH. Action processing will fail. Proceeding in NO_OP mode anyway." else bail "The cleartool utility was not found on the PATH. Action processing will fail. Aborting." fi else msg "Verified: The cleartool utility was found on the PATH." fi if [[ "$VCC2P4_HOME" == "$(dirname $PWD)" ]]; then if [[ $NO_OP -eq 1 ]]; then warnmsg "VCC2P4_HOME was not defined. EXTRACT and CAPTURE actions will fail. Proceeding in NO_OP mode anyway." else warnmsg "VCC2P4_HOME was not defined. EXTRACT and CAPTURE actions will fail. Proceeding anyway." fi else msg "Verified: VCC2P4_HOME is defined." fi msg "Preparing for clean start." runCmd "/bin/rm -rf CONTENT EXTRACT CONTENT.tar.gz EXTRACT.tar.gz" \ "Blasting old CONTENT and EXTRACT dirs." ||\ bail "Failed to cleanup from prior runs. Aborting." runCmd "/bin/cp -vpr CONTENT.orig CONTENT" \ "Creating new CONTENT dir." ||\ bail "Failed to creatre new CONTENT dir." runCmd "/bin/cp -vpr EXTRACT.orig EXTRACT" \ "Creating new EXTRACT dir." ||\ bail "Failed to creatre new EXTRACT dir." msg "Reading actions from $CfgFile." while read line; do case $line in (TITLE=*) eval export $line msg "================= SECTION: $TITLE ==================\n\n" ;; (CC_VOB_PREFIX=*|CC_TEST_MODE=*|CC_LINK_VOB=*|VOBSTORE=*|VOBEXT=*|VOBBASE=*|VOB=*|VIEW=*|VIEWSTORE=*|VIEWEXT=*|CS=*|TOPDIR=*|ACTION_ID=*) msg "ENV: export $line" eval export $line ;; (SCRIPT:) ActionScript=/tmp/actions.$ACTION_ID.sh msg "Processing SCRIPT: directive, generating Action Script [$ActionScript] to run in view [$VIEW]." echo "#!/bin/bash" > $ActionScript echo -e "# Generated action script $ActionScript.\n" >> $ActionScript for var in VOBSTORE VOBEXT VOBBASE VOB TITLE VIEW VIEWSTORE VIEWEXT TOPDIR ACTION_ID; do echo "export $var=$(eval echo \$$var)" >> $ActionScript done ;; (RMVOB) msg "Processing RMVOB directive." runCmd "cleartool lsvob $VOBBASE/$VOB" \ "Checking to see if VOB $VOBBASE/$VOB exists." if [[ $CMDEXITCODE -eq 0 ]]; then runCmd "cleartool umount $VOBBASE/$VOB" \ "Unmounting VOB [$VOBBASE/$VOB]." runCmd "cleartool rmvob -force $VOBSTORE/${VOB}${VOBEXT}" \ "Removing VOB $VOBBASE/$VOB." || \ bail "Failed to remove VOB $VOBBASE/$VOB." else msg "No VOB $VOBBASE/$VOB exists; skipping VOB removal." fi ;; (MKVOB) msg "Processing MKVOB directive." runCmd "cleartool lsvob $VOBBASE/$VOB" \ "Checking to see if VOB $VOBBASE/$VOB exists." if [[ $CMDEXITCODE -eq 1 ]]; then CCRgyPassword=$(cat /home/clearcase/bin/.vob_registry_password) runCmd "cleartool mkvob -tag $VOBBASE/$VOB -public -pas $CCRgyPassword -c TESTDATA $VOBSTORE/${VOB}${VOBEXT}" \ "Creating test VOB $VOBBASE/$VOB." ||\ bail "Failed to remove VOB $VOBBASE/$VOB." runCmd "cleartool mount $VOBBASE/$VOB" \ "Mounting VOB [$VOBBASE/$VOB]." else msg "VOB $VOBBASE/$VOB already exists; skipping VOB creation." fi ;; (RMVIEW) msg "Processing RMVIEW directive." runCmd "cleartool lsview $VIEW" \ "Checking to see if view [$VIEW] exists." if [[ $CMDEXITCODE -eq 0 ]]; then runCmd "cleartool rmview -force -tag $VIEW" \ "Removing view [$VIEW]." ||\ bail "Failed to remove view $VIEW." else msg "View [$VIEW] does not exist; skipping view removal." fi ;; (MKVIEW) msg "Processing MKVIEW directive." runCmd "cleartool lsview $VIEW" \ "Checking to see if view [$VIEW] exists." if [[ $CMDEXITCODE -eq 1 ]]; then runCmd "cleartool mkview -tag $VIEW $VIEWSTORE/${VIEW}${VIEWEXT}" \ "Creating view [$VIEW]." ||\ bail "Failed to create view [$VIEW]." else msg "View [$VIEW] already exists; skipping view creation." fi echo $CS | sed "s:__N__:\n:g" > $CSFile msg "Contents of config spec file [$CSFile]:" cat $CSFile runCmd "cleartool setcs -tag $VIEW $CSFile" \ "Setting config spec for view [$VIEW]." ;; (RUN) msg "Processing RUN directive. Contents of action script:" cat $ActionScript chmod +x $ActionScript msg "Running Action Script [$ActionScript] in view [$VIEW]." runCmd "cleartool setview -exec $ActionScript $VIEW" ;; (EXTRACT) msg "Processing EXTRACT directive." ExtractDir=$PWD/EXTRACT/$TITLE.$ACTION_ID ExtractScript=$PWD/EXTRACT/extract.$TITLE.$ACTION_ID.sh runCmd "/bin/mkdir -vp $ExtractDir" \ "Creating extraction dir [$ExtractDir]." 0 echo "#!/bin/bash" > $ExtractScript echo "export CC_VOB_PREFIX=$VOBBASE/$VOB" >> $ExtractScript echo "export CC_TEST_MODE=0" >> $ExtractScript echo "export CC_LINK_VOB=$CC_VOB_PREFIX" >> $ExtractScript echo "cd $CC_VOB_PREFIX" >> $ExtractScript echo "cleartool find -all -visible -type f -print > $ExtractDir/fx.in" >> $ExtractScript echo "cleartool find -all -nvisible -type f -print >> $ExtractDir/fx.in" >> $ExtractScript echo "cleartool find -all -visible -type d -print > $ExtractDir/dx.in" >> $ExtractScript echo "cleartool find -all -nvisible -type d -print >> $ExtractDir/dx.in" >> $ExtractScript echo "cd $ExtractDir" >> $ExtractScript echo "fxraw.pl fx.in" >> $ExtractScript #echo "fxraw2db.pl fxraw.raw" >> $ExtractScript echo "dxraw.pl dx.in" >> $ExtractScript #echo "dxraw2db.pl dxraw.raw" >> $ExtractScript #echo "DBINOScan.pl fxdb.db" >> $ExtractScript #echo "DBINOScan.pl dxdb.db" >> $ExtractScript #echo "DBAliasScan.pl fxdb.db" >> $ExtractScript #echo "DBAliasScan.pl dxdb.db" >> $ExtractScript # Skip Control Generation (cg.pl) and vcc2p4.pl parts. msg "Contents of Extract Script [$ExtractScript]:" cat $ExtractScript chmod +x $ExtractScript runCmd "cleartool setview -exec $ExtractScript $VIEW" \ "Running Extract Script [$ExtractScript] in view [$VIEW]." if [[ $CMDEXITCODE -ne 0 ]]; then errmsg "Extraction failed." OverallReturnStatus=1 fi ;; (CAPTURE=*) CaptureTag=${line#CAPTURE=} msg "Processing CAPTURE directive [$CaptureTag]." CaptureDir=$PWD/CONTENT/$CaptureTag CaptureScript=$PWD/CONTENT/capture.$TITLE.$CaptureTag.sh runCmd "/bin/mkdir -p $CaptureDir" \ "Creating capture dir [$CaptureDir]." ||\ bail "Failed to create dir [$CaptureDir]." echo "#!/bin/bash" > $CaptureScript echo "/bin/cp -vpr $VOBBASE/$VOB/HL $CaptureDir/." >> $CaptureScript msg "Contents of Capture Script [$CaptureScript]:" cat $CaptureScript chmod +x $CaptureScript runCmd "cleartool setview -exec $CaptureScript $VIEW" \ "Running Capture Script [$CaptureScript] in view [$VIEW]." if [[ $CMDEXITCODE -ne 0 ]]; then errmsg "Capture failed." OverallReturnStatus=1 fi [[ -r "$CaptureScript" ]] && /bin/rm -f "$CaptureScript" ;; (END) break ;; ("") ;; (\#*) ;; (*) #vmsg "Appending line [$line] to action script $ActionScript." echo $line | sed "s:__MACRO_ALL_FILES__:\$(cleartool lsco -all -short):g" |\ sed "s:__MACRO_KEYBOARD_INPUT_YES__: < $KeyboardInputYes:g" >> $ActionScript ;; esac done < $CfgFile runCmd "tar -cvzpf logs/CONTENT.${Timestamp}.tar.gz CONTENT" \ "Packaging up CONTENT tarfile." runCmd "tar -cvzpf logs/EXTRACT.${Timestamp}.tar.gz EXTRACT" \ "Packaging EXTRACT tarfile." if [[ $OverallReturnStatus -eq 0 ]]; then msg "${H}\nAll processing completed successfully.\n" else msg "${H}\nProcessing completed, but with errors. Scan above output carefully.\n" fi # Illustrate using $SECONDS to display runtime of a script. msg "That took about $(($SECONDS/3600)) hours $(($SECONDS%3600/60)) minutes $(($SECONDS%60)) seconds.\n" # See the terminate() function, which is really where this script exits. exit $OverallReturnStatus
# | Change | User | Description | Committed | |
---|---|---|---|---|---|
#7 | 25065 | C. Thomas Tyler |
vdsl v1.2.0: * Added README page in Markdown format, complying with Workshop style. * Enhanced script docs. * Added dependency checks and warnings. * Branched local copies of bash script libraries from the to remove dependence on that package for local testing, so at least '-h' and '-man' can be run without errors. * No functionality changes other than new behaviors for failed dependency checks. #review @neal_firth |
||
#6 | 8844 | C. Thomas Tyler |
vdsl.sh v1.1.8: * Added new macro to better simulate keyboard input. * Normalized macro names to use '__' pre/postfix. * Made corresponding changes to ACTIONS.cfg to use the macro for all 'cleartool findmerge' commands. Other: * Removed a duplicate/bugus CAPTURE HL_E2 tag in ACTIONS.cfg |
||
#5 | 8837 | C. Thomas Tyler |
vdsl v1.1.7: Bug fix: Extraction scripts were overwritten when more than one extraction was run with the same TITLE block. Fixed. Now captureis CONTENT and EXTRACT result dirs as tar files. |
||
#4 | 8834 | C. Thomas Tyler |
Completed translating ACTIONS.txt format to ACTIONS.cfg. Minor enhancements to vdsl.sh. |
||
#3 | 8829 | C. Thomas Tyler | Tweaked to use 'logs' subdir. | ||
#2 | 8826 | C. Thomas Tyler |
First apparently successful dry run, with a partial config file. |
||
#1 | 8824 | C. Thomas Tyler | Added vdsl v1.0.0 (WIP). |