|
|
bc4e95 |
From d54c102cee7a61dd3eccd62d60af218aa97a85fc Mon Sep 17 00:00:00 2001
|
|
|
bc4e95 |
From: Ivan Devat <idevat@redhat.com>
|
|
|
bc4e95 |
Date: Thu, 9 Jan 2020 15:53:37 +0100
|
|
|
bc4e95 |
Subject: [PATCH 6/7] squash bz1783106 fix-sinatra-wrapper-performance-issue
|
|
|
bc4e95 |
|
|
|
bc4e95 |
create prototype of tornado - thin communication
|
|
|
bc4e95 |
|
|
|
bc4e95 |
put socket path to settings
|
|
|
bc4e95 |
|
|
|
bc4e95 |
don't mix logs from threads in ruby daemon
|
|
|
bc4e95 |
|
|
|
bc4e95 |
run ruby daemon via systemd units
|
|
|
bc4e95 |
|
|
|
bc4e95 |
support trailing slash by gui urls e.g. /manage/
|
|
|
bc4e95 |
|
|
|
bc4e95 |
decode body from ruby response for log
|
|
|
bc4e95 |
|
|
|
bc4e95 |
configure ruby wrapper by socket path
|
|
|
bc4e95 |
|
|
|
bc4e95 |
remove env values not used for ruby calls any more
|
|
|
bc4e95 |
|
|
|
bc4e95 |
deal with ruby daemon communication issues
|
|
|
bc4e95 |
|
|
|
bc4e95 |
fix tests
|
|
|
bc4e95 |
|
|
|
bc4e95 |
cleanup ruby server code
|
|
|
bc4e95 |
|
|
|
bc4e95 |
deal with errors from ruby daemon in python daemon
|
|
|
bc4e95 |
|
|
|
bc4e95 |
remove unused cmdline wrapper
|
|
|
bc4e95 |
|
|
|
bc4e95 |
add ruby daemon infrastructure to spec etc.
|
|
|
bc4e95 |
|
|
|
bc4e95 |
stop logging to stderr from ruby daemon
|
|
|
bc4e95 |
|
|
|
bc4e95 |
fix spec file
|
|
|
bc4e95 |
|
|
|
bc4e95 |
* add missing cp for new rubygems
|
|
|
bc4e95 |
* make sure to start the new ruby daemon on package upgrade
|
|
|
bc4e95 |
* tests: give the new daemon enough time to start
|
|
|
bc4e95 |
---
|
|
|
bc4e95 |
.gitlab-ci.yml | 7 +-
|
|
|
bc4e95 |
Makefile | 6 +
|
|
|
bc4e95 |
pcs.spec.in | 30 ++++-
|
|
|
bc4e95 |
pcs/daemon/app/sinatra_ui.py | 2 +-
|
|
|
bc4e95 |
pcs/daemon/env.py | 36 ------
|
|
|
bc4e95 |
pcs/daemon/ruby_pcsd.py | 136 +++++++++++-----------
|
|
|
bc4e95 |
pcs/daemon/run.py | 8 +-
|
|
|
bc4e95 |
pcs/settings_default.py | 1 +
|
|
|
bc4e95 |
pcs_test/tier0/daemon/app/fixtures_app.py | 3 +-
|
|
|
bc4e95 |
pcs_test/tier0/daemon/test_env.py | 66 +----------
|
|
|
bc4e95 |
pcs_test/tier0/daemon/test_ruby_pcsd.py | 13 +--
|
|
|
bc4e95 |
pcsd/Gemfile | 1 +
|
|
|
bc4e95 |
pcsd/Gemfile.lock | 7 ++
|
|
|
bc4e95 |
pcsd/Makefile | 3 +
|
|
|
bc4e95 |
pcsd/bootstrap.rb | 20 +++-
|
|
|
bc4e95 |
pcsd/cfgsync.rb | 6 +-
|
|
|
bc4e95 |
pcsd/pcs.rb | 9 +-
|
|
|
bc4e95 |
pcsd/pcsd-cli.rb | 3 +-
|
|
|
bc4e95 |
pcsd/pcsd-ruby.service | 20 ++++
|
|
|
bc4e95 |
pcsd/pcsd.conf | 4 +
|
|
|
bc4e95 |
pcsd/pcsd.rb | 31 ++---
|
|
|
bc4e95 |
pcsd/pcsd.service | 2 +
|
|
|
bc4e95 |
pcsd/pcsd.service-runner | 24 ++++
|
|
|
bc4e95 |
pcsd/remote.rb | 6 +-
|
|
|
bc4e95 |
pcsd/rserver.rb | 98 ++++++++++++++++
|
|
|
bc4e95 |
pcsd/settings.rb | 1 +
|
|
|
bc4e95 |
pcsd/settings.rb.debian | 1 +
|
|
|
bc4e95 |
pcsd/sinatra_cmdline_wrapper.rb | 63 ----------
|
|
|
bc4e95 |
28 files changed, 330 insertions(+), 277 deletions(-)
|
|
|
bc4e95 |
create mode 100644 pcsd/pcsd-ruby.service
|
|
|
bc4e95 |
create mode 100644 pcsd/pcsd.service-runner
|
|
|
bc4e95 |
create mode 100644 pcsd/rserver.rb
|
|
|
bc4e95 |
delete mode 100644 pcsd/sinatra_cmdline_wrapper.rb
|
|
|
bc4e95 |
|
|
|
bc4e95 |
diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml
|
|
|
bc4e95 |
index 23ab56a9..92b32033 100644
|
|
|
bc4e95 |
--- a/.gitlab-ci.yml
|
|
|
bc4e95 |
+++ b/.gitlab-ci.yml
|
|
|
bc4e95 |
@@ -116,8 +116,11 @@ python_smoke_tests:
|
|
|
bc4e95 |
procps-ng
|
|
|
bc4e95 |
rpms/pcs-ci-*.rpm
|
|
|
bc4e95 |
"
|
|
|
bc4e95 |
- - /usr/sbin/pcsd & # start pcsd
|
|
|
bc4e95 |
- - sleep 10 # wait for pcsd to start up properly
|
|
|
bc4e95 |
+ - export GEM_HOME=/usr/lib/pcsd/vendor/bundle/ruby
|
|
|
bc4e95 |
+ - /usr/lib/pcsd/pcsd & # start pcsd (ruby - thin)
|
|
|
bc4e95 |
+ - sleep 10 # wait for pcsd (ruby - thin) to start up properly
|
|
|
bc4e95 |
+ - /usr/sbin/pcsd & # start pcsd (python - tornado)
|
|
|
bc4e95 |
+ - sleep 10 # wait for pcsd (python - tornado) to start up properly
|
|
|
bc4e95 |
- pcs_test/smoke.sh
|
|
|
bc4e95 |
artifacts:
|
|
|
bc4e95 |
paths:
|
|
|
bc4e95 |
diff --git a/Makefile b/Makefile
|
|
|
bc4e95 |
index f2b0d9b9..b9f64acd 100644
|
|
|
bc4e95 |
--- a/Makefile
|
|
|
bc4e95 |
+++ b/Makefile
|
|
|
bc4e95 |
@@ -267,7 +267,12 @@ ifeq ($(IS_DEBIAN)$(IS_SYSTEMCTL),truefalse)
|
|
|
bc4e95 |
else
|
|
|
bc4e95 |
install -d ${DEST_SYSTEMD_SYSTEM}
|
|
|
bc4e95 |
install -m 644 ${SYSTEMD_SERVICE_FILE} ${DEST_SYSTEMD_SYSTEM}/pcsd.service
|
|
|
bc4e95 |
+ install -m 644 pcsd/pcsd-ruby.service ${DEST_SYSTEMD_SYSTEM}/pcsd-ruby.service
|
|
|
bc4e95 |
endif
|
|
|
bc4e95 |
+ # ${DEST_LIB}/pcsd/pcsd holds the selinux context
|
|
|
bc4e95 |
+ install -m 755 pcsd/pcsd.service-runner ${DEST_LIB}/pcsd/pcsd
|
|
|
bc4e95 |
+ rm ${DEST_LIB}/pcsd/pcsd.service-runner
|
|
|
bc4e95 |
+
|
|
|
bc4e95 |
install -m 700 -d ${DESTDIR}/var/lib/pcsd
|
|
|
bc4e95 |
install -m 644 -D pcsd/pcsd.logrotate ${DESTDIR}/etc/logrotate.d/pcsd
|
|
|
bc4e95 |
install -m644 -D pcsd/pcsd.8 ${DEST_MAN}/pcsd.8
|
|
|
bc4e95 |
@@ -293,6 +298,7 @@ ifeq ($(IS_DEBIAN)$(IS_SYSTEMCTL),truefalse)
|
|
|
bc4e95 |
rm -f ${DEST_INIT}/pcsd
|
|
|
bc4e95 |
else
|
|
|
bc4e95 |
rm -f ${DEST_SYSTEMD_SYSTEM}/pcsd.service
|
|
|
bc4e95 |
+ rm -f ${DEST_SYSTEMD_SYSTEM}/pcsd-ruby.service
|
|
|
bc4e95 |
rm -f ${DEST_SYSTEMD_SYSTEM}/pcs_snmp_agent.service
|
|
|
bc4e95 |
endif
|
|
|
bc4e95 |
rm -f ${DESTDIR}/etc/pam.d/pcsd
|
|
|
bc4e95 |
diff --git a/pcs.spec.in b/pcs.spec.in
|
|
|
bc4e95 |
index 5195dc51..32fbf614 100644
|
|
|
bc4e95 |
--- a/pcs.spec.in
|
|
|
bc4e95 |
+++ b/pcs.spec.in
|
|
|
bc4e95 |
@@ -28,7 +28,9 @@ Summary: Pacemaker Configuration System
|
|
|
bc4e95 |
%global pyagentx_version 0.4.pcs.2
|
|
|
bc4e95 |
%global tornado_version 6.0.3
|
|
|
bc4e95 |
%global version_rubygem_backports 3.11.4
|
|
|
bc4e95 |
+%global version_rubygem_daemons 1.3.1
|
|
|
bc4e95 |
%global version_rubygem_ethon 0.11.0
|
|
|
bc4e95 |
+%global version_rubygem_eventmachine 1.2.7
|
|
|
bc4e95 |
%global version_rubygem_ffi 1.9.25
|
|
|
bc4e95 |
%global version_rubygem_json 2.1.0
|
|
|
bc4e95 |
%global version_rubygem_mustermann 1.0.3
|
|
|
bc4e95 |
@@ -37,6 +39,7 @@ Summary: Pacemaker Configuration System
|
|
|
bc4e95 |
%global version_rubygem_rack_protection 2.0.4
|
|
|
bc4e95 |
%global version_rubygem_rack_test 1.0.0
|
|
|
bc4e95 |
%global version_rubygem_sinatra 2.0.4
|
|
|
bc4e95 |
+%global version_rubygem_thin 1.7.2
|
|
|
bc4e95 |
%global version_rubygem_tilt 2.0.9
|
|
|
bc4e95 |
|
|
|
bc4e95 |
# We do not use _libdir macro because upstream is not prepared for it.
|
|
|
bc4e95 |
@@ -83,6 +86,9 @@ Source89: https://rubygems.org/downloads/rack-protection-%{version_rubygem_rack_
|
|
|
bc4e95 |
Source90: https://rubygems.org/downloads/rack-test-%{version_rubygem_rack_test}.gem
|
|
|
bc4e95 |
Source91: https://rubygems.org/downloads/sinatra-%{version_rubygem_sinatra}.gem
|
|
|
bc4e95 |
Source92: https://rubygems.org/downloads/tilt-%{version_rubygem_tilt}.gem
|
|
|
bc4e95 |
+Source93: https://rubygems.org/downloads/eventmachine-%{version_rubygem_eventmachine}.gem
|
|
|
bc4e95 |
+Source94: https://rubygems.org/downloads/daemons-%{version_rubygem_daemons}.gem
|
|
|
bc4e95 |
+Source95: https://rubygems.org/downloads/thin-%{version_rubygem_thin}.gem
|
|
|
bc4e95 |
|
|
|
bc4e95 |
Source100: https://github.com/idevat/pcs-web-ui/archive/%{ui_commit}/%{ui_src_name}.tar.gz
|
|
|
bc4e95 |
Source101: https://github.com/idevat/pcs-web-ui/releases/download/%{ui_commit}/pcs-web-ui-node-modules-%{ui_commit}.tar.xz
|
|
|
bc4e95 |
@@ -164,7 +170,9 @@ Recommends: overpass-fonts
|
|
|
bc4e95 |
|
|
|
bc4e95 |
Provides: bundled(tornado) = %{tornado_version}
|
|
|
bc4e95 |
Provides: bundled(backports) = %{version_rubygem_backports}
|
|
|
bc4e95 |
+Provides: bundled(daemons) = %{version_rubygem_daemons}
|
|
|
bc4e95 |
Provides: bundled(ethon) = %{version_rubygem_ethon}
|
|
|
bc4e95 |
+Provides: bundled(eventmachine) = %{version_rubygem_eventmachine}
|
|
|
bc4e95 |
Provides: bundled(ffi) = %{version_rubygem_ffi}
|
|
|
bc4e95 |
Provides: bundled(json) = %{version_rubygem_json}
|
|
|
bc4e95 |
Provides: bundled(mustermann) = %{version_rubygem_mustermann}
|
|
|
bc4e95 |
@@ -173,6 +181,7 @@ Provides: bundled(rack) = %{version_rubygem_rack}
|
|
|
bc4e95 |
Provides: bundled(rack) = %{version_rubygem_rack_protection}
|
|
|
bc4e95 |
Provides: bundled(rack) = %{version_rubygem_rack_test}
|
|
|
bc4e95 |
Provides: bundled(sinatra) = %{version_rubygem_sinatra}
|
|
|
bc4e95 |
+Provides: bundled(thin) = %{version_rubygem_thin}
|
|
|
bc4e95 |
Provides: bundled(tilt) = %{version_rubygem_tilt}
|
|
|
bc4e95 |
|
|
|
bc4e95 |
%description
|
|
|
bc4e95 |
@@ -228,6 +237,9 @@ cp -f %SOURCE89 pcsd/vendor/cache
|
|
|
bc4e95 |
cp -f %SOURCE90 pcsd/vendor/cache
|
|
|
bc4e95 |
cp -f %SOURCE91 pcsd/vendor/cache
|
|
|
bc4e95 |
cp -f %SOURCE92 pcsd/vendor/cache
|
|
|
bc4e95 |
+cp -f %SOURCE93 pcsd/vendor/cache
|
|
|
bc4e95 |
+cp -f %SOURCE94 pcsd/vendor/cache
|
|
|
bc4e95 |
+cp -f %SOURCE95 pcsd/vendor/cache
|
|
|
bc4e95 |
|
|
|
bc4e95 |
|
|
|
bc4e95 |
# 3) dir for python bundles
|
|
|
bc4e95 |
@@ -262,15 +274,18 @@ gem install \
|
|
|
bc4e95 |
--force --verbose -l --no-user-install %{gem_install_params} \
|
|
|
bc4e95 |
-i %{rubygem_bundle_dir} \
|
|
|
bc4e95 |
%{rubygem_cache_dir}/backports-%{version_rubygem_backports}.gem \
|
|
|
bc4e95 |
+ %{rubygem_cache_dir}/daemons-%{version_rubygem_daemons}.gem \
|
|
|
bc4e95 |
%{rubygem_cache_dir}/ethon-%{version_rubygem_ethon}.gem \
|
|
|
bc4e95 |
+ %{rubygem_cache_dir}/eventmachine-%{version_rubygem_eventmachine}.gem \
|
|
|
bc4e95 |
%{rubygem_cache_dir}/ffi-%{version_rubygem_ffi}.gem \
|
|
|
bc4e95 |
%{rubygem_cache_dir}/json-%{version_rubygem_json}.gem \
|
|
|
bc4e95 |
%{rubygem_cache_dir}/mustermann-%{version_rubygem_mustermann}.gem \
|
|
|
bc4e95 |
%{rubygem_cache_dir}/open4-%{version_rubygem_open4}.gem \
|
|
|
bc4e95 |
- %{rubygem_cache_dir}/rack-%{version_rubygem_rack}.gem \
|
|
|
bc4e95 |
%{rubygem_cache_dir}/rack-protection-%{version_rubygem_rack_protection}.gem \
|
|
|
bc4e95 |
%{rubygem_cache_dir}/rack-test-%{version_rubygem_rack_test}.gem \
|
|
|
bc4e95 |
+ %{rubygem_cache_dir}/rack-%{version_rubygem_rack}.gem \
|
|
|
bc4e95 |
%{rubygem_cache_dir}/sinatra-%{version_rubygem_sinatra}.gem \
|
|
|
bc4e95 |
+ %{rubygem_cache_dir}/thin-%{version_rubygem_thin}.gem \
|
|
|
bc4e95 |
%{rubygem_cache_dir}/tilt-%{version_rubygem_tilt}.gem \
|
|
|
bc4e95 |
-- '--with-ldflags=-Wl,-z,relro -Wl,-z,ibt -Wl,-z,now -Wl,--gc-sections' \
|
|
|
bc4e95 |
'--with-cflags=-O2 -ffunction-sections'
|
|
|
bc4e95 |
@@ -324,20 +339,31 @@ rm -r -v ${pcsd_dir}/test
|
|
|
bc4e95 |
# remove javascript testing files
|
|
|
bc4e95 |
rm -r -v ${pcsd_dir}/public/js/dev
|
|
|
bc4e95 |
|
|
|
bc4e95 |
+%posttrans
|
|
|
bc4e95 |
+# Make sure the new version of the daemon is runnning.
|
|
|
bc4e95 |
+# Also, make sure to start pcsd-ruby if it hasn't been started or even
|
|
|
bc4e95 |
+# installed before. This is done by restarting pcsd.service.
|
|
|
bc4e95 |
+%{_bindir}/systemctl daemon-reload
|
|
|
bc4e95 |
+%{_bindir}/systemctl try-restart pcsd.service
|
|
|
bc4e95 |
+
|
|
|
bc4e95 |
+
|
|
|
bc4e95 |
%post
|
|
|
bc4e95 |
%systemd_post pcsd.service
|
|
|
bc4e95 |
+%systemd_post pcsd-ruby.service
|
|
|
bc4e95 |
|
|
|
bc4e95 |
%post -n %{pcs_snmp_pkg_name}
|
|
|
bc4e95 |
%systemd_post pcs_snmp_agent.service
|
|
|
bc4e95 |
|
|
|
bc4e95 |
%preun
|
|
|
bc4e95 |
%systemd_preun pcsd.service
|
|
|
bc4e95 |
+%systemd_preun pcsd-ruby.service
|
|
|
bc4e95 |
|
|
|
bc4e95 |
%preun -n %{pcs_snmp_pkg_name}
|
|
|
bc4e95 |
%systemd_preun pcs_snmp_agent.service
|
|
|
bc4e95 |
|
|
|
bc4e95 |
%postun
|
|
|
bc4e95 |
%systemd_postun_with_restart pcsd.service
|
|
|
bc4e95 |
+%systemd_postun_with_restart pcsd-ruby.service
|
|
|
bc4e95 |
|
|
|
bc4e95 |
%postun -n %{pcs_snmp_pkg_name}
|
|
|
bc4e95 |
%systemd_postun_with_restart pcs_snmp_agent.service
|
|
|
bc4e95 |
@@ -357,6 +383,7 @@ rm -r -v ${pcsd_dir}/public/js/dev
|
|
|
bc4e95 |
%{pcs_libdir}/pcsd/.bundle/config
|
|
|
bc4e95 |
%{pcs_libdir}/pcs/bundled/packages/tornado*
|
|
|
bc4e95 |
%{_unitdir}/pcsd.service
|
|
|
bc4e95 |
+%{_unitdir}/pcsd-ruby.service
|
|
|
bc4e95 |
%{_datadir}/bash-completion/completions/pcs
|
|
|
bc4e95 |
%{_sharedstatedir}/pcsd
|
|
|
bc4e95 |
%{_sysconfdir}/pam.d/pcsd
|
|
|
bc4e95 |
@@ -374,6 +401,7 @@ rm -r -v ${pcsd_dir}/public/js/dev
|
|
|
bc4e95 |
%{_mandir}/man8/pcsd.*
|
|
|
bc4e95 |
%exclude %{pcs_libdir}/pcsd/*.debian
|
|
|
bc4e95 |
%exclude %{pcs_libdir}/pcsd/pcsd.service
|
|
|
bc4e95 |
+%exclude %{pcs_libdir}/pcsd/pcsd-ruby.service
|
|
|
bc4e95 |
%exclude %{pcs_libdir}/pcsd/pcsd.conf
|
|
|
bc4e95 |
%exclude %{pcs_libdir}/pcsd/pcsd.8
|
|
|
bc4e95 |
%exclude %{pcs_libdir}/pcsd/public/js/dev/*
|
|
|
bc4e95 |
diff --git a/pcs/daemon/app/sinatra_ui.py b/pcs/daemon/app/sinatra_ui.py
|
|
|
bc4e95 |
index 1348134d..5315a48f 100644
|
|
|
bc4e95 |
--- a/pcs/daemon/app/sinatra_ui.py
|
|
|
bc4e95 |
+++ b/pcs/daemon/app/sinatra_ui.py
|
|
|
bc4e95 |
@@ -153,7 +153,7 @@ def get_routes(
|
|
|
bc4e95 |
# The protection by session was moved from ruby code to python code
|
|
|
bc4e95 |
# (tornado).
|
|
|
bc4e95 |
(
|
|
|
bc4e95 |
- r"/($|manage$|permissions$|managec/.+/main)",
|
|
|
bc4e95 |
+ r"/($|manage/?$|permissions/?$|managec/.+/main)",
|
|
|
bc4e95 |
SinatraGuiProtected,
|
|
|
bc4e95 |
{**sessions, **ruby_wrapper}
|
|
|
bc4e95 |
),
|
|
|
bc4e95 |
diff --git a/pcs/daemon/env.py b/pcs/daemon/env.py
|
|
|
bc4e95 |
index 54a9819f..26cdcf9b 100644
|
|
|
bc4e95 |
--- a/pcs/daemon/env.py
|
|
|
bc4e95 |
+++ b/pcs/daemon/env.py
|
|
|
bc4e95 |
@@ -15,7 +15,6 @@ from pcs.lib.validate import is_port_number
|
|
|
bc4e95 |
# Relative location instead of system location is used for development purposes.
|
|
|
bc4e95 |
PCSD_LOCAL_DIR = realpath(dirname(abspath(__file__)) + "/../../pcsd")
|
|
|
bc4e95 |
|
|
|
bc4e95 |
-PCSD_CMDLINE_ENTRY_RB_SCRIPT = "sinatra_cmdline_wrapper.rb"
|
|
|
bc4e95 |
PCSD_STATIC_FILES_DIR_NAME = "public"
|
|
|
bc4e95 |
|
|
|
bc4e95 |
PCSD_PORT = "PCSD_PORT"
|
|
|
bc4e95 |
@@ -26,12 +25,8 @@ NOTIFY_SOCKET = "NOTIFY_SOCKET"
|
|
|
bc4e95 |
PCSD_DEBUG = "PCSD_DEBUG"
|
|
|
bc4e95 |
PCSD_DISABLE_GUI = "PCSD_DISABLE_GUI"
|
|
|
bc4e95 |
PCSD_SESSION_LIFETIME = "PCSD_SESSION_LIFETIME"
|
|
|
bc4e95 |
-GEM_HOME = "GEM_HOME"
|
|
|
bc4e95 |
PCSD_DEV = "PCSD_DEV"
|
|
|
bc4e95 |
-PCSD_CMDLINE_ENTRY = "PCSD_CMDLINE_ENTRY"
|
|
|
bc4e95 |
PCSD_STATIC_FILES_DIR = "PCSD_STATIC_FILES_DIR"
|
|
|
bc4e95 |
-HTTPS_PROXY = "HTTPS_PROXY"
|
|
|
bc4e95 |
-NO_PROXY = "NO_PROXY"
|
|
|
bc4e95 |
|
|
|
bc4e95 |
Env = namedtuple("Env", [
|
|
|
bc4e95 |
PCSD_PORT,
|
|
|
bc4e95 |
@@ -42,11 +37,7 @@ Env = namedtuple("Env", [
|
|
|
bc4e95 |
PCSD_DEBUG,
|
|
|
bc4e95 |
PCSD_DISABLE_GUI,
|
|
|
bc4e95 |
PCSD_SESSION_LIFETIME,
|
|
|
bc4e95 |
- GEM_HOME,
|
|
|
bc4e95 |
- PCSD_CMDLINE_ENTRY,
|
|
|
bc4e95 |
PCSD_STATIC_FILES_DIR,
|
|
|
bc4e95 |
- HTTPS_PROXY,
|
|
|
bc4e95 |
- NO_PROXY,
|
|
|
bc4e95 |
PCSD_DEV,
|
|
|
bc4e95 |
"has_errors",
|
|
|
bc4e95 |
])
|
|
|
bc4e95 |
@@ -62,11 +53,7 @@ def prepare_env(environ, logger=None):
|
|
|
bc4e95 |
loader.pcsd_debug(),
|
|
|
bc4e95 |
loader.pcsd_disable_gui(),
|
|
|
bc4e95 |
loader.session_lifetime(),
|
|
|
bc4e95 |
- loader.gem_home(),
|
|
|
bc4e95 |
- loader.pcsd_cmdline_entry(),
|
|
|
bc4e95 |
loader.pcsd_static_files_dir(),
|
|
|
bc4e95 |
- loader.https_proxy(),
|
|
|
bc4e95 |
- loader.no_proxy(),
|
|
|
bc4e95 |
loader.pcsd_dev(),
|
|
|
bc4e95 |
loader.has_errors(),
|
|
|
bc4e95 |
)
|
|
|
bc4e95 |
@@ -173,20 +160,6 @@ class EnvLoader:
|
|
|
bc4e95 |
def pcsd_debug(self):
|
|
|
bc4e95 |
return self.__has_true_in_environ(PCSD_DEBUG)
|
|
|
bc4e95 |
|
|
|
bc4e95 |
- def gem_home(self):
|
|
|
bc4e95 |
- if settings.pcsd_gem_path is None:
|
|
|
bc4e95 |
- return None
|
|
|
bc4e95 |
- return self.__in_pcsd_path(
|
|
|
bc4e95 |
- settings.pcsd_gem_path,
|
|
|
bc4e95 |
- "Ruby gem location"
|
|
|
bc4e95 |
- )
|
|
|
bc4e95 |
-
|
|
|
bc4e95 |
- def pcsd_cmdline_entry(self):
|
|
|
bc4e95 |
- return self.__in_pcsd_path(
|
|
|
bc4e95 |
- PCSD_CMDLINE_ENTRY_RB_SCRIPT,
|
|
|
bc4e95 |
- "Ruby handlers entrypoint"
|
|
|
bc4e95 |
- )
|
|
|
bc4e95 |
-
|
|
|
bc4e95 |
def pcsd_static_files_dir(self):
|
|
|
bc4e95 |
return self.__in_pcsd_path(
|
|
|
bc4e95 |
PCSD_STATIC_FILES_DIR_NAME,
|
|
|
bc4e95 |
@@ -194,15 +167,6 @@ class EnvLoader:
|
|
|
bc4e95 |
existence_required=not self.pcsd_disable_gui()
|
|
|
bc4e95 |
)
|
|
|
bc4e95 |
|
|
|
bc4e95 |
- def https_proxy(self):
|
|
|
bc4e95 |
- for key in ["https_proxy", HTTPS_PROXY, "all_proxy", "ALL_PROXY"]:
|
|
|
bc4e95 |
- if key in self.environ:
|
|
|
bc4e95 |
- return self.environ[key]
|
|
|
bc4e95 |
- return None
|
|
|
bc4e95 |
-
|
|
|
bc4e95 |
- def no_proxy(self):
|
|
|
bc4e95 |
- return self.environ.get("no_proxy", self.environ.get(NO_PROXY, None))
|
|
|
bc4e95 |
-
|
|
|
bc4e95 |
@lru_cache()
|
|
|
bc4e95 |
def pcsd_dev(self):
|
|
|
bc4e95 |
return self.__has_true_in_environ(PCSD_DEV)
|
|
|
bc4e95 |
diff --git a/pcs/daemon/ruby_pcsd.py b/pcs/daemon/ruby_pcsd.py
|
|
|
bc4e95 |
index 5bdaffeb..e612f8da 100644
|
|
|
bc4e95 |
--- a/pcs/daemon/ruby_pcsd.py
|
|
|
bc4e95 |
+++ b/pcs/daemon/ruby_pcsd.py
|
|
|
bc4e95 |
@@ -1,14 +1,16 @@
|
|
|
bc4e95 |
import json
|
|
|
bc4e95 |
import logging
|
|
|
bc4e95 |
-import os.path
|
|
|
bc4e95 |
-from base64 import b64decode
|
|
|
bc4e95 |
+from base64 import b64decode, b64encode, binascii
|
|
|
bc4e95 |
from collections import namedtuple
|
|
|
bc4e95 |
from time import time as now
|
|
|
bc4e95 |
|
|
|
bc4e95 |
-from tornado.gen import multi, convert_yielded
|
|
|
bc4e95 |
+import pycurl
|
|
|
bc4e95 |
+from tornado.gen import convert_yielded
|
|
|
bc4e95 |
from tornado.web import HTTPError
|
|
|
bc4e95 |
from tornado.httputil import split_host_and_port, HTTPServerRequest
|
|
|
bc4e95 |
-from tornado.process import Subprocess
|
|
|
bc4e95 |
+from tornado.httpclient import AsyncHTTPClient
|
|
|
bc4e95 |
+from tornado.curl_httpclient import CurlError
|
|
|
bc4e95 |
+
|
|
|
bc4e95 |
|
|
|
bc4e95 |
from pcs.daemon import log
|
|
|
bc4e95 |
|
|
|
bc4e95 |
@@ -33,7 +35,7 @@ class SinatraResult(namedtuple("SinatraResult", "headers, status, body")):
|
|
|
bc4e95 |
return cls(
|
|
|
bc4e95 |
response["headers"],
|
|
|
bc4e95 |
response["status"],
|
|
|
bc4e95 |
- b64decode(response["body"])
|
|
|
bc4e95 |
+ response["body"]
|
|
|
bc4e95 |
)
|
|
|
bc4e95 |
|
|
|
bc4e95 |
def log_group_id_generator():
|
|
|
bc4e95 |
@@ -58,24 +60,12 @@ def process_response_logs(rb_log_list):
|
|
|
bc4e95 |
group_id=group_id
|
|
|
bc4e95 |
)
|
|
|
bc4e95 |
|
|
|
bc4e95 |
-def log_communication(request_json, stdout, stderr):
|
|
|
bc4e95 |
- log.pcsd.debug("Request for ruby pcsd wrapper: '%s'", request_json)
|
|
|
bc4e95 |
- log.pcsd.debug("Response stdout from ruby pcsd wrapper: '%s'", stdout)
|
|
|
bc4e95 |
- log.pcsd.debug("Response stderr from ruby pcsd wrapper: '%s'", stderr)
|
|
|
bc4e95 |
-
|
|
|
bc4e95 |
class Wrapper:
|
|
|
bc4e95 |
- # pylint: disable=too-many-instance-attributes
|
|
|
bc4e95 |
- def __init__(
|
|
|
bc4e95 |
- self, pcsd_cmdline_entry, gem_home=None, debug=False,
|
|
|
bc4e95 |
- ruby_executable="ruby", https_proxy=None, no_proxy=None
|
|
|
bc4e95 |
- ):
|
|
|
bc4e95 |
- self.__gem_home = gem_home
|
|
|
bc4e95 |
- self.__pcsd_cmdline_entry = pcsd_cmdline_entry
|
|
|
bc4e95 |
- self.__pcsd_dir = os.path.dirname(pcsd_cmdline_entry)
|
|
|
bc4e95 |
- self.__ruby_executable = ruby_executable
|
|
|
bc4e95 |
+ def __init__(self, pcsd_ruby_socket, debug=False):
|
|
|
bc4e95 |
self.__debug = debug
|
|
|
bc4e95 |
- self.__https_proxy = https_proxy
|
|
|
bc4e95 |
- self.__no_proxy = no_proxy
|
|
|
bc4e95 |
+ AsyncHTTPClient.configure('tornado.curl_httpclient.CurlAsyncHTTPClient')
|
|
|
bc4e95 |
+ self.__client = AsyncHTTPClient()
|
|
|
bc4e95 |
+ self.__pcsd_ruby_socket = pcsd_ruby_socket
|
|
|
bc4e95 |
|
|
|
bc4e95 |
@staticmethod
|
|
|
bc4e95 |
def get_sinatra_request(request: HTTPServerRequest):
|
|
|
bc4e95 |
@@ -102,55 +92,76 @@ class Wrapper:
|
|
|
bc4e95 |
"rack.input": request.body.decode("utf8"),
|
|
|
bc4e95 |
}}
|
|
|
bc4e95 |
|
|
|
bc4e95 |
+ def prepare_curl_callback(self, curl):
|
|
|
bc4e95 |
+ curl.setopt(pycurl.UNIX_SOCKET_PATH, self.__pcsd_ruby_socket)
|
|
|
bc4e95 |
+ curl.setopt(pycurl.TIMEOUT, 70)
|
|
|
bc4e95 |
+
|
|
|
bc4e95 |
async def send_to_ruby(self, request_json):
|
|
|
bc4e95 |
- env = {
|
|
|
bc4e95 |
- "PCSD_DEBUG": "true" if self.__debug else "false"
|
|
|
bc4e95 |
- }
|
|
|
bc4e95 |
- if self.__gem_home is not None:
|
|
|
bc4e95 |
- env["GEM_HOME"] = self.__gem_home
|
|
|
bc4e95 |
-
|
|
|
bc4e95 |
- if self.__no_proxy is not None:
|
|
|
bc4e95 |
- env["NO_PROXY"] = self.__no_proxy
|
|
|
bc4e95 |
- if self.__https_proxy is not None:
|
|
|
bc4e95 |
- env["HTTPS_PROXY"] = self.__https_proxy
|
|
|
bc4e95 |
-
|
|
|
bc4e95 |
- pcsd_ruby = Subprocess(
|
|
|
bc4e95 |
- [
|
|
|
bc4e95 |
- self.__ruby_executable, "-I",
|
|
|
bc4e95 |
- self.__pcsd_dir,
|
|
|
bc4e95 |
- self.__pcsd_cmdline_entry
|
|
|
bc4e95 |
- ],
|
|
|
bc4e95 |
- stdin=Subprocess.STREAM,
|
|
|
bc4e95 |
- stdout=Subprocess.STREAM,
|
|
|
bc4e95 |
- stderr=Subprocess.STREAM,
|
|
|
bc4e95 |
- env=env
|
|
|
bc4e95 |
- )
|
|
|
bc4e95 |
- await pcsd_ruby.stdin.write(str.encode(request_json))
|
|
|
bc4e95 |
- pcsd_ruby.stdin.close()
|
|
|
bc4e95 |
- return await multi([
|
|
|
bc4e95 |
- pcsd_ruby.stdout.read_until_close(),
|
|
|
bc4e95 |
- pcsd_ruby.stderr.read_until_close(),
|
|
|
bc4e95 |
- pcsd_ruby.wait_for_exit(raise_error=False),
|
|
|
bc4e95 |
- ])
|
|
|
bc4e95 |
+ # We do not need location for communication with ruby itself since we
|
|
|
bc4e95 |
+ # communicate via unix socket. But it is required by AsyncHTTPClient so
|
|
|
bc4e95 |
+ # "localhost" is used.
|
|
|
bc4e95 |
+ tornado_request = b64encode(request_json.encode()).decode()
|
|
|
bc4e95 |
+ return (await self.__client.fetch(
|
|
|
bc4e95 |
+ "localhost",
|
|
|
bc4e95 |
+ method="POST",
|
|
|
bc4e95 |
+ body=f"TORNADO_REQUEST={tornado_request}",
|
|
|
bc4e95 |
+ prepare_curl_callback=self.prepare_curl_callback,
|
|
|
bc4e95 |
+ )).body
|
|
|
bc4e95 |
|
|
|
bc4e95 |
async def run_ruby(self, request_type, request=None):
|
|
|
bc4e95 |
+ """
|
|
|
bc4e95 |
+ request_type: SINATRA_GUI|SINATRA_REMOTE|SYNC_CONFIGS
|
|
|
bc4e95 |
+ request: result of get_sinatra_request|None
|
|
|
bc4e95 |
+ i.e. it has structure returned by get_sinatra_request if the request
|
|
|
bc4e95 |
+ is not None - so we can get SERVER_NAME and SERVER_PORT
|
|
|
bc4e95 |
+ """
|
|
|
bc4e95 |
request = request or {}
|
|
|
bc4e95 |
request.update({"type": request_type})
|
|
|
bc4e95 |
request_json = json.dumps(request)
|
|
|
bc4e95 |
- stdout, stderr, dummy_status = await self.send_to_ruby(request_json)
|
|
|
bc4e95 |
+
|
|
|
bc4e95 |
+ if self.__debug:
|
|
|
bc4e95 |
+ log.pcsd.debug("Ruby daemon request: '%s'", request_json)
|
|
|
bc4e95 |
try:
|
|
|
bc4e95 |
- response = json.loads(stdout)
|
|
|
bc4e95 |
- except json.JSONDecodeError as e:
|
|
|
bc4e95 |
- self.__log_bad_response(
|
|
|
bc4e95 |
- f"Cannot decode json from ruby pcsd wrapper: '{e}'",
|
|
|
bc4e95 |
- request_json, stdout, stderr
|
|
|
bc4e95 |
+ ruby_response = await self.send_to_ruby(request_json)
|
|
|
bc4e95 |
+ except CurlError as e:
|
|
|
bc4e95 |
+ log.pcsd.error(
|
|
|
bc4e95 |
+ "Cannot connect to ruby daemon (message: '%s'). Is it running?",
|
|
|
bc4e95 |
+ e
|
|
|
bc4e95 |
)
|
|
|
bc4e95 |
raise HTTPError(500)
|
|
|
bc4e95 |
- else:
|
|
|
bc4e95 |
- if self.__debug:
|
|
|
bc4e95 |
- log_communication(request_json, stdout, stderr)
|
|
|
bc4e95 |
- process_response_logs(response["logs"])
|
|
|
bc4e95 |
+
|
|
|
bc4e95 |
+ try:
|
|
|
bc4e95 |
+ response = json.loads(ruby_response)
|
|
|
bc4e95 |
+ if "error" in response:
|
|
|
bc4e95 |
+ log.pcsd.error(
|
|
|
bc4e95 |
+ "Ruby daemon response contains an error: '%s'",
|
|
|
bc4e95 |
+ json.dumps(response)
|
|
|
bc4e95 |
+ )
|
|
|
bc4e95 |
+ raise HTTPError(500)
|
|
|
bc4e95 |
+
|
|
|
bc4e95 |
+ logs = response.pop("logs", [])
|
|
|
bc4e95 |
+ if "body" in response:
|
|
|
bc4e95 |
+ body = b64decode(response.pop("body"))
|
|
|
bc4e95 |
+ if self.__debug:
|
|
|
bc4e95 |
+ log.pcsd.debug(
|
|
|
bc4e95 |
+ "Ruby daemon response (without logs and body): '%s'",
|
|
|
bc4e95 |
+ json.dumps(response)
|
|
|
bc4e95 |
+ )
|
|
|
bc4e95 |
+ log.pcsd.debug("Ruby daemon response body: '%s'", body)
|
|
|
bc4e95 |
+ response["body"] = body
|
|
|
bc4e95 |
+
|
|
|
bc4e95 |
+ elif self.__debug:
|
|
|
bc4e95 |
+ log.pcsd.debug(
|
|
|
bc4e95 |
+ "Ruby daemon response (without logs): '%s'",
|
|
|
bc4e95 |
+ json.dumps(response)
|
|
|
bc4e95 |
+ )
|
|
|
bc4e95 |
+ process_response_logs(logs)
|
|
|
bc4e95 |
return response
|
|
|
bc4e95 |
+ except (json.JSONDecodeError, binascii.Error) as e:
|
|
|
bc4e95 |
+ if self.__debug:
|
|
|
bc4e95 |
+ log.pcsd.debug("Ruby daemon response: '%s'", ruby_response)
|
|
|
bc4e95 |
+ log.pcsd.error("Cannot decode json from ruby pcsd wrapper: '%s'", e)
|
|
|
bc4e95 |
+ raise HTTPError(500)
|
|
|
bc4e95 |
|
|
|
bc4e95 |
async def request_gui(
|
|
|
bc4e95 |
self, request: HTTPServerRequest, user, groups, is_authenticated
|
|
|
bc4e95 |
@@ -186,8 +197,3 @@ class Wrapper:
|
|
|
bc4e95 |
except HTTPError:
|
|
|
bc4e95 |
log.pcsd.error("Config synchronization failed")
|
|
|
bc4e95 |
return int(now()) + DEFAULT_SYNC_CONFIG_DELAY
|
|
|
bc4e95 |
-
|
|
|
bc4e95 |
- def __log_bad_response(self, error_message, request_json, stdout, stderr):
|
|
|
bc4e95 |
- log.pcsd.error(error_message)
|
|
|
bc4e95 |
- if self.__debug:
|
|
|
bc4e95 |
- log_communication(request_json, stdout, stderr)
|
|
|
bc4e95 |
diff --git a/pcs/daemon/run.py b/pcs/daemon/run.py
|
|
|
bc4e95 |
index bafd9f3c..874ee2f1 100644
|
|
|
bc4e95 |
--- a/pcs/daemon/run.py
|
|
|
bc4e95 |
+++ b/pcs/daemon/run.py
|
|
|
bc4e95 |
@@ -65,6 +65,8 @@ def configure_app(
|
|
|
bc4e95 |
# old web ui by default
|
|
|
bc4e95 |
[(r"/", RedirectHandler, dict(url="/manage"))]
|
|
|
bc4e95 |
+
|
|
|
bc4e95 |
+ [(r"/ui", RedirectHandler, dict(url="/ui/"))]
|
|
|
bc4e95 |
+ +
|
|
|
bc4e95 |
ui.get_routes(
|
|
|
bc4e95 |
url_prefix="/ui/",
|
|
|
bc4e95 |
app_dir=os.path.join(public_dir, "ui"),
|
|
|
bc4e95 |
@@ -101,12 +103,8 @@ def main():
|
|
|
bc4e95 |
|
|
|
bc4e95 |
sync_config_lock = Lock()
|
|
|
bc4e95 |
ruby_pcsd_wrapper = ruby_pcsd.Wrapper(
|
|
|
bc4e95 |
- pcsd_cmdline_entry=env.PCSD_CMDLINE_ENTRY,
|
|
|
bc4e95 |
- gem_home=env.GEM_HOME,
|
|
|
bc4e95 |
+ settings.pcsd_ruby_socket,
|
|
|
bc4e95 |
debug=env.PCSD_DEBUG,
|
|
|
bc4e95 |
- ruby_executable=settings.ruby_executable,
|
|
|
bc4e95 |
- https_proxy=env.HTTPS_PROXY,
|
|
|
bc4e95 |
- no_proxy=env.NO_PROXY,
|
|
|
bc4e95 |
)
|
|
|
bc4e95 |
make_app = configure_app(
|
|
|
bc4e95 |
session.Storage(env.PCSD_SESSION_LIFETIME),
|
|
|
bc4e95 |
diff --git a/pcs/settings_default.py b/pcs/settings_default.py
|
|
|
bc4e95 |
index 6d8f33ac..f761ce43 100644
|
|
|
bc4e95 |
--- a/pcs/settings_default.py
|
|
|
bc4e95 |
+++ b/pcs/settings_default.py
|
|
|
bc4e95 |
@@ -43,6 +43,7 @@ cibadmin = os.path.join(pacemaker_binaries, "cibadmin")
|
|
|
bc4e95 |
crm_mon_schema = '/usr/share/pacemaker/crm_mon.rng'
|
|
|
bc4e95 |
agent_metadata_schema = "/usr/share/resource-agents/ra-api-1.dtd"
|
|
|
bc4e95 |
pcsd_var_location = "/var/lib/pcsd/"
|
|
|
bc4e95 |
+pcsd_ruby_socket = "/run/pcsd-ruby.socket"
|
|
|
bc4e95 |
pcsd_cert_location = os.path.join(pcsd_var_location, "pcsd.crt")
|
|
|
bc4e95 |
pcsd_key_location = os.path.join(pcsd_var_location, "pcsd.key")
|
|
|
bc4e95 |
pcsd_known_hosts_location = os.path.join(pcsd_var_location, "known-hosts")
|
|
|
bc4e95 |
diff --git a/pcs_test/tier0/daemon/app/fixtures_app.py b/pcs_test/tier0/daemon/app/fixtures_app.py
|
|
|
bc4e95 |
index 2e4feba4..8d5b8f4c 100644
|
|
|
bc4e95 |
--- a/pcs_test/tier0/daemon/app/fixtures_app.py
|
|
|
bc4e95 |
+++ b/pcs_test/tier0/daemon/app/fixtures_app.py
|
|
|
bc4e95 |
@@ -1,4 +1,3 @@
|
|
|
bc4e95 |
-from base64 import b64encode
|
|
|
bc4e95 |
from pprint import pformat
|
|
|
bc4e95 |
from urllib.parse import urlencode
|
|
|
bc4e95 |
|
|
|
bc4e95 |
@@ -30,7 +29,7 @@ class RubyPcsdWrapper(ruby_pcsd.Wrapper):
|
|
|
bc4e95 |
return {
|
|
|
bc4e95 |
"headers": self.headers,
|
|
|
bc4e95 |
"status": self.status_code,
|
|
|
bc4e95 |
- "body": b64encode(self.body),
|
|
|
bc4e95 |
+ "body": self.body,
|
|
|
bc4e95 |
}
|
|
|
bc4e95 |
|
|
|
bc4e95 |
class AppTest(AsyncHTTPTestCase):
|
|
|
bc4e95 |
diff --git a/pcs_test/tier0/daemon/test_env.py b/pcs_test/tier0/daemon/test_env.py
|
|
|
bc4e95 |
index 9e78eafd..e2f7f5b1 100644
|
|
|
bc4e95 |
--- a/pcs_test/tier0/daemon/test_env.py
|
|
|
bc4e95 |
+++ b/pcs_test/tier0/daemon/test_env.py
|
|
|
bc4e95 |
@@ -41,11 +41,7 @@ class Prepare(TestCase, create_setup_patch_mixin(env)):
|
|
|
bc4e95 |
env.PCSD_DEBUG: False,
|
|
|
bc4e95 |
env.PCSD_DISABLE_GUI: False,
|
|
|
bc4e95 |
env.PCSD_SESSION_LIFETIME: settings.gui_session_lifetime_seconds,
|
|
|
bc4e95 |
- env.GEM_HOME: pcsd_dir(settings.pcsd_gem_path),
|
|
|
bc4e95 |
- env.PCSD_CMDLINE_ENTRY: pcsd_dir(env.PCSD_CMDLINE_ENTRY_RB_SCRIPT),
|
|
|
bc4e95 |
env.PCSD_STATIC_FILES_DIR: pcsd_dir(env.PCSD_STATIC_FILES_DIR_NAME),
|
|
|
bc4e95 |
- env.HTTPS_PROXY: None,
|
|
|
bc4e95 |
- env.NO_PROXY: None,
|
|
|
bc4e95 |
env.PCSD_DEV: False,
|
|
|
bc4e95 |
"has_errors": False,
|
|
|
bc4e95 |
}
|
|
|
bc4e95 |
@@ -77,8 +73,6 @@ class Prepare(TestCase, create_setup_patch_mixin(env)):
|
|
|
bc4e95 |
env.PCSD_DISABLE_GUI: "true",
|
|
|
bc4e95 |
env.PCSD_SESSION_LIFETIME: str(session_lifetime),
|
|
|
bc4e95 |
env.PCSD_DEV: "true",
|
|
|
bc4e95 |
- env.HTTPS_PROXY: "proxy1",
|
|
|
bc4e95 |
- env.NO_PROXY: "host",
|
|
|
bc4e95 |
env.PCSD_DEV: "true",
|
|
|
bc4e95 |
}
|
|
|
bc4e95 |
self.assert_environ_produces_modified_pcsd_env(
|
|
|
bc4e95 |
@@ -92,15 +86,9 @@ class Prepare(TestCase, create_setup_patch_mixin(env)):
|
|
|
bc4e95 |
env.PCSD_DEBUG: True,
|
|
|
bc4e95 |
env.PCSD_DISABLE_GUI: True,
|
|
|
bc4e95 |
env.PCSD_SESSION_LIFETIME: session_lifetime,
|
|
|
bc4e95 |
- env.GEM_HOME: pcsd_dir(settings.pcsd_gem_path),
|
|
|
bc4e95 |
- env.PCSD_CMDLINE_ENTRY: pcsd_dir(
|
|
|
bc4e95 |
- env.PCSD_CMDLINE_ENTRY_RB_SCRIPT
|
|
|
bc4e95 |
- ),
|
|
|
bc4e95 |
env.PCSD_STATIC_FILES_DIR: pcsd_dir(
|
|
|
bc4e95 |
env.PCSD_STATIC_FILES_DIR_NAME
|
|
|
bc4e95 |
),
|
|
|
bc4e95 |
- env.HTTPS_PROXY: environ[env.HTTPS_PROXY],
|
|
|
bc4e95 |
- env.NO_PROXY: environ[env.NO_PROXY],
|
|
|
bc4e95 |
env.PCSD_DEV: True,
|
|
|
bc4e95 |
},
|
|
|
bc4e95 |
)
|
|
|
bc4e95 |
@@ -167,13 +155,6 @@ class Prepare(TestCase, create_setup_patch_mixin(env)):
|
|
|
bc4e95 |
self.assert_environ_produces_modified_pcsd_env(
|
|
|
bc4e95 |
specific_env_values={"has_errors": True},
|
|
|
bc4e95 |
errors=[
|
|
|
bc4e95 |
- f"Ruby gem location '{pcsd_dir(settings.pcsd_gem_path)}'"
|
|
|
bc4e95 |
- " does not exist"
|
|
|
bc4e95 |
- ,
|
|
|
bc4e95 |
- "Ruby handlers entrypoint"
|
|
|
bc4e95 |
- f" '{pcsd_dir(env.PCSD_CMDLINE_ENTRY_RB_SCRIPT)}'"
|
|
|
bc4e95 |
- " does not exist"
|
|
|
bc4e95 |
- ,
|
|
|
bc4e95 |
"Directory with web UI assets"
|
|
|
bc4e95 |
f" '{pcsd_dir(env.PCSD_STATIC_FILES_DIR_NAME)}'"
|
|
|
bc4e95 |
" does not exist"
|
|
|
bc4e95 |
@@ -181,54 +162,13 @@ class Prepare(TestCase, create_setup_patch_mixin(env)):
|
|
|
bc4e95 |
]
|
|
|
bc4e95 |
)
|
|
|
bc4e95 |
|
|
|
bc4e95 |
- def test_errors_on_missing_paths_disabled_gui(self):
|
|
|
bc4e95 |
+ def test_no_errors_on_missing_paths_disabled_gui(self):
|
|
|
bc4e95 |
self.path_exists.return_value = False
|
|
|
bc4e95 |
- pcsd_dir = partial(join_path, settings.pcsd_exec_location)
|
|
|
bc4e95 |
self.assert_environ_produces_modified_pcsd_env(
|
|
|
bc4e95 |
environ={env.PCSD_DISABLE_GUI: "true"},
|
|
|
bc4e95 |
specific_env_values={
|
|
|
bc4e95 |
env.PCSD_DISABLE_GUI: True,
|
|
|
bc4e95 |
- "has_errors": True,
|
|
|
bc4e95 |
+ "has_errors": False,
|
|
|
bc4e95 |
},
|
|
|
bc4e95 |
- errors=[
|
|
|
bc4e95 |
- f"Ruby gem location '{pcsd_dir(settings.pcsd_gem_path)}'"
|
|
|
bc4e95 |
- " does not exist"
|
|
|
bc4e95 |
- ,
|
|
|
bc4e95 |
- "Ruby handlers entrypoint"
|
|
|
bc4e95 |
- f" '{pcsd_dir(env.PCSD_CMDLINE_ENTRY_RB_SCRIPT)}'"
|
|
|
bc4e95 |
- " does not exist"
|
|
|
bc4e95 |
- ,
|
|
|
bc4e95 |
- ]
|
|
|
bc4e95 |
+ errors=[]
|
|
|
bc4e95 |
)
|
|
|
bc4e95 |
-
|
|
|
bc4e95 |
- def test_lower_case_no_proxy_has_precedence(self):
|
|
|
bc4e95 |
- def it_selects(proxy_value):
|
|
|
bc4e95 |
- self.assert_environ_produces_modified_pcsd_env(
|
|
|
bc4e95 |
- environ=environ,
|
|
|
bc4e95 |
- specific_env_values={env.NO_PROXY: proxy_value}
|
|
|
bc4e95 |
- )
|
|
|
bc4e95 |
-
|
|
|
bc4e95 |
- environ = {"NO_PROXY": "no_proxy_1"}
|
|
|
bc4e95 |
- it_selects("no_proxy_1")
|
|
|
bc4e95 |
-
|
|
|
bc4e95 |
- environ["no_proxy"] = "no_proxy_2"
|
|
|
bc4e95 |
- it_selects("no_proxy_2")
|
|
|
bc4e95 |
-
|
|
|
bc4e95 |
- def test_http_proxy_is_setup_by_precedence(self):
|
|
|
bc4e95 |
- def it_selects(proxy_value):
|
|
|
bc4e95 |
- self.assert_environ_produces_modified_pcsd_env(
|
|
|
bc4e95 |
- environ=environ,
|
|
|
bc4e95 |
- specific_env_values={env.HTTPS_PROXY: proxy_value}
|
|
|
bc4e95 |
- )
|
|
|
bc4e95 |
-
|
|
|
bc4e95 |
- environ = {"ALL_PROXY": "all_proxy_1"}
|
|
|
bc4e95 |
- it_selects("all_proxy_1")
|
|
|
bc4e95 |
-
|
|
|
bc4e95 |
- environ["all_proxy"] = "all_proxy_2"
|
|
|
bc4e95 |
- it_selects("all_proxy_2")
|
|
|
bc4e95 |
-
|
|
|
bc4e95 |
- environ["HTTPS_PROXY"] = "https_proxy_1"
|
|
|
bc4e95 |
- it_selects("https_proxy_1")
|
|
|
bc4e95 |
-
|
|
|
bc4e95 |
- environ["https_proxy"] = "https_proxy_2"
|
|
|
bc4e95 |
- it_selects("https_proxy_2")
|
|
|
bc4e95 |
diff --git a/pcs_test/tier0/daemon/test_ruby_pcsd.py b/pcs_test/tier0/daemon/test_ruby_pcsd.py
|
|
|
bc4e95 |
index d7fd71a0..28f14c87 100644
|
|
|
bc4e95 |
--- a/pcs_test/tier0/daemon/test_ruby_pcsd.py
|
|
|
bc4e95 |
+++ b/pcs_test/tier0/daemon/test_ruby_pcsd.py
|
|
|
bc4e95 |
@@ -16,10 +16,7 @@ from pcs.daemon import ruby_pcsd
|
|
|
bc4e95 |
logging.getLogger("pcs.daemon").setLevel(logging.CRITICAL)
|
|
|
bc4e95 |
|
|
|
bc4e95 |
def create_wrapper():
|
|
|
bc4e95 |
- return ruby_pcsd.Wrapper(
|
|
|
bc4e95 |
- rc("/path/to/gem_home"),
|
|
|
bc4e95 |
- rc("/path/to/pcsd/cmdline/entry"),
|
|
|
bc4e95 |
- )
|
|
|
bc4e95 |
+ return ruby_pcsd.Wrapper(rc("/path/to/ruby_socket"))
|
|
|
bc4e95 |
|
|
|
bc4e95 |
def create_http_request():
|
|
|
bc4e95 |
return HTTPServerRequest(
|
|
|
bc4e95 |
@@ -63,9 +60,7 @@ patch_ruby_pcsd = create_patcher(ruby_pcsd)
|
|
|
bc4e95 |
|
|
|
bc4e95 |
class RunRuby(AsyncTestCase):
|
|
|
bc4e95 |
def setUp(self):
|
|
|
bc4e95 |
- self.stdout = ""
|
|
|
bc4e95 |
- self.stderr = ""
|
|
|
bc4e95 |
- self.exit_status = 0
|
|
|
bc4e95 |
+ self.ruby_response = ""
|
|
|
bc4e95 |
self.request = self.create_request()
|
|
|
bc4e95 |
self.wrapper = create_wrapper()
|
|
|
bc4e95 |
patcher = mock.patch.object(
|
|
|
bc4e95 |
@@ -79,14 +74,14 @@ class RunRuby(AsyncTestCase):
|
|
|
bc4e95 |
|
|
|
bc4e95 |
async def send_to_ruby(self, request_json):
|
|
|
bc4e95 |
self.assertEqual(json.loads(request_json), self.request)
|
|
|
bc4e95 |
- return self.stdout, self.stderr, self.exit_status
|
|
|
bc4e95 |
+ return self.ruby_response
|
|
|
bc4e95 |
|
|
|
bc4e95 |
@staticmethod
|
|
|
bc4e95 |
def create_request(_type=ruby_pcsd.SYNC_CONFIGS):
|
|
|
bc4e95 |
return {"type": _type}
|
|
|
bc4e95 |
|
|
|
bc4e95 |
def set_run_result(self, run_result):
|
|
|
bc4e95 |
- self.stdout = json.dumps({**run_result, "logs": []})
|
|
|
bc4e95 |
+ self.ruby_response = json.dumps({**run_result, "logs": []})
|
|
|
bc4e95 |
|
|
|
bc4e95 |
def assert_sinatra_result(self, result, headers, status, body):
|
|
|
bc4e95 |
self.assertEqual(result.headers, headers)
|
|
|
bc4e95 |
diff --git a/pcsd/Gemfile b/pcsd/Gemfile
|
|
|
bc4e95 |
index 27898f71..716991a6 100644
|
|
|
bc4e95 |
--- a/pcsd/Gemfile
|
|
|
bc4e95 |
+++ b/pcsd/Gemfile
|
|
|
bc4e95 |
@@ -10,3 +10,4 @@ gem 'json'
|
|
|
bc4e95 |
gem 'open4'
|
|
|
bc4e95 |
gem 'ffi'
|
|
|
bc4e95 |
gem 'ethon'
|
|
|
bc4e95 |
+gem 'thin'
|
|
|
bc4e95 |
diff --git a/pcsd/Gemfile.lock b/pcsd/Gemfile.lock
|
|
|
bc4e95 |
index 6f833888..c8b02a94 100644
|
|
|
bc4e95 |
--- a/pcsd/Gemfile.lock
|
|
|
bc4e95 |
+++ b/pcsd/Gemfile.lock
|
|
|
bc4e95 |
@@ -2,8 +2,10 @@ GEM
|
|
|
bc4e95 |
remote: https://rubygems.org/
|
|
|
bc4e95 |
specs:
|
|
|
bc4e95 |
backports (3.11.4)
|
|
|
bc4e95 |
+ daemons (1.3.1)
|
|
|
bc4e95 |
ethon (0.11.0)
|
|
|
bc4e95 |
ffi (>= 1.3.0)
|
|
|
bc4e95 |
+ eventmachine (1.2.7)
|
|
|
bc4e95 |
ffi (1.9.25)
|
|
|
bc4e95 |
json (2.1.0)
|
|
|
bc4e95 |
mustermann (1.0.3)
|
|
|
bc4e95 |
@@ -18,6 +20,10 @@ GEM
|
|
|
bc4e95 |
rack (~> 2.0)
|
|
|
bc4e95 |
rack-protection (= 2.0.4)
|
|
|
bc4e95 |
tilt (~> 2.0)
|
|
|
bc4e95 |
+ thin (1.7.2)
|
|
|
bc4e95 |
+ daemons (~> 1.0, >= 1.0.9)
|
|
|
bc4e95 |
+ eventmachine (~> 1.0, >= 1.0.4)
|
|
|
bc4e95 |
+ rack (>= 1, < 3)
|
|
|
bc4e95 |
tilt (2.0.9)
|
|
|
bc4e95 |
|
|
|
bc4e95 |
PLATFORMS
|
|
|
bc4e95 |
@@ -33,6 +39,7 @@ DEPENDENCIES
|
|
|
bc4e95 |
rack-protection
|
|
|
bc4e95 |
rack-test
|
|
|
bc4e95 |
sinatra
|
|
|
bc4e95 |
+ thin
|
|
|
bc4e95 |
tilt
|
|
|
bc4e95 |
|
|
|
bc4e95 |
BUNDLED WITH
|
|
|
bc4e95 |
diff --git a/pcsd/Makefile b/pcsd/Makefile
|
|
|
bc4e95 |
index 5fe3f3f3..5dde50e3 100644
|
|
|
bc4e95 |
--- a/pcsd/Makefile
|
|
|
bc4e95 |
+++ b/pcsd/Makefile
|
|
|
bc4e95 |
@@ -26,6 +26,9 @@ build_gems_without_bundler:
|
|
|
bc4e95 |
vendor/cache/rack-test-1.1.0.gem \
|
|
|
bc4e95 |
vendor/cache/sinatra-2.0.4.gem \
|
|
|
bc4e95 |
vendor/cache/tilt-2.0.9.gem \
|
|
|
bc4e95 |
+ vendor/cache/eventmachine-1.2.7.gem \
|
|
|
bc4e95 |
+ vendor/cache/daemons-1.3.1.gem \
|
|
|
bc4e95 |
+ vendor/cache/thin-1.7.2.gem \
|
|
|
bc4e95 |
-- '--with-ldflags="-Wl,-z,now -Wl,-z,relro"'
|
|
|
bc4e95 |
|
|
|
bc4e95 |
get_gems:
|
|
|
bc4e95 |
diff --git a/pcsd/bootstrap.rb b/pcsd/bootstrap.rb
|
|
|
bc4e95 |
index ec6b535c..fc9d9b8c 100644
|
|
|
bc4e95 |
--- a/pcsd/bootstrap.rb
|
|
|
bc4e95 |
+++ b/pcsd/bootstrap.rb
|
|
|
bc4e95 |
@@ -51,8 +51,23 @@ if not defined? $cur_node_name
|
|
|
bc4e95 |
$cur_node_name = `/bin/hostname`.chomp
|
|
|
bc4e95 |
end
|
|
|
bc4e95 |
|
|
|
bc4e95 |
-def configure_logger(log_device)
|
|
|
bc4e95 |
- logger = Logger.new(log_device)
|
|
|
bc4e95 |
+def configure_logger()
|
|
|
bc4e95 |
+ logger = Logger.new(StringIO.new())
|
|
|
bc4e95 |
+ logger.formatter = proc {|severity, datetime, progname, msg|
|
|
|
bc4e95 |
+ if Thread.current.key?(:pcsd_logger_container)
|
|
|
bc4e95 |
+ Thread.current[:pcsd_logger_container] << {
|
|
|
bc4e95 |
+ :level => severity,
|
|
|
bc4e95 |
+ :timestamp_usec => (datetime.to_f * 1000000).to_i,
|
|
|
bc4e95 |
+ :message => msg,
|
|
|
bc4e95 |
+ }
|
|
|
bc4e95 |
+ else
|
|
|
bc4e95 |
+ STDERR.puts("#{datetime} #{progname} #{severity} #{msg}")
|
|
|
bc4e95 |
+ end
|
|
|
bc4e95 |
+ }
|
|
|
bc4e95 |
+ return logger
|
|
|
bc4e95 |
+end
|
|
|
bc4e95 |
+
|
|
|
bc4e95 |
+def early_log(logger)
|
|
|
bc4e95 |
if ENV['PCSD_DEBUG'] and ENV['PCSD_DEBUG'].downcase == "true" then
|
|
|
bc4e95 |
logger.level = Logger::DEBUG
|
|
|
bc4e95 |
logger.info "PCSD Debugging enabled"
|
|
|
bc4e95 |
@@ -65,7 +80,6 @@ def configure_logger(log_device)
|
|
|
bc4e95 |
else
|
|
|
bc4e95 |
logger.debug "Detected systemd is not in use"
|
|
|
bc4e95 |
end
|
|
|
bc4e95 |
- return logger
|
|
|
bc4e95 |
end
|
|
|
bc4e95 |
|
|
|
bc4e95 |
def get_capabilities(logger)
|
|
|
bc4e95 |
diff --git a/pcsd/cfgsync.rb b/pcsd/cfgsync.rb
|
|
|
bc4e95 |
index 16bcfbdc..1cab512e 100644
|
|
|
bc4e95 |
--- a/pcsd/cfgsync.rb
|
|
|
bc4e95 |
+++ b/pcsd/cfgsync.rb
|
|
|
bc4e95 |
@@ -468,7 +468,8 @@ module Cfgsync
|
|
|
bc4e95 |
node_response = {}
|
|
|
bc4e95 |
threads = []
|
|
|
bc4e95 |
@nodes.each { |node|
|
|
|
bc4e95 |
- threads << Thread.new {
|
|
|
bc4e95 |
+ threads << Thread.new(Thread.current[:pcsd_logger_container]) { |logger|
|
|
|
bc4e95 |
+ Thread.current[:pcsd_logger_container] = logger
|
|
|
bc4e95 |
code, out = send_request_with_token(
|
|
|
bc4e95 |
@auth_user, node, 'set_configs', true, data, true, nil, 30,
|
|
|
bc4e95 |
@additional_known_hosts
|
|
|
bc4e95 |
@@ -616,7 +617,8 @@ module Cfgsync
|
|
|
bc4e95 |
node_configs = {}
|
|
|
bc4e95 |
connected_to = {}
|
|
|
bc4e95 |
nodes.each { |node|
|
|
|
bc4e95 |
- threads << Thread.new {
|
|
|
bc4e95 |
+ threads << Thread.new(Thread.current[:pcsd_logger_container]) { |logger|
|
|
|
bc4e95 |
+ Thread.current[:pcsd_logger_container] = logger
|
|
|
bc4e95 |
code, out = send_request_with_token(
|
|
|
bc4e95 |
@auth_user, node, 'get_configs', false, data, true, nil, nil,
|
|
|
bc4e95 |
@additional_known_hosts
|
|
|
bc4e95 |
diff --git a/pcsd/pcs.rb b/pcsd/pcs.rb
|
|
|
bc4e95 |
index 7b991ac0..9a0efb46 100644
|
|
|
bc4e95 |
--- a/pcsd/pcs.rb
|
|
|
bc4e95 |
+++ b/pcsd/pcs.rb
|
|
|
bc4e95 |
@@ -923,7 +923,8 @@ def is_auth_against_nodes(auth_user, node_names, timeout=10)
|
|
|
bc4e95 |
offline_nodes = []
|
|
|
bc4e95 |
|
|
|
bc4e95 |
node_names.uniq.each { |node_name|
|
|
|
bc4e95 |
- threads << Thread.new {
|
|
|
bc4e95 |
+ threads << Thread.new(Thread.current[:pcsd_logger_container]) { |logger|
|
|
|
bc4e95 |
+ Thread.current[:pcsd_logger_container] = logger
|
|
|
bc4e95 |
code, response = send_request_with_token(
|
|
|
bc4e95 |
auth_user, node_name, 'check_auth', false, {}, true, nil, timeout
|
|
|
bc4e95 |
)
|
|
|
bc4e95 |
@@ -963,7 +964,8 @@ def pcs_auth(auth_user, nodes)
|
|
|
bc4e95 |
auth_responses = {}
|
|
|
bc4e95 |
threads = []
|
|
|
bc4e95 |
nodes.each { |node_name, node_data|
|
|
|
bc4e95 |
- threads << Thread.new {
|
|
|
bc4e95 |
+ threads << Thread.new(Thread.current[:pcsd_logger_container]) { |logger|
|
|
|
bc4e95 |
+ Thread.current[:pcsd_logger_container] = logger
|
|
|
bc4e95 |
begin
|
|
|
bc4e95 |
addr = node_data.fetch('dest_list').fetch(0).fetch('addr')
|
|
|
bc4e95 |
port = node_data.fetch('dest_list').fetch(0).fetch('port')
|
|
|
bc4e95 |
@@ -1199,7 +1201,8 @@ def cluster_status_from_nodes(auth_user, cluster_nodes, cluster_name)
|
|
|
bc4e95 |
|
|
|
bc4e95 |
threads = []
|
|
|
bc4e95 |
cluster_nodes.uniq.each { |node|
|
|
|
bc4e95 |
- threads << Thread.new {
|
|
|
bc4e95 |
+ threads << Thread.new(Thread.current[:pcsd_logger_container]) { |logger|
|
|
|
bc4e95 |
+ Thread.current[:pcsd_logger_container] = logger
|
|
|
bc4e95 |
code, response = send_request_with_token(
|
|
|
bc4e95 |
auth_user,
|
|
|
bc4e95 |
node,
|
|
|
bc4e95 |
diff --git a/pcsd/pcsd-cli.rb b/pcsd/pcsd-cli.rb
|
|
|
bc4e95 |
index 942bae84..4daa93ba 100755
|
|
|
bc4e95 |
--- a/pcsd/pcsd-cli.rb
|
|
|
bc4e95 |
+++ b/pcsd/pcsd-cli.rb
|
|
|
bc4e95 |
@@ -29,7 +29,8 @@ end
|
|
|
bc4e95 |
auth_user = {}
|
|
|
bc4e95 |
PCS = get_pcs_path()
|
|
|
bc4e95 |
$logger_device = StringIO.new
|
|
|
bc4e95 |
-$logger = configure_logger($logger_device)
|
|
|
bc4e95 |
+$logger = Logger.new($logger_device)
|
|
|
bc4e95 |
+early_log($logger)
|
|
|
bc4e95 |
|
|
|
bc4e95 |
capabilities, capabilities_pcsd = get_capabilities($logger)
|
|
|
bc4e95 |
CAPABILITIES = capabilities.freeze
|
|
|
bc4e95 |
diff --git a/pcsd/pcsd-ruby.service b/pcsd/pcsd-ruby.service
|
|
|
bc4e95 |
new file mode 100644
|
|
|
bc4e95 |
index 00000000..deefdf4f
|
|
|
bc4e95 |
--- /dev/null
|
|
|
bc4e95 |
+++ b/pcsd/pcsd-ruby.service
|
|
|
bc4e95 |
@@ -0,0 +1,20 @@
|
|
|
bc4e95 |
+[Unit]
|
|
|
bc4e95 |
+Description=PCS GUI and remote configuration interface (Ruby)
|
|
|
bc4e95 |
+Documentation=man:pcsd(8)
|
|
|
bc4e95 |
+Documentation=man:pcs(8)
|
|
|
bc4e95 |
+Requires=network-online.target
|
|
|
bc4e95 |
+After=network-online.target
|
|
|
bc4e95 |
+# Stop the service automatically if nothing that depends on it is running
|
|
|
bc4e95 |
+StopWhenUnneeded=true
|
|
|
bc4e95 |
+# When stopping or restarting pcsd, stop or restart pcsd-ruby as well
|
|
|
bc4e95 |
+PartOf=pcsd.service
|
|
|
bc4e95 |
+
|
|
|
bc4e95 |
+[Service]
|
|
|
bc4e95 |
+EnvironmentFile=/etc/sysconfig/pcsd
|
|
|
bc4e95 |
+Environment=GEM_HOME=/usr/lib/pcsd/vendor/bundle/ruby
|
|
|
bc4e95 |
+# This file holds the selinux context
|
|
|
bc4e95 |
+ExecStart=/usr/lib/pcsd/pcsd
|
|
|
bc4e95 |
+Type=notify
|
|
|
bc4e95 |
+
|
|
|
bc4e95 |
+[Install]
|
|
|
bc4e95 |
+WantedBy=multi-user.target
|
|
|
bc4e95 |
diff --git a/pcsd/pcsd.conf b/pcsd/pcsd.conf
|
|
|
bc4e95 |
index 4761c73f..a968f459 100644
|
|
|
bc4e95 |
--- a/pcsd/pcsd.conf
|
|
|
bc4e95 |
+++ b/pcsd/pcsd.conf
|
|
|
bc4e95 |
@@ -38,3 +38,7 @@ PCSD_SESSION_LIFETIME=3600
|
|
|
bc4e95 |
#HTTPS_PROXY=
|
|
|
bc4e95 |
# Do not use proxy for specified hostnames
|
|
|
bc4e95 |
#NO_PROXY=
|
|
|
bc4e95 |
+
|
|
|
bc4e95 |
+
|
|
|
bc4e95 |
+# Do not change
|
|
|
bc4e95 |
+RACK_ENV=production
|
|
|
bc4e95 |
diff --git a/pcsd/pcsd.rb b/pcsd/pcsd.rb
|
|
|
bc4e95 |
index eff5c9a8..4cb98799 100644
|
|
|
bc4e95 |
--- a/pcsd/pcsd.rb
|
|
|
bc4e95 |
+++ b/pcsd/pcsd.rb
|
|
|
bc4e95 |
@@ -22,6 +22,7 @@ require 'permissions.rb'
|
|
|
bc4e95 |
use Rack::CommonLogger
|
|
|
bc4e95 |
|
|
|
bc4e95 |
set :app_file, __FILE__
|
|
|
bc4e95 |
+set :logging, false
|
|
|
bc4e95 |
|
|
|
bc4e95 |
def __msg_cluster_name_already_used(cluster_name)
|
|
|
bc4e95 |
return "The cluster name '#{cluster_name}' has already been added. You may not add two clusters with the same name."
|
|
|
bc4e95 |
@@ -44,17 +45,17 @@ end
|
|
|
bc4e95 |
|
|
|
bc4e95 |
def getAuthUser()
|
|
|
bc4e95 |
return {
|
|
|
bc4e95 |
- :username => $tornado_username,
|
|
|
bc4e95 |
- :usergroups => $tornado_groups,
|
|
|
bc4e95 |
+ :username => Thread.current[:tornado_username],
|
|
|
bc4e95 |
+ :usergroups => Thread.current[:tornado_groups],
|
|
|
bc4e95 |
}
|
|
|
bc4e95 |
end
|
|
|
bc4e95 |
|
|
|
bc4e95 |
before do
|
|
|
bc4e95 |
# nobody is logged in yet
|
|
|
bc4e95 |
@auth_user = nil
|
|
|
bc4e95 |
- @tornado_session_username = $tornado_username
|
|
|
bc4e95 |
- @tornado_session_groups = $tornado_groups
|
|
|
bc4e95 |
- @tornado_is_authenticated = $tornado_is_authenticated
|
|
|
bc4e95 |
+ @tornado_session_username = Thread.current[:tornado_username]
|
|
|
bc4e95 |
+ @tornado_session_groups = Thread.current[:tornado_groups]
|
|
|
bc4e95 |
+ @tornado_is_authenticated = Thread.current[:tornado_is_authenticated]
|
|
|
bc4e95 |
|
|
|
bc4e95 |
if(request.path.start_with?('/remote/') and request.path != "/remote/auth") or request.path == '/run_pcs'
|
|
|
bc4e95 |
# Sets @auth_user to a hash containing info about logged in user or halts
|
|
|
bc4e95 |
@@ -71,18 +72,8 @@ end
|
|
|
bc4e95 |
configure do
|
|
|
bc4e95 |
PCS = get_pcs_path()
|
|
|
bc4e95 |
PCS_INTERNAL = get_pcs_internal_path()
|
|
|
bc4e95 |
- $logger = configure_logger(StringIO.new())
|
|
|
bc4e95 |
- $logger.formatter = proc {|severity, datetime, progname, msg|
|
|
|
bc4e95 |
- # rushing a raw logging info into the global
|
|
|
bc4e95 |
- $tornado_logs << {
|
|
|
bc4e95 |
- :level => severity,
|
|
|
bc4e95 |
- :timestamp_usec => (datetime.to_f * 1000000).to_i,
|
|
|
bc4e95 |
- :message => msg,
|
|
|
bc4e95 |
- }
|
|
|
bc4e95 |
- # don't need any log to the stream
|
|
|
bc4e95 |
- ""
|
|
|
bc4e95 |
- }
|
|
|
bc4e95 |
-
|
|
|
bc4e95 |
+ $logger = configure_logger()
|
|
|
bc4e95 |
+ early_log($logger)
|
|
|
bc4e95 |
capabilities, capabilities_pcsd = get_capabilities($logger)
|
|
|
bc4e95 |
CAPABILITIES = capabilities.freeze
|
|
|
bc4e95 |
CAPABILITIES_PCSD = capabilities_pcsd.freeze
|
|
|
bc4e95 |
@@ -599,7 +590,8 @@ get '/manage/get_nodes_sw_versions' do
|
|
|
bc4e95 |
nodes = params[:node_list]
|
|
|
bc4e95 |
end
|
|
|
bc4e95 |
nodes.each {|node|
|
|
|
bc4e95 |
- threads << Thread.new {
|
|
|
bc4e95 |
+ threads << Thread.new(Thread.current[:pcsd_logger_container]) { |logger|
|
|
|
bc4e95 |
+ Thread.current[:pcsd_logger_container] = logger
|
|
|
bc4e95 |
code, response = send_request_with_token(
|
|
|
bc4e95 |
auth_user, node, 'get_sw_versions'
|
|
|
bc4e95 |
)
|
|
|
bc4e95 |
@@ -625,7 +617,8 @@ post '/manage/auth_gui_against_nodes' do
|
|
|
bc4e95 |
|
|
|
bc4e95 |
data = JSON.parse(params.fetch('data_json'))
|
|
|
bc4e95 |
data.fetch('nodes').each { |node_name, node_data|
|
|
|
bc4e95 |
- threads << Thread.new {
|
|
|
bc4e95 |
+ threads << Thread.new(Thread.current[:pcsd_logger_container]) { |logger|
|
|
|
bc4e95 |
+ Thread.current[:pcsd_logger_container] = logger
|
|
|
bc4e95 |
dest_list = node_data.fetch('dest_list')
|
|
|
bc4e95 |
addr = dest_list.fetch(0).fetch('addr')
|
|
|
bc4e95 |
port = dest_list.fetch(0).fetch('port')
|
|
|
bc4e95 |
diff --git a/pcsd/pcsd.service b/pcsd/pcsd.service
|
|
|
bc4e95 |
index 88d237af..0cab20ef 100644
|
|
|
bc4e95 |
--- a/pcsd/pcsd.service
|
|
|
bc4e95 |
+++ b/pcsd/pcsd.service
|
|
|
bc4e95 |
@@ -4,6 +4,8 @@ Documentation=man:pcsd(8)
|
|
|
bc4e95 |
Documentation=man:pcs(8)
|
|
|
bc4e95 |
Requires=network-online.target
|
|
|
bc4e95 |
After=network-online.target
|
|
|
bc4e95 |
+Requires=pcsd-ruby.service
|
|
|
bc4e95 |
+After=pcsd-ruby.service
|
|
|
bc4e95 |
|
|
|
bc4e95 |
[Service]
|
|
|
bc4e95 |
EnvironmentFile=/etc/sysconfig/pcsd
|
|
|
bc4e95 |
diff --git a/pcsd/pcsd.service-runner b/pcsd/pcsd.service-runner
|
|
|
bc4e95 |
new file mode 100644
|
|
|
bc4e95 |
index 00000000..40c401fa
|
|
|
bc4e95 |
--- /dev/null
|
|
|
bc4e95 |
+++ b/pcsd/pcsd.service-runner
|
|
|
bc4e95 |
@@ -0,0 +1,24 @@
|
|
|
bc4e95 |
+#!/usr/bin/ruby
|
|
|
bc4e95 |
+# This file is a runner for ruby part of pcsd callable from a systemd unit.
|
|
|
bc4e95 |
+# It also serves as a holder of a selinux context.
|
|
|
bc4e95 |
+
|
|
|
bc4e95 |
+begin
|
|
|
bc4e95 |
+ # add pcsd to the load path (ruby -I)
|
|
|
bc4e95 |
+ libdir = File.dirname(__FILE__)
|
|
|
bc4e95 |
+ $LOAD_PATH.unshift(libdir) unless $LOAD_PATH.include?(libdir)
|
|
|
bc4e95 |
+
|
|
|
bc4e95 |
+ # change current directory (ruby -C)
|
|
|
bc4e95 |
+ Dir.chdir('/var/lib/pcsd')
|
|
|
bc4e95 |
+
|
|
|
bc4e95 |
+ # import and run ruby daemon
|
|
|
bc4e95 |
+ require 'rserver.rb'
|
|
|
bc4e95 |
+rescue SignalException => e
|
|
|
bc4e95 |
+ if [Signal.list['INT'], Signal.list['TERM']].include?(e.signo)
|
|
|
bc4e95 |
+ # gracefully exit on SIGINT and SIGTERM
|
|
|
bc4e95 |
+ # pcsd sets up signal handlers later, this catches exceptions which occur
|
|
|
bc4e95 |
+ # by recieving signals before the handlers have been set up.
|
|
|
bc4e95 |
+ exit
|
|
|
bc4e95 |
+ else
|
|
|
bc4e95 |
+ raise
|
|
|
bc4e95 |
+ end
|
|
|
bc4e95 |
+end
|
|
|
bc4e95 |
diff --git a/pcsd/remote.rb b/pcsd/remote.rb
|
|
|
bc4e95 |
index 28b91382..760d3374 100644
|
|
|
bc4e95 |
--- a/pcsd/remote.rb
|
|
|
bc4e95 |
+++ b/pcsd/remote.rb
|
|
|
bc4e95 |
@@ -938,7 +938,8 @@ def status_all(params, request, auth_user, nodes=[], dont_update_config=false)
|
|
|
bc4e95 |
threads = []
|
|
|
bc4e95 |
forbidden_nodes = {}
|
|
|
bc4e95 |
nodes.each {|node|
|
|
|
bc4e95 |
- threads << Thread.new {
|
|
|
bc4e95 |
+ threads << Thread.new(Thread.current[:pcsd_logger_container]) { |logger|
|
|
|
bc4e95 |
+ Thread.current[:pcsd_logger_container] = logger
|
|
|
bc4e95 |
code, response = send_request_with_token(auth_user, node, 'status')
|
|
|
bc4e95 |
if 403 == code
|
|
|
bc4e95 |
forbidden_nodes[node] = true
|
|
|
bc4e95 |
@@ -994,7 +995,8 @@ def clusters_overview(params, request, auth_user)
|
|
|
bc4e95 |
threads = []
|
|
|
bc4e95 |
config = PCSConfig.new(Cfgsync::PcsdSettings.from_file().text())
|
|
|
bc4e95 |
config.clusters.each { |cluster|
|
|
|
bc4e95 |
- threads << Thread.new {
|
|
|
bc4e95 |
+ threads << Thread.new(Thread.current[:pcsd_logger_container]) { |logger|
|
|
|
bc4e95 |
+ Thread.current[:pcsd_logger_container] = logger
|
|
|
bc4e95 |
cluster_map[cluster.name] = {
|
|
|
bc4e95 |
'cluster_name' => cluster.name,
|
|
|
bc4e95 |
'error_list' => [
|
|
|
bc4e95 |
diff --git a/pcsd/rserver.rb b/pcsd/rserver.rb
|
|
|
bc4e95 |
new file mode 100644
|
|
|
bc4e95 |
index 00000000..6002a73c
|
|
|
bc4e95 |
--- /dev/null
|
|
|
bc4e95 |
+++ b/pcsd/rserver.rb
|
|
|
bc4e95 |
@@ -0,0 +1,98 @@
|
|
|
bc4e95 |
+require "base64"
|
|
|
bc4e95 |
+require "date"
|
|
|
bc4e95 |
+require "json"
|
|
|
bc4e95 |
+require 'rack'
|
|
|
bc4e95 |
+require 'sinatra'
|
|
|
bc4e95 |
+require 'thin'
|
|
|
bc4e95 |
+
|
|
|
bc4e95 |
+require 'settings.rb'
|
|
|
bc4e95 |
+
|
|
|
bc4e95 |
+def pack_response(response)
|
|
|
bc4e95 |
+ return [200, {}, [response.to_json.to_str]]
|
|
|
bc4e95 |
+end
|
|
|
bc4e95 |
+
|
|
|
bc4e95 |
+def unpack_request(transport_env)
|
|
|
bc4e95 |
+ return JSON.parse(Base64.strict_decode64(
|
|
|
bc4e95 |
+ transport_env["rack.request.form_hash"]["TORNADO_REQUEST"]
|
|
|
bc4e95 |
+ ))
|
|
|
bc4e95 |
+end
|
|
|
bc4e95 |
+
|
|
|
bc4e95 |
+class TornadoCommunicationMiddleware
|
|
|
bc4e95 |
+ def initialize(app)
|
|
|
bc4e95 |
+ @app = app
|
|
|
bc4e95 |
+ end
|
|
|
bc4e95 |
+
|
|
|
bc4e95 |
+ def call(transport_env)
|
|
|
bc4e95 |
+ Thread.current[:pcsd_logger_container] = []
|
|
|
bc4e95 |
+ begin
|
|
|
bc4e95 |
+ request = unpack_request(transport_env)
|
|
|
bc4e95 |
+
|
|
|
bc4e95 |
+ if ["sinatra_gui", "sinatra_remote"].include?(request["type"])
|
|
|
bc4e95 |
+ if request["type"] == "sinatra_gui"
|
|
|
bc4e95 |
+ session = request["session"]
|
|
|
bc4e95 |
+ Thread.current[:tornado_username] = session["username"]
|
|
|
bc4e95 |
+ Thread.current[:tornado_groups] = session["groups"]
|
|
|
bc4e95 |
+ Thread.current[:tornado_is_authenticated] = session["is_authenticated"]
|
|
|
bc4e95 |
+ end
|
|
|
bc4e95 |
+
|
|
|
bc4e95 |
+ # Keys rack.input and rack.errors are required. We make sure they are
|
|
|
bc4e95 |
+ # there.
|
|
|
bc4e95 |
+ request_env = request["env"]
|
|
|
bc4e95 |
+ request_env["rack.input"] = StringIO.new(request_env["rack.input"])
|
|
|
bc4e95 |
+ request_env["rack.errors"] = StringIO.new()
|
|
|
bc4e95 |
+
|
|
|
bc4e95 |
+ status, headers, body = @app.call(request_env)
|
|
|
bc4e95 |
+
|
|
|
bc4e95 |
+ rack_errors = request_env['rack.errors'].string()
|
|
|
bc4e95 |
+ if not rack_errors.empty?()
|
|
|
bc4e95 |
+ $logger.error(rack_errors)
|
|
|
bc4e95 |
+ end
|
|
|
bc4e95 |
+
|
|
|
bc4e95 |
+ return pack_response({
|
|
|
bc4e95 |
+ :status => status,
|
|
|
bc4e95 |
+ :headers => headers,
|
|
|
bc4e95 |
+ :body => Base64.encode64(body.join("")),
|
|
|
bc4e95 |
+ :logs => Thread.current[:pcsd_logger_container],
|
|
|
bc4e95 |
+ })
|
|
|
bc4e95 |
+ end
|
|
|
bc4e95 |
+
|
|
|
bc4e95 |
+ if request["type"] == "sync_configs"
|
|
|
bc4e95 |
+ return pack_response({
|
|
|
bc4e95 |
+ :next => Time.now.to_i + run_cfgsync(),
|
|
|
bc4e95 |
+ :logs => Thread.current[:pcsd_logger_container],
|
|
|
bc4e95 |
+ })
|
|
|
bc4e95 |
+ end
|
|
|
bc4e95 |
+
|
|
|
bc4e95 |
+ raise "Unexpected value for key 'type': '#{request['type']}'"
|
|
|
bc4e95 |
+ rescue => e
|
|
|
bc4e95 |
+ return pack_response({:error => "Processing request error: '#{e}'"})
|
|
|
bc4e95 |
+ end
|
|
|
bc4e95 |
+ end
|
|
|
bc4e95 |
+end
|
|
|
bc4e95 |
+
|
|
|
bc4e95 |
+
|
|
|
bc4e95 |
+use TornadoCommunicationMiddleware
|
|
|
bc4e95 |
+
|
|
|
bc4e95 |
+require 'pcsd'
|
|
|
bc4e95 |
+
|
|
|
bc4e95 |
+::Rack::Handler.get('thin').run(Sinatra::Application, {
|
|
|
bc4e95 |
+ :Host => PCSD_RUBY_SOCKET,
|
|
|
bc4e95 |
+}) do |server|
|
|
|
bc4e95 |
+ puts server.class
|
|
|
bc4e95 |
+ server.threaded = true
|
|
|
bc4e95 |
+ # notify systemd we are running
|
|
|
bc4e95 |
+ if ISSYSTEMCTL
|
|
|
bc4e95 |
+ if ENV['NOTIFY_SOCKET']
|
|
|
bc4e95 |
+ socket_name = ENV['NOTIFY_SOCKET'].dup
|
|
|
bc4e95 |
+ if socket_name.start_with?('@')
|
|
|
bc4e95 |
+ # abstract namespace socket
|
|
|
bc4e95 |
+ socket_name[0] = "\0"
|
|
|
bc4e95 |
+ end
|
|
|
bc4e95 |
+ $logger.info("Notifying systemd we are running (socket #{socket_name})")
|
|
|
bc4e95 |
+ sd_socket = Socket.new(Socket::AF_UNIX, Socket::SOCK_DGRAM)
|
|
|
bc4e95 |
+ sd_socket.connect(Socket.pack_sockaddr_un(socket_name))
|
|
|
bc4e95 |
+ sd_socket.send('READY=1', 0)
|
|
|
bc4e95 |
+ sd_socket.close()
|
|
|
bc4e95 |
+ end
|
|
|
bc4e95 |
+ end
|
|
|
bc4e95 |
+end
|
|
|
bc4e95 |
diff --git a/pcsd/settings.rb b/pcsd/settings.rb
|
|
|
bc4e95 |
index e8dc0c96..4caa5b4c 100644
|
|
|
bc4e95 |
--- a/pcsd/settings.rb
|
|
|
bc4e95 |
+++ b/pcsd/settings.rb
|
|
|
bc4e95 |
@@ -3,6 +3,7 @@ PCS_INTERNAL_EXEC = '/usr/lib/pcs/pcs_internal'
|
|
|
bc4e95 |
PCSD_EXEC_LOCATION = '/usr/lib/pcsd/'
|
|
|
bc4e95 |
PCSD_VAR_LOCATION = '/var/lib/pcsd/'
|
|
|
bc4e95 |
PCSD_DEFAULT_PORT = 2224
|
|
|
bc4e95 |
+PCSD_RUBY_SOCKET = '/run/pcsd-ruby.socket'
|
|
|
bc4e95 |
|
|
|
bc4e95 |
CRT_FILE = PCSD_VAR_LOCATION + 'pcsd.crt'
|
|
|
bc4e95 |
KEY_FILE = PCSD_VAR_LOCATION + 'pcsd.key'
|
|
|
bc4e95 |
diff --git a/pcsd/settings.rb.debian b/pcsd/settings.rb.debian
|
|
|
bc4e95 |
index daaae37b..c547bc51 100644
|
|
|
bc4e95 |
--- a/pcsd/settings.rb.debian
|
|
|
bc4e95 |
+++ b/pcsd/settings.rb.debian
|
|
|
bc4e95 |
@@ -3,6 +3,7 @@ PCS_INTERNAL_EXEC = '/usr/lib/pcs/pcs_internal'
|
|
|
bc4e95 |
PCSD_EXEC_LOCATION = '/usr/share/pcsd/'
|
|
|
bc4e95 |
PCSD_VAR_LOCATION = '/var/lib/pcsd/'
|
|
|
bc4e95 |
PCSD_DEFAULT_PORT = 2224
|
|
|
bc4e95 |
+PCSD_RUBY_SOCKET = '/run/pcsd-ruby.socket'
|
|
|
bc4e95 |
|
|
|
bc4e95 |
CRT_FILE = PCSD_VAR_LOCATION + 'pcsd.crt'
|
|
|
bc4e95 |
KEY_FILE = PCSD_VAR_LOCATION + 'pcsd.key'
|
|
|
bc4e95 |
diff --git a/pcsd/sinatra_cmdline_wrapper.rb b/pcsd/sinatra_cmdline_wrapper.rb
|
|
|
bc4e95 |
deleted file mode 100644
|
|
|
bc4e95 |
index f7b22008..00000000
|
|
|
bc4e95 |
--- a/pcsd/sinatra_cmdline_wrapper.rb
|
|
|
bc4e95 |
+++ /dev/null
|
|
|
bc4e95 |
@@ -1,63 +0,0 @@
|
|
|
bc4e95 |
-require "base64"
|
|
|
bc4e95 |
-require "date"
|
|
|
bc4e95 |
-require "json"
|
|
|
bc4e95 |
-
|
|
|
bc4e95 |
-request_json = ARGF.read()
|
|
|
bc4e95 |
-
|
|
|
bc4e95 |
-begin
|
|
|
bc4e95 |
- request = JSON.parse(request_json)
|
|
|
bc4e95 |
-rescue => e
|
|
|
bc4e95 |
- puts e
|
|
|
bc4e95 |
- exit
|
|
|
bc4e95 |
-end
|
|
|
bc4e95 |
-
|
|
|
bc4e95 |
-if !request.include?("type")
|
|
|
bc4e95 |
- result = {:error => "Type not specified"}
|
|
|
bc4e95 |
- print result.to_json
|
|
|
bc4e95 |
- exit
|
|
|
bc4e95 |
-end
|
|
|
bc4e95 |
-
|
|
|
bc4e95 |
-$tornado_logs = []
|
|
|
bc4e95 |
-
|
|
|
bc4e95 |
-require 'pcsd'
|
|
|
bc4e95 |
-
|
|
|
bc4e95 |
-if ["sinatra_gui", "sinatra_remote"].include?(request["type"])
|
|
|
bc4e95 |
- if request["type"] == "sinatra_gui"
|
|
|
bc4e95 |
- $tornado_username = request["session"]["username"]
|
|
|
bc4e95 |
- $tornado_groups = request["session"]["groups"]
|
|
|
bc4e95 |
- $tornado_is_authenticated = request["session"]["is_authenticated"]
|
|
|
bc4e95 |
- end
|
|
|
bc4e95 |
-
|
|
|
bc4e95 |
- set :logging, true
|
|
|
bc4e95 |
- set :run, false
|
|
|
bc4e95 |
- # Do not turn exceptions into fancy 100kB HTML pages and print them on stdout.
|
|
|
bc4e95 |
- # Instead, rack.errors is logged and therefore returned in result[:log].
|
|
|
bc4e95 |
- set :show_exceptions, false
|
|
|
bc4e95 |
- app = [Sinatra::Application][0]
|
|
|
bc4e95 |
-
|
|
|
bc4e95 |
- env = request["env"]
|
|
|
bc4e95 |
- env["rack.input"] = StringIO.new(env["rack.input"])
|
|
|
bc4e95 |
- env["rack.errors"] = StringIO.new()
|
|
|
bc4e95 |
-
|
|
|
bc4e95 |
- status, headers, body = app.call(env)
|
|
|
bc4e95 |
- rack_errors = env['rack.errors'].string()
|
|
|
bc4e95 |
- if not rack_errors.empty?()
|
|
|
bc4e95 |
- $logger.error(rack_errors)
|
|
|
bc4e95 |
- end
|
|
|
bc4e95 |
-
|
|
|
bc4e95 |
- result = {
|
|
|
bc4e95 |
- :status => status,
|
|
|
bc4e95 |
- :headers => headers,
|
|
|
bc4e95 |
- :body => Base64.encode64(body.join("")),
|
|
|
bc4e95 |
- }
|
|
|
bc4e95 |
-
|
|
|
bc4e95 |
-elsif request["type"] == "sync_configs"
|
|
|
bc4e95 |
- result = {
|
|
|
bc4e95 |
- :next => Time.now.to_i + run_cfgsync()
|
|
|
bc4e95 |
- }
|
|
|
bc4e95 |
-else
|
|
|
bc4e95 |
- result = {:error => "Unknown type: '#{request["type"]}'"}
|
|
|
bc4e95 |
-end
|
|
|
bc4e95 |
-
|
|
|
bc4e95 |
-result[:logs] = $tornado_logs
|
|
|
bc4e95 |
-print result.to_json
|
|
|
bc4e95 |
--
|
|
|
bc4e95 |
2.21.1
|
|
|
bc4e95 |
|