Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

semi-delayed restart after plug-in installs #574

Open
chazzly opened this issue Mar 7, 2017 · 4 comments
Open

semi-delayed restart after plug-in installs #574

chazzly opened this issue Mar 7, 2017 · 4 comments

Comments

@chazzly
Copy link
Contributor

chazzly commented Mar 7, 2017

Cookbook version

4.2.1

Chef-client version

12.18.31

Platform Details

Oracle Linux Server release 7.2

Expected Result:

Install / update plug-ins, restart jenkins, continue chef run and and configuration.

This is more of a question than an issue. I'm hoping there's a better approach than what I'm doing. I have read through the documentation in this repo and a number of past/present issue, but I'm not seeing what I'm after. In my jenkins wrapper cookbook, I go through the list of plug-ins to be installed:

node['jenkins']['plug_ins'].each` do |p, ver|
  jenkins_plugin p do
     Chef::Log.info("installing #{p} plugin")
     version ver
     retries 1
     action :install
  end
end

In some cases, these plugins must be installed and active for later config changes to work, so jenkins needs to be restarted. I could, of course, add a notify to restart jenkins immediately, but that means jenkins would get restarted with each and every plug-in, which could be dozens, especially on initial install. So, I'm trying to use a global variable as a flag, a ruby block to update that flag if (and only if) any of the plug-ins are installed, then test for that flag and do an immediate service restart:

$updt = false

ruby_block 'plug-in updt' do
  block { $updt = true }
  action :nothing
end

node['jenkins']['plug_ins'].each do |p, ver|
  jenkins_plugin p do
     Chef::Log.info("installing #{p} plugin")
     version ver
     retries 1
     action :install
     notifies :run, 'ruby_block[plug-in updt]', :immediately
  end
end

ruby_block 'immediate restart' do
  block { puts 'restarting Jenkins....'}
  notifies :restart, 'service[jenkins]', :immediately
  only_if lazy { $updt }
end

the "only_if" for the restart ruby_block needs to be lazy because, the ruby_block to update $updt only fires after the notification during execution phase.

Unfortunately, it doesn't work.

The immediate restart block runs every chef run, even if no plug-ins are install / updated. I've tried digging in to it with my tests, but can't seem to accurately test/stub the lazy variable. Anyone know what I'm doing wrong? Any better way to go about this?

@StephenKing
Copy link
Contributor

Yes, this is really a bit annoying. You can find my way around it here, which is to write down all the plugin name/version combinations into a file on the Jenkins master and trigger a restart if that file changes.
Could be cleaner, if it would be wrapped by a resource that takes all the plugins+versions to install.

@chazzly
Copy link
Contributor Author

chazzly commented Mar 9, 2017

@StephenKing - Thanks that's a lot cleaner than what I was trying to do. Yeah, there almost needs to be a separate resource to handle all the plug-ins as a whole, then restart.

@ehaselwanter
Copy link

ehaselwanter commented Mar 16, 2017

I do it like so:

%w( simple-build-for-pipeline=0.2
    github-branch-source=2.0.4
    workflow-api=2.12
..... lllllllloooooong list of all my plugins ....
    token-macro=2.0
    pam-auth=1.3
    workflow-multibranch=2.14
).each do |plugin|
  plugin, version = plugin.split('=')
  jenkins_plugin plugin do
    version version if version
    install_deps false
    notifies :create, 'ruby_block[jenkins_restart_flag]', :immediately
  end
end

# Is notified only when a 'jenkins_plugin' is installed or updated.
ruby_block 'jenkins_restart_flag' do
  block do
    node.run_state['restart_required'] = true
  end
  action :nothing
end

jenkins_command 'restart' do
  only_if { node.run_state['restart_required'] }
end

@chazzly you never ever should use a global var. $updt ... you can use node.run_state to share values (https://docs.chef.io/recipes.html#node-run-state)
and it doe not need to be lazy because a guard (https://docs.chef.io/resource_common.html#guards) is executed during the execute phase

@grv87
Copy link
Contributor

grv87 commented Sep 6, 2017

@StephenKing, with your method of plugin installation, have you met the following situation?

After safe-restart converge is failed with

ERROR: Jenkins has not been started, or was already shut down

Either some waiting time is needed or safe-restart is not enough, and we have to restart the service.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

7 participants