diff --git a/resources/puppetlabs/lein-ezbake/template/global/ext/cli/reload.erb b/resources/puppetlabs/lein-ezbake/template/global/ext/cli/reload.erb new file mode 100644 index 00000000..a2966453 --- /dev/null +++ b/resources/puppetlabs/lein-ezbake/template/global/ext/cli/reload.erb @@ -0,0 +1,39 @@ +#!/usr/bin/env bash +set +e + +restartfile="/run/puppetlabs/<%= EZBake::Config[:real_name] %>/restartcounter" +reload_timeout="${RELOAD_TIMEOUT:-<%= EZBake::Config[:reload_timeout] %>}" +timeout="$reload_timeout" + +if [ ! -r $restartfile ]; then + echo "Restart counter does not exist or is not readable: ${restartfile}" 1>&2 + exit 1 +fi + +pid="$(systemctl show --value -p MainPID <%= EZBake::Config[:project] %>)" +if [[ ! "$pid" =~ ^[0-9]+$ ]] || [ "$pid" -eq 0 ]; then + echo "Service not running so cannot be reloaded" 1>&2 + exit 1 +fi + +initial="$(head -n 1 "$restartfile")" +kill -HUP "$pid" >/dev/null 2>&1 +sleep 0.1 +cur="$(head -n 1 "$restartfile")" +while [ "$cur" == "$initial" ] ;do + kill -0 "$pid" >/dev/null 2>&1 + if [ $? -ne 0 ]; then + echo "Process $pid exited before reload had completed" 1>&2 + exit 1 + fi + sleep 1 + cur="$(head -n 1 "$restartfile")" + + ((timeout--)) + if [ $timeout -le 0 ]; then + echo "Reload timed out after $reload_timeout seconds" + exit 1 + fi +done + +exit 0 diff --git a/resources/puppetlabs/lein-ezbake/template/global/ext/debian/ezbake.service.erb b/resources/puppetlabs/lein-ezbake/template/global/ext/debian/ezbake.service.erb index 22878e46..19a185b5 100644 --- a/resources/puppetlabs/lein-ezbake/template/global/ext/debian/ezbake.service.erb +++ b/resources/puppetlabs/lein-ezbake/template/global/ext/debian/ezbake.service.erb @@ -19,7 +19,7 @@ Wants=<%= EZBake::Config[:start_after].map {|dep| "#{dep}.service" }.join(" ") % <% end -%> [Service] -Type=notify-reload +Type=notify LogsDirectory=puppetlabs/<%= EZBake::Config[:real_name] %> RuntimeDirectory=puppetlabs/<%= EZBake::Config[:real_name] %> EnvironmentFile=/etc/default/<%= EZBake::Config[:project] %> @@ -59,8 +59,11 @@ ExecStart=<%= EZBake::Config[:java_bin] %> $JAVA_ARGS $LOG_APPENDER -Dlogappende -m <%= EZBake::Config[:main_namespace] %> \ --config "${CONFIG}" \ --bootstrap-config "${BOOTSTRAP_CONFIG}" \ + --restart-file /run/puppetlabs/<%= EZBake::Config[:real_name] %>/restartcounter \ $TK_ARGS +ExecReload=/opt/puppetlabs/server/apps/<%= EZBake::Config[:real_name] %>/bin/<%= EZBake::Config[:real_name] %> reload + KillMode=process <% EZBake::Config[:debian][:post_start_action].each do |action| -%> diff --git a/resources/puppetlabs/lein-ezbake/template/global/ext/fpm.rb b/resources/puppetlabs/lein-ezbake/template/global/ext/fpm.rb index a4368141..c6c13fd1 100755 --- a/resources/puppetlabs/lein-ezbake/template/global/ext/fpm.rb +++ b/resources/puppetlabs/lein-ezbake/template/global/ext/fpm.rb @@ -7,37 +7,58 @@ require 'tmpdir' def patch_files(options) - if options.java_bin == EZBake::Config[:java_bin] - yield - else - suffix = '.backup' - [ - # Debian - '/etc/default/puppet*', - '/lib/systemd/system/puppet*.service', - # RPM - '/usr/lib/systemd/system/puppet*.service', - '/etc/sysconfig/puppet*', - ].each do |path| - Dir.glob(File.join(options.chdir, path)).each do |real_path| - content = File.read(real_path) - next unless content.include?(EZBake::Config[:java_bin]) - - warn "Copying #{real_path} to #{real_path}#{suffix}" - FileUtils.cp(real_path, "#{real_path}#{suffix}") + suffix = '.backup' + [ + # Debian + '/etc/default/puppet*', + '/lib/systemd/system/puppet*.service', + # RPM + '/usr/lib/systemd/system/puppet*.service', + '/etc/sysconfig/puppet*', + ].each do |path| + Dir.glob(File.join(options.chdir, path)).each do |real_path| + content = File.read(real_path) + + warn "Copying #{real_path} to #{real_path}#{suffix}" + FileUtils.cp(real_path, "#{real_path}#{suffix}") + + if content.include?(EZBake::Config[:java_bin]) warn "Patching #{real_path} to use #{options.java_bin}" - File.write(real_path, content.gsub(EZBake::Config[:java_bin], options.java_bin)) + content.gsub!(EZBake::Config[:java_bin], options.java_bin) end - end - yield + if real_path.end_with?('.service') && notify_reload?(options) + warn "Patching #{real_path} to use Type=notify-reload" + content.sub!(/^Type=notify$/, 'Type=notify-reload') + # Swallow the trailing newline so we don't leave a blank line behind. + content.sub!(/^ExecReload=[^\n]*\n/, '') + end - Dir.glob(File.join(options.chdir, '**', "*#{suffix}")).each do |path| - original = File.join(File.dirname(path), File.basename(path, suffix)) - warn "Restoring #{path} to #{original}" - FileUtils.mv(path, original) + File.write(real_path, content) end end + + yield + + Dir.glob(File.join(options.chdir, '**', "*#{suffix}")).each do |path| + original = File.join(File.dirname(path), File.basename(path, suffix)) + warn "Restoring #{path} to #{original}" + FileUtils.mv(path, original) + end +end + +# Type=notify-reload was introduced in systemd v253. Anything older has to stay +# on Type=notify plus an explicit ExecReload. +def notify_reload?(options) + case [options.operating_system, options.os_version.to_s, options.dist] + in [:redhatfips, _, _] then false # Built against EL 8 and 9 + in [:el, '8' | '9', _] then false # systemd 239 and 252 + in [:amazon, '2023', _] then false # systemd 252 + in [:sles, '15', _] then false # systemd 249 up to and including SP5 + in [:debian, _, 'ubuntu22.04'] then false # systemd 249 + else + true + end end def create_sles_rpmbuild_wrapper diff --git a/resources/puppetlabs/lein-ezbake/template/global/ext/redhat/ezbake.service.erb b/resources/puppetlabs/lein-ezbake/template/global/ext/redhat/ezbake.service.erb index 5ab6a91f..128305df 100644 --- a/resources/puppetlabs/lein-ezbake/template/global/ext/redhat/ezbake.service.erb +++ b/resources/puppetlabs/lein-ezbake/template/global/ext/redhat/ezbake.service.erb @@ -19,7 +19,7 @@ Wants=<%= EZBake::Config[:start_after].map {|dep| "#{dep}.service" }.join(" ") % <% end -%> [Service] -Type=notify-reload +Type=notify LogsDirectory=puppetlabs/<%= EZBake::Config[:real_name] %> RuntimeDirectory=puppetlabs/<%= EZBake::Config[:real_name] %> EnvironmentFile=/etc/sysconfig/<%= EZBake::Config[:project] %> @@ -59,8 +59,11 @@ ExecStart=<%= EZBake::Config[:java_bin] %> $JAVA_ARGS -Dlogappender=F1 \ -m <%= EZBake::Config[:main_namespace] %> \ --config "${CONFIG}" \ --bootstrap-config "${BOOTSTRAP_CONFIG}" \ + --restart-file /run/puppetlabs/<%= EZBake::Config[:real_name] %>/restartcounter \ $TK_ARGS +ExecReload=/opt/puppetlabs/server/apps/<%= EZBake::Config[:real_name] %>/bin/<%= EZBake::Config[:real_name] %> reload + KillMode=process <% EZBake::Config[:redhat][:post_start_action].each do |action| -%>