#!/bin/bash #------------------------------------------------------------------------------ # snapclone.sh: This script clones a personal repo, using rsync to simulate # copying a pre-cloned DVCS repo template from a NetApp filer snapshot. # # It modifiers the local workspace in ways to "Make it your own," by: # - Changing the default user in .p4config # - Taking a local checkpoint and performing minor surgery on it to # correct the protections table for the current user. # - Modifying the generated .p4config to enable local journaling. # - Adjusting the RemoteUser: field of the 'origin' remote spec to the current # user. # set -u function msg () { echo -e "$*"; } function cmd () { msg "Executing: $*"; $*; return $?; } function bail () { msg "Error: $1"; exit ${2:-1}; } function usage () { msg "Usage:\n\t${0##*/} -p <proj> [-u <user>] [-f]\n\n OR, if flexclone_space already run:\n\t${0##*/} -d <repo_dir>\n"; exit 1; } declare TemplateOwner= declare TemplateStorageBase=/netapp/p4/ws/templates declare TemplateStorage= declare Proj=Unset declare Passwd=Unset declare Port=Unset declare User=Unset declare TemplateSet=s1 declare TemplateName=${Proj}-${TemplateSet} declare RepoStorageBase=/netapp/p4/ws declare RepoStorage=Unset declare RemoteSpecFile= declare Version=1.1.3 declare -i DoFetch=0 declare -i Force=0 declare -i shiftArgs=0 set +u while [[ $# -gt 0 ]]; do case $1 in (-f) Force=1;; (-u) User=$2; shiftArgs=1;; (-p) Proj=$2; shiftArgs=1;; (-d) RepoStorage=$2; shiftArgs=1;; (-P) Passwd=$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. (*) bail "Usage Error: Unknown arg ($1)." ;; esac # Shift (modify $#) the appropriate number of times. shift; while [[ $shiftArgs -gt 0 ]]; do [[ $# -eq 0 ]] && bail "Usage Error: Bad argument count." shiftArgs=$shiftArgs-1 shift done done set -u #------------------------------------------------------------------------------ # Command Line Validation if [[ $RepoStorage == Unset ]]; then [[ $Proj == Unset ]] && bail "Usage Error: Specify either '-d <repo_dir>' or '-p <proj>')." fi #------------------------------------------------------------------------------ # Main Program. msg "Started ${0##*/} v$Version at $(date).\n" export P4ENVIRO=/dev/null/.p4enviro #export P4CONFIG=${P4CONFIG:-.p4config} export P4CONFIG=${P4CONFIG:-.P4Config} export P4CONFIG=${P4CONFIG##*/} [[ $User == Unset ]] && User=$(whoami) if [[ $RepoStorage == Unset ]]; then TemplateStorage=${TemplateStorageBase}/${Proj}-${TemplateSet} if [[ -d $TemplateStorage/.p4root ]]; then msg "Using template $TemplateStorage." else bail "Could not find a suitable template. Checked: $TemplateStorage" fi RepoStorage=${RepoStorageBase}/${User}/${Proj} if [[ -d $RepoStorage ]]; then if [[ $Force -eq 1 ]]; then /bin/rm -rf $RepoStorage || bail "Failed to remove existing repo dir: $RepoStorage." else bail "Repo already exists at $RepoStorage." fi fi mkdir -p $RepoStorage || bail "Failed to create repo storage dir: $RepoStorage." msg "Snap/Cloning from $TemplateStorage to $RepoStorage." rsync -a $TemplateStorage/ $RepoStorage || bail "Failed to snap/clone template repo." else [[ ! -d "$RepoStorage" ]] && bail "The dir specified with '-d <repo_dir>' does not exist." fi msg "Massaging data". cd $RepoStorage/.p4root || bail "Failed to cd to $RepoStorage/.p4root" p4d -r $RepoStorage/.p4root -k db.remote,db.protect,db.user -jd partial_ckp TemplateOwner=$(grep "@pv@ 7 @db.user@" partial_ckp|cut -d '@' -f 6) msg "Adjusting metadata to change owner from $TemplateOwner to $User." sed -e "s:@db.remote@ @origin@ @${TemplateOwner}@:@db.remote@ @origin@ @${User}@:g" \ -e "s:@db.protect@ 0 0 @${TemplateOwner}@:@db.protect@ 0 0 @${User}@:g" \ -e "s:@db.protect@ 1 0 @${TemplateOwner}@:@db.protect@ 1 0 @${User}@:g" \ -e "s:@db.protect@ 1 0 @${TemplateOwner}@:@db.protect@ 1 0 @${User}@:g" \ -e "s:@${TemplateOwner}@:@${User}@:g" \ partial_ckp > partial_ckp.mod # For safety, disable server vars so 'p4 init' doesn't go haywire on p4d. unset P4PORT P4ROOT P4JOURNAL P4LOG P4DEBUG P4AUDIT p4d -r $RepoStorage/.p4root -jr partial_ckp.mod grep -v P4USER= $RepoStorage/$P4CONFIG > $RepoStorage/${P4CONFIG}.1 grep -v P4PORT= $RepoStorage/${P4CONFIG}.1 > $RepoStorage/${P4CONFIG}.2 echo "P4PORT=rsh:/bin/sh -c \"umask 077 && exec p4d -i -J '\$configdir/.p4root/journal' -r '\$configdir/.p4root'\"" >> $RepoStorage/${P4CONFIG}.2 echo "P4USER=$User" >> $RepoStorage/${P4CONFIG}.2 mv $RepoStorage/${P4CONFIG}.2 $RepoStorage/${P4CONFIG} rm -f $RepoStorage/${P4CONFIG}.1 Port=$(p4 -ztag -F %Address% remote -o origin) if [[ $Port == ssl:* ]]; then export P4TRUST=$RepoStorage/.p4trust cmd p4 -p $Port trust -y fi msg "\nAdding User $User to 'origin' remote spec." RemoteSpecFile=$(mktemp) p4 remote -o origin > $RemoteSpecFile ||\ bail "Failed to write remote spec file to $RemoteSpecFile." echo "RemoteUser: $User" >> $RemoteSpecFile p4 remote -i < $RemoteSpecFile || bail "Failed to load remote spec file $RemoteSpecFile with these contents:\n$(cat $RemoteSpecFile)\n" rm -f $RemoteSpecFile if [[ $Passwd != Unset ]]; then touch .p4passwd chmod 600 .p4passwd echo "$Passwd" > .p4passwd msg "P:[$(cat .p4passwd)]" msg "Logging in to master server." p4 login -r origin < .p4passwd rm -f .p4passwd fi p4 login -r origin -s > /dev/null 2>&1 if [[ $? -eq 0 ]]; then DoFetch=1 else msg "\nSkipping auto fetch due to not being logged in to mastser server. Please do:\n\tp4 login -r origin\n\tp4 fetch\n" fi if [[ $DoFetch -eq 1 ]]; then msg "\nFetching." p4 fetch fi msg "\nDone. Enjoy your repo in: $RepoStorage" msg "That took $(($SECONDS/3600)) hours $(($SECONDS%3600/60)) minutes $(($SECONDS%60)) seconds.\n" exit 0
# | Change | User | Description | Committed | |
---|---|---|---|---|---|
#13 | 20216 | Perforce maintenance | Don't need db.domain. | ||
#12 | 20215 | Perforce maintenance | Removed redundant call to mktemp(). | ||
#11 | 20214 | Perforce maintenance |
snapclone.sh v1.1.8: * Changed old '-f' to '-F' * Added new '-f' (fetch); changed default behavior to not fetch. * Updated usage(). * Updated test suite accordingly. |
||
#10 | 20213 | Perforce maintenance | Changed TemplateOwner to MasterWS. | ||
#9 | 20212 | Perforce maintenance |
snapclone.sh v1.1.6: * Changed workspace Owner field to current user. |
||
#8 | 20128 | Perforce maintenance |
snapclone.sh v1.1.3: * Fixed compatibility with '-d' usage vs. '-p' usage. |
||
#7 | 20123 | C. Thomas Tyler |
snapclone.sh v1.1.2: * Added '-d' flag to start processing after external creation of snapshotted clone tree. * Misc code cleanup. |
||
#6 | 20118 | Perforce maintenance |
snapclone.sh v1.1.1: * Refined performance improvement, fixing issues. * Cleaned up excess .p4config.1 file generated. |
||
#5 | 20115 | C. Thomas Tyler |
snapclone.sh v1.1.0: * Performance enhancement, now checkpoints only tables that need transmogrification. |
||
#4 | 20114 | Perforce maintenance |
snapclone.sh v1.0.9: * Improved handling of remote spec file. * Added more error checking and handling. |
||
#3 | 20089 | Perforce maintenance | Adjusted storage location. | ||
#2 | 19957 | Perforce maintenance | Enhanced checkpoint surgery to make it more narrow. | ||
#1 | 19956 | Perforce maintenance | Refactored. | ||
//guest/tom_tyler/snapclone/main/flexclone.sh | |||||
#5 | 19955 | Perforce maintenance | Added notes. | ||
#4 | 19953 | Perforce maintenance |
flexclone.sh is taking shape. Added test script. |
||
#3 | 19952 | Perforce maintenance | Milestone PoC. | ||
#2 | 19951 | Perforce maintenance | wip. | ||
#1 | 19950 | Perforce maintenance | Added flexclone script, wip. |