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,174 @@
|
|
1
|
+
class Params < ParamsBase
|
2
|
+
attr_reader :application
|
3
|
+
attr_reader :component
|
4
|
+
attr_reader :component_version
|
5
|
+
|
6
|
+
attr_reader :request_id
|
7
|
+
attr_reader :request_name
|
8
|
+
attr_reader :request_number
|
9
|
+
attr_reader :request_environment
|
10
|
+
attr_reader :request_scheduled_at
|
11
|
+
attr_reader :request_started_at
|
12
|
+
attr_reader :request_status
|
13
|
+
|
14
|
+
attr_reader :request_plan
|
15
|
+
attr_reader :request_plan_id
|
16
|
+
attr_reader :request_plan_member_id
|
17
|
+
attr_reader :request_plan_stage
|
18
|
+
|
19
|
+
attr_reader :request_run_id
|
20
|
+
attr_reader :request_run_name
|
21
|
+
|
22
|
+
attr_reader :step_id
|
23
|
+
attr_reader :step_number
|
24
|
+
attr_reader :step_name
|
25
|
+
attr_reader :step_description
|
26
|
+
attr_reader :step_estimate
|
27
|
+
|
28
|
+
attr_reader :step_version
|
29
|
+
attr_reader :step_version_artifact_url
|
30
|
+
|
31
|
+
attr_reader :servers
|
32
|
+
|
33
|
+
attr_reader :ticket_ids
|
34
|
+
attr_reader :tickets_foreign_ids
|
35
|
+
|
36
|
+
attr_reader :run_key
|
37
|
+
|
38
|
+
attr_reader :home_dir
|
39
|
+
attr_reader :automation_results_dir
|
40
|
+
attr_reader :output_dir
|
41
|
+
attr_reader :output_file
|
42
|
+
attr_reader :config_dir
|
43
|
+
|
44
|
+
attr_reader :log_file
|
45
|
+
|
46
|
+
attr_reader :brpm_url
|
47
|
+
attr_reader :brpm_api_token
|
48
|
+
|
49
|
+
attr_reader :run_from_brpm
|
50
|
+
attr_reader :unit_test
|
51
|
+
attr_reader :also_log_to_console
|
52
|
+
|
53
|
+
attr_reader :private_params
|
54
|
+
|
55
|
+
def initialize(params)
|
56
|
+
self.merge!(params)
|
57
|
+
|
58
|
+
@application = params["application"]
|
59
|
+
@component = params["component"]
|
60
|
+
@component_version = params["component_version"]
|
61
|
+
|
62
|
+
@request_id = params["request_id"]
|
63
|
+
@request_name = params["request_name"]
|
64
|
+
@request_number = params["request_number"]
|
65
|
+
@request_environment = params["request_environment"]
|
66
|
+
@request_scheduled_at = params["request_scheduled_at"]
|
67
|
+
@request_started_at = params["request_started_at"]
|
68
|
+
@request_status = params["request_status"]
|
69
|
+
|
70
|
+
@request_plan = params["request_plan"]
|
71
|
+
@request_plan_id = params["request_plan_id"]
|
72
|
+
@request_plan_member_id = params["request_plan_member_id"]
|
73
|
+
@request_plan_stage = params["request_plan_stage"]
|
74
|
+
|
75
|
+
@request_run_id = params["request_run_id"]
|
76
|
+
@request_run_name = params["request_run_name"]
|
77
|
+
|
78
|
+
@step_id = params["step_id"]
|
79
|
+
@step_number = params["step_number"]
|
80
|
+
@step_name = params["step_name"]
|
81
|
+
@step_description = params["step_description"]
|
82
|
+
@step_estimate = params["step_estimate"]
|
83
|
+
|
84
|
+
@step_version = params["step_version"]
|
85
|
+
@step_version_artifact_url = params["step_version_artifact_url"]
|
86
|
+
|
87
|
+
@servers = get_server_list
|
88
|
+
|
89
|
+
@ticket_ids = params["ticket_ids"]
|
90
|
+
@tickets_foreign_ids = params["tickets_foreign_ids"]
|
91
|
+
|
92
|
+
@run_key = params["SS_run_key"] || params["run_key"]
|
93
|
+
|
94
|
+
if params["SS_automation_results_dir"]
|
95
|
+
@home_dir = params["SS_automation_results_dir"].sub("automation_results", "")
|
96
|
+
else
|
97
|
+
@home_dir = params["home_dir"] || Dir.pwd
|
98
|
+
end
|
99
|
+
@automation_results_dir = params["SS_automation_results_dir"]
|
100
|
+
@output_dir = params["SS_output_dir"] || params["output_dir"] || Dir.pwd
|
101
|
+
@output_file = params["SS_output_file"]
|
102
|
+
@config_dir = "#{@home_dir}/config"
|
103
|
+
|
104
|
+
@log_file = params["log_file"] || "#{@output_dir}/brpm_auto.log"
|
105
|
+
|
106
|
+
@brpm_url = params["SS_base_url"] || params["brpm_url"]
|
107
|
+
@brpm_api_token = params["SS_api_token"] || params["brpm_api_token"]
|
108
|
+
|
109
|
+
@run_from_brpm = (@run_key != nil)
|
110
|
+
@unit_test = (params["unit_test"] == "true" || params["unit_test"] == 'true')
|
111
|
+
@also_log_to_console = (params["also_log_to_console"] == "true" || params["also_log_to_console"] == 'true')
|
112
|
+
|
113
|
+
@private_params = {}
|
114
|
+
if self.run_from_brpm
|
115
|
+
params.each do |k,v|
|
116
|
+
if k.end_with?("_encrypt") || k.end_with?("_enc")
|
117
|
+
if k.end_with?("_encrypt")
|
118
|
+
key_decrypted = k.gsub("_encrypt","")
|
119
|
+
elsif k.end_with?("_enc")
|
120
|
+
key_decrypted = k.gsub("_enc","")
|
121
|
+
end
|
122
|
+
value_decrypted = decrypt_string_with_prefix(v)
|
123
|
+
@private_params[key_decrypted] = value_decrypted
|
124
|
+
end
|
125
|
+
end
|
126
|
+
end
|
127
|
+
self.merge!(@private_params)
|
128
|
+
end
|
129
|
+
|
130
|
+
# Servers in params need to be filtered by OS
|
131
|
+
def get_servers_by_os_platform(os_platform, alt_servers = nil)
|
132
|
+
servers = alt_servers || @servers
|
133
|
+
result = servers.select{|k,v| v["os_platform"].downcase =~ /#{os_platform}/ }
|
134
|
+
end
|
135
|
+
|
136
|
+
# Fetches the property value for a server
|
137
|
+
#
|
138
|
+
# ==== Returns
|
139
|
+
#
|
140
|
+
# * property value
|
141
|
+
def get_server_property(server, property)
|
142
|
+
ans = ""
|
143
|
+
ans = @servers[server][property] if @servers.has_key?(server) && @servers[server].has_key?(property)
|
144
|
+
ans
|
145
|
+
end
|
146
|
+
|
147
|
+
# Returns the request id for use in rest calls
|
148
|
+
#
|
149
|
+
def rest_request_id
|
150
|
+
(self["request_id"].to_i - 1000).to_s
|
151
|
+
end
|
152
|
+
|
153
|
+
private
|
154
|
+
|
155
|
+
def get_server_list()
|
156
|
+
rxp = /server\d+_/
|
157
|
+
slist = {}
|
158
|
+
lastcur = -1
|
159
|
+
curname = ""
|
160
|
+
|
161
|
+
self.sort.reject{ |k| k[0].scan(rxp).empty? }.each_with_index do |server, idx|
|
162
|
+
cur = (server[0].scan(rxp)[0].gsub("server","").to_i * 0.001).round * 1000
|
163
|
+
if cur == lastcur
|
164
|
+
prop = server[0].gsub(rxp, "")
|
165
|
+
slist[curname][prop] = server[1]
|
166
|
+
else # new server
|
167
|
+
lastcur = cur
|
168
|
+
curname = server[1].chomp("0")
|
169
|
+
slist[curname] = {}
|
170
|
+
end
|
171
|
+
end
|
172
|
+
return slist
|
173
|
+
end
|
174
|
+
end
|
@@ -0,0 +1,81 @@
|
|
1
|
+
class ParamsBase < Hash
|
2
|
+
def [] key
|
3
|
+
BrpmAuto.substitute_tokens(super(key))
|
4
|
+
end
|
5
|
+
|
6
|
+
# Gets a params
|
7
|
+
#
|
8
|
+
# ==== Attributes
|
9
|
+
#
|
10
|
+
# * +key+ - key to find
|
11
|
+
def get(key, default_value = "")
|
12
|
+
self[key] || default_value
|
13
|
+
end
|
14
|
+
|
15
|
+
# Adds a key/value to the params
|
16
|
+
#
|
17
|
+
# ==== Attributes
|
18
|
+
#
|
19
|
+
# * +key_name+ - key name
|
20
|
+
# * +value+ - value to assign
|
21
|
+
#
|
22
|
+
# ==== Returns
|
23
|
+
#
|
24
|
+
# * value added
|
25
|
+
def add(key, value)
|
26
|
+
self[key] = value
|
27
|
+
end
|
28
|
+
|
29
|
+
# Adds a key/value to the params if not found
|
30
|
+
#
|
31
|
+
# ==== Attributes
|
32
|
+
#
|
33
|
+
# * +key_name+ - key name
|
34
|
+
# * +value+ - value to assign
|
35
|
+
#
|
36
|
+
# ==== Returns
|
37
|
+
#
|
38
|
+
# * value of key
|
39
|
+
def find_or_add(key, value)
|
40
|
+
ans = get(key)
|
41
|
+
add(key, value) if ans == ""
|
42
|
+
ans == "" ? value : ans
|
43
|
+
end
|
44
|
+
|
45
|
+
# Allows you to specify a key like a method call
|
46
|
+
#
|
47
|
+
# ==== Attributes
|
48
|
+
#
|
49
|
+
# * +key_name+ - key name note: you must use get if keyname has spaces
|
50
|
+
# * +*args+ - allows you to send a default value
|
51
|
+
#
|
52
|
+
# ==== Returns
|
53
|
+
#
|
54
|
+
# * value of key - including resolved properties that may be embedded
|
55
|
+
#
|
56
|
+
# ==== Examples
|
57
|
+
#
|
58
|
+
# @p = Params.new(params)
|
59
|
+
# @p.SS_application
|
60
|
+
# => "Sales"
|
61
|
+
def method_missing(key, *args)
|
62
|
+
ans = get(key.to_s)
|
63
|
+
ans = args[0] if ans == "" && args[0]
|
64
|
+
ans
|
65
|
+
end
|
66
|
+
|
67
|
+
# Raises an error if a key is not found
|
68
|
+
#
|
69
|
+
# ==== Attributes
|
70
|
+
#
|
71
|
+
# * +key_name+ - key name
|
72
|
+
#
|
73
|
+
# ==== Returns
|
74
|
+
#
|
75
|
+
# * value of key
|
76
|
+
def required(key)
|
77
|
+
raise "ParamsError: param #{key} must be present" unless self.has_key?(key)
|
78
|
+
get(key)
|
79
|
+
end
|
80
|
+
|
81
|
+
end
|
@@ -0,0 +1,38 @@
|
|
1
|
+
class RequestParams < ParamsBase
|
2
|
+
attr_reader :file_path
|
3
|
+
|
4
|
+
def initialize(path)
|
5
|
+
@file_path = "#{path}/request_data.json"
|
6
|
+
|
7
|
+
self.merge!(get_request_params)
|
8
|
+
end
|
9
|
+
|
10
|
+
def self.new_for_request(automation_results_dir, app_name, request_id)
|
11
|
+
self.new("#{automation_results_dir}/request/#{app_name}/#{request_id}")
|
12
|
+
end
|
13
|
+
|
14
|
+
def []=(key,val)
|
15
|
+
super(key, val)
|
16
|
+
|
17
|
+
set_request_params
|
18
|
+
end
|
19
|
+
|
20
|
+
#TODO: support parallel steps modifying the same request params file
|
21
|
+
|
22
|
+
private
|
23
|
+
|
24
|
+
def set_request_params
|
25
|
+
File.open(@file_path, "w") do |file|
|
26
|
+
file.puts(self.to_json)
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
30
|
+
def get_request_params
|
31
|
+
if File.exist?(@file_path)
|
32
|
+
json = File.read(@file_path)
|
33
|
+
JSON.parse(json)
|
34
|
+
else
|
35
|
+
{}
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
data/lib/rest_api.rb
ADDED
@@ -0,0 +1,155 @@
|
|
1
|
+
require 'rest-client'
|
2
|
+
require 'uri'
|
3
|
+
require 'json'
|
4
|
+
require 'cgi'
|
5
|
+
|
6
|
+
class Rest
|
7
|
+
class << self
|
8
|
+
def get(url, options = {})
|
9
|
+
rest_call(url, "get", options)
|
10
|
+
end
|
11
|
+
|
12
|
+
def post(url, data, options = {})
|
13
|
+
options[:data] = data
|
14
|
+
rest_call(url, "post", options)
|
15
|
+
end
|
16
|
+
|
17
|
+
def put(url, data, options = {})
|
18
|
+
options[:data] = data
|
19
|
+
rest_call(url, "put", options)
|
20
|
+
end
|
21
|
+
|
22
|
+
def delete(url, options = {})
|
23
|
+
rest_call(url, "delete", options)
|
24
|
+
end
|
25
|
+
|
26
|
+
# Makes an http method call and returns data in JSON
|
27
|
+
#
|
28
|
+
# ==== Attributes
|
29
|
+
#
|
30
|
+
# * +url+ - the url for the request
|
31
|
+
# * +method+ - the http method [get, put, post]
|
32
|
+
# * +options+ - a hash of options
|
33
|
+
# +verbose+: gives verbose output (yes/no)
|
34
|
+
# +data+: required for put and post methods a hash of post data
|
35
|
+
# +username+: username for basic http authentication
|
36
|
+
# +password+: password for basic http authentication
|
37
|
+
# +suppress_errors+: continues after errors if true
|
38
|
+
#
|
39
|
+
# ==== Returns
|
40
|
+
#
|
41
|
+
# * returns a hash of the http response with these keys
|
42
|
+
# * +status+ - success or ERROR
|
43
|
+
# * +message+ - if status is ERROR this will hold an error message
|
44
|
+
# * +code+ - the http status code 200=ok, 404=not found, 500=error, 504=not authorized
|
45
|
+
# * +data+ - the body of the http response
|
46
|
+
def rest_call(url, method, options = {})
|
47
|
+
methods = %w{get post put delete}
|
48
|
+
result = rest_params = {}
|
49
|
+
rest_params[:url] = URI.escape(url)
|
50
|
+
|
51
|
+
unless methods.include?(method.downcase)
|
52
|
+
BrpmAuto.log "No method named: #{method}"
|
53
|
+
result["code"] = -1
|
54
|
+
result["status"] = "failure"
|
55
|
+
result["message"] = "No method named: #{method}"
|
56
|
+
return result
|
57
|
+
end
|
58
|
+
|
59
|
+
rest_params[:method] = method.downcase
|
60
|
+
|
61
|
+
begin
|
62
|
+
BrpmAuto.log("REST #{method.upcase} #{BrpmAuto.privatize(url, get_token(url))}") unless options.has_key?("quiet")
|
63
|
+
|
64
|
+
if options.has_key?(:username) && options.has_key?(:password)
|
65
|
+
rest_params[:user] = options[:username]
|
66
|
+
rest_params[:password] = options[:password]
|
67
|
+
end
|
68
|
+
|
69
|
+
if %{put post}.include?(method.downcase)
|
70
|
+
options[:data] = options["data"] if options.has_key?("data")
|
71
|
+
rest_params[:payload] = options[:data].to_json if options.has_key?(:data)
|
72
|
+
if !options.has_key?(:data) || rest_params[:payload].length < 4
|
73
|
+
result["code"] = -1
|
74
|
+
result["status"] = "failure"
|
75
|
+
result["message"] = "No Post data"
|
76
|
+
return result
|
77
|
+
end
|
78
|
+
BrpmAuto.log "\tPost Data: #{rest_params[:payload].inspect}" unless options.has_key?("quiet")
|
79
|
+
end
|
80
|
+
|
81
|
+
rest_params.merge!({:headers => { :accept => :json, :content_type => :json }})
|
82
|
+
rest_params.merge!({:verify_ssl => OpenSSL::SSL::VERIFY_NONE})
|
83
|
+
rest_params.merge!({:cookies => options["cookies"] }) if options.has_key?("cookies")
|
84
|
+
|
85
|
+
BrpmAuto.log rest_params.inspect if options.has_key?("verbose")
|
86
|
+
|
87
|
+
response = RestClient::Request.new(rest_params).execute
|
88
|
+
|
89
|
+
BrpmAuto.log "\tParsing response to JSON format ..." if options.has_key?("verbose")
|
90
|
+
begin
|
91
|
+
parsed_response = JSON.parse(response)
|
92
|
+
rescue
|
93
|
+
parsed_response = response
|
94
|
+
end
|
95
|
+
BrpmAuto.log "Parsed response: #{parsed_response.inspect}" if options.has_key?("verbose")
|
96
|
+
|
97
|
+
if response.code < 300
|
98
|
+
BrpmAuto.log "\treturn code: #{response.code}" unless options.has_key?("quiet")
|
99
|
+
result["status"] = "success"
|
100
|
+
result["code"] = response.code
|
101
|
+
result["response"] = parsed_response
|
102
|
+
result["cookies"] = response.cookies if options.has_key?("cookies")
|
103
|
+
else
|
104
|
+
result["status"] = "error"
|
105
|
+
result["code"] = response.code
|
106
|
+
result["response"] = parsed_response
|
107
|
+
result["error_message"] = "REST call returned HTTP code:\n#{response.code}\n#{response}"
|
108
|
+
BrpmAuto.log "\tREST call returned HTTP code #{response.code}" unless options.has_key?("quiet")
|
109
|
+
end
|
110
|
+
|
111
|
+
rescue RestClient::Exception => e
|
112
|
+
BrpmAuto.log "\tREST call generated an error: #{e.message}" unless options.has_key?("quiet")
|
113
|
+
|
114
|
+
if e.response.nil?
|
115
|
+
result["status"] = "error"
|
116
|
+
result["code"] = 1000
|
117
|
+
result["response"] = "No response received."
|
118
|
+
result["error_message"] = "REST call generated a RestClient error:\n#{e.message}\n#{e.backtrace}"
|
119
|
+
return
|
120
|
+
end
|
121
|
+
|
122
|
+
BrpmAuto.log "\tParsing response to JSON format ..." unless options.has_key?("quiet")
|
123
|
+
begin
|
124
|
+
parsed_response = JSON.parse(e.response)
|
125
|
+
rescue
|
126
|
+
parsed_response = e.response
|
127
|
+
end
|
128
|
+
BrpmAuto.log "\tParsed response: #{parsed_response.inspect}"
|
129
|
+
|
130
|
+
result["status"] = "error"
|
131
|
+
result["code"] = e.response.code
|
132
|
+
result["response"] = parsed_response
|
133
|
+
result["error_message"] = "REST call generated a RestClient error:\n#{e.response.code}\n#{e.response}\n#{e.message}\n#{e.backtrace}"
|
134
|
+
|
135
|
+
BrpmAuto.log "Back trace:\n#{e.backtrace}" unless already_exists_error(result) or not_found_error(result)
|
136
|
+
end
|
137
|
+
result
|
138
|
+
end
|
139
|
+
|
140
|
+
def already_exists_error(result)
|
141
|
+
result["code"] == 422 && result["response"].keys.count >= 1 && (result["response"][result["response"].keys[0]][0] == "has already been taken" || result["response"][result["response"].keys[0]][0] =~ /Version Tag is not unique/)
|
142
|
+
end
|
143
|
+
|
144
|
+
def not_found_error(result)
|
145
|
+
result["code"] == 404
|
146
|
+
end
|
147
|
+
|
148
|
+
private
|
149
|
+
|
150
|
+
def get_token(url)
|
151
|
+
params = CGI::parse(url.split("?").last)
|
152
|
+
params.has_key?("token") ? params["token"] : ""
|
153
|
+
end
|
154
|
+
end
|
155
|
+
end
|
data/lib/semaphore.rb
ADDED
@@ -0,0 +1,79 @@
|
|
1
|
+
# Creates a pid-file semaphore to govern global execution
|
2
|
+
#
|
3
|
+
# ==== Attributes
|
4
|
+
#
|
5
|
+
# * +semaphore_key+ - string to name semaphore
|
6
|
+
# ==== Returns
|
7
|
+
#
|
8
|
+
# true if semaphore created, false if already exists
|
9
|
+
#
|
10
|
+
def semaphore(semaphore_key)
|
11
|
+
semaphore_dir = "#{BrpmAuto.params.automation_results_dir}/semaphores"
|
12
|
+
semaphore_name = "#{semaphore_key}.pid"
|
13
|
+
FileUtils.mkdir(semaphore_dir) unless File.exist?(semaphore_dir)
|
14
|
+
return false if File.exist?(File.join(semaphore_dir, semaphore_name))
|
15
|
+
fil = File.open(File.join(semaphore_dir, semaphore_name), "w+")
|
16
|
+
fil.puts BrpmAuto.precision_timestamp
|
17
|
+
fil.flush
|
18
|
+
fil.close
|
19
|
+
return true
|
20
|
+
end
|
21
|
+
|
22
|
+
# Clears a pid-file semaphore to govern global execution
|
23
|
+
#
|
24
|
+
# ==== Attributes
|
25
|
+
#
|
26
|
+
# * +semaphore_key+ - string to name semaphore
|
27
|
+
# ==== Returns
|
28
|
+
#
|
29
|
+
# true if semaphore deleted, false if it doesn't exist
|
30
|
+
#
|
31
|
+
def semaphore_clear(semaphore_key)
|
32
|
+
semaphore_dir = "#{BrpmAuto.params.automation_results_dir}/semaphores"
|
33
|
+
semaphore_name = "#{semaphore_key}.pid"
|
34
|
+
return false unless File.exist?(File.join(semaphore_dir, semaphore_name))
|
35
|
+
File.delete(File.join(semaphore_dir, semaphore_name))
|
36
|
+
return true
|
37
|
+
end
|
38
|
+
|
39
|
+
# Checks if a semaphore exists
|
40
|
+
#
|
41
|
+
# ==== Attributes
|
42
|
+
#
|
43
|
+
# * +semaphore_key+ - string to name semaphore
|
44
|
+
# ==== Returns
|
45
|
+
#
|
46
|
+
# true if semaphore exists, false if it doesn't exist
|
47
|
+
#
|
48
|
+
def semaphore_exists(semaphore_key)
|
49
|
+
semaphore_dir = "#{BrpmAuto.params.automation_results_dir}/semaphores"
|
50
|
+
semaphore_name = "#{semaphore_key}.pid"
|
51
|
+
return true if File.exist?(File.join(semaphore_dir, semaphore_name))
|
52
|
+
return false
|
53
|
+
end
|
54
|
+
|
55
|
+
# Waits a specified period for a semaphore to clear
|
56
|
+
# throws error after wait time if semaphore does not clear
|
57
|
+
# ==== Attributes
|
58
|
+
#
|
59
|
+
# * +semaphore_key+ - string to name semaphore
|
60
|
+
# * +wait_time+ - time in minutes before failure (default = 15mins)
|
61
|
+
# ==== Returns
|
62
|
+
#
|
63
|
+
# true if semaphore is cleared
|
64
|
+
#
|
65
|
+
def semaphore_wait(semaphore_key, wait_time = 15)
|
66
|
+
interval = 20; elapsed = 0
|
67
|
+
semaphore_dir = "#{BrpmAuto.params.automation_results_dir}/semaphores"
|
68
|
+
semaphore_name = "#{semaphore_key}.pid"
|
69
|
+
semaphore = File.join(semaphore_dir, semaphore_name)
|
70
|
+
return true if !File.exist?(semaphore)
|
71
|
+
until !File.exist?(semaphore) || (elapsed/60 > wait_time) do
|
72
|
+
sleep interval
|
73
|
+
elapsed += interval
|
74
|
+
end
|
75
|
+
if File.exist?(semaphore)
|
76
|
+
raise "ERROR: Semaphore (#{semaphore}) still exists after #{wait_time} minutes"
|
77
|
+
end
|
78
|
+
return true
|
79
|
+
end
|