@echo off
REM Copyright (c) 2009 Exemplics LLC
REM Permission is hereby granted, free of charge, to any person obtaining a copy
REM of this software and associated documentation files (the "Software"), to deal
REM in the Software without restriction, including without limitation the rights
REM to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
REM copies of the Software, and to permit persons to whom the Software is
REM furnished to do so, subject to the following conditions:
REM The above copyright notice and this permission notice shall be included in
REM all copies or substantial portions of the Software.
REM THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
REM IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
REM FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
REM AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
REM LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
REM OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
REM THE SOFTWARE.
REM Version 2009.2
goto Initialize:
REM <Functions>
:StartProcedure
REM delayed expansion must be disabled so the ! character can be echoed
setlocal DisableDelayedExpansion
echo ^<?xml version="1.0" encoding="UTF-8"?^> > %xmlOut%
if defined includeStyleSheet (
echo ^<?xml-stylesheet type="text/xsl" href="PerforceBackupProcedureHTML.xsl"?^> >> %xmlOut%
)
echo ^<!DOCTYPE BackupProcedure^> >> %xmlOut%
echo ^<BackupProcedure ServerShortName="%serverShortName%" CheckpointNumber="%checkpointNumber%" BackupType="%backupType%"^> >> %xmlOut%
goto :Eof
:P4Info
setlocal EnableDelayedExpansion
pushd "%workspace%"
echo ^<P4Info^> >> %xmlOut%
for /f "delims=: tokens=1,*" %%i in ('p4 info') do (
set rawValue=%%j
REM Strip off the leading space.
set value=!rawValue:~1!
echo ^<Variable Name="%%i" Value="!value!" /^> >> %xmlOut%
)
echo ^</P4Info^> >> %xmlOut%
popd
goto :Eof
:Environment
setlocal EnableDelayedExpansion
echo ^<Environment^> >> %xmlOut%
for /f "tokens=1,2 delims==" %%i in ('set') do (
set rawValue=%%j
REM Replace " characters with equivalent xml entities.
set value=!rawValue:"="!
echo ^<Variable Name="%%i" Value="!value!" /^> >> %xmlOut%
)
echo ^</Environment^> >> %xmlOut%
goto :Eof
:StartSteps
echo ^<Steps^> >> %xmlOut%
goto :Eof
:Steps
REM Verify and checkpoint Perforce database.
REM Do not backup if an error occurs here.
call :Verify
if ERRORLEVEL 1 goto :Eof
call :SearchVerifyOutput
if ERRORLEVEL 1 goto :Eof
call :Checkpoint
if ERRORLEVEL 1 goto :Eof
REM Restore the checkpoint and verify it.
REM Continue to backup even if these fail.
call :Restore
call :TestRestore
call :Backup
goto :Eof
:Verify
REM delayed expansion must be disabled so the ! character can be echoed
setlocal DisableDelayedExpansion
pushd "%workspace%"
set startTime=%DATE% %TIME:~0,-3%
set output=%verifyOut%
set command=p4 verify //...
echo ^<Step Name="Verify"^> >> %xmlOut%
call :P4Set
echo ^<Command CurrentDirectory="%CD%"^>^<![CDATA[%command%]]^>^</Command^> >> %xmlOut%
echo ^<ConsoleText^>^<![CDATA[ >> %xmlOut%
if defined runCommands %command% > "%output%" 2>> %xmlOut%
set result=%ERRORLEVEL%
echo ]]^>^</ConsoleText^> >> %xmlOut%
call :StartOutputs
call :File "%output%" VerificationResultsFile
call :EndOutputs
echo ^<Summary ResultCode="%result%" StartTime="%startTime%" EndTime="%DATE% %TIME:~0,-3%" /^> >> %xmlOut%
echo ^</Step^> >> %xmlOut%
popd
exit /b %result%
:SearchVerifyOutput
REM Look for lines ending in ! (MISSING! or BAD!)
REM delayed expansion must be disabled so the ! character can be echoed
setlocal DisableDelayedExpansion
set startTime=%DATE% %TIME:~0,-3%
set command=findstr /e ! "%verifyOut%"
echo ^<Step Name="SearchVerifyOutput"^> >> %xmlOut%
echo ^<Command CurrentDirectory="%CD%"^>^<![CDATA[%command%]]^>^</Command^> >> %xmlOut%
call :StartInputs
call :File "%verifyOut%" VerificationResultsFile
call :EndInputs
echo ^<ConsoleText^>^<![CDATA[ >> %xmlOut%
if defined runCommands (
%command% >> %xmlOut% 2>&1
if ERRORLEVEL 1 (
REM not finding a line ending with ! is a good thing
set result=0
) else (
set result=1
)
) else (
REM Succeed if in test mode
set result=0
)
echo ]]^>^</ConsoleText^> >> %xmlOut%
echo ^<Summary ResultCode="%result%" StartTime="%startTime%" EndTime="%DATE% %TIME:~0,-3%" /^> >> %xmlOut%
echo ^</Step^> >> %xmlOut%
exit /b %result%
:Checkpoint
REM delayed expansion must be disabled so the ! character can be echoed
setlocal DisableDelayedExpansion
pushd "%workspace%"
set startTime=%DATE% %TIME:~0,-3%
set output=%checkpoint%
set command=p4 admin checkpoint -z
echo ^<Step Name="Checkpoint"^> >> %xmlOut%
call :P4Set
echo ^<Command CurrentDirectory="%CD%"^>^<![CDATA[%command%]]^>^</Command^> >> %xmlOut%
echo ^<ConsoleText^>^<![CDATA[ >> %xmlOut%
if defined runCommands %command% >> %xmlOut% 2>&1
set result=%ERRORLEVEL%
echo ]]^>^</ConsoleText^> >> %xmlOut%
call :StartOutputs
call :File "%output%" CheckpointFile
call :EndOutputs
echo ^<Summary ResultCode="%result%" StartTime="%startTime%" EndTime="%DATE% %TIME:~0,-3%" /^> >> %xmlOut%
echo ^</Step^> >> %xmlOut%
popd
exit /b %result%
:Restore
REM Test restore the checkpoint
REM delayed expansion must be disabled so the ! character can be echoed
setlocal DisableDelayedExpansion
REM Start with a clean folder
rd /q/s "%restoreOut%" 2> nul
mkdir "%restoreOut%" 2> nul
pushd "%restoreOut%"
set startTime=%DATE% %TIME:~0,-3%
set command=p4d -jr -z "%checkpoint%"
echo ^<Step Name="Restore"^> >> %xmlOut%
call :P4Set
call :StartInputs
call :File "%checkpoint%" CheckpointFile
call :EndInputs
echo ^<Command CurrentDirectory="%CD%"^>^<![CDATA[%command%]]^>^</Command^> >> %xmlOut%
echo ^<ConsoleText^>^<![CDATA[ >> %xmlOut%
if defined runCommands %command% >> %xmlOut% 2>&1
set result=%ERRORLEVEL%
echo ]]^>^</ConsoleText^> >> %xmlOut%
echo ^<Summary ResultCode="%result%" StartTime="%startTime%" EndTime="%DATE% %TIME:~0,-3%" /^> >> %xmlOut%
echo ^</Step^> >> %xmlOut%
popd
exit /b %result%
:TestRestore
setlocal EnableDelayedExpansion
REM Verify test restore of the checkpoint
pushd "%restoreOut%"
set startTime=%DATE% %TIME:~0,-3%
echo ^<Step Name="TestRestore"^> >> %xmlOut%
echo ^<Command CurrentDirectory="%CD%"^>^</Command^> >> %xmlOut%
REM Verify directory contents (db.*)
set actual=
for %%i in (*) do set actual=!actual! %%i
set expected= db.archmap db.boddate db.bodtext db.change db.changex db.counters db.depot db.desc db.domain db.fix db.fixrev db.group db.have db.integ db.integed db.ixdate db.ixtext db.job db.jobdesc db.label db.locks db.logger db.message db.monitor db.protect db.resolve db.rev db.revcx db.revdx db.revhx db.review db.revpx db.revsx db.traits db.trigger db.user db.view db.working
if "!actual!"=="%expected%" (
set result=0
) else (
set result=1
)
echo ^<Summary ResultCode="%result%" StartTime="%startTime%" EndTime="%DATE% %TIME:~0,-3%" Actual="!actual!" Expected="%expected%"/^> >> %xmlOut%
echo ^</Step^> >> %xmlOut%
popd
exit /b %result%
:Backup
setlocal EnableDelayedExpansion
pushd "%workspace%"
set licenseFile=%serverRoot%\license
set description=%backupType% backup of %serverRoot% checkpoint %checkpointNumber% %DATE% %TIME:~0,-3%
set job=%serverShortName% %checkpointNumber%
set backupFile=%backupDirectory%\%serverShortName%.%checkpointNumber%.%backupType%.bkf
set backupLog=%outputPathPrefix%.Backup.txt
REM /v:yes = verify data after backup
REM /l:f = full log
REM /snap:on = snapshot of the data at the time the backup began
set verifyData=yes
set logType=f
set snap=on
REM Where backup items list will be saved
set backupSelectionFile=%outputPathPrefix%.bks
set startTime=%DATE% %TIME:~0,-3%
set output=%backupFile%
echo ^<Step Name="Backup"^> >> %xmlOut%
call :StartInputs
REM "cmd /u /c echo" is used to output the backup items
REM to the backup selection file in "unicode" format.
if exist "%licenseFile%" (
REM licensed server
call :File "%licenseFile%" ServerLicenseFile
cmd /u /c echo %licenseFile% > "%backupSelectionFile%"
call :File "%checkpoint%" CheckpointFile
cmd /u /c echo %checkpoint% >> "%backupSelectionFile%"
) else (
call :File "%checkpoint%" CheckpointFile
cmd /u /c echo %checkpoint% > "%backupSelectionFile%"
)
for /f "tokens=4,*" %%i in ('p4 depots') do (
set localOrSpec=false
if %%i==local set localOrSpec=true
if %%i==spec set localOrSpec=true
if !localOrSpec!==true (
REM Depot Description starts with '.
REM The path we want comes before that.
for /f "tokens=1 delims='" %%n in ("%%j") do (
set rawValue=%%n
REM strip the trailing "/... "
set versionedFileTree=!rawValue:~0,-5!
set isAbsolute=false
REM Path is absolute path if it starts with / or drive letter.
REM The first case should not happen on Windows
if "!versionedFileTree:~0,1!"=="/" set isAbsolute=true
if "!versionedFileTree:~1,1!"==":" set isAbsolute=true
if !isAbsolute!==true (
REM replace pathname delimiter / with \
set versionedFileTree=!versionedFileTree:/=\!
) else (
set versionedFileTree=%serverRoot%\!versionedFileTree!
)
REM Check to see if the directory exists.
REM It will not if no files have been added to its depot.
dir /b "!versionedFileTree!" > nul 2>&1
if not ERRORLEVEL 1 (
REM The directory does exist.
REM "cmd /u /c echo" is used to output the
REM backup items to the backup selection file in
REM "unicode" format. Directories must end with "\".
cmd /u /c echo !versionedFileTree!\ >> "%backupSelectionFile%"
call :Directory "!versionedFileTree!" DepotVersionedFileTree
)
)
)
)
call :EndInputs
set command=ntbackup backup "@%backupSelectionFile%" /m %backupType% /d "%description%" /j "%job%" /v:%verifyData% /l:%logType% /snap:%snap% /f "%backupFile%"
setlocal DisableDelayedExpansion
echo ^<Command CurrentDirectory="%CD%"^>^<![CDATA[%command%]]^>^</Command^> >> %xmlOut%
echo ^<ConsoleText^>^<![CDATA[ >> %xmlOut%
if defined runCommands %command% >> %xmlOut% 2>&1
set result=%ERRORLEVEL%
echo ]]^>^</ConsoleText^> >> %xmlOut%
REM Copy the ntbackup log file to the log directory
pushd "%USERPROFILE%\Local Settings\Application Data\Microsoft\Windows NT\NTBackup\data"
REM Find the backup log corresponding to this backup
for %%i in (backup*.log) do (
REM Use "type" to convert from UNICODE to ANSI for findstr
REM The backup logs contains the backupFile name. Restore logs do not.
type "%%i" | findstr /c:"%backupFile%" > nul
if NOT ERRORLEVEL 1 (
REM string found
set ntbackupLog=%%i
goto :Done
)
)
:Done
copy /y "%ntbackupLog%" "%backupLog%" > nul
popd
call :StartOutputs
call :File "%backupSelectionFile%" BackupSelectionFile
call :File "%output%" BackupFile
call :File "%backupLog%" BackupLogFile
call :EndOutputs
echo ^<Summary ResultCode="%result%" StartTime="%startTime%" EndTime="%DATE% %TIME:~0,-3%" /^> >> %xmlOut%
echo ^</Step^> >> %xmlOut%
popd
exit /b %result%
:EndSteps
echo ^</Steps^> >> %xmlOut%
goto :Eof
:Storage
echo ^<Storage^> >> %xmlOut%
call :Directory "%serverRoot%" ServerRoot
call :Directory "%logDirectory%" LogDirectory
call :Directory "%backupDirectory%" BackupDirectory
echo ^</Storage^> >> %xmlOut%
goto :Eof
:EndProcedure
echo ^</BackupProcedure^> >> %xmlOut%
goto :Eof
:P4Set
echo ^<P4Set^> >> %xmlOut%
for /f "tokens=1,2 delims==" %%i in ('p4 set') do (
echo ^<Variable Name="%%i" Value="%%j" /^> >> %xmlOut%
)
echo ^</P4Set^> >> %xmlOut%
goto :Eof
:StartInputs
echo ^<Inputs^> >> %xmlOut%
goto :Eof
:File
setlocal
REM strip quotes
set pathname=%~1
set kind=%~2
if exist "%pathname%" (
for /f "skip=5 tokens=4" %%i in ('dir /-c /q /4 "%pathname%"') do (
echo ^<File Bytes="%%i" Pathname="%pathname%" Kind="%kind%" /^> >> %xmlOut%
REM stop at first match
goto :Eof
)
) else (
echo ^<File Bytes="" Pathname="%pathname%" Kind="%kind%" /^> >> %xmlOut%
)
goto :Eof
:Directory
setlocal EnableDelayedExpansion
REM strip quotes
set pathname=%~1
set kind=%~2
set bytesFree=
if exist "%pathname%" (
for /f "skip=8 tokens=3" %%i in ('dir /ad /-c "%pathname%"') do (
set bytesFree=%%i
)
)
echo ^<Directory BytesFree="!bytesFree!" Pathname="%pathname%" Kind="%kind%" /^> >> %xmlOut%
goto :Eof
:EndInputs
echo ^</Inputs^> >> %xmlOut%
goto :Eof
:StartOutputs
echo ^<Outputs^> >> %xmlOut%
goto :Eof
:EndOutputs
echo ^</Outputs^> >> %xmlOut%
goto :Eof
REM </Functions>
REM <Initialize>
:Initialize
REM Setup the environment
setlocal EnableDelayedExpansion
REM get the checkpoint number
pushd "%workspace%"
for /f "delims=: tokens=1,*" %%i in ('p4 info') do (
if "%%i"=="Server root" (
set rawValue=%%j
REM Strip off the leading space.
set serverRoot=!rawValue:~1!
)
)
for /f %%i in ('p4 counter journal') do set lastCheckpointNumber=%%i
set /a checkpointNumber=%lastCheckpointNumber%+1
popd
REM These need to be global for use in multiple steps
REM Where checkpoint file is located
set checkpoint=%serverRoot%\checkpoint.%checkpointNumber%.gz
REM Path and file name prefix to use for output files.
set outputPathPrefix=%logDirectory%\%serverShortName%.%checkpointNumber%
REM Where p4 verify results will be saved
set verifyOut=%outputPathPrefix%.Verify.txt
REM Where script results will be stored in xml format
set xmlOut="%outputPathPrefix%.BackupProcedure.xml"
REM Where a test restore of the checkpoint will be performed
set restoreOut=%outputPathPrefix%.Restore
REM </Initialize>
REM <Main>
set startTime=%DATE% %TIME:~0,-3%
call :StartProcedure
call :P4Info
call :Environment
call :StartSteps
call :Steps
call :EndSteps
call :Storage
echo ^<Summary StartTime="%startTime%" EndTime="%DATE% %TIME:~0,-3%" /^> >> %xmlOut%
call :EndProcedure
REM </Main>
view plain text source
Bookmark/Search this post with: