install-osrf.sh: set ejabberd host correctly during registration on prod
[sitka/sitka-tools.git] / patching / patch-eg.sh
1 #!/bin/bash
2 # Author: schan@sitka.bclibraries.ca
3
4 Help() {
5         cat<<____
6
7 DESCRIPTION:
8 Apply or unapply a patch to remote Evergreen hosts
9
10 USAGE:
11 ./patch-eg.sh -p ID [ -b backup_label ] [ -P rule ] [ -y ] [ -R ] [ -h ] host1 host2...
12
13 OPTIONS:
14     -p SHA1 ID of patch to apply (mandatory)
15     -b Backup label of patch
16        Defaults to patch ID
17     -P Patch rule (web, tt2, xul, bin, perl, util) to determine patch directory, user, and strip level
18        Defaults to 'web'
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
22 ____
23 }
24
25 # Parse command line for run-time options
26 while getopts 'p:b:P:yRh' Option; do
27         case $Option in
28         (p) Patch_ID=$OPTARG;;
29         (b) Patch_Backup=$OPTARG;;
30         (P) Patch_Rule=$OPTARG;;
31         (y) Runit='';;
32         (R) Reverse='-R';;
33         (h) Help && exit 0;;
34         esac
35 done
36 shift $(( $OPTIND - 1 ))
37
38 # Calculate default options
39 Remote_Host=${1:?}
40 Patch_ID=${Patch_ID:?}
41 Patch_Backup=${Patch_Backup:-$Patch_ID}
42 Patch_Rule=${Patch_Rule:-web}
43 Runit=${Runit-'--dry-run'}
44 Reverse=${Reverse-''}
45
46 # Define function to echo the intended action for a host
47 Echo_Intention() {
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"
51 }
52
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
55 declare -A Rule
56 case $Patch_Rule in
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 );;
63 esac
64
65
66 # Set local environment
67
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
76
77
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)}'"
85
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); }
88
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 \""; }
91
92 # Ask the user once for sudo password
93 read -s -p "$LOGIN's sudo password: " Password ; echo
94
95 for Host; do
96         Echo_Intention $Host
97         [[ $Patch_Rule == 'perl' ]] && Rule[path]=$(Perl_Dir $Host)
98         Patch_Dir $Host ${Rule[path]} <<< $Password
99 done