brpm_content_framework 0.1.55
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +15 -0
- data/.gitignore +38 -0
- data/.travis.yml +17 -0
- data/Gemfile +3 -0
- data/LICENSE +21 -0
- data/README.md +308 -0
- data/Rakefile +23 -0
- data/TO_BE_MIGRATED.txt +9 -0
- data/architecture.png +0 -0
- data/automations/direct_execute.meta +10 -0
- data/automations/direct_execute.rb +10 -0
- data/automations/install_module.meta +10 -0
- data/automations/install_module.rb +13 -0
- data/bin/brpm_install +30 -0
- data/bin/brpm_uninstall +30 -0
- data/bin/event_handler +63 -0
- data/bin/webhook_receiver +49 -0
- data/brpm_content.gemspec +31 -0
- data/config.yml +8 -0
- data/infrastructure/.bashrc +6 -0
- data/infrastructure/.brpm +2 -0
- data/infrastructure/config/customer_include.rb +26 -0
- data/infrastructure/config/server.yml +3 -0
- data/infrastructure/log.html +39 -0
- data/infrastructure/scripts/backup_database.sh +19 -0
- data/infrastructure/scripts/ddns.sh +10 -0
- data/infrastructure/scripts/install_brpm.sh +63 -0
- data/infrastructure/scripts/maintenance.sh +4 -0
- data/infrastructure/scripts/patch_brpm.sh +90 -0
- data/infrastructure/scripts/restore_database.sh +33 -0
- data/infrastructure/scripts/run_event_handler.cmd +19 -0
- data/infrastructure/scripts/run_event_handler.sh +20 -0
- data/infrastructure/scripts/run_webhook_receiver.cmd +15 -0
- data/infrastructure/scripts/run_webhook_receiver.sh +15 -0
- data/infrastructure/silent_install_options_4.6.txt +93 -0
- data/infrastructure/silent_install_options_upgrade_4.6.txt +92 -0
- data/infrastructure/smtp_settings.rb +42 -0
- data/lib/brpm_auto.rb +358 -0
- data/lib/brpm_script_executor.rb +80 -0
- data/lib/logging/brpm_logger.rb +39 -0
- data/lib/logging/logger_base.rb +36 -0
- data/lib/logging/simple_logger.rb +27 -0
- data/lib/module_installer.rb +483 -0
- data/lib/params/all_params.rb +80 -0
- data/lib/params/integration_settings.rb +27 -0
- data/lib/params/params.rb +174 -0
- data/lib/params/params_base.rb +81 -0
- data/lib/params/request_params.rb +38 -0
- data/lib/rest_api.rb +155 -0
- data/lib/semaphore.rb +79 -0
- data/lib/utilities.rb +317 -0
- data/lib/version_control/git.rb +192 -0
- data/lib/version_control/svn.rb +221 -0
- data/lib/write_to.rb +1 -0
- data/tests/all_params_spec.rb +116 -0
- data/tests/brpm_auto_spec.rb +84 -0
- data/tests/customer_include/config/customer_include.rb +10 -0
- data/tests/customer_include/config/server.yml +3 -0
- data/tests/customer_include_spec.rb +29 -0
- data/tests/gemspec_spec.rb +11 -0
- data/tests/module_installer_spec.rb +46 -0
- data/tests/params_spec.rb +172 -0
- data/tests/request_params_spec.rb +86 -0
- data/tests/server_yaml_spec.rb +19 -0
- data/tests/spec_helper.rb +64 -0
- data/to_be_migrated/brpm_framework.rb +88 -0
- data/to_be_migrated/customer_include_default.rb +25 -0
- data/to_be_migrated/local_jirb.rb +15 -0
- data/to_be_migrated/resource_framework.rb +211 -0
- data/transport/dispatch_baa.rb +355 -0
- data/transport/dispatch_base.rb +345 -0
- data/transport/dispatch_nsh.rb +248 -0
- data/transport/dispatch_ssh.rb +154 -0
- data/transport/transport_baa.rb +1095 -0
- data/transport/transport_nsh.rb +359 -0
- data/transport/transport_ssh.rb +220 -0
- metadata +204 -0
@@ -0,0 +1,345 @@
|
|
1
|
+
# dispatch_base.rb
|
2
|
+
# Module for action dispatch common methods
|
3
|
+
require 'digest/md5'
|
4
|
+
|
5
|
+
DEFAULT_PARAMS_FILTER = "ENV_" if !defined?(DEFAULT_PARAMS_FILTER)
|
6
|
+
STANDARD_PROPERTIES = ["SS_application", "SS_component", "SS_environment", "SS_component_version", "SS_request_number"]
|
7
|
+
OS_PLATFORMS = {
|
8
|
+
"win" => {"name" => "Windows", "tmp_dir" => "/C/Windows/temp"},
|
9
|
+
"nix" => {"name" => "Unix", "tmp_dir" => "/tmp"},
|
10
|
+
"nux" => {"name" => "Linux", "tmp_dir" => "/tmp"}}
|
11
|
+
|
12
|
+
|
13
|
+
class DispatchBase
|
14
|
+
# Initialize the class
|
15
|
+
#
|
16
|
+
# ==== Attributes
|
17
|
+
#
|
18
|
+
# * +options+ - hash of options to use, send "output_file" to point to the logging file
|
19
|
+
# * +test_mode+ - true/false to simulate commands instead of running them
|
20
|
+
#
|
21
|
+
def initialize(options = {}, compat_options = {})
|
22
|
+
self.extend Utilities
|
23
|
+
if options.has_key?("SS_output_dir")
|
24
|
+
BrpmAuto.log "Load for this class has changed, no longer necessary to send params as 1st argument"
|
25
|
+
options = compat_options
|
26
|
+
end
|
27
|
+
@verbose = get_option(options, "verbose", false)
|
28
|
+
@output_dir = BrpmAuto.params.output_dir
|
29
|
+
end
|
30
|
+
|
31
|
+
# Builds a hash of properties to transfer to target
|
32
|
+
#
|
33
|
+
# ==== Attributes
|
34
|
+
#
|
35
|
+
# * +keyword_filter+ - filter for params (param selected if filter included in key)
|
36
|
+
# * +strip_filter+ - removes filter text from resulting key
|
37
|
+
# ==== Returns
|
38
|
+
#
|
39
|
+
# hash of properties to transfer
|
40
|
+
#
|
41
|
+
def get_transfer_properties(keyword_filter = DEFAULT_PARAMS_FILTER, strip_filter = true)
|
42
|
+
result = {}
|
43
|
+
STANDARD_PROPERTIES.each{|prop| result[prop.gsub("SS_","RPM_")] = BrpmAuto.params[prop] }
|
44
|
+
BrpmAuto.params.each{|k,v| result[strip_filter ? k.gsub(keyword_filter,"") : k] = v if k.include?(keyword_filter) }
|
45
|
+
result
|
46
|
+
end
|
47
|
+
|
48
|
+
# Add BRPD-like params to transfer_properties
|
49
|
+
#
|
50
|
+
# ==== Attributes
|
51
|
+
#
|
52
|
+
# * +props+ - the existing transfer properties hash
|
53
|
+
# * +payload_path+ - the path for any previously delivered content
|
54
|
+
# * +target_dir+ - the delivery directory on the target
|
55
|
+
# ==== Returns
|
56
|
+
#
|
57
|
+
# nothing - modifies passed property hash
|
58
|
+
#
|
59
|
+
def brpd_compatibility(props, payload_path = nil, servers = nil)
|
60
|
+
props["VL_CONTENT_PATH"] = payload_path if payload_path
|
61
|
+
props["VL_CONTENT_NAME"] = File.basename(payload_path) if payload_path
|
62
|
+
props["VL_CHANNEL_ROOT"] = props["RPM_CHANNEL_ROOT"]
|
63
|
+
props["VL_DISPATCH_TARGET_HOST"] = servers.nil? ? get_server_list.keys[0] : servers.first[0]
|
64
|
+
end
|
65
|
+
|
66
|
+
# Add server properties to transfer properties
|
67
|
+
#
|
68
|
+
# ==== Attributes
|
69
|
+
#
|
70
|
+
# * +props+ - the existing transfer properties hash
|
71
|
+
# * +servers+ - hash of server properties
|
72
|
+
# * +os_platform+ - os platform
|
73
|
+
# ==== Returns
|
74
|
+
#
|
75
|
+
# nothing - modifies passed property hash
|
76
|
+
#
|
77
|
+
def add_channel_properties(props, servers, os_platform = "win")
|
78
|
+
s_props = servers.first[1]
|
79
|
+
base_dir = s_props["CHANNEL_ROOT"] if s_props.has_key?("CHANNEL_ROOT")
|
80
|
+
base_dir ||= s_props["base_dir"] if s_props.has_key?("base_dir")
|
81
|
+
base_dir ||= OS_PLATFORMS[os_platform]["tmp_dir"]
|
82
|
+
props["RPM_CHANNEL_ROOT"] = base_dir
|
83
|
+
end
|
84
|
+
|
85
|
+
# Removes carriage returns for unix compatibility
|
86
|
+
# Opens passed script path, modifies and saves file
|
87
|
+
# ==== Attributes
|
88
|
+
#
|
89
|
+
# * +os_platform+ - os platform
|
90
|
+
# * +script_file+ - path to script to modify
|
91
|
+
# * +contents+ - optional - if passed will replace the content in script_file
|
92
|
+
# ==== Returns
|
93
|
+
#
|
94
|
+
# path to modified script
|
95
|
+
#
|
96
|
+
def clean_line_breaks(os_platform, script_file, contents = nil)
|
97
|
+
return if os_platform =~ /win/
|
98
|
+
contents = File.open(script_file).read if contents.nil?
|
99
|
+
fil = File.open(script_file,"w+")
|
100
|
+
fil.puts contents.gsub("\r", "")
|
101
|
+
fil.flush
|
102
|
+
fil.close
|
103
|
+
script_file
|
104
|
+
end
|
105
|
+
|
106
|
+
# Creates a temp file in output dir
|
107
|
+
# returns path to temp file
|
108
|
+
# ==== Attributes
|
109
|
+
#
|
110
|
+
# * +content+ - content for file
|
111
|
+
# * +options+ - hash of options, includes ext to force the file extension e.g. {"ext" => ".sql"}
|
112
|
+
# ==== Returns
|
113
|
+
#
|
114
|
+
# path to file
|
115
|
+
#
|
116
|
+
def make_temp_file(content, platform = "linux", options = {})
|
117
|
+
ext = get_option(options, "ext")
|
118
|
+
if ext == ""
|
119
|
+
ext = platform.downcase == "linux" ? ".sh" : ".bat"
|
120
|
+
end
|
121
|
+
file_path = File.join(BrpmAuto.params["SS_output_dir"],"shell_#{precision_timestamp}#{ext}")
|
122
|
+
fil = File.open(file_path, "w+")
|
123
|
+
fil.puts content
|
124
|
+
fil.flush
|
125
|
+
fil.close
|
126
|
+
file_path
|
127
|
+
end
|
128
|
+
|
129
|
+
# Builds the wrapper script for the target
|
130
|
+
# sets environment variables and call to run target script
|
131
|
+
# follows platform directives or shebang information
|
132
|
+
#
|
133
|
+
# ==== Attributes
|
134
|
+
#
|
135
|
+
# * +os_platform+ - os platform
|
136
|
+
# * +shebang+ - hash of processed shebang
|
137
|
+
# * +properties+ - hash of properties to become environment variables
|
138
|
+
# * +options+ - hash of optionss, includes script_target - what the wrapper will call
|
139
|
+
# ==== Returns
|
140
|
+
#
|
141
|
+
# path to wrapper script
|
142
|
+
#
|
143
|
+
def build_wrapper_script(os_platform, shebang, properties, options = {})
|
144
|
+
msg = "Environment variables from BRPM"
|
145
|
+
wrapper = "srun_wrapper_#{precision_timestamp}"
|
146
|
+
alt_target = get_option(options,"script_target")
|
147
|
+
cmd = shebang["cmd"]
|
148
|
+
target = alt_target == "" ? File.basename(get_param("SS_script_file")) : alt_target
|
149
|
+
cmd = cmd.gsub("%%", target) if shebang["cmd"].end_with?("%%")
|
150
|
+
cmd = "#{cmd} #{target}" unless shebang["cmd"].end_with?("%%")
|
151
|
+
if os_platform =~ /win/
|
152
|
+
properties["RPM_CHANNEL_ROOT"] = dos_path(properties["RPM_CHANNEL_ROOT"])
|
153
|
+
properties["VL_CHANNEL_ROOT"] = properties["RPM_CHANNEL_ROOT"]
|
154
|
+
wrapper = "#{wrapper}.bat"
|
155
|
+
script = "@echo off\r\necho |hostname > junk.txt\r\nset /p HOST=<junk.txt\r\necho y|del junk.txt\r\n"
|
156
|
+
script += "echo ============== HOSTNAME: %HOST% ==============\r\n"
|
157
|
+
script += "echo #{msg} \r\n"
|
158
|
+
properties.each{|k,v| script += "set #{k}=#{v}\r\n" }
|
159
|
+
script += "echo Execute the file\r\n"
|
160
|
+
script += "cd %RPM_CHANNEL_ROOT%\r\n"
|
161
|
+
script += "#{cmd}\r\n"
|
162
|
+
script += "echo EXIT_CODE: %errorlevel%\r\n"
|
163
|
+
script += "timeout /t <5> /nobreak\r\n"
|
164
|
+
script += "echo y|del #{target}\r\n"
|
165
|
+
else
|
166
|
+
wrapper = "#{wrapper}.sh"
|
167
|
+
script = "echo \"============== HOSTNAME: `hostname` ==============\"\n"
|
168
|
+
script += "echo #{msg} \n"
|
169
|
+
properties.each{|k,v| script += "export #{k}=\"#{v}\"\n" }
|
170
|
+
script += "echo Execute the file\n"
|
171
|
+
script += "cd $RPM_CHANNEL_ROOT\n"
|
172
|
+
script += "#{cmd}\n"
|
173
|
+
script += "echo EXIT_CODE: $?\n"
|
174
|
+
script += "sleep 2\nrm -f #{target}"
|
175
|
+
end
|
176
|
+
fil = File.open(File.join(@output_dir, wrapper),"w+")
|
177
|
+
fil.puts script
|
178
|
+
fil.flush
|
179
|
+
fil.close
|
180
|
+
File.join(@output_dir, wrapper)
|
181
|
+
end
|
182
|
+
|
183
|
+
# Builds the wrapper script for a single command
|
184
|
+
#
|
185
|
+
# ==== Attributes
|
186
|
+
#
|
187
|
+
# * +command+ - command to execute e.g. unzip
|
188
|
+
# * +os_platform+ - os platform
|
189
|
+
# * +source_path+ - path to source file (local)
|
190
|
+
# * +target_path+ - destination path on target server
|
191
|
+
# ==== Returns
|
192
|
+
#
|
193
|
+
# path to wrapper script
|
194
|
+
#
|
195
|
+
def create_command_wrapper(command, os_platform, source_path, target_path)
|
196
|
+
msg = "Environment variables from BRPM"
|
197
|
+
wrapper = "srun_wrapper_#{precision_timestamp}"
|
198
|
+
target = File.basename(source_path)
|
199
|
+
if os_platform =~ /win/
|
200
|
+
target_path = dos_path(target_path)
|
201
|
+
wrapper = "#{wrapper}.bat"
|
202
|
+
script = "@echo off\r\necho |hostname > junk.txt\r\nset /p HOST=<junk.txt\r\necho y | del junk.txt\r\n"
|
203
|
+
script += "echo ============== HOSTNAME: %HOST% ==============\r\n"
|
204
|
+
script += "echo #{msg} \r\n"
|
205
|
+
script += "set RPM_CHANNEL_ROOT=#{target_path}\r\n"
|
206
|
+
script += "echo Execute the file\r\n"
|
207
|
+
script += "cd %RPM_CHANNEL_ROOT%\r\n"
|
208
|
+
script += "#{command} #{target}\r\n"
|
209
|
+
script += "echo EXIT_CODE: %errorlevel%\r\n"
|
210
|
+
script += "timeout /t <5> /nobreak\r\n"
|
211
|
+
script += "echo y|del #{target}\r\n"
|
212
|
+
else
|
213
|
+
wrapper = "#{wrapper}.sh"
|
214
|
+
script = "echo \"============== HOSTNAME: `hostname` ==============\"\n"
|
215
|
+
script += "echo #{msg} \n"
|
216
|
+
script += "export RPM_CHANNEL_ROOT=\"#{target_path}\"\n"
|
217
|
+
script += "echo Execute the file\n"
|
218
|
+
script += "cd $RPM_CHANNEL_ROOT\n"
|
219
|
+
script += "#{command} #{target}\n"
|
220
|
+
script += "echo EXIT_CODE: $?\n"
|
221
|
+
script += "sleep 2\nrm -f #{target}"
|
222
|
+
end
|
223
|
+
fil = File.open(File.join(@output_dir, wrapper),"w+")
|
224
|
+
fil.puts script
|
225
|
+
fil.flush
|
226
|
+
fil.close
|
227
|
+
File.join(@output_dir, wrapper)
|
228
|
+
end
|
229
|
+
|
230
|
+
# Builds the list of files for deployment
|
231
|
+
# assumes that there are 3 sources: version, path entry and uploads
|
232
|
+
# ==== Attributes
|
233
|
+
#
|
234
|
+
# * +p_obj+ - a handle to the current params object
|
235
|
+
# * +options+ - hash of options including:
|
236
|
+
#
|
237
|
+
# ==== Returns
|
238
|
+
#
|
239
|
+
# array of nsh paths
|
240
|
+
#
|
241
|
+
def get_artifact_paths(p_obj, options = {})
|
242
|
+
files_to_deploy = []
|
243
|
+
artifact_path = p_obj.get("step_version_artifact_url", nil)
|
244
|
+
artifact_paths = p_obj.split_nsh_path(artifact_path) unless artifact_path.nil?
|
245
|
+
path_server = artifact_path.nil? ? "" : artifact_paths[0]
|
246
|
+
version = p_obj.get("step_version")
|
247
|
+
staging_server = p_obj.get("staging_server", path_server)
|
248
|
+
brpm_hostname = p_obj.get("SS_base_url").gsub(/^.*\:\/\//, "").gsub(/\:\d.*/, "")
|
249
|
+
files_to_deploy << p_obj.get_attachment_nsh_path(brpm_hostname, p_obj.get("Upload Action File")) unless p_obj.get("Upload Action File") == ""
|
250
|
+
files_to_deploy << p_obj.get_attachment_nsh_path(brpm_hostname, p_obj.uploadfile_1) unless p_obj.uploadfile_1 == ""
|
251
|
+
files_to_deploy << p_obj.get_attachment_nsh_path(brpm_hostname, p_obj.uploadfile_2) unless p_obj.uploadfile_2 == ""
|
252
|
+
entered_paths = p_obj.get("nsh_paths", p_obj.get("artifact_paths"))
|
253
|
+
if entered_paths != ""
|
254
|
+
staging_server = "none"
|
255
|
+
entered_paths.split(',').each do |path|
|
256
|
+
ans = p_obj.split_nsh_path(path)
|
257
|
+
staging_server = ans[0] if ans[0].length > 2
|
258
|
+
files_to_deploy << "//#{staging_server}#{ans[1].strip}" if ans[1].length > 2
|
259
|
+
end
|
260
|
+
end
|
261
|
+
unless artifact_path.nil?
|
262
|
+
staging_server = "none"
|
263
|
+
staging_server = artifact_paths[0] if artifact_paths[0].length > 2
|
264
|
+
if artifact_path.start_with?("//")
|
265
|
+
artifact_paths[1].split(',').each do |path|
|
266
|
+
staging = staging_server
|
267
|
+
ans = p_obj.split_nsh_path(path)
|
268
|
+
staging = ans[0] if ans[0].length > 2
|
269
|
+
files_to_deploy << "//#{staging}#{ans[1].strip}" if ans[1].length > 2
|
270
|
+
end
|
271
|
+
else
|
272
|
+
artifact_paths[1].split(',').each do |path|
|
273
|
+
files_to_deploy << path
|
274
|
+
end
|
275
|
+
end
|
276
|
+
end
|
277
|
+
files_to_deploy
|
278
|
+
end
|
279
|
+
|
280
|
+
# Packages files from local staging directory
|
281
|
+
#
|
282
|
+
# ==== Attributes
|
283
|
+
#
|
284
|
+
# * +staging_path+ - path to files
|
285
|
+
# * +version+ - version to assign
|
286
|
+
# ==== Returns
|
287
|
+
#
|
288
|
+
# hash of instance_path and md5 - {"instance_path" => "", "md5" => ""}
|
289
|
+
def package_staged_artifacts(staging_path, version)
|
290
|
+
package_file = "package_#{version}.zip"
|
291
|
+
instance_path = File.join(staging_path, package_file)
|
292
|
+
staging_artifacts = Dir.entries(staging_path).reject{|k| [".",".."].include?(k) }
|
293
|
+
return {"instance_path" => "ERROR - no files in staging area", "md5" => ""} if staging_artifacts.size < 1
|
294
|
+
cmd = "cd #{staging_path} && zip -r #{package_file} *" unless Windows
|
295
|
+
result = execute_shell(cmd)
|
296
|
+
md5 = Digest::MD5.file(instance_path).hexdigest
|
297
|
+
{"instance_path" => instance_path, "md5" => md5, "manifest" => staging_artifacts}
|
298
|
+
end
|
299
|
+
|
300
|
+
# Return the name or dns of servers in a hash list
|
301
|
+
# if dns exists, uses that, otherwise, name
|
302
|
+
# ==== Attributes
|
303
|
+
#
|
304
|
+
# * +servers+ - standard servers hash
|
305
|
+
# ==== Returns
|
306
|
+
#
|
307
|
+
# * array of server dns's
|
308
|
+
#
|
309
|
+
def server_dns_names(servers)
|
310
|
+
result = []
|
311
|
+
servers.each do |name,props|
|
312
|
+
if props["dns"].length < 3 || props["dns"].start_with?("http")
|
313
|
+
result << name
|
314
|
+
else
|
315
|
+
result << props["dns"]
|
316
|
+
end
|
317
|
+
end
|
318
|
+
result
|
319
|
+
end
|
320
|
+
|
321
|
+
# Returns the short name for the os platform
|
322
|
+
# Send the OS
|
323
|
+
def os_platform(platform, abbrev = true)
|
324
|
+
result = "nux"
|
325
|
+
result = "nix" if platform.downcase =~ /nix/
|
326
|
+
result = "win" if platform.downcase =~ /win/
|
327
|
+
result = {"nux" => "unix", "nix" => "linux", "win" => "windows"}[result] unless abbrev
|
328
|
+
result
|
329
|
+
end
|
330
|
+
|
331
|
+
# Returns plaform information about the first server assigned
|
332
|
+
# (works on teh assumption that all assigned servers are similar!)
|
333
|
+
# ==== Returns
|
334
|
+
#
|
335
|
+
# * hash of server information {"server", "os", "channel_root"}
|
336
|
+
#
|
337
|
+
def lead_server_info
|
338
|
+
servers = BrpmAuto.params.servers
|
339
|
+
cur = servers.keys.first
|
340
|
+
os = os_platform(servers[cur]["os_platform"], false)
|
341
|
+
channel_root = servers[cur].has_key?("CHANNEL_ROOT") ? servers[cur]["CHANNEL_ROOT"] : (os == "windows" ? "C:\\temp" : "/tmp")
|
342
|
+
server_info = {"server" => cur, "os" => os, "channel_root" => channel_root}
|
343
|
+
end
|
344
|
+
|
345
|
+
end
|
@@ -0,0 +1,248 @@
|
|
1
|
+
# dispatch_srun.rb
|
2
|
+
# Module for action dispatch with nsh protocol
|
3
|
+
libDir = File.expand_path(File.dirname(__FILE__))
|
4
|
+
require "#{libDir}/dispatch_base"
|
5
|
+
|
6
|
+
|
7
|
+
class DispatchNSH < DispatchBase
|
8
|
+
# Initialize the class
|
9
|
+
#
|
10
|
+
# ==== Attributes
|
11
|
+
#
|
12
|
+
# * +nsh_object+ - handle to an NSH object
|
13
|
+
# * +options+ - hash of options to use, send "output_file" to point to the logging file
|
14
|
+
# * +test_mode+ - true/false to simulate commands instead of running them
|
15
|
+
#
|
16
|
+
def initialize(nsh_object, options = {}, compat_options = {})
|
17
|
+
self.extend Utilities
|
18
|
+
if options.has_key?("SS_output_dir")
|
19
|
+
BrpmAuto.log "Load for this class has changed, no longer necessary to send params as 2nd argument"
|
20
|
+
options = compat_options
|
21
|
+
end
|
22
|
+
@nsh = nsh_object
|
23
|
+
@verbose = get_option(options, "verbose", false)
|
24
|
+
@output_dir = BrpmAuto.params["SS_output_dir"]
|
25
|
+
end
|
26
|
+
|
27
|
+
# Wrapper to run a shell action
|
28
|
+
# opens passed script path, or executes passed text
|
29
|
+
# processes the script in erb first to allow param substitution
|
30
|
+
# note script may have keyword directives (see additional docs)
|
31
|
+
# ==== Attributes
|
32
|
+
#
|
33
|
+
# * +script_file+ - the path to the script or the text of the script
|
34
|
+
# * +options+ - hash of options, includes:
|
35
|
+
# * +-servers to override step servers
|
36
|
+
# * +-transfer_properties - the properties to push to the wrapper script
|
37
|
+
# * +-transfer_prefix - prefix to grab transfer properties from params
|
38
|
+
#
|
39
|
+
# ==== Returns
|
40
|
+
#
|
41
|
+
# action output
|
42
|
+
#
|
43
|
+
def execute_script(script_file, options = {})
|
44
|
+
# get the body of the action
|
45
|
+
content = File.open(script_file).read
|
46
|
+
seed_servers = get_option(options, "servers")
|
47
|
+
loop_servers = get_option(options, "each_server")
|
48
|
+
transfer_properties = get_option(options, "transfer_properties",{})
|
49
|
+
keyword_items = get_keyword_items(content)
|
50
|
+
params_filter = get_option(keyword_items, "RPM_PARAMS_FILTER")
|
51
|
+
params_filter = get_option(options, "transfer_prefix", DEFAULT_PARAMS_FILTER)
|
52
|
+
transfer_properties.merge!(get_transfer_properties(params_filter, strip_prefix = true))
|
53
|
+
BrpmAuto.log "#----------- Executing Script on Remote Hosts -----------------#"
|
54
|
+
BrpmAuto.log "# Script: #{script_file}"
|
55
|
+
result = "No servers to execute on"
|
56
|
+
# Loop through the platforms
|
57
|
+
OS_PLATFORMS.each do |os, os_details|
|
58
|
+
servers = BrpmAuto.params.get_servers_by_os_platform(os) if seed_servers == ""
|
59
|
+
servers = BrpmAuto.params.get_servers_by_os_platform(os, seed_servers) if seed_servers != ""
|
60
|
+
BrpmAuto.message_box "OS Platform: #{os_details["name"]}"
|
61
|
+
BrpmAuto.log "No servers selected for: #{os_details["name"]}" if servers.size == 0
|
62
|
+
next if servers.size == 0
|
63
|
+
BrpmAuto.log "# #{os_details["name"]} - Targets: #{servers.inspect}"
|
64
|
+
BrpmAuto.log "# Setting Properties:"
|
65
|
+
add_channel_properties(transfer_properties, servers, os)
|
66
|
+
brpd_compatibility(transfer_properties, nil, servers)
|
67
|
+
transfer_properties.each{|k,v| BrpmAuto.log "\t#{k} => #{v}" }
|
68
|
+
shebang = read_shebang(os, content)
|
69
|
+
BrpmAuto.log "Shebang: #{shebang.inspect}"
|
70
|
+
wrapper_path = build_wrapper_script(os, shebang, transfer_properties, {"script_target" => File.basename(script_file)})
|
71
|
+
BrpmAuto.log "# Wrapper: #{wrapper_path}"
|
72
|
+
target_path = @nsh.nsh_path(transfer_properties["RPM_CHANNEL_ROOT"])
|
73
|
+
BrpmAuto.log "# Copying script to target: "
|
74
|
+
clean_line_breaks(os, script_file, content)
|
75
|
+
result = @nsh.ncp(server_dns_names(servers), script_file, target_path)
|
76
|
+
BrpmAuto.log result
|
77
|
+
BrpmAuto.log "# Executing script on target via wrapper:"
|
78
|
+
result = @nsh.script_exec(server_dns_names(servers), wrapper_path, target_path)
|
79
|
+
BrpmAuto.log result
|
80
|
+
end
|
81
|
+
result
|
82
|
+
end
|
83
|
+
|
84
|
+
# Wrapper to run a shell action
|
85
|
+
# opens passed script path, or executes passed text
|
86
|
+
# processes the script in erb first to allow param substitution
|
87
|
+
# this method will separately resolve each server properties and execute in sequence
|
88
|
+
# note script may have keyword directives (see additional docs)
|
89
|
+
# ==== Attributes
|
90
|
+
#
|
91
|
+
# * +script_file+ - the path to the script or the text of the script
|
92
|
+
# * +options+ - hash of options, includes:
|
93
|
+
# * +-servers to override step servers
|
94
|
+
# * +-transfer_properties - the properties to push to the wrapper script
|
95
|
+
# * +-transfer_prefix - prefix to grab transfer properties from params
|
96
|
+
# * +-strip_prefix - remove the prefix or leave it (true/false)
|
97
|
+
#
|
98
|
+
# ==== Returns
|
99
|
+
#
|
100
|
+
# action output
|
101
|
+
#
|
102
|
+
def execute_script_per_server(script_file, options = {})
|
103
|
+
# get the body of the action
|
104
|
+
content = File.open(script_file).read
|
105
|
+
seed_servers = get_option(options, "servers")
|
106
|
+
transfer_properties = get_option(options, "transfer_properties",{})
|
107
|
+
keyword_items = get_keyword_items(content)
|
108
|
+
params_filter = get_option(keyword_items, "RPM_PARAMS_FILTER")
|
109
|
+
params_filter = get_option(options, "transfer_prefix", DEFAULT_PARAMS_FILTER)
|
110
|
+
strip_prefix = get_option(options, "strip_prefix", true)
|
111
|
+
transfer_properties.merge!(get_transfer_properties(params_filter, strip_prefix))
|
112
|
+
BrpmAuto.log "#----------- Executing Script on Remote Hosts -----------------#"
|
113
|
+
BrpmAuto.log "# Script: #{script_file}"
|
114
|
+
result = "No servers to execute on"
|
115
|
+
grouped_result = []
|
116
|
+
# Loop through the platforms
|
117
|
+
OS_PLATFORMS.each do |os, os_details|
|
118
|
+
servers_list = BrpmAuto.params.get_servers_by_os_platform(os) if seed_servers == ""
|
119
|
+
servers_list = BrpmAuto.params.get_servers_by_os_platform(os, seed_servers) if seed_servers != ""
|
120
|
+
BrpmAuto.message_box "OS Platform: #{os_details["name"]}"
|
121
|
+
BrpmAuto.log "No servers selected for: #{os_details["name"]}" if servers_list.size == 0
|
122
|
+
next if servers_list.size == 0
|
123
|
+
BrpmAuto.log "# #{os_details["name"]} - Targets: #{servers_list.inspect}"
|
124
|
+
servers_list.each do |item|
|
125
|
+
servers = {item[0] => item[1]}
|
126
|
+
BrpmAuto.log "#=> Endpoint: #{servers.keys[0]}"
|
127
|
+
BrpmAuto.log "# Setting Properties:"
|
128
|
+
add_channel_properties(transfer_properties, servers, os)
|
129
|
+
brpd_compatibility(transfer_properties, nil, servers)
|
130
|
+
transfer_properties.each{|k,v| BrpmAuto.log "\t#{k} => #{v}" }
|
131
|
+
shebang = read_shebang(os, content)
|
132
|
+
BrpmAuto.log "Shebang: #{shebang.inspect}"
|
133
|
+
wrapper_path = build_wrapper_script(os, shebang, transfer_properties, {"script_target" => File.basename(script_file)})
|
134
|
+
BrpmAuto.log "# Wrapper: #{wrapper_path}"
|
135
|
+
target_path = @nsh.nsh_path(transfer_properties["RPM_CHANNEL_ROOT"])
|
136
|
+
BrpmAuto.log "# Copying script to target: "
|
137
|
+
clean_line_breaks(os, script_file, content)
|
138
|
+
result = @nsh.ncp(server_dns_names(servers), script_file, target_path)
|
139
|
+
grouped_result << result
|
140
|
+
BrpmAuto.log result
|
141
|
+
BrpmAuto.log "# Executing script on target via wrapper:"
|
142
|
+
result = @nsh.script_exec(server_dns_names(servers), wrapper_path, target_path)
|
143
|
+
grouped_result << result
|
144
|
+
BrpmAuto.log result
|
145
|
+
end
|
146
|
+
end
|
147
|
+
grouped_result.join("\n")
|
148
|
+
end
|
149
|
+
|
150
|
+
# Copies remote files to a local staging repository
|
151
|
+
#
|
152
|
+
# ==== Attributes
|
153
|
+
#
|
154
|
+
# * +file_list+ - array of nsh_paths
|
155
|
+
# * +options+ - hash of options, includes: version
|
156
|
+
# ==== Returns
|
157
|
+
#
|
158
|
+
# hash of instance_path and md5 - {"instance_path" => "", "md5" => ""}
|
159
|
+
#
|
160
|
+
def package_artifacts(file_list, options = {})
|
161
|
+
version = get_option(options, "version", "")
|
162
|
+
version = "#{get_param("SS_request_number")}_#{precision_timestamp}" if version == ""
|
163
|
+
staging_path = get_staging_dir(version, true)
|
164
|
+
BrpmAuto.message_box "Copying Files to Staging via NSH"
|
165
|
+
BrpmAuto.log "\t StagingPath: #{staging_path}"
|
166
|
+
file_list.each do |file_path|
|
167
|
+
BrpmAuto.log "\t #{file_path}"
|
168
|
+
result = @nsh.ncp(nil, @nsh.nsh_path(file_path), staging_path)
|
169
|
+
BrpmAuto.log "\tCopy Result: #{result}"
|
170
|
+
end
|
171
|
+
package_file = "package_#{version}.zip"
|
172
|
+
@nsh.package_staged_artifacts(staging_path, package_file)
|
173
|
+
end
|
174
|
+
|
175
|
+
# Deploys a packaged instance based on staging info
|
176
|
+
# staging info is generated by the stage_files routine
|
177
|
+
# ==== Attributes
|
178
|
+
#
|
179
|
+
# * +staging_info+ - hash returned by stage_files
|
180
|
+
# * +options+ - hash of options, includes allow_md5_mismatch(true/false) and target_path to override server channel_root
|
181
|
+
# ==== Returns
|
182
|
+
#
|
183
|
+
# action output
|
184
|
+
#
|
185
|
+
def deploy_package_instance(staging_info, options = {})
|
186
|
+
mismatch_ok = get_option(options, "allow_md5_mismatch", false)
|
187
|
+
target_path = get_option(options, "target_path")
|
188
|
+
seed_servers = get_option(options, "servers")
|
189
|
+
instance_path = staging_info["instance_path"]
|
190
|
+
BrpmAuto.message_box "Deploying Files to Targets via NSH"
|
191
|
+
return_result = {"payload_path" => "", "results" => "FAILURE"}
|
192
|
+
raise "Command_Failed: no artifacts staged in #{File.dirname(instance_path)}" if Dir.entries(File.dirname(instance_path)).size < 3
|
193
|
+
BrpmAuto.log "\t StagingArchive: #{instance_path}"
|
194
|
+
md5 = Digest::MD5.file(instance_path).hexdigest
|
195
|
+
md5_match = md5 == staging_info["md5"]
|
196
|
+
BrpmAuto.log "\t Checksum: expected: #{staging_info["md5"]} - actual: #{md5}#{md5_match ? " MATCHED" : " NO MATCH"}"
|
197
|
+
raise "Command_Failed: bad md5 checksum match" if !md5_match && !allow_md5_mismatch
|
198
|
+
result = "No servers to execute on"
|
199
|
+
# Loop through the platforms
|
200
|
+
OS_PLATFORMS.each do |os, os_details|
|
201
|
+
servers = BrpmAuto.params.get_servers_by_os_platform(os) if seed_servers == ""
|
202
|
+
servers = BrpmAuto.params.get_servers_by_os_platform(os, seed_servers) if seed_servers != ""
|
203
|
+
BrpmAuto.message_box "OS Platform: #{os_details["name"]}"
|
204
|
+
BrpmAuto.log "No servers selected for: #{os_details["name"]}" if servers.size == 0
|
205
|
+
next if servers.size == 0
|
206
|
+
BrpmAuto.log "# #{os_details["name"]} - Targets: #{servers.inspect}"
|
207
|
+
target_path = @nsh.nsh_path(target_path) if target_path != ""
|
208
|
+
target_path = @nsh.nsh_path(servers.first[1].has_key?("CHANNEL_ROOT") ? servers.first[1]["CHANNEL_ROOT"] : os_details["tmp_dir"]) if target_path == ""
|
209
|
+
final_path = File.join(target_path, get_param("SS_run_key"))
|
210
|
+
return_result["payload_path"] = File.join(final_path)
|
211
|
+
result = @nsh.script_execute_body(server_dns_names(servers), "mkdir #{final_path}", target_path)
|
212
|
+
BrpmAuto.log result
|
213
|
+
BrpmAuto.log "# Deploying package on target:"
|
214
|
+
result = @nsh.ncp(server_dns_names(servers), instance_path, final_path)
|
215
|
+
BrpmAuto.log result
|
216
|
+
BrpmAuto.log "# Unzipping package on target:"
|
217
|
+
wrapper_path = create_command_wrapper("unzip -o", os, instance_path, final_path)
|
218
|
+
result = @nsh.script_exec(server_dns_names(servers), wrapper_path, final_path)
|
219
|
+
BrpmAuto.log result
|
220
|
+
end
|
221
|
+
result
|
222
|
+
end
|
223
|
+
|
224
|
+
# Copies remote files to a local staging repository
|
225
|
+
#
|
226
|
+
# ==== Attributes
|
227
|
+
#
|
228
|
+
# * +source+ - nsh path to source file
|
229
|
+
# * +destination+ - path to destination file
|
230
|
+
# * +options+ - hash of options
|
231
|
+
#
|
232
|
+
def copy_file(source, destination, options = {})
|
233
|
+
BrpmAuto.message_box "Copying files via NSH"
|
234
|
+
BrpmAuto.log "\t Source: #{source}"
|
235
|
+
BrpmAuto.log "\t Destination: #{destination}"
|
236
|
+
result = @nsh.cp(source, destination)
|
237
|
+
BrpmAuto.log "\tCopy Result: #{result}"
|
238
|
+
result
|
239
|
+
end
|
240
|
+
|
241
|
+
end
|
242
|
+
|
243
|
+
@rpm.log "Initializing nsh transport"
|
244
|
+
baa_path = defined?(BAA_BASE_PATH) ? BAA_BASE_PATH : "/opt/bmc/bladelogic"
|
245
|
+
nsh_path = "#{BAA_BASE_PATH}/NSH"
|
246
|
+
@nsh = TransportNSH.new(nsh_path)
|
247
|
+
@rpm.log "Path to nsh: #{nsh_path}"
|
248
|
+
@transport = DispatchNSH.new(@nsh)
|