From 9883362e410734e46ceea4d1c1b80e277ff3b277 Mon Sep 17 00:00:00 2001 From: Ewoud Kohl van Wijngaarden Date: Thu, 25 Jul 2024 19:02:28 +0200 Subject: [PATCH] Fixes #37686 - Stop puppetserver if java is too old When upgrading from puppetserver 7 to puppetserver 8 it'll typically be configured with /usr/bin/java and that usually points to Java 8. Puppetserver 8 has started to require Java 11, so upgrading fails. By properly stopping the service before running Puppet we know for sure that it can be started safely again. It also helps free up CPU from the constant restart loop, which reduces the slowdown. --- hooks/boot/04-services.rb | 2 +- .../31-puppet_puppet_server_invalid_java.rb | 31 +++++++++++++++++++ spec/services_hook_extensions_spec.rb | 6 ++-- 3 files changed, 35 insertions(+), 4 deletions(-) create mode 100644 hooks/pre/31-puppet_puppet_server_invalid_java.rb diff --git a/hooks/boot/04-services.rb b/hooks/boot/04-services.rb index 68d4bb50..0c980bc8 100644 --- a/hooks/boot/04-services.rb +++ b/hooks/boot/04-services.rb @@ -24,7 +24,7 @@ def stop_services(services = ALL_POSSIBLE_SERVICES) raise "Can't stop all services" if services.empty? logger.debug('Getting running services') - stdout_str, stderr_str, status = Open3.capture3('systemctl', 'list-units', '--no-legend', '--type=service,socket', '--state=running', *services) + stdout_str, stderr_str, status = Open3.capture3('systemctl', 'list-units', '--no-legend', '--type=service,socket', '--state=activating,running', *services) fail_and_exit("Failed to get running services: #{stderr_str}", status.exitstatus) unless status.success? running = stdout_str.lines.map { |line| line.split.first } logger.debug("Found running services #{running.inspect}") diff --git a/hooks/pre/31-puppet_puppet_server_invalid_java.rb b/hooks/pre/31-puppet_puppet_server_invalid_java.rb new file mode 100644 index 00000000..fc300865 --- /dev/null +++ b/hooks/pre/31-puppet_puppet_server_invalid_java.rb @@ -0,0 +1,31 @@ +# With Puppetserver 8 the minimum java version has been increased to Java 11 +# If the user is upgrading from Puppet 7 to Puppet 8 then /usr/bin/java may +# point to Java 8, which is what Puppetserver uses by default. The installer +# will explicitly configure Java 17, but puppetserver.service can end up in a +# restart loop where puppet can't properly restart the service. +# +# This hook detects Java 8 and Puppetserver 8 and explicitly stops the service. +# The installer should then reconfigure it and start it again. +# +# See https://github.com/theforeman/puppet-puppet/pull/910 which is currently +# only implemented for Red Hat based systems. +sysconfig_file = '/etc/sysconfig/puppetserver' +if File.exist?(sysconfig_file) + puppetserver_stdout_stderr, _status = execute_command('puppetserver --version', false, true) + puppetserver_stdout_stderr&.match(/puppetserver version: (?\d+)\.\d+\.\d+/) do |puppetserver_match| + logger.debug("Found Puppetserver #{puppetserver_match[:version]}") + if puppetserver_match[:version] == '8' + java_stdout_stderr, _status = execute_command("source #{sysconfig_file} ; $JAVA_BIN -version", false, true) + java_stdout_stderr&.match(/version "\d+\.(?\d+)\.\d+/) do |java_match| + if java_match[:version] && java_match[:version].to_i < 11 + logger.info "Detected Java #{java_match[:version]} which is too old for Puppetserver #{puppetserver_match[:version]}" + if app_value(:noop) + logger.debug 'Would stop puppetserver.service' + else + stop_services(['puppetserver.service']) + end + end + end + end + end +end diff --git a/spec/services_hook_extensions_spec.rb b/spec/services_hook_extensions_spec.rb index f6674c6f..259937fd 100644 --- a/spec/services_hook_extensions_spec.rb +++ b/spec/services_hook_extensions_spec.rb @@ -130,7 +130,7 @@ expect(subject).to be_nil expect(logger).to have_received(:debug).with('Getting running services') - expect(Open3).to have_received(:capture3).with('systemctl', 'list-units', '--no-legend', '--type=service,socket', '--state=running', 'httpd.service') + expect(Open3).to have_received(:capture3).with('systemctl', 'list-units', '--no-legend', '--type=service,socket', '--state=activating,running', 'httpd.service') expect(logger).to have_received(:debug).with('Found running services []') expect(logger).not_to have_received(:debug).with('Stopping running services httpd.service') expect(Open3).not_to have_received(:capture2e).with('systemctl', 'stop', 'httpd.service') @@ -153,7 +153,7 @@ expect(subject).to be_nil expect(logger).to have_received(:debug).with('Getting running services') - expect(Open3).to have_received(:capture3).with('systemctl', 'list-units', '--no-legend', '--type=service,socket', '--state=running', 'httpd.service') + expect(Open3).to have_received(:capture3).with('systemctl', 'list-units', '--no-legend', '--type=service,socket', '--state=activating,running', 'httpd.service') expect(logger).to have_received(:debug).with('Found running services ["httpd.service"]') expect(logger).to have_received(:debug).with('Stopping running services httpd.service') expect(Open3).to have_received(:capture2e).with('systemctl', 'stop', 'httpd.service') @@ -175,7 +175,7 @@ expect { subject }.to raise_error(RuntimeError, 'called fail_and_exit') expect(logger).to have_received(:debug).with('Getting running services') - expect(Open3).to have_received(:capture3).with('systemctl', 'list-units', '--no-legend', '--type=service,socket', '--state=running', 'httpd.service') + expect(Open3).to have_received(:capture3).with('systemctl', 'list-units', '--no-legend', '--type=service,socket', '--state=activating,running', 'httpd.service') expect(context).to have_received(:fail_and_exit).with('Failed to get running services: Failed StdErr', 1) end end