Commit 5dad053a82a824c61a813aaf608d1e9240e1020c
Exists in
master
and in
4 other branches
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 | ... | ... |
| 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 | ... | ... |