- #!/bin/sh
- ############################################################ IDENT(1)
- #
- # $Title: Script to replay perforce checkpoint $
- #
- ############################################################ CONFIGURATION
- #
- # User to perform replay as
- #
- P4D_USER=p4admin
- #
- # Local perforce server settings
- # NB: Taken from rc.conf(5) on FreeBSD
- #
- P4D_ROOT=$( sysrc -n p4d_root 2> /dev/null )
- #
- # Sensible defaults (i.e., Linux)
- #
- : ${P4D_ROOT:=/perforce}
- ############################################################ GLOBALS
- pgm="${0##*/}" # Program basename
- #
- # Global exit status
- #
- SUCCESS=0
- FAILURE=1
- #
- # Command-line options
- #
- DEBUG= # -d
- ROOTDIR= # -R dir
- UNPACK_ONLY= # -U
- USER= # -u user
- #
- # Miscellaneous
- #
- export LC_ALL="${LC_ALL:-en_US.ISO8859-1}" # separators in dpv(1) status
- FIFO=replay_fifo.$$
- FILE=
- GZFILE=
- STOPPED_P4D=
- # TODO: Add `-V' option to perform md5(1) verification when *.md5 exists
- # NOTE: LC_ALL=en_US.ISO8859-1 dpv -xmd5 $( stat -f%z $FILE ):$FILE < $FILE
- # wrapped in a sub-shell to capture output and add `-t title' et al.
- ############################################################ FUNCTIONS
- quietly(){ "$@" > /dev/null 2>&1; }
- have(){ quietly type "$@"; }
- die()
- {
- local fmt="$1"
- exec >&2
- if [ "$fmt" ]; then
- shift 1 # fmt
- printf "$fmt\n" "$@"
- fi
- exit $FAILURE
- }
- usage()
- {
- exec >&2
- local optfmt="\t%-8s %s\n"
- printf "Usage: %s [-U|-d] [OPTIONS] checkpoint.NNNN[.gz]\n" "$pgm"
- printf "OPTIONS:\n"
- printf "$optfmt" "-U" \
- "Unpack the checkpoint if-required (first step) and exit."
- printf "$optfmt" "-d" \
- "Debug. Don't stop p4d and don't replay but simulate it."
- printf "$optfmt" "-R dir" \
- "Perform replay in dir (default $P4D_ROOT)."
- printf "$optfmt" "-u user" \
- "Perform replay as user (default $P4D_USER)."
- exit $FAILURE
- }
- ############################################################ MAIN
- #
- # Command-line options
- #
- while getopts dR:u:U flag; do
- case "$flag" in
- d) DEBUG=1 ;;
- R) ROOTDIR="$OPTARG" ;;
- u) USER="$OPTARG" ;;
- U) UNPACK_ONLY=1 ;;
- *) usage
- esac
- done
- shift $(( $OPTIND - 1 ))
- FILE="$1"
- #
- # Validate command-line arguments
- #
- [ "$FILE" ] || usage
- # set after last-call to usage()
- P4D_ROOT="${ROOTDIR:-$P4D_ROOT}"
- P4D_USER="${USER:-$P4D_USER}"
- #
- # All actions should be performed within the p4d_root (e.g., /perforce)
- #
- cd "$P4D_ROOT" || exit
- #
- # Validate command-line arguments (continued)
- #
- [ "$FILE" != "${FILE%.[Gg][Zz]}" ] && GZFILE="$FILE" FILE="${FILE%.[Gg][Zz]}"
- IN="${GZFILE:-$FILE}"
- [ -e "$IN" ] || die "%s: %s: No such file or directory" "$pgm" "$IN"
- [ -f "$IN" ] || die "%s: %s: Is a directory" "$pgm" "$IN"
- #
- # Make sure we have required users and sufficient privileges to proceed
- #
- [ "$( id -u )" -eq 0 ] || die "Must be root!"
- id -u ${P4D_USER:+"$P4D_USER"} > /dev/null || exit
- #
- # If the checkpoint argument was named `*.gz' (case-insensitive), unpack the
- # checkpoint first.
- #
- if [ "$GZFILE" -a ! -e "$FILE" ]; then
- size=$( stat -f%z "$GZFILE" )
- trap 'rm -f "$FILE"' SIGINT
- export FILE
- if ! time dpv \
- -wmx 'zcat > "$FILE"' -b "$pgm" -t "zcat(1)" \
- -p "Unpacking checkpoint file...\n" \
- -a "\nNEXT: Stop p4d, backup files, replay checkpoint" \
- "${size:+$size:} $GZFILE" "$GZFILE"
- then
- quietly rm -f "$FILE"
- exit $FAILURE
- fi
- trap - SIGINT
- [ ! "$P4D_USER" ] || chown "$P4D_USER" "$FILE" || exit
- quietly chmod 0444 "$FILE"
- fi
- [ "$UNPACK_ONLY" ] && exit $SUCCESS
- # NOTREACHED if given `-U' option
- #
- # Make a backup directory for the existing db files
- #
- vers=$( p4d -V | awk '/^Rev./&&split($2,vers,"/"){print vers[3]}' ) || exit
- back="db-$vers@$( date +%F+%H_%M )"
- create=
- if [ ! "$DEBUG" ]; then
- for f in db.* *.lbr journal state; do
- [ -e "$f" ] || continue
- create=1
- break
- done
- [ ! "$create" ] || mkdir -pm0755 "$back" || exit
- [ ! "$P4D_USER" ] || chown "$P4D_USER" "$back" || exit
- fi
- #
- # Is p4d running? (we'll pause for 10 seconds before stopping it)
- # NB: If we stop it, we'll later start it
- #
- if [ ! "$DEBUG" ] && quietly service p4d status; then
- dialog --backtitle "$pgm" --title "Count Down" \
- --hline "Press Ctrl-C to Abort" --nook --nocancel --pause \
- "Stopping p4d...\nNEXT: Backup files, replay checkpoint" \
- 7 50 10
- service p4d stop || exit
- STOPPED_P4D=1
- fi
- #
- # Move the existing db files to backup directory
- #
- if [ ! "$DEBUG" ]; then
- for f in db.* *.lbr journal state; do
- [ -e "$f" ] || continue
- mv -n "$f" "$back" || exit
- done
- [ -d "$back" ] && dialog --backtitle "$pgm" --title "Count Down" \
- --hline "Press Ctrl-C to Abort" --nook --nocancel --pause \
- "Files backed up to $back\nNEXT: Replay checkpoint" 7 50 10
- fi
- #
- # Start the replay
- #
- [ -e "$FIFO" ] || mkfifo "$FIFO" || exit
- trap 'quietly rm -f "$FIFO"' EXIT
- if [ "$DEBUG" ]; then
- quietly cat "$FIFO" &
- else
- cmd='p4d -r "$P4D_ROOT" -jr "$FIFO"'
- if [ "$P4D_USER" ]; then
- export P4D_ROOT FIFO cmd
- if have sudo; then
- export SUDO_PROMPT="${SUDO_PROMPT:-[sudo] Password:}"
- sudo -Eu "$P4D_USER" sh -c 'eval "$cmd" &'
- else
- export P4D_USER
- # WARNING! cmd executed by tcsh(1) (root's shell)
- su -m <<-'EOF'
- echo 'eval "$cmd" &' | su -m "$P4D_USER"
- EOF
- fi
- else
- eval "$cmd" &
- fi
- fi
- size=$( stat -f%z "$FILE" )
- time dpv -wmo "$FIFO" -b "$pgm" -t "p4d" \
- -p "Replaying checkpoint file...\n" \
- -a "\nThis may take a while." \
- "${size:+$size:} $FILE" "$FILE" || exit
- wait $!
- #
- # Restart p4d if we stopped it (we'll pause for 10 seconds before starting it)
- # NB: Prevents error "p4d already running? (pid=<PID>)."
- #
- if [ "$STOPPED_P4D" ]; then
- dialog --backtitle "$pgm" --title "Count Down" \
- --hline "Press Ctrl-C to Abort" --nook --nocancel --pause \
- "Starting p4d..." 6 50 10
- service p4d start || exit
- fi
- exit $SUCCESS
- ################################################################################
- # END
- ################################################################################
- #
- # $Copyright: 2015 Devin Teske. All rights reserved. $
- #
- # $Header: //guest/freebsdfrau/p4t/libexec/replay_checkpoint#1 $
- #
- ################################################################################
# | Change | User | Description | Committed | |
---|---|---|---|---|---|
#1 | 16365 | freebsdfrau | Import p4t - p4d admin tool | 9 years ago |