Skip to content
This repository was archived by the owner on Aug 2, 2021. It is now read-only.

Commit

Permalink
Allow build jobs to be configured and managed by puppet. Includes vox…
Browse files Browse the repository at this point in the history
  • Loading branch information
jchristi committed Aug 21, 2014
1 parent d0040f6 commit c54187a
Show file tree
Hide file tree
Showing 12 changed files with 386 additions and 5 deletions.
27 changes: 27 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,33 @@ puppet module install rtyler/jenkins
```
Then the service should be running at [http://hostname.example.com:8080/](http://hostname.example.com:8080/).

### Managing Jenkins jobs


Build jobs can be managed using the `jenkins::job` define

#### Creating or updating a build job
```puppet
jenkins::job { 'test-build-job':
config => template("${templates}/test-build-job.xml.erb"),
}
```

#### Disabling a build job
```puppet
jenkins::job { 'test-build-job':
enabled => 0,
config => template("${templates}/test-build-job.xml.erb"),
}
```

#### Removing an existing build job
```puppet
jenkins::job { 'test-build-job':
ensure => 'absent',
}
```

### Installing Jenkins plugins


Expand Down
55 changes: 53 additions & 2 deletions manifests/cli.pp
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,18 @@
fail("Use of private class ${name} by ${caller_module_name}")
}

$jar = '/usr/lib/jenkins/jenkins-cli.jar'
$extract_jar = 'unzip /usr/lib/jenkins/jenkins.war WEB-INF/jenkins-cli.jar'
case $::osfamily {
'Debian': {
$war = '/usr/share/jenkins/jenkins.war'
$jar = '/usr/share/jenkins/jenkins-cli.jar'
}
default: {
$war = '/usr/lib/jenkins/jenkins.war'
$jar = '/usr/lib/jenkins/jenkins-cli.jar'
}
}

$extract_jar = "unzip ${war} WEB-INF/jenkins-cli.jar"
$move_jar = "mv WEB-INF/jenkins-cli.jar ${jar}"
$remove_dir = 'rm -rf WEB-INF'

Expand All @@ -21,4 +31,45 @@
require => Package['jenkins'],
}

file { $jar:
ensure => file,
require => Exec['jenkins-cli'],
}

# Get the value of JENKINS_PORT from config_hash or default
$hash = $::jenkins::config_hash
if is_hash($hash) and has_key($hash, 'JENKINS_PORT') and
has_key($hash['JENKINS_PORT'], 'value') {
$port = $hash['JENKINS_PORT']['value']
} else {
$port = '8080'
}

# The jenkins cli command with required parameter(s)
$cmd = "java -jar ${jar} -s http://localhost:${port}"

# Reload all Jenkins config from disk (only when notified)
exec { 'reload-jenkins':
command => "${cmd} reload-configuration",
tries => 10,
try_sleep => 2,
refreshonly => true,
require => [
Service['jenkins'],
File[$jar],
],
}

# Do a safe restart of Jenkins (only when notified)
exec { 'safe-restart-jenkins':
command => "${cmd} safe-restart && /bin/sleep 10",
tries => 10,
try_sleep => 2,
refreshonly => true,
require => [
Service['jenkins'],
File[$jar],
],
}

}
5 changes: 4 additions & 1 deletion manifests/init.pp
Original file line number Diff line number Diff line change
Expand Up @@ -76,6 +76,7 @@
$service_ensure = $jenkins::params::service_ensure,
$config_hash = {},
$plugin_hash = {},
$job_hash = {},
$configure_firewall = undef,
$install_java = $jenkins::params::install_java,
$proxy_host = undef,
Expand Down Expand Up @@ -103,12 +104,14 @@
class {'jenkins::repo':}
}

class {'jenkins::package': }
class { 'jenkins::package': }

class { 'jenkins::config': }

class { 'jenkins::plugins': }

class { 'jenkins::jobs': }

if $proxy_host and $proxy_port {
class { 'jenkins::proxy':
require => Package['jenkins'],
Expand Down
38 changes: 38 additions & 0 deletions manifests/job.pp
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
# Define: jenkins::job
#
# This class create a new jenkins job given a name and config xml
#
# Parameters:
#
# config
# the content of the jenkins job config file (required)
#
# jobname = $title
# the name of the jenkins job
#
# enabled = true
# whether to enable the job
#
# ensure = 'present'
# choose 'absent' to ensure the job is removed
#
define jenkins::job(
$config,
$jobname = $title,
$enabled = 1,
$ensure = 'present',
){

if ($ensure == 'absent') {
jenkins::job::absent { $title:
jobname => $jobname,
}
} else {
jenkins::job::present { $title:
config => $config,
jobname => $jobname,
enabled => $enabled,
}
}

}
34 changes: 34 additions & 0 deletions manifests/job/absent.pp
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
# Define: jenkins::job::absent
#
# Removes a jenkins build job
#
# Parameters:
#
# config
# the content of the jenkins job config file (required)
#
# jobname = $title
# the name of the jenkins job
#
define jenkins::job::absent(
$jobname = $title,
){
require jenkins::cli

$tmp_config_path = "/tmp/${jobname}-config.xml"
$job_dir = "/var/lib/jenkins/jobs/${jobname}"
$config_path = "${job_dir}/config.xml"

# Temp file to use as stdin for Jenkins CLI executable
file { $tmp_config_path:
ensure => absent,
}

# Delete the job
exec { "jenkins delete-job ${jobname}":
command => "${jenkins::cli::cmd} delete-job ${jobname}",
logoutput => false,
onlyif => "test -f ${config_path}",
}

}
106 changes: 106 additions & 0 deletions manifests/job/present.pp
Original file line number Diff line number Diff line change
@@ -0,0 +1,106 @@
# Define: jenkins::job::present
#
# Creates or updates a jenkins build job
#
# Parameters:
#
# config
# the content of the jenkins job config file (required)
#
# jobname = $title
# the name of the jenkins job
#
# enabled = 1
# if the job should be enabled
#
define jenkins::job::present(
$config,
$jobname = $title,
$enabled = 1,
){
require jenkins::cli

$jenkins_cli = $jenkins::cli::cmd
$tmp_config_path = "/tmp/${jobname}-config.xml"
$job_dir = "/var/lib/jenkins/jobs/${jobname}"
$config_path = "${job_dir}/config.xml"

Exec {
logoutput => false,
path => '/bin:/usr/bin:/sbin:/usr/sbin',
tries => 5,
try_sleep => 5,
}

#
# When a Jenkins job is imported via the cli, Jenkins will
# re-format the xml file based on its own internal rules.
# In order to make job management idempotent, we need to
# apply that formatting before the import, so we can do a diff
# on any pre-existing job to determine if an update is needed.
#
# Jenkins likes to change single quotes to double quotes
$a = regsubst($config, "version='1.0' encoding='UTF-8'",
'version="1.0" encoding="UTF-8"')
# Change empty tags into self-closing tags
$b = regsubst($a, '<([a-z]+)><\/\1>', '<\1/>', 'IG')
# Change &quot; to " since Jenkins is wierd like that
$c = regsubst($b, '&quot;', '"', 'MG')

# Temp file to use as stdin for Jenkins CLI executable
file { $tmp_config_path:
content => $c,
}
#file { 'normalized_content':
# content => normalize_jenkins_job($config),
#}

anchor { "before-create-${jobname}":
require => [
Service['jenkins'],
File[$tmp_config_path]
],
}

# Use Jenkins CLI to create the job
$cat_config = "cat ${tmp_config_path}"
$create_job = "${jenkins_cli} create-job ${jobname}"
exec { "jenkins create-job ${jobname}":
command => "${cat_config} | ${create_job}",
creates => [$config_path, "${job_dir}/builds"],
require => Anchor["before-create-${jobname}"],
}

# Use Jenkins CLI to update the job if it already exists
$update_job = "${jenkins_cli} update-job ${jobname}"
exec { "jenkins update-job ${jobname}":
command => "${cat_config} | ${update_job}",
onlyif => "test -e ${config_path}",
unless => "diff -b -q ${config_path} ${tmp_config_path}",
require => Anchor["before-create-${jobname}"],
notify => Exec['reload-jenkins'],
}

anchor { "after-create-${jobname}":
require => [
Exec["jenkins create-job ${jobname}"],
Exec["jenkins update-job ${jobname}"],
],
}

# Enable or disable the job (if necessary)
if ($enabled == 1) {
exec { "jenkins enable-job ${jobname}":
command => "${jenkins_cli} enable-job ${jobname}",
onlyif => "cat ${config_path} | grep '<disabled>true'",
require => Anchor["after-create-${jobname}"],
}
} else {
exec { "jenkins disable-job ${jobname}":
command => "${jenkins_cli} disable-job ${jobname}",
onlyif => "cat ${config_path} | grep '<disabled>false'",
require => Anchor["after-create-${jobname}"],
}
}

}
11 changes: 11 additions & 0 deletions manifests/jobs.pp
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
# Class: jenkins::jobs
#
class jenkins::jobs {

if $caller_module_name != $module_name {
fail("Use of private class ${name} by ${caller_module_name}")
}

create_resources('jenkins::job',$::jenkins::job_hash)

}
7 changes: 6 additions & 1 deletion spec/classes/jenkins_cli_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -9,9 +9,14 @@
end

context '$cli => true' do
let(:params) { { :cli => true } }
let(:params) {{ :cli => true,
:config_hash => { 'JENKINS_PORT' => { 'value' => '9000' } }
}}
it { should create_class('jenkins::cli') }
it { should contain_exec('jenkins-cli') }
it { should contain_exec('reload-jenkins').with_command(/http:\/\/localhost:9000/) }
it { should contain_exec('safe-restart-jenkins') }
it { should contain_jenkins__sysconfig('JENKINS_PORT').with_value('9000') }
end
end

Expand Down
2 changes: 1 addition & 1 deletion spec/classes/jenkins_config_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@

context 'create config' do
let(:params) { { :config_hash => { 'AJP_PORT' => { 'value' => '1234' } } }}
it { should contain_jenkins__sysconfig('AJP_PORT') }
it { should contain_jenkins__sysconfig('AJP_PORT').with_value('1234') }
end
end

Expand Down
Loading

0 comments on commit c54187a

Please sign in to comment.