tweak httpd service script for f27 - ${!http_port} issues "bad substitution" in some...
[myplc.git] / plc.d / httpd
1 #!/bin/bash
2 #
3 # priority: 600
4 #
5 # Configure Apache web server
6 #
7 # Mark Huang <mlhuang@cs.princeton.edu>
8 # Copyright (C) 2006 The Trustees of Princeton University
9 #
10
11 # Source function library and configuration
12 . /etc/plc.d/functions
13 . /etc/planetlab/plc_config
14
15 # Be verbose
16 set -x
17
18 # Default locations
19 DocumentRoot=/var/www/html
20 php_ini=/etc/php.ini
21 httpd_conf=/etc/httpd/conf/httpd.conf
22 ssl_conf=/etc/httpd/conf.d/ssl.conf
23 plc_conf=/etc/httpd/conf.d/plc.conf
24
25 function disable_file () {
26     file=$1; shift
27     [ -f $file ] && mv -f $file $file.disabled
28 }
29 function enable_file () {
30     file=$1; shift
31     [ ! -f $file ] && mv -f $file.disabled $file
32 }
33
34 case "$1" in
35     start)
36         if [ "$PLC_API_ENABLED" != "1" -a \
37              "$PLC_BOOT_ENABLED" != "1" -a \
38              "$PLC_WWW_ENABLED" != "1" ] ; then
39             exit 0
40         fi
41
42         MESSAGE=$"Starting web server"
43         dialog "$MESSAGE"
44
45         # set document root - not really useful on fedora but just in case
46         sed -i -e "s@^DocumentRoot.*@DocumentRoot \"$DocumentRoot\"@" $httpd_conf
47         # whether WWW is enabled or not : 
48         if [ "$PLC_WWW_ENABLED" != "1" ] ; then
49             # avoid hitting drupal, that would try to connect to the db and create noise
50             disable_file $DocumentRoot/index.php
51         else
52             enable_file $DocumentRoot/index.php
53         fi
54
55         # Set the default include path
56         include_path=".:$DocumentRoot/planetlab/includes:$DocumentRoot/plekit/php:$DocumentRoot/generated:/etc/planetlab/php:/usr/share/plc_api/php"
57         sed -i -e "s@[;]*include_path = \"\.:.*\"@include_path = \"$include_path\"@" $php_ini
58
59         # Set open_basedir so as to avoid leaks
60         open_basedir="$DocumentRoot:/etc/planetlab/php:/usr/share/plc_api/php:/var/log/myslice:/var/tmp/bootmedium:/var/log/bm:/tmp"
61         sed -i -e "s@[;]*open_basedir =.*@open_basedir = \"$open_basedir\"@" $php_ini
62         
63         # for php-5.3 under fedora12, otherwise issues tons of warning messages
64         # Set timezone in php.ini if not already there
65         if grep '^;date.timezone' $php_ini >& /dev/null; then
66             dialog 'Setting PHP timezone to GMT'
67             sed -i -e 's,^;date.timezone.*,date.timezone = GMT,' $php_ini
68         fi
69
70         if grep '^short_open_tag = Off' $php_ini >& /dev/null; then
71             sed -i -e 's,^short_open_tag = Off,short_open_tag = On,' $php_ini
72         fi
73
74         # Disable default Listen directive
75         sed -i -e '/^Listen/d' $httpd_conf
76
77         plc_api_path_noslash=$(echo $PLC_API_PATH | sed -e s,/,,g)
78         # Set the port numbers
79         for server in WWW API BOOT ; do
80             enabled=PLC_${server}_ENABLED
81             if [ "${!enabled}" != "1" ] ; then
82                 continue
83             fi
84             hostname=PLC_${server}_HOST
85             http_port=PLC_${server}_PORT
86             https_port=PLC_${server}_SSL_PORT
87
88             # API should always be accessed via SSL
89             if [ "$server" = "API" ] ; then
90                 https_port=${!http_port}
91                 http_port=
92             fi
93
94             # Check if we are already listening on these ports
95             skip_http=0
96             skip_https=0
97             for previous_server in WWW API BOOT ; do
98                 if [ "$server" = "$previous_server" ] ; then
99                     break
100                 fi
101                 previous_enabled=PLC_${previous_server}_ENABLED
102                 if [ "${!previous_enabled}" != "1" ] ; then
103                     continue
104                 fi
105                 previous_http_port=PLC_${previous_server}_PORT
106                 previous_https_port=PLC_${previous_server}_SSL_PORT
107
108                 if [ -z "${http_port}" ]; then
109                     skip_http=1;
110                 elif [ -z "${!http_port}" ]; then
111                     skip_http=1;                    
112                 elif [ "${!http_port}" = "${!previous_http_port}" ] ; then
113                     skip_http=1
114                 fi
115                 if [ -z "${https_port}" ]; then
116                     skip_https=1
117                 elif [ -z "${!https_port}" ]; then
118                     skip_https=1
119                 elif [ "${!https_port}" = "${!previous_https_port}" ] ; then
120                     skip_https=1
121                 fi
122             done
123
124             # HTTP configuration
125             if [ $skip_http -eq 0 ] ; then
126                 cat <<EOF
127 Listen ${!http_port}
128 <VirtualHost *:${!http_port}>
129     # Make sure that the admin web pages are always accessed via SSL
130     Redirect /db https://$PLC_WWW_HOST:$PLC_WWW_SSL_PORT/db
131     Redirect /planetlab https://$PLC_WWW_HOST:$PLC_WWW_SSL_PORT/planetlab
132 # as a matter of fact most xmlrpc clients won't follow the redirection
133 # so this is mostly rethorical, but just in case...
134    Redirect /$plc_api_path_noslash https://$PLC_WWW_HOST:$PLC_WWW_SSL_PORT/$plc_api_path_noslash
135 </VirtualHost>
136
137 EOF
138             fi
139
140             # HTTPS configuration
141             if [ $skip_https -eq 0 ] ; then
142                 # XXX Cannot support NameVirtualHost over SSL. If
143                 # the API, boot, and web servers are all running
144                 # on the same machine, the web server certificate
145                 # takes precedence.
146                 sed -i \
147                     -e "s/^Listen .*/Listen ${!https_port}/" \
148                     -e "s/<VirtualHost _default_:.*>/<VirtualHost _default_:${!https_port}>/" \
149                     $ssl_conf
150                 # this is used to locate the right certificates
151                 server_lower=$(echo $server | tr 'A-Z' 'a-z')
152
153                 # which one is used is currently configured in myplc.spec,
154                 # with mod_python preferred
155                 if rpm -q mod_python >& /dev/null ; then
156                     configure_for_mod_python=true
157                 elif rpm -q mod_wsgi >& /dev/null ; then
158                     configure_for_mod_wsgi=true
159                 else
160                     echo "Requires mod_python or mod_wsgi.... exiting"
161                     exit 1
162                 fi
163
164                 # It would be tempting to use <IfModule> here 
165                 # but early tests showed this could be tricky/fragile
166                 # So let's hard-wire it for one module
167                 # A lot of trial-and -error was involved in getting this that way...
168
169                 if [ -n "$configure_for_mod_python" ] ; then
170 #################### for mod_python
171                     cat <<EOF
172 # mod_python location
173 <Location /PLCAPI/>
174     SetHandler mod_python
175     PythonPath "sys.path + ['/usr/share/plc_api']"
176     PythonHandler apache.ModPython
177 </Location>
178 EOF
179
180                 elif [ -n "$configure_for_mod_wsgi" ] ; then
181 #################### for mod_wsgi
182                     cat <<EOF
183 # create wsgi socket where we have the permission
184 WSGISocketPrefix run/wsgi
185
186 <VirtualHost *:${!https_port}>
187
188    # SSL
189    SSLEngine On
190    SSLCertificateFile /etc/planetlab/${server_lower}_ssl.crt
191    SSLCertificateKeyFile /etc/planetlab/${server_lower}_ssl.key
192    SSLCertificateChainFile /etc/planetlab/${server_lower}_ca_ssl.crt
193
194    WSGIScriptAlias /$plc_api_path_noslash /usr/share/plc_api/apache/plc.wsgi
195 # xxx would be cool to be able to tweak this through config
196    WSGIDaemonProcess plcapi-wsgi-ssl user=apache group=apache processes=1 threads=25
197    WSGIProcessGroup plcapi-wsgi-ssl
198
199    <Directory "/usr/share/plc_api/apache">
200       Options +ExecCGI
201       $(apache_allow)
202    </Directory>
203
204 </VirtualHost>
205 EOF
206                 fi
207             fi
208         done >$plc_conf
209
210         # Set custom Apache directives
211         (
212             # could be restricted to boot boxes but harmless..
213             cat <<EOF
214 AddType application/octet-stream .iso
215 AddType application/octet-stream .usb
216 EOF
217             # make sure /PLCAPI can't get accessed if API not enabled here
218             if [ "$PLC_API_ENABLED" != "1" ] ; then
219                 cat <<EOF
220 # mod_wsgi location
221 <Location $PLC_API_PATH>
222     $(apache_forbid)
223 </Location> 
224 EOF
225             fi
226
227             # redirect www requests if not on the right server
228             if [ "$PLC_WWW_ENABLED" != "1" ] ; then
229                 cat <<EOF
230 Redirect /index.html http://$PLC_WWW_HOST:$PLC_WWW_PORT/
231 EOF
232             fi
233         ) >>$plc_conf
234
235         # Make alpina-logs directory writable for bootmanager log upload
236         chown apache:apache $DocumentRoot/alpina-logs/nodes
237
238         # Make the Drupal files upload directory owned by Apache
239         mkdir -p $DocumentRoot/files
240         chown apache:apache $DocumentRoot/files
241
242         # Symlink any (real) files or directories in
243         # /data/var/www/html/* to /var/www/html/. We could descend
244         # into subdirectories, but the code to do so properly would be
245         # madness.
246         for file in /data/$DocumentRoot/* ; do
247             if [ -e "$file" -a ! -h "$file" ] ; then
248                 base=$(basename "$file")
249                 if [ ! -e "$DocumentRoot/$base" ] ; then
250                     ln -nsf "$file" "$DocumentRoot/$base"
251                 fi
252             fi
253         done
254
255         # Cleanup broken symlinks
256         for file in $DocumentRoot/* ; do
257             if [ -h "$file" -a ! -e "$file" ] ; then
258                 rm -f "$file"
259             fi
260         done
261
262         # Old style PHP constants
263         mkdir -p /etc/planetlab/php
264         cat >/etc/planetlab/php/site_constants.php <<"EOF"
265 <?php
266 include('plc_config.php');
267
268 define('PL_API_SERVER', PLC_API_HOST);
269 define('PL_API_PATH', PLC_API_PATH);
270 define('PL_API_PORT', PLC_API_PORT);
271 define('PL_API_CAPABILITY_AUTH_METHOD', 'capability');
272 define('PL_API_CAPABILITY_PASS', PLC_API_MAINTENANCE_PASSWORD);
273 define('PL_API_CAPABILITY_USERNAME', PLC_API_MAINTENANCE_USER);
274 define('WWW_BASE', PLC_WWW_HOST);
275 define('BOOT_BASE', PLC_BOOT_HOST);
276 define('DEBUG', PLC_WWW_DEBUG);
277 define('API_CALL_DEBUG', PLC_API_DEBUG);
278 define('SENDMAIL', PLC_MAIL_ENABLED);
279 define('PLANETLAB_SUPPORT_EMAIL', PLC_NAME . ' Support <' . PLC_MAIL_SUPPORT_ADDRESS . '>');
280 define('PLANETLAB_SUPPORT_EMAIL_ONLY', PLC_MAIL_SUPPORT_ADDRESS);
281 ?>
282 EOF
283
284         ## patch php.ini
285         # memory limit
286         sed -i -e 's,^memory_limit = 32M *;,memory_limit = 80M ; patch myplc -- ,' $php_ini 
287         # log_errors : is On by default
288         # error_log
289         if ! grep '^error_log *=' $php_ini > /dev/null ; then
290           echo 'error_log = /var/log/php.log' >> $php_ini
291           touch /var/log/php.log
292           chmod 666 /var/log/php.log
293         fi
294
295         ## make room for logs
296         touch /var/log/plcapi.log
297         chmod 666 /var/log/plcapi.log
298
299         plc_daemon httpd
300         check
301
302         result "$MESSAGE"
303         ;;
304
305     stop)
306         MESSAGE=$"Stopping web server"
307         dialog "$MESSAGE"
308
309         killproc plc_httpd
310         check
311
312         result "$MESSAGE"
313         ;;
314 esac
315
316 exit $ERRORS