Add uWSGI role and use systemd instead of emperor mode

Using the emperor mode of uWSGI is redundant now that we depend on
systemd. This change switches uWSGI Keystone to systemd template services
based on the recipe from the uWSGI documentation [1].

A new role is created to encapsulate the uWSGI login in anticipation of
switching Ironic API to uWSGI as well. Reduce repetition in Keystone.

[1] https://uwsgi-docs.readthedocs.io/en/latest/Systemd.html

Change-Id: I50bc3f7a4faf14c36b92e7656b7149e9c833c85e
This commit is contained in:
Dmitry Tantsur 2021-08-26 10:22:50 +02:00
parent 358a989e64
commit 5c1881282c
12 changed files with 167 additions and 68 deletions

View File

@ -22,13 +22,6 @@
--network-interface argument to "bifrost-cli install".
when: ('ansible_' + ans_network_interface) not in hostvars[inventory_hostname]
# NOTE(TheJulia): There is significant commonality between this playbook
# and the bifrost bootstrap process.
- name: "Get uwsgi install location"
shell: echo $(dirname $(which uwsgi))
register: uwsgi_install_prefix
environment: "{{ bifrost_venv_env }}"
- name: "Get keystone-wsgi-admin location"
shell: echo $(dirname $(which keystone-wsgi-admin))
register: keystone_install_prefix
@ -224,29 +217,10 @@
group: "{{ nginx_user }}"
mode: 0754
- name: "Ensure /etc/uwsgi exists"
file:
name: "/etc/uwsgi"
state: directory
owner: "{{ nginx_user }}"
group: "{{ nginx_user }}" # TODO(TheJulia): Split webserver user/group.
mode: 0755
- name: "Ensure /etc/uwsgi/apps-available exists"
file:
name: "/etc/uwsgi/apps-available"
state: directory
owner: "{{ nginx_user }}"
group: "{{ nginx_user }}" # TODO(TheJulia): Split webserver user/group.
mode: 0755
- name: "Ensure /etc/uwsgi/apps-enabled exists"
file:
name: "/etc/uwsgi/apps-enabled"
state: directory
owner: "{{ nginx_user }}"
group: "{{ nginx_user }}" # TODO(TheJulia): Split webserver user/group.
mode: 0755
- name: "Bootstrap uWSGI"
include_role:
name: bifrost-uwsgi-install
tasks_from: bootstrap
- name: "Place keystone uWSGI config"
template:
@ -278,19 +252,6 @@
group: "{{ nginx_user }}" # TODO(TheJulia): Split webserver user/group.
mode: 0755
- name: "Place uwsgi services"
template:
src: systemd_template.j2
dest: "{{ init_dest_dir }}{{ item.service_name }}.service"
owner: "root"
group: "root"
loop:
- { service_path: "{{ uwsgi_install_prefix.stdout | default('') }}",
service_name: 'uwsgi',
username: "{{ nginx_user }}",
exec_start_pre: "/usr/bin/install -m 755 -o {{ nginx_user }} -g {{ nginx_user }} -d /run/uwsgi",
args: '--master --emperor /etc/uwsgi/apps-enabled'} # TODO(TheJulia): Split webserver user/group.
- block:
- name: "Explicitly allow keystone port (TCP) on selinux"
seport:

View File

@ -28,18 +28,17 @@
file: name=/opt/stack state=directory owner=root group=root
when: not skip_install | bool
- name: "Install uWSGI"
include_role:
name: bifrost-uwsgi-install
tasks_from: install
- name: "Install pymysql"
include_role:
name: bifrost-pip-install
vars:
package: pymysql
- name: "Install uWSGI in venv if using"
include_role:
name: bifrost-pip-install
vars:
package: uWSGI
- name: "Install python-openstackclient"
include_role:
name: bifrost-pip-install

View File

@ -15,10 +15,16 @@
systemd:
daemon_reload: yes
- name: "Start Keystone services"
service:
name: uwsgi@keystone-{{ item }}
state: restarted
enabled: yes
loop:
- public
- admin
- name: "Start Nginx"
import_role:
name: bifrost-nginx-install
tasks_from: start
- name: "Ensure uwsgi is running with current config"
service: name=uwsgi state=restarted enabled=yes

View File

@ -1,15 +0,0 @@
[Unit]
Description={{ item.service_name }} service
[Service]
Restart=on-failure
PermissionsStartOnly=true
{% if item.exec_start_pre %}
ExecStartPre={{ item.exec_start_pre }}
{% endif %}
ExecStart={{ item.service_path }}/{{ item.service_name }} {{ item.args }}
User={{ item.username }}
[Install]
WantedBy=multi-user.target
Alias={{ item.service_name }}.service

View File

@ -7,6 +7,8 @@ no-orphans = true
chmod-socket = 660
virtualenv = {{ bifrost_venv_dir }}
procname-prefix = keystone-{{ item }}
socket = /run/uwsgi/keystone-{{ item }}.socket
pidfile = /run/uwsgi/keystone-{{ item }}.pid

View File

@ -0,0 +1,23 @@
---
# If testing is true, then the environment is setup for using libvirt
# virtual machines for the hardware instead of real hardware.
testing: false
# set to true to skip installation completely
skip_install: False
# set to true to skip installing dependencies
skip_package_install: False
# set to true to skip generation of configs and database configuration
skip_bootstrap: False
nginx_user: "{{ 'www-data' if ansible_os_family == 'Debian' else 'nginx' }}"
init_dest_path: "{{ '/usr' if ansible_os_family != 'Debian' else '' }}/lib/systemd/system/"
# Settings related to installing bifrost in a virtual environment
bifrost_venv_dir: "{{ lookup('env', 'VENV') or '/opt/stack/bifrost' }}"
bifrost_venv_env:
VIRTUAL_ENV: "{{ bifrost_venv_dir }}"
PATH: "{{ bifrost_venv_dir }}/bin:{{ ansible_env.PATH }}" # include regular path via lookup env
pydoc: "python -m pydoc"
ansible_python_interpreter: "{{ bifrost_venv_dir + '/bin/python3' }}"

View File

@ -0,0 +1,57 @@
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
# implied.
# See the License for the specific language governing permissions and
# limitations under the License.
---
# NOTE(TheJulia): There is significant commonality between this playbook
# and the bifrost bootstrap process.
- name: "Get uwsgi install location"
shell: echo $(dirname $(which uwsgi))
register: uwsgi_install_prefix
environment: "{{ bifrost_venv_env }}"
- name: "Ensure /etc/uwsgi exists"
file:
name: "/etc/uwsgi"
state: directory
owner: "{{ nginx_user }}"
group: "{{ nginx_user }}" # TODO(TheJulia): Split webserver user/group.
mode: 0755
- name: "Ensure /etc/uwsgi/apps-available exists"
file:
name: "/etc/uwsgi/apps-available"
state: directory
owner: "{{ nginx_user }}"
group: "{{ nginx_user }}" # TODO(TheJulia): Split webserver user/group.
mode: 0755
- name: "Ensure /etc/uwsgi/apps-enabled exists"
file:
name: "/etc/uwsgi/apps-enabled"
state: directory
owner: "{{ nginx_user }}"
group: "{{ nginx_user }}" # TODO(TheJulia): Split webserver user/group.
mode: 0755
- name: "Disable standalone uWSGI service"
service:
name: uwsgi
state: stopped
enabled: no
ignore_errors: true
- name: "Place the uWSGI service template"
template:
src: uwsgi@.service.j2
dest: "{{ init_dest_dir }}uwsgi@.service"
owner: "root"
group: "root"

View File

@ -0,0 +1,18 @@
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
# implied.
# See the License for the specific language governing permissions and
# limitations under the License.
---
- name: "Install uWSGI via pip"
include_role:
name: bifrost-pip-install
vars:
package: uWSGI

View File

@ -0,0 +1,20 @@
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
# implied.
# See the License for the specific language governing permissions and
# limitations under the License.
---
- name: "Install uWSGI"
include: install.yml
when: not skip_package_install | bool
- name: "Bootstrap uWSGI"
include: bootstrap.yml
when: not skip_bootstrap | bool

View File

@ -0,0 +1,17 @@
[Unit]
Description=%i uWSGI service
[Service]
ExecStart={{ uwsgi_install_prefix.stdout | default('/usr/bin') }}/uwsgi \
--ini /etc/uwsgi/apps-enabled/%i.ini
SyslogIdentifier=%i
RuntimeDirectory=uwsgi
User={{ nginx_user }}
Group={{ nginx_user }}
Restart=on-failure
KillSignal=SIGQUIT
Type=notify
NotifyAccess=all
[Install]
WantedBy=multi-user.target

View File

@ -0,0 +1,10 @@
---
features:
- |
Adds a new role ``bifrost-uwsgi-install`` encapsulating uWSGI configuration
logic.
upgrade:
- |
Keystone services are now run as separate systemd services
``uwsgi@keystone-public`` and ``uwsgi@keystone-admin``. The standalone
``uwsgi`` service is no longer used and is disabled on upgrade.

View File

@ -76,7 +76,8 @@ sudo journalctl -u ironic-inspector &> ${LOG_LOCATION}/ironic-inspector.log
sudo journalctl -u dnsmasq &> ${LOG_LOCATION}/dnsmasq.log
sudo journalctl -u vbmcd &> ${LOG_LOCATION}/vbmcd.log
sudo journalctl -u redfish-emulator &> ${LOG_LOCATION}/redfish-emulator.log
sudo journalctl -u uwsgi &> ${LOG_LOCATION}/uwsgi.log
sudo journalctl -u uwsgi@keystone-public &> ${LOG_LOCATION}/keystone-public.log
sudo journalctl -u uwsgi@keystone-admin &> ${LOG_LOCATION}/keystone-admin.log
# Copy PXE information
mkdir -p ${LOG_LOCATION}/pxe/