2 # Author: schan@sitka.bclibraries.ca
8 Apply or unapply a patch to remote Evergreen hosts
11 ./patch-eg.sh -p ID [ -b backup_label ] [ -P rule ] [ -y ] [ -R ] [ -h ] host1 host2...
14 -p SHA1 ID of patch to apply (mandatory)
15 -b Backup label of patch
17 -P Patch rule (web, xul, perl) to determine patch directory, user, and strip level
19 -y Yes, apply the patch instead of doing a dry run
20 -R Reverse or undo the patch instead of applying it
21 -h Print this message and exit
25 # Parse command line for run-time options
26 while getopts 'p:b:P:yRh' Option; do
28 (p) Patch_ID=$OPTARG;;
29 (b) Patch_Backup=$OPTARG;;
30 (P) Patch_Rule=$OPTARG;;
36 shift $(( $OPTIND - 1 ))
38 # Calculate default options
40 Patch_ID=${Patch_ID:?}
41 Patch_Backup=${Patch_Backup:-$Patch_ID}
42 Patch_Rule=${Patch_Rule:-web}
43 Runit=${Runit-'--dry-run'}
46 # Define function to echo the intended action for a host
48 [[ $Runit == '--dry-run' ]] && echo -ne '\nDry run: '
49 if [[ $Reverse == '-R' ]]; then echo -n 'Reversing '; else echo -n 'Applying '; fi
50 echo -e "patch $Patch_ID to $1 and backing up as $Patch_Backup"
53 # Associate the patch rule to patch path, strip level, and sudo user
54 # If patch rule is 'perl', the patch path will be dynamically determined from the host
57 (web) Rule=( [path]=/srv/openils/var [level]=2 [sudo]=opensrf );;
58 (xul) Rule=( [path]=/srv/openils/var/web/xul [level]=4 [sudo]=opensrf );;
59 (perl) Rule=( [path]=/usr/local/share/perl/5.14.2 [level]=5 [sudo]=root );;
63 # Set local environment
65 # Domain name of patch host (Evergreen)
66 #declare -r SOURCE="git.evergreen-ils.org/?p=Evergreen.git"
67 # Domain name of patch host (Sitka)
68 declare -r SOURCE="git.sitka.bclibraries.ca/gitweb/?p=sitka/evergreen.git"
69 # Domain name of target hosts
70 declare -r TARGET=sitka.bclibraries.ca
71 # Name of ssh and sudo user
72 declare -r LOGIN=sitkastaff
75 # Calculate command text strings
76 declare -r SUDO="sudo -p '' -S -u ${Rule[sudo]}"
77 declare -r Patch_URL="http://$SOURCE;a=patch;h=$Patch_ID"
78 declare -r WGET="wget -q -O - '$Patch_URL'"
79 declare -r Backup_Policy="-b -B .patch/$Patch_Backup/ -V simple"
80 declare -r PATCH="patch $Runit $Reverse -r - $Backup_Policy -p${Rule[level]}"
81 declare -r OPENILS_DIR="perl -MOpenILS -e 'print \$INC{qq(OpenILS.pm)}'"
83 # Define function to find directory name of the OpenILS Perl module at a host
84 Perl_Dir() { dirname $(ssh "$LOGIN@$1.$TARGET" $OPENILS_DIR); }
86 # Define function to patch a directory at a host via ssh sudo
87 Patch_Dir() { ssh "$LOGIN@$1.$TARGET" "$SUDO bash -c \"$WGET | $PATCH -d $2 \""; }
89 # Ask the user once for sudo password
90 read -s -p "$LOGIN's sudo password: " Password ; echo
94 [[ $Patch_Rule == 'perl' ]] && Rule[path]=$(Perl_Dir $Host)
95 Patch_Dir $Host ${Rule[path]} <<< $Password