-
Notifications
You must be signed in to change notification settings - Fork 1.4k
/
Copy pathapache
425 lines (387 loc) · 15.5 KB
/
apache
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
#!/bin/bash
#
# lib/apache
# Functions to control configuration and operation of apache web server
# Dependencies:
#
# - ``functions`` file
# - ``STACK_USER`` must be defined
#
# lib/apache exports the following functions:
#
# - install_apache_wsgi
# - apache_site_config_for
# - enable_apache_site
# - disable_apache_site
# - start_apache_server
# - stop_apache_server
# - restart_apache_server
# Save trace setting
_XTRACE_LIB_APACHE=$(set +o | grep xtrace)
set +o xtrace
# Allow overriding the default Apache user and group, default to
# current user and his default group.
APACHE_USER=${APACHE_USER:-$STACK_USER}
APACHE_GROUP=${APACHE_GROUP:-$(id -gn $APACHE_USER)}
APACHE_LOCAL_HOST=$SERVICE_LOCAL_HOST
if [[ "$SERVICE_IP_VERSION" == 6 ]]; then
APACHE_LOCAL_HOST=[$APACHE_LOCAL_HOST]
fi
# Set up apache name and configuration directory
# Note that APACHE_CONF_DIR is really more accurately apache's vhost
# configuration dir but we can't just change this because public interfaces.
if is_ubuntu; then
APACHE_NAME=apache2
APACHE_CONF_DIR=${APACHE_CONF_DIR:-/etc/$APACHE_NAME/sites-available}
APACHE_SETTINGS_DIR=${APACHE_SETTINGS_DIR:-/etc/$APACHE_NAME/conf-enabled}
elif is_fedora; then
APACHE_NAME=httpd
APACHE_CONF_DIR=${APACHE_CONF_DIR:-/etc/$APACHE_NAME/conf.d}
APACHE_SETTINGS_DIR=${APACHE_SETTINGS_DIR:-/etc/$APACHE_NAME/conf.d}
fi
APACHE_LOG_DIR="/var/log/${APACHE_NAME}"
# Functions
# ---------
# Enable apache mod and restart apache if it isn't already enabled.
function enable_apache_mod {
local mod=$1
# Apache installation, because we mark it NOPRIME
if is_ubuntu; then
# Skip mod_version as it is not a valid mod to enable
# on debuntu, instead it is built in.
if [[ "$mod" != "version" ]] && ! a2query -m $mod ; then
sudo a2enmod $mod
restart_apache_server
fi
elif is_fedora; then
# pass
true
else
exit_distro_not_supported "apache enable mod"
fi
}
# NOTE(sdague): Install uwsgi including apache module, we need to get
# to 2.0.6+ to get a working mod_proxy_uwsgi. We can probably build a
# check for that and do it differently for different platforms.
function install_apache_uwsgi {
local apxs="apxs2"
if is_fedora; then
apxs="apxs"
fi
if is_ubuntu; then
local pkg_list="uwsgi uwsgi-plugin-python3 libapache2-mod-proxy-uwsgi"
install_package ${pkg_list}
# NOTE(ianw) 2022-02-03 : Fedora 35 needs to skip this and fall
# into the install-from-source because the upstream packages
# didn't fix Python 3.10 compatibility before release. Should be
# fixed in uwsgi 4.9.0; can remove this when packages available
# or we drop this release
elif is_fedora && ! is_openeuler && ! [[ $DISTRO =~ f36 ]]; then
# Note httpd comes with mod_proxy_uwsgi and it is loaded by
# default; the mod_proxy_uwsgi package actually conflicts now.
# See:
# https://bugzilla.redhat.com/show_bug.cgi?id=1574335
#
# Thus there is nothing else to do after this install
install_package uwsgi \
uwsgi-plugin-python3
else
# Compile uwsgi from source.
local dir
dir=$(mktemp -d)
pushd $dir
pip_install uwsgi
pip download uwsgi -c $REQUIREMENTS_DIR/upper-constraints.txt
local uwsgi
uwsgi=$(ls uwsgi*)
tar xvf $uwsgi
cd uwsgi*/apache2
sudo $apxs -i -c mod_proxy_uwsgi.c
popd
# delete the temp directory
sudo rm -rf $dir
fi
if is_ubuntu; then
# we've got to enable proxy and proxy_uwsgi for this to work
sudo a2enmod proxy
sudo a2enmod proxy_uwsgi
elif is_fedora; then
# redhat is missing a nice way to turn on/off modules
echo "LoadModule proxy_uwsgi_module modules/mod_proxy_uwsgi.so" \
| sudo tee /etc/httpd/conf.modules.d/02-proxy-uwsgi.conf
fi
restart_apache_server
}
# install_apache_wsgi() - Install Apache server and wsgi module
function install_apache_wsgi {
# Apache installation, because we mark it NOPRIME
if is_ubuntu; then
# Install apache2, which is NOPRIME'd
install_package apache2
if is_package_installed libapache2-mod-wsgi; then
uninstall_package libapache2-mod-wsgi
fi
install_package libapache2-mod-wsgi-py3
elif is_fedora; then
sudo rm -f /etc/httpd/conf.d/000-*
install_package httpd python3-mod_wsgi
# rpm distros dont enable httpd by default so enable it to support reboots.
sudo systemctl enable httpd
# For consistency with Ubuntu, switch to the worker mpm, as
# the default is event
sudo sed -i '/mod_mpm_prefork.so/s/^/#/g' /etc/httpd/conf.modules.d/00-mpm.conf
sudo sed -i '/mod_mpm_event.so/s/^/#/g' /etc/httpd/conf.modules.d/00-mpm.conf
sudo sed -i '/mod_mpm_worker.so/s/^#//g' /etc/httpd/conf.modules.d/00-mpm.conf
else
exit_distro_not_supported "apache wsgi installation"
fi
# WSGI isn't enabled by default, enable it
enable_apache_mod wsgi
}
# apache_site_config_for() - The filename of the site's configuration file.
# This function uses the global variables APACHE_NAME and APACHE_CONF_DIR.
#
# On Ubuntu 14.04+, the site configuration file must have a .conf suffix for a2ensite and a2dissite to
# recognise it. a2ensite and a2dissite ignore the .conf suffix used as parameter. The default sites'
# files are 000-default.conf and default-ssl.conf.
#
# On Fedora, any file in /etc/httpd/conf.d/ whose name ends with .conf is enabled.
#
# On RHEL and CentOS, things should hopefully work as in Fedora.
#
# The table below summarizes what should happen on each distribution:
# +----------------------+--------------------+--------------------------+--------------------------+
# | Distribution | File name | Site enabling command | Site disabling command |
# +----------------------+--------------------+--------------------------+--------------------------+
# | Ubuntu 14.04 | site.conf | a2ensite site | a2dissite site |
# | Fedora, RHEL, CentOS | site.conf.disabled | mv site.conf{.disabled,} | mv site.conf{,.disabled} |
# +----------------------+--------------------+--------------------------+--------------------------+
function apache_site_config_for {
local site=$@
if is_ubuntu; then
# Ubuntu 14.04 - Apache 2.4
echo $APACHE_CONF_DIR/${site}.conf
elif is_fedora; then
# fedora conf.d is only imported if it ends with .conf so this is approx the same
local enabled_site_file="$APACHE_CONF_DIR/${site}.conf"
if [ -f $enabled_site_file ]; then
echo ${enabled_site_file}
else
echo ${enabled_site_file}.disabled
fi
fi
}
# enable_apache_site() - Enable a particular apache site
function enable_apache_site {
local site=$@
# Many of our sites use mod version. Just enable it.
enable_apache_mod version
if is_ubuntu; then
sudo a2ensite ${site}
elif is_fedora; then
local enabled_site_file="$APACHE_CONF_DIR/${site}.conf"
# Do nothing if site already enabled or no site config exists
if [[ -f ${enabled_site_file}.disabled ]] && [[ ! -f ${enabled_site_file} ]]; then
sudo mv ${enabled_site_file}.disabled ${enabled_site_file}
fi
fi
}
# disable_apache_site() - Disable a particular apache site
function disable_apache_site {
local site=$@
if is_ubuntu; then
sudo a2dissite ${site} || true
elif is_fedora; then
local enabled_site_file="$APACHE_CONF_DIR/${site}.conf"
# Do nothing if no site config exists
if [[ -f ${enabled_site_file} ]]; then
sudo mv ${enabled_site_file} ${enabled_site_file}.disabled
fi
fi
}
# start_apache_server() - Start running apache server
function start_apache_server {
start_service $APACHE_NAME
}
# stop_apache_server() - Stop running apache server
function stop_apache_server {
if [ -n "$APACHE_NAME" ]; then
stop_service $APACHE_NAME
else
exit_distro_not_supported "apache configuration"
fi
}
# restart_apache_server
function restart_apache_server {
# Apache can be slow to stop, doing an explicit stop, sleep, start helps
# to mitigate issues where apache will claim a port it's listening on is
# still in use and fail to start.
restart_service $APACHE_NAME
}
# write_uwsgi_config() - Create a new uWSGI config file
function write_uwsgi_config {
local conf=$1
local wsgi=$2
local url=$3
local http=$4
local name=$5
if [ -z "$name" ]; then
name=$(basename $wsgi)
fi
# create a home for the sockets; note don't use /tmp -- apache has
# a private view of it on some platforms.
local socket_dir='/var/run/uwsgi'
# /var/run will be empty on ubuntu after reboot, so we can use systemd-temptiles
# to automatically create $socket_dir.
sudo mkdir -p /etc/tmpfiles.d/
echo "d $socket_dir 0755 $STACK_USER root" | sudo tee /etc/tmpfiles.d/uwsgi.conf
sudo systemd-tmpfiles --create /etc/tmpfiles.d/uwsgi.conf
local socket="$socket_dir/${name}.socket"
# always cleanup given that we are using iniset here
rm -rf $conf
# Set either the module path or wsgi script path depending on what we've
# been given. Note that the regex isn't exhaustive - neither Python modules
# nor Python variables can start with a number - but it's "good enough"
if [[ "$wsgi" =~ ^[a-zA-Z0-9_.]+:[a-zA-Z0-9_]+$ ]]; then
iniset "$conf" uwsgi module "$wsgi"
else
deprecated 'Configuring uWSGI with a WSGI file is deprecated, use module paths instead'
iniset "$conf" uwsgi wsgi-file "$wsgi"
fi
iniset "$conf" uwsgi processes $API_WORKERS
# This is running standalone
iniset "$conf" uwsgi master true
# Set die-on-term & exit-on-reload so that uwsgi shuts down
iniset "$conf" uwsgi die-on-term true
iniset "$conf" uwsgi exit-on-reload false
# Set worker-reload-mercy so that worker will not exit till the time
# configured after graceful shutdown
iniset "$conf" uwsgi worker-reload-mercy $WORKER_TIMEOUT
iniset "$conf" uwsgi enable-threads true
iniset "$conf" uwsgi plugins http,python3
# uwsgi recommends this to prevent thundering herd on accept.
iniset "$conf" uwsgi thunder-lock true
# Set hook to trigger graceful shutdown on SIGTERM
iniset "$conf" uwsgi hook-master-start "unix_signal:15 gracefully_kill_them_all"
# Override the default size for headers from the 4k default.
iniset "$conf" uwsgi buffer-size 65535
# Make sure the client doesn't try to re-use the connection.
iniset "$conf" uwsgi add-header "Connection: close"
# This ensures that file descriptors aren't shared between processes.
iniset "$conf" uwsgi lazy-apps true
# Starting time of the WSGi server
iniset "$conf" uwsgi start-time %t
# If we said bind directly to http, then do that and don't start the apache proxy
if [[ -n "$http" ]]; then
iniset "$conf" uwsgi http $http
else
local apache_conf=""
apache_conf=$(apache_site_config_for $name)
iniset "$conf" uwsgi socket "$socket"
iniset "$conf" uwsgi chmod-socket 666
echo "ProxyPass \"${url}\" \"unix:${socket}|uwsgi://uwsgi-uds-${name}\" retry=0 acquire=1 " | sudo tee -a $apache_conf
enable_apache_site $name
restart_apache_server
fi
}
# For services using chunked encoding, the only services known to use this
# currently are Glance and Swift, we need to use an http proxy instead of
# mod_proxy_uwsgi because the chunked encoding gets dropped. See:
# https://github.com/unbit/uwsgi/issues/1540.
function write_local_uwsgi_http_config {
local conf=$1
local wsgi=$2
local url=$3
local name=$4
if [ -z "$name" ]; then
name=$(basename $wsgi)
fi
# create a home for the sockets; note don't use /tmp -- apache has
# a private view of it on some platforms.
# always cleanup given that we are using iniset here
rm -rf $conf
# Set either the module path or wsgi script path depending on what we've
# been given
if [[ "$wsgi" =~ ^[a-zA-Z0-9_.]+:[a-zA-Z0-9_]+$ ]]; then
iniset "$conf" uwsgi module "$wsgi"
else
deprecated 'Configuring uWSGI with a WSGI file is deprecated, use module paths instead'
iniset "$conf" uwsgi wsgi-file "$wsgi"
fi
port=$(get_random_port)
iniset "$conf" uwsgi http-socket "$APACHE_LOCAL_HOST:$port"
iniset "$conf" uwsgi processes $API_WORKERS
# This is running standalone
iniset "$conf" uwsgi master true
# Set die-on-term & exit-on-reload so that uwsgi shuts down
iniset "$conf" uwsgi die-on-term true
iniset "$conf" uwsgi exit-on-reload false
# Set worker-reload-mercy so that worker will not exit till the time
# configured after graceful shutdown
iniset "$conf" uwsgi worker-reload-mercy $WORKER_TIMEOUT
iniset "$conf" uwsgi enable-threads true
iniset "$conf" uwsgi plugins http,python3
# uwsgi recommends this to prevent thundering herd on accept.
iniset "$conf" uwsgi thunder-lock true
# Set hook to trigger graceful shutdown on SIGTERM
iniset "$conf" uwsgi hook-master-start "unix_signal:15 gracefully_kill_them_all"
# Override the default size for headers from the 4k default.
iniset "$conf" uwsgi buffer-size 65535
# Make sure the client doesn't try to re-use the connection.
iniset "$conf" uwsgi add-header "Connection: close"
# This ensures that file descriptors aren't shared between processes.
iniset "$conf" uwsgi lazy-apps true
iniset "$conf" uwsgi chmod-socket 666
iniset "$conf" uwsgi http-raw-body true
iniset "$conf" uwsgi http-chunked-input true
iniset "$conf" uwsgi http-auto-chunked true
iniset "$conf" uwsgi http-keepalive false
# Increase socket timeout for slow chunked uploads
iniset "$conf" uwsgi socket-timeout 30
# Starting time of the WSGi server
iniset "$conf" uwsgi start-time %t
enable_apache_mod proxy
enable_apache_mod proxy_http
local apache_conf=""
apache_conf=$(apache_site_config_for $name)
echo "KeepAlive Off" | sudo tee $apache_conf
echo "SetEnv proxy-sendchunked 1" | sudo tee -a $apache_conf
echo "ProxyPass \"${url}\" \"http://$APACHE_LOCAL_HOST:$port\" retry=0 acquire=1 " | sudo tee -a $apache_conf
enable_apache_site $name
restart_apache_server
}
# Write a straight-through proxy for a service that runs locally and just needs
# to be reachable via the main http proxy at $loc
function write_local_proxy_http_config {
local name=$1
local url=$2
local loc=$3
local apache_conf
apache_conf=$(apache_site_config_for $name)
enable_apache_mod proxy
enable_apache_mod proxy_http
echo "KeepAlive Off" | sudo tee $apache_conf
echo "SetEnv proxy-sendchunked 1" | sudo tee -a $apache_conf
echo "ProxyPass \"${loc}\" \"$url\" retry=0 acquire=1 " | sudo tee -a $apache_conf
enable_apache_site $name
restart_apache_server
}
function remove_uwsgi_config {
local conf=$1
local wsgi=$2
local name=""
# TODO(stephenfin): Remove this call when everyone is using module path
# configuration instead of file path configuration
name=$(basename $wsgi)
if [[ "$wsgi" = /* ]]; then
deprecated "Passing a wsgi script to remove_uwsgi_config is deprecated, pass an application name instead"
fi
rm -rf $conf
disable_apache_site $name
}
# Restore xtrace
$_XTRACE_LIB_APACHE
# Tell emacs to use shell-script-mode
## Local variables:
## mode: shell-script
## End: