jenkins-capistrano 0.0.4 → 0.0.5

Sign up to get free protection for your applications and to get access to all the features.
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: