├── .gitignore ├── .ruby-version ├── CHANGES.md ├── Gemfile ├── Gemfile.lock ├── README.md ├── chef.pluginspec ├── images └── layout.png ├── models └── chef-builder.rb └── views └── chef_builder ├── config.erb └── help.html /.gitignore: -------------------------------------------------------------------------------- 1 | work/ 2 | pkg/ 3 | 4 | -------------------------------------------------------------------------------- /.ruby-version: -------------------------------------------------------------------------------- 1 | jruby-1.7.20.1 2 | -------------------------------------------------------------------------------- /CHANGES.md: -------------------------------------------------------------------------------- 1 | # 0.1.7 2 | - [issue7](https://github.com/melezhik/chef-plugin/issues/7) - views/chef_builder/config.erb - workaround when instance method return nil, it happens when you create build_step 3 | 4 | # 0.1.6 5 | - fix for `dry_run, enabled settings get reset after jenkins restart' 6 | 7 | # 0.1.5 8 | - add -o 'StrictHostKeyChecking no' to ssh run 9 | - ship json data as file ( via scp ), so use file:// not http:// `resource' to avoid http related issues when run chef-client with -j parameter 10 | 11 | # 0.1.4 12 | - ssh identity path option 13 | - regenerated and impoved documentation 14 | - typo fixes 15 | 16 | 17 | # 0.1.3 18 | documentation changes, cleaning up README.md 19 | 20 | # 0.1.0 21 | chef client explicitly run chef client with `-l info` 22 | 23 | # 0.0.4 24 | - syntax error bugfix 25 | 26 | # 0.0.3 27 | - dry-run mode improved - real run of chef-client, but with --why-run flag 28 | 29 | # 0.0.2 30 | - dry-run mode added 31 | - replace publisher by builder 32 | - use simple_console 33 | - doc updated and imporved 34 | 35 | 36 | # 0.0.1 37 | - first release version 38 | -------------------------------------------------------------------------------- /Gemfile: -------------------------------------------------------------------------------- 1 | source 'https://rubygems.org' 2 | gem "jenkins-plugin-runtime" 3 | gem "json" 4 | gem "simple_console", :git => "git://github.com/melezhik/simple_console.git" 5 | -------------------------------------------------------------------------------- /Gemfile.lock: -------------------------------------------------------------------------------- 1 | GIT 2 | remote: git://github.com/melezhik/simple_console.git 3 | revision: 553fc2d6b630092c15bf384dd4d8de3ef16482dd 4 | specs: 5 | simple_console (0.0.1) 6 | logger 7 | term-ansicolor 8 | 9 | GEM 10 | remote: https://rubygems.org/ 11 | specs: 12 | jenkins-plugin-runtime (0.2.3) 13 | json 14 | slop (~> 3.0.2) 15 | json (1.7.7) 16 | json (1.7.7-java) 17 | logger (1.2.8) 18 | slop (3.0.4) 19 | term-ansicolor (1.1.1) 20 | 21 | PLATFORMS 22 | java 23 | ruby 24 | 25 | DEPENDENCIES 26 | jenkins-plugin-runtime 27 | json 28 | simple_console! 29 | 30 | BUNDLED WITH 31 | 1.10.4 32 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # SYNOPSIS 2 | 3 | This is jenkins plugin to run chef-client on remote host. 4 | Plugin starts ssh session on remote host using public key authentication and run chef-client there. 5 | 6 | 7 | # Plugin general settings 8 | 9 | - host - Specifies remote host to run chef client on. 10 | - login - Specifies the user to log in as on the remote machine. 11 | 12 | # Plugin advanced settings 13 | 14 | - ssh\_indetity\_file - Specifies a path to file from which the identity (private key) for public key authentication is read. 15 | - chef\_client\_config - Specifies a path to file ( on remote host ) from which chef client configuration is read, default values is /etc/chef/client.rb 16 | - chef\_json\_template - Specifies chef attributes and run-list ( see chef documentation ). 17 | - dry\_run - Use to run chef client in why-run mode, which is a type of chef-client run that does everything except modify the system, default value is false. 18 | 19 | # User interface 20 | 21 | ![layout](https://raw.github.com/melezhik/chef-plugin/master/images/layout.png "layout") 22 | 23 | # Chef attributes and run list settings 24 | 25 | - Use chef\_json\_template to define chef attributes and run list. 26 | If you define one, plugin will parse chef_json_template data and stored result in file which in turn will passed as -j parameter into chef-client run. 27 | 28 | - Please check out [chef wiki](http://wiki.opscode.com/display/chef/Setting+the+run_list+in+JSON+during+run+time) to learn more about chef json files. 29 | 30 | - Chef\_json\_template confirms [ERB](http://www.stuartellis.eu/articles/erb/) template syntax. Here is example of chef\_json\_template: 31 | 32 | <% 33 | runlist = %w{apache::server mysql} 34 | chef_json = { 35 | :run_list => runlist.map { |r| "recipe[#{r}]" } , 36 | :apache => { 37 | :version => 80 38 | } 39 | } 40 | %> 41 | <%= chef_json.to_json.to_s %> 42 | 43 | # Prerequisites 44 | - ruby-runtime jenkins plugin 45 | - ssh client 46 | 47 | 48 | # Environment variables 49 | 50 | You can set some environment variables qith "Jenkins/Configuration/Global properties/Environment variables" . Here the list of varibales to be processed in the plugin: 51 | 52 | - LC\_ALL # sets encoding to avoid chef log issues 53 | 54 | # Latest stable version 55 | 56 | [0.1.7](http://maven.jenkins-ci.org/content/repositories/releases/org/jenkins-ci/ruby-plugins/chef/0.1.7) 57 | 58 | -------------------------------------------------------------------------------- /chef.pluginspec: -------------------------------------------------------------------------------- 1 | Jenkins::Plugin::Specification.new do |plugin| 2 | plugin.name = "chef" 3 | plugin.display_name = "Chef Plugin" 4 | plugin.version = '0.1.7' 5 | plugin.description = 'run chef-client remotely under Jenkins CI' 6 | 7 | # You should create a wiki-page for your plugin when you publish it, see 8 | plugin.url = 'https://github.com/melezhik/chef-plugin' 9 | 10 | # The first argument is your user name for jenkins-ci.org. 11 | plugin.developed_by "melezhik", "Alexey Melezhik " 12 | 13 | # This specifies where your code is hosted. 14 | plugin.uses_repository :github => "jenkinsci/chef-plugin" 15 | 16 | # This is a required dependency for every ruby plugin. 17 | plugin.depends_on 'ruby-runtime', '0.12' 18 | 19 | # This is a sample dependency for a Jenkins plugin, 'git'. 20 | #plugin.depends_on 'git', '1.1.11' 21 | end 22 | 23 | -------------------------------------------------------------------------------- /images/layout.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/melezhik/chef-plugin/e4d2ef8a3a8ca33fd289fac8d83445804eed1008/images/layout.png -------------------------------------------------------------------------------- /models/chef-builder.rb: -------------------------------------------------------------------------------- 1 | require 'erb' 2 | require 'json' 3 | require 'simple/console' 4 | 5 | class ChefBuilder < Jenkins::Tasks::Builder 6 | 7 | attr_accessor :enabled, :dry_run, :chef_json_template, :color_output 8 | attr_accessor :ssh_host, :ssh_login, :ssh_identity_path, :chef_client_config 9 | attr_accessor :enabled_int, :dry_run_int, :color_output_int 10 | 11 | display_name "Run chef client on remote host" 12 | 13 | def initialize(attrs = {}) 14 | @enabled = attrs["enabled"] 15 | @dry_run = attrs["dry_run"] 16 | @chef_json_template = attrs["chef_json_template"] 17 | @ssh_host = attrs["ssh_host"] 18 | @ssh_login = attrs["ssh_login"] 19 | @chef_client_config = attrs["chef_client_config"] 20 | @color_output = attrs['color_output'] 21 | @ssh_identity_path = attrs['ssh_identity_path'] 22 | @dry_run_int = @dry_run == true ? 1 : 0 23 | @enabled_int = @enabled == true ? 1 : 0 24 | @color_output_int = @color_output_int == true ? 1 : 0 25 | end 26 | 27 | def prebuild(build, listener) 28 | end 29 | 30 | 31 | def perform(build, launcher, listener) 32 | 33 | 34 | if @enabled == true 35 | @sc = Simple::Console.new(:color_output => @color_output) 36 | 37 | # generate chef json file 38 | 39 | 40 | env = build.native.getEnvironment() 41 | job = build.send(:native).get_project.name 42 | workspace = build.send(:native).workspace.to_s 43 | 44 | listener.info @sc.info('rendering ERB template') 45 | 46 | renderer = ERB.new(@chef_json_template) 47 | json_str = renderer.result 48 | json_str.sub! '"{','{' 49 | json_str.sub! '}"','}' 50 | 51 | listener.info @sc.info('parsing JSON string') 52 | 53 | JSON.parse(json_str) 54 | 55 | listener.info @sc.info('saving JSON to file') 56 | 57 | File.open("#{workspace}/chef.json", 'w') {|f| f.write(JSON.pretty_generate(JSON.parse(json_str))) } 58 | 59 | why_run_flag = '' 60 | if @dry_run == true 61 | listener.info @sc.info('dry run mode is ON, so will run chef-client with --why-run flag') 62 | why_run_flag = '--why-run' 63 | end 64 | 65 | chef_color_flag = '' 66 | if @color_output == true 67 | chef_color_flag = '--color' 68 | end 69 | 70 | listener.info @sc.info(@ssh_host, :title => 'host') 71 | config_path = '' 72 | config_path = " -c #{@chef_client_config}" unless (@chef_client_config.nil? || @chef_client_config.empty?) 73 | 74 | ssh_command = "ssh -o 'StrictHostKeyChecking no'" 75 | scp_command = "scp -o 'StrictHostKeyChecking no'" 76 | 77 | unless ( @ssh_identity_path.nil? || @ssh_identity_path.empty? ) 78 | ssh_command << " -i #{@ssh_identity_path}" 79 | scp_command << " -i #{@ssh_identity_path}" 80 | end 81 | 82 | cmd = [] 83 | cmd << "export LC_ALL=#{env['LC_ALL']}" unless ( env['LC_ALL'].nil? || env['LC_ALL'].empty? ) 84 | cmd << "#{scp_command} #{workspace}/chef.json #{@ssh_login}@#{@ssh_host}:/tmp/#{job}-by-#{@ssh_login}-chef.json" 85 | build.abort unless launcher.execute("bash", "-c", cmd.join(' && '), { :out => listener } ) == 0 86 | 87 | 88 | cmd = [] 89 | cmd << "export LC_ALL=#{env['LC_ALL']}" unless ( env['LC_ALL'].nil? || env['LC_ALL'].empty? ) 90 | 91 | cmd << "#{ssh_command} #{@ssh_login}@#{@ssh_host} 'sudo chef-client --force-formatter -l info -j /tmp/#{job}-by-#{@ssh_login}-chef.json #{config_path} #{why_run_flag} #{chef_color_flag}'" 92 | build.abort unless launcher.execute("bash", "-c", cmd.join(' && '), { :out => listener } ) == 0 93 | 94 | 95 | end 96 | 97 | 98 | end 99 | 100 | end 101 | 102 | 103 | -------------------------------------------------------------------------------- /views/chef_builder/config.erb: -------------------------------------------------------------------------------- 1 | <% 2 | f = taglib("/lib/form") 3 | 4 | f.entry(:title => 'enabled', :field => 'enabled', :description => "enable/disable plugin #{@enabled_int}" ) do 5 | if instance.nil? 6 | f.checkbox :checked => true 7 | else 8 | f.checkbox :checked => ( instance.get('enabled_int').nil? or instance.get('enabled_int') == 1 ) 9 | end 10 | end 11 | 12 | 13 | f.entry(:title => 'dry run', :field => 'dry_run', :description => "run in dry run mode" ) do 14 | if instance.nil? 15 | f.checkbox :checked => false 16 | else 17 | f.checkbox :checked => instance.get('dry_run_int') == 1 18 | end 19 | end 20 | f.entry(:title => 'ssh host', :field => 'ssh_host', :description => "remote host") do 21 | f.textbox 22 | end 23 | f.entry(:title => 'ssh login', :field => 'ssh_login', :description => "ssh login") do 24 | f.textbox 25 | end 26 | f.entry(:title => 'chef json template', :field => 'chef_json_template', :description => "chef attributes and run-list") do 27 | f.textarea 28 | end 29 | 30 | f.advanced do 31 | 32 | f.entry(:title => 'ssh identity path path', :field => 'ssh_identity_path', :description => "path to file from which the identity (private key) for public key authentication is read") do 33 | f.textbox 34 | end 35 | 36 | f.entry(:title => 'chef client config', :field => 'chef_client_config', :description => "path to chef client configuration file") do 37 | f.textbox 38 | end 39 | 40 | f.entry(:title => 'color output', :field => 'color_output', :description => "enable/disable color output") do 41 | if instance.nil? 42 | f.checkbox :checked => false 43 | else 44 | f.checkbox :checked => instance.get('color_output_int') == 1 45 | end 46 | end 47 | 48 | 49 | end 50 | 51 | %> 52 | -------------------------------------------------------------------------------- /views/chef_builder/help.html: -------------------------------------------------------------------------------- 1 |

SYNOPSIS

2 | 3 |

This is jenkins plugin to run chef-client on remote host. 4 | Plugin starts ssh session on remote host using public key authentication and chef-client there.

5 | 6 |

Plugin general settings

7 | 8 | 12 | 13 |

Plugin advanced settings

14 | 15 | 21 | 22 |

User interface

23 | 24 |

layout

25 | 26 |

Chef attributes and run list settings

27 | 28 | 46 | 47 |

Prerequisites

48 | 49 | 53 | 54 |

Environment variables

55 | 56 |

You can set some environment variables qith "Jenkins/Configuration/Global properties/Environment variables" . Here the list of varibales to be processed in the plugin:

57 | 58 | 61 | 62 |

Download latest version

63 | 64 |

[http://repo.jenkins-ci.org/releases/org/jenkins-ci/ruby-plugins/chef/0.1.4/]

65 | --------------------------------------------------------------------------------