jenkins-capistrano 0.0.4 → 0.0.5

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
data/README.rst CHANGED
@@ -51,6 +51,17 @@ deploy.rb::
51
51
 
52
52
  before 'deploy', 'jenkins:deploy_jobs'
53
53
 
54
+ Want to disabling some jobs for specific environment?
55
+ -----------------------------------------------------
56
+
57
+ Since 0.0.5, you can disabling jobs using `disabled_jobs` option.
58
+ Use this option with `multistage-extension <https://github.com/capistrano/capistrano/wiki/2.x-Multistage-Extension>`_.
59
+
60
+ Put the following line into `config/deploy/<env>.rb`::
61
+
62
+ set :disabled_jobs, %w(job1 job2)
63
+
64
+
54
65
  Node Configuration
55
66
  ~~~~~~~~~~~~~~~~~~
56
67
 
@@ -9,7 +9,7 @@ end
9
9
 
10
10
  # Capistrano task for Jenkins.
11
11
  #
12
- # Just add "require 'jenkins-capistrano'" in your Capistrano deploy.rb, and
12
+ # Just add "require 'jenkins-capistrano'" in your Capistrano deploy.rb
13
13
  Capistrano::Configuration.instance(:must_exist).load do
14
14
 
15
15
  _cset(:jenkins_host) { abort "Please specify the host of your jenkins server, set :jenkins_host, 'http://localhost:8080'" }
@@ -20,6 +20,8 @@ Capistrano::Configuration.instance(:must_exist).load do
20
20
  _cset(:jenkins_job_config_dir) { 'config/jenkins/jobs' }
21
21
  _cset(:jenkins_node_config_dir) { 'config/jenkins/nodes' }
22
22
 
23
+ _cset(:disabled_jobs) { [] }
24
+
23
25
  def client
24
26
  @client ||= Jenkins::Client.new(jenkins_host, { :username => jenkins_username, :password => jenkins_password})
25
27
  end
@@ -40,31 +42,48 @@ Capistrano::Configuration.instance(:must_exist).load do
40
42
  namespace :jenkins do
41
43
 
42
44
  desc <<-DESC
43
- Deploy the jobs to Jenkins server -- meaning create or update --
45
+ Deploy the jobs to Jenkins server -- meaning create or update --
46
+
47
+ Configuration
48
+ -------------
49
+ jenkins_job_config_dir
50
+ the directory path where the config.xml stored.
51
+ default: 'config/jenkins/jobs'
52
+
53
+ disabled_jobs
54
+ job names array which should be disabled after deployment.
55
+ default: []
44
56
 
45
- set :jenkins_job_config_dir, 'config/jenkins/jobs'
46
- set :jenkins_job_deploy_strategy, :clean | :merge
47
57
  DESC
48
58
  task :deploy_jobs do
49
- strategy = fetch(:jenkins_job_deploy_strategy, :clean)
50
59
  logger.info "deploying jenkins jobs to #{jenkins_host}"
51
60
  logger.important "no job configs found." if job_configs.empty?
52
61
  job_configs.each do |file|
53
62
  name = File.basename(file, '.xml')
63
+ msg = StringIO.new
64
+
54
65
  client.create_or_update_job(name, File.read(file))
55
- logger.trace "job #{name} created."
66
+ msg << "job #{name} created"
67
+
68
+ if disabled_jobs.include? name
69
+ client.disable_job(name)
70
+ msg << ", but was set to disabled"
71
+ end
72
+ msg << "."
73
+ logger.trace msg.string
56
74
  end
57
-
58
75
  end
59
76
 
60
77
  desc <<-DESC
61
- Configure the nodes to Jenkins server -- meaning create or update --
78
+ Configure the nodes to Jenkins server -- meaning create or update --
62
79
 
63
- set :jenkins_node_config_dir, 'config/jenkins/nodes'
64
- set :jenkins_node_deploy_strategy, :clean | :merge
80
+ Configuration
81
+ -------------
82
+ jenkins_node_config_dir
83
+ the directory path where the node's configuration stored.
84
+ default: 'config/jenkins/nodes'
65
85
  DESC
66
86
  task :config_nodes do
67
- strategy = fetch(:jenkins_node_deploy_strategy, :clean)
68
87
  logger.info "configuring jenkins nodes to #{jenkins_host}"
69
88
  logger.important "no node configs found." if node_configs.empty?
70
89
  node_configs.each do |file|
@@ -1,6 +1,8 @@
1
1
  require 'httparty'
2
2
  require 'cgi/util'
3
3
  require 'json'
4
+ require 'jenkins-capistrano/client/node'
5
+ require 'jenkins-capistrano/client/job'
4
6
 
5
7
  module Jenkins
6
8
  class Client
@@ -16,137 +18,15 @@ module Jenkins
16
18
  self.class.basic_auth opts[:username], opts[:password] if opts[:username] and opts[:password]
17
19
  end
18
20
 
19
- def create_job(name, config)
20
- res = self.class.post("/createItem/api/xml?name=#{CGI.escape(name)}", xml_body(config))
21
- raise ServerError, parse_error_message(res) unless res.code.to_i == 200
22
- rescue => e
23
- raise ServerError, "Failed to create job: #{name}, make sure you have specified auth info properly"
24
- end
25
-
26
- def update_job(name, config)
27
- res = self.class.post("/job/#{CGI.escape(name)}/config.xml", xml_body(config))
28
- raise ServerError, parse_error_message(res) unless res.code.to_i == 200
29
- rescue => e
30
- raise ServerError, "Failed to create job: #{name}, make sure you have specified auth info properly"
31
- end
32
-
33
- def create_or_update_job(name, config)
34
- begin
35
- create_job(name, config)
36
- rescue ServerError => e
37
- update_job(name, config)
38
- end
39
- end
40
-
41
- def add_node(name, opts = {})
42
- options = default_node_options.merge(opts)
43
- options[:name] = name
44
- options[:labels] = options[:labels].split(/\s*,\s*/).join(' ') if options[:labels]
45
- options[:env_vars] = options[:env_vars].map { |k, v| { :key => k, :value => v } }
46
-
47
- response = post_form("/computer/doCreateItem", node_form_fields(options))
48
- case response
49
- when Net::HTTPFound
50
- { :name => name, :slave_host => options[:slave_host] }
51
- else
52
- raise ServerError, parse_error_message(response)
53
- end
54
- end
55
-
56
- def update_node(name, opts = {})
57
- options = default_node_options.merge(opts)
58
- options[:name] = name
59
- options[:labels] = options[:labels].split(/\s*,\s*/).join(' ') if options[:labels]
60
- options[:env_vars] = options[:env_vars].map { |k, v| { :key => k, :value => v } }
61
-
62
- response = post_form("/computer/#{CGI::escape(name)}/configSubmit", node_form_fields(options))
63
- case response
64
- when Net::HTTPFound
65
- { :name => name, :slave_host => options[:slave_host] }
66
- else
67
- raise ServerError, parse_error_message(response)
68
- end
69
- end
70
-
71
- def config_node(name, opts = {})
72
- begin
73
- add_node(name, opts)
74
- rescue ServerError => e
75
- update_node(name, opts)
76
- end
77
- end
78
-
79
- private
80
- def xml_body(xml_str)
81
- {
82
- :body => xml_str,
83
- :format => :xml,
84
- :headers => { 'content-type' => 'application/xml' }
85
- }
86
- end
87
-
88
21
  def parse_error_message(response)
89
22
  require "hpricot"
90
23
  doc = Hpricot(response.body)
91
24
  error_msg = doc.search("td#main-panel p")
92
- error_msg.inner_text.empty? ? "Server error: code=#{response.code}, #{response.body}" : error_msg
25
+ error_msg.inner_text.empty? ? doc.search("body").text : error_msg
93
26
  end
94
27
 
95
- def post_form(path, fields)
96
- url = URI.parse("#{self.class.base_uri}/#{path}")
97
- req = Net::HTTP::Post.new(url.path)
98
-
99
- basic_auth = self.class.default_options[:basic_auth]
100
- req.basic_auth basic_auth[:username], basic_auth[:password] if basic_auth
101
-
102
- req.set_form_data(fields)
103
- http = Net::HTTP.new(url.host, url.port)
104
- http.request(req)
105
- end
106
-
107
- def default_node_options
108
- {
109
- :slave_port => 22,
110
- :slave_user => 'jenkins',
111
- :master_key => "/var/lib/jenkins/.ssh/id_rsa",
112
- :slave_fs => "/data/jenkins-slave/",
113
- :description => "Automatically created by capistrano-jenkins",
114
- :executors => 2,
115
- :exclusive => true
116
- }
117
- end
118
-
119
- def node_form_fields(options = {})
120
- {
121
- "name" => options[:name],
122
- "type" => "hudson.slaves.DumbSlave$DescriptorImpl",
123
- "json" => {
124
- "name" => options[:name],
125
- "type" => "hudson.slaves.DumbSlave$DescriptorImpl",
126
- "nodeDescription" => options[:description],
127
- "numExecutors" => options[:executors],
128
- "remoteFS" => options[:slave_fs],
129
- "labelString" => options[:labels],
130
- "mode" => options[:exclusive] ? "EXCLUSIVE" : "NORMAL",
131
- "retentionStrategy" => { "stapler-class" => "hudson.slaves.RetentionStrategy$Always" },
132
- "launcher" => {
133
- "stapler-class" => "hudson.plugins.sshslaves.SSHLauncher",
134
- "host" => options[:slave_host],
135
- "port" => options[:slave_port],
136
- "username" => options[:slave_user],
137
- "privatekey" => options[:master_key],
138
- "javaPath" => options[:java_path],
139
- "jvmOptions" => options[:jvm_options]
140
- },
141
- "nodeProperties" => {
142
- "stapler-class-bag" => "true",
143
- "hudson-slaves-EnvironmentVariablesNodeProperty" => {
144
- "env" => options[:env_vars]
145
- }
146
- }
147
- }.to_json
148
- }
149
- end
28
+ include Node
29
+ include Job
150
30
 
151
31
  end
152
32
  end
@@ -0,0 +1,47 @@
1
+
2
+ module Jenkins
3
+ class Client
4
+ module Job
5
+
6
+ def job_names
7
+ self.class.get("/api/json")['jobs'].map {|job| job['name'] }
8
+ end
9
+
10
+ def create_job(name, config)
11
+ res = self.class.post("/createItem/api/xml?name=#{CGI.escape(name)}", xml_body(config))
12
+ raise ServerError, parse_error_message(res) unless res.code.to_i == 200
13
+ rescue => e
14
+ raise ServerError, "Failed to create job: #{name}, make sure you have specified auth info properly"
15
+ end
16
+
17
+ def update_job(name, config)
18
+ res = self.class.post("/job/#{CGI.escape(name)}/config.xml", xml_body(config))
19
+ raise ServerError, parse_error_message(res) unless res.code.to_i == 200
20
+ rescue => e
21
+ raise ServerError, "Failed to create job: #{name}, make sure you have specified auth info properly"
22
+ end
23
+
24
+ def create_or_update_job(name, config)
25
+ job_names.include?(name) ? update_job(name, config) : create_job(name, config)
26
+ end
27
+
28
+ def disable_job(name)
29
+ res = self.class.post("/job/#{CGI.escape(name)}/disable")
30
+ raise ServerError, parse_error_message(res) unless res.code.to_i == 200
31
+ rescue => e
32
+ raise ServerError, "Failed to create job: #{name}, make sure you have specified auth info properly"
33
+ end
34
+
35
+ private
36
+ def xml_body(xml_str)
37
+ {
38
+ :body => xml_str,
39
+ :format => :xml,
40
+ :headers => { 'content-type' => 'application/xml' }
41
+ }
42
+ end
43
+
44
+ end
45
+ end
46
+ end
47
+
@@ -0,0 +1,103 @@
1
+
2
+ module Jenkins
3
+ class Client
4
+ module Node
5
+
6
+ def node_names
7
+ self.class.get("/computer/api/json")['computer'].map {|computer| computer['displayName'] }
8
+ end
9
+
10
+ def add_node(name, opts = {})
11
+ options = default_node_options.merge(opts)
12
+ options[:name] = name
13
+ options[:labels] = options[:labels].split(/\s*,\s*/).join(' ') if options[:labels]
14
+ options[:env_vars] = options[:env_vars].map { |k, v| { :key => k, :value => v } }
15
+
16
+ response = post_form("/computer/doCreateItem", node_form_fields(options))
17
+ case response
18
+ when Net::HTTPFound
19
+ { :name => name, :slave_host => options[:slave_host] }
20
+ else
21
+ raise ServerError, parse_error_message(response)
22
+ end
23
+ end
24
+
25
+ def update_node(name, opts = {})
26
+ options = default_node_options.merge(opts)
27
+ options[:name] = name
28
+ options[:labels] = options[:labels].split(/\s*,\s*/).join(' ') if options[:labels]
29
+ options[:env_vars] = options[:env_vars].map { |k, v| { :key => k, :value => v } }
30
+
31
+ response = post_form("/computer/#{CGI::escape(name)}/configSubmit", node_form_fields(options))
32
+ case response
33
+ when Net::HTTPFound
34
+ { :name => name, :slave_host => options[:slave_host] }
35
+ else
36
+ raise ServerError, parse_error_message(response)
37
+ end
38
+ end
39
+
40
+ def config_node(name, opts = {})
41
+ node_names.include?(name) ? update_node(name, config) : add_node(name, config)
42
+ end
43
+
44
+ private
45
+ def post_form(path, fields)
46
+ url = URI.parse("#{self.class.base_uri}/#{path}")
47
+ req = Net::HTTP::Post.new(url.path)
48
+
49
+ basic_auth = self.class.default_options[:basic_auth]
50
+ req.basic_auth basic_auth[:username], basic_auth[:password] if basic_auth
51
+
52
+ req.set_form_data(fields)
53
+ http = Net::HTTP.new(url.host, url.port)
54
+ http.request(req)
55
+ end
56
+
57
+ def default_node_options
58
+ {
59
+ :slave_port => 22,
60
+ :slave_user => 'jenkins',
61
+ :master_key => "/var/lib/jenkins/.ssh/id_rsa",
62
+ :slave_fs => "/data/jenkins-slave/",
63
+ :description => "Automatically created by capistrano-jenkins",
64
+ :executors => 2,
65
+ :exclusive => true
66
+ }
67
+ end
68
+
69
+ def node_form_fields(options = {})
70
+ {
71
+ "name" => options[:name],
72
+ "type" => "hudson.slaves.DumbSlave$DescriptorImpl",
73
+ "json" => {
74
+ "name" => options[:name],
75
+ "type" => "hudson.slaves.DumbSlave$DescriptorImpl",
76
+ "nodeDescription" => options[:description],
77
+ "numExecutors" => options[:executors],
78
+ "remoteFS" => options[:slave_fs],
79
+ "labelString" => options[:labels],
80
+ "mode" => options[:exclusive] ? "EXCLUSIVE" : "NORMAL",
81
+ "retentionStrategy" => { "stapler-class" => "hudson.slaves.RetentionStrategy$Always" },
82
+ "launcher" => {
83
+ "stapler-class" => "hudson.plugins.sshslaves.SSHLauncher",
84
+ "host" => options[:slave_host],
85
+ "port" => options[:slave_port],
86
+ "username" => options[:slave_user],
87
+ "privatekey" => options[:master_key],
88
+ "javaPath" => options[:java_path],
89
+ "jvmOptions" => options[:jvm_options]
90
+ },
91
+ "nodeProperties" => {
92
+ "stapler-class-bag" => "true",
93
+ "hudson-slaves-EnvironmentVariablesNodeProperty" => {
94
+ "env" => options[:env_vars]
95
+ }
96
+ }
97
+ }.to_json
98
+ }
99
+ end
100
+ end
101
+ end
102
+ end
103
+
@@ -1,5 +1,5 @@
1
1
  module Jenkins
2
2
  module Capistrano
3
- VERSION = "0.0.4"
3
+ VERSION = "0.0.5"
4
4
  end
5
5
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: jenkins-capistrano
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.4
4
+ version: 0.0.5
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -9,7 +9,7 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2012-06-24 00:00:00.000000000 Z
12
+ date: 2012-10-24 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: capistrano
@@ -106,6 +106,8 @@ files:
106
106
  - jenkins-capistrano.gemspec
107
107
  - lib/jenkins-capistrano.rb
108
108
  - lib/jenkins-capistrano/client.rb
109
+ - lib/jenkins-capistrano/client/job.rb
110
+ - lib/jenkins-capistrano/client/node.rb
109
111
  - lib/jenkins-capistrano/version.rb
110
112
  homepage: https://github.com/cynipe/jenkins-capistrano
111
113
  licenses: []
@@ -119,18 +121,12 @@ required_ruby_version: !ruby/object:Gem::Requirement
119
121
  - - ! '>='
120
122
  - !ruby/object:Gem::Version
121
123
  version: '0'
122
- segments:
123
- - 0
124
- hash: 2200036594680116764
125
124
  required_rubygems_version: !ruby/object:Gem::Requirement
126
125
  none: false
127
126
  requirements:
128
127
  - - ! '>='
129
128
  - !ruby/object:Gem::Version
130
129
  version: '0'
131
- segments:
132
- - 0
133
- hash: 2200036594680116764
134
130
  requirements: []
135
131
  rubyforge_project:
136
132
  rubygems_version: 1.8.24
@@ -138,3 +134,4 @@ signing_key:
138
134
  specification_version: 3
139
135
  summary: ''
140
136
  test_files: []
137
+ has_rdoc: