From 5c1881282c0417dd30b978332f2b768b2386b5b6 Mon Sep 17 00:00:00 2001 From: Dmitry Tantsur Date: Thu, 26 Aug 2021 10:22:50 +0200 Subject: [PATCH] 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 --- .../tasks/bootstrap.yml | 47 ++------------- .../tasks/install.yml | 11 ++-- .../bifrost-keystone-install/tasks/start.yml | 12 +++- .../templates/systemd_template.j2 | 15 ----- .../templates/uwsgi-keystone.ini.j2 | 2 + .../bifrost-uwsgi-install/defaults/main.yml | 23 ++++++++ .../bifrost-uwsgi-install/tasks/bootstrap.yml | 57 +++++++++++++++++++ .../bifrost-uwsgi-install/tasks/install.yml | 18 ++++++ .../bifrost-uwsgi-install/tasks/main.yml | 20 +++++++ .../templates/uwsgi@.service.j2 | 17 ++++++ .../notes/uwsgi-install-eea2f9dca2470006.yaml | 10 ++++ scripts/collect-test-info.sh | 3 +- 12 files changed, 167 insertions(+), 68 deletions(-) delete mode 100644 playbooks/roles/bifrost-keystone-install/templates/systemd_template.j2 create mode 100644 playbooks/roles/bifrost-uwsgi-install/defaults/main.yml create mode 100644 playbooks/roles/bifrost-uwsgi-install/tasks/bootstrap.yml create mode 100644 playbooks/roles/bifrost-uwsgi-install/tasks/install.yml create mode 100644 playbooks/roles/bifrost-uwsgi-install/tasks/main.yml create mode 100644 playbooks/roles/bifrost-uwsgi-install/templates/uwsgi@.service.j2 create mode 100644 releasenotes/notes/uwsgi-install-eea2f9dca2470006.yaml diff --git a/playbooks/roles/bifrost-keystone-install/tasks/bootstrap.yml b/playbooks/roles/bifrost-keystone-install/tasks/bootstrap.yml index 48f10fb1a..befc36309 100644 --- a/playbooks/roles/bifrost-keystone-install/tasks/bootstrap.yml +++ b/playbooks/roles/bifrost-keystone-install/tasks/bootstrap.yml @@ -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: diff --git a/playbooks/roles/bifrost-keystone-install/tasks/install.yml b/playbooks/roles/bifrost-keystone-install/tasks/install.yml index 5f0be0c2f..3a87e2189 100644 --- a/playbooks/roles/bifrost-keystone-install/tasks/install.yml +++ b/playbooks/roles/bifrost-keystone-install/tasks/install.yml @@ -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 diff --git a/playbooks/roles/bifrost-keystone-install/tasks/start.yml b/playbooks/roles/bifrost-keystone-install/tasks/start.yml index 0cc20e584..8909a2b9a 100644 --- a/playbooks/roles/bifrost-keystone-install/tasks/start.yml +++ b/playbooks/roles/bifrost-keystone-install/tasks/start.yml @@ -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 diff --git a/playbooks/roles/bifrost-keystone-install/templates/systemd_template.j2 b/playbooks/roles/bifrost-keystone-install/templates/systemd_template.j2 deleted file mode 100644 index 378a2e40d..000000000 --- a/playbooks/roles/bifrost-keystone-install/templates/systemd_template.j2 +++ /dev/null @@ -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 diff --git a/playbooks/roles/bifrost-keystone-install/templates/uwsgi-keystone.ini.j2 b/playbooks/roles/bifrost-keystone-install/templates/uwsgi-keystone.ini.j2 index 119941518..1e9fbd9c8 100644 --- a/playbooks/roles/bifrost-keystone-install/templates/uwsgi-keystone.ini.j2 +++ b/playbooks/roles/bifrost-keystone-install/templates/uwsgi-keystone.ini.j2 @@ -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 diff --git a/playbooks/roles/bifrost-uwsgi-install/defaults/main.yml b/playbooks/roles/bifrost-uwsgi-install/defaults/main.yml new file mode 100644 index 000000000..cf1a5974c --- /dev/null +++ b/playbooks/roles/bifrost-uwsgi-install/defaults/main.yml @@ -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' }}" diff --git a/playbooks/roles/bifrost-uwsgi-install/tasks/bootstrap.yml b/playbooks/roles/bifrost-uwsgi-install/tasks/bootstrap.yml new file mode 100644 index 000000000..71d831c22 --- /dev/null +++ b/playbooks/roles/bifrost-uwsgi-install/tasks/bootstrap.yml @@ -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" diff --git a/playbooks/roles/bifrost-uwsgi-install/tasks/install.yml b/playbooks/roles/bifrost-uwsgi-install/tasks/install.yml new file mode 100644 index 000000000..994908d58 --- /dev/null +++ b/playbooks/roles/bifrost-uwsgi-install/tasks/install.yml @@ -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 diff --git a/playbooks/roles/bifrost-uwsgi-install/tasks/main.yml b/playbooks/roles/bifrost-uwsgi-install/tasks/main.yml new file mode 100644 index 000000000..66c5989d8 --- /dev/null +++ b/playbooks/roles/bifrost-uwsgi-install/tasks/main.yml @@ -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 diff --git a/playbooks/roles/bifrost-uwsgi-install/templates/uwsgi@.service.j2 b/playbooks/roles/bifrost-uwsgi-install/templates/uwsgi@.service.j2 new file mode 100644 index 000000000..c49d22d1a --- /dev/null +++ b/playbooks/roles/bifrost-uwsgi-install/templates/uwsgi@.service.j2 @@ -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 diff --git a/releasenotes/notes/uwsgi-install-eea2f9dca2470006.yaml b/releasenotes/notes/uwsgi-install-eea2f9dca2470006.yaml new file mode 100644 index 000000000..2f6932c98 --- /dev/null +++ b/releasenotes/notes/uwsgi-install-eea2f9dca2470006.yaml @@ -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. diff --git a/scripts/collect-test-info.sh b/scripts/collect-test-info.sh index b15736198..f09a53027 100755 --- a/scripts/collect-test-info.sh +++ b/scripts/collect-test-info.sh @@ -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/