jenkins-capistrano 0.0.2 → 0.0.3
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 +86 -0
- data/jenkins-capistrano.gemspec +2 -1
- data/lib/jenkins-capistrano.rb +28 -1
- data/lib/jenkins-capistrano/client.rb +88 -0
- data/lib/jenkins-capistrano/version.rb +1 -1
- metadata +22 -6
- data/README.md +0 -53
data/README.rst
ADDED
@@ -0,0 +1,86 @@
|
|
1
|
+
==================
|
2
|
+
jenkins-capistrano
|
3
|
+
==================
|
4
|
+
|
5
|
+
The capistrano tasks for Jenkins CI Server
|
6
|
+
|
7
|
+
Installation
|
8
|
+
============
|
9
|
+
|
10
|
+
Add this line to your application's Gemfile::
|
11
|
+
|
12
|
+
gem 'jenkins-capistrano'
|
13
|
+
|
14
|
+
And then execute::
|
15
|
+
|
16
|
+
$ bundle
|
17
|
+
|
18
|
+
Or install it yourself as::
|
19
|
+
|
20
|
+
$ gem install jenkins-capistrano
|
21
|
+
|
22
|
+
Example
|
23
|
+
=======
|
24
|
+
|
25
|
+
Job Configuration
|
26
|
+
~~~~~~~~~~~~~~~~~
|
27
|
+
|
28
|
+
The following code will creates or updates Jenkins jobs before each deploy task:
|
29
|
+
|
30
|
+
config directory structure(name your config.xml as a job name)::
|
31
|
+
|
32
|
+
config
|
33
|
+
├── deploy.rb
|
34
|
+
└── jenkins
|
35
|
+
└── jobs
|
36
|
+
├── job-name1.xml
|
37
|
+
├── job-name2.xml
|
38
|
+
└── job-name3.xml
|
39
|
+
|
40
|
+
|
41
|
+
deploy.rb::
|
42
|
+
|
43
|
+
set :application, "your-awesome-app"
|
44
|
+
set :scm, :git
|
45
|
+
set :repository, "https://github.com/your/repository.git"
|
46
|
+
|
47
|
+
set :jenkins_host, 'http://localhost:8080'
|
48
|
+
# set :jenkins_username, '' # default empty
|
49
|
+
# set :jenkins_password, '' # default empty
|
50
|
+
# set :jenkins_job_config_dir, 'config/jenkins/jobs'
|
51
|
+
|
52
|
+
before 'deploy', 'jenkins:deploy_jobs'
|
53
|
+
|
54
|
+
Node Configuration
|
55
|
+
~~~~~~~~~~~~~~~~~~
|
56
|
+
|
57
|
+
config directory structure::
|
58
|
+
|
59
|
+
config
|
60
|
+
├── deploy.rb
|
61
|
+
└── jenkins
|
62
|
+
└── nodes
|
63
|
+
├── node1.json
|
64
|
+
├── node2.json
|
65
|
+
└── node3.json
|
66
|
+
|
67
|
+
deploy.rb::
|
68
|
+
|
69
|
+
set :application, "your-awesome-app"
|
70
|
+
set :scm, :git
|
71
|
+
set :repository, "https://github.com/your/repository.git"
|
72
|
+
|
73
|
+
set :jenkins_host, 'http://localhost:8080'
|
74
|
+
# set :jenkins_username, '' # default empty
|
75
|
+
# set :jenkins_password, '' # default empty
|
76
|
+
# set :jenkins_node_config_dir, 'config/jenkins/nodes'
|
77
|
+
|
78
|
+
before 'deploy', 'jenkins:config_nodes'
|
79
|
+
|
80
|
+
## Contributing
|
81
|
+
|
82
|
+
1. Fork it
|
83
|
+
2. Create your feature branch (`git checkout -b my-new-feature`)
|
84
|
+
3. Commit your changes (`git commit -am 'Added some feature'`)
|
85
|
+
4. Push to the branch (`git push origin my-new-feature`)
|
86
|
+
5. Create new Pull Request
|
data/jenkins-capistrano.gemspec
CHANGED
@@ -16,8 +16,9 @@ Gem::Specification.new do |gem|
|
|
16
16
|
gem.version = Jenkins::Capistrano::VERSION
|
17
17
|
|
18
18
|
gem.add_dependency 'capistrano'
|
19
|
-
gem.add_dependency 'httparty', '~> 0.
|
19
|
+
gem.add_dependency 'httparty', '~> 0.8.3'
|
20
20
|
gem.add_dependency 'hpricot'
|
21
21
|
|
22
22
|
gem.add_development_dependency 'rake'
|
23
|
+
gem.add_development_dependency 'pry'
|
23
24
|
end
|
data/lib/jenkins-capistrano.rb
CHANGED
@@ -18,15 +18,22 @@ Capistrano::Configuration.instance(:must_exist).load do
|
|
18
18
|
_cset(:jenkins_password) { '' }
|
19
19
|
|
20
20
|
_cset(:jenkins_job_config_dir) { 'config/jenkins/jobs' }
|
21
|
+
_cset(:jenkins_node_config_dir) { 'config/jenkins/nodes' }
|
21
22
|
|
22
23
|
def client
|
23
24
|
@client ||= Jenkins::Client.new(jenkins_host, { :username => jenkins_username, :password => jenkins_password})
|
24
25
|
end
|
25
26
|
|
26
27
|
def job_configs
|
28
|
+
abort "Please create the jenkins_job_config_dir first: #{jenkins_job_config_dir}" unless Dir.exists? jenkins_job_config_dir
|
27
29
|
Dir.glob("#{jenkins_job_config_dir}/*.xml")
|
28
30
|
end
|
29
31
|
|
32
|
+
def node_configs
|
33
|
+
abort "Please create the jenkins_node_config_dir first: #{jenkins_node_config_dir}" unless Dir.exists? jenkins_node_config_dir
|
34
|
+
Dir.glob("#{jenkins_node_config_dir}/*.json")
|
35
|
+
end
|
36
|
+
|
30
37
|
# minimum configurations
|
31
38
|
#
|
32
39
|
# role :jenkins, 'localhost:8080'
|
@@ -41,7 +48,7 @@ Capistrano::Configuration.instance(:must_exist).load do
|
|
41
48
|
task :deploy_jobs do
|
42
49
|
strategy = fetch(:jenkins_job_deploy_strategy, :clean)
|
43
50
|
logger.info "deploying jenkins jobs to #{jenkins_host}"
|
44
|
-
logger.
|
51
|
+
logger.important "no job configs found." if job_configs.empty?
|
45
52
|
job_configs.each do |file|
|
46
53
|
name = File.basename(file, '.xml')
|
47
54
|
client.create_or_update_job(name, File.read(file))
|
@@ -50,6 +57,26 @@ Capistrano::Configuration.instance(:must_exist).load do
|
|
50
57
|
|
51
58
|
end
|
52
59
|
|
60
|
+
desc <<-DESC
|
61
|
+
Configure the nodes to Jenkins server -- meaning create or update --
|
62
|
+
|
63
|
+
set :jenkins_node_config_dir, 'config/jenkins/nodes'
|
64
|
+
set :jenkins_node_deploy_strategy, :clean | :merge
|
65
|
+
DESC
|
66
|
+
task :config_nodes do
|
67
|
+
strategy = fetch(:jenkins_node_deploy_strategy, :clean)
|
68
|
+
logger.info "configuring jenkins nodes to #{jenkins_host}"
|
69
|
+
logger.important "no node configs found." if node_configs.empty?
|
70
|
+
node_configs.each do |file|
|
71
|
+
name = File.basename(file, '.json')
|
72
|
+
opts = JSON.parse(File.read(file)).to_hash.
|
73
|
+
inject({}) { |mem, (key, val)| mem[key.to_sym] = val; mem }
|
74
|
+
client.config_node(name, opts)
|
75
|
+
logger.trace "node #{name} created."
|
76
|
+
end
|
77
|
+
|
78
|
+
end
|
79
|
+
|
53
80
|
end
|
54
81
|
|
55
82
|
end
|
@@ -1,5 +1,6 @@
|
|
1
1
|
require 'httparty'
|
2
2
|
require 'cgi/util'
|
3
|
+
require 'json'
|
3
4
|
|
4
5
|
module Jenkins
|
5
6
|
class Client
|
@@ -37,6 +38,42 @@ module Jenkins
|
|
37
38
|
end
|
38
39
|
end
|
39
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
|
+
|
46
|
+
response = post_form("/computer/doCreateItem", node_form_fields(options))
|
47
|
+
case response
|
48
|
+
when Net::HTTPFound
|
49
|
+
{ :name => options[:name], :slave_host => options[:slave_host] }
|
50
|
+
else
|
51
|
+
raise ServerError, parse_error_message(response)
|
52
|
+
end
|
53
|
+
end
|
54
|
+
|
55
|
+
def update_node(name, opts = {})
|
56
|
+
options = default_node_options.merge(opts)
|
57
|
+
options[:name] = name
|
58
|
+
options[:labels] = options[:labels].split(/\s*,\s*/).join(' ') if options[:labels]
|
59
|
+
|
60
|
+
response = post_form("/computer/#{CGI::escape(name)}/configSubmit", node_form_fields(options))
|
61
|
+
case response
|
62
|
+
when Net::HTTPFound
|
63
|
+
{ :name => options[:name], :slave_host => options[:slave_host] }
|
64
|
+
else
|
65
|
+
raise ServerError, parse_error_message(response)
|
66
|
+
end
|
67
|
+
end
|
68
|
+
|
69
|
+
def config_node(name, opts = {})
|
70
|
+
begin
|
71
|
+
add_node(name, opts)
|
72
|
+
rescue ServerError => e
|
73
|
+
update_node(name, opts)
|
74
|
+
end
|
75
|
+
end
|
76
|
+
|
40
77
|
private
|
41
78
|
def xml_body(xml_str)
|
42
79
|
{
|
@@ -52,6 +89,57 @@ module Jenkins
|
|
52
89
|
error_msg = doc.search("td#main-panel p")
|
53
90
|
error_msg.inner_text.empty? ? "Server error: code=#{response.code}, #{response.body}" : error_msg
|
54
91
|
end
|
92
|
+
|
93
|
+
def post_form(path, fields)
|
94
|
+
url = URI.parse("#{self.class.base_uri}/#{path}")
|
95
|
+
req = Net::HTTP::Post.new(url.path)
|
96
|
+
|
97
|
+
basic_auth = self.class.default_options[:basic_auth]
|
98
|
+
req.basic_auth basic_auth[:username], basic_auth[:password] if basic_auth
|
99
|
+
|
100
|
+
req.set_form_data(fields)
|
101
|
+
http = Net::HTTP.new(url.host, url.port)
|
102
|
+
http.request(req)
|
103
|
+
end
|
104
|
+
|
105
|
+
def default_node_options
|
106
|
+
{
|
107
|
+
:slave_port => 22,
|
108
|
+
:slave_user => 'jenkins',
|
109
|
+
:master_key => "/var/lib/jenkins/.ssh/id_rsa",
|
110
|
+
:slave_fs => "/data/jenkins-slave/",
|
111
|
+
:description => "Automatically created by capistrano-jenkins",
|
112
|
+
:executors => 2,
|
113
|
+
:exclusive => true
|
114
|
+
}
|
115
|
+
end
|
116
|
+
|
117
|
+
def node_form_fields(options = {})
|
118
|
+
{
|
119
|
+
"name" => options[:name],
|
120
|
+
"type" => "hudson.slaves.DumbSlave$DescriptorImpl",
|
121
|
+
"json" => {
|
122
|
+
"name" => options[:name],
|
123
|
+
"type" => "hudson.slaves.DumbSlave$DescriptorImpl",
|
124
|
+
"nodeDescription" => options[:description],
|
125
|
+
"numExecutors" => options[:executors],
|
126
|
+
"remoteFS" => options[:slave_fs],
|
127
|
+
"labelString" => options[:labels],
|
128
|
+
"mode" => options[:exclusive] ? "EXCLUSIVE" : "NORMAL",
|
129
|
+
"retentionStrategy" => { "stapler-class" => "hudson.slaves.RetentionStrategy$Always" },
|
130
|
+
"nodeProperties" => { "stapler-class-bag" => "true" },
|
131
|
+
"launcher" => {
|
132
|
+
"stapler-class" => "hudson.plugins.sshslaves.SSHLauncher",
|
133
|
+
"host" => options[:slave_host],
|
134
|
+
"port" => options[:slave_port],
|
135
|
+
"username" => options[:slave_user],
|
136
|
+
"privatekey" => options[:master_key],
|
137
|
+
}
|
138
|
+
}.to_json
|
139
|
+
}
|
140
|
+
end
|
141
|
+
|
142
|
+
|
55
143
|
end
|
56
144
|
end
|
57
145
|
|
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
|
+
version: 0.0.3
|
5
5
|
prerelease:
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
@@ -34,7 +34,7 @@ dependencies:
|
|
34
34
|
requirements:
|
35
35
|
- - ~>
|
36
36
|
- !ruby/object:Gem::Version
|
37
|
-
version: 0.
|
37
|
+
version: 0.8.3
|
38
38
|
type: :runtime
|
39
39
|
prerelease: false
|
40
40
|
version_requirements: !ruby/object:Gem::Requirement
|
@@ -42,7 +42,7 @@ dependencies:
|
|
42
42
|
requirements:
|
43
43
|
- - ~>
|
44
44
|
- !ruby/object:Gem::Version
|
45
|
-
version: 0.
|
45
|
+
version: 0.8.3
|
46
46
|
- !ruby/object:Gem::Dependency
|
47
47
|
name: hpricot
|
48
48
|
requirement: !ruby/object:Gem::Requirement
|
@@ -75,6 +75,22 @@ dependencies:
|
|
75
75
|
- - ! '>='
|
76
76
|
- !ruby/object:Gem::Version
|
77
77
|
version: '0'
|
78
|
+
- !ruby/object:Gem::Dependency
|
79
|
+
name: pry
|
80
|
+
requirement: !ruby/object:Gem::Requirement
|
81
|
+
none: false
|
82
|
+
requirements:
|
83
|
+
- - ! '>='
|
84
|
+
- !ruby/object:Gem::Version
|
85
|
+
version: '0'
|
86
|
+
type: :development
|
87
|
+
prerelease: false
|
88
|
+
version_requirements: !ruby/object:Gem::Requirement
|
89
|
+
none: false
|
90
|
+
requirements:
|
91
|
+
- - ! '>='
|
92
|
+
- !ruby/object:Gem::Version
|
93
|
+
version: '0'
|
78
94
|
description: The capistrano tasks for Jenkins CI Server
|
79
95
|
email:
|
80
96
|
- cynipe@gmail.com
|
@@ -85,7 +101,7 @@ files:
|
|
85
101
|
- .gitignore
|
86
102
|
- Gemfile
|
87
103
|
- LICENSE
|
88
|
-
- README.
|
104
|
+
- README.rst
|
89
105
|
- Rakefile
|
90
106
|
- jenkins-capistrano.gemspec
|
91
107
|
- lib/jenkins-capistrano.rb
|
@@ -105,7 +121,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
105
121
|
version: '0'
|
106
122
|
segments:
|
107
123
|
- 0
|
108
|
-
hash:
|
124
|
+
hash: 2715284464672624709
|
109
125
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
110
126
|
none: false
|
111
127
|
requirements:
|
@@ -114,7 +130,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
114
130
|
version: '0'
|
115
131
|
segments:
|
116
132
|
- 0
|
117
|
-
hash:
|
133
|
+
hash: 2715284464672624709
|
118
134
|
requirements: []
|
119
135
|
rubyforge_project:
|
120
136
|
rubygems_version: 1.8.24
|
data/README.md
DELETED
@@ -1,53 +0,0 @@
|
|
1
|
-
# jenkins-capistrano
|
2
|
-
|
3
|
-
The capistrano tasks for Jenkins CI Server
|
4
|
-
|
5
|
-
## Installation
|
6
|
-
|
7
|
-
Add this line to your application's Gemfile:
|
8
|
-
|
9
|
-
gem 'jenkins-capistrano'
|
10
|
-
|
11
|
-
And then execute:
|
12
|
-
|
13
|
-
$ bundle
|
14
|
-
|
15
|
-
Or install it yourself as:
|
16
|
-
|
17
|
-
$ gem install jenkins-capistrano
|
18
|
-
|
19
|
-
## Example
|
20
|
-
|
21
|
-
The following code will creates or updates Jenkins jobs before each deploy task:
|
22
|
-
|
23
|
-
config directory structure(name your config.xml as a job name):
|
24
|
-
|
25
|
-
config
|
26
|
-
├── deploy.rb
|
27
|
-
└── jenkins
|
28
|
-
└── jobs
|
29
|
-
├── job-name1.xml
|
30
|
-
├── job-name2.xml
|
31
|
-
└── job-name3.xml
|
32
|
-
|
33
|
-
|
34
|
-
deploy.rb:
|
35
|
-
|
36
|
-
set :application, "your-awesome-app"
|
37
|
-
set :scm, :git
|
38
|
-
set :repository, "https://github.com/your/repository.git"
|
39
|
-
|
40
|
-
set :jenkins_host, 'http://localhost:8080'
|
41
|
-
# set :jenkins_username, '' # default empty
|
42
|
-
# set :jenkins_password, '' # default empty
|
43
|
-
# set :jenkins_job_config_dir, 'config/jenkins/jobs'
|
44
|
-
|
45
|
-
before 'deploy', 'jenkins:deploy_jobs'
|
46
|
-
|
47
|
-
## Contributing
|
48
|
-
|
49
|
-
1. Fork it
|
50
|
-
2. Create your feature branch (`git checkout -b my-new-feature`)
|
51
|
-
3. Commit your changes (`git commit -am 'Added some feature'`)
|
52
|
-
4. Push to the branch (`git push origin my-new-feature`)
|
53
|
-
5. Create new Pull Request
|