From 19ce5ec842128637595ecbd5b8e1f9733d0999ce Mon Sep 17 00:00:00 2001
From: Miroslav Lisik <mlisik@redhat.com>
Date: Mon, 5 Feb 2024 13:33:50 +0100
Subject: [PATCH] Fix pcsd ruby

---
 configure.ac                       | 19 ++++++++++++++
 m4/ac_ruby_gem.m4                  |  4 +--
 pcs_test/smoke.sh.in               | 42 +++++++++++++++++++++++++++++-
 pcsd/pcsd.rb                       | 12 ++++++---
 pcsd/{rserver.rb => rserver.rb.in} |  3 ++-
 5 files changed, 72 insertions(+), 8 deletions(-)
 rename pcsd/{rserver.rb => rserver.rb.in} (97%)

diff --git a/configure.ac b/configure.ac
index 68de52c..86de294 100644
--- a/configure.ac
+++ b/configure.ac
@@ -399,9 +399,22 @@ AC_DEFUN([PCS_CHECK_GEM], [
 	fi
 ])
 
+# PCS_GEM_ACTION([curversion], [op], [cmpversion][, action-if-true] [, action-if-false])
+AC_DEFUN([PCS_GEM_ACTION], [
+	if test -n "$1"; then
+		AC_COMPARE_VERSIONS([$1], [$2], [$3], [$4], [$5])
+	else
+		true
+		$5
+	fi
+])
+
 PCS_CHECK_GEM([power_assert])
 PCS_CHECK_GEM([test-unit])
 
+RACK_HANDLER="Rackup"
+REQUIRE_RACKUP="require 'rackup'"
+
 if test "x$tests_only" != "xyes"; then
 	PCS_CHECK_GEM([backports])
 	PCS_CHECK_GEM([childprocess])
@@ -411,14 +424,19 @@ if test "x$tests_only" != "xyes"; then
 	PCS_CHECK_GEM([ruby2_keywords])
 	PCS_CHECK_GEM([mustermann])
 	PCS_CHECK_GEM([rack])
+	PCS_GEM_ACTION([$HAVE_RUBYGEM_RACK_VERSION], [<], [3.0], [RACK_HANDLER=Rack REQUIRE_RACKUP=""], [PCS_CHECK_GEM([rackup])])
 	PCS_CHECK_GEM([rack-protection])
+	PCS_GEM_ACTION([$HAVE_RUBYGEM_RACK_PROTECTION_VERSION], [<], [3.2.0], [], [PCS_CHECK_GEM([base64], [>= 0.1.0])])
 	PCS_CHECK_GEM([rack-test])
 	PCS_CHECK_GEM([sinatra])
+	PCS_GEM_ACTION([$HAVE_RUBYGEM_SINATRA_VERSION], [<], [4.0.0], [], [PCS_CHECK_GEM([rack-session], [>= 2.0.0])])
 	PCS_CHECK_GEM([tilt])
 	PCS_CHECK_GEM([nio4r])
 	PCS_CHECK_GEM([puma])
 	PCS_CHECK_GEM([rexml])
 fi
+AC_SUBST([RACK_HANDLER])
+AC_SUBST([REQUIRE_RACKUP])
 
 if test "x$local_build" = "xyes" && test $(wc -l < Gemfile) -gt 2; then
 	GEM_HOME="$LIB_DIR/$PCSD_BUNDLED_DIR_ROOT_LOCAL"
@@ -603,6 +621,7 @@ AC_CONFIG_FILES([Makefile
 		 pcsd/pcsd-cli.rb
 		 pcsd/pcsd-ruby.service
 		 pcsd/pcsd.service
+		 pcsd/rserver.rb
 		 pcsd/settings.rb
 		 pcsd/logrotate/pcsd])
 
diff --git a/m4/ac_ruby_gem.m4 b/m4/ac_ruby_gem.m4
index 6e202a3..465084c 100644
--- a/m4/ac_ruby_gem.m4
+++ b/m4/ac_ruby_gem.m4
@@ -29,12 +29,12 @@ AC_DEFUN([AC_RUBY_GEM],[
 		fi
 		AC_MSG_RESULT([yes (detected: $curversion)])
 		eval AS_TR_CPP(HAVE_RUBYGEM_$module)=yes
-		eval AS_TR_CPP(HAVE_RUBYGEM_$module_version)=$curversion
+		eval AS_TR_CPP(HAVE_RUBYGEM_${module}_version)=$curversion
 		$3
 	else
 		AC_MSG_RESULT([no])
 		eval AS_TR_CPP(HAVE_RUBYGEM_$module)=no
-		eval AS_TR_CPP(HAVE_RUBYGEM_$module_version)=""
+		eval AS_TR_CPP(HAVE_RUBYGEM_${module}_version)=""
 		$4
 	fi
 ])
diff --git a/pcs_test/smoke.sh.in b/pcs_test/smoke.sh.in
index e9466ef..a4b3ac7 100755
--- a/pcs_test/smoke.sh.in
+++ b/pcs_test/smoke.sh.in
@@ -5,7 +5,9 @@ SCRIPT_DIR="$(dirname -- "$(realpath -- "$0")")"
 
 cluster_user=hacluster
 cluster_user_password=qa57Jk27eP
+cluster_name="cluster-name"
 pcsd_socket_path="@LOCALSTATEDIR@/run/pcsd.socket"
+pcsd_settings_conf_path="@LOCALSTATEDIR@/lib/pcsd/pcs_settings.conf"
 
 echo "${cluster_user_password}" | passwd --stdin "${cluster_user}";
 
@@ -14,11 +16,12 @@ pcs --version
 pcs host auth localhost --debug -u ${cluster_user} -p ${cluster_user_password}
 if pidof systemd | grep "\b1\b"; then
     # this command requires full system with proper init process
-    pcs cluster setup cluster-name localhost --debug
+    pcs cluster setup ${cluster_name} localhost --debug
 fi
 
 output_file=$(mktemp)
 token_file=$(mktemp)
+cookie_file=$(mktemp)
 
 # Sanity check of API V0
 token=$(python3 -c "import json; print(json.load(open('@LOCALSTATEDIR@/lib/pcsd/known-hosts'))['known_hosts']['localhost']['token']);")
@@ -33,6 +36,41 @@ pcs host auth "${custom_localhost_node_name}" addr=localhost --token "${token_fi
 pcs pcsd accept_token "${token_file}"
 pcs pcsd status "${custom_localhost_node_name}" | grep "${custom_localhost_node_name}: Online"
 
+# Test passing request body (raw_data) in ruby daemon
+cat <<EOF > ${pcsd_settings_conf_path}
+{
+  "format_version": 2,
+  "data_version": 1,
+  "clusters": [
+    {
+      "name": "${cluster_name}",
+      "nodes": [
+        "localhost"
+      ]
+    }
+  ],
+  "permissions": {
+    "local_cluster": [
+      {
+        "type": "group",
+        "name": "haclient",
+        "allow": [
+          "grant",
+          "read",
+          "write"
+        ]
+      }
+    ]
+  }
+}
+EOF
+cat ${pcsd_settings_conf_path}
+pcs cluster start --all --wait
+curl --insecure --data "username=${cluster_user}&password=${cluster_user_password}" --cookie-jar ${cookie_file} https://localhost:2224/ui/login
+curl --insecure --cookie ${cookie_file} --header "X-Requested-With: XMLHttpRequest" --data "hidden[hidden_input]=&config[stonith-enabled]=false" https://localhost:2224/managec/${cluster_name}/update_cluster_settings > "${output_file}"
+cat "${output_file}"; echo ""
+[ "$(cat ${output_file})" = "Update Successful" ]
+
 # Sanity check of API V1
 curl -kb "token=${token}" https://localhost:2224/api/v1/resource-agent-get-agents-list/v1 --data '{}' > "${output_file}"
 cat "${output_file}"; echo ""
@@ -57,6 +95,8 @@ su testuser -c '! curl --unix-socket '"${pcsd_socket_path}"' http:/something/api
 # cleanup
 rm "${token_file}"
 rm "${output_file}"
+rm "${cookie_file}"
+rm "${pcsd_settings_conf_path}"
 pcs cluster destroy --force
 userdel -r testuser
 exit 0
diff --git a/pcsd/pcsd.rb b/pcsd/pcsd.rb
index 2e2baa2..5b8d0a1 100644
--- a/pcsd/pcsd.rb
+++ b/pcsd/pcsd.rb
@@ -848,6 +848,7 @@ end
 post '/managec/:cluster/api/v1/:command' do
   auth_user = getAuthUser()
   if params[:cluster] and params[:command]
+    request.body.rewind
     return send_cluster_request_with_token(
       auth_user,
       params[:cluster],
@@ -855,7 +856,7 @@ post '/managec/:cluster/api/v1/:command' do
       true, # post
       {}, # data - useless when there are raw_data
       false, # remote
-      request.env['rack.input'].read # raw_data
+      request.body.read # raw_data
     )
   end
 end
@@ -863,6 +864,7 @@ end
 get '/managec/:cluster/api/v1/:command' do
   auth_user = getAuthUser()
   if params[:cluster] and params[:command]
+    request.body.rewind
     return send_cluster_request_with_token(
       auth_user,
       params[:cluster],
@@ -870,14 +872,15 @@ get '/managec/:cluster/api/v1/:command' do
       false, # post
       {}, # data - useless when there are raw_data
       false, # remote
-      request.env['rack.input'].read # raw_data
+      request.body.read # raw_data
     )
   end
 end
 
 post '/managec/:cluster/?*' do
   auth_user = getAuthUser()
-  raw_data = request.env["rack.input"].read
+  request.body.rewind
+  raw_data = request.body.read
   if params[:cluster]
     request = "/" + params[:splat].join("/")
 
@@ -889,7 +892,8 @@ end
 
 get '/managec/:cluster/?*' do
   auth_user = getAuthUser()
-  raw_data = request.env["rack.input"].read
+  request.body.rewind
+  raw_data = request.body.read
   if params[:cluster]
     request = "/" + params[:splat].join("/")
     code, out = send_cluster_request_with_token(
diff --git a/pcsd/rserver.rb b/pcsd/rserver.rb.in
similarity index 97%
rename from pcsd/rserver.rb
rename to pcsd/rserver.rb.in
index 400df28..02d1a34 100644
--- a/pcsd/rserver.rb
+++ b/pcsd/rserver.rb.in
@@ -2,6 +2,7 @@ require "base64"
 require "date"
 require "json"
 require 'rack'
+@REQUIRE_RACKUP@
 require 'sinatra'
 
 require 'settings.rb'
@@ -59,7 +60,7 @@ use TornadoCommunicationMiddleware
 
 require 'pcsd'
 
-::Rack::Handler.get('puma').run(
+::@RACK_HANDLER@::Handler.get('puma').run(
   Sinatra::Application, :Host => "#{PCSD_RUBY_SOCKET}?umask=0o077", :timeout => 0
 ) do |server|
   puts server.class
-- 
2.41.0

