Commit 5dad053a82a824c61a813aaf608d1e9240e1020c

Authored by Jacob Vosmaer
2 parents 54faf787 fe8fa9a5

Merge pull request #4920 from Rovanion/init-rewrite

Rewrote init script.
Showing 2 changed files with 202 additions and 77 deletions   Show diff stats
1 v 6.1.0 1 v 6.1.0
  2 + - Rewrite: Init script now less prone to errors and keeps better track of the service.
2 - Link issues, merge requests, and commits when they reference each other with GFM 3 - Link issues, merge requests, and commits when they reference each other with GFM
3 - Close issues automatically when pushing commits with a special message 4 - Close issues automatically when pushing commits with a special message
4 - Project internal ids for issues, mr, milestones 5 - Project internal ids for issues, mr, milestones
lib/support/init.d/gitlab 100644 → 100755
1 -#! /bin/bash 1 +#! /bin/sh
2 2
3 # GITLAB 3 # GITLAB
4 # Maintainer: @randx 4 # Maintainer: @randx
  5 +# Authors: rovanion.luckey@gmail.com, @randx
5 # App Version: 6.0 6 # App Version: 6.0
6 7
7 ### BEGIN INIT INFO 8 ### BEGIN INIT INFO
@@ -14,102 +15,227 @@ @@ -14,102 +15,227 @@
14 # Description: GitLab git repository management 15 # Description: GitLab git repository management
15 ### END INIT INFO 16 ### END INIT INFO
16 17
  18 +### Environment variables
  19 +RAILS_ENV="production"
17 20
18 -APP_ROOT="/home/git/gitlab"  
19 -APP_USER="git"  
20 -DAEMON_OPTS="-c $APP_ROOT/config/unicorn.rb -E production"  
21 -PID_PATH="$APP_ROOT/tmp/pids"  
22 -SOCKET_PATH="$APP_ROOT/tmp/sockets"  
23 -WEB_SERVER_PID="$PID_PATH/unicorn.pid"  
24 -SIDEKIQ_PID="$PID_PATH/sidekiq.pid"  
25 -STOP_SIDEKIQ="RAILS_ENV=production bundle exec rake sidekiq:stop"  
26 -START_SIDEKIQ="RAILS_ENV=production bundle exec rake sidekiq:start"  
27 -NAME="gitlab"  
28 -DESC="GitLab service"  
29 -  
30 -check_pid(){  
31 - if [ -f $WEB_SERVER_PID ]; then  
32 - PID=`cat $WEB_SERVER_PID`  
33 - SPID=`cat $SIDEKIQ_PID`  
34 - STATUS=`ps aux | grep $PID | grep -v grep | wc -l` 21 +# Script variable names should be lower-case not to conflict with internal
  22 +# /bin/sh variables such as PATH, EDITOR or SHELL.
  23 +app_root="/home/git/gitlab"
  24 +app_user="git"
  25 +unicorn_conf="$app_root/config/unicorn.rb"
  26 +pid_path="$app_root/tmp/pids"
  27 +socket_path="$app_root/tmp/sockets"
  28 +web_server_pid_path="$pid_path/unicorn.pid"
  29 +sidekiq_pid_path="$pid_path/sidekiq.pid"
  30 +
  31 +
  32 +
  33 +### Here ends user configuration ###
  34 +
  35 +
  36 +# Switch to the app_user if it is not he/she who is running the script.
  37 +if [ "$USER" != "$app_user" ]; then
  38 + sudo -u "$app_user" -H $0 "$@"; exit;
  39 +fi
  40 +
  41 +# Switch to the gitlab path, if it fails exit with an error.
  42 +if ! cd "$app_root" ; then
  43 + echo "Failed to cd into $app_root, exiting!"; exit 1
  44 +fi
  45 +
  46 +### Init Script functions
  47 +
  48 +check_pids(){
  49 + if ! mkdir -p "$pid_path"; then
  50 + echo "Could not create the path $pid_path needed to store the pids."
  51 + exit 1
  52 + fi
  53 + # If there exists a file which should hold the value of the Unicorn pid: read it.
  54 + if [ -f "$web_server_pid_path" ]; then
  55 + wpid=$(cat "$web_server_pid_path")
35 else 56 else
36 - STATUS=0  
37 - PID=0 57 + wpid=0
  58 + fi
  59 + if [ -f "$sidekiq_pid_path" ]; then
  60 + spid=$(cat "$sidekiq_pid_path")
  61 + else
  62 + spid=0
38 fi 63 fi
39 } 64 }
40 65
41 -execute() {  
42 - sudo -u $APP_USER -H bash -l -c "$1"  
43 -} 66 +# We use the pids in so many parts of the script it makes sense to always check them.
  67 +# Only after start() is run should the pids change. Sidekiq sets it's own pid.
  68 +check_pids
44 69
45 -start() {  
46 - cd $APP_ROOT  
47 - check_pid  
48 - if [ "$PID" -ne 0 -a "$STATUS" -ne 0 ]; then  
49 - # Program is running, exit with error code 1.  
50 - echo "Error! $DESC $NAME is currently running!"  
51 - exit 1 70 +
  71 +# Checks whether the different parts of the service are already running or not.
  72 +check_status(){
  73 + check_pids
  74 + # If the web server is running kill -0 $wpid returns true, or rather 0.
  75 + # Checks of *_status should only check for == 0 or != 0, never anything else.
  76 + if [ $wpid -ne 0 ]; then
  77 + kill -0 "$wpid" 2>/dev/null
  78 + web_status="$?"
52 else 79 else
53 - if [ `whoami` = root ]; then  
54 - execute "rm -f $SOCKET_PATH/gitlab.socket"  
55 - execute "RAILS_ENV=production bundle exec unicorn_rails $DAEMON_OPTS > /dev/null 2>&1 &"  
56 - execute "mkdir -p $PID_PATH && $START_SIDEKIQ > /dev/null 2>&1 &"  
57 - echo "$DESC started" 80 + web_status="-1"
  81 + fi
  82 + if [ $spid -ne 0 ]; then
  83 + kill -0 "$spid" 2>/dev/null
  84 + sidekiq_status="$?"
  85 + else
  86 + sidekiq_status="-1"
  87 + fi
  88 +}
  89 +
  90 +# Check for stale pids and remove them if necessary
  91 +check_stale_pids(){
  92 + check_status
  93 + # If there is a pid it is something else than 0, the service is running if
  94 + # *_status is == 0.
  95 + if [ "$wpid" != "0" -a "$web_status" != "0" ]; then
  96 + echo "Removing stale Unicorn web server pid. This is most likely caused by the web server crashing the last time it ran."
  97 + if ! rm "$web_server_pid_path"; then
  98 + echo "Unable to remove stale pid, exiting"
  99 + exit 1
  100 + fi
  101 + fi
  102 + if [ "$spid" != "0" -a "$sidekiq_status" != "0" ]; then
  103 + echo "Removing stale Sidekiq web server pid. This is most likely caused by the Sidekiq crashing the last time it ran."
  104 + if ! rm "$sidekiq_pid_path"; then
  105 + echo "Unable to remove stale pid, exiting"
  106 + exit 1
58 fi 107 fi
59 fi 108 fi
60 } 109 }
61 110
62 -stop() {  
63 - cd $APP_ROOT  
64 - check_pid  
65 - if [ "$PID" -ne 0 -a "$STATUS" -ne 0 ]; then  
66 - ## Program is running, stop it.  
67 - kill -QUIT `cat $WEB_SERVER_PID`  
68 - execute "mkdir -p $PID_PATH && $STOP_SIDEKIQ > /dev/null 2>&1 &"  
69 - rm "$WEB_SERVER_PID" >> /dev/null  
70 - echo "$DESC stopped" 111 +# If no parts of the service is running, bail out.
  112 +exit_if_not_running(){
  113 + check_stale_pids
  114 + if [ "$web_status" != "0" -a "$sidekiq_status" != "0" ]; then
  115 + echo "GitLab is not running."
  116 + exit
  117 + fi
  118 +}
  119 +
  120 +# Starts Unicorn and Sidekiq.
  121 +start() {
  122 + check_stale_pids
  123 +
  124 + # Then check if the service is running. If it is: don't start again.
  125 + if [ "$web_status" = "0" ]; then
  126 + echo "The Unicorn web server already running with pid $wpid, not restarting."
71 else 127 else
72 - ## Program is not running, exit with error.  
73 - echo "Error! $DESC not started!"  
74 - exit 1 128 + echo "Starting the GitLab Unicorn web server..."
  129 + # Remove old socket if it exists
  130 + rm -f "$socket_path"/gitlab.socket 2>/dev/null
  131 + # Start the webserver
  132 + bundle exec unicorn_rails -D -c "$unicorn_conf" -E "$RAILS_ENV"
  133 + fi
  134 +
  135 + # If sidekiq is already running, don't start it again.
  136 + if [ "$sidekiq_status" = "0" ]; then
  137 + echo "The Sidekiq job dispatcher is already running with pid $spid, not restarting"
  138 + else
  139 + echo "Starting the GitLab Sidekiq event dispatcher..."
  140 + RAILS_ENV=$RAILS_ENV bundle exec rake sidekiq:start
  141 + # We are sleeping a bit here because sidekiq is slow at writing it's pid
  142 + sleep 2
75 fi 143 fi
  144 +
  145 + # Finally check the status to tell wether or not GitLab is running
  146 + status
76 } 147 }
77 148
78 -restart() {  
79 - cd $APP_ROOT  
80 - check_pid  
81 - if [ "$PID" -ne 0 -a "$STATUS" -ne 0 ]; then  
82 - echo "Restarting $DESC..."  
83 - kill -USR2 `cat $WEB_SERVER_PID`  
84 - execute "mkdir -p $PID_PATH && $STOP_SIDEKIQ > /dev/null 2>&1"  
85 - if [ `whoami` = root ]; then  
86 - execute "mkdir -p $PID_PATH && $START_SIDEKIQ > /dev/null 2>&1 &"  
87 - fi  
88 - echo "$DESC restarted." 149 +# Asks the Unicorn and the Sidekiq if they would be so kind as to stop, if not kills them.
  150 +stop() {
  151 + exit_if_not_running
  152 + # If the Unicorn web server is running, tell it to stop;
  153 + if [ "$web_status" = "0" ]; then
  154 + kill -QUIT "$wpid" &
  155 + echo "Stopping the GitLab Unicorn web server..."
  156 + stopping=true
89 else 157 else
90 - echo "Error, $NAME not running!"  
91 - exit 1 158 + echo "The Unicorn web was not running, doing nothing."
  159 + fi
  160 + # And do the same thing for the Sidekiq.
  161 + if [ "$sidekiq_status" = "0" ]; then
  162 + printf "Stopping Sidekiq job dispatcher."
  163 + RAILS_ENV=$RAILS_ENV bundle exec rake sidekiq:stop &
  164 + stopping=true
  165 + else
  166 + echo "The Sidekiq was not running, must have run out of breath."
92 fi 167 fi
  168 +
  169 +
  170 + # If something needs to be stopped, lets wait for it to stop. Never use SIGKILL in a script.
  171 + while [ "$stopping" = "true" ]; do
  172 + sleep 1
  173 + check_status
  174 + if [ "$web_status" = "0" -o "$sidekiq_status" = "0" ]; then
  175 + printf "."
  176 + else
  177 + printf "\n"
  178 + break
  179 + fi
  180 + done
  181 + sleep 1
  182 + # Cleaning up unused pids
  183 + rm "$web_server_pid_path" 2>/dev/null
  184 + # rm "$sidekiq_pid_path" # Sidekiq seems to be cleaning up it's own pid.
  185 +
  186 + status
93 } 187 }
94 188
  189 +# Returns the status of GitLab and it's components
95 status() { 190 status() {
96 - cd $APP_ROOT  
97 - check_pid  
98 - if [ "$PID" -ne 0 -a "$STATUS" -ne 0 ]; then  
99 - echo "$DESC / Unicorn with PID $PID is running."  
100 - echo "$DESC / Sidekiq with PID $SPID is running." 191 + check_status
  192 + if [ "$web_status" != "0" -a "$sidekiq_status" != "0" ]; then
  193 + echo "GitLab is not running."
  194 + return
  195 + fi
  196 + if [ "$web_status" = "0" ]; then
  197 + echo "The GitLab Unicorn webserver with pid $wpid is running."
101 else 198 else
102 - echo "$DESC is not running."  
103 - exit 1 199 + printf "The GitLab Unicorn webserver is \033[31mnot running\033[0m.\n"
  200 + fi
  201 + if [ "$sidekiq_status" = "0" ]; then
  202 + echo "The GitLab Sidekiq job dispatcher with pid $spid is running."
  203 + else
  204 + printf "The GitLab Sidekiq job dispatcher is \033[31mnot running\033[0m.\n"
  205 + fi
  206 + if [ "$web_status" = "0" -a "$sidekiq_status" = "0" ]; then
  207 + printf "GitLab and all it's components are \033[32mup and running\033[0m.\n"
104 fi 208 fi
105 } 209 }
106 210
107 -## Check to see if we are running as root first.  
108 -## Found at http://www.cyberciti.biz/tips/shell-root-user-check-script.html  
109 -if [ "$(id -u)" != "0" ]; then  
110 - echo "This script must be run as root" 211 +reload(){
  212 + exit_if_not_running
  213 + if [ "$wpid" = "0" ];then
  214 + echo "The GitLab Unicorn Web server is not running thus its configuration can't be reloaded."
111 exit 1 215 exit 1
112 -fi 216 + fi
  217 + printf "Reloading GitLab Unicorn configuration... "
  218 + kill -USR2 "$wpid"
  219 + echo "Done."
  220 + echo "Restarting GitLab Sidekiq since it isn't capable of reloading its config..."
  221 + RAILS_ENV=$RAILS_ENV bundle exec rake sidekiq:stop
  222 + echo "Starting Sidekiq..."
  223 + RAILS_ENV=$RAILS_ENV bundle exec rake sidekiq:start
  224 + # Waiting 2 seconds for sidekiq to write it.
  225 + sleep 2
  226 + status
  227 +}
  228 +
  229 +restart(){
  230 + check_status
  231 + if [ "$web_status" = "0" -o "$sidekiq_status" = "0" ]; then
  232 + stop
  233 + fi
  234 + start
  235 +}
  236 +
  237 +
  238 +## Finally the input handling.
113 239
114 case "$1" in 240 case "$1" in
115 start) 241 start)
@@ -122,17 +248,15 @@ case "$1" in @@ -122,17 +248,15 @@ case "$1" in
122 restart 248 restart
123 ;; 249 ;;
124 reload|force-reload) 250 reload|force-reload)
125 - echo -n "Reloading $NAME configuration: "  
126 - kill -HUP `cat $PID`  
127 - echo "done." 251 + reload
128 ;; 252 ;;
129 status) 253 status)
130 status 254 status
131 ;; 255 ;;
132 *) 256 *)
133 - echo "Usage: sudo service gitlab {start|stop|restart|reload}" >&2 257 + echo "Usage: service gitlab {start|stop|restart|reload|status}"
134 exit 1 258 exit 1
135 ;; 259 ;;
136 esac 260 esac
137 261
138 -exit 0 262 +exit