[rt18107] Deploy from git
authorLiam Whalen <liam.whalen@bc.libraries.coop>
Mon, 9 Dec 2013 22:57:03 +0000 (14:57 -0800)
committerLiam Whalen <liam.whalen@bc.libraries.coop>
Fri, 13 Dec 2013 22:00:27 +0000 (14:00 -0800)
Pull files from a remote repo.  Figure out where they are on the
server. Display the deployfile.sh command that could be executed.

Needs some more work and lots of testing.  Eventually it will execute the deployfile.sh
command without the use of a switch.

Working with tmp dir and real filename

Had to change the temp file to use the real file name of the file being
pushed otherwise deployfile.sh would not work properly.

Should we clean up the temp files?  I am hesitant to put any rm commands
into a script.

Modifed to work with pathmap.ini and access_pathmap.pl

This script now derives the host directories to deploy to via
pathmap.ini.  As well, I put in some safe guards to prevent deploying to
production while the script is in testing.

Added ability to specify location of git repo

Added the ability to specify the location of the git repo.  It defaults
to the current directory.  This allows users to run git-deploy.sh from a
central directory or from the PATH.  This script does assume that
access_pathmap.pl is in the user's PATH.

deployment/access_pathmap.pl
deployment/git-deploy.sh [new file with mode: 0755]

index 117e2aa..678accb 100755 (executable)
@@ -62,6 +62,15 @@ if (!$component) {
         print $key . "\n";
     }
 } else {
-    print $cfg->get_block($component)->{$srcpath};
+    while (!defined $cfg->get_block($component)->{$srcpath}) {
+        $srcpath =~ s/\/[^\/]*$//;
+        if ($srcpath !~ '/') {
+            last;
+        }
+    }
+
+    if (defined $cfg->get_block($component)->{$srcpath}) {
+        print $cfg->get_block($component)->{$srcpath};
+    }
 }
 
diff --git a/deployment/git-deploy.sh b/deployment/git-deploy.sh
new file mode 100755 (executable)
index 0000000..ad68998
--- /dev/null
@@ -0,0 +1,149 @@
+#!/bin/bash
+
+#TODO decide about sql files and other odd files
+#TODO make sure access_pathmap.ini is fixed so Open-ILS/xul/staff_client/ files map properly
+
+PROD_SERVERS=" app1-1 app1-2 app2-1 app2-2 app3-1 app3-2 stanns bibc-prod "
+REPO='.'
+
+function usage()
+{
+    cat <<EOF
+USAGE:
+./git-deploy.sh -g ~/evergreen/.git -r origin -b HEAD host1 [ host2 ... ]
+./git-deploy.sh -r origin -b user/lwhalen/rt15288 -P
+
+This script is currently in testing.  By default it will echo the commands it would run to the screen.
+If you wan to deploy something you need to use the -d option.
+
+e.g. ./git-deploy.sh -r origin -b HEAD -d host1
+
+As well, this script will not deploy to our production servers currently.  It will print out a message
+saying so if you try to use a production server as a host option or if you use the -P option to deploy
+to all production servers.
+
+OPTIONS:
+    -g The location of the git repo
+    -r The remote to deploy from
+    -b The branch on the remote to deploy from
+    -P Deploy to all production servers
+    -d Actually deploy.  While testing this option is needed to force the commands to execute
+EOF
+}
+
+function create_tmp_file() {
+    TMP_DIR=$1
+    FILENAME=$2
+    touch $TMP_DIR/$FILENAME
+    echo "$TMP_DIR/$FILENAME"
+}
+
+function get_full_path() {
+    RELATIVE_PATH=$1
+
+    for COMPONENT in `access_pathmap.pl --config $PATH_MAP_FILE`
+    do
+        BASE_PATH=`access_pathmap.pl --config $PATH_MAP_FILE --component $COMPONENT --srcpath $RELATIVE_PATH`
+        if [[ $BASE_PATH ]]
+        then
+            #We extract the last directory in the base path so we can
+            #use parameter substitution to remove everything up to the
+            #last directory in the BASE_PATH from the RELATIVE_PATH
+            #this leaves us with the part of the git source tree path
+            #that needs to be appended to the base path in order to locate
+            #the file on the server
+            LAST_DIR_IN_BASE_PATH=`basename $BASE_PATH`
+            RELATIVE_PART=${RELATIVE_PATH/*$LAST_DIR_IN_BASE_PATH/}
+            echo $BASE_PATH$RELATIVE_PART
+            return;
+        fi
+    done
+}
+
+function deployfile() {
+    REMOTE=$1
+    BRANCH=$2
+    RELATIVE_PATH=$3
+    FILENAME=$4
+    TMP_DIR=$5
+    HOSTS=$6
+
+    PERL_FILE_RE='^.*.pm$'
+    SQL_FILE_RE='^.*.sql$'
+    TT2_FILE_RE='^Open-ILS/src/(templates)/(.*)$'
+    USER='opensrf'
+
+    if [[ $FILENAME =~ $PERL_FILE_RE ]]
+    then
+        USER='root'
+    elif [[ $FILENAME =~ $SQL_FILE_RE ]]
+    then
+        echo 'SQL file -- TAKE THE TIME TO LOAD THIS PROPERLY INTO THE DATABASE.  DO NOT FORGET TO WRAP IT IN BEGIN AND COMMIT'
+        return
+    else
+        USER='opensrf'
+    fi
+
+    FULL_PATH=`get_full_path $RELATIVE_PATH`
+
+    TEMPFILE=`create_tmp_file $TMP_DIR $FILENAME`
+    git --git-dir $REPO show $REMOTE/$BRANCH:$RELATIVE_PATH/$FILENAME > $TEMPFILE
+    for HOST in $HOSTS
+    do
+        if [[ $PROD_SERVERS =~ " $HOST " ]]
+        then
+            echo "Cannot deploy `basename $TEMPFILE` to $HOST while testing.  Please use another server"
+        else 
+            COMMAND="deployfile.sh -f $TEMPFILE -p $FULL_PATH -u $USER -b $HOST"
+            if [[ -z "$DEPLOY" ]]
+            then
+                echo $COMMAND
+            else 
+                $COMMAND
+            fi
+
+        fi
+    done
+}
+
+while getopts ":g:r:b:c:Pdh" opt
+do
+    case $opt in
+        g ) REPO=$OPTARG;;
+        r ) REMOTE=$OPTARG;;
+        b ) BRANCH=$OPTARG;;
+        c ) PATH_MAP_FILE=$OPTARG;;
+        P ) PROD="P";;
+        d ) DEPLOY="d";;
+        h ) usage && exit 0;;
+    esac
+done
+
+if [[ ! "$REPO" =~ .git$ ]]
+then
+    REPO=$REPO"/.git"
+fi
+
+shift $(($OPTIND - 1))
+
+if [[ -z "$PROD" ]]
+then
+    HOST_LIST=$@
+else
+    HOST_LIST=$@$PROD_SERVERS
+fi
+
+if [[ -z $HOST_LIST ]]
+then
+    echo 'You must specify a host to deploy to in order to use this script'
+    exit 1
+fi
+
+TMP_DIR=`mktemp -d`
+git --git-dir $REPO show $REMOTE/$BRANCH --name-only --oneline | awk '{if(NR!=1) {print}}' | \
+while read PATH_AND_FILENAME 
+do
+    FILENAME=`basename $PATH_AND_FILENAME`
+    RELATIVE_PATH=`dirname $PATH_AND_FILENAME`
+    deployfile $REMOTE $BRANCH $RELATIVE_PATH $FILENAME $TMP_DIR "$HOST_LIST"
+done