bricolage 5.23.3 → 5.24.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 +4 -4
- data/lib/bricolage/application.rb +160 -37
- data/lib/bricolage/commandlineapplication.rb +0 -0
- data/lib/bricolage/commandutils.rb +0 -20
- data/lib/bricolage/context.rb +19 -4
- data/lib/bricolage/job.rb +38 -38
- data/lib/bricolage/jobfile.rb +2 -1
- data/lib/bricolage/jobnet.rb +21 -3
- data/lib/bricolage/jobnetrunner.rb +102 -62
- data/lib/bricolage/logfilepath.rb +2 -2
- data/lib/bricolage/loglocator.rb +71 -0
- data/lib/bricolage/loglocatorbuilder.rb +29 -0
- data/lib/bricolage/psqldatasource.rb +1 -1
- data/lib/bricolage/s3writer.rb +22 -0
- data/lib/bricolage/version.rb +1 -1
- data/test/home/Gemfile.lock +41 -0
- data/test/home/config/bricolage.yml +3 -0
- data/test/home/config/development/database.yml +113 -0
- data/test/home/config/development/password.yml +6 -0
- data/test/home/config/development/variable.yml +7 -0
- data/test/home/config/streamingload.yml +8 -0
- data/test/home/log/20170117/subsys::job1/20170117_202014082/subsys-job1.log +3 -0
- data/test/home/log/20170117/subsys::job1/20170117_202334852/subsys-job1.log +3 -0
- data/test/home/log/20170117/subsys::job1/20170117_202405056/subsys-job1.log +3 -0
- data/test/home/log/20170117/subsys::migrate/20170117_202548409/subsys-migrate.log +80 -0
- data/test/home/log/20170117/subsys::migrate/20170117_202636115/subsys-migrate.log +79 -0
- data/test/home/log/20170117/subsys::net1/20170117_203022461/subsys-job1.log +3 -0
- data/test/home/log/20170117/subsys::net1/20170117_203022461/subsys-job2.log +3 -0
- data/test/home/log/20170117/subsys::net1/20170117_203022461/subsys-job3.log +3 -0
- data/test/home/log/20170117/subsys::net1/20170117_203022461/subsys-job4.log +3 -0
- data/test/home/log/20170117/subsys::net1/20170117_203102130/subsys-job1.log +3 -0
- data/test/home/log/20170117/subsys::net1/20170117_203102130/subsys-job2.log +3 -0
- data/test/home/log/20170117/subsys::net1/20170117_203102130/subsys-job3.log +3 -0
- data/test/home/log/20170117/subsys::net1/20170117_203102130/subsys-job4.log +3 -0
- data/test/home/log/20170117/subsys::net1/20170117_203232033/subsys-job1.log +3 -0
- data/test/home/log/20170117/subsys::net1/20170117_203232033/subsys-job2.log +3 -0
- data/test/home/log/20170117/subsys::net1/20170117_203232033/subsys-job3.log +3 -0
- data/test/home/log/20170117/subsys::net1/20170117_203232033/subsys-job4.log +3 -0
- data/test/home/log/20170629/subsys::job1/20170629_155543985/subsys-job1.log +3 -0
- data/test/home/log/20170629/subsys::net1/20170629_154308811/subsys-job1.log +3 -0
- data/test/home/log/20170629/subsys::net1/20170629_154308811/subsys-job2.log +3 -0
- data/test/home/log/20170629/subsys::net1/20170629_154308811/subsys-job3.log +3 -0
- data/test/home/log/20170629/subsys::net1/20170629_154308811/subsys-job4.log +3 -0
- data/test/home/log/20170629/subsys::net1/20170629_155330208/subsys-job1.log +3 -0
- data/test/home/log/20170629/subsys::net1/20170629_155330208/subsys-job2.log +3 -0
- data/test/home/log/20170629/subsys::net1/20170629_155330208/subsys-job3.log +3 -0
- data/test/home/log/20170629/subsys::net1/20170629_155330208/subsys-job4.log +3 -0
- data/test/home/log/20170630/subsys::net1/20170630_145523511/subsys-job1.log +3 -0
- data/test/home/log/20170630/subsys::net1/20170630_145523511/subsys-job2.log +3 -0
- data/test/home/log/20170630/subsys::net1/20170630_145523511/subsys-job3.log +3 -0
- data/test/home/log/20170630/subsys::net1/20170630_145523511/subsys-job4.log +3 -0
- data/test/home/log/20170630/subsys::net1/20170630_145545097/subsys-job1.log +3 -0
- data/test/home/log/20170630/subsys::net1/20170630_145545097/subsys-job2.log +3 -0
- data/test/home/log/20170630/subsys::net1/20170630_145545097/subsys-job3.log +3 -0
- data/test/home/log/20170630/subsys::net1/20170630_145545097/subsys-job4.log +3 -0
- data/test/home/log/20170630/subsys::net1/20170630_145615702/subsys-job1.log +3 -0
- data/test/home/log/20170630/subsys::net1/20170630_145615702/subsys-job2.log +3 -0
- data/test/home/log/20170630/subsys::net1/20170630_145615702/subsys-job3.log +3 -0
- data/test/home/log/20170630/subsys::net1/20170630_145615702/subsys-job4.log +3 -0
- data/test/home/log/20170630/subsys::net1/20170630_153437221/subsys-job1.log +3 -0
- data/test/home/log/20170630/subsys::net1/20170630_153507519/subsys-job1.log +3 -0
- data/test/home/log/20170630/subsys::net1/20170630_153507519/subsys-job2.log +3 -0
- data/test/home/log/20170630/subsys::net1/20170630_153507519/subsys-job3.log +3 -0
- data/test/home/log/20170630/subsys::net1/20170630_153507519/subsys-job4.log +3 -0
- data/test/home/log/20170704/subsys::insert.sql.job/20170704_163033119/subsys-insert.log +14 -0
- data/test/home/log/20170704/subsys::insert.sql.job/20170704_172410576/subsys-insert.log +14 -0
- data/test/home/log/20170704/subsys::insert.sql.job/20170704_173130175/subsys-insert.log +14 -0
- data/test/home/log/20170704/subsys::insert.sql.job/20170704_173201376/subsys-insert.log +14 -0
- data/test/home/log/20170704/subsys::insert.sql/20170704_164143661/subsys-insert.sql.log +14 -0
- data/test/home/log/20170704/subsys::insert/20170704_164335210/subsys-insert.log +14 -0
- data/test/home/log/20170704/subsys::insert/20170704_164344251/subsys-insert.log +14 -0
- data/test/home/log/20170704/subsys::insert/20170704_164723299/subsys-insert.log +14 -0
- data/test/home/log/20170704/subsys::net1/20170704_162457694/subsys-job1.log +3 -0
- data/test/home/log/20170704/subsys::net1/20170704_162544282/subsys-job1.log +3 -0
- data/test/home/log/20170704/subsys::net1/20170704_162544282/subsys-job2.log +3 -0
- data/test/home/log/20170704/subsys::net1/20170704_162544282/subsys-job3.log +3 -0
- data/test/home/log/20170704/subsys::net1/20170704_162544282/subsys-job4.log +3 -0
- data/test/home/log/20170706/subsys::net1/20170706_201157129/subsys-job1.log +3 -0
- data/test/home/log/20170706/subsys::net1/20170706_201157129/subsys-job2.log +3 -0
- data/test/home/log/20170706/subsys::net1/20170706_201157129/subsys-job3.log +3 -0
- data/test/home/log/20170706/subsys::net1/20170706_201157129/subsys-job4.log +3 -0
- data/test/home/log/20170707/subsys::insert/20170707_020050817/subsys-insert.log +51 -0
- data/test/home/log/20170707/subsys::insert/20170707_020050817/subsys-insert.log.status +1 -0
- data/test/home/log/20170707/subsys::job1/20170707_020542902/subsys-job1.log +3 -0
- data/test/home/log/20170707/subsys::net1/20170707_012252058/subsys-job1.log +3 -0
- data/test/home/log/20170707/subsys::net1/20170707_012252058/subsys-job2.log +3 -0
- data/test/home/log/20170707/subsys::net1/20170707_012252058/subsys-job3.log +3 -0
- data/test/home/log/20170707/subsys::net1/20170707_012252058/subsys-job4.log +3 -0
- data/test/home/log/20170707/subsys::net1/20170707_020039222/subsys-job1.log +3 -0
- data/test/home/log/20170707/subsys::net1/20170707_020039222/subsys-job2.log +3 -0
- data/test/home/log/20170707/subsys::net1/20170707_020039222/subsys-job3.log +3 -0
- data/test/home/log/20170707/subsys::net1/20170707_020039222/subsys-job4.log +3 -0
- data/test/home/revert.sh +7 -0
- data/test/home/s +1 -0
- metadata +125 -43
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA1:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: f06abf75b09a7c9188d54ca938ccca52e8f122b5
|
|
4
|
+
data.tar.gz: 59c808715776490dc3374ef141528c3dc1d61960
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: ee5d6895a71111e135885180841cc2c5518cf7fc822bdad0ea576c84a5f77fccade1a3f0f8d68ab3240c3e9cc4d21e01798c685f73e3e8fc114ed6997daf69e2
|
|
7
|
+
data.tar.gz: df04ca26661704bc676ee26afcbe1d9bc2940bfbd97bd8c70f42725ee4ccf5842046903620f1e87471ffd97bdbeec9059a8b61c42de0dda37142df9692d067cb
|
|
@@ -8,6 +8,7 @@ require 'bricolage/datasource'
|
|
|
8
8
|
require 'bricolage/eventhandlers'
|
|
9
9
|
require 'bricolage/postgresconnection'
|
|
10
10
|
require 'bricolage/logfilepath'
|
|
11
|
+
require 'bricolage/loglocatorbuilder'
|
|
11
12
|
require 'bricolage/logger'
|
|
12
13
|
require 'bricolage/exception'
|
|
13
14
|
require 'bricolage/version'
|
|
@@ -36,15 +37,26 @@ module Bricolage
|
|
|
36
37
|
def main
|
|
37
38
|
opts = GlobalOptions.new(self)
|
|
38
39
|
@hooks.run_before_option_parsing_hooks(opts)
|
|
39
|
-
opts.parse
|
|
40
|
+
opts.parse!(ARGV)
|
|
41
|
+
|
|
40
42
|
@ctx = Context.for_application(opts.home, opts.job_file, environment: opts.environment, global_variables: opts.global_variables)
|
|
43
|
+
opts.merge_saved_options(@ctx.load_system_options)
|
|
44
|
+
|
|
45
|
+
if opts.dump_options?
|
|
46
|
+
opts.option_pairs.each do |name, value|
|
|
47
|
+
puts "#{name}=#{value.inspect}"
|
|
48
|
+
end
|
|
49
|
+
exit 0
|
|
50
|
+
end
|
|
41
51
|
if opts.list_global_variables?
|
|
42
52
|
list_variables @ctx.global_variables.resolve
|
|
43
53
|
exit 0
|
|
44
54
|
end
|
|
55
|
+
|
|
45
56
|
job = load_job(@ctx, opts)
|
|
46
|
-
process_job_options
|
|
57
|
+
process_job_options(job, opts)
|
|
47
58
|
job.compile
|
|
59
|
+
|
|
48
60
|
if opts.list_declarations?
|
|
49
61
|
list_declarations job.declarations
|
|
50
62
|
exit 0
|
|
@@ -62,11 +74,11 @@ module Bricolage
|
|
|
62
74
|
exit 0
|
|
63
75
|
end
|
|
64
76
|
|
|
77
|
+
@log_locator_builder = LogLocatorBuilder.for_options(@ctx, opts.log_path_format, opts.log_s3_ds, opts.log_s3_key_format)
|
|
78
|
+
|
|
65
79
|
@hooks.run_before_all_jobs_hooks(BeforeAllJobsEvent.new(job.id, [job]))
|
|
66
80
|
@hooks.run_before_job_hooks(BeforeJobEvent.new(job))
|
|
67
|
-
result =
|
|
68
|
-
job.execute
|
|
69
|
-
}
|
|
81
|
+
result = job.execute(log_locator: build_log_locator(job))
|
|
70
82
|
@hooks.run_after_job_hooks(AfterJobEvent.new(result))
|
|
71
83
|
@hooks.run_after_all_jobs_hooks(AfterAllJobsEvent.new(result.success?, [job]))
|
|
72
84
|
exit result.status
|
|
@@ -78,28 +90,13 @@ module Bricolage
|
|
|
78
90
|
error_exit ex.message
|
|
79
91
|
end
|
|
80
92
|
|
|
81
|
-
def
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
path = log_path.format(
|
|
93
|
+
def build_log_locator(job)
|
|
94
|
+
@log_locator_builder.build(
|
|
85
95
|
job_ref: JobNet::JobRef.new(job.subsystem, job.id, '-'),
|
|
86
96
|
jobnet_id: "#{job.subsystem}/#{job.id}",
|
|
87
97
|
job_start_time: @start_time,
|
|
88
98
|
jobnet_start_time: @start_time
|
|
89
99
|
)
|
|
90
|
-
FileUtils.mkdir_p File.dirname(path)
|
|
91
|
-
stdout_save = $stdout.dup
|
|
92
|
-
stderr_save = $stderr.dup
|
|
93
|
-
begin
|
|
94
|
-
File.open(path, 'w+') {|f|
|
|
95
|
-
$stdout.reopen f
|
|
96
|
-
$stderr.reopen f
|
|
97
|
-
}
|
|
98
|
-
return yield
|
|
99
|
-
ensure
|
|
100
|
-
$stdout.reopen stdout_save; stdout_save.close
|
|
101
|
-
$stderr.reopen stderr_save; stderr_save.close
|
|
102
|
-
end
|
|
103
100
|
end
|
|
104
101
|
|
|
105
102
|
def load_job(ctx, opts)
|
|
@@ -175,7 +172,124 @@ module Bricolage
|
|
|
175
172
|
end
|
|
176
173
|
end
|
|
177
174
|
|
|
178
|
-
class
|
|
175
|
+
class CommonApplicationOptions
|
|
176
|
+
OptionValue = Struct.new(:location, :value)
|
|
177
|
+
class OptionValue
|
|
178
|
+
def inspect
|
|
179
|
+
if location
|
|
180
|
+
"#{value.inspect} (#{location})"
|
|
181
|
+
else
|
|
182
|
+
value.inspect
|
|
183
|
+
end
|
|
184
|
+
end
|
|
185
|
+
end
|
|
186
|
+
|
|
187
|
+
def init_options
|
|
188
|
+
@opts = nil # valid only after #parse!
|
|
189
|
+
@opts_default = opts_default()
|
|
190
|
+
@opts_saved = {}
|
|
191
|
+
@opts_env = opts_env()
|
|
192
|
+
@opts_cmdline = {}
|
|
193
|
+
@parser = OptionParser.new
|
|
194
|
+
define_options @parser
|
|
195
|
+
end
|
|
196
|
+
private :init_options
|
|
197
|
+
|
|
198
|
+
attr_reader :parser
|
|
199
|
+
|
|
200
|
+
def opts_default
|
|
201
|
+
{
|
|
202
|
+
'log-path' => OptionValue.new('default value', nil),
|
|
203
|
+
'log-dir' => OptionValue.new('default value', nil),
|
|
204
|
+
's3-log' => OptionValue.new('default value', nil)
|
|
205
|
+
}
|
|
206
|
+
end
|
|
207
|
+
private :opts_default
|
|
208
|
+
|
|
209
|
+
def opts_env
|
|
210
|
+
env = {}
|
|
211
|
+
if path = ENV['BRICOLAGE_LOG_PATH']
|
|
212
|
+
env['log-path'] = OptionValue.new('env BRICOLAGE_LOG_PATH', path)
|
|
213
|
+
end
|
|
214
|
+
if path = ENV['BRICOLAGE_LOG_DIR']
|
|
215
|
+
env['log-dir'] = OptionValue.new('env BRICOLAGE_LOG_DIR', path)
|
|
216
|
+
end
|
|
217
|
+
env
|
|
218
|
+
end
|
|
219
|
+
private :opts_env
|
|
220
|
+
|
|
221
|
+
# abstract :define_options
|
|
222
|
+
|
|
223
|
+
def define_common_options
|
|
224
|
+
@parser.on('-L', '--log-dir=PATH', 'Log file prefix.') {|path|
|
|
225
|
+
@opts_cmdline['log-dir'] = OptionValue.new('--log-dir option', path)
|
|
226
|
+
}
|
|
227
|
+
@parser.on('--log-path=PATH', 'Log file path template.') {|path|
|
|
228
|
+
@opts_cmdline['log-path'] = OptionValue.new('--log-path option', path)
|
|
229
|
+
}
|
|
230
|
+
@parser.on('--s3-log=DS_KEY', 'S3 log file. (format: "DS:KEY")') {|spec|
|
|
231
|
+
@opts_cmdline['s3-log'] = OptionValue.new('--s3-log option', spec)
|
|
232
|
+
}
|
|
233
|
+
end
|
|
234
|
+
private :define_common_options
|
|
235
|
+
|
|
236
|
+
def merge_saved_options(vars)
|
|
237
|
+
saved = {}
|
|
238
|
+
@opts_default.keys.each do |key|
|
|
239
|
+
if val = vars.get_force(key)
|
|
240
|
+
saved[key] = OptionValue.new("bricolage.yml:#{key}", val)
|
|
241
|
+
end
|
|
242
|
+
end
|
|
243
|
+
@opts_saved = saved
|
|
244
|
+
build_common_options!
|
|
245
|
+
end
|
|
246
|
+
|
|
247
|
+
def build_common_options!
|
|
248
|
+
@opts = [@opts_default, @opts_saved, @opts_env, @opts_cmdline].inject({}) {|h, opts| h.update(opts); h }
|
|
249
|
+
end
|
|
250
|
+
private :build_common_options!
|
|
251
|
+
|
|
252
|
+
#
|
|
253
|
+
# Accessors
|
|
254
|
+
#
|
|
255
|
+
|
|
256
|
+
def common_options
|
|
257
|
+
@opts
|
|
258
|
+
end
|
|
259
|
+
|
|
260
|
+
def log_path_format
|
|
261
|
+
if opt = @opts['log-dir']
|
|
262
|
+
LogFilePath.new("#{opt.value}/%{std}.log")
|
|
263
|
+
elsif opt = @opts['log-path']
|
|
264
|
+
LogFilePath.new(opt.value)
|
|
265
|
+
else
|
|
266
|
+
nil
|
|
267
|
+
end
|
|
268
|
+
end
|
|
269
|
+
|
|
270
|
+
def log_s3_ds
|
|
271
|
+
s3_log_spec.first
|
|
272
|
+
end
|
|
273
|
+
|
|
274
|
+
def log_s3_key_format
|
|
275
|
+
s3_log_spec.last
|
|
276
|
+
end
|
|
277
|
+
|
|
278
|
+
def s3_log_spec
|
|
279
|
+
@s3_log_spec ||=
|
|
280
|
+
if opt = @opts['s3-log']
|
|
281
|
+
spec = opt.value
|
|
282
|
+
ds, k = spec.split(':', 2)
|
|
283
|
+
k = k.to_s.strip
|
|
284
|
+
key = k.empty? ? nil : k
|
|
285
|
+
[ds, LogFilePath.new(key || '%{std}.log')]
|
|
286
|
+
else
|
|
287
|
+
[nil, nil]
|
|
288
|
+
end
|
|
289
|
+
end
|
|
290
|
+
end
|
|
291
|
+
|
|
292
|
+
class GlobalOptions < CommonApplicationOptions
|
|
179
293
|
def initialize(app)
|
|
180
294
|
@app = app
|
|
181
295
|
@job_file = nil
|
|
@@ -184,16 +298,13 @@ module Bricolage
|
|
|
184
298
|
@global_variables = Variables.new
|
|
185
299
|
@dry_run = false
|
|
186
300
|
@explain = false
|
|
187
|
-
@log_path = LogFilePath.default
|
|
188
301
|
@list_global_variables = false
|
|
189
302
|
@list_variables = false
|
|
190
303
|
@list_declarations = false
|
|
191
|
-
@
|
|
192
|
-
|
|
304
|
+
@dump_options = false
|
|
305
|
+
init_options
|
|
193
306
|
end
|
|
194
307
|
|
|
195
|
-
attr_reader :parser
|
|
196
|
-
|
|
197
308
|
def help
|
|
198
309
|
@parser.help
|
|
199
310
|
end
|
|
@@ -220,12 +331,9 @@ Global Options:
|
|
|
220
331
|
parser.on('-E', '--explain', 'Applies EXPLAIN to the SQL.') {
|
|
221
332
|
@explain = true
|
|
222
333
|
}
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
parser.on('--log-path=PATH', 'Log file path template.') {|path|
|
|
227
|
-
@log_path = LogFilePath.new(path)
|
|
228
|
-
}
|
|
334
|
+
|
|
335
|
+
define_common_options
|
|
336
|
+
|
|
229
337
|
parser.on('--list-job-class', 'Lists job class name and (internal) class path.') {
|
|
230
338
|
JobClass.list.each do |name|
|
|
231
339
|
puts name
|
|
@@ -248,6 +356,9 @@ Global Options:
|
|
|
248
356
|
name, value = name_value.split('=', 2)
|
|
249
357
|
@global_variables[name] = value
|
|
250
358
|
}
|
|
359
|
+
parser.on('--dump-options', 'Shows option parsing result and quit.') {
|
|
360
|
+
@dump_options = true
|
|
361
|
+
}
|
|
251
362
|
parser.on('--help', 'Shows this message and quit.') {
|
|
252
363
|
puts parser.help
|
|
253
364
|
exit 0
|
|
@@ -262,19 +373,18 @@ Global Options:
|
|
|
262
373
|
@parser.on(*args, &block)
|
|
263
374
|
end
|
|
264
375
|
|
|
265
|
-
def parse(argv)
|
|
376
|
+
def parse!(argv)
|
|
266
377
|
@parser.order! argv
|
|
267
378
|
@rest_args = argv.dup
|
|
379
|
+
build_common_options!
|
|
268
380
|
rescue OptionParser::ParseError => ex
|
|
269
381
|
raise OptionError, ex.message
|
|
270
382
|
end
|
|
271
383
|
|
|
272
384
|
attr_reader :environment
|
|
273
385
|
attr_reader :home
|
|
274
|
-
attr_reader :global_variables
|
|
275
386
|
|
|
276
387
|
attr_reader :job_file
|
|
277
|
-
attr_reader :log_path
|
|
278
388
|
|
|
279
389
|
def file_mode?
|
|
280
390
|
!!@job_file
|
|
@@ -288,6 +398,12 @@ Global Options:
|
|
|
288
398
|
@explain
|
|
289
399
|
end
|
|
290
400
|
|
|
401
|
+
def dump_options?
|
|
402
|
+
@dump_options
|
|
403
|
+
end
|
|
404
|
+
|
|
405
|
+
attr_reader :global_variables
|
|
406
|
+
|
|
291
407
|
def list_global_variables?
|
|
292
408
|
@list_global_variables
|
|
293
409
|
end
|
|
@@ -299,6 +415,13 @@ Global Options:
|
|
|
299
415
|
def list_declarations?
|
|
300
416
|
@list_declarations
|
|
301
417
|
end
|
|
418
|
+
|
|
419
|
+
def option_pairs
|
|
420
|
+
common_options.merge({
|
|
421
|
+
'environment' => OptionValue.new(nil, @environment),
|
|
422
|
+
'home' => OptionValue.new(nil, @home)
|
|
423
|
+
})
|
|
424
|
+
end
|
|
302
425
|
end
|
|
303
426
|
|
|
304
427
|
end
|
|
File without changes
|
|
@@ -27,26 +27,6 @@ module Bricolage
|
|
|
27
27
|
def new_tmpfile_path(tmpdir = Dir.tmpdir)
|
|
28
28
|
"#{tmpdir}/#{Time.now.to_i}_#{$$}_#{'%x' % Thread.current.object_id}_#{rand(2**16)}"
|
|
29
29
|
end
|
|
30
|
-
|
|
31
|
-
# CLUDGE: FIXME: bricolage-jobnet command writes stderr to the file, we can find error messages from there.
|
|
32
|
-
# Using a temporary file or Ruby SQL driver is **MUCH** better.
|
|
33
|
-
def retrieve_last_match_from_stderr(re, nth = 0)
|
|
34
|
-
return unless $stderr.stat.file?
|
|
35
|
-
$stderr.flush
|
|
36
|
-
f = $stderr.dup
|
|
37
|
-
matched = nil
|
|
38
|
-
begin
|
|
39
|
-
f.seek(0)
|
|
40
|
-
f.each do |line|
|
|
41
|
-
m = line.slice(re, nth)
|
|
42
|
-
matched = m if m
|
|
43
|
-
end
|
|
44
|
-
ensure
|
|
45
|
-
f.close
|
|
46
|
-
end
|
|
47
|
-
matched = matched.to_s.strip
|
|
48
|
-
matched.empty? ? nil : matched
|
|
49
|
-
end
|
|
50
30
|
end
|
|
51
31
|
|
|
52
32
|
end
|
data/lib/bricolage/context.rb
CHANGED
|
@@ -84,6 +84,16 @@ module Bricolage
|
|
|
84
84
|
:parameter_file,
|
|
85
85
|
:parameter_file_loader
|
|
86
86
|
|
|
87
|
+
#
|
|
88
|
+
# System Parameters
|
|
89
|
+
#
|
|
90
|
+
|
|
91
|
+
SYSTEM_OPTION_FILE = 'bricolage.yml'
|
|
92
|
+
|
|
93
|
+
def load_system_options
|
|
94
|
+
load_variables_for_all_scopes(SYSTEM_OPTION_FILE)
|
|
95
|
+
end
|
|
96
|
+
|
|
87
97
|
#
|
|
88
98
|
# Variables
|
|
89
99
|
#
|
|
@@ -103,15 +113,20 @@ module Bricolage
|
|
|
103
113
|
}
|
|
104
114
|
end
|
|
105
115
|
|
|
116
|
+
GLOBAL_VARIABLE_FILE = 'variable.yml'
|
|
117
|
+
|
|
106
118
|
def load_global_variables
|
|
107
|
-
|
|
108
|
-
|
|
119
|
+
load_variables_for_all_scopes(GLOBAL_VARIABLE_FILE)
|
|
120
|
+
end
|
|
121
|
+
|
|
122
|
+
def load_variables_for_all_scopes(basename)
|
|
123
|
+
subsys_path = scoped? ? [@filesystem.relative(basename)] : []
|
|
124
|
+
vars_list = (config_pathes(basename) + subsys_path).map {|path|
|
|
109
125
|
path.exist? ? load_variables(path) : nil
|
|
110
126
|
}
|
|
111
127
|
Variables.union(*vars_list.compact)
|
|
112
128
|
end
|
|
113
|
-
|
|
114
|
-
GLOBAL_VARIABLE_FILE = 'variable.yml'
|
|
129
|
+
private :load_variables_for_all_scopes
|
|
115
130
|
|
|
116
131
|
def load_variables(path)
|
|
117
132
|
Variables.define {|vars|
|
data/lib/bricolage/job.rb
CHANGED
|
@@ -55,7 +55,8 @@ module Bricolage
|
|
|
55
55
|
end
|
|
56
56
|
|
|
57
57
|
def init_global_variables
|
|
58
|
-
# Context#global_variables loads file on each call,
|
|
58
|
+
# Context#global_variables loads file on each call,
|
|
59
|
+
# updating @global_variables is multi-thread safe.
|
|
59
60
|
@global_variables = @context.global_variables
|
|
60
61
|
@global_variables['bricolage_cwd'] = Dir.pwd
|
|
61
62
|
@global_variables['bricolage_job_dir'] = @context.job_dir.to_s
|
|
@@ -135,7 +136,26 @@ module Bricolage
|
|
|
135
136
|
@script.run_explain
|
|
136
137
|
end
|
|
137
138
|
|
|
138
|
-
def execute
|
|
139
|
+
def execute(log_locator: LogLocator.empty)
|
|
140
|
+
log_locator.redirect_stdouts {
|
|
141
|
+
do_execute
|
|
142
|
+
}
|
|
143
|
+
end
|
|
144
|
+
|
|
145
|
+
def execute_in_process(log_locator:)
|
|
146
|
+
# ??? FIXME: status_path should be independent from log_path.
|
|
147
|
+
# Also, status_path should be defined regardless of log_path.
|
|
148
|
+
status_path = log_locator.path ? "#{log_locator.path}.status" : nil
|
|
149
|
+
isolate_process(status_path) {
|
|
150
|
+
log_locator.redirect_stdouts {
|
|
151
|
+
do_execute
|
|
152
|
+
}
|
|
153
|
+
}
|
|
154
|
+
end
|
|
155
|
+
|
|
156
|
+
private
|
|
157
|
+
|
|
158
|
+
def do_execute
|
|
139
159
|
ENV['BRICOLAGE_PID'] = Process.pid.to_s
|
|
140
160
|
logger = @context.logger
|
|
141
161
|
logger.info "#{@context.environment} environment"
|
|
@@ -154,60 +174,40 @@ module Bricolage
|
|
|
154
174
|
return JobResult.error(ex)
|
|
155
175
|
end
|
|
156
176
|
|
|
157
|
-
def
|
|
158
|
-
isolate(log_path) {
|
|
159
|
-
execute
|
|
160
|
-
}
|
|
161
|
-
end
|
|
162
|
-
|
|
163
|
-
private
|
|
164
|
-
|
|
165
|
-
def isolate(log_path)
|
|
177
|
+
def isolate_process(status_path)
|
|
166
178
|
cpid = Process.fork {
|
|
167
179
|
Process.setproctitle "bricolage [#{@id}]"
|
|
168
|
-
redirect_stdouts_to log_path if log_path
|
|
169
180
|
result = yield
|
|
170
|
-
save_result result,
|
|
181
|
+
save_result result, status_path
|
|
171
182
|
exit result.status
|
|
172
183
|
}
|
|
173
184
|
_, st = Process.waitpid2(cpid)
|
|
174
|
-
restore_result(st,
|
|
175
|
-
end
|
|
176
|
-
|
|
177
|
-
def redirect_stdouts_to(path)
|
|
178
|
-
FileUtils.mkdir_p File.dirname(path)
|
|
179
|
-
# make readable for retrieve_last_match_from_stderr
|
|
180
|
-
File.open(path, 'w+') {|f|
|
|
181
|
-
$stdout.reopen f
|
|
182
|
-
$stderr.reopen f
|
|
183
|
-
}
|
|
185
|
+
restore_result(st, status_path)
|
|
184
186
|
end
|
|
185
187
|
|
|
186
|
-
def save_result(result,
|
|
188
|
+
def save_result(result, status_path)
|
|
187
189
|
return if result.success?
|
|
188
|
-
return unless
|
|
190
|
+
return unless status_path
|
|
189
191
|
begin
|
|
190
|
-
File.open(
|
|
192
|
+
File.open(status_path, 'w') {|f|
|
|
191
193
|
f.puts result.message
|
|
192
194
|
}
|
|
193
195
|
rescue
|
|
194
196
|
end
|
|
195
197
|
end
|
|
196
198
|
|
|
197
|
-
def restore_result(st,
|
|
198
|
-
JobResult.for_process_status(st, restore_message(
|
|
199
|
-
end
|
|
200
|
-
|
|
201
|
-
def restore_message(log_path)
|
|
202
|
-
return nil unless log_path
|
|
203
|
-
msg = read_if_exist(error_log_path(log_path))
|
|
204
|
-
msg ? msg.strip : nil
|
|
205
|
-
ensure
|
|
206
|
-
FileUtils.rm_f error_log_path(log_path) if log_path
|
|
199
|
+
def restore_result(st, status_path)
|
|
200
|
+
JobResult.for_process_status(st, restore_message(status_path))
|
|
207
201
|
end
|
|
208
202
|
|
|
209
|
-
def
|
|
210
|
-
|
|
203
|
+
def restore_message(status_path)
|
|
204
|
+
return nil unless status_path
|
|
205
|
+
begin
|
|
206
|
+
msg = read_if_exist(status_path)
|
|
207
|
+
msg ? msg.strip : nil
|
|
208
|
+
ensure
|
|
209
|
+
FileUtils.rm_f status_path
|
|
210
|
+
end
|
|
211
211
|
end
|
|
212
212
|
|
|
213
213
|
def read_if_exist(path)
|