System for quickly installing an OpenStack cloud from upstream git for testing and development.
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

apache 13KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370
  1. #!/bin/bash
  2. #
  3. # lib/apache
  4. # Functions to control configuration and operation of apache web server
  5. # Dependencies:
  6. #
  7. # - ``functions`` file
  8. # - ``STACK_USER`` must be defined
  9. #
  10. # lib/apache exports the following functions:
  11. #
  12. # - install_apache_wsgi
  13. # - apache_site_config_for
  14. # - enable_apache_site
  15. # - disable_apache_site
  16. # - start_apache_server
  17. # - stop_apache_server
  18. # - restart_apache_server
  19. # Save trace setting
  20. _XTRACE_LIB_APACHE=$(set +o | grep xtrace)
  21. set +o xtrace
  22. # Allow overriding the default Apache user and group, default to
  23. # current user and his default group.
  24. APACHE_USER=${APACHE_USER:-$STACK_USER}
  25. APACHE_GROUP=${APACHE_GROUP:-$(id -gn $APACHE_USER)}
  26. # Set up apache name and configuration directory
  27. # Note that APACHE_CONF_DIR is really more accurately apache's vhost
  28. # configuration dir but we can't just change this because public interfaces.
  29. if is_ubuntu; then
  30. APACHE_NAME=apache2
  31. APACHE_CONF_DIR=${APACHE_CONF_DIR:-/etc/$APACHE_NAME/sites-available}
  32. APACHE_SETTINGS_DIR=${APACHE_SETTINGS_DIR:-/etc/$APACHE_NAME/conf-enabled}
  33. elif is_fedora; then
  34. APACHE_NAME=httpd
  35. APACHE_CONF_DIR=${APACHE_CONF_DIR:-/etc/$APACHE_NAME/conf.d}
  36. APACHE_SETTINGS_DIR=${APACHE_SETTINGS_DIR:-/etc/$APACHE_NAME/conf.d}
  37. elif is_suse; then
  38. APACHE_NAME=apache2
  39. APACHE_CONF_DIR=${APACHE_CONF_DIR:-/etc/$APACHE_NAME/vhosts.d}
  40. APACHE_SETTINGS_DIR=${APACHE_SETTINGS_DIR:-/etc/$APACHE_NAME/conf.d}
  41. fi
  42. APACHE_LOG_DIR="/var/log/${APACHE_NAME}"
  43. # Functions
  44. # ---------
  45. # Enable apache mod and restart apache if it isn't already enabled.
  46. function enable_apache_mod {
  47. local mod=$1
  48. # Apache installation, because we mark it NOPRIME
  49. if is_ubuntu; then
  50. # Skip mod_version as it is not a valid mod to enable
  51. # on debuntu, instead it is built in.
  52. if [[ "$mod" != "version" ]] && ! a2query -m $mod ; then
  53. sudo a2enmod $mod
  54. restart_apache_server
  55. fi
  56. elif is_suse; then
  57. if ! a2enmod -q $mod ; then
  58. sudo a2enmod $mod
  59. restart_apache_server
  60. fi
  61. elif is_fedora; then
  62. # pass
  63. true
  64. else
  65. exit_distro_not_supported "apache enable mod"
  66. fi
  67. }
  68. # NOTE(sdague): Install uwsgi including apache module, we need to get
  69. # to 2.0.6+ to get a working mod_proxy_uwsgi. We can probably build a
  70. # check for that and do it differently for different platforms.
  71. function install_apache_uwsgi {
  72. local apxs="apxs2"
  73. if is_fedora; then
  74. apxs="apxs"
  75. fi
  76. # Ubuntu xenial is back level on uwsgi so the proxy doesn't
  77. # actually work. Hence we have to build from source for now.
  78. #
  79. # Centos 7 actually has the module in epel, but there was a big
  80. # push to disable epel by default. As such, compile from source
  81. # there as well.
  82. local dir
  83. dir=$(mktemp -d)
  84. pushd $dir
  85. pip_install uwsgi
  86. pip download uwsgi -c $REQUIREMENTS_DIR/upper-constraints.txt
  87. local uwsgi
  88. uwsgi=$(ls uwsgi*)
  89. tar xvf $uwsgi
  90. cd uwsgi*/apache2
  91. sudo $apxs -i -c mod_proxy_uwsgi.c
  92. popd
  93. # delete the temp directory
  94. sudo rm -rf $dir
  95. if is_ubuntu || is_suse ; then
  96. # we've got to enable proxy and proxy_uwsgi for this to work
  97. sudo a2enmod proxy
  98. sudo a2enmod proxy_uwsgi
  99. elif is_fedora; then
  100. # redhat is missing a nice way to turn on/off modules
  101. echo "LoadModule proxy_uwsgi_module modules/mod_proxy_uwsgi.so" \
  102. | sudo tee /etc/httpd/conf.modules.d/02-proxy-uwsgi.conf
  103. fi
  104. restart_apache_server
  105. }
  106. # install_apache_wsgi() - Install Apache server and wsgi module
  107. function install_apache_wsgi {
  108. # Apache installation, because we mark it NOPRIME
  109. if is_ubuntu; then
  110. # Install apache2, which is NOPRIME'd
  111. install_package apache2
  112. if python3_enabled; then
  113. if is_package_installed libapache2-mod-wsgi; then
  114. uninstall_package libapache2-mod-wsgi
  115. fi
  116. install_package libapache2-mod-wsgi-py3
  117. else
  118. install_package libapache2-mod-wsgi
  119. fi
  120. elif is_fedora; then
  121. sudo rm -f /etc/httpd/conf.d/000-*
  122. install_package httpd mod_wsgi
  123. # For consistency with Ubuntu, switch to the worker mpm, as
  124. # the default is event
  125. sudo sed -i '/mod_mpm_prefork.so/s/^/#/g' /etc/httpd/conf.modules.d/00-mpm.conf
  126. sudo sed -i '/mod_mpm_event.so/s/^/#/g' /etc/httpd/conf.modules.d/00-mpm.conf
  127. sudo sed -i '/mod_mpm_worker.so/s/^#//g' /etc/httpd/conf.modules.d/00-mpm.conf
  128. elif is_suse; then
  129. install_package apache2 apache2-mod_wsgi
  130. else
  131. exit_distro_not_supported "apache wsgi installation"
  132. fi
  133. # WSGI isn't enabled by default, enable it
  134. enable_apache_mod wsgi
  135. }
  136. # apache_site_config_for() - The filename of the site's configuration file.
  137. # This function uses the global variables APACHE_NAME and APACHE_CONF_DIR.
  138. #
  139. # On Ubuntu 14.04+, the site configuration file must have a .conf suffix for a2ensite and a2dissite to
  140. # recognise it. a2ensite and a2dissite ignore the .conf suffix used as parameter. The default sites'
  141. # files are 000-default.conf and default-ssl.conf.
  142. #
  143. # On Fedora and openSUSE, any file in /etc/httpd/conf.d/ whose name ends with .conf is enabled.
  144. #
  145. # On RHEL and CentOS, things should hopefully work as in Fedora.
  146. #
  147. # The table below summarizes what should happen on each distribution:
  148. # +----------------------+--------------------+--------------------------+--------------------------+
  149. # | Distribution | File name | Site enabling command | Site disabling command |
  150. # +----------------------+--------------------+--------------------------+--------------------------+
  151. # | Ubuntu 14.04 | site.conf | a2ensite site | a2dissite site |
  152. # | Fedora, RHEL, CentOS | site.conf.disabled | mv site.conf{.disabled,} | mv site.conf{,.disabled} |
  153. # +----------------------+--------------------+--------------------------+--------------------------+
  154. function apache_site_config_for {
  155. local site=$@
  156. if is_ubuntu; then
  157. # Ubuntu 14.04 - Apache 2.4
  158. echo $APACHE_CONF_DIR/${site}.conf
  159. elif is_fedora || is_suse; then
  160. # fedora conf.d is only imported if it ends with .conf so this is approx the same
  161. local enabled_site_file="$APACHE_CONF_DIR/${site}.conf"
  162. if [ -f $enabled_site_file ]; then
  163. echo ${enabled_site_file}
  164. else
  165. echo ${enabled_site_file}.disabled
  166. fi
  167. fi
  168. }
  169. # enable_apache_site() - Enable a particular apache site
  170. function enable_apache_site {
  171. local site=$@
  172. # Many of our sites use mod version. Just enable it.
  173. enable_apache_mod version
  174. if is_ubuntu; then
  175. sudo a2ensite ${site}
  176. elif is_fedora || is_suse; then
  177. local enabled_site_file="$APACHE_CONF_DIR/${site}.conf"
  178. # Do nothing if site already enabled or no site config exists
  179. if [[ -f ${enabled_site_file}.disabled ]] && [[ ! -f ${enabled_site_file} ]]; then
  180. sudo mv ${enabled_site_file}.disabled ${enabled_site_file}
  181. fi
  182. fi
  183. }
  184. # disable_apache_site() - Disable a particular apache site
  185. function disable_apache_site {
  186. local site=$@
  187. if is_ubuntu; then
  188. sudo a2dissite ${site} || true
  189. elif is_fedora || is_suse; then
  190. local enabled_site_file="$APACHE_CONF_DIR/${site}.conf"
  191. # Do nothing if no site config exists
  192. if [[ -f ${enabled_site_file} ]]; then
  193. sudo mv ${enabled_site_file} ${enabled_site_file}.disabled
  194. fi
  195. fi
  196. }
  197. # start_apache_server() - Start running apache server
  198. function start_apache_server {
  199. start_service $APACHE_NAME
  200. }
  201. # stop_apache_server() - Stop running apache server
  202. function stop_apache_server {
  203. if [ -n "$APACHE_NAME" ]; then
  204. stop_service $APACHE_NAME
  205. else
  206. exit_distro_not_supported "apache configuration"
  207. fi
  208. }
  209. # restart_apache_server
  210. function restart_apache_server {
  211. # Apache can be slow to stop, doing an explicit stop, sleep, start helps
  212. # to mitigate issues where apache will claim a port it's listening on is
  213. # still in use and fail to start.
  214. restart_service $APACHE_NAME
  215. }
  216. function write_uwsgi_config {
  217. local file=$1
  218. local wsgi=$2
  219. local url=$3
  220. local http=$4
  221. local name=""
  222. name=$(basename $wsgi)
  223. # create a home for the sockets; note don't use /tmp -- apache has
  224. # a private view of it on some platforms.
  225. local socket_dir='/var/run/uwsgi'
  226. # /var/run will be empty on ubuntu after reboot, so we can use systemd-temptiles
  227. # to automatically create $socket_dir.
  228. sudo mkdir -p /etc/tmpfiles.d/
  229. echo "d $socket_dir 0755 $STACK_USER root" | sudo tee /etc/tmpfiles.d/uwsgi.conf
  230. sudo systemd-tmpfiles --create /etc/tmpfiles.d/uwsgi.conf
  231. local socket="$socket_dir/${name}.socket"
  232. # always cleanup given that we are using iniset here
  233. rm -rf $file
  234. iniset "$file" uwsgi wsgi-file "$wsgi"
  235. iniset "$file" uwsgi processes $API_WORKERS
  236. # This is running standalone
  237. iniset "$file" uwsgi master true
  238. # Set die-on-term & exit-on-reload so that uwsgi shuts down
  239. iniset "$file" uwsgi die-on-term true
  240. iniset "$file" uwsgi exit-on-reload false
  241. # Set worker-reload-mercy so that worker will not exit till the time
  242. # configured after graceful shutdown
  243. iniset "$file" uwsgi worker-reload-mercy $WORKER_TIMEOUT
  244. iniset "$file" uwsgi enable-threads true
  245. iniset "$file" uwsgi plugins python
  246. # uwsgi recommends this to prevent thundering herd on accept.
  247. iniset "$file" uwsgi thunder-lock true
  248. # Set hook to trigger graceful shutdown on SIGTERM
  249. iniset "$file" uwsgi hook-master-start "unix_signal:15 gracefully_kill_them_all"
  250. # Override the default size for headers from the 4k default.
  251. iniset "$file" uwsgi buffer-size 65535
  252. # Make sure the client doesn't try to re-use the connection.
  253. iniset "$file" uwsgi add-header "Connection: close"
  254. # This ensures that file descriptors aren't shared between processes.
  255. iniset "$file" uwsgi lazy-apps true
  256. # If we said bind directly to http, then do that and don't start the apache proxy
  257. if [[ -n "$http" ]]; then
  258. iniset "$file" uwsgi http $http
  259. else
  260. local apache_conf=""
  261. apache_conf=$(apache_site_config_for $name)
  262. iniset "$file" uwsgi socket "$socket"
  263. iniset "$file" uwsgi chmod-socket 666
  264. echo "ProxyPass \"${url}\" \"unix:${socket}|uwsgi://uwsgi-uds-${name}/\" retry=0 " | sudo tee -a $apache_conf
  265. enable_apache_site $name
  266. restart_apache_server
  267. fi
  268. }
  269. # For services using chunked encoding, the only services known to use this
  270. # currently are Glance and Swift, we need to use an http proxy instead of
  271. # mod_proxy_uwsgi because the chunked encoding gets dropped. See:
  272. # https://github.com/unbit/uwsgi/issues/1540 You can workaround this on python2
  273. # but that involves having apache buffer the request before sending it to
  274. # uwsgi.
  275. function write_local_uwsgi_http_config {
  276. local file=$1
  277. local wsgi=$2
  278. local url=$3
  279. name=$(basename $wsgi)
  280. # create a home for the sockets; note don't use /tmp -- apache has
  281. # a private view of it on some platforms.
  282. # always cleanup given that we are using iniset here
  283. rm -rf $file
  284. iniset "$file" uwsgi wsgi-file "$wsgi"
  285. port=$(get_random_port)
  286. iniset "$file" uwsgi http-socket "127.0.0.1:$port"
  287. iniset "$file" uwsgi processes $API_WORKERS
  288. # This is running standalone
  289. iniset "$file" uwsgi master true
  290. # Set die-on-term & exit-on-reload so that uwsgi shuts down
  291. iniset "$file" uwsgi die-on-term true
  292. iniset "$file" uwsgi exit-on-reload false
  293. iniset "$file" uwsgi enable-threads true
  294. iniset "$file" uwsgi plugins python
  295. # uwsgi recommends this to prevent thundering herd on accept.
  296. iniset "$file" uwsgi thunder-lock true
  297. # Set hook to trigger graceful shutdown on SIGTERM
  298. iniset "$file" uwsgi hook-master-start "unix_signal:15 gracefully_kill_them_all"
  299. # Set worker-reload-mercy so that worker will not exit till the time
  300. # configured after graceful shutdown
  301. iniset "$file" uwsgi worker-reload-mercy $WORKER_TIMEOUT
  302. # Override the default size for headers from the 4k default.
  303. iniset "$file" uwsgi buffer-size 65535
  304. # Make sure the client doesn't try to re-use the connection.
  305. iniset "$file" uwsgi add-header "Connection: close"
  306. # This ensures that file descriptors aren't shared between processes.
  307. iniset "$file" uwsgi lazy-apps true
  308. iniset "$file" uwsgi chmod-socket 666
  309. iniset "$file" uwsgi http-raw-body true
  310. iniset "$file" uwsgi http-chunked-input true
  311. iniset "$file" uwsgi http-auto-chunked true
  312. iniset "$file" uwsgi http-keepalive false
  313. # Increase socket timeout for slow chunked uploads
  314. iniset "$file" uwsgi socket-timeout 30
  315. enable_apache_mod proxy
  316. enable_apache_mod proxy_http
  317. local apache_conf=""
  318. apache_conf=$(apache_site_config_for $name)
  319. echo "KeepAlive Off" | sudo tee $apache_conf
  320. echo "SetEnv proxy-sendchunked 1" | sudo tee -a $apache_conf
  321. echo "ProxyPass \"${url}\" \"http://127.0.0.1:$port\" retry=0 " | sudo tee -a $apache_conf
  322. enable_apache_site $name
  323. restart_apache_server
  324. }
  325. function remove_uwsgi_config {
  326. local file=$1
  327. local wsgi=$2
  328. local name=""
  329. name=$(basename $wsgi)
  330. rm -rf $file
  331. disable_apache_site $name
  332. }
  333. # Restore xtrace
  334. $_XTRACE_LIB_APACHE
  335. # Tell emacs to use shell-script-mode
  336. ## Local variables:
  337. ## mode: shell-script
  338. ## End: