rq 0.1.7
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.
- data/DEPENDS +5 -0
- data/HISTORY +26 -0
- data/README +552 -0
- data/TODO +13 -0
- data/VERSION +1 -0
- data/bin/rq +391 -0
- data/bin/rq-0.1.7 +410 -0
- data/install.rb +143 -0
- data/lib/rq-0.1.7.rb +82 -0
- data/lib/rq-0.1.7/backer.rb +27 -0
- data/lib/rq-0.1.7/configfile.rb +78 -0
- data/lib/rq-0.1.7/configurator.rb +36 -0
- data/lib/rq-0.1.7/creator.rb +23 -0
- data/lib/rq-0.1.7/defaultconfig.txt +5 -0
- data/lib/rq-0.1.7/deleter.rb +39 -0
- data/lib/rq-0.1.7/executor.rb +41 -0
- data/lib/rq-0.1.7/feeder.rb +367 -0
- data/lib/rq-0.1.7/job.rb +51 -0
- data/lib/rq-0.1.7/jobqueue.rb +432 -0
- data/lib/rq-0.1.7/jobrunner.rb +63 -0
- data/lib/rq-0.1.7/jobrunnerdaemon.rb +179 -0
- data/lib/rq-0.1.7/lister.rb +22 -0
- data/lib/rq-0.1.7/locker.rb +37 -0
- data/lib/rq-0.1.7/logging.rb +117 -0
- data/lib/rq-0.1.7/mainhelper.rb +53 -0
- data/lib/rq-0.1.7/qdb.rb +634 -0
- data/lib/rq-0.1.7/querier.rb +33 -0
- data/lib/rq-0.1.7/refresher.rb +72 -0
- data/lib/rq-0.1.7/sleepcycle.rb +46 -0
- data/lib/rq-0.1.7/snapshotter.rb +25 -0
- data/lib/rq-0.1.7/statuslister.rb +22 -0
- data/lib/rq-0.1.7/submitter.rb +90 -0
- data/lib/rq-0.1.7/updater.rb +95 -0
- data/lib/rq-0.1.7/usage.rb +609 -0
- data/lib/rq-0.1.7/util.rb +286 -0
- data/lib/rq.rb +84 -0
- data/rdoc.cmd +2 -0
- data/rq +2 -0
- data/rq.gemspec +36 -0
- data/rq.help +552 -0
- data/white_box/crontab +2 -0
- data/white_box/killrq +18 -0
- data/white_box/rq_killer +27 -0
- metadata +126 -0
data/TODO
ADDED
@@ -0,0 +1,13 @@
|
|
1
|
+
---
|
2
|
+
- re-think db schema: separate critical info/index for speed?
|
3
|
+
- user docs
|
4
|
+
- examples
|
5
|
+
- installer script
|
6
|
+
- api docs
|
7
|
+
- rq relay mode (submit and track exit_status in local db)
|
8
|
+
- housekeeping - make backups of queue every so often, integrity_checks at
|
9
|
+
- scheduled intervals
|
10
|
+
- full boolean resource monitoring and resource requests
|
11
|
+
- in db message queue to send commands to remote nodes - ttl issues here...
|
12
|
+
- track feeders in queue rather than using lock on local file?
|
13
|
+
- use nodes to periodically generate stats (cache)
|
data/VERSION
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
0.1.7
|
data/bin/rq
ADDED
@@ -0,0 +1,391 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
#
|
3
|
+
# rq - http://raa.ruby-lang.org/project/rq
|
4
|
+
#
|
5
|
+
require 'rq'
|
6
|
+
#
|
7
|
+
# main program class
|
8
|
+
#
|
9
|
+
class Main
|
10
|
+
#{{{
|
11
|
+
include RQ
|
12
|
+
include RQ::Util
|
13
|
+
include RQ::Logging
|
14
|
+
include RQ::Usage
|
15
|
+
|
16
|
+
OPTSPEC =
|
17
|
+
#{{{
|
18
|
+
[
|
19
|
+
[
|
20
|
+
'--priority=priority', '-p',
|
21
|
+
'modes <submit> : set the job(s) priority - lowest(0) .. highest(n) - (default 0)'
|
22
|
+
],
|
23
|
+
[
|
24
|
+
'--tag=tag', '-t',
|
25
|
+
'modes <submit> : set the job(s) user data tag'
|
26
|
+
],
|
27
|
+
[
|
28
|
+
'--infile=infile', '-i',
|
29
|
+
'modes <submit> : infile'
|
30
|
+
],
|
31
|
+
[
|
32
|
+
'--quiet', '-q',
|
33
|
+
'modes <submit, feed> : do not echo submitted jobs, fail silently if
|
34
|
+
another process is already feeding'
|
35
|
+
],
|
36
|
+
[
|
37
|
+
'--daemon', '-d',
|
38
|
+
'modes <feed> : spawn a daemon'
|
39
|
+
],
|
40
|
+
[
|
41
|
+
'--max_feed=max_feed', '-f',
|
42
|
+
'modes <feed> : the maximum number of concurrent jobs run'
|
43
|
+
],
|
44
|
+
# [
|
45
|
+
# '--name=name',
|
46
|
+
# 'set the feeder name - (default q path)'
|
47
|
+
# ],
|
48
|
+
[
|
49
|
+
'--retries=retries', '-r',
|
50
|
+
'modes <feed> : specify transaction retries'
|
51
|
+
],
|
52
|
+
[
|
53
|
+
'--min_sleep=min_sleep', '-m',
|
54
|
+
'modes <feed> : specify min sleep'
|
55
|
+
],
|
56
|
+
[
|
57
|
+
'--max_sleep=max_sleep', '-M',
|
58
|
+
'modes <feed> : specify max sleep'
|
59
|
+
],
|
60
|
+
[
|
61
|
+
'--snapshot', '-s',
|
62
|
+
'operate on snapshot of queue'
|
63
|
+
],
|
64
|
+
[
|
65
|
+
'--verbosity=verbostiy', '-v',
|
66
|
+
'0|fatal < 1|error < 2|warn < 3|info < 4|debug - (default info)'
|
67
|
+
],
|
68
|
+
[
|
69
|
+
'--log=path','-l',
|
70
|
+
'set log file - (default stderr)'
|
71
|
+
],
|
72
|
+
[
|
73
|
+
'--log_age=log_age',
|
74
|
+
'daily | weekly | monthly - what age will cause log rolling (default nil)'
|
75
|
+
],
|
76
|
+
[
|
77
|
+
'--log_size=log_size',
|
78
|
+
'size in bytes - what size will cause log rolling (default nil)'
|
79
|
+
],
|
80
|
+
# [
|
81
|
+
# '--config=path',
|
82
|
+
# 'valid path - specify config file (default nil)'
|
83
|
+
# ],
|
84
|
+
# [
|
85
|
+
# '--template=[path]',
|
86
|
+
# 'valid path - generate a template config file in path (default stdout)'
|
87
|
+
# ],
|
88
|
+
[
|
89
|
+
'--help', '-h',
|
90
|
+
'this message'
|
91
|
+
],
|
92
|
+
]
|
93
|
+
#}}}
|
94
|
+
|
95
|
+
CONFIG_DEFAULT_PATH = 'rq.conf'
|
96
|
+
|
97
|
+
CONFIG_SEARCH_PATH = %w( . ~ /dmsp/reference/etc /usr/local/etc /usr/etc /etc )
|
98
|
+
|
99
|
+
attr :logger
|
100
|
+
attr :argv
|
101
|
+
attr :env
|
102
|
+
attr :cmd
|
103
|
+
attr :options
|
104
|
+
attr :qpath
|
105
|
+
attr :mode
|
106
|
+
attr :q
|
107
|
+
attr :daemon
|
108
|
+
|
109
|
+
def initialize argv = ARGV, env = ENV
|
110
|
+
#{{{
|
111
|
+
begin
|
112
|
+
@logger = Logger::new STDERR
|
113
|
+
@argv = mcp(argv.to_a)
|
114
|
+
@env = mcp(env.to_hash)
|
115
|
+
@cmd = ([$0] + @argv).join(' ')
|
116
|
+
|
117
|
+
parse_options
|
118
|
+
|
119
|
+
if(@options.has_key?('help') or @argv.include?('help'))
|
120
|
+
usage('port' => STDOUT, 'long' => true)
|
121
|
+
exit EXIT_SUCCESS
|
122
|
+
end
|
123
|
+
|
124
|
+
if(@options.has_key?('template') or (idx = @argv.index('template')))
|
125
|
+
gen_template(@options['template'] || @argv[idx + 1])
|
126
|
+
exit EXIT_SUCCESS
|
127
|
+
end
|
128
|
+
|
129
|
+
parse_argv
|
130
|
+
|
131
|
+
status = run
|
132
|
+
|
133
|
+
case status
|
134
|
+
when Integer
|
135
|
+
exit status
|
136
|
+
else
|
137
|
+
exit(status ? EXIT_SUCCESS : EXIT_FAILURE)
|
138
|
+
end
|
139
|
+
rescue => e
|
140
|
+
unless SystemExit === e
|
141
|
+
logerr e
|
142
|
+
exit EXIT_FAILURE
|
143
|
+
else
|
144
|
+
exit e.status
|
145
|
+
end
|
146
|
+
end
|
147
|
+
#}}}
|
148
|
+
end
|
149
|
+
def parse_argv
|
150
|
+
#{{{
|
151
|
+
@qpath = ENV['RQ_Q'] || @argv.shift
|
152
|
+
@mode = @argv.shift
|
153
|
+
#}}}
|
154
|
+
end
|
155
|
+
def run
|
156
|
+
#{{{
|
157
|
+
@qpath = Util::realpath @qpath
|
158
|
+
|
159
|
+
if @mode.nil? or @mode.strip.empty?
|
160
|
+
usage 'port' => STDERR, 'long' => false
|
161
|
+
exit EXIT_FAILURE
|
162
|
+
end
|
163
|
+
|
164
|
+
shortcuts = {
|
165
|
+
'c' => 'create',
|
166
|
+
's' => 'submit',
|
167
|
+
'l' => 'list',
|
168
|
+
'ls' => 'list',
|
169
|
+
't' => 'status',
|
170
|
+
'd' => 'delete',
|
171
|
+
'rm' => 'delete',
|
172
|
+
'u' => 'update',
|
173
|
+
'q' => 'query',
|
174
|
+
'e' => 'execute',
|
175
|
+
'C' => 'configure',
|
176
|
+
'S' => 'snapshot',
|
177
|
+
'L' => 'lock',
|
178
|
+
'b' => 'backup',
|
179
|
+
'h' => 'help',
|
180
|
+
'f' => 'feed',
|
181
|
+
}
|
182
|
+
|
183
|
+
if((longmode = shortcuts[@mode]))
|
184
|
+
@mode = longmode
|
185
|
+
end
|
186
|
+
|
187
|
+
begin
|
188
|
+
case @mode
|
189
|
+
when 'create'
|
190
|
+
create
|
191
|
+
when 'submit'
|
192
|
+
submit
|
193
|
+
when 'list'
|
194
|
+
list
|
195
|
+
when 'status'
|
196
|
+
status
|
197
|
+
when 'delete'
|
198
|
+
delete
|
199
|
+
when 'update'
|
200
|
+
update
|
201
|
+
when 'query'
|
202
|
+
query
|
203
|
+
when 'execute'
|
204
|
+
execute
|
205
|
+
when 'configure'
|
206
|
+
configure
|
207
|
+
when 'snapshot'
|
208
|
+
snapshot
|
209
|
+
when 'lock'
|
210
|
+
lock
|
211
|
+
when 'backup'
|
212
|
+
backup
|
213
|
+
when 'help'
|
214
|
+
usage 'port' => STDOUT, 'long' => true
|
215
|
+
exit EXIT_SUCCESS
|
216
|
+
when 'feed'
|
217
|
+
feed
|
218
|
+
else
|
219
|
+
raise "invalid mode <#{ @mode }>"
|
220
|
+
end
|
221
|
+
rescue Errno::EPIPE => e
|
222
|
+
raise if STDOUT.tty?
|
223
|
+
end
|
224
|
+
#}}}
|
225
|
+
end
|
226
|
+
def create
|
227
|
+
#{{{
|
228
|
+
init_logging
|
229
|
+
creator = Creator::new self
|
230
|
+
creator.create
|
231
|
+
#}}}
|
232
|
+
end
|
233
|
+
def submit
|
234
|
+
#{{{
|
235
|
+
init_logging
|
236
|
+
submitter = Submitter::new self
|
237
|
+
submitter.submit
|
238
|
+
#}}}
|
239
|
+
end
|
240
|
+
def list
|
241
|
+
#{{{
|
242
|
+
init_logging
|
243
|
+
lister = Lister::new self
|
244
|
+
lister.list
|
245
|
+
#}}}
|
246
|
+
end
|
247
|
+
def status
|
248
|
+
#{{{
|
249
|
+
init_logging
|
250
|
+
statuslister = StatusLister::new self
|
251
|
+
statuslister.statuslist
|
252
|
+
#}}}
|
253
|
+
end
|
254
|
+
def delete
|
255
|
+
#{{{
|
256
|
+
init_logging
|
257
|
+
deleter = Deleter::new self
|
258
|
+
deleter.delete
|
259
|
+
#}}}
|
260
|
+
end
|
261
|
+
def update
|
262
|
+
#{{{
|
263
|
+
init_logging
|
264
|
+
updater = Updater::new self
|
265
|
+
updater.update
|
266
|
+
#}}}
|
267
|
+
end
|
268
|
+
def query
|
269
|
+
#{{{
|
270
|
+
init_logging
|
271
|
+
querier = Querier::new self
|
272
|
+
querier.query
|
273
|
+
#}}}
|
274
|
+
end
|
275
|
+
def execute
|
276
|
+
#{{{
|
277
|
+
init_logging
|
278
|
+
executor = Executor::new self
|
279
|
+
executor.execute
|
280
|
+
#}}}
|
281
|
+
end
|
282
|
+
def configure
|
283
|
+
#{{{
|
284
|
+
init_logging
|
285
|
+
configurator = Configurator::new self
|
286
|
+
configurator.configure
|
287
|
+
#}}}
|
288
|
+
end
|
289
|
+
def snapshot
|
290
|
+
#{{{
|
291
|
+
init_logging
|
292
|
+
snapshotter = Snapshotter::new self
|
293
|
+
snapshotter.snapshot
|
294
|
+
#}}}
|
295
|
+
end
|
296
|
+
def lock
|
297
|
+
#{{{
|
298
|
+
init_logging
|
299
|
+
locker = Locker::new self
|
300
|
+
locker.lock
|
301
|
+
#}}}
|
302
|
+
end
|
303
|
+
def backup
|
304
|
+
#{{{
|
305
|
+
init_logging
|
306
|
+
backer = Backer::new self
|
307
|
+
backer.backup
|
308
|
+
#}}}
|
309
|
+
end
|
310
|
+
def feed
|
311
|
+
#{{{
|
312
|
+
feeder = Feeder::new self
|
313
|
+
feeder.feed
|
314
|
+
#}}}
|
315
|
+
end
|
316
|
+
def parse_options
|
317
|
+
#{{{
|
318
|
+
@op = OptionParser.new
|
319
|
+
@options = {}
|
320
|
+
OPTSPEC.each do |spec|
|
321
|
+
k = spec.first.gsub(%r/(?:--)|(?:=.*$)|(?:\s+)/o,'')
|
322
|
+
@op.def_option(*spec){|v| @options[k] = v}
|
323
|
+
end
|
324
|
+
@op.parse! @argv
|
325
|
+
@options
|
326
|
+
#}}}
|
327
|
+
end
|
328
|
+
def init_logging
|
329
|
+
#{{{
|
330
|
+
log, log_age, log_size, verbosity =
|
331
|
+
@options.values_at 'log', 'log_age', 'log_size', 'verbosity'
|
332
|
+
log_age = atoi log_age rescue nil
|
333
|
+
log_size = atoi log_size rescue nil
|
334
|
+
$logger = @logger = Logger::new(log || STDERR, log_age, log_size)
|
335
|
+
#
|
336
|
+
# hack to fix Logger sync bug
|
337
|
+
#
|
338
|
+
class << @logger; attr :logdev unless @logger.respond_to?(:logdev); end
|
339
|
+
@logdev = @logger.logdev.dev
|
340
|
+
@logdev.sync = true
|
341
|
+
level = nil
|
342
|
+
verbosity ||= 'info'
|
343
|
+
verbosity =
|
344
|
+
case verbosity
|
345
|
+
when /^\s*(?:4|d|debug)\s*$/io
|
346
|
+
level = 'Logging::DEBUG'
|
347
|
+
4
|
348
|
+
when /^\s*(?:3|i|info)\s*$/io
|
349
|
+
level = 'Logging::INFO'
|
350
|
+
3
|
351
|
+
when /^\s*(?:2|w|warn)\s*$/io
|
352
|
+
level = 'Logging::WARN'
|
353
|
+
2
|
354
|
+
when /^\s*(?:1|e|error)\s*$/io
|
355
|
+
level = 'Logging::ERROR'
|
356
|
+
1
|
357
|
+
when /^\s*(?:0|f|fatal)\s*$/io
|
358
|
+
level = 'Logging::FATAL'
|
359
|
+
0
|
360
|
+
else
|
361
|
+
abort "illegal verbosity setting <#{ verbosity }>"
|
362
|
+
end
|
363
|
+
@logger.level = 2 - ((verbosity % 5) - 2)
|
364
|
+
debug {"logging level <#{ level }>"}
|
365
|
+
@logger
|
366
|
+
#}}}
|
367
|
+
end
|
368
|
+
def init_config
|
369
|
+
#{{{
|
370
|
+
@config =
|
371
|
+
if @options['config']
|
372
|
+
ConfigFile::new(@options['config'])
|
373
|
+
else
|
374
|
+
ConfigFile::any CONFIG_DEFAULT_PATH, CONFIG_SEARCH_PATH
|
375
|
+
end
|
376
|
+
debug { "config.path <#{ @config.path }>" }
|
377
|
+
@config
|
378
|
+
#}}}
|
379
|
+
end
|
380
|
+
def gen_template template
|
381
|
+
#{{{
|
382
|
+
ConfigFile::gen_template(template)
|
383
|
+
self
|
384
|
+
#}}}
|
385
|
+
end
|
386
|
+
#}}}
|
387
|
+
end
|
388
|
+
#
|
389
|
+
# run main program unless included as lib
|
390
|
+
#
|
391
|
+
Main::new if $0 == __FILE__
|
data/bin/rq-0.1.7
ADDED
@@ -0,0 +1,410 @@
|
|
1
|
+
#!/dmsp/reference/bin/ruby
|
2
|
+
#
|
3
|
+
# rq - http://raa.ruby-lang.org/project/rq
|
4
|
+
#
|
5
|
+
require 'rq'
|
6
|
+
#
|
7
|
+
# main program class
|
8
|
+
#
|
9
|
+
class Main
|
10
|
+
#{{{
|
11
|
+
include RQ
|
12
|
+
include RQ::Util
|
13
|
+
include RQ::Logging
|
14
|
+
include RQ::Usage
|
15
|
+
|
16
|
+
#
|
17
|
+
# TODO - pull out config stuff into separate class
|
18
|
+
# TODO - add resouce manager
|
19
|
+
#
|
20
|
+
CONFIG_DEFAULT_PATH = "#{ $0 }.conf"
|
21
|
+
CONFIG_SEARCH_PATH = %w(. ~ /usr/local/etc /usr/etc /etc)
|
22
|
+
|
23
|
+
OPTSPEC =
|
24
|
+
#{{{
|
25
|
+
[
|
26
|
+
[
|
27
|
+
'--max_feed', '-f',
|
28
|
+
'the maximum number of concurrent jobs'
|
29
|
+
],
|
30
|
+
[
|
31
|
+
'--priority', '-p',
|
32
|
+
'set the job priority - lowest(0) .. highest(n) - (default 0)'
|
33
|
+
],
|
34
|
+
[
|
35
|
+
'--name',
|
36
|
+
'set the feeder name - (default q path)'
|
37
|
+
],
|
38
|
+
[
|
39
|
+
'--daemon', '-d',
|
40
|
+
'run in daemon mode'
|
41
|
+
],
|
42
|
+
[
|
43
|
+
'--quiet', '-q',
|
44
|
+
'fail quietly'
|
45
|
+
],
|
46
|
+
[
|
47
|
+
'--snapshot', '-s',
|
48
|
+
'operate on snapshot of queue'
|
49
|
+
],
|
50
|
+
[
|
51
|
+
'--retries', '-r',
|
52
|
+
'retries'
|
53
|
+
],
|
54
|
+
[
|
55
|
+
'--min_sleep', '-m',
|
56
|
+
'min sleep'
|
57
|
+
],
|
58
|
+
[
|
59
|
+
'--max_sleep', '-M',
|
60
|
+
'max sleep'
|
61
|
+
],
|
62
|
+
[
|
63
|
+
'--infile', '-i',
|
64
|
+
'infile'
|
65
|
+
],
|
66
|
+
[
|
67
|
+
'--help', '-h',
|
68
|
+
'this message'
|
69
|
+
],
|
70
|
+
[
|
71
|
+
'--verbosity=verbostiy', '-v',
|
72
|
+
'0|fatal < 1|error < 2|warn < 3|info < 4|debug - (default info)'
|
73
|
+
],
|
74
|
+
[
|
75
|
+
'--log=path','-l',
|
76
|
+
'set log file - (default stderr)'
|
77
|
+
],
|
78
|
+
[
|
79
|
+
'--log_age=log_age',
|
80
|
+
'daily | weekly | monthly - what age will cause log rolling (default nil)'
|
81
|
+
],
|
82
|
+
[
|
83
|
+
'--log_size=log_size',
|
84
|
+
'size in bytes - what size will cause log rolling (default nil)'
|
85
|
+
],
|
86
|
+
[
|
87
|
+
'--config=path',
|
88
|
+
'valid path - specify config file (default nil)'
|
89
|
+
],
|
90
|
+
[
|
91
|
+
'--template=[path]',
|
92
|
+
'valid path - generate a template config file in path (default stdout)'
|
93
|
+
],
|
94
|
+
]
|
95
|
+
#}}}
|
96
|
+
|
97
|
+
attr :logger
|
98
|
+
attr :argv
|
99
|
+
attr :env
|
100
|
+
attr :cmd
|
101
|
+
attr :options
|
102
|
+
attr :qpath
|
103
|
+
attr :mode
|
104
|
+
attr :q
|
105
|
+
attr :daemon
|
106
|
+
|
107
|
+
def initialize argv = ARGV, env = ENV
|
108
|
+
#{{{
|
109
|
+
begin
|
110
|
+
@logger = Logger::new STDERR
|
111
|
+
@argv = mcp(argv.to_a)
|
112
|
+
@env = mcp(env.to_hash)
|
113
|
+
@cmd = ([$0] + @argv).join(' ')
|
114
|
+
|
115
|
+
parse_options
|
116
|
+
|
117
|
+
if @options.has_key? 'help'
|
118
|
+
usage('port' => STDOUT, 'long' => true)
|
119
|
+
exit EXIT_SUCCESS
|
120
|
+
end
|
121
|
+
|
122
|
+
if @options.has_key? 'template'
|
123
|
+
gen_template @options['template']
|
124
|
+
exit EXIT_SUCCESS
|
125
|
+
end
|
126
|
+
|
127
|
+
parse_argv
|
128
|
+
|
129
|
+
status = run
|
130
|
+
|
131
|
+
case status
|
132
|
+
when Integer
|
133
|
+
exit status
|
134
|
+
else
|
135
|
+
exit(status ? EXIT_SUCCESS : EXIT_FAILURE)
|
136
|
+
end
|
137
|
+
rescue => e
|
138
|
+
unless SystemExit === e
|
139
|
+
logerr e
|
140
|
+
exit EXIT_FAILURE
|
141
|
+
else
|
142
|
+
exit e.status
|
143
|
+
end
|
144
|
+
end
|
145
|
+
#}}}
|
146
|
+
end
|
147
|
+
def parse_argv
|
148
|
+
#{{{
|
149
|
+
@qpath = ENV['RQ_Q'] || @argv.shift
|
150
|
+
@mode = @argv.shift
|
151
|
+
#}}}
|
152
|
+
end
|
153
|
+
def run
|
154
|
+
#{{{
|
155
|
+
if @qpath == 'help'
|
156
|
+
usage 'port' => STDOUT, 'long' => true
|
157
|
+
exit EXIT_SUCCESS
|
158
|
+
end
|
159
|
+
|
160
|
+
@qpath = Util::realpath @qpath
|
161
|
+
|
162
|
+
if @mode.nil? or @mode.strip.empty?
|
163
|
+
usage 'port' => STDERR, 'long' => false
|
164
|
+
exit EXIT_FAILURE
|
165
|
+
end
|
166
|
+
|
167
|
+
shortcuts = {
|
168
|
+
'c' => 'create',
|
169
|
+
's' => 'submit',
|
170
|
+
'l' => 'list',
|
171
|
+
'ls' => 'list',
|
172
|
+
't' => 'status',
|
173
|
+
'd' => 'delete',
|
174
|
+
'rm' => 'delete',
|
175
|
+
'u' => 'update',
|
176
|
+
'q' => 'query',
|
177
|
+
'e' => 'execute',
|
178
|
+
'C' => 'configure',
|
179
|
+
'S' => 'snapshot',
|
180
|
+
'L' => 'lock',
|
181
|
+
'b' => 'backup',
|
182
|
+
'h' => 'help',
|
183
|
+
'f' => 'feed',
|
184
|
+
}
|
185
|
+
|
186
|
+
if((longmode = shortcuts[@mode]))
|
187
|
+
@mode = longmode
|
188
|
+
end
|
189
|
+
|
190
|
+
begin
|
191
|
+
case @mode
|
192
|
+
when 'create'
|
193
|
+
create
|
194
|
+
when 'submit'
|
195
|
+
submit
|
196
|
+
when 'list'
|
197
|
+
list
|
198
|
+
when 'status'
|
199
|
+
status
|
200
|
+
when 'delete'
|
201
|
+
delete
|
202
|
+
when 'update'
|
203
|
+
update
|
204
|
+
when 'query'
|
205
|
+
query
|
206
|
+
when 'execute'
|
207
|
+
execute
|
208
|
+
when 'configure'
|
209
|
+
configure
|
210
|
+
when 'snapshot'
|
211
|
+
snapshot
|
212
|
+
when 'lock'
|
213
|
+
lock
|
214
|
+
when 'backup'
|
215
|
+
backup
|
216
|
+
when 'help'
|
217
|
+
usage 'port' => STDOUT, 'long' => true
|
218
|
+
exit EXIT_SUCCESS
|
219
|
+
when 'feed'
|
220
|
+
feed
|
221
|
+
else
|
222
|
+
raise "invalid mode <#{ @mode }>"
|
223
|
+
end
|
224
|
+
rescue Errno::EPIPE => e
|
225
|
+
raise if STDOUT.tty?
|
226
|
+
end
|
227
|
+
#}}}
|
228
|
+
end
|
229
|
+
def create
|
230
|
+
#{{{
|
231
|
+
init_logging
|
232
|
+
creator = Creator::new self
|
233
|
+
creator.create
|
234
|
+
#}}}
|
235
|
+
end
|
236
|
+
def submit
|
237
|
+
#{{{
|
238
|
+
init_logging
|
239
|
+
submitter = Submitter::new self
|
240
|
+
submitter.submit
|
241
|
+
#}}}
|
242
|
+
end
|
243
|
+
def list
|
244
|
+
#{{{
|
245
|
+
init_logging
|
246
|
+
lister = Lister::new self
|
247
|
+
lister.list
|
248
|
+
#}}}
|
249
|
+
end
|
250
|
+
def status
|
251
|
+
#{{{
|
252
|
+
init_logging
|
253
|
+
statuslister = StatusLister::new self
|
254
|
+
statuslister.statuslist
|
255
|
+
#}}}
|
256
|
+
end
|
257
|
+
def delete
|
258
|
+
#{{{
|
259
|
+
init_logging
|
260
|
+
deleter = Deleter::new self
|
261
|
+
deleter.delete
|
262
|
+
#}}}
|
263
|
+
end
|
264
|
+
def update
|
265
|
+
#{{{
|
266
|
+
init_logging
|
267
|
+
updater = Updater::new self
|
268
|
+
updater.update
|
269
|
+
#}}}
|
270
|
+
end
|
271
|
+
def query
|
272
|
+
#{{{
|
273
|
+
init_logging
|
274
|
+
querier = Querier::new self
|
275
|
+
querier.query
|
276
|
+
#}}}
|
277
|
+
end
|
278
|
+
def execute
|
279
|
+
#{{{
|
280
|
+
init_logging
|
281
|
+
executor = Executor::new self
|
282
|
+
executor.execute
|
283
|
+
#}}}
|
284
|
+
end
|
285
|
+
def configure
|
286
|
+
#{{{
|
287
|
+
init_logging
|
288
|
+
configurator = Configurator::new self
|
289
|
+
configurator.configure
|
290
|
+
#}}}
|
291
|
+
end
|
292
|
+
def snapshot
|
293
|
+
#{{{
|
294
|
+
init_logging
|
295
|
+
snapshotter = Snapshotter::new self
|
296
|
+
snapshotter.snapshot
|
297
|
+
#}}}
|
298
|
+
end
|
299
|
+
def lock
|
300
|
+
#{{{
|
301
|
+
init_logging
|
302
|
+
locker = Locker::new self
|
303
|
+
locker.lock
|
304
|
+
#}}}
|
305
|
+
end
|
306
|
+
def backup
|
307
|
+
#{{{
|
308
|
+
init_logging
|
309
|
+
backer = Backer::new self
|
310
|
+
backer.backup
|
311
|
+
#}}}
|
312
|
+
end
|
313
|
+
def feed
|
314
|
+
#{{{
|
315
|
+
feeder = Feeder::new self
|
316
|
+
feeder.feed
|
317
|
+
#}}}
|
318
|
+
end
|
319
|
+
def parse_options
|
320
|
+
#{{{
|
321
|
+
@op = OptionParser.new
|
322
|
+
@options = {}
|
323
|
+
OPTSPEC.each do |spec|
|
324
|
+
k = spec.first.gsub(%r/(?:--)|(?:=.*$)|(?:\s+)/o,'')
|
325
|
+
@op.def_option(*spec){|v| @options[k] = v}
|
326
|
+
end
|
327
|
+
#begin
|
328
|
+
@op.parse! @argv
|
329
|
+
#rescue OptionParser::InvalidOption => e
|
330
|
+
# preverve unknown options
|
331
|
+
#e.recover(argv)
|
332
|
+
#end
|
333
|
+
@options
|
334
|
+
#}}}
|
335
|
+
end
|
336
|
+
def init_logging
|
337
|
+
#{{{
|
338
|
+
log, log_age, log_size, verbosity =
|
339
|
+
@options.values_at 'log', 'log_age', 'log_size', 'verbosity'
|
340
|
+
log_age = atoi log_age rescue nil
|
341
|
+
log_size = atoi log_size rescue nil
|
342
|
+
$logger = @logger = Logger::new(log || STDERR, log_age, log_size)
|
343
|
+
#
|
344
|
+
# hack to fix Logger sync bug
|
345
|
+
#
|
346
|
+
class << @logger; attr :logdev unless @logger.respond_to?(:logdev); end
|
347
|
+
@logdev = @logger.logdev.dev
|
348
|
+
@logdev.sync = true
|
349
|
+
level = nil
|
350
|
+
verbosity ||= 'info'
|
351
|
+
verbosity =
|
352
|
+
case verbosity
|
353
|
+
when /^\s*(?:4|d|debug)\s*$/io
|
354
|
+
level = 'Logging::DEBUG'
|
355
|
+
4
|
356
|
+
when /^\s*(?:3|i|info)\s*$/io
|
357
|
+
level = 'Logging::INFO'
|
358
|
+
3
|
359
|
+
when /^\s*(?:2|w|warn)\s*$/io
|
360
|
+
level = 'Logging::WARN'
|
361
|
+
2
|
362
|
+
when /^\s*(?:1|e|error)\s*$/io
|
363
|
+
level = 'Logging::ERROR'
|
364
|
+
1
|
365
|
+
when /^\s*(?:0|f|fatal)\s*$/io
|
366
|
+
level = 'Logging::FATAL'
|
367
|
+
0
|
368
|
+
else
|
369
|
+
abort "illegal verbosity setting <#{ verbosity }>"
|
370
|
+
end
|
371
|
+
@logger.level = 2 - ((verbosity % 5) - 2)
|
372
|
+
debug {"logging level <#{ level }>"}
|
373
|
+
@logger
|
374
|
+
#}}}
|
375
|
+
end
|
376
|
+
def init_config
|
377
|
+
#{{{
|
378
|
+
@config =
|
379
|
+
if @options['config']
|
380
|
+
ConfigFile::new(@options['config'])
|
381
|
+
else
|
382
|
+
ConfigFile::any CONFIG_DEFAULT_PATH, CONFIG_SEARCH_PATH
|
383
|
+
end
|
384
|
+
debug { "config.path <#{ @config.path }>" }
|
385
|
+
debug { "config\n#{ @config.to_hash.to_yaml }\n" }
|
386
|
+
@config
|
387
|
+
#}}}
|
388
|
+
end
|
389
|
+
def gen_template template
|
390
|
+
#{{{
|
391
|
+
ConfigFile::gen_template(template)
|
392
|
+
self
|
393
|
+
#}}}
|
394
|
+
end
|
395
|
+
#}}}
|
396
|
+
end
|
397
|
+
#
|
398
|
+
# run main program unless included as lib
|
399
|
+
#
|
400
|
+
Main::new if $0 == __FILE__
|
401
|
+
#
|
402
|
+
# the default config is stored here
|
403
|
+
#
|
404
|
+
__END__
|
405
|
+
#
|
406
|
+
# default config
|
407
|
+
#
|
408
|
+
|
409
|
+
key0 : value0
|
410
|
+
key1 : value1
|