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 | ... | ... |