Module: Jenkins::Api
- Includes:
- HTTParty
- Defined in:
- lib/jenkins/api.rb
Constant Summary collapse
- JobAlreadyExistsError =
http_proxy ‘localhost’, ‘8888’
Class.new(Exception)
Class Method Summary collapse
-
.add_node(options = {}) ⇒ Object
Adds SSH nodes only, for now.
-
.build_details(job_name, build_number) ⇒ Object
Return a hash of information about a build.
- .build_job(name) ⇒ Object
-
.create_job(name, job_config, options = {}) ⇒ Object
returns true if successfully create a new job on Jenkins
job_config
is a Jenkins::JobConfigBuilder instanceoptions
are: :override - true, will delete any existing job with same name, else error. -
.delete_job(name) ⇒ Object
Attempts to delete a job
name
. - .delete_node(name) ⇒ Object
-
.get_plain(path, options = {}) ⇒ Object
Helper for GET that don’t barf at Jenkins’s crappy API responses.
-
.job(name) ⇒ Object
Return hash of job statuses.
- .job_names ⇒ Object
- .nodes ⇒ Object
-
.post_plain(path, data = "", options = {}) ⇒ Object
Helper for POST that don’t barf at Jenkins’s crappy API responses.
- .setup_base_url(options) ⇒ Object
- .summary ⇒ Object
Class Method Details
.add_node(options = {}) ⇒ Object
Adds SSH nodes only, for now
120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 |
# File 'lib/jenkins/api.rb', line 120 def self.add_node( = {}) = .with_clean_keys = Hash.new if [:vagrant] .merge!( :slave_port => 2222, :slave_user => 'vagrant', :master_key => "/Library/Ruby/Gems/1.8/gems/vagrant-0.6.7/keys/vagrant", # FIXME - hardcoded master username assumption :slave_fs => "/vagrant/tmp/jenkins-slave/", :description => "Automatically created by Jenkins.rb", :executors => 2, :exclusive => true ) else .merge!( :slave_port => 22, :slave_user => 'deploy', :master_key => "/home/deploy/.ssh/id_rsa", # FIXME - hardcoded master username assumption :slave_fs => "/data/jenkins-slave/", :description => "Automatically created by Jenkins.rb", :executors => 2, :exclusive => true ) end = .merge() slave_host = [:slave_host] name = [:name] || slave_host labels = [:labels].split(/\s*,\s*/).join(' ') if [:labels] type = "hudson.slaves.DumbSlave$DescriptorImpl" fields = { "name" => name, "type" => type, "json" => { "name" => name, "nodeDescription" => [:description], "numExecutors" => [:executors], "remoteFS" => [:slave_fs], "labelString" => labels, "mode" => [:exclusive] ? "EXCLUSIVE" : "NORMAL", "type" => type, "retentionStrategy" => { "stapler-class" => "hudson.slaves.RetentionStrategy$Always" }, "nodeProperties" => { "stapler-class-bag" => "true" }, "launcher" => { "stapler-class" => "hudson.plugins.sshslaves.SSHLauncher", "host" => slave_host, "port" => [:slave_port], "username" => [:slave_user], "privatekey" => [:master_key], } }.to_json } url = URI.parse("#{base_uri}/computer/doCreateItem") req = Net::HTTP::Post.new(url.path) req.set_form_data(fields) http = Net::HTTP.new(url.host, url.port) response = http.request(req) case response when Net::HTTPFound { :name => name, :slave_host => slave_host } else # error message looks like: # <td id="main-panel"> # <h1>Error</h1><p>Slave called 'localhost' already exists</p> require "hpricot" error = Hpricot(response.body).search("td#main-panel p").text unless error.blank? puts error else puts response.body # so we can find other errors end false end end |
.build_details(job_name, build_number) ⇒ Object
Return a hash of information about a build.
103 104 105 106 107 108 109 110 111 |
# File 'lib/jenkins/api.rb', line 103 def self.build_details(job_name, build_number) begin json = get "/job/#{job_name}/#{build_number}/api/json" cache_base_uri json rescue Crack::ParseError false end end |
.build_job(name) ⇒ Object
76 77 78 79 |
# File 'lib/jenkins/api.rb', line 76 def self.build_job(name) res = get_plain "/job/#{name}/build" res.code.to_i == 302 end |
.create_job(name, job_config, options = {}) ⇒ Object
returns true if successfully create a new job on Jenkins job_config
is a Jenkins::JobConfigBuilder instance options
are:
:override - true, will delete any existing job with same name, else error
returns true if successful, else false
TODO Exceptions?
40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 |
# File 'lib/jenkins/api.rb', line 40 def self.create_job(name, job_config, = {}) = .with_clean_keys delete_job(name) if [:override] begin res = post "/createItem/api/xml?name=#{CGI.escape(name)}", { :body => job_config.to_xml, :format => :xml, :headers => { 'content-type' => 'application/xml' } } if res.code.to_i == 200 cache_base_uri true else require "hpricot" doc = Hpricot(res.body) error_msg = doc.search("td#main-panel p") unless error_msg.inner_text.blank? $stderr.puts error_msg.inner_text else # TODO - what are the errors we get? puts "Server error:" p res.code puts res.body end false end rescue REXML::ParseException => e # For some reason, if the job exists we get back half a page of HTML raise JobAlreadyExistsError.new(name) end end |
.delete_job(name) ⇒ Object
Attempts to delete a job name
71 72 73 74 |
# File 'lib/jenkins/api.rb', line 71 def self.delete_job(name) res = post_plain "#{job_url name}/doDelete" res.code.to_i == 302 end |
.delete_node(name) ⇒ Object
202 203 204 |
# File 'lib/jenkins/api.rb', line 202 def self.delete_node(name) post_plain("#{base_uri}/computer/#{CGI::escape(name).gsub('+', '%20')}/doDelete/api/json") end |
.get_plain(path, options = {}) ⇒ Object
Helper for GET that don’t barf at Jenkins’s crappy API responses
220 221 222 223 224 |
# File 'lib/jenkins/api.rb', line 220 def self.get_plain(path, = {}) = .with_clean_keys uri = URI.parse base_uri res = Net::HTTP.start(uri.host, uri.port) { |http| http.get(path, ) } end |
.job(name) ⇒ Object
Return hash of job statuses
92 93 94 95 96 97 98 99 100 |
# File 'lib/jenkins/api.rb', line 92 def self.job(name) begin json = get "/job/#{name}/api/json" cache_base_uri json rescue Crack::ParseError false end end |
.job_names ⇒ Object
87 88 89 |
# File 'lib/jenkins/api.rb', line 87 def self.job_names summary["jobs"].map {|job| job["name"]} end |
.nodes ⇒ Object
113 114 115 116 117 |
# File 'lib/jenkins/api.rb', line 113 def self.nodes json = get "/computer/api/json" cache_base_uri json end |
.post_plain(path, data = "", options = {}) ⇒ Object
Helper for POST that don’t barf at Jenkins’s crappy API responses
207 208 209 210 211 212 213 214 215 216 217 |
# File 'lib/jenkins/api.rb', line 207 def self.post_plain(path, data = "", = {}) = .with_clean_keys uri = URI.parse base_uri res = Net::HTTP.start(uri.host, uri.port) do |http| if RUBY_VERSION =~ /1.8/ http.post(path, ) else http.post(path, data, ) end end end |
.setup_base_url(options) ⇒ Object
19 20 21 22 23 24 25 26 27 28 29 30 |
# File 'lib/jenkins/api.rb', line 19 def self.setup_base_url() = .with_clean_keys # Thor's HashWithIndifferentAccess is based on string keys which URI::HTTP.build ignores = .inject({}) { |mem, (key, val)| mem[key.to_sym] = val; mem } [:host] ||= ENV['JENKINS_HOST'] [:port] ||= ENV['JENKINS_PORT'] [:port] &&= [:port].to_i return false unless [:host] || Jenkins::Config.config["base_uri"] uri = [:host] ? URI::HTTP.build() : Jenkins::Config.config["base_uri"] base_uri uri.to_s uri end |
.summary ⇒ Object
81 82 83 84 85 |
# File 'lib/jenkins/api.rb', line 81 def self.summary json = get "/api/json" cache_base_uri json end |