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
CHANGELOG
1 1 v 6.1.0
  2 + - Rewrite: Init script now less prone to errors and keeps better track of the service.
2 3 - Link issues, merge requests, and commits when they reference each other with GFM
3 4 - Close issues automatically when pushing commits with a special message
4 5 - Project internal ids for issues, mr, milestones
... ...
lib/support/init.d/gitlab 100644 → 100755
1   -#! /bin/bash
  1 +#! /bin/sh
2 2  
3 3 # GITLAB
4 4 # Maintainer: @randx
  5 +# Authors: rovanion.luckey@gmail.com, @randx
5 6 # App Version: 6.0
6 7  
7 8 ### BEGIN INIT INFO
... ... @@ -14,102 +15,227 @@
14 15 # Description: GitLab git repository management
15 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 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 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 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 107 fi
59 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 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 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 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 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 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 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 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 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 240 case "$1" in
115 241 start)
... ... @@ -122,17 +248,15 @@ case "$1" in
122 248 restart
123 249 ;;
124 250 reload|force-reload)
125   - echo -n "Reloading $NAME configuration: "
126   - kill -HUP `cat $PID`
127   - echo "done."
  251 + reload
128 252 ;;
129 253 status)
130 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 258 exit 1
135 259 ;;
136 260 esac
137 261  
138   -exit 0
  262 +exit
... ...