jenkins_api_client 0.14.1 → 1.0.0
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.
- checksums.yaml +7 -0
- data/.gitignore +3 -0
- data/.travis.yml +5 -23
- data/CHANGELOG.md +104 -35
- data/CONTRIBUTORS.md +1 -11
- data/Gemfile +4 -2
- data/README.md +107 -7
- data/Rakefile +1 -0
- data/Vagrantfile +6 -8
- data/jenkins_api_client.gemspec +30 -12
- data/lib/jenkins_api_client/cli/helper.rb +1 -0
- data/lib/jenkins_api_client/client.rb +162 -69
- data/lib/jenkins_api_client/exceptions.rb +26 -17
- data/lib/jenkins_api_client/job.rb +321 -75
- data/lib/jenkins_api_client/node.rb +22 -10
- data/lib/jenkins_api_client/plugin_manager.rb +460 -0
- data/lib/jenkins_api_client/urihelper.rb +17 -0
- data/lib/jenkins_api_client/user.rb +4 -2
- data/lib/jenkins_api_client/version.rb +3 -3
- data/lib/jenkins_api_client/view.rb +10 -7
- data/lib/jenkins_api_client.rb +1 -0
- data/scripts/login_with_pry.rb +54 -0
- data/spec/func_tests/client_spec.rb +3 -3
- data/spec/func_tests/job_spec.rb +90 -7
- data/spec/func_tests/{node_spec.rb → node_spec.rb.pending} +9 -9
- data/spec/func_tests/plugin_spec.rb +148 -0
- data/spec/unit_tests/client_spec.rb +108 -27
- data/spec/unit_tests/fake_http_response.rb +9 -0
- data/spec/unit_tests/fixtures/files/available_plugins.json +1 -0
- data/spec/unit_tests/fixtures/files/installed_plugins.json +1 -0
- data/spec/unit_tests/fixtures/files/updatable_plugins.json +1 -0
- data/spec/unit_tests/job_spec.rb +109 -6
- data/spec/unit_tests/node_spec.rb +18 -6
- data/spec/unit_tests/plugin_spec.rb +165 -0
- data/spec/unit_tests/spec_helper.rb +11 -1
- data/spec/unit_tests/system_spec.rb +2 -1
- data/spec/unit_tests/user_spec.rb +1 -1
- data/travis/hudson.model.UpdateCenter.xml +7 -0
- data/travis/setup.sh +2 -1
- metadata +76 -64
@@ -20,12 +20,15 @@
|
|
20
20
|
# THE SOFTWARE.
|
21
21
|
#
|
22
22
|
|
23
|
+
require 'jenkins_api_client/urihelper'
|
24
|
+
|
23
25
|
module JenkinsApi
|
24
26
|
class Client
|
25
27
|
# This class communicates with Jenkins "/computer" API to obtain details
|
26
28
|
# about nodes or slaves connected to the Jenkins.
|
27
29
|
#
|
28
30
|
class Node
|
31
|
+
include JenkinsApi::UriHelper
|
29
32
|
|
30
33
|
# General attributes of a node.
|
31
34
|
# This allows the following methods to be called on this node object.
|
@@ -103,7 +106,7 @@ module JenkinsApi
|
|
103
106
|
|
104
107
|
# Creates a new node with the specified parameters
|
105
108
|
#
|
106
|
-
# @param [Hash] params parameters for creating a
|
109
|
+
# @param [Hash] params parameters for creating a dumb slave
|
107
110
|
# * +:name+ name of the slave
|
108
111
|
# * +:description+ description of the new slave
|
109
112
|
# * +:executors+ number of executors
|
@@ -113,9 +116,10 @@ module JenkinsApi
|
|
113
116
|
# * +:slave_host+ Hostname/IP of the slave
|
114
117
|
# * +:slave_port+ Slave port
|
115
118
|
# * +:private_key_file+ Private key file of master
|
119
|
+
# * +:credentials_id+ Id for credential in Jenkins
|
116
120
|
#
|
117
|
-
# @example Create a
|
118
|
-
#
|
121
|
+
# @example Create a Dumb Slave
|
122
|
+
# create_dumb_slave(
|
119
123
|
# :name => "slave1",
|
120
124
|
# :slave_host => "10.10.10.10",
|
121
125
|
# :private_key_file => "/root/.ssh/id_rsa",
|
@@ -123,21 +127,23 @@ module JenkinsApi
|
|
123
127
|
# :labels => "slave, ruby"
|
124
128
|
# )
|
125
129
|
#
|
126
|
-
def
|
130
|
+
def create_dumb_slave(params)
|
127
131
|
unless params[:name] && params[:slave_host] && params[:private_key_file]
|
128
132
|
raise ArgumentError, "Name, slave host, and private key file are" +
|
129
133
|
" required for creating a slave."
|
130
134
|
end
|
131
135
|
|
132
|
-
@logger.info "Creating a
|
133
|
-
@logger.debug "Creating a
|
136
|
+
@logger.info "Creating a dumb slave '#{params[:name]}'"
|
137
|
+
@logger.debug "Creating a dumb slave with params: #{params.inspect}"
|
134
138
|
default_params = {
|
135
139
|
:description => "Automatically created through jenkins_api_client",
|
136
140
|
:executors => 2,
|
137
141
|
:remote_fs => "/var/jenkins",
|
138
142
|
:labels => params[:name],
|
139
143
|
:slave_port => 22,
|
140
|
-
:mode => "normal"
|
144
|
+
:mode => "normal",
|
145
|
+
:private_key_file => "",
|
146
|
+
:credentials_id => ""
|
141
147
|
}
|
142
148
|
|
143
149
|
params = default_params.merge(params)
|
@@ -167,6 +173,7 @@ module JenkinsApi
|
|
167
173
|
"port" => params[:slave_port],
|
168
174
|
"username" => params[:slave_user],
|
169
175
|
"privatekey" => params[:private_key_file],
|
176
|
+
"credentialsId" => params[:credentials_id]
|
170
177
|
}
|
171
178
|
}.to_json
|
172
179
|
}
|
@@ -175,6 +182,11 @@ module JenkinsApi
|
|
175
182
|
@client.api_post_request("/computer/doCreateItem", post_params)
|
176
183
|
end
|
177
184
|
|
185
|
+
def create_dump_slave(params)
|
186
|
+
@logger.warn '[DEPRECATED] Please use create_dumb_slave instead.'
|
187
|
+
create_dumb_slave(params)
|
188
|
+
end
|
189
|
+
|
178
190
|
# Deletes the specified node
|
179
191
|
#
|
180
192
|
# @param [String] node_name Name of the node to delete
|
@@ -182,7 +194,7 @@ module JenkinsApi
|
|
182
194
|
def delete(node_name)
|
183
195
|
@logger.info "Deleting node '#{node_name}'"
|
184
196
|
if list.include?(node_name)
|
185
|
-
@client.api_post_request("/computer/#{node_name}/doDelete")
|
197
|
+
@client.api_post_request("/computer/#{path_encode node_name}/doDelete")
|
186
198
|
else
|
187
199
|
raise "The specified node '#{node_name}' doesn't exist in Jenkins."
|
188
200
|
end
|
@@ -280,7 +292,7 @@ module JenkinsApi
|
|
280
292
|
def get_config(node_name)
|
281
293
|
@logger.info "Obtaining the config.xml of node '#{node_name}'"
|
282
294
|
node_name = "(master)" if node_name == "master"
|
283
|
-
@client.get_config("/computer/#{node_name}")
|
295
|
+
@client.get_config("/computer/#{ path_encode node_name}")
|
284
296
|
end
|
285
297
|
|
286
298
|
# Posts the given config.xml to the Jenkins node
|
@@ -291,7 +303,7 @@ module JenkinsApi
|
|
291
303
|
def post_config(node_name, xml)
|
292
304
|
@logger.info "Posting the config.xml of node '#{node_name}'"
|
293
305
|
node_name = "(master)" if node_name == "master"
|
294
|
-
@client.post_config("/computer/#{node_name}/config.xml", xml)
|
306
|
+
@client.post_config("/computer/#{path_encode node_name}/config.xml", xml)
|
295
307
|
end
|
296
308
|
|
297
309
|
end
|
@@ -0,0 +1,460 @@
|
|
1
|
+
#
|
2
|
+
# Copyright (c) 2012-2013 Kannan Manickam <arangamani.kannan@gmail.com>
|
3
|
+
#
|
4
|
+
# Permission is hereby granted, free of charge, to any person obtaining a copy
|
5
|
+
# of this software and associated documentation files (the "Software"), to deal
|
6
|
+
# in the Software without restriction, including without limitation the rights
|
7
|
+
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
8
|
+
# copies of the Software, and to permit persons to whom the Software is
|
9
|
+
# furnished to do so, subject to the following conditions:
|
10
|
+
#
|
11
|
+
# The above copyright notice and this permission notice shall be included in
|
12
|
+
# all copies or substantial portions of the Software.
|
13
|
+
#
|
14
|
+
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
15
|
+
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
16
|
+
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
17
|
+
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
18
|
+
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
19
|
+
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
20
|
+
# THE SOFTWARE.
|
21
|
+
#
|
22
|
+
|
23
|
+
module JenkinsApi
|
24
|
+
class Client
|
25
|
+
# This classes communicates with the /pluginManager API for listing
|
26
|
+
# installed plugins, installing new plgins through hacks, and performing a
|
27
|
+
# lot of operations on installed plugins. It also gives the ability to
|
28
|
+
# obtain the details about available plugins in Jenkins update center by
|
29
|
+
# commmunicating with /updateCenter API.
|
30
|
+
#
|
31
|
+
class PluginManager
|
32
|
+
|
33
|
+
# Initializes a new PluginManager object.
|
34
|
+
#
|
35
|
+
# @param [Object] client a reference to Client
|
36
|
+
#
|
37
|
+
def initialize(client)
|
38
|
+
@client = client
|
39
|
+
@logger = @client.logger
|
40
|
+
end
|
41
|
+
|
42
|
+
# Returns a string representation of PluginManager class.
|
43
|
+
#
|
44
|
+
def to_s
|
45
|
+
"#<JenkinsApi::Client::PluginManager>"
|
46
|
+
end
|
47
|
+
|
48
|
+
# Defines a method to perform the given action on plugin(s)
|
49
|
+
#
|
50
|
+
# @param action [Symbol] the action to perform
|
51
|
+
# @param post_endpoint [Symbol] the endpoint in the POST request for the
|
52
|
+
# action
|
53
|
+
#
|
54
|
+
def self.plugin_action_method(action, post_endpoint)
|
55
|
+
define_method(action) do |plugins|
|
56
|
+
plugins = [plugins] unless plugins.is_a?(Array)
|
57
|
+
@logger.info "Performing '#{action}' on plugins: #{plugins.inspect}"
|
58
|
+
plugins.each do |plugin|
|
59
|
+
@client.api_post_request(
|
60
|
+
"/pluginManager/plugin/#{plugin}/#{post_endpoint}"
|
61
|
+
)
|
62
|
+
end
|
63
|
+
end
|
64
|
+
end
|
65
|
+
|
66
|
+
# Obtains the list of installed plugins from Jenkins along with their
|
67
|
+
# version numbers with optional filters
|
68
|
+
#
|
69
|
+
# @param filters [Hash] optional filters to apply. Use symbols for filter
|
70
|
+
# keys
|
71
|
+
#
|
72
|
+
# @option filters [Boolean] :active filter active/non-active plugins
|
73
|
+
# @option filters [Boolean] :bundled filter bundled/non-bundled plugins
|
74
|
+
# @option filters [Boolean] :deleted filter deleted/available plugins
|
75
|
+
# @option filters [Boolean] :downgradable filter downgradable plugins
|
76
|
+
# @option filters [Boolean] :enabled filter enabled/disabled plugins
|
77
|
+
# @option filters [Boolean] :hasUpdate filter plugins that has update
|
78
|
+
# available. Note that 'U' is capitalized in hasUpdate.
|
79
|
+
# @option filters [Boolean] :pinned filter pinned/un-pinned plugins
|
80
|
+
#
|
81
|
+
# @return [Hash<String, String>] installed plugins and their versions
|
82
|
+
# matching the filter provided. returns an empty hash if there are no
|
83
|
+
# plugins matched the filters or no plugins are installed in jenkins.
|
84
|
+
#
|
85
|
+
# @example Listing installed plugins from jenkins
|
86
|
+
# >> @client.plugin.list_installed
|
87
|
+
# => {
|
88
|
+
# "mailer" => "1.5",
|
89
|
+
# "external-monitor-job" => "1.1",
|
90
|
+
# "ldap" => "1.2"
|
91
|
+
# }
|
92
|
+
# >> @client.plugin.list_installed(true)
|
93
|
+
# => {}
|
94
|
+
#
|
95
|
+
# @example Listing installed plugins based on filters provided
|
96
|
+
# >> @client.plugin.list_installed(
|
97
|
+
# :active => true, :deleted => false, :bundled => false
|
98
|
+
# )
|
99
|
+
# => {
|
100
|
+
# "sourcemonitor" => "0.2",
|
101
|
+
# "sms-notification" => "1.0",
|
102
|
+
# "jquery" => "1.7.2-1",
|
103
|
+
# "simple-theme-plugin" => "0.3",
|
104
|
+
# "jquery-ui" => "1.0.2",
|
105
|
+
# "analysis-core" => "1.49"
|
106
|
+
# }
|
107
|
+
#
|
108
|
+
def list_installed(filters = {})
|
109
|
+
supported_filters = [
|
110
|
+
:active, :bundled, :deleted, :downgradable, :enabled, :hasUpdate,
|
111
|
+
:pinned
|
112
|
+
]
|
113
|
+
unless filters.keys.all? { |filter| supported_filters.include?(filter) }
|
114
|
+
raise ArgumentError, "Unsupported filters specified." +
|
115
|
+
" Supported filters: #{supported_filters.inspect}"
|
116
|
+
end
|
117
|
+
tree_filters = filters.empty? ? "" : ",#{filters.keys.join(",")}"
|
118
|
+
plugins = @client.api_get_request(
|
119
|
+
"/pluginManager",
|
120
|
+
"tree=plugins[shortName,version#{tree_filters}]"
|
121
|
+
)["plugins"]
|
122
|
+
installed = Hash[plugins.map do |plugin|
|
123
|
+
if filters.keys.all? { |key| plugin[key.to_s] == filters[key] }
|
124
|
+
[plugin["shortName"], plugin["version"]]
|
125
|
+
end
|
126
|
+
end.compact]
|
127
|
+
installed
|
128
|
+
end
|
129
|
+
|
130
|
+
# Obtains the details of a single installed plugin
|
131
|
+
#
|
132
|
+
# @param plugin [String] the plugin ID of the desired plugin
|
133
|
+
#
|
134
|
+
# @return [Hash] the details of the given installed plugin
|
135
|
+
#
|
136
|
+
# @example Obtain the information of an installed plugin
|
137
|
+
# >> @client.plugin.get_installed_info "ldap"
|
138
|
+
# => {
|
139
|
+
# "active"=>false,
|
140
|
+
# "backupVersion"=>"1.2",
|
141
|
+
# "bundled"=>true,
|
142
|
+
# "deleted"=>false,
|
143
|
+
# "dependencies"=>[],
|
144
|
+
# "downgradable"=>true,
|
145
|
+
# "enabled"=>false,
|
146
|
+
# "hasUpdate"=>false,
|
147
|
+
# "longName"=>"LDAP Plugin",
|
148
|
+
# "pinned"=>true,
|
149
|
+
# "shortName"=>"ldap",
|
150
|
+
# "supportsDynamicLoad"=>"MAYBE",
|
151
|
+
# "url"=>"http://wiki.jenkins-ci.org/display/JENKINS/LDAP+Plugin",
|
152
|
+
# "version"=>"1.5"
|
153
|
+
# }
|
154
|
+
#
|
155
|
+
def get_installed_info(plugin)
|
156
|
+
@logger.info "Obtaining the details of plugin: #{plugin}"
|
157
|
+
plugins = @client.api_get_request(
|
158
|
+
"/pluginManager",
|
159
|
+
"depth=1"
|
160
|
+
)["plugins"]
|
161
|
+
matched_plugin = plugins.select do |a_plugin|
|
162
|
+
a_plugin["shortName"] == plugin
|
163
|
+
end
|
164
|
+
if matched_plugin.empty?
|
165
|
+
raise Exceptions::PluginNotFound.new(
|
166
|
+
@logger,
|
167
|
+
"Plugin '#{plugin}' is not found"
|
168
|
+
)
|
169
|
+
else
|
170
|
+
matched_plugin.first
|
171
|
+
end
|
172
|
+
end
|
173
|
+
|
174
|
+
# List the available plugins from jenkins update center along with their
|
175
|
+
# version numbers
|
176
|
+
#
|
177
|
+
# @param filters [Hash] optional filters to filter available plugins.
|
178
|
+
#
|
179
|
+
# @option filters [Array] :category the category of the plugin to
|
180
|
+
# filter
|
181
|
+
# @option filters [Array] :dependency the dependency of the plugin to
|
182
|
+
# filter
|
183
|
+
#
|
184
|
+
# @return [Hash<String, String>] available plugins and their versions.
|
185
|
+
# returns an empty if no plugins are available.
|
186
|
+
#
|
187
|
+
# @example Listing available plugins from jenkins
|
188
|
+
# >> @client.plugin.list_available
|
189
|
+
# => {
|
190
|
+
# "accurev" => "0.6.18",
|
191
|
+
# "active-directory" => "1.33",
|
192
|
+
# "AdaptivePlugin" => "0.1",
|
193
|
+
# ...
|
194
|
+
# "zubhium" => "0.1.6"
|
195
|
+
# }
|
196
|
+
#
|
197
|
+
# @example Listing available plugins matching a particular category
|
198
|
+
# >> pp @client.plugin.list_available(:category => "ui")
|
199
|
+
# => {
|
200
|
+
# "all-changes"=>"1.3",
|
201
|
+
# "bruceschneier"=>"0.1",
|
202
|
+
# ...
|
203
|
+
# "xfpanel"=>"1.2.2"
|
204
|
+
# }
|
205
|
+
#
|
206
|
+
# @example Listing available plugins matching a particular dependency
|
207
|
+
# >> pp @client.plugin.list_available(:dependency => "git")
|
208
|
+
# => {
|
209
|
+
# "build-failure-analyzer"=>"1.5.0",
|
210
|
+
# "buildheroes"=>"0.2",
|
211
|
+
# ...
|
212
|
+
# "xpdev"=>"1.0"
|
213
|
+
# }
|
214
|
+
#
|
215
|
+
def list_available(filters = {})
|
216
|
+
supported_filters = [:category, :dependency]
|
217
|
+
filter_plural_map = {
|
218
|
+
:dependency => "dependencies",
|
219
|
+
:category => "categories"
|
220
|
+
}
|
221
|
+
unless filters.keys.all? { |filter| supported_filters.include?(filter) }
|
222
|
+
raise ArgumentError, "Unsupported filters specified." +
|
223
|
+
" Supported filters: #{supported_filters.inspect}"
|
224
|
+
end
|
225
|
+
# Compute the filters to be passed to the JSON tree parameter
|
226
|
+
tree_filters =
|
227
|
+
if filters.empty?
|
228
|
+
""
|
229
|
+
else
|
230
|
+
",#{filters.keys.map{ |key| filter_plural_map[key] }.join(",")}"
|
231
|
+
end
|
232
|
+
|
233
|
+
availables = @client.api_get_request(
|
234
|
+
"/updateCenter/coreSource",
|
235
|
+
"tree=availables[name,version#{tree_filters}]"
|
236
|
+
)["availables"]
|
237
|
+
Hash[availables.map do |plugin|
|
238
|
+
if filters.keys.all? do |key|
|
239
|
+
!plugin[filter_plural_map[key]].nil? &&
|
240
|
+
plugin[filter_plural_map[key]].include?(filters[key])
|
241
|
+
end
|
242
|
+
[plugin["name"], plugin["version"]]
|
243
|
+
end
|
244
|
+
end]
|
245
|
+
end
|
246
|
+
|
247
|
+
# Obtains the information about a plugin that is available in the Jenkins
|
248
|
+
# update center
|
249
|
+
#
|
250
|
+
# @param plugin [String] the plugin ID to obtain information for
|
251
|
+
#
|
252
|
+
# @return [Hash] the details of the given plugin
|
253
|
+
#
|
254
|
+
# @example Obtaining the details of a plugin available in jenkins
|
255
|
+
# >> @client.plugin.get_available_info "status-view"
|
256
|
+
# => {
|
257
|
+
# "name"=>"status-view",
|
258
|
+
# "sourceId"=>"default",
|
259
|
+
# "url"=>"http://updates.jenkins-ci.org/download/plugins/status-view/1.0/status-view.hpi",
|
260
|
+
# "version"=>"1.0",
|
261
|
+
# "categories"=>["ui"],
|
262
|
+
# "compatibleSinceVersion"=>nil,
|
263
|
+
# "compatibleWithInstalledVersion"=>true,
|
264
|
+
# "dependencies"=>{},
|
265
|
+
# "excerpt"=>"View type to show jobs filtered by the status of the last completed build.",
|
266
|
+
# "installed"=>nil, "neededDependencies"=>[],
|
267
|
+
# "requiredCore"=>"1.342",
|
268
|
+
# "title"=>"Status View Plugin",
|
269
|
+
# "wiki"=>"https://wiki.jenkins-ci.org/display/JENKINS/Status+View+Plugin"
|
270
|
+
# }
|
271
|
+
#
|
272
|
+
def get_available_info(plugin)
|
273
|
+
plugins = @client.api_get_request(
|
274
|
+
"/updateCenter/coreSource",
|
275
|
+
"depth=1"
|
276
|
+
)["availables"]
|
277
|
+
matched_plugin = plugins.select do |a_plugin|
|
278
|
+
a_plugin["name"] == plugin
|
279
|
+
end
|
280
|
+
if matched_plugin.empty?
|
281
|
+
raise Exceptions::PluginNotFound.new(
|
282
|
+
@logger,
|
283
|
+
"Plugin '#{plugin}' is not found"
|
284
|
+
)
|
285
|
+
else
|
286
|
+
matched_plugin.first
|
287
|
+
end
|
288
|
+
end
|
289
|
+
|
290
|
+
# List the available updates for plugins from jenkins update center
|
291
|
+
# along with their version numbers
|
292
|
+
#
|
293
|
+
# @return [Hash<String, String>] available plugin updates and their
|
294
|
+
# versions. returns an empty if no plugins are available.
|
295
|
+
#
|
296
|
+
# @example Listing available plugin updates from jenkins
|
297
|
+
# >> @client.plugin.list_updates
|
298
|
+
# => {
|
299
|
+
# "ldap" => "1.5",
|
300
|
+
# "ssh-slaves" => "0.27",
|
301
|
+
# "subversion" => "1".50
|
302
|
+
# }
|
303
|
+
#
|
304
|
+
def list_updates
|
305
|
+
updates = @client.api_get_request(
|
306
|
+
"/updateCenter/coreSource",
|
307
|
+
"tree=updates[name,version]"
|
308
|
+
)["updates"]
|
309
|
+
Hash[updates.map { |plugin| [plugin["name"], plugin["version"]] }]
|
310
|
+
end
|
311
|
+
|
312
|
+
# Installs a specific plugin or list of plugins. This method will install
|
313
|
+
# the latest available plugins that jenkins reports. The installation
|
314
|
+
# might not take place right away for some plugins and they might require
|
315
|
+
# restart of jenkins instances. This method makes a single POST request
|
316
|
+
# for the installation of multiple plugins. Updating plugins can be done
|
317
|
+
# the same way. When the install action is issued, it gets the latest
|
318
|
+
# version of the plugin if the plugin is outdated.
|
319
|
+
#
|
320
|
+
# @see Client#api_post_request
|
321
|
+
# @see #restart_required?
|
322
|
+
# @see System#restart
|
323
|
+
# @see #uninstall
|
324
|
+
#
|
325
|
+
# @param plugins [String, Array] a single plugin or a list of plugins to
|
326
|
+
# be installed
|
327
|
+
#
|
328
|
+
# @return [String] the HTTP code from the plugin install POST request
|
329
|
+
#
|
330
|
+
# @example Installing a plugin and restart jenkins if required
|
331
|
+
# >> @client.plugin.install "s3"
|
332
|
+
# => "302" # Response code from plugin installation POST
|
333
|
+
# >> @client.plugin.restart_required?
|
334
|
+
# => true # A restart is required for the installation completion
|
335
|
+
# >> @client.system.restart(true)
|
336
|
+
# => "302" # A force restart is performed
|
337
|
+
#
|
338
|
+
def install(plugins)
|
339
|
+
# Convert the input argument to an array if it is not already an array
|
340
|
+
plugins = [plugins] unless plugins.is_a?(Array)
|
341
|
+
@logger.info "Installing plugins: #{plugins.inspect}"
|
342
|
+
|
343
|
+
# Build the form data to post to jenkins
|
344
|
+
form_data = {}
|
345
|
+
plugins.each { |plugin| form_data["plugin.#{plugin}.default"] = "on" }
|
346
|
+
@client.api_post_request("/pluginManager/install", form_data)
|
347
|
+
end
|
348
|
+
alias_method :update, :install
|
349
|
+
|
350
|
+
|
351
|
+
# @!method uninstall(plugins)
|
352
|
+
#
|
353
|
+
# Uninstalls the specified plugin or list of plugins. Only the user
|
354
|
+
# installed plugins can be uninstalled. The plugins installed by default
|
355
|
+
# by jenkins (also known as bundled plugins) cannot be uninstalled. The
|
356
|
+
# call will succeed but the plugins wil still remain in jenkins installed.
|
357
|
+
# This method makes a POST request for every plugin requested - so it
|
358
|
+
# might lead to some delay if a big list is provided.
|
359
|
+
#
|
360
|
+
# @see Client#api_post_request
|
361
|
+
# @see #restart_required?
|
362
|
+
# @see System#restart
|
363
|
+
# @see #install
|
364
|
+
#
|
365
|
+
# @param plugins [String, Array] a single plugin or list of plugins to be
|
366
|
+
# uninstalled
|
367
|
+
#
|
368
|
+
plugin_action_method :uninstall, :doUninstall
|
369
|
+
|
370
|
+
# @!method downgrade(plugins)
|
371
|
+
#
|
372
|
+
# Downgrades the specified plugin or list of plugins. This method makes s
|
373
|
+
# POST request for every plugin specified - so it might lead to some
|
374
|
+
# delay if a big list is provided.
|
375
|
+
#
|
376
|
+
# @see Client#api_post_request
|
377
|
+
# @see #restart_required?
|
378
|
+
# @see System#restart
|
379
|
+
# @see #install
|
380
|
+
#
|
381
|
+
# @param [String, Array] a single plugin or list of plugins to be
|
382
|
+
# downgraded
|
383
|
+
#
|
384
|
+
plugin_action_method :downgrade, :downgrade
|
385
|
+
|
386
|
+
# @!method unpin(plugins)
|
387
|
+
#
|
388
|
+
# Unpins the specified plugin or list of plugins. This method makes a
|
389
|
+
# POST request for every plugin specified - so it might lead to some
|
390
|
+
# delay if a big list is provided.
|
391
|
+
#
|
392
|
+
# @see Client#api_post_request
|
393
|
+
# @see #restart_required?
|
394
|
+
# @see System#restart
|
395
|
+
#
|
396
|
+
# @param plugins [String, Array] a single plugin or list of plugins to be
|
397
|
+
# uninstalled
|
398
|
+
#
|
399
|
+
plugin_action_method :unpin, :unpin
|
400
|
+
|
401
|
+
# @!method enable(plugins)
|
402
|
+
#
|
403
|
+
# Enables the specified plugin or list of plugins. This method makes a
|
404
|
+
# POST request for every plugin specified - so it might lead to some
|
405
|
+
# delay if a big list is provided.
|
406
|
+
#
|
407
|
+
# @see Client#api_post_request
|
408
|
+
# @see #restart_required?
|
409
|
+
# @see System#restart
|
410
|
+
# @see #disable
|
411
|
+
#
|
412
|
+
# @param plugins [String, Array] a single plugin or list of plugins to be
|
413
|
+
# uninstalled
|
414
|
+
#
|
415
|
+
plugin_action_method :enable, :makeEnabled
|
416
|
+
|
417
|
+
# @!method disable(plugins)
|
418
|
+
#
|
419
|
+
# Disables the specified plugin or list of plugins. This method makes a
|
420
|
+
# POST request for every plugin specified - so it might lead to some
|
421
|
+
# delay if a big list is provided.
|
422
|
+
#
|
423
|
+
# @see Client#api_post_request
|
424
|
+
# @see #restart_required?
|
425
|
+
# @see System#restart
|
426
|
+
# @see #enable
|
427
|
+
#
|
428
|
+
# @param plugins [String, Array] a single plugin or list of plugins to be
|
429
|
+
# uninstalled
|
430
|
+
#
|
431
|
+
plugin_action_method :disable, :makeDisabled
|
432
|
+
|
433
|
+
# Requests the Jenkins plugin manager to check for updates by connecting
|
434
|
+
# to the update site.
|
435
|
+
#
|
436
|
+
# @see #list_updates
|
437
|
+
#
|
438
|
+
def check_for_updates
|
439
|
+
@client.api_post_request("/pluginManager/checkUpdates")
|
440
|
+
end
|
441
|
+
|
442
|
+
# Whether restart required for the completion of plugin
|
443
|
+
# installations/uninstallations
|
444
|
+
#
|
445
|
+
# @see Client#api_get_request
|
446
|
+
#
|
447
|
+
# @return [Boolean] whether restart is required for the completion for
|
448
|
+
# plugin installations/uninstallations.
|
449
|
+
#
|
450
|
+
def restart_required?
|
451
|
+
response = @client.api_get_request(
|
452
|
+
"/updateCenter",
|
453
|
+
"tree=restartRequiredForCompletion"
|
454
|
+
)
|
455
|
+
response["restartRequiredForCompletion"] ||
|
456
|
+
!list_installed(:deleted => true).empty?
|
457
|
+
end
|
458
|
+
end
|
459
|
+
end
|
460
|
+
end
|
@@ -0,0 +1,17 @@
|
|
1
|
+
require 'uri'
|
2
|
+
|
3
|
+
module JenkinsApi
|
4
|
+
module UriHelper
|
5
|
+
# Encode a string for using in the query part of an URL
|
6
|
+
#
|
7
|
+
def form_encode(string)
|
8
|
+
URI.encode_www_form_component string.encode(Encoding::UTF_8)
|
9
|
+
end
|
10
|
+
|
11
|
+
# Encode a string for use in the hiearchical part of an URL
|
12
|
+
#
|
13
|
+
def path_encode(path)
|
14
|
+
URI.escape(path.encode(Encoding::UTF_8))
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
@@ -21,6 +21,7 @@
|
|
21
21
|
#
|
22
22
|
|
23
23
|
require 'timeout'
|
24
|
+
require 'jenkins_api_client/urihelper'
|
24
25
|
|
25
26
|
module JenkinsApi
|
26
27
|
class Client
|
@@ -31,6 +32,7 @@ module JenkinsApi
|
|
31
32
|
# @since 0.14.0
|
32
33
|
#
|
33
34
|
class User
|
35
|
+
include JenkinsApi::UriHelper
|
34
36
|
|
35
37
|
# Initializes a new User object.
|
36
38
|
#
|
@@ -44,7 +46,7 @@ module JenkinsApi
|
|
44
46
|
@timeout = @client.timeout
|
45
47
|
end
|
46
48
|
|
47
|
-
# Returns a string representation of
|
49
|
+
# Returns a string representation of User class.
|
48
50
|
#
|
49
51
|
def to_s
|
50
52
|
"#<JenkinsApi::Client::User>"
|
@@ -111,7 +113,7 @@ module JenkinsApi
|
|
111
113
|
# }
|
112
114
|
#
|
113
115
|
def get(user_id)
|
114
|
-
response = @client.api_get_request("/user/#{user_id}")
|
116
|
+
response = @client.api_get_request("/user/#{path_encode user_id}")
|
115
117
|
end
|
116
118
|
|
117
119
|
end
|
@@ -23,11 +23,11 @@
|
|
23
23
|
module JenkinsApi
|
24
24
|
class Client
|
25
25
|
# Major version of the gem
|
26
|
-
MAJOR =
|
26
|
+
MAJOR = 1
|
27
27
|
# Minor version of the gem
|
28
|
-
MINOR =
|
28
|
+
MINOR = 0
|
29
29
|
# Tiny version of the gem used for patches
|
30
|
-
TINY =
|
30
|
+
TINY = 0
|
31
31
|
# Used for pre-releases
|
32
32
|
PRE = nil
|
33
33
|
# Version String of Jenkins API Client.
|