jenkins-capistrano 0.0.2 → 0.0.3

Sign up to get free protection for your applications and to get access to all the features.
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
@@ -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.6.1'
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
@@ -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.warn "no job configs found." if job_configs.empty?
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
 
@@ -1,5 +1,5 @@
1
1
  module Jenkins
2
2
  module Capistrano
3
- VERSION = "0.0.2"
3
+ VERSION = "0.0.3"
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.2
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.6.1
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.6.1
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.md
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: -981150246330867854
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: -981150246330867854
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