brpm_content_framework 0.1.55
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 +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)
|