sous-chefs / jenkins

Development repository for the jenkins cookbook
https://supermarket.chef.io/cookbooks/jenkins
Apache License 2.0
424 stars 636 forks source link

Jenkins now uses systemd instead of SysV but override.conf is not created #783

Open pklassen-work opened 2 years ago

pklassen-work commented 2 years ago

:ghost: Brief Description

As of Jenkins 2.332.1, the Linux installation packages use systemd instead of SysV. The cookbook manages /etc/sysconfig/jenkins to handle startup options for SysV, but doesn't create an /etc/systemd/system/jenkins.service.d/override.conf file to handle startup options for systemd. As a result, default startup options are used; options placed into node['jenkins']['master']['jvm_options'] don't take effect.

:pancakes: Cookbook version

9.5.0

:woman_cook: Chef-Infra Version

Chef Infra Client: 16.8.14

:tophat: Platform details

Amazon Linux 2 running in AWS

Steps To Reproduce

Steps to reproduce the behavior:

  1. Start with a recipe that depends on this cookbook to build a Jenkins controller from scratch.
  2. Set the ['master']['home'] and ['master']['jvm_options'] attributes, e.g.
    override['jenkins']['master']['home'] = '/var/lib/jenkins_nonstandard_home'
    default['jenkins']['master']['jvm_options'] = "-Djava.io.tmpdir=/var/jenkins_tmp -Djenkins.install.runSetupWizard=false -Dcasc.jenkins.config=#{node['jenkins']['master']['home']}/casc_configs"
  3. include_recipe 'jenkins::master'
  4. Run your recipe.
  5. See the missing /etc/systemd/system/jenkins.service.d/override.conf file and the missing java options from the process (ps -efww|grep java)

:police_car: Expected behavior

The cookbook should create an /etc/systemd/system/jenkins.service.d/override.conf file to handle startup options for systemd.

ChrisPetr0 commented 2 years ago

Thanks this also affects the attribute jenkins_args. Same problem as above

ChrisPetr0 commented 2 years ago

Here's a recipe and template in my wrapper cookbook to get around this.... can pass other supoprted env vars too (env vars is a hash attribute)

jenkins_env = node['jenkins_configuration_wrapper']['jenkins_env']
jenkins_url = node['jenkins_configuration_wrapper']['jenkins_url']
jenkins_env_vars = node['jenkins_configuration_wrapper']['env_vars']

if jenkins_env == 'DEV'
  uri_path = jenkins_url.split('/')[-1]
  prefix = "Environment=\"JENKINS_PREFIX=/#{uri_path}\""
else
  prefix = ''
end

directory '/etc/systemd/system/jenkins.service.d/' do
  owner 'root'
  group 'root'
  mode '0755'
  action :create
end

template '/etc/systemd/system/jenkins.service.d/override.conf' do
  source 'jenkins_service_override.erb'
  owner 'root'
  group 'root'
  mode '0644'
  variables(prefix: prefix,
            env_vars: jenkins_env_vars)
end

service 'jenkins' do
  action :stop
end

bash 'reload systemctls' do
  code <<-RELOAD
    systemctl daemon-reload
  RELOAD
end

service 'jenkins' do
  action :start
end

template

[Service]

<%= @prefix %>

Environment="JAVA_OPTS=-Djava.awt.headless=true -Djenkins.install.runSetupWizard=false"

<% @env_vars.each do |name, value| %>
<%= "Environment=\"#{name}=#{value}\"" %>
<% end %>
dee-kryvenko commented 1 year ago

Here's more complete example ripped off line by line from https://github.com/sous-chefs/jenkins/blob/main/templates/jenkins-config-rhel.erb

[Service]

User=<%= node['jenkins']['master']['user'] %>
Environment=JENKINS_HOME="<%= node['jenkins']['master']['home'] %>"
Environment=JENKINS_JAVA_CMD="<%= node['jenkins']['java'] %>"
Environment=JENKINS_USER="<%= node['jenkins']['master']['user'] %>"
<% if node['jenkins']['master']['jvm_options'] %>
Environment=JENKINS_JAVA_OPTIONS="<%= node['jenkins']['master']['jvm_options'] %>"
<% end %>
Environment=JENKINS_PORT="<%= node['jenkins']['master']['port'] %>"
Environment=MAXOPENFILES=<%= node['jenkins']['master']['maxopenfiles'] %>
Environment=JENKINS_LISTEN_ADDRESS="<%= node['jenkins']['master']['listen_address'] %>"
Environment=JENKINS_HTTPS_PORT=""
Environment=JENKINS_HTTPS_LISTEN_ADDRESS=""
Environment=JENKINS_AJP_PORT="<%= node['jenkins']['master']['ajp_port'] %>"
Environment=JENKINS_AJP_LISTEN_ADDRESS=""
Environment=JENKINS_DEBUG_LEVEL="<%= node['jenkins']['master']['debug_level'] %>"
Environment=JENKINS_ENABLE_ACCESS_LOG="<%= node['jenkins']['master']['access_log'] %>"
Environment=JENKINS_HANDLER_MAX="<%= node['jenkins']['master']['handler_max'] %>"
Environment=JENKINS_HANDLER_IDLE="<%= node['jenkins']['master']['handler_idle'] %>"
<% if node['jenkins']['master']['jenkins_args'] %>
Environment=JENKINS_ARGS="$JENKINS_ARGS <%= node['jenkins']['master']['jenkins_args'] %>"
<% end %>
<% node['jenkins']['master']['extra_variables'].each do |name, value| -%>
Environment=<%= name %>="<%= value %>"
<% end -%>

It is sad nothing been done to this and other critical issues for almost a year. This cookbook basically is inoperable out of the box with latest Jenkins versions. Looks like everyone, including cookbook maintainers, already moved to Kubernetes? Or GitHub Actions? Or both?

dee-kryvenko commented 1 year ago

And of course that didn't worked, here's what did in the end:

[Service]

User=<%= node['jenkins']['master']['user'] %>
Group=<%= node['jenkins']['master']['group'] %>
WorkingDirectory=<%= node['jenkins']['master']['home'] %>
Environment="JENKINS_HOME=<%= node['jenkins']['master']['home'] %>"
Environment="JENKINS_JAVA_CMD=<%= node['jenkins']['java'] %>"
Environment="JENKINS_USER=<%= node['jenkins']['master']['user'] %>"
<% if node['jenkins']['master']['jvm_options'] %>
Environment="JAVA_OPTS=<%= node['jenkins']['master']['jvm_options'] %>"
<% end %>
Environment="JENKINS_PORT=<%= node['jenkins']['master']['port'] %>"
Environment="MAXOPENFILES=<%= node['jenkins']['master']['maxopenfiles'] %>"
Environment="JENKINS_LISTEN_ADDRESS=<%= node['jenkins']['master']['listen_address'] %>"
Environment="JENKINS_HTTPS_PORT="
Environment="JENKINS_HTTPS_LISTEN_ADDRESS="
Environment="JENKINS_AJP_PORT=<%= node['jenkins']['master']['ajp_port'] %>"
Environment="JENKINS_AJP_LISTEN_ADDRESS="
Environment="JENKINS_DEBUG_LEVEL=<%= node['jenkins']['master']['debug_level'] %>"
Environment="JENKINS_ENABLE_ACCESS_LOG=<%= node['jenkins']['master']['access_log'] %>"
Environment="JENKINS_HANDLER_MAX=<%= node['jenkins']['master']['handler_max'] %>"
Environment="JENKINS_HANDLER_IDLE=<%= node['jenkins']['master']['handler_idle'] %>"
<% if node['jenkins']['master']['jenkins_args'] %>
Environment="JENKINS_OPTS=<%= node['jenkins']['master']['jenkins_args'] %>"
<% end %>
<% node['jenkins']['master']['extra_variables'].each do |name, value| -%>
Environment="<%= name %>=<%= value %>"
<% end -%>
Environment="JENKINS_LOG=<%= node['jenkins']['master']['log_directory'] %>/jenkins.log"

Also, to better adhere to the jenkins cookbook from the wrapper, it can be done in this way:

# See https://github.com/sous-chefs/jenkins/issues/783
# create an empty resource if it does not exist yet
find_resource(:service, 'jenkins') do
  action :nothing
end
# create systemd folder if doesn't exists
directory '/etc/systemd/system/jenkins.service.d/' do
  owner 'root'
  group 'root'
  mode '0755'
  action :create
end
# create override file later used by jenkins cookbook
# See https://github.com/sous-chefs/jenkins/blob/main/templates/jenkins-config-rhel.erb
template '/etc/systemd/system/jenkins.service.d/override.conf' do
  source 'jenkins_service_override.erb'
  owner 'root'
  group 'root'
  mode '0644'
end
bash 'reload systemctls on jenkins systemd change' do
  code <<-RELOAD
    systemctl daemon-reload
  RELOAD
  action :nothing
  subscribes :run, 'template[/etc/systemd/system/jenkins.service.d/override.conf]', :immediately
end
# end of the workaround

# install jenkins
include_recipe 'jenkins::master'

# See https://github.com/sous-chefs/jenkins/issues/783
# Make the service resource to subscribe to systemd changes
find_resource(:service, 'jenkins') do
  subscribes :restart, 'template[/etc/systemd/system/jenkins.service.d/override.conf]', :immediately
end
# end of the workaround