From dde35c2ece75878409065746a77df242810defee Mon Sep 17 00:00:00 2001 From: "Eric G. Wolfe" Date: Fri, 25 May 2012 18:11:16 -0400 Subject: [PATCH 1/9] ## v0.7.0 * General clean up, per Foodcritic compliance * Fix several minor platform bugs on RedHat/CentOS * Change service assumptions regarding Redhat/Centos * Added several missing dependencies * Fenced off debian/ubuntu specific cases in case switches * Changed sshkey generation to use pure Ruby via gem, instead of execute. * Made basic auth optional in proxy_apache2, as Jenkins comes with several of its own auth plugins --- CHANGELOG.md | 9 ++ README.md | 89 +++++++------- attributes/default.rb | 114 +++++++++--------- attributes/proxy_apache2.rb | 22 ++++ attributes/proxy_nginx.rb | 21 ++++ libraries/manage_node.rb | 80 ++++++------- metadata.rb | 4 +- providers/cli.rb | 9 +- providers/execute.rb | 19 +-- providers/job.rb | 19 +-- providers/node.rb | 2 +- recipes/default.rb | 139 +++++++++++----------- recipes/iptables.rb | 4 +- recipes/node_jnlp.rb | 36 +++--- recipes/node_ssh.rb | 72 +++++------ recipes/node_windows.rb | 24 ++-- recipes/proxy_apache2.rb | 25 ++-- recipes/proxy_nginx.rb | 16 +-- resources/job.rb | 2 +- templates/default/apache_jenkins.erb | 8 +- templates/default/id_rsa.erb | 1 + templates/default/id_rsa.pub.erb | 1 + templates/default/jenkins.erb | 10 +- templates/default/nginx_jenkins.conf.erb | 8 +- templates/default/port_jenkins.erb | 2 +- templates/default/sv-hudson-slave-run.erb | 8 +- 26 files changed, 411 insertions(+), 333 deletions(-) create mode 100644 CHANGELOG.md create mode 100644 attributes/proxy_apache2.rb create mode 100644 attributes/proxy_nginx.rb create mode 100644 templates/default/id_rsa.erb create mode 100644 templates/default/id_rsa.pub.erb diff --git a/CHANGELOG.md b/CHANGELOG.md new file mode 100644 index 0000000..8965281 --- /dev/null +++ b/CHANGELOG.md @@ -0,0 +1,9 @@ +## v0.7.0 + +* General clean up, per Foodcritic compliance +* Fix several minor platform bugs on RedHat/CentOS +* Change service assumptions regarding Redhat/Centos +* Added several missing dependencies +* Fenced off debian/ubuntu specific cases in case switches +* Changed sshkey generation to use pure Ruby via gem, instead of execute. +* Made basic auth optional in proxy_apache2, as Jenkins comes with several of its own auth plugins diff --git a/README.md b/README.md index e75eb3b..58f0833 100644 --- a/README.md +++ b/README.md @@ -37,44 +37,47 @@ If your Jenkins instance requires authentication, you'll either need to embed us Where the jenkins_login recipe is simply: - jenkins_cli "login --username #{node[:jenkins][:username]} --password #{node[:jenkins][:password]}" + jenkins_cli "login --username #{node['jenkins']['username']} --password #{node['jenkins']['password']}" Attributes ========== -* jenkins[:mirror] - Base URL for downloading Jenkins (server) -* jenkins[:java_home] - Java install path, used for for cli commands -* jenkins[:server][:home] - JENKINS_HOME directory -* jenkins[:server][:user] - User the Jenkins server runs as -* jenkins[:server][:group] - Jenkins user primary group -* jenkins[:server][:port] - TCP listen port for the Jenkins server -* jenkins[:server][:url] - Base URL of the Jenkins server -* jenkins[:server][:plugins] - Download the latest version of plugins in this list, bypassing update center -* jenkins[:node][:name] - Name of the node within Jenkins -* jenkins[:node][:description] - Jenkins node description -* jenkins[:node][:executors] - Number of node executors -* jenkins[:node][:home] - Home directory ("Remote FS root") of the node -* jenkins[:node][:labels] - Node labels -* jenkins[:node][:mode] - Node usage mode, "normal" or "exclusive" (tied jobs only) -* jenkins[:node][:launcher] - Node launch method, "jnlp", "ssh" or "command" -* jenkins[:node][:availability] - "always" keeps node on-line, "demand" off-lines when idle -* jenkins[:node][:in_demand_delay] - number of minutes for which jobs must be waiting in the queue before attempting to launch this slave. -* jenkins[:node][:idle_delay] - number of minutes that this slave must remain idle before taking it off-line. -* jenkins[:node][:env] - "Node Properties" -> "Environment Variables" -* jenkins[:node][:user] - user the slave runs as -* jenkins[:node][:ssh_host] - Hostname or IP Jenkins should connect to when launching an SSH slave -* jenkins[:node][:ssh_port] - SSH slave port -* jenkins[:node][:ssh_user] - SSH slave user name (only required if jenkins server and slave user is different) -* jenkins[:node][:ssh_pass] - SSH slave password (not required when server is installed via default recipe) -* jenkins[:node][:ssh_private_key] - jenkins master defaults to: `~/.ssh/id_rsa` (created by the default recipe) -* jenkins[:node][:jvm_options] - SSH slave JVM options -* jenkins[:iptables_allow] - if iptables is enabled, add a rule passing 'jenkins[:server][:port]' -* jenkins[:nginx][:http_proxy][:variant] - use `nginx` or `apache2` to proxy traffic to jenkins backend (`nil` by default) -* jenkins[:http_proxy][:www_redirect] - add a redirect rule for 'www.*' URL requests ("disable" by default) -* jenkins[:http_proxy][:listen_ports] - list of HTTP ports for the HTTP proxy to listen on ([80] by default) -* jenkins[:http_proxy][:host_name] - primary vhost name for the HTTP proxy to respond to (`node[:fqdn]` by default) -* jenkins[:http_proxy][:host_aliases] - optional list of other host aliases to respond to (empty by default) -* jenkins[:http_proxy][:client_max_body_size] - max client upload size ("1024m" by default, nginx only) +* jenkins['mirror'] - Base URL for downloading Jenkins (server) +* jenkins['java_home'] - Java install path, used for for cli commands +* jenkins['server']['home'] - JENKINS_HOME directory +* jenkins['server']['user'] - User the Jenkins server runs as +* jenkins['server']['group'] - Jenkins user primary group +* jenkins['server']['port'] - TCP listen port for the Jenkins server +* jenkins['server']['url'] - Base URL of the Jenkins server +* jenkins['server']['plugins'] - Download the latest version of plugins in this list, bypassing update center +* jenkins['node']['name'] - Name of the node within Jenkins +* jenkins['node']['description'] - Jenkins node description +* jenkins['node']['executors'] - Number of node executors +* jenkins['node']['home'] - Home directory ("Remote FS root") of the node +* jenkins['node']['labels'] - Node labels +* jenkins['node']['mode'] - Node usage mode, "normal" or "exclusive" (tied jobs only) +* jenkins['node']['launcher'] - Node launch method, "jnlp", "ssh" or "command" +* jenkins['node']['availability'] - "always" keeps node on-line, "demand" off-lines when idle +* jenkins['node']['in_demand_delay'] - number of minutes for which jobs must be waiting in the queue before attempting to launch this slave. +* jenkins['node']['idle_delay'] - number of minutes that this slave must remain idle before taking it off-line. +* jenkins['node']['env'] - "Node Properties" -> "Environment Variables" +* jenkins['node']['user'] - user the slave runs as +* jenkins['node']['ssh_host'] - Hostname or IP Jenkins should connect to when launching an SSH slave +* jenkins['node']['ssh_port'] - SSH slave port +* jenkins['node']['ssh_user'] - SSH slave user name (only required if jenkins server and slave user is different) +* jenkins['node']['ssh_pass'] - SSH slave password (not required when server is installed via default recipe) +* jenkins['node']['ssh_private_key'] - jenkins master defaults to: `~/.ssh/id_rsa` (created by the default recipe) +* jenkins['node']['jvm_options'] - SSH slave JVM options +* jenkins['iptables_allow'] - if iptables is enabled, add a rule passing 'jenkins['server']['port']' +* jenkins['nginx']['http_proxy']['variant'] - use `nginx` or `apache2` to proxy traffic to jenkins backend (`nil` by default) +* jenkins['http_proxy']['www_redirect'] - add a redirect rule for 'www.*' URL requests ("disable" by default) +* jenkins['http_proxy']['listen_ports'] - list of HTTP ports for the HTTP proxy to listen on ([80] by default) +* jenkins['http_proxy']['host_name'] - primary vhost name for the HTTP proxy to respond to (`node['fqdn']` by default) +* jenkins['http_proxy']['host_aliases'] - optional list of other host aliases to respond to (empty by default) +* jenkins['http_proxy']['client_max_body_size'] - max client upload size ("1024m" by default, nginx only) +* jenkins['http_proxy']['basic_auth'] - boolean, whether basic auth gets enabled in proxy_apache2 or not. (default true) +* jenkins['http_proxy']['basic_auth_username'] - used in the proxy_apache2 recipe, (default jenkins) +* jenkins['http_proxy']['basic_auth_password'] - used in the proxy_apache2 recipe, (defualt jenkins) Usage ===== @@ -82,12 +85,12 @@ Usage 'default' recipe ---------------- -Installs a Jenkins CI server using the http://jenkins-ci.org/redhat RPM. The recipe also generates an ssh private key and stores the ssh public key in the node 'jenkins[:pubkey]' attribute for use by the node recipes. +Installs a Jenkins CI server using the http://jenkins-ci.org/redhat RPM. The recipe also generates an ssh private key and stores the ssh public key in the node 'jenkins['pubkey']' attribute for use by the node recipes. 'node_ssh' recipe ----------------- -Creates the user and group for the Jenkins slave to run as and sets `.ssh/authorized_keys` to the 'jenkins[:pubkey]' attribute. The 'jenkins-cli.jar'[1] is downloaded from the Jenkins server and used to manage the nodes via the 'groovy'[2] cli command. Jenkins is configured to launch a slave agent on the node using its SSH slave plugin[3]. +Creates the user and group for the Jenkins slave to run as and sets `.ssh/authorized_keys` to the 'jenkins['pubkey']' attribute. The 'jenkins-cli.jar'[1] is downloaded from the Jenkins server and used to manage the nodes via the 'groovy'[2] cli command. Jenkins is configured to launch a slave agent on the node using its SSH slave plugin[3]. [1] http://wiki.jenkins-ci.org/display/JENKINS/Jenkins+CLI [2] http://wiki.jenkins-ci.org/display/JENKINS/Jenkins+Script+Console @@ -110,12 +113,12 @@ Creates the home directory for the node slave and sets 'JENKINS_HOME' and 'JENKI 'proxy_nginx' recipe -------------------- -Uses the nginx::source recipe from the nginx cookbook to install an HTTP frontend proxy. To automatically activate this recipe set the `node[:jenkins][:http_proxy][:variant]` to `nginx`. +Uses the nginx::source recipe from the nginx cookbook to install an HTTP frontend proxy. To automatically activate this recipe set the `node['jenkins']['http_proxy']['variant']` to `nginx`. 'proxy_apache2' recipe ---------------------- -Uses the apache2 recipe from the apache2 cookbook to install an HTTP frontend proxy. To automatically activate this recipe set the `node[:jenkins][:http_proxy][:variant]` to `apache2`. +Uses the apache2 recipe from the apache2 cookbook to install an HTTP frontend proxy. To automatically activate this recipe set the `node['jenkins']['http_proxy']['variant']` to `apache2`. 'jenkins_cli' resource provider ------------------------------- @@ -132,12 +135,12 @@ This resource can be used to execute the Jenkins cli from your recipes. For exa This resource can be used to configure nodes as the 'node_ssh' and 'node_windows' recipes do or "Launch slave via execution of command on the Master". - jenkins_node node[:fqdn] do + jenkins_node node['fqdn'] do description "My node for things, stuff and whatnot" executors 5 remote_fs "/var/jenkins" launcher "command" - command "ssh -i my_key #{node[:fqdn]} java -jar #{remote_fs}/slave.jar" + command "ssh -i my_key #{node['fqdn']} java -jar #{remote_fs}/slave.jar" env "ANT_HOME" => "/usr/local/ant", "M2_REPO" => "/dev/null" end @@ -151,9 +154,9 @@ This resource manages jenkins jobs, supporting the following actions: The 'create' and 'update' actions require a jenkins job config.xml. Example: git_branch = 'master' - job_name = "sigar-#{branch}-#{node[:os]}-#{node[:kernel][:machine]}" + job_name = "sigar-#{branch}-#{node['os']}-#{node['kernel']['machine']}" - job_config = File.join(node[:jenkins][:node][:home], "#{job_name}-config.xml") + job_config = File.join(node['jenkins']['node']['home'], "#{job_name}-config.xml") jenkins_job job_name do action :nothing @@ -162,7 +165,7 @@ The 'create' and 'update' actions require a jenkins job config.xml. Example: template job_config do source "sigar-jenkins-config.xml" - variables :job_name => job_name, :branch => git_branch, :node => node[:fqdn] + variables :job_name => job_name, :branch => git_branch, :node => node['fqdn'] notifies :update, resources(:jenkins_job => job_name), :immediately notifies :build, resources(:jenkins_job => job_name), :immediately end diff --git a/attributes/default.rb b/attributes/default.rb index 42caf88..325eb82 100644 --- a/attributes/default.rb +++ b/attributes/default.rb @@ -21,105 +21,113 @@ # limitations under the License. # -default[:jenkins][:mirror] = "http://mirrors.jenkins-ci.org" -default[:jenkins][:package_url] = "http://pkg.jenkins-ci.org" -default[:jenkins][:java_home] = ENV['JAVA_HOME'] - -default[:jenkins][:server][:home] = "/var/lib/jenkins" -default[:jenkins][:server][:user] = "jenkins" - -case node[:platform] -when "debian", "ubuntu" - default[:jenkins][:server][:group] = "nogroup" +default['jenkins']['mirror'] = "http://mirrors.jenkins-ci.org" +default['jenkins']['package_url'] = "http://pkg.jenkins-ci.org" +default['jenkins']['java_home'] = ENV['JAVA_HOME'] + +default['jenkins']['server']['home'] = "/var/lib/jenkins" +default['jenkins']['server']['user'] = "jenkins" + +case node['platform'] +when "debian", "ubuntu" + default['jenkins']['server']['group'] = "nogroup" + default['jenkins']['install_starts_service'] = true + default['jenkins']['pid_file'] = "/var/run/jenkins/jenkins.pid" +when "redhat", "centos", "scientific", "amazon" + default['jenkins']['install_starts_service'] = true + default['jenkins']['server']['group'] = node['jenkins']['server']['user'] + default['jenkins']['pid_file'] = "/var/run/jenkins.pid" else - default[:jenkins][:server][:group] = node[:jenkins][:server][:user] + default['jenkins']['install_starts_service'] = false + default['jenkins']['server']['group'] = node['jenkins']['server']['user'] end -default[:jenkins][:server][:port] = 8080 -default[:jenkins][:server][:host] = node[:fqdn] -default[:jenkins][:server][:url] = "http://#{node[:jenkins][:server][:host]}:#{node[:jenkins][:server][:port]}" +default['jenkins']['server']['port'] = 8080 +default['jenkins']['server']['host'] = node['fqdn'] +default['jenkins']['server']['url'] = "http://#{node['jenkins']['server']['host']}:#{node['jenkins']['server']['port']}" -default[:jenkins][:iptables_allow] = "disable" +default['jenkins']['iptables_allow'] = "disable" #download the latest version of plugins, bypassing update center #example: ["git", "URLSCM", ...] -default[:jenkins][:server][:plugins] = [] +default['jenkins']['server']['plugins'] = [] #working around: http://tickets.opscode.com/browse/CHEF-1848 #set to true if you have the CHEF-1848 patch applied -default[:jenkins][:server][:use_head] = false +default['jenkins']['server']['use_head'] = false #See Jenkins >> Nodes >> $name >> Configure #"Name" -default[:jenkins][:node][:name] = node[:fqdn] +default['jenkins']['node']['name'] = node['fqdn'] #"Description" -default[:jenkins][:node][:description] = - "#{node[:platform]} #{node[:platform_version]} " << - "[#{node[:kernel][:os]} #{node[:kernel][:release]} #{node[:kernel][:machine]}] " << - "slave on #{node[:hostname]}" +default['jenkins']['node']['description'] = + "#{node['platform']} #{node['platform_version']} " << + "[#{node['kernel']['os']} #{node['kernel']['release']} #{node['kernel']['machine']}] " << + "slave on #{node['hostname']}" #"# of executors" -default[:jenkins][:node][:executors] = 1 +default['jenkins']['node']['executors'] = 1 #"Remote FS root" -if node[:os] == "windows" - default[:jenkins][:node][:home] = "C:/jenkins" -elsif node[:os] == "darwin" - default[:jenkins][:node][:home] = "/Users/jenkins" +if node['os'] == "windows" + default['jenkins']['node']['home'] = "C:/jenkins" +elsif node['os'] == "darwin" + default['jenkins']['node']['home'] = "/Users/jenkins" else - default[:jenkins][:node][:home] = "/home/jenkins" + default['jenkins']['node']['home'] = "/home/jenkins" end #"Labels" -default[:jenkins][:node][:labels] = (node[:tags] || []).join(" ") +default['jenkins']['node']['labels'] = (node['tags'] || []).join(" ") #"Usage" # "Utilize this slave as much as possible" -> "normal" # "Leave this machine for tied jobs only" -> "exclusive" -default[:jenkins][:node][:mode] = "normal" +default['jenkins']['node']['mode'] = "normal" #"Launch method" # "Launch slave agents via JNLP" -> "jnlp" # "Launch slave via execution of command on the Master" -> "command" # "Launch slave agents on Unix machines via SSH" -> "ssh" -if node[:os] == "windows" - default[:jenkins][:node][:launcher] = "jnlp" +if node['os'] == "windows" + default['jenkins']['node']['launcher'] = "jnlp" else - default[:jenkins][:node][:launcher] = "ssh" + default['jenkins']['node']['launcher'] = "ssh" end #"Availability" # "Keep this slave on-line as much as possible" -> "always" # "Take this slave on-line when in demand and off-line when idle" -> "demand" -default[:jenkins][:node][:availability] = "always" +default['jenkins']['node']['availability'] = "always" # "In demand delay" -default[:jenkins][:node][:in_demand_delay] = 0 +default['jenkins']['node']['in_demand_delay'] = 0 # "Idle delay" -default[:jenkins][:node][:idle_delay] = 1 +default['jenkins']['node']['idle_delay'] = 1 #"Node Properties" #[x] "Environment Variables" -default[:jenkins][:node][:env] = nil +default['jenkins']['node']['env'] = nil -default[:jenkins][:node][:user] = "jenkins-node" +default['jenkins']['node']['user'] = "jenkins-node" #SSH options -default[:jenkins][:node][:ssh_host] = node[:fqdn] -default[:jenkins][:node][:ssh_port] = 22 -default[:jenkins][:node][:ssh_user] = default[:jenkins][:node][:user] -default[:jenkins][:node][:ssh_pass] = nil -default[:jenkins][:node][:jvm_options] = nil +default['jenkins']['node']['ssh_host'] = node['fqdn'] +default['jenkins']['node']['ssh_port'] = 22 +default['jenkins']['node']['ssh_user'] = default['jenkins']['node']['user'] +default['jenkins']['node']['ssh_pass'] = nil +default['jenkins']['node']['jvm_options'] = nil #jenkins master defaults to: "#{ENV['HOME']}/.ssh/id_rsa" -default[:jenkins][:node][:ssh_private_key] = nil - -default[:jenkins][:http_proxy][:variant] = nil -default[:jenkins][:http_proxy][:www_redirect] = "disable" -default[:jenkins][:http_proxy][:listen_ports] = [ 80 ] -default[:jenkins][:http_proxy][:host_name] = nil -default[:jenkins][:http_proxy][:host_aliases] = [] -default[:jenkins][:http_proxy][:client_max_body_size] = "1024m" -default[:jenkins][:http_proxy][:basic_auth_username] = "jenkins" -default[:jenkins][:http_proxy][:basic_auth_password] = "jenkins" +default['jenkins']['node']['ssh_private_key'] = nil + +default['jenkins']['http_proxy']['variant'] = nil +default['jenkins']['http_proxy']['www_redirect'] = "disable" +default['jenkins']['http_proxy']['listen_ports'] = [ 80 ] +default['jenkins']['http_proxy']['host_name'] = nil +default['jenkins']['http_proxy']['host_aliases'] = [] +default['jenkins']['http_proxy']['client_max_body_size'] = "1024m" +default['jenkins']['http_proxy']['basic_auth'] = true +default['jenkins']['http_proxy']['basic_auth_username'] = "jenkins" +default['jenkins']['http_proxy']['basic_auth_password'] = "jenkins" diff --git a/attributes/proxy_apache2.rb b/attributes/proxy_apache2.rb new file mode 100644 index 0000000..5f6dcd4 --- /dev/null +++ b/attributes/proxy_apache2.rb @@ -0,0 +1,22 @@ +# +# Cookbook Name:: jenkins +# Attirbutes:: proxy_apache2 +# +# Author:: Fletcher Nichol +# +# Copyright 2011, Fletcher Nichol +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# + +include_attribute "apache2" diff --git a/attributes/proxy_nginx.rb b/attributes/proxy_nginx.rb new file mode 100644 index 0000000..e0f4291 --- /dev/null +++ b/attributes/proxy_nginx.rb @@ -0,0 +1,21 @@ +# +# Cookbook Name:: jenkins +# Attributes:: proxy_nginx +# +# Author:: Fletcher Nichol +# +# Copyright 2011, Fletcher Nichol +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +include_attribute "nginx" diff --git a/libraries/manage_node.rb b/libraries/manage_node.rb index 859b015..6a16469 100644 --- a/libraries/manage_node.rb +++ b/libraries/manage_node.rb @@ -22,35 +22,35 @@ # def jenkins_node_defaults(args) - args[:name] ||= nil #required - args[:description] ||= "" - args[:remote_fs] ||= nil #required - args[:executors] ||= 1 - args[:mode] ||= "NORMAL" #"NORMAL" or "EXCLUSIVE" - args[:labels] ||= "" - args[:launcher] ||= "jnlp" #"jnlp" or "command" or "ssh" - args[:availability] ||= "Always" #"Always" or "Demand" - args[:env] = args[:env] ? args[:env].to_hash : nil - args[:mode].upcase! - args[:availability].capitalize! - - if args[:availability] == "Demand" - args[:in_demand_delay] ||= 0 - args[:idle_delay] ||= 1 + args['name'] ||= nil #required + args['description'] ||= "" + args['remote_fs'] ||= nil #required + args['executors'] ||= 1 + args['mode'] ||= "NORMAL" #"NORMAL" or "EXCLUSIVE" + args['labels'] ||= "" + args['launcher'] ||= "jnlp" #"jnlp" or "command" or "ssh" + args['availability'] ||= "Always" #"Always" or "Demand" + args['env'] = args['env'] ? args['env'].to_hash : nil + args['mode'].upcase! + args['availability'].capitalize! + + if args['availability'] == "Demand" + args['in_demand_delay'] ||= 0 + args['idle_delay'] ||= 1 end - case args[:launcher] + case args['launcher'] when "jnlp" when "command" - args[:command] ||= "" + args['command'] ||= "" when "ssh" - args[:host] ||= args[:name] - args[:port] ||= 22 - args[:username] ||= "" - args[:private_key] ||= "" - args[:jvm_options] ||= "" - args[:host_dsa_public] ||= nil - args[:host_rsa_public] ||= nil + args['host'] ||= args['name'] + args['port'] ||= 22 + args['username'] ||= "" + args['private_key'] ||= "" + args['jvm_options'] ||= "" + args['host_dsa_public'] ||= nil + args['host_rsa_public'] ||= nil end args @@ -67,11 +67,11 @@ def jenkins_node_compare(current_node, new_node) default.keys.each do |key| val = new_node[key] || default[key] if !val.nil? && current_node[key.to_s] != val - Chef::Log::debug("#{new_node[:name]} node.#{key} changed (#{current_node[key.to_s]} != #{val})") + Chef::Log::debug("#{new_node['name']} node.#{key} changed (#{current_node[key.to_s]} != #{val})") return true end end - Chef::Log::debug("#{new_node[:name]} node unchanged") + Chef::Log::debug("#{new_node['name']} node unchanged") false end @@ -79,33 +79,33 @@ def jenkins_node_compare(current_node, new_node) def jenkins_node_manage(args) args = jenkins_node_defaults(args) - if args[:env] - map = args[:env].collect { |k,v| %Q("#{k}":"#{v}") }.join(",") + if args['env'] + map = args['env'].collect { |k,v| %Q("#{k}":"#{v}") }.join(",") env = "new jenkins.EnvVars([#{map}])" else env = "null" end - case args[:launcher] + case args['launcher'] when "jnlp" launcher = "new JNLPLauncher()" when "command" - launcher = %Q(new CommandLauncher("#{args[:command]}", env)) + launcher = %Q(new CommandLauncher("#{args['command']}", env)) when "ssh" - if args[:password] == nil + if args['password'] == nil password = "null" else - password = %Q("#{args[:password]}") + password = %Q("#{args['password']}") end - launcher = %Q(new_ssh_launcher(["#{args[:host]}", #{args[:port]}, "#{args[:username]}", #{password}, - "#{args[:private_key]}", "#{args[:jvm_options]}"] as Object[])) + launcher = %Q(new_ssh_launcher(["#{args['host']}", #{args['port']}, "#{args['username']}", #{password}, + "#{args['private_key']}", "#{args['jvm_options']}"] as Object[])) end - remote_fs = args[:remote_fs].gsub('\\', '\\\\\\') # C:\jenkins -> C:\\jenkins + remote_fs = args['remote_fs'].gsub('\\', '\\\\\\') # C:\jenkins -> C:\\jenkins - if args[:availability] == "Demand" - rs_args = "#{args[:in_demand_delay]}, #{args[:idle_delay]}" + if args['availability'] == "Demand" + rs_args = "#{args['in_demand_delay']}, #{args['idle_delay']}" else rs_args = "" end @@ -129,10 +129,10 @@ def new_ssh_launcher(args) { props << new EnvironmentVariablesNodeProperty(entries) } -slave = new DumbSlave("#{args[:name]}", "#{args[:description]}", "#{remote_fs}", - "#{args[:executors]}", Node.Mode.#{args[:mode]}, "#{args[:labels]}", +slave = new DumbSlave("#{args['name']}", "#{args['description']}", "#{remote_fs}", + "#{args['executors']}", Node.Mode.#{args['mode']}, "#{args['labels']}", #{launcher}, - new RetentionStrategy.#{args[:availability]}(#{rs_args}), props) + new RetentionStrategy.#{args['availability']}(#{rs_args}), props) nodes = new ArrayList(app.getNodes()) ix = nodes.indexOf(slave) diff --git a/metadata.rb b/metadata.rb index 5690c14..362c351 100644 --- a/metadata.rb +++ b/metadata.rb @@ -3,7 +3,7 @@ license "Apache 2.0" description "Installs and configures Jenkins CI server & slaves" long_description IO.read(File.join(File.dirname(__FILE__), 'README.md')) -version "0.6.3" +version "0.7.0" -%w(runit java).each { |cb| depends cb } +%w(apache2 nginx runit java chef_gem yumrepo).each { |cb| depends cb } %w(iptables yum apt).each { |cb| recommends cb } diff --git a/providers/cli.rb b/providers/cli.rb index ce354c9..aa9356e 100644 --- a/providers/cli.rb +++ b/providers/cli.rb @@ -22,13 +22,13 @@ # def action_run - url = @new_resource.url || node[:jenkins][:server][:url] - home = @new_resource.home || node[:jenkins][:node][:home] + url = @new_resource.url || node['jenkins']['server']['url'] + home = @new_resource.home || node['jenkins']['node']['home'] #recipes will chown to jenkins later if this doesn't already exist directory "home for jenkins-cli.jar" do action :create - path node[:jenkins][:node][:home] + path node['jenkins']['node']['home'] end cli_jar = ::File.join(home, "jenkins-cli.jar") @@ -37,7 +37,7 @@ def action_run not_if { ::File.exists?(cli_jar) } end - java_home = node[:jenkins][:java_home] || (node.has_key?(:java) ? node[:java][:jdk_dir] : nil) + java_home = node['jenkins']['java_home'] || (node.has_key?(:java) ? node['java']['jdk_dir'] : nil) if java_home == nil java = "java" else @@ -49,5 +49,6 @@ def action_run jenkins_execute command do cwd home block { |stdout| new_resource.block.call(stdout) } if new_resource.block + new_resource.updated_by_last_action(true) end end diff --git a/providers/execute.rb b/providers/execute.rb index aee7f3b..ff152db 100644 --- a/providers/execute.rb +++ b/providers/execute.rb @@ -27,22 +27,23 @@ def action_run args = { - :command => @new_resource.command, - :command_string => @new_resource.to_s, + :command => new_resource.command, + :command_string => new_resource.to_s, } - args[:only_if] = @new_resource.only_if if @new_resource.only_if - args[:not_if] = @new_resource.not_if if @new_resource.not_if - args[:timeout] = @new_resource.timeout if @new_resource.timeout - args[:cwd] = @new_resource.cwd if @new_resource.cwd + args[:only_if] = new_resource.only_if if new_resource.only_if + args[:not_if] = new_resource.not_if if new_resource.not_if + args[:timeout] = new_resource.timeout if new_resource.timeout + args[:cwd] = new_resource.cwd if new_resource.cwd status, stdout, stderr = output_of_command(args[:command], args) if status.exitstatus == 0 - @new_resource.block.call(stdout) if @new_resource.block - @new_resource.updated_by_last_action(true) - Chef::Log.info("Ran #{@new_resource} successfully") + new_resource.block.call(stdout) if new_resource.block + new_resource.updated_by_last_action(true) + Chef::Log.info("Ran #{new_resource} successfully") else command_output = "JENKINS STDOUT: #{stdout}" command_output << "JENKINS STDERR: #{stderr}" handle_command_failures(status, command_output, args) + new_resource.updated_by_last_action(true) end end diff --git a/providers/job.rb b/providers/job.rb index 4b61dce..baf42e0 100644 --- a/providers/job.rb +++ b/providers/job.rb @@ -22,13 +22,13 @@ # def job_url - job_url = "#{@new_resource.url}/job/#{@new_resource.job_name}/config.xml" + job_url = "#{new_resource.url}/job/#{new_resource.job_name}/config.xml" Chef::Log.debug "[jenkins_job] job_url: #{job_url}" job_url end def new_job_url - "#{@new_resource.url}/createItem?name=#{@new_resource.job_name}" + "#{new_resource.url}/createItem?name=#{new_resource.job_name}" end def job_exists @@ -41,16 +41,17 @@ def job_exists def post_job(url) #shame we can't use http_request resource url = URI.parse(url) - Chef::Log.debug("[jenkins_job] POST #{url.request_uri} using #{@new_resource.config}") - body = IO.read(@new_resource.config) + Chef::Log.debug("[jenkins_job] POST #{url.request_uri} using #{new_resource.config}") + body = IO.read(new_resource.config) headers = {"Content-Type" => "text/xml"} res = Chef::REST::RESTRequest.new(:POST, url, body, headers).call + new_resource.updated_by_last_action(true) res.error! unless res.kind_of?(Net::HTTPSuccess) end def action_create unless job_exists - jenkins_cli "create-job #{@new_resource.job_name} < #{@new_resource.config}" + jenkins_cli "create-job #{new_resource.job_name} < #{new_resource.config}" end end @@ -64,17 +65,17 @@ def action_update end def action_delete - jenkins_cli "delete-job #{@new_resource.job_name}" + jenkins_cli "delete-job #{new_resource.job_name}" end def action_disable - jenkins_cli "disable-job #{@new_resource.job_name}" + jenkins_cli "disable-job #{new_resource.job_name}" end def action_enable - jenkins_cli "enable-job #{@new_resource.job_name}" + jenkins_cli "enable-job #{new_resource.job_name}" end def action_build - jenkins_cli "build #{@new_resource.job_name}" + jenkins_cli "build #{new_resource.job_name}" end diff --git a/providers/node.rb b/providers/node.rb index 400b00c..60253eb 100644 --- a/providers/node.rb +++ b/providers/node.rb @@ -33,7 +33,7 @@ def action_create backup false end - cookbook_file "#{node[:jenkins][:node][:home]}/node_info.groovy" do + cookbook_file "#{node['jenkins']['node']['home']}/node_info.groovy" do source "node_info.groovy" end diff --git a/recipes/default.rb b/recipes/default.rb index 7c359e2..5247aee 100644 --- a/recipes/default.rb +++ b/recipes/default.rb @@ -22,84 +22,91 @@ # limitations under the License. # -pkey = "#{node[:jenkins][:server][:home]}/.ssh/id_rsa" +# Install sshkey gem into chef +chef_gem "sshkey" + +pkey = "#{node['jenkins']['server']['home']}/.ssh/id_rsa" tmp = "/tmp" -user node[:jenkins][:server][:user] do - home node[:jenkins][:server][:home] +user node['jenkins']['server']['user'] do + home node['jenkins']['server']['home'] + shell "/bin/bash" end -directory node[:jenkins][:server][:home] do +directory node['jenkins']['server']['home'] do recursive true - owner node[:jenkins][:server][:user] - group node[:jenkins][:server][:group] + owner node['jenkins']['server']['user'] + group node['jenkins']['server']['group'] end -directory "#{node[:jenkins][:server][:home]}/.ssh" do +directory "#{node['jenkins']['server']['home']}/.ssh" do mode 0700 - owner node[:jenkins][:server][:user] - group node[:jenkins][:server][:group] + owner node['jenkins']['server']['user'] + group node['jenkins']['server']['group'] +end + +# Generate and deploy ssh public/private keys +Gem.clear_paths +require 'sshkey' +sshkey = SSHKey.generate(:type => 'RSA', :comment => "#{node['jenkins']['server']['user']}@#{node['fqdn']}") +node.set_unless['jenkins']['server']['pubkey'] = sshkey.ssh_public_key + +# Save public_key to node, unless it is already set. +unless Chef::Config['solo'] + ruby_block "save node data" do + block do + node.save + end + action :create + end end -execute "ssh-keygen -f #{pkey} -N ''" do - user node[:jenkins][:server][:user] - group node[:jenkins][:server][:group] - not_if { File.exists?(pkey) } +# Save private key, unless pkey file exists +template pkey do + owner node['jenkins']['server']['user'] + group node['jenkins']['server']['group'] + variables( :ssh_private_key => sshkey.private_key ) + mode 0600 + not_if { File.exists?("#{node['jenkins']['server']['home']}/.ssh/id_rsa") } end -ruby_block "store jenkins ssh pubkey" do - block do - node.set[:jenkins][:server][:pubkey] = File.open("#{pkey}.pub") { |f| f.gets } - end +# Template public key out to pkey.pub file +template "#{pkey}.pub" do + owner node['jenkins']['server']['user'] + group node['jenkins']['server']['group'] + mode 0644 end -directory "#{node[:jenkins][:server][:home]}/plugins" do - owner node[:jenkins][:server][:user] - group node[:jenkins][:server][:group] - only_if { node[:jenkins][:server][:plugins].size > 0 } +directory "#{node['jenkins']['server']['home']}/plugins" do + owner node['jenkins']['server']['user'] + group node['jenkins']['server']['group'] + only_if { node['jenkins']['server']['plugins'].size > 0 } end -node[:jenkins][:server][:plugins].each do |name| - remote_file "#{node[:jenkins][:server][:home]}/plugins/#{name}.hpi" do - source "#{node[:jenkins][:mirror]}/plugins/#{name}/latest/#{name}.hpi" +node['jenkins']['server']['plugins'].each do |name| + remote_file "#{node['jenkins']['server']['home']}/plugins/#{name}.hpi" do + source "#{node['jenkins']['mirror']}/plugins/#{name}/latest/#{name}.hpi" backup false - owner node[:jenkins][:server][:user] - group node[:jenkins][:server][:group] + owner node['jenkins']['server']['user'] + group node['jenkins']['server']['group'] action :create_if_missing end end -case node.platform +include_recipe "java" + +case node['platform'] when "ubuntu", "debian" include_recipe "apt" - include_recipe "java" - - pid_file = "/var/run/jenkins/jenkins.pid" - install_starts_service = true apt_repository "jenkins" do - uri "#{node.jenkins.package_url}/debian" + uri "#{node['jenkins']['package_url']}/debian" components %w[binary/] key "http://pkg.jenkins-ci.org/debian/jenkins-ci.org.key" action :add end -when "centos", "redhat" - include_recipe "yum" - - pid_file = "/var/run/jenkins.pid" - install_starts_service = false - - yum_key "jenkins" do - url "#{node.jenkins.package_url}/redhat/jenkins-ci.org.key" - action :add - end - - yum_repository "jenkins" do - description "repository for jenkins" - url "#{node.jenkins.package_url}/redhat/" - key "jenkins" - action :add - end +when "centos", "redhat", "centos", "scientific", "amazon" + include_recipe "yumrepo::jenkins" end #"jenkins stop" may (likely) exit before the process is actually dead @@ -108,11 +115,11 @@ block do 10.times do if IO.popen("netstat -lnt").entries.select { |entry| - entry.split[3] =~ /:#{node[:jenkins][:server][:port]}$/ + entry.split[3] =~ /:#{node['jenkins']['server']['port']}$/ }.size == 0 break end - Chef::Log.debug("service[jenkins] still listening (port #{node[:jenkins][:server][:port]})") + Chef::Log.debug("service[jenkins] still listening (port #{node['jenkins']['server']['port']})") sleep 1 end end @@ -121,16 +128,16 @@ service "jenkins" do supports [ :stop, :start, :restart, :status ] - status_command "test -f #{pid_file} && kill -0 `cat #{pid_file}`" + status_command "test -f #{node['jenkins']['pid_file']} && kill -0 `cat #{node['jenkins']['pid_file']}`" action :nothing end ruby_block "block_until_operational" do block do until IO.popen("netstat -lnt").entries.select { |entry| - entry.split[3] =~ /:#{node[:jenkins][:server][:port]}$/ + entry.split[3] =~ /:#{node['jenkins']['server']['port']}$/ }.size == 1 - Chef::Log.debug "service[jenkins] not listening on port #{node.jenkins.server.port}" + Chef::Log.debug "service[jenkins] not listening on port #{node['jenkins']['server']['port']}" sleep 1 end @@ -147,20 +154,19 @@ log "jenkins: install and start" do notifies :install, "package[jenkins]", :immediately - notifies :start, "service[jenkins]", :immediately unless install_starts_service + notifies :start, "service[jenkins]", :immediately unless node['jenkins']['install_starts_service'] notifies :create, "ruby_block[block_until_operational]", :immediately not_if do File.exists? "/usr/share/jenkins/jenkins.war" end end -template "/etc/default/jenkins" - -package "jenkins" do - action :nothing - notifies :create, "template[/etc/default/jenkins]", :immediately +template "/etc/default/jenkins" do + only_if { node['platform'] == "ubuntu" || node['platform'] == "debian" } end +package "jenkins" + # restart if this run only added new plugins log "plugins updated, restarting jenkins" do #ugh :restart does not work, need to sleep after stop. @@ -169,29 +175,28 @@ notifies :start, "service[jenkins]", :immediately notifies :create, "ruby_block[block_until_operational]", :immediately only_if do - if File.exists?(pid_file) - htime = File.mtime(pid_file) - Dir["#{node[:jenkins][:server][:home]}/plugins/*.hpi"].select { |file| + if File.exists?(node['jenkins']['pid_file']) + htime = File.mtime(node['jenkins']['pid_file']) + Dir["#{node['jenkins']['server']['home']}/plugins/*.hpi"].select { |file| File.mtime(file) > htime }.size > 0 end end - action :nothing end # Front Jenkins with an HTTP server -case node[:jenkins][:http_proxy][:variant] +case node['jenkins']['http_proxy']['variant'] when "nginx" include_recipe "jenkins::proxy_nginx" when "apache2" include_recipe "jenkins::proxy_apache2" end -if node.jenkins.iptables_allow == "enable" +if node['jenkins']['iptables_allow'] == "enable" include_recipe "iptables" iptables_rule "port_jenkins" do - if node[:jenkins][:iptables_allow] == "enable" + if node['jenkins']['iptables_allow'] == "enable" enable true else enable false diff --git a/recipes/iptables.rb b/recipes/iptables.rb index e9ac6aa..078a461 100644 --- a/recipes/iptables.rb +++ b/recipes/iptables.rb @@ -19,10 +19,10 @@ # limitations under the License. # -if platform?("redhat","centos","debian","ubuntu") +if platform?("redhat","centos","scientific","amazon","debian","ubuntu") include_recipe "iptables" iptables_rule "port_jenkins" do - if node[:jenkins][:iptables_allow] == "enable" + if node['jenkins']['iptables_allow'] == "enable" enable true else enable false diff --git a/recipes/node_jnlp.rb b/recipes/node_jnlp.rb index cad8523..d6b4319 100644 --- a/recipes/node_jnlp.rb +++ b/recipes/node_jnlp.rb @@ -24,37 +24,37 @@ include_recipe "runit" service_name = "jenkins-slave" -slave_jar = "#{node[:jenkins][:node][:home]}/slave.jar" +slave_jar = "#{node['jenkins']['node']['home']}/slave.jar" -group node[:jenkins][:node][:user] do +group node['jenkins']['node']['user'] do end -user node[:jenkins][:node][:user] do +user node['jenkins']['node']['user'] do comment "Jenkins CI node (jnlp)" - gid node[:jenkins][:node][:user] - home node[:jenkins][:node][:home] + gid node['jenkins']['node']['user'] + home node['jenkins']['node']['home'] end -directory node[:jenkins][:node][:home] do +directory node['jenkins']['node']['home'] do action :create - owner node[:jenkins][:node][:user] - group node[:jenkins][:node][:user] + owner node['jenkins']['node']['user'] + group node['jenkins']['node']['user'] end -jenkins_node node[:jenkins][:node][:name] do - description node[:jenkins][:node][:description] - executors node[:jenkins][:node][:executors] - remote_fs node[:jenkins][:node][:home] - labels node[:jenkins][:node][:labels] - mode node[:jenkins][:node][:mode] +jenkins_node node['jenkins']['node']['name'] do + description node['jenkins']['node']['description'] + executors node['jenkins']['node']['executors'] + remote_fs node['jenkins']['node']['home'] + labels node['jenkins']['node']['labels'] + mode node['jenkins']['node']['mode'] launcher "jnlp" - mode node[:jenkins][:node][:mode] - availability node[:jenkins][:node][:availability] + mode node['jenkins']['node']['mode'] + availability node['jenkins']['node']['availability'] end remote_file slave_jar do - source "#{node[:jenkins][:server][:url]}/jnlpJars/slave.jar" - owner node[:jenkins][:node][:user] + source "#{node['jenkins']['server']['url']}/jnlpJars/slave.jar" + owner node['jenkins']['node']['user'] #only restart if slave.jar is updated if ::File.exists?(slave_jar) notifies :restart, "service[#{service_name}]", :immediately diff --git a/recipes/node_ssh.rb b/recipes/node_ssh.rb index 8e70405..210a3bd 100644 --- a/recipes/node_ssh.rb +++ b/recipes/node_ssh.rb @@ -21,61 +21,63 @@ # limitations under the License. # -unless node[:jenkins][:server][:pubkey] - host = node[:jenkins][:server][:host] - if host == node[:fqdn] - host = URI.parse(node[:jenkins][:server][:url]).host +unless node['jenkins']['server']['pubkey'] + host = node['jenkins']['server']['host'] + if host == node['fqdn'] + host = URI.parse(node['jenkins']['server']['url']).host + end + unless Chef::Config[:solo] + jenkins_node = search(:node, "fqdn:#{host}").first + node.set['jenkins']['server']['pubkey'] = jenkins_node['jenkins']['server']['pubkey'] end - jenkins_node = search(:node, "fqdn:#{host}").first - node.set[:jenkins][:server][:pubkey] = jenkins_node[:jenkins][:server][:pubkey] end -group node[:jenkins][:node][:user] do +group node['jenkins']['node']['user'] do end -user node[:jenkins][:node][:user] do +user node['jenkins']['node']['user'] do comment "Jenkins CI node (ssh)" - gid node[:jenkins][:node][:user] - home node[:jenkins][:node][:home] + gid node['jenkins']['node']['user'] + home node['jenkins']['node']['home'] shell "/bin/sh" end -directory node[:jenkins][:node][:home] do +directory node['jenkins']['node']['home'] do action :create - owner node[:jenkins][:node][:user] - group node[:jenkins][:node][:user] + owner node['jenkins']['node']['user'] + group node['jenkins']['node']['user'] end -directory "#{node[:jenkins][:node][:home]}/.ssh" do +directory "#{node['jenkins']['node']['home']}/.ssh" do action :create mode 0700 - owner node[:jenkins][:node][:user] - group node[:jenkins][:node][:user] + owner node['jenkins']['node']['user'] + group node['jenkins']['node']['user'] end -file "#{node[:jenkins][:node][:home]}/.ssh/authorized_keys" do +file "#{node['jenkins']['node']['home']}/.ssh/authorized_keys" do action :create mode 0600 - owner node[:jenkins][:node][:user] - group node[:jenkins][:node][:user] - content node[:jenkins][:server][:pubkey] + owner node['jenkins']['node']['user'] + group node['jenkins']['node']['user'] + content node['jenkins']['server']['pubkey'] end -jenkins_node node[:jenkins][:node][:name] do - description node[:jenkins][:node][:description] - executors node[:jenkins][:node][:executors] - remote_fs node[:jenkins][:node][:home] - labels node[:jenkins][:node][:labels] - mode node[:jenkins][:node][:mode] +jenkins_node node['jenkins']['node']['name'] do + description node['jenkins']['node']['description'] + executors node['jenkins']['node']['executors'] + remote_fs node['jenkins']['node']['home'] + labels node['jenkins']['node']['labels'] + mode node['jenkins']['node']['mode'] launcher "ssh" - mode node[:jenkins][:node][:mode] - availability node[:jenkins][:node][:availability] - env node[:jenkins][:node][:env] + mode node['jenkins']['node']['mode'] + availability node['jenkins']['node']['availability'] + env node['jenkins']['node']['env'] #ssh options - host node[:jenkins][:node][:ssh_host] - port node[:jenkins][:node][:ssh_port] - username node[:jenkins][:node][:ssh_user] - password node[:jenkins][:node][:ssh_pass] - private_key node[:jenkins][:node][:ssh_private_key] - jvm_options node[:jenkins][:node][:jvm_options] + host node['jenkins']['node']['ssh_host'] + port node['jenkins']['node']['ssh_port'] + username node['jenkins']['node']['ssh_user'] + password node['jenkins']['node']['ssh_pass'] + private_key node['jenkins']['node']['ssh_private_key'] + jvm_options node['jenkins']['node']['jvm_options'] end diff --git a/recipes/node_windows.rb b/recipes/node_windows.rb index b8d7b71..2df9a90 100644 --- a/recipes/node_windows.rb +++ b/recipes/node_windows.rb @@ -21,8 +21,8 @@ # limitations under the License. # -home = node[:jenkins][:node][:home] -url = node[:jenkins][:server][:url] +home = node['jenkins']['node']['home'] +url = node['jenkins']['server']['url'] jenkins_exe = "#{home}\\jenkins-slave.exe" service_name = "jenkinsslave" @@ -44,7 +44,7 @@ template "#{home}/jenkins-slave.xml" do source "jenkins-slave.xml" variables(:jenkins_home => home, - :jnlp_url => "#{url}/computer/#{node[:jenkins][:node][:name]}/slave-agent.jnlp") + :jnlp_url => "#{url}/computer/#{node['jenkins']['node']['name']}/slave-agent.jnlp") end #XXX how-to get this directly from the jenkins server? @@ -62,15 +62,15 @@ action :nothing end -jenkins_node node[:jenkins][:node][:name] do - description node[:jenkins][:node][:description] - executors node[:jenkins][:node][:executors] - remote_fs node[:jenkins][:node][:home] - labels node[:jenkins][:node][:labels] - mode node[:jenkins][:node][:mode] - launcher node[:jenkins][:node][:launcher] - mode node[:jenkins][:node][:mode] - availability node[:jenkins][:node][:availability] +jenkins_node node['jenkins']['node']['name'] do + description node['jenkins']['node']['description'] + executors node['jenkins']['node']['executors'] + remote_fs node['jenkins']['node']['home'] + labels node['jenkins']['node']['labels'] + mode node['jenkins']['node']['mode'] + launcher node['jenkins']['node']['launcher'] + mode node['jenkins']['node']['mode'] + availability node['jenkins']['node']['availability'] end remote_file "#{home}\\slave.jar" do diff --git a/recipes/proxy_apache2.rb b/recipes/proxy_apache2.rb index 4e6808e..01151c4 100644 --- a/recipes/proxy_apache2.rb +++ b/recipes/proxy_apache2.rb @@ -25,36 +25,37 @@ apache_module "proxy_http" apache_module "vhost_alias" -if node[:jenkins][:http_proxy][:www_redirect] == "enable" +if node['jenkins']['http_proxy']['www_redirect'] == "enable" www_redirect = true apache_module "rewrite" else www_redirect = false end -host_name = node[:jenkins][:http_proxy][:host_name] || node[:fqdn] +host_name = node['jenkins']['http_proxy']['host_name'] || node['fqdn'] -template "#{node.apache.dir}/htpasswd" do - variables( :username => node.jenkins.http_proxy.basic_auth_username, - :password => node.jenkins.http_proxy.basic_auth_password) - owner node.apache.user - group node.apache.user +template "#{node['apache']['dir']}/htpasswd" do + variables( :username => node['jenkins']['http_proxy']['basic_auth_username'], + :password => node['jenkins']['http_proxy']['basic_auth_password']) + owner node['apache']['user'] + group node['apache']['user'] mode 0600 + only_if { node['jenkins']['http_proxy']['basic_auth'] } end -template "#{node[:apache][:dir]}/sites-available/jenkins" do +template "#{node['apache']['dir']}/sites-available/jenkins" do source "apache_jenkins.erb" owner 'root' group 'root' mode '0644' variables( :host_name => host_name, - :host_aliases => node[:jenkins][:http_proxy][:host_aliases], - :listen_ports => node[:jenkins][:http_proxy][:listen_ports], + :host_aliases => node['jenkins']['http_proxy']['host_aliases'], + :listen_ports => node['jenkins']['http_proxy']['listen_ports'], :www_redirect => www_redirect ) - if File.exists?("#{node[:apache][:dir]}/sites-enabled/jenkins") + if File.exists?("#{node['apache']['dir']}/sites-enabled/jenkins") notifies :restart, 'service[apache2]' end end @@ -64,7 +65,7 @@ end apache_site "jenkins" do - if node[:jenkins][:http_proxy][:variant] == "apache2" + if node['jenkins']['http_proxy']['variant'] == "apache2" enable true else enable false diff --git a/recipes/proxy_nginx.rb b/recipes/proxy_nginx.rb index ee77b23..52a69ca 100644 --- a/recipes/proxy_nginx.rb +++ b/recipes/proxy_nginx.rb @@ -21,34 +21,34 @@ include_recipe "nginx::source" -if node[:jenkins][:http_proxy][:www_redirect] == "enable" +if node['jenkins']['http_proxy']['www_redirect'] == "enable" www_redirect = true else www_redirect = false end -host_name = node[:jenkins][:http_proxy][:host_name] || node[:fqdn] +host_name = node['jenkins']['http_proxy']['host_name'] || node['fqdn'] -template "#{node[:nginx][:dir]}/sites-available/jenkins.conf" do +template "#{node['nginx']['dir']}/sites-available/jenkins.conf" do source "nginx_jenkins.conf.erb" owner 'root' group 'root' mode '0644' variables( :host_name => host_name, - :host_aliases => node[:jenkins][:http_proxy][:host_aliases], - :listen_ports => node[:jenkins][:http_proxy][:listen_ports], + :host_aliases => node['jenkins']['http_proxy']['host_aliases'], + :listen_ports => node['jenkins']['http_proxy']['listen_ports'], :www_redirect => www_redirect, - :max_upload_size => node[:jenkins][:http_proxy][:client_max_body_size] + :max_upload_size => node['jenkins']['http_proxy']['client_max_body_size'] ) - if File.exists?("#{node[:nginx][:dir]}/sites-enabled/jenkins.conf") + if File.exists?("#{node['nginx']['dir']}/sites-enabled/jenkins.conf") notifies :restart, 'service[nginx]' end end nginx_site "jenkins.conf" do - if node[:jenkins][:http_proxy][:variant] == "nginx" + if node['jenkins']['http_proxy']['variant'] == "nginx" enable true else enable false diff --git a/resources/job.rb b/resources/job.rb index 7174f3f..e7e6f3b 100644 --- a/resources/job.rb +++ b/resources/job.rb @@ -31,5 +31,5 @@ def initialize(name, run_context=nil) super @action = :update @job_name = name - @url = node[:jenkins][:server][:url] + @url = node['jenkins']['server']['url'] end diff --git a/templates/default/apache_jenkins.erb b/templates/default/apache_jenkins.erb index b05d87a..accd556 100644 --- a/templates/default/apache_jenkins.erb +++ b/templates/default/apache_jenkins.erb @@ -21,15 +21,16 @@ # Local reverse proxy authorization override # Most unix distribution deny proxy by default # (ie /etc/apache2/mods-enabled/proxy.conf in Ubuntu) - /*> + /*> Order deny,allow Allow from all ProxyPreserveHost on - ProxyPass / http://localhost:<%= node[:jenkins][:server][:port] %>/ - ProxyPassReverse / http://localhost:<%= node[:jenkins][:server][:port] %>/ + ProxyPass / http://localhost:<%= node['jenkins']['server']['port'] %>/ + ProxyPassReverse / http://localhost:<%= node['jenkins']['server']['port'] %>/ +<% if node['jenkins']['http_proxy']['basic_auth'] -%> AuthType basic AuthName "Jenkins" @@ -37,4 +38,5 @@ AuthUserFile <%= File.join(node.apache.dir, "htpasswd") %> require valid-user +<% end -%> diff --git a/templates/default/id_rsa.erb b/templates/default/id_rsa.erb new file mode 100644 index 0000000..9b76f49 --- /dev/null +++ b/templates/default/id_rsa.erb @@ -0,0 +1 @@ +<%= @ssh_private_key -%> diff --git a/templates/default/id_rsa.pub.erb b/templates/default/id_rsa.pub.erb new file mode 100644 index 0000000..91cecee --- /dev/null +++ b/templates/default/id_rsa.pub.erb @@ -0,0 +1 @@ +<%= node['jenkins']['server']['pubkey'] %> diff --git a/templates/default/jenkins.erb b/templates/default/jenkins.erb index d759156..11ef53a 100644 --- a/templates/default/jenkins.erb +++ b/templates/default/jenkins.erb @@ -10,16 +10,16 @@ JAVA=/usr/bin/java #JAVA_ARGS="-Xmx256m" #JAVA_ARGS="-Djava.net.preferIPv4Stack=true" # make jenkins listen on IPv4 address -PIDFILE=/var/run/jenkins/jenkins.pid +PIDFILE=<%= node['jenkins']['pid_file'] %> # user id to be invoked as (otherwise will run as root; not wise!) -JENKINS_USER=<%= node.jenkins.server.user %> +JENKINS_USER=<%= node['jenkins']['server']['user'] %> # location of the jenkins war file JENKINS_WAR=/usr/share/jenkins/jenkins.war # jenkins home location -JENKINS_HOME=<%= node.jenkins.server.home %> +JENKINS_HOME=<%= node['jenkins']['server']['home'] %> # set this to false if you don't want Hudson to run by itself # in this set up, you are expected to provide a servlet container @@ -38,8 +38,8 @@ JENKINS_LOG=/var/log/jenkins/$NAME.log MAXOPENFILES=8192 # port for HTTP connector (default 8080; disable with -1) -HTTP_HOST=<%= node.jenkins.server.host %> -HTTP_PORT=<%= node.jenkins.server.port %> +HTTP_HOST=<%= node['jenkins']['server']['host'] %> +HTTP_PORT=<%= node['jenkins']['server']['port'] %> # port for AJP connector (disabled by default) AJP_PORT=-1 diff --git a/templates/default/nginx_jenkins.conf.erb b/templates/default/nginx_jenkins.conf.erb index 2efcaab..9b42c81 100644 --- a/templates/default/nginx_jenkins.conf.erb +++ b/templates/default/nginx_jenkins.conf.erb @@ -1,6 +1,6 @@ # nginx jenkins application vhost # -# Generated by Chef for <%= node[:fqdn] %> +# Generated by Chef for <%= node['fqdn'] %> # Local modifications will be overwritten. # <% if @www_redirect -%> @@ -22,12 +22,12 @@ server { client_max_body_size <%= @max_upload_size %>; location / { - proxy_pass http://127.0.0.1:<%= node[:jenkins][:server][:port] %>; + proxy_pass http://127.0.0.1:<%= node['jenkins']['server']['port'] %>; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_set_header Host $http_host; } - error_log <%= node[:nginx][:log_dir] %>/jenkins-error.log; - access_log <%= node[:nginx][:log_dir] %>/jenkins-access.log; + error_log <%= node['nginx']['log_dir'] %>/jenkins-error.log; + access_log <%= node['nginx']['log_dir'] %>/jenkins-access.log; } diff --git a/templates/default/port_jenkins.erb b/templates/default/port_jenkins.erb index 5ec2081..8fa6e83 100644 --- a/templates/default/port_jenkins.erb +++ b/templates/default/port_jenkins.erb @@ -1,2 +1,2 @@ # jenkins --A FWR -p tcp -m tcp --dport <%= node[:jenkins][:server][:firewall_port] %> -j ACCEPT +-A FWR -p tcp -m tcp --dport <%= node['jenkins']['server']['firewall_port'] %> -j ACCEPT diff --git a/templates/default/sv-hudson-slave-run.erb b/templates/default/sv-hudson-slave-run.erb index ec4ccde..d837094 100644 --- a/templates/default/sv-hudson-slave-run.erb +++ b/templates/default/sv-hudson-slave-run.erb @@ -1,6 +1,6 @@ #!/bin/sh exec 2>&1 -cd <%= node[:jenkins][:node][:home] %> -exec chpst -u <%= node[:jenkins][:node][:user] %> \ -java -jar <%= node[:jenkins][:node][:home] %>/slave.jar \ --jnlpUrl <%= node[:jenkins][:server][:url] %>/computer/<%= node[:jenkins][:node][:name] %>/slave-agent.jnlp +cd <%= node['jenkins']['node']['home'] %> +exec chpst -u <%= node['jenkins']['node']['user'] %> \ +java -jar <%= node['jenkins']['node']['home'] %>/slave.jar \ +-jnlpUrl <%= node['jenkins']['server']['url'] %>/computer/<%= node['jenkins']['node']['name'] %>/slave-agent.jnlp From 37e2764bf7a79ce6fc867e33fb765bf08910c562 Mon Sep 17 00:00:00 2001 From: "Eric G. Wolfe" Date: Tue, 29 May 2012 12:58:09 -0400 Subject: [PATCH 2/9] Recipe typo and updated_by_last_action fix-up --- providers/cli.rb | 4 +++- providers/execute.rb | 3 +-- recipes/default.rb | 18 +++++++----------- recipes/node_ssh.rb | 4 +++- 4 files changed, 14 insertions(+), 15 deletions(-) diff --git a/providers/cli.rb b/providers/cli.rb index aa9356e..a2c6a5c 100644 --- a/providers/cli.rb +++ b/providers/cli.rb @@ -30,12 +30,14 @@ def action_run action :create path node['jenkins']['node']['home'] end + new_resource.updated_by_last_action(true) cli_jar = ::File.join(home, "jenkins-cli.jar") remote_file cli_jar do source "#{url}/jnlpJars/jenkins-cli.jar" not_if { ::File.exists?(cli_jar) } end + new_resource.updated_by_last_action(true) java_home = node['jenkins']['java_home'] || (node.has_key?(:java) ? node['java']['jdk_dir'] : nil) if java_home == nil @@ -49,6 +51,6 @@ def action_run jenkins_execute command do cwd home block { |stdout| new_resource.block.call(stdout) } if new_resource.block - new_resource.updated_by_last_action(true) end + new_resource.updated_by_last_action(true) end diff --git a/providers/execute.rb b/providers/execute.rb index ff152db..285b2c1 100644 --- a/providers/execute.rb +++ b/providers/execute.rb @@ -38,12 +38,11 @@ def action_run status, stdout, stderr = output_of_command(args[:command], args) if status.exitstatus == 0 new_resource.block.call(stdout) if new_resource.block - new_resource.updated_by_last_action(true) Chef::Log.info("Ran #{new_resource} successfully") else command_output = "JENKINS STDOUT: #{stdout}" command_output << "JENKINS STDERR: #{stderr}" handle_command_failures(status, command_output, args) - new_resource.updated_by_last_action(true) end + new_resource.updated_by_last_action(true) end diff --git a/recipes/default.rb b/recipes/default.rb index 5247aee..cf54850 100644 --- a/recipes/default.rb +++ b/recipes/default.rb @@ -52,13 +52,11 @@ node.set_unless['jenkins']['server']['pubkey'] = sshkey.ssh_public_key # Save public_key to node, unless it is already set. -unless Chef::Config['solo'] - ruby_block "save node data" do - block do - node.save - end - action :create +ruby_block "save node data" do + block do + node.save unless Chef::Config['solo'] end + action :create end # Save private key, unless pkey file exists @@ -142,7 +140,7 @@ end loop do - url = URI.parse("#{node.jenkins.server.url}/job/test/config.xml") + url = URI.parse("#{node['jenkins']['server']['url']}/job/test/config.xml") res = Chef::REST::RESTRequest.new(:GET, url, nil).call break if res.kind_of?(Net::HTTPSuccess) or res.kind_of?(Net::HTTPNotFound) Chef::Log.debug "service[jenkins] not responding OK to GET / #{res.inspect}" @@ -187,10 +185,8 @@ # Front Jenkins with an HTTP server case node['jenkins']['http_proxy']['variant'] -when "nginx" - include_recipe "jenkins::proxy_nginx" -when "apache2" - include_recipe "jenkins::proxy_apache2" +when "nginx", "apache2" + include_recipe "jenkins::proxy_#{node['jenkins']['http_proxy']['variant']}" end if node['jenkins']['iptables_allow'] == "enable" diff --git a/recipes/node_ssh.rb b/recipes/node_ssh.rb index 210a3bd..8e1785b 100644 --- a/recipes/node_ssh.rb +++ b/recipes/node_ssh.rb @@ -26,7 +26,9 @@ if host == node['fqdn'] host = URI.parse(node['jenkins']['server']['url']).host end - unless Chef::Config[:solo] + if Chef::Config['solo'] + Chef::Log.warn("This recipe uses search. Chef Solo does not support search.") + else jenkins_node = search(:node, "fqdn:#{host}").first node.set['jenkins']['server']['pubkey'] = jenkins_node['jenkins']['server']['pubkey'] end From 89a949b619791812a1db2c7710238f5d5cacde32 Mon Sep 17 00:00:00 2001 From: gbloquel Date: Tue, 12 Jun 2012 15:41:48 +0200 Subject: [PATCH 3/9] Bug fix redhat familiy The variables home, user, port can be updated. --- recipes/default.rb | 10 +++- templates/default/jenkins-rh.erb | 97 ++++++++++++++++++++++++++++++++ 2 files changed, 105 insertions(+), 2 deletions(-) create mode 100644 templates/default/jenkins-rh.erb diff --git a/recipes/default.rb b/recipes/default.rb index cf54850..520ed7c 100644 --- a/recipes/default.rb +++ b/recipes/default.rb @@ -159,10 +159,16 @@ end end -template "/etc/default/jenkins" do - only_if { node['platform'] == "ubuntu" || node['platform'] == "debian" } +case node['platform'] +when "ubuntu", "debian" + template "/etc/default/jenkins" +when "centos", "redhat", "suse", "fedora", "scientific", "amazon" + template "/etc/sysconfig/jenkins" do + source jenkins-rh.erb + end end + package "jenkins" # restart if this run only added new plugins diff --git a/templates/default/jenkins-rh.erb b/templates/default/jenkins-rh.erb new file mode 100644 index 0000000..8dc323e --- /dev/null +++ b/templates/default/jenkins-rh.erb @@ -0,0 +1,97 @@ +## Path: Development/Jenkins +## Description: Configuration for the Jenkins continuous build server +## Type: string +## Default: "/var/lib/jenkins" +## ServiceRestart: jenkins +# +# Directory where Jenkins store its configuration and working +# files (checkouts, build reports, artifacts, ...). +# +JENKINS_HOME=<%= node['jenkins']['server']['home'] %> + +## Type: string +## Default: "" +## ServiceRestart: jenkins +# +# Java executable to run Jenkins +# When left empty, we'll try to find the suitable Java. +# +JENKINS_JAVA_CMD="" + +## Type: string +## Default: "jenkins" +## ServiceRestart: jenkins +# +# Unix user account that runs the Jenkins daemon +# Be careful when you change this, as you need to update +# permissions of $JENKINS_HOME and /var/log/jenkins. +# +JENKINS_USER=<%= node['jenkins']['server']['user'] %> + +## Type: string +## Default: "-Djava.awt.headless=true" +## ServiceRestart: jenkins +# +# Options to pass to java when running Jenkins. +# +JENKINS_JAVA_OPTIONS="-Djava.awt.headless=true" + +## Type: integer(0:65535) +## Default: 8080 +## ServiceRestart: jenkins +# +# Port Jenkins is listening on. +# Set to -1 to disable +# +JENKINS_PORT=<%= node['jenkins']['server']['port'] %> + +## Type: integer(0:65535) +## Default: 8009 +## ServiceRestart: jenkins +# +# Ajp13 Port Jenkins is listening on. +# Set to -1 to disable +# +JENKINS_AJP_PORT="8009" + +## Type: integer(1:9) +## Default: 5 +## ServiceRestart: jenkins +# +# Debug level for logs -- the higher the value, the more verbose. +# 5 is INFO. +# +JENKINS_DEBUG_LEVEL="5" + +## Type: yesno +## Default: no +## ServiceRestart: jenkins +# +# Whether to enable access logging or not. +# +JENKINS_ENABLE_ACCESS_LOG="no" + +## Type: integer +## Default: 100 +## ServiceRestart: jenkins +# +# Maximum number of HTTP worker threads. +# +JENKINS_HANDLER_MAX="100" + +## Type: integer +## Default: 20 +## ServiceRestart: jenkins +# +# Maximum number of idle HTTP worker threads. +# +JENKINS_HANDLER_IDLE="20" + +## Type: string +## Default: "" +## ServiceRestart: jenkins +# +# Pass arbitrary arguments to Jenkins. +# Full option list: java -jar jenkins.war --help +# +JENKINS_ARGS="" From ee76e3946f6c0f5a26886235d90b3f853bf53dcb Mon Sep 17 00:00:00 2001 From: "Eric G. Wolfe" Date: Thu, 14 Jun 2012 16:32:09 -0400 Subject: [PATCH 4/9] v0.7.1 * Add a few attribute knobs for java_options, pid and war file locations. * Make sysconfig template platform neutral for redhat/debian distributions --- CHANGELOG.md | 5 ++ README.md | 5 ++ attributes/default.rb | 11 +++- metadata.rb | 2 +- recipes/default.rb | 13 ++--- templates/default/jenkins-rh.erb | 97 -------------------------------- templates/default/jenkins.erb | 59 +++++++++++++++++-- 7 files changed, 81 insertions(+), 111 deletions(-) delete mode 100644 templates/default/jenkins-rh.erb diff --git a/CHANGELOG.md b/CHANGELOG.md index 8965281..3b3f835 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,8 @@ +## v0.7.1 + +* Add a few attribute knobs for java_options, pid and war file locations. +* Make sysconfig template platform neutral for redhat/debian distributions + ## v0.7.0 * General clean up, per Foodcritic compliance diff --git a/README.md b/README.md index 58f0833..2248bea 100644 --- a/README.md +++ b/README.md @@ -44,6 +44,11 @@ Attributes * jenkins['mirror'] - Base URL for downloading Jenkins (server) * jenkins['java_home'] - Java install path, used for for cli commands +* jenkins['java_options'] - Java options passed to sysconfig template +* jenkins['ajp_port'] - Set to 8009 for AJP, or -1 to disable. Default is disabled. +* jenkins['sysconf_template'] - sysconfig file for platform specific init scripts +* jenkins['pid_file'] - location of pid file +* jenkins['war_file'] - location of jenkins WAR file * jenkins['server']['home'] - JENKINS_HOME directory * jenkins['server']['user'] - User the Jenkins server runs as * jenkins['server']['group'] - Jenkins user primary group diff --git a/attributes/default.rb b/attributes/default.rb index 325eb82..8d307ad 100644 --- a/attributes/default.rb +++ b/attributes/default.rb @@ -27,16 +27,25 @@ default['jenkins']['server']['home'] = "/var/lib/jenkins" default['jenkins']['server']['user'] = "jenkins" +default['jenkins']['java_options'] = "-Xmx256m -Djava.awt.headless=true" +default['jenkins']['ajp_port'] = -1 +default['jenkins']['sysconf_template'] +default['jenkins']['pid_file'] +default['jenkins']['war_file'] case node['platform'] -when "debian", "ubuntu" +when "debian", "ubuntu" + default['jenkins']['sysconf_template'] = "/etc/default/jenkins" default['jenkins']['server']['group'] = "nogroup" default['jenkins']['install_starts_service'] = true default['jenkins']['pid_file'] = "/var/run/jenkins/jenkins.pid" + default['jenkins']['war_file'] = "/usr/share/jenkins/jenkins.war" when "redhat", "centos", "scientific", "amazon" + default['jenkins']['sysconf_template'] = "/etc/sysconfig/jenkins" default['jenkins']['install_starts_service'] = true default['jenkins']['server']['group'] = node['jenkins']['server']['user'] default['jenkins']['pid_file'] = "/var/run/jenkins.pid" + default['jenkins']['war_file'] = "/usr/lib/jenkins/jenkins.war" else default['jenkins']['install_starts_service'] = false default['jenkins']['server']['group'] = node['jenkins']['server']['user'] diff --git a/metadata.rb b/metadata.rb index 362c351..bfbfb10 100644 --- a/metadata.rb +++ b/metadata.rb @@ -3,7 +3,7 @@ license "Apache 2.0" description "Installs and configures Jenkins CI server & slaves" long_description IO.read(File.join(File.dirname(__FILE__), 'README.md')) -version "0.7.0" +version "0.7.1" %w(apache2 nginx runit java chef_gem yumrepo).each { |cb| depends cb } %w(iptables yum apt).each { |cb| recommends cb } diff --git a/recipes/default.rb b/recipes/default.rb index 520ed7c..d88945c 100644 --- a/recipes/default.rb +++ b/recipes/default.rb @@ -155,17 +155,14 @@ notifies :start, "service[jenkins]", :immediately unless node['jenkins']['install_starts_service'] notifies :create, "ruby_block[block_until_operational]", :immediately not_if do - File.exists? "/usr/share/jenkins/jenkins.war" + File.exists?(node['jenkins']['war_file']) end end -case node['platform'] -when "ubuntu", "debian" - template "/etc/default/jenkins" -when "centos", "redhat", "suse", "fedora", "scientific", "amazon" - template "/etc/sysconfig/jenkins" do - source jenkins-rh.erb - end +unless node['jenkins']['sysconf_template'].nil? + template node['jenkins']['sysconf_template'] do + notifies :restart, "service[jenkins]", :immediately + end end diff --git a/templates/default/jenkins-rh.erb b/templates/default/jenkins-rh.erb deleted file mode 100644 index 8dc323e..0000000 --- a/templates/default/jenkins-rh.erb +++ /dev/null @@ -1,97 +0,0 @@ -## Path: Development/Jenkins -## Description: Configuration for the Jenkins continuous build server -## Type: string -## Default: "/var/lib/jenkins" -## ServiceRestart: jenkins -# -# Directory where Jenkins store its configuration and working -# files (checkouts, build reports, artifacts, ...). -# -JENKINS_HOME=<%= node['jenkins']['server']['home'] %> - -## Type: string -## Default: "" -## ServiceRestart: jenkins -# -# Java executable to run Jenkins -# When left empty, we'll try to find the suitable Java. -# -JENKINS_JAVA_CMD="" - -## Type: string -## Default: "jenkins" -## ServiceRestart: jenkins -# -# Unix user account that runs the Jenkins daemon -# Be careful when you change this, as you need to update -# permissions of $JENKINS_HOME and /var/log/jenkins. -# -JENKINS_USER=<%= node['jenkins']['server']['user'] %> - -## Type: string -## Default: "-Djava.awt.headless=true" -## ServiceRestart: jenkins -# -# Options to pass to java when running Jenkins. -# -JENKINS_JAVA_OPTIONS="-Djava.awt.headless=true" - -## Type: integer(0:65535) -## Default: 8080 -## ServiceRestart: jenkins -# -# Port Jenkins is listening on. -# Set to -1 to disable -# -JENKINS_PORT=<%= node['jenkins']['server']['port'] %> - -## Type: integer(0:65535) -## Default: 8009 -## ServiceRestart: jenkins -# -# Ajp13 Port Jenkins is listening on. -# Set to -1 to disable -# -JENKINS_AJP_PORT="8009" - -## Type: integer(1:9) -## Default: 5 -## ServiceRestart: jenkins -# -# Debug level for logs -- the higher the value, the more verbose. -# 5 is INFO. -# -JENKINS_DEBUG_LEVEL="5" - -## Type: yesno -## Default: no -## ServiceRestart: jenkins -# -# Whether to enable access logging or not. -# -JENKINS_ENABLE_ACCESS_LOG="no" - -## Type: integer -## Default: 100 -## ServiceRestart: jenkins -# -# Maximum number of HTTP worker threads. -# -JENKINS_HANDLER_MAX="100" - -## Type: integer -## Default: 20 -## ServiceRestart: jenkins -# -# Maximum number of idle HTTP worker threads. -# -JENKINS_HANDLER_IDLE="20" - -## Type: string -## Default: "" -## ServiceRestart: jenkins -# -# Pass arbitrary arguments to Jenkins. -# Full option list: java -jar jenkins.war --help -# -JENKINS_ARGS="" diff --git a/templates/default/jenkins.erb b/templates/default/jenkins.erb index 11ef53a..78978e9 100644 --- a/templates/default/jenkins.erb +++ b/templates/default/jenkins.erb @@ -1,26 +1,64 @@ -# defaults for jenkins continuous integration server +# Generated by Chef for <%= node['fqdn'] %> +# Local modifications will be overwritten. +# +## Path: Development/Jenkins +## Description: Configuration for the Jenkins continuous build server +## Type: string +## Default: <%= node['jenkins']['server']['home'] %> +## ServiceRestart: jenkins +# # pulled in from the init script; makes things easier. NAME=jenkins # location of java -JAVA=/usr/bin/java +<% case node['platform'] when 'redhat','centos','scientific','amazon','oracle' -%> +# Java executable to run Jenkins +JENKINS_JAVA_CMD="<%= node['jenkins']['java_home'] %>/bin/java" +<% else -%> +JAVA="<%= node['jenkins']['java_home'] %>/bin/java" +<% end -%> # arguments to pass to java +<% case node['platform'] when 'redhat','centos','scientific','amazon','oracle' -%> +JENKINS_JAVA_OPTIONS="<%= node['jenkins']['java_options'] %>" +<% else -%> #JAVA_ARGS="-Xmx256m" #JAVA_ARGS="-Djava.net.preferIPv4Stack=true" # make jenkins listen on IPv4 address +JAVA_ARGS="<% node['jenkins']['java_options'] %> +<% end -%> +<% case node['platform'] when 'redhat','centos','scientific','amazon','oracle' -%> +JENKINS_PID_FILE="<%= node['jenkins']['pid_file'] %>" +<% else -%> PIDFILE=<%= node['jenkins']['pid_file'] %> +<% end -%> # user id to be invoked as (otherwise will run as root; not wise!) JENKINS_USER=<%= node['jenkins']['server']['user'] %> # location of the jenkins war file -JENKINS_WAR=/usr/share/jenkins/jenkins.war +JENKINS_WAR=<%= node['jenkins']['war_file'] %> # jenkins home location JENKINS_HOME=<%= node['jenkins']['server']['home'] %> +<%# Some redhat default-isms -%> +<% case node['platform'] when 'redhat','centos','scientific','amazon','oracle' -%> +# Debug level for logs -- the higher the value, the more verbose. +# 5 is INFO +JENKINS_DEBUG_LEVEL="5" + +# Whether to enable access logging or not. +JENKINS_ENABLE_ACCESS_LOG="no" + +# Maximum number of HTTP worker threads. +JENKINS_HANDLER_MAX="100" + +# Maximum n umber of idle HTTP worker threads. +JENKINS_HANDLER_IDLE="20" +<%# Some debian default-isms -%> +<% else -%> # set this to false if you don't want Hudson to run by itself # in this set up, you are expected to provide a servlet container # to host jenkins. @@ -36,14 +74,24 @@ JENKINS_LOG=/var/log/jenkins/$NAME.log # reported that Ubuntu's PAM configuration doesn't include pam_limits.so, and as a result the # of file # descriptors are forced to 1024 regardless of /etc/security/limits.conf MAXOPENFILES=8192 +<% end -%> # port for HTTP connector (default 8080; disable with -1) +<% case node['platform'] when 'redhat','centos','scientific','amazon','oracle' -%> +JENKINS_PORT=<%= node['jenkins']['server']['port'] -%> +<% else -%> HTTP_HOST=<%= node['jenkins']['server']['host'] %> HTTP_PORT=<%= node['jenkins']['server']['port'] %> +<% end -%> # port for AJP connector (disabled by default) -AJP_PORT=-1 +<% case node['platform'] when 'redhat','centos','scientific','amazon','oracle' -%> +JENKINS_AJP_PORT=<% node['jenkins']['ajp_port'] %> +<% else -%> +AJP_PORT=<% node['jenkins']['ajp_port'] %> +<% end -%> +<% case node['platform'] when 'debian','ubuntu' -%> # arguments to pass to jenkins. # --javahome=$JAVA_HOME # --httpPort=$HTTP_PORT (default 8080; disable with -1) @@ -53,3 +101,6 @@ AJP_PORT=-1 # --argumentsRealm.$ADMIN_USER=admin # --webroot=~/.jenkins/war JENKINS_ARGS="--webroot=/var/run/jenkins/war --httpListenAddress=$HTTP_HOST --httpPort=$HTTP_PORT --ajp13Port=$AJP_PORT" +<% else -%> +JENKINS_ARGS="" +<% end -%> From ba5303621a6f015c4116ddb7613e38755c457460 Mon Sep 17 00:00:00 2001 From: Chris Griego Date: Mon, 25 Jun 2012 11:40:21 -0500 Subject: [PATCH 5/9] Fix missing terminating double quote --- templates/default/jenkins.erb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/templates/default/jenkins.erb b/templates/default/jenkins.erb index 78978e9..241840f 100644 --- a/templates/default/jenkins.erb +++ b/templates/default/jenkins.erb @@ -25,7 +25,7 @@ JENKINS_JAVA_OPTIONS="<%= node['jenkins']['java_options'] %>" <% else -%> #JAVA_ARGS="-Xmx256m" #JAVA_ARGS="-Djava.net.preferIPv4Stack=true" # make jenkins listen on IPv4 address -JAVA_ARGS="<% node['jenkins']['java_options'] %> +JAVA_ARGS="<% node['jenkins']['java_options'] %>" <% end -%> <% case node['platform'] when 'redhat','centos','scientific','amazon','oracle' -%> From 32893427a45c48173bc0633b5fe41d361e0ce6e9 Mon Sep 17 00:00:00 2001 From: Chris Griego Date: Mon, 25 Jun 2012 12:21:24 -0500 Subject: [PATCH 6/9] Fix missing ERB output --- templates/default/jenkins.erb | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/templates/default/jenkins.erb b/templates/default/jenkins.erb index 241840f..2642c9e 100644 --- a/templates/default/jenkins.erb +++ b/templates/default/jenkins.erb @@ -25,7 +25,7 @@ JENKINS_JAVA_OPTIONS="<%= node['jenkins']['java_options'] %>" <% else -%> #JAVA_ARGS="-Xmx256m" #JAVA_ARGS="-Djava.net.preferIPv4Stack=true" # make jenkins listen on IPv4 address -JAVA_ARGS="<% node['jenkins']['java_options'] %>" +JAVA_ARGS="<%= node['jenkins']['java_options'] %>" <% end -%> <% case node['platform'] when 'redhat','centos','scientific','amazon','oracle' -%> @@ -86,9 +86,9 @@ HTTP_PORT=<%= node['jenkins']['server']['port'] %> # port for AJP connector (disabled by default) <% case node['platform'] when 'redhat','centos','scientific','amazon','oracle' -%> -JENKINS_AJP_PORT=<% node['jenkins']['ajp_port'] %> +JENKINS_AJP_PORT=<%= node['jenkins']['ajp_port'] %> <% else -%> -AJP_PORT=<% node['jenkins']['ajp_port'] %> +AJP_PORT=<%= node['jenkins']['ajp_port'] %> <% end -%> <% case node['platform'] when 'debian','ubuntu' -%> From 954ddf08df077a5cf5db716e125cc0256333b6cb Mon Sep 17 00:00:00 2001 From: Chris Griego Date: Mon, 25 Jun 2012 19:32:49 -0500 Subject: [PATCH 7/9] Always defer to private/public keys on filesystem If using a persistent volume that will end up migrating from node to node, such as an EBS volume on EC2, then the cookbook will now always defer to the files on disk and not overwrite them. It will also update the node pubkey setting from the data on disk. --- recipes/default.rb | 24 ++++++++++++------------ templates/default/id_rsa.pub.erb | 2 +- 2 files changed, 13 insertions(+), 13 deletions(-) diff --git a/recipes/default.rb b/recipes/default.rb index d88945c..ff4b48d 100644 --- a/recipes/default.rb +++ b/recipes/default.rb @@ -49,30 +49,30 @@ Gem.clear_paths require 'sshkey' sshkey = SSHKey.generate(:type => 'RSA', :comment => "#{node['jenkins']['server']['user']}@#{node['fqdn']}") -node.set_unless['jenkins']['server']['pubkey'] = sshkey.ssh_public_key - -# Save public_key to node, unless it is already set. -ruby_block "save node data" do - block do - node.save unless Chef::Config['solo'] - end - action :create -end # Save private key, unless pkey file exists template pkey do - owner node['jenkins']['server']['user'] + owner node['jenkins']['server']['user'] group node['jenkins']['server']['group'] variables( :ssh_private_key => sshkey.private_key ) mode 0600 - not_if { File.exists?("#{node['jenkins']['server']['home']}/.ssh/id_rsa") } + action :create_if_missing end # Template public key out to pkey.pub file template "#{pkey}.pub" do - owner node['jenkins']['server']['user'] + owner node['jenkins']['server']['user'] group node['jenkins']['server']['group'] + variables( :ssh_public_key => sshkey.ssh_public_key ) mode 0644 + action :create_if_missing +end + +ruby_block "store jenkins ssh pubkey" do + block do + node.set[:jenkins][:server][:pubkey] = File.read("#{pkey}.pub") + node.save unless Chef::Config['solo'] + end end directory "#{node['jenkins']['server']['home']}/plugins" do diff --git a/templates/default/id_rsa.pub.erb b/templates/default/id_rsa.pub.erb index 91cecee..2059ba8 100644 --- a/templates/default/id_rsa.pub.erb +++ b/templates/default/id_rsa.pub.erb @@ -1 +1 @@ -<%= node['jenkins']['server']['pubkey'] %> +<%= @ssh_public_key -%> From 067a4fbc98147db8032103fe0f8706127dd81e4d Mon Sep 17 00:00:00 2001 From: Chris Griego Date: Fri, 29 Jun 2012 13:38:28 -0500 Subject: [PATCH 8/9] Create jenkins user as a system user and allow uid to be specified --- README.md | 1 + recipes/default.rb | 2 ++ 2 files changed, 3 insertions(+) diff --git a/README.md b/README.md index 2248bea..bda2b76 100644 --- a/README.md +++ b/README.md @@ -52,6 +52,7 @@ Attributes * jenkins['server']['home'] - JENKINS_HOME directory * jenkins['server']['user'] - User the Jenkins server runs as * jenkins['server']['group'] - Jenkins user primary group +* jenkins['server']['uid'] - User ID the Jenkins server runs as * jenkins['server']['port'] - TCP listen port for the Jenkins server * jenkins['server']['url'] - Base URL of the Jenkins server * jenkins['server']['plugins'] - Download the latest version of plugins in this list, bypassing update center diff --git a/recipes/default.rb b/recipes/default.rb index ff4b48d..537cb14 100644 --- a/recipes/default.rb +++ b/recipes/default.rb @@ -31,6 +31,8 @@ user node['jenkins']['server']['user'] do home node['jenkins']['server']['home'] shell "/bin/bash" + system true + uid node['jenkins']['server']['uid'] if node['jenkins']['server']['uid'] end directory node['jenkins']['server']['home'] do From ce89212b1362bdf4d3e49aba0b8eba300fa3dd95 Mon Sep 17 00:00:00 2001 From: Chris Griego Date: Tue, 3 Jul 2012 20:45:21 -0500 Subject: [PATCH 9/9] Don't use localhost with Jenkins, it seems to prefer ipv6 --- templates/default/apache_jenkins.erb | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/templates/default/apache_jenkins.erb b/templates/default/apache_jenkins.erb index accd556..e37c7f8 100644 --- a/templates/default/apache_jenkins.erb +++ b/templates/default/apache_jenkins.erb @@ -21,14 +21,14 @@ # Local reverse proxy authorization override # Most unix distribution deny proxy by default # (ie /etc/apache2/mods-enabled/proxy.conf in Ubuntu) - /*> + :<%= node['jenkins']['server']['port'] %>/*> Order deny,allow Allow from all ProxyPreserveHost on - ProxyPass / http://localhost:<%= node['jenkins']['server']['port'] %>/ - ProxyPassReverse / http://localhost:<%= node['jenkins']['server']['port'] %>/ + ProxyPass / http://<%= node['fqdn'] %>:<%= node['jenkins']['server']['port'] %>/ + ProxyPassReverse / http://<%= node['fqdn'] %>:<%= node['jenkins']['server']['port'] %>/ <% if node['jenkins']['http_proxy']['basic_auth'] -%>