tengine_job_agent 1.1.0 → 1.2.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml ADDED
@@ -0,0 +1,15 @@
1
+ ---
2
+ !binary "U0hBMQ==":
3
+ metadata.gz: !binary |-
4
+ ZjgwODA5ODNkNDMzMWM5ZjI2MjhiOWM4ZjZmM2ZjMTVhNjc3ZThkNQ==
5
+ data.tar.gz: !binary |-
6
+ M2ZlOGM2MGM3NjEwZWE2YjBhZTVmZmEzN2Q4ZDMwZjY3MTVmMTk4MA==
7
+ !binary "U0hBNTEy":
8
+ metadata.gz: !binary |-
9
+ MzVjODdkYzExOTBkZmFhM2RhZWM3MGViMWZkMTVmMmE3YTI0YmRiNDEzM2Zj
10
+ MmQzMTY1N2Q2MTg1ZTI0ZGQzNzQwY2I4MDU4ZGJmNjZmNmVhMmM2ZjE0YWIz
11
+ YTZlN2FmYTcwZTA0Mjg4YzVmNmFlYjFhYjI1MThkYjc2ZTQzM2Y=
12
+ data.tar.gz: !binary |-
13
+ NjM1OTZkNWYwZGQ5OGJjMThhNDgxNzVjZDk4NzI5ZDVhY2ZhYzUzMjBkNmRl
14
+ ZWM0N2MzNzU5YjE3Yzg5ZDExOGI2NzRjZGMzZTVkMmFmNWVlZTJmNGFhZDU1
15
+ ZTI4NGRhMTBlYTRlYTY0Mjg4N2Y5ODMzZjFjZjljYzBmOGM0NmQ=
data/Gemfile.lock CHANGED
@@ -1,38 +1,53 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- tengine_job_agent (1.1.0)
5
- tengine_event (~> 1.1.0)
6
- tengine_support (~> 1.1.0)
4
+ tengine_job_agent (1.2.0)
5
+ tengine_event (~> 1.2.0)
6
+ tengine_support (~> 1.2.0)
7
7
 
8
8
  GEM
9
9
  remote: http://rubygems.org/
10
10
  specs:
11
- ZenTest (4.8.2)
12
- activesupport (3.2.9)
13
- i18n (~> 0.6)
11
+ ZenTest (4.9.1)
12
+ activesupport (3.2.13)
13
+ i18n (= 0.6.1)
14
14
  multi_json (~> 1.0)
15
- amq-client (0.8.7)
16
- amq-protocol (>= 0.8.4)
15
+ amq-client (0.9.12)
16
+ amq-protocol (>= 1.2.0)
17
17
  eventmachine
18
- amq-protocol (0.8.4)
19
- amqp (0.8.4)
20
- amq-client (~> 0.8.7)
21
- amq-protocol (~> 0.8.4)
18
+ amq-protocol (1.2.0)
19
+ amqp (0.9.10)
20
+ amq-client (~> 0.9.12)
21
+ amq-protocol (~> 1.2.0)
22
22
  eventmachine
23
23
  autotest (4.4.6)
24
24
  ZenTest (>= 4.4.1)
25
- builder (3.1.3)
26
- ci_reporter (1.6.9)
27
- builder (>= 2.1.2)
25
+ coderay (1.0.9)
26
+ columnize (0.3.6)
27
+ debugger (1.5.0)
28
+ columnize (>= 0.3.1)
29
+ debugger-linecache (~> 1.2.0)
30
+ debugger-ruby_core_source (~> 1.2.0)
31
+ debugger-linecache (1.2.0)
32
+ debugger-ruby_core_source (1.2.0)
28
33
  diff-lcs (1.1.3)
29
- eventmachine (1.0.0)
34
+ eventmachine (1.0.3)
30
35
  i18n (0.6.1)
31
36
  macaddr (1.6.1)
32
37
  systemu (~> 2.5.0)
33
- multi_json (1.3.6)
34
- rake (0.9.2.2)
35
- rdiscount (1.6.8)
38
+ method_source (0.8.1)
39
+ multi_json (1.7.2)
40
+ pry (0.9.12.1)
41
+ coderay (~> 1.0.5)
42
+ method_source (~> 0.8)
43
+ slop (~> 3.4)
44
+ pry-debugger (0.2.2)
45
+ debugger (~> 1.3)
46
+ pry (~> 0.9.10)
47
+ pry-doc (0.4.5)
48
+ pry (>= 0.9)
49
+ yard (>= 0.8)
50
+ rake (10.0.4)
36
51
  rspec (2.10.0)
37
52
  rspec-core (~> 2.10.0)
38
53
  rspec-expectations (~> 2.10.0)
@@ -41,32 +56,35 @@ GEM
41
56
  rspec-expectations (2.10.0)
42
57
  diff-lcs (~> 1.1.3)
43
58
  rspec-mocks (2.10.1)
44
- simplecov (0.6.4)
59
+ simplecov (0.7.1)
45
60
  multi_json (~> 1.0)
46
- simplecov-html (~> 0.5.3)
47
- simplecov-html (0.5.3)
61
+ simplecov-html (~> 0.7.1)
62
+ simplecov-html (0.7.1)
63
+ slop (3.4.4)
48
64
  systemu (2.5.2)
49
- tengine_event (1.1.0)
65
+ tengine_event (1.2.0)
50
66
  activesupport (>= 3.0.0)
51
- amqp (~> 0.8.0)
52
- tengine_support (~> 1.1.0)
67
+ amqp (~> 0.9.10)
68
+ tengine_support (~> 1.2.0)
53
69
  uuid (~> 2.3.4)
54
- tengine_support (1.1.0)
70
+ tengine_support (1.2.0)
55
71
  activesupport (>= 3.0.0)
56
- uuid (2.3.5)
72
+ uuid (2.3.7)
57
73
  macaddr (~> 1.0)
58
- yard (0.8.2.1)
74
+ yard (0.8.6.1)
59
75
 
60
76
  PLATFORMS
61
77
  ruby
62
78
 
63
79
  DEPENDENCIES
80
+ ZenTest (~> 4.9.0)
64
81
  autotest
65
82
  bundler
66
- ci_reporter (~> 1.6.5)
67
- rake (~> 0.9.2.2)
68
- rdiscount
83
+ pry
84
+ pry-debugger
85
+ pry-doc
86
+ rake
69
87
  rspec (~> 2.10.0)
70
- simplecov (~> 0.6.4)
88
+ simplecov
71
89
  tengine_job_agent!
72
- yard (~> 0.8.1)
90
+ yard
@@ -1,12 +1,10 @@
1
1
  #!/usr/bin/env ruby
2
2
  # -*- coding: utf-8 -*-
3
3
 
4
- unless RUBY_VERSION >= "1.9.2"
5
- raise "RUBY_VERSION must be >= 1.9.2 but was #{RUBY_VERSION}"
6
- end
7
-
8
- # Process.daemon(true, true)
9
- Process.daemon(true)
4
+ # IGNORE SIGHUP like a daemon
5
+ # http://stackoverflow.com/questions/3688550/make-a-ruby-program-a-daemon
6
+ # source code of call_as_daemon method in http://daemons.rubyforge.org/classes/Daemonize.html
7
+ Signal.trap 'SIGHUP', 'IGNORE'
10
8
 
11
9
  $LOAD_PATH << File.expand_path("../lib", File.dirname(__FILE__))
12
10
  require "tengine_job_agent"
@@ -1,27 +1,72 @@
1
+ # -*- coding: utf-8 -*-
2
+ require 'tengine_event'
1
3
  require 'tengine_job_agent'
4
+ require 'time'
2
5
  require 'logger'
3
6
  require 'yaml'
4
7
  require 'tengine/support/yaml_with_erb'
5
8
 
9
+ require 'eventmachine'
10
+
6
11
  module TengineJobAgent::CommandUtils
7
12
  def self.included(mod)
8
13
  mod.extend(ClassMethods)
9
14
  end
10
15
 
16
+ DEFAULT_CONFIG = {
17
+ 'timeout' => 1,
18
+ # 'logfile' => "log/#{File.basename($PROGRAM_NAME)}-#{`hostname`.strip}-#{Process.pid}.log",
19
+ 'logfile' => "#{File.basename($PROGRAM_NAME)}.log",
20
+ # 'logfile' => "tengine_job_agent.log",
21
+ 'connection' => {
22
+ 'host' => ENV['TENGINE_MQ_HOST'] || 'localhost',
23
+ 'port' => (ENV['TENGINE_MQ_PORT'] || 5672).to_i,
24
+ # vhost:
25
+ # user:
26
+ # pass:
27
+ },
28
+ 'exchange' => {
29
+ 'name' => 'tengine_event_exchange',
30
+ 'type' => 'direct',
31
+ 'durable' => true,
32
+ },
33
+ 'sender' => {
34
+ 'keep_connection' => true,
35
+ },
36
+ 'heartbeat' => {
37
+ 'job' => {
38
+ 'interval' => 1
39
+ }
40
+ }
41
+ }.freeze
42
+
11
43
  module ClassMethods
12
44
  def load_config
13
45
  config_path = Dir["{.,./config,/etc}/tengine_job_agent{.yml,.yml.erb}"].first
14
- YAML.load_file(config_path)
46
+ if config_path
47
+ YAML.load_file(config_path)
48
+ else
49
+ DEFAULT_CONFIG
50
+ end
15
51
  end
16
52
 
17
53
  def process(*args)
18
54
  config = load_config
19
55
  logger = new_logger(config)
56
+ Tengine.logger = logger
57
+ Kernel.at_exit do
58
+ logger.info("process is exiting now")
59
+ end
60
+
20
61
  begin
21
- return new(logger, args, config).process
62
+ logger.info("#{self.name}#process starting")
63
+ new(logger, args, config).process
64
+ logger.info("#{self.name}#process finished successfully")
22
65
  rescue Exception => e
23
- logger.error("error: [#{e.class.name}] #{e.message}\n " << e.backtrace.join("\n"))
66
+ logger.error("#{self.name}#process error: [#{e.class.name}] #{e.message}\n " << e.backtrace.join("\n"))
24
67
  return false
68
+ ensure
69
+ logger.info("#{self.name}#process finished at the end")
25
70
  end
26
71
  end
27
72
 
@@ -31,7 +76,9 @@ module TengineJobAgent::CommandUtils
31
76
  prefix = self.name.split('::').last.downcase
32
77
  logfile = File.expand_path("#{prefix}-#{Process.pid}.log", config['log_dir'])
33
78
  end
34
- Logger.new(logfile)
79
+ result = Tengine::Support::NamedLogger.new(File.basename($PROGRAM_NAME), logfile)
80
+ result.level = Logger::DEBUG
81
+ result
35
82
  end
36
83
 
37
84
  end
@@ -12,7 +12,6 @@ class TengineJobAgent::Run
12
12
  @error_output = STDERR
13
13
  @args = args
14
14
  @config = config
15
- @pid_path = File.expand_path("pid_for_#{Process.pid}", @config['log_dir'])
16
15
  @timeout = (config[:timeout ] || ENV["MM_SYSTEM_AGENT_RUN_TIMEOUT" ] || 600).to_i # seconds
17
16
  @timeout_alert = (config[:timeout_alert] || ENV["MM_SYSTEM_AGENT_RUN_TIMEOUT_ALERT"] || 30 ).to_i # seconds
18
17
  end
@@ -21,44 +20,67 @@ class TengineJobAgent::Run
21
20
  validate_environment
22
21
  line = nil
23
22
  process_spawned = false
24
- begin
25
- timeout(@timeout) do #タイムアウト(秒)
26
- @logger.info("watchdog process spawning for #{@args.join(' ')}")
27
- pid = spawn_watchdog # watchdogプロセスをspawnで起動
28
- @logger.info("watchdog process spawned. PID: #{pid.inspect}")
29
- File.open(@pid_path, "r") do |f|
30
- sleep(0.1) until line = f.gets
31
- process_spawned = true
32
- @logger.info("watchdog process returned first result: #{line.inspect}")
33
- if line =~ /\A\d+\n?\Z/ # 数字と改行のみで構成されるならそれはPIDのはず。
34
- @pid_output.puts(line.strip)
35
- @logger.info("return PID: #{pid.inspect}")
36
- else
37
- f.rewind
38
- msg = f.read
39
- @logger.error("error occurred:\n#{msg}")
40
- @error_output.puts(msg)
41
- return false
23
+ setup_pid_file do |pid_path|
24
+ begin
25
+ timeout(@timeout) do #タイムアウト()
26
+ @logger.info("watchdog process spawning for #{@args.join(' ')}")
27
+ pid = spawn_watchdog(pid_path) # watchdogプロセスをspawnで起動
28
+ @logger.info("watchdog daemon invocation process spawned. PID: #{pid.inspect}")
29
+ File.open(pid_path, "r") do |f|
30
+ sleep(0.1) until line = f.gets
31
+ process_spawned = true
32
+ @logger.info("watchdog process returned first result: #{line.inspect}")
33
+ if line =~ /\A\d+\n?\Z/ # 数字と改行のみで構成されるならそれはPIDのはず。
34
+ @pid_output.puts(line.strip)
35
+ @logger.info("return PID: #{line.strip}")
36
+ else
37
+ f.rewind
38
+ msg = f.read
39
+ @logger.error("error occurred:\n#{msg}")
40
+ @error_output.puts(msg)
41
+ return false
42
+ end
42
43
  end
43
44
  end
45
+ rescue Timeout::Error => e
46
+ @error_output.puts("[#{e.class.name}] #{e.message}")
47
+ raise e # raiseしたものはTengineJobAgent::Run.processでloggerに出力されるので、ここでは何もしません
44
48
  end
45
- rescue Timeout::Error => e
46
- @error_output.puts("[#{e.class.name}] #{e.message}")
47
- raise e # raiseしたものはTengineJobAgent::Run.processでloggerに出力されるので、ここでは何もしません
48
49
  end
49
50
  end
50
51
 
51
- # 引数に@pid_pathを渡してwatchdogを起動します。戻り値は起動したwatchdogのPIDです
52
- def spawn_watchdog
53
- @logger.info("pid file creating: #{@pid_path}")
54
- File.open(@pid_path, "w"){ } # ファイルをクリア
55
- @logger.info("pid file created: #{@pid_path}")
52
+ def pid_path
53
+ File.expand_path("pid_for_#{Process.pid}", @config['log_dir'])
54
+ end
55
+
56
+ def setup_pid_file
57
+ path = self.pid_path
58
+ @logger.info("pid file creating: #{path}")
59
+ File.open(path, "w"){ } # ファイルをクリア
60
+ @logger.info("pid file created: #{path}")
61
+ begin
62
+ res = yield(path)
63
+ File.delete(path) if File.exist?(path)
64
+ return res
65
+ rescue => e
66
+ @logger.warn("pid file #{path.inspect} is not deleted cause of #{e.class.name}")
67
+ raise
68
+ end
69
+ end
70
+
71
+ # 引数にpid_pathを渡してwatchdogを起動します。戻り値は起動したwatchdogのPIDです
72
+ def spawn_watchdog(pid_path)
56
73
  # http://doc.ruby-lang.org/ja/1.9.2/method/Kernel/m/spawn.html を参考にしています
57
74
  args = @args # + [{:out => stdout_w}] #, :err => stderr_w}]
58
75
  watchdog = File.expand_path("../../bin/tengine_job_agent_watchdog", File.dirname(__FILE__))
59
- @logger.info("spawning watchdog: #{@pid_path}")
60
- pid = Process.spawn(RbConfig.ruby, watchdog, @pid_path, *args)
76
+ # args = [RbConfig.ruby, watchdog, pid_path, *(@args + [{:out => stdout_w, :err => stderr_w}])]
77
+ args = [RbConfig.ruby, watchdog, pid_path, *@args]
78
+ @logger.info("Process.spawn(*#{args.inspect})")
79
+ pid = Process.spawn(*args)
80
+ # ただしこのpidとして起動したプロセスはデーモンプロセスを起動するためのプロセスであり、
81
+ # 即座に終了してします
61
82
  @logger.info("spawned watchdog: #{pid}")
83
+ @logger.debug("spawned watchdog:" << `ps aux | grep tengine_job_agent_watchdog | grep -v grep`)
62
84
  return pid
63
85
  end
64
86
 
@@ -7,6 +7,8 @@ require 'tengine_event'
7
7
  require 'eventmachine'
8
8
  require 'uuid'
9
9
 
10
+ require 'tengine/support/core_ext/hash/keys' # for deep_symbolize_keys
11
+
10
12
  class TengineJobAgent::Watchdog
11
13
  include TengineJobAgent::CommandUtils
12
14
 
@@ -19,59 +21,91 @@ class TengineJobAgent::Watchdog
19
21
  end
20
22
 
21
23
  def process
24
+ @logger.info("process start")
22
25
  pid, process_status = nil, nil
26
+ @logger.debug("#{__FILE__}##{__LINE__} before with_tmp_outs")
23
27
  with_tmp_outs do |stdout, stderr|
28
+ @logger.debug("#{__FILE__}##{__LINE__} before EM.run")
24
29
  EM.run do
30
+ @logger.debug("#{__FILE__}##{__LINE__} before sender.mq_suite.send :ensures, :connection")
25
31
  sender.mq_suite.send :ensures, :connection do
26
- sender.wait_for_connection do
32
+ @logger.debug("before spawn_process")
27
33
  begin
34
+ @logger.debug("#{__FILE__}##{__LINE__} before spawn_process")
28
35
  pid = spawn_process
36
+ @logger.debug("#{__FILE__}##{__LINE__} before output pid")
29
37
  File.open(@pid_path, "a"){|f| f.puts(pid)} # 起動したPIDを呼び出し元に返す
30
- detach_and_wait_process(pid)
38
+ @logger.debug("#{__FILE__}##{__LINE__} before start_wait_process")
39
+ start_wait_process(pid)
40
+ @logger.debug("#{__FILE__}##{__LINE__} after start_wait_process")
31
41
  rescue Exception => e
32
- File.open(@pid_path, "a"){|f| f.puts("[#{e.class.name}] #{e.message}")}
33
42
  @logger.error("[#{e.class.name}] #{e.message}")
43
+ File.open(@pid_path, "a"){|f| f.puts("[#{e.class.name}] #{e.message}")}
34
44
  EM.stop
35
45
  end
36
- end
46
+ @logger.debug("#{__FILE__}##{__LINE__}")
37
47
  end
48
+ @logger.debug("#{__FILE__}##{__LINE__} after sender.mq_suite.send :ensures, :connection")
38
49
  end
50
+ @logger.debug("#{__FILE__}##{__LINE__} after EM.run")
39
51
  end
52
+ @logger.debug("#{__FILE__}##{__LINE__} after with_tmp_outs")
40
53
  end
41
54
 
42
55
  def spawn_process
43
- @logger.info("spawning process " << [@program, @args].flatten.join(" "))
44
56
  options = {
45
57
  :out => @stdout.path,
46
58
  :err => @stderr.path,
47
59
  :pgroup => true}
48
- pid = Process.spawn(@program, *(@args + [options]))
60
+ args = [@program, *(@args + [options])]
61
+ @logger.info("Process.spawn(*#{args.inspect})")
62
+ pid = Process.spawn(*args)
49
63
  @logger.info("spawned process PID: #{pid}")
50
64
  return pid
65
+ rescue Exception => e
66
+ @logger.error("[#{e.class.name}] #{e.message}\n " << e.backtrace.join("\n "))
67
+ raise
51
68
  end
52
69
 
53
- def detach_and_wait_process(pid)
54
- @logger.info("detaching process PID: #{pid}")
70
+ def start_wait_process(pid)
71
+ @logger.info("#{self.class.name}#start_wait_process(#{pid}) begin")
55
72
  fire_heartbeat pid do
73
+ @logger.info("\e[31mbegin block for fire_heartbeat(#{pid})")
56
74
  timer = nil
75
+ @logger.info("#{__FILE__}##{__LINE__}")
57
76
  int = @config["heartbeat"]["job"]["interval"]
77
+ @logger.info("#{__FILE__}##{__LINE__}")
58
78
  if int and int > 0
79
+ @logger.info("before EM.add_periodic_timer(#{int.inspect})")
59
80
  timer = EM.add_periodic_timer int do
60
81
  fire_heartbeat pid do end # <- rspecを黙らせるための無駄なブロック
61
82
  end
62
83
  end
63
- EM.defer(lambda { Process.waitpid2 pid }, lambda {|a|
64
- @logger.info("process finished: " << a[1].exitstatus.inspect)
65
- EM.cancel_timer timer if timer
66
- fire_finished(*a)
67
- })
84
+
85
+ @logger.info("\e[31mbefore EM.defer ...")
86
+ EM.defer(
87
+ lambda {
88
+ @logger.info("before Process.waitpid2 #{pid} ...")
89
+ res = Process.waitpid2 pid
90
+ @logger.info("$?: " << $?.inspect)
91
+ res
92
+ },
93
+ lambda {|a|
94
+ @logger.info("process finished: " << a[1].exitstatus.inspect)
95
+ EM.cancel_timer timer if timer
96
+ fire_finished(*a)
97
+ }
98
+ )
99
+
100
+ @logger.info("after EM.defer ...")
68
101
  end
102
+ @logger.info("#{self.class.name}#start_wait_process(#{pid}) end")
69
103
  end
70
104
 
71
105
  def fire_finished(pid, process_status)
72
106
  exit_status = process_status.exitstatus # killされた場合にnilの可能性がある
73
107
  level_key = exit_status == 0 ? :info : :error
74
- @logger.info("fire_finished starting #{pid} #{level_key}(#{exit_status})")
108
+ @logger.info("#{self.class.name}#fire_finished starting #{pid} #{level_key}(#{exit_status})")
75
109
  event_properties = {
76
110
  "execution_id" => ENV['MM_SCHEDULE_ID'],
77
111
  "root_jobnet_id" => ENV['MM_ROOT_JOBNET_ID'],
@@ -81,18 +115,21 @@ class TengineJobAgent::Watchdog
81
115
  "exit_status" => exit_status,
82
116
  "command" => [@program, @args].flatten.join(" "),
83
117
  }
118
+
84
119
  user_stdout_path = output_filepath("stdout", pid)
85
120
  user_stderr_path = output_filepath("stderr", pid)
86
- FileUtils.cp(@stdout.path, user_stdout_path)
87
- FileUtils.cp(@stderr.path, user_stderr_path)
88
- event_properties[:stdout_log] = user_stdout_path
89
- event_properties[:stderr_log] = user_stderr_path
121
+
122
+ condition = (level_key == :info) ? lambda{|src| File.size(src) > 0} : nil
123
+ event_properties[:stdout_log] = copy_file(@stdout.path, user_stdout_path, &condition)
124
+ event_properties[:stderr_log] = copy_file(@stderr.path, user_stderr_path, &condition)
125
+
90
126
  if level_key == :error
91
127
  event_properties[:message] =
92
128
  "Job process failed. STDOUT and STDERR were redirected to files.\n" <<
93
129
  "You can see them at '#{user_stdout_path}' and '#{user_stderr_path}'\n" <<
94
130
  "on the server '#{ENV['MM_SERVER_NAME']}'"
95
131
  end
132
+
96
133
  sender.fire("finished.process.job.tengine", {
97
134
  :key => @uuid,
98
135
  :level_key => level_key,
@@ -100,7 +137,7 @@ class TengineJobAgent::Watchdog
100
137
  :sender_name => sender_name,
101
138
  :properties => event_properties,
102
139
  })
103
- @logger.info("fire_finished complete")
140
+ @logger.info("#{self.class.name}#fire_finished complete")
104
141
  sender.stop
105
142
  end
106
143
 
@@ -121,11 +158,19 @@ class TengineJobAgent::Watchdog
121
158
  :keep_connection => true,
122
159
  :retry_count => 0,
123
160
  }, &block)
124
- @logger.debug("fire_heartbeat #{pid}")
161
+ @logger.debug("#{self.class.name}#fire_heartbeat #{pid}")
125
162
  end
126
163
 
127
164
  def sender
128
- @sender ||= Tengine::Event::Sender.new(@config)
165
+ unless @sender
166
+ sender_config = {logger: @logger}.update((@config || {}).deep_symbolize_keys)
167
+ c = sender_config[:sender] ||= {}
168
+ c[:keep_connection] = true
169
+ @logger.info("config for sender: #{sender_config.inspect}")
170
+ @sender = Tengine::Event::Sender.new(sender_config)
171
+ @logger.info("#{self.class.name}@sender.default_keep_connection # => #{@sender.default_keep_connection.inspect}")
172
+ end
173
+ @sender
129
174
  end
130
175
 
131
176
  private
@@ -159,4 +204,13 @@ class TengineJobAgent::Watchdog
159
204
  end
160
205
  end
161
206
 
207
+ def copy_file(src, dest)
208
+ return nil unless File.exist?(src)
209
+ if block_given?
210
+ return nil unless yield(src)
211
+ end
212
+ FileUtils.cp(src, dest)
213
+ dest
214
+ end
215
+
162
216
  end
metadata CHANGED
@@ -1,8 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: tengine_job_agent
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.1.0
5
- prerelease:
4
+ version: 1.2.0
6
5
  platform: ruby
7
6
  authors:
8
7
  - taigou
@@ -13,44 +12,39 @@ authors:
13
12
  autorequire:
14
13
  bindir: bin
15
14
  cert_chain: []
16
- date: 2012-12-19 00:00:00.000000000 Z
15
+ date: 2013-04-30 00:00:00.000000000 Z
17
16
  dependencies:
18
17
  - !ruby/object:Gem::Dependency
19
18
  name: tengine_support
20
19
  requirement: !ruby/object:Gem::Requirement
21
- none: false
22
20
  requirements:
23
21
  - - ~>
24
22
  - !ruby/object:Gem::Version
25
- version: 1.1.0
23
+ version: 1.2.0
26
24
  type: :runtime
27
25
  prerelease: false
28
26
  version_requirements: !ruby/object:Gem::Requirement
29
- none: false
30
27
  requirements:
31
28
  - - ~>
32
29
  - !ruby/object:Gem::Version
33
- version: 1.1.0
30
+ version: 1.2.0
34
31
  - !ruby/object:Gem::Dependency
35
32
  name: tengine_event
36
33
  requirement: !ruby/object:Gem::Requirement
37
- none: false
38
34
  requirements:
39
35
  - - ~>
40
36
  - !ruby/object:Gem::Version
41
- version: 1.1.0
37
+ version: 1.2.0
42
38
  type: :runtime
43
39
  prerelease: false
44
40
  version_requirements: !ruby/object:Gem::Requirement
45
- none: false
46
41
  requirements:
47
42
  - - ~>
48
43
  - !ruby/object:Gem::Version
49
- version: 1.1.0
44
+ version: 1.2.0
50
45
  - !ruby/object:Gem::Dependency
51
46
  name: bundler
52
47
  requirement: !ruby/object:Gem::Requirement
53
- none: false
54
48
  requirements:
55
49
  - - ! '>='
56
50
  - !ruby/object:Gem::Version
@@ -58,7 +52,6 @@ dependencies:
58
52
  type: :development
59
53
  prerelease: false
60
54
  version_requirements: !ruby/object:Gem::Requirement
61
- none: false
62
55
  requirements:
63
56
  - - ! '>='
64
57
  - !ruby/object:Gem::Version
@@ -66,23 +59,20 @@ dependencies:
66
59
  - !ruby/object:Gem::Dependency
67
60
  name: rake
68
61
  requirement: !ruby/object:Gem::Requirement
69
- none: false
70
62
  requirements:
71
- - - ~>
63
+ - - ! '>='
72
64
  - !ruby/object:Gem::Version
73
- version: 0.9.2.2
65
+ version: '0'
74
66
  type: :development
75
67
  prerelease: false
76
68
  version_requirements: !ruby/object:Gem::Requirement
77
- none: false
78
69
  requirements:
79
- - - ~>
70
+ - - ! '>='
80
71
  - !ruby/object:Gem::Version
81
- version: 0.9.2.2
72
+ version: '0'
82
73
  - !ruby/object:Gem::Dependency
83
74
  name: rspec
84
75
  requirement: !ruby/object:Gem::Requirement
85
- none: false
86
76
  requirements:
87
77
  - - ~>
88
78
  - !ruby/object:Gem::Version
@@ -90,7 +80,6 @@ dependencies:
90
80
  type: :development
91
81
  prerelease: false
92
82
  version_requirements: !ruby/object:Gem::Requirement
93
- none: false
94
83
  requirements:
95
84
  - - ~>
96
85
  - !ruby/object:Gem::Version
@@ -98,39 +87,34 @@ dependencies:
98
87
  - !ruby/object:Gem::Dependency
99
88
  name: yard
100
89
  requirement: !ruby/object:Gem::Requirement
101
- none: false
102
90
  requirements:
103
- - - ~>
91
+ - - ! '>='
104
92
  - !ruby/object:Gem::Version
105
- version: 0.8.1
93
+ version: '0'
106
94
  type: :development
107
95
  prerelease: false
108
96
  version_requirements: !ruby/object:Gem::Requirement
109
- none: false
110
97
  requirements:
111
- - - ~>
98
+ - - ! '>='
112
99
  - !ruby/object:Gem::Version
113
- version: 0.8.1
100
+ version: '0'
114
101
  - !ruby/object:Gem::Dependency
115
102
  name: simplecov
116
103
  requirement: !ruby/object:Gem::Requirement
117
- none: false
118
104
  requirements:
119
- - - ~>
105
+ - - ! '>='
120
106
  - !ruby/object:Gem::Version
121
- version: 0.6.4
107
+ version: '0'
122
108
  type: :development
123
109
  prerelease: false
124
110
  version_requirements: !ruby/object:Gem::Requirement
125
- none: false
126
111
  requirements:
127
- - - ~>
112
+ - - ! '>='
128
113
  - !ruby/object:Gem::Version
129
- version: 0.6.4
114
+ version: '0'
130
115
  - !ruby/object:Gem::Dependency
131
116
  name: autotest
132
117
  requirement: !ruby/object:Gem::Requirement
133
- none: false
134
118
  requirements:
135
119
  - - ! '>='
136
120
  - !ruby/object:Gem::Version
@@ -138,15 +122,41 @@ dependencies:
138
122
  type: :development
139
123
  prerelease: false
140
124
  version_requirements: !ruby/object:Gem::Requirement
141
- none: false
142
125
  requirements:
143
126
  - - ! '>='
144
127
  - !ruby/object:Gem::Version
145
128
  version: '0'
146
129
  - !ruby/object:Gem::Dependency
147
- name: rdiscount
130
+ name: pry
131
+ requirement: !ruby/object:Gem::Requirement
132
+ requirements:
133
+ - - ! '>='
134
+ - !ruby/object:Gem::Version
135
+ version: '0'
136
+ type: :development
137
+ prerelease: false
138
+ version_requirements: !ruby/object:Gem::Requirement
139
+ requirements:
140
+ - - ! '>='
141
+ - !ruby/object:Gem::Version
142
+ version: '0'
143
+ - !ruby/object:Gem::Dependency
144
+ name: pry-doc
145
+ requirement: !ruby/object:Gem::Requirement
146
+ requirements:
147
+ - - ! '>='
148
+ - !ruby/object:Gem::Version
149
+ version: '0'
150
+ type: :development
151
+ prerelease: false
152
+ version_requirements: !ruby/object:Gem::Requirement
153
+ requirements:
154
+ - - ! '>='
155
+ - !ruby/object:Gem::Version
156
+ version: '0'
157
+ - !ruby/object:Gem::Dependency
158
+ name: pry-debugger
148
159
  requirement: !ruby/object:Gem::Requirement
149
- none: false
150
160
  requirements:
151
161
  - - ! '>='
152
162
  - !ruby/object:Gem::Version
@@ -154,27 +164,24 @@ dependencies:
154
164
  type: :development
155
165
  prerelease: false
156
166
  version_requirements: !ruby/object:Gem::Requirement
157
- none: false
158
167
  requirements:
159
168
  - - ! '>='
160
169
  - !ruby/object:Gem::Version
161
170
  version: '0'
162
171
  - !ruby/object:Gem::Dependency
163
- name: ci_reporter
172
+ name: ZenTest
164
173
  requirement: !ruby/object:Gem::Requirement
165
- none: false
166
174
  requirements:
167
175
  - - ~>
168
176
  - !ruby/object:Gem::Version
169
- version: 1.6.5
177
+ version: 4.9.0
170
178
  type: :development
171
179
  prerelease: false
172
180
  version_requirements: !ruby/object:Gem::Requirement
173
- none: false
174
181
  requirements:
175
182
  - - ~>
176
183
  - !ruby/object:Gem::Version
177
- version: 1.6.5
184
+ version: 4.9.0
178
185
  description: tengine_job_agent works with tengine_job
179
186
  email: tengine-info@groovenauts.jp
180
187
  executables:
@@ -198,30 +205,26 @@ files:
198
205
  homepage: http://github.com/tengine/tengine_job_agent
199
206
  licenses:
200
207
  - MPL2.0/LGPLv3
208
+ metadata: {}
201
209
  post_install_message:
202
210
  rdoc_options: []
203
211
  require_paths:
204
212
  - lib
205
213
  required_ruby_version: !ruby/object:Gem::Requirement
206
- none: false
207
214
  requirements:
208
215
  - - ! '>='
209
216
  - !ruby/object:Gem::Version
210
217
  version: '0'
211
- segments:
212
- - 0
213
- hash: -739102963510828694
214
218
  required_rubygems_version: !ruby/object:Gem::Requirement
215
- none: false
216
219
  requirements:
217
220
  - - ! '>='
218
221
  - !ruby/object:Gem::Version
219
222
  version: '0'
220
223
  requirements: []
221
224
  rubyforge_project:
222
- rubygems_version: 1.8.23
225
+ rubygems_version: 2.0.3
223
226
  signing_key:
224
- specification_version: 3
227
+ specification_version: 4
225
228
  summary: tengine_job_agent invoke job, watches it and notify its finish to tengine
226
229
  server
227
230
  test_files: []