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, tt2, xul, bin, perl, util) 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 (tt2) Rule=( [path]=/srv/openils/var [level]=3 [sudo]=opensrf );;
59 (xul) Rule=( [path]=/srv/openils/var/web/xul [level]=4 [sudo]=opensrf );;
60 (bin) Rule=( [path]=/srv/openils/bin [level]=4 [sudo]=opensrf );;
61 (perl) Rule=( [path]=/usr/local/share/perl/5.14.2 [level]=5 [sudo]=root );;
62 (util) Rule=( [path]=/srv/openils/var/web/xul/server [level]=6 [sudo]=opensrf );;
66 # Set local environment
68 # Domain name of patch host (Evergreen)
69 #declare -r SOURCE="git.evergreen-ils.org/?p=Evergreen.git"
70 # Domain name of patch host (Sitka)
71 declare -r SOURCE="git.sitka.bclibraries.ca/gitweb/?p=sitka/evergreen.git"
72 # Domain name of target hosts
73 declare -r TARGET=sitka.bclibraries.ca
74 # Name of ssh and sudo user
75 declare -r LOGIN=sitkastaff
78 # Calculate command text strings
79 declare -r SUDO="sudo -p '' -S -u ${Rule[sudo]}"
80 declare -r Patch_URL="http://$SOURCE;a=patch;h=$Patch_ID"
81 declare -r WGET="wget -q -O - '$Patch_URL'"
82 declare -r Backup_Policy="-b -B .patch/$Patch_Backup/ -V simple"
83 declare -r PATCH="patch $Runit $Reverse -r - $Backup_Policy -p${Rule[level]}"
84 declare -r OPENILS_DIR="perl -MOpenILS -e 'print \$INC{qq(OpenILS.pm)}'"
86 # Define function to find directory name of the OpenILS Perl module at a host
87 Perl_Dir() { dirname $(ssh "$LOGIN@$1.$TARGET" $OPENILS_DIR); }
89 # Define function to patch a directory at a host via ssh sudo
90 Patch_Dir() { ssh "$LOGIN@$1.$TARGET" "$SUDO bash -c \"$WGET | $PATCH -d $2 \""; }
92 # Ask the user once for sudo password
93 read -s -p "$LOGIN's sudo password: " Password ; echo
97 [[ $Patch_Rule == 'perl' ]] && Rule[path]=$(Perl_Dir $Host)
98 Patch_Dir $Host ${Rule[path]} <<< $Password