Skip to content

Commit

Permalink
Merge pull request #75 from rightscale/OPS-2810_officialize_chimp_imp…
Browse files Browse the repository at this point in the history
…rovements

Ops 2810 officialize chimp improvements
  • Loading branch information
Marc committed May 24, 2016
2 parents 216b8d3 + fb3fc71 commit fd1fa83
Show file tree
Hide file tree
Showing 9 changed files with 94 additions and 61 deletions.
4 changes: 4 additions & 0 deletions CHANGES
Original file line number Diff line number Diff line change
Expand Up @@ -156,3 +156,7 @@ Version 2.1.13
* Feature: Changed error reporting format
* Feature: Web UI now shows job_uuid
* Feature: One can now associate a "note" to a job by using --job-notes="foo"

Version 2.1.15
---------------
* Feature: We now are able to query a subset of job_uuids and total stats format.
4 changes: 2 additions & 2 deletions Gemfile.lock
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
PATH
remote: .
specs:
right_chimp (2.1.12)
right_chimp (2.1.15)
highline (~> 1.7.2)
nokogiri (~> 1.6.7.1)
progressbar (~> 0.11.0)
Expand All @@ -16,7 +16,7 @@ GEM
coderay (1.1.0)
debug_inspector (0.0.2)
diff-lcs (1.1.3)
domain_name (0.5.20160128)
domain_name (0.5.20160310)
unf (>= 0.0.5, < 1.0.0)
highline (1.7.8)
http-cookie (1.0.2)
Expand Down
77 changes: 47 additions & 30 deletions lib/right_chimp/daemon/ChimpDaemon.rb
Original file line number Diff line number Diff line change
Expand Up @@ -392,6 +392,7 @@ class JobServlet < GenericServlet

def do_POST(req, resp)
id = -1
# we don't know the job_id because we cant guess how many tasks one call creates.
job_id = self.get_id(req)
job_uuid= self.get_job_uuid(req)
verb = self.get_verb(req)
Expand All @@ -405,12 +406,6 @@ def do_POST(req, resp)
#
# Ask chimpd to process a Chimp object directly
#
#if verb == 'process' or verb == 'add'
# payload.interactive = false
# tasks = payload.process
# tasks.each do |task|
# q.push(group, task)
# end
if verb == 'process' or verb == 'add'
ChimpDaemon.instance.chimp_queue.push payload
ChimpDaemon.instance.semaphore.synchronize do
Expand All @@ -423,10 +418,9 @@ def do_POST(req, resp)
q.get_job(job_id).status = payload.status
end


resp.body = {
'job_uuid' => job_uuid ,
'id' => id
'id' => job_id
}.to_yaml

raise WEBrick::HTTPStatus::OK
Expand Down Expand Up @@ -582,9 +576,10 @@ def do_GET(req, resp)
job_types.each do |type|
jobs[type] = queue.get_jobs_by_status(type).map do |job|
{ :id => job.job_id,
:server => job.server.params["name"],
:name => job.exec.params["right_script"]["name"],
:error_message => job.error.nil? ? "" : job.error.message
:uuid => job.job_uuid,
:server => job.server.name,
:script => job.info,
:audit_entry_url => job.audit_entry_url
}
end
end
Expand All @@ -594,35 +589,58 @@ def do_GET(req, resp)
raise WEBrick::HTTPStatus::OK
end

if req.request_uri.path =~ /jobs\.json\/id\/\d+$/

job_id = File.basename(req.request_uri.path)
queue = ChimpQueue.instance

res = queue.get_job(job_id)

case res
when ExecRightScript

result = {}
result[:id] = job_id
result[:uuid] = res.job_uuid
result[:status] = res.status
result[:server] = res.server.name
result[:script] = res.info
result[:audit_entry_url] = res.audit_entry_url

resp.body = result.to_json
end

raise WEBrick::HTTPStatus::OK

end
#
# Attempt to return just 1 job data
# Attempt to return just 1 job_UUID data
#
if req.request_uri.path =~ /jobs\.json\/id\/*\w{6}$/
if req.request_uri.path =~ /jobs\.json\/uuid\/*\w{6}$/

job_uid = File.basename(req.request_uri.path)
#instance the queue
uuid = File.basename(req.request_uri.path)
# instance the queue
queue = ChimpQueue.instance

my_hash = {}
res = queue.get_jobs_by_uuid(uuid)

jobs = {}

#! Multiple servers WILL match for the same job_uuid
queue.group.each { |group|
#per each group, locate all jobs
group[1].get_jobs.each {|job|
my_hash[job.job_uuid] = { job.job_id => { "state" => job.results,
"server" => job.server.params["name"],
"audit_entry" => job.audit_entry_data,
}
}
}
}
res.each_with_index do |r, i|
jobs[i] = { id: r.job_id,
uuid: r.job_uuid,
status: r.status,
server: r.server.name,
script: r.info,
audit_entry_url: r.audit_entry_url
}
end

resp.body = my_hash[job_uid].to_json
resp.body = jobs.to_json

raise WEBrick::HTTPStatus::OK
end


#
# Check for static CSS files and serve them
#
Expand Down Expand Up @@ -663,6 +681,5 @@ def do_GET(req, resp)
end
end
end # DisplayServlet

end # ChimpDaemon
end
1 change: 1 addition & 0 deletions lib/right_chimp/daemon/ChimpDaemonClient.rb
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ def self.submit(host, port, chimp_object, job_uuid)

if response.code > 199 and response.code < 300
Log.debug "Response code was #{response.code}"

id = YAML::load(response.body)['id']
#ID changes upon execution, not upon submission.
job_uuid = YAML::load(response.body)['job_uuid']
Expand Down
15 changes: 8 additions & 7 deletions lib/right_chimp/exec/ExecRightScript.rb
Original file line number Diff line number Diff line change
Expand Up @@ -4,35 +4,36 @@
module Chimp
class ExecRightScript < Executor

attr_accessor :audit_entry_data
attr_accessor :audit_entry_data, :audit_entry_url

def run
options = {:ignore_lock => true}.merge(@inputs)
options = { ignore_lock: true }.merge(@inputs)

if @timeout < 300
Log.error "timeout was less than 5 minutes! resetting to 5 minutes"
Log.error 'timeout was less than 5 minutes! resetting to 5 minutes'
@timeout = 300
end

run_with_retry do
task=Task.new
task.tasker = @server.run_executable(@exec, options)
task.wait_for_state("completed", @timeout)
@audit_entry_url = task.friendly_url
task.wait_for_state('completed', @timeout)
@results = task.state
@audit_entry_data = task.details
end
end

def describe_work
return "[#{@job_uuid}] ExecRightScript job_id=#{@job_id} script=\"#{@exec.params['right_script']['name']}\" server=\"#{@server.nickname}\""
"[#{@job_uuid}] ExecRightScript job_id=#{@job_id} script=\"#{@exec.params['right_script']['name']}\" server=\"#{@server.nickname}\""
end

def info
return @exec.params['right_script']['name']
@exec.params['right_script']['name']
end

def target
return @server.nickname
@server.nickname
end

end
Expand Down
23 changes: 8 additions & 15 deletions lib/right_chimp/exec/Executor.rb
Original file line number Diff line number Diff line change
Expand Up @@ -127,7 +127,7 @@ def run_with_retry(&block)
@status = STATUS_DONE
@group.job_completed
else
Log.warn "[#{@job_uuid}] Ownership of job_id #{job_id} lost. User cancelled operation?"
Log.warn "[#{@job_uuid}][#{@job_id}] Ownership of job_id #{job_id} lost. User cancelled operation?"
end

rescue SystemExit, Interrupt => ex
Expand All @@ -141,34 +141,27 @@ def run_with_retry(&block)

if @retry_count > 0
@status = STATUS_RETRYING
Log.error "[#{@job_uuid}] Error executing on \"#{name}\". Retrying in #{@retry_sleep} seconds..."
Log.error "[#{@job_uuid}][#{@job_id}] Error executing on \"#{name}\". Retrying in #{@retry_sleep} seconds..."
@retry_count -= 1
sleep @retry_sleep
retry
end

@status = STATUS_ERROR
@error = ex
Log.error "[#{@job_uuid}] Error executing on \"#{name}\": #{ex}"
Log.error "[#{@job_uuid}][#{@job_id}] Error executing on \"#{name}\": #{ex}"

ensure
@time_end = Time.now
Log.info self.describe_work_done unless @quiet
end

rescue RuntimeError => ex
if @server.params["ip_address"]
err = ex.message + "IP: #{@server.params["ip_address"]}\n"
end
if @group.group_id
err += " Group: #{@group.group_id}\n"
end
if @job_notes
err += " Notes: #{@job_notes}\n"
end
Log.error "[#{@job_uuid}] Caught RuntimeError: #{err} Aborting job.\n"
#Log.error ex.inspect
#Log.error ex.backtrace
err = ex.message + "IP: #{@server.params["ip_address"]}\n" if @server.params['ip_address']
err += " Group: #{@group.group_id}\n" if @group.group_id
err += " Notes: #{@job_notes}\n" if @job_notes
err += " Notes: #{@job_notes}\n" if @job_notes
Log.error "[#{@job_uuid}][#{@job_id}] Caught RuntimeError: #{err} Job failed.\n"
@status = STATUS_ERROR
@error = ex
end
Expand Down
14 changes: 12 additions & 2 deletions lib/right_chimp/queue/ChimpQueue.rb
Original file line number Diff line number Diff line change
Expand Up @@ -162,7 +162,7 @@ def get_job(id)
jobs = self.get_jobs

jobs.each do |j|
return j if j.job_id == id
return j if j.job_id == id.to_i
end
end

Expand All @@ -172,9 +172,19 @@ def get_jobs
group.get_jobs.each { |job| r << job }
end

return r
r
end

def get_jobs_by_uuid(uuid)
r = []
jobs = self.get_jobs

jobs.each do |j|
r << j if j.job_uuid == uuid
end

r
end
#############################################################
protected

Expand Down
15 changes: 11 additions & 4 deletions lib/right_chimp/resources/Task.rb
Original file line number Diff line number Diff line change
Expand Up @@ -14,18 +14,18 @@ def wait_for_state(desired_state, timeout=900)
while(timeout > 0)
state=self.tasker.show.summary
return true if self.state.match(desired_state)
friendly_url = Connection.audit_url+"/audit_entries/"
friendly_url = Connection.audit_url + '/audit_entries/'
friendly_url += self.href.split(/\//).last
friendly_url = friendly_url.gsub("ae-","")
raise "FATAL error, #{self.tasker.show.summary}\n\n Audit: #{friendly_url}'\n " if self.state.match("failed")
friendly_url = friendly_url.gsub('ae-', '')
raise "FATAL error, #{tasker.show.summary}\n\n Audit: #{friendly_url}'\n " if self.state.match("failed")
sleep 30
timeout -= 30
end
raise "FATAL: Timeout waiting for Executable to complete. State was #{self.state}" if timeout <= 0
end

def wait_for_completed(timeout=900)
wait_for_state("completed", timeout)
wait_for_state('completed', timeout)
end

def state
Expand All @@ -36,6 +36,13 @@ def href
self.tasker.href
end

def friendly_url
friendly_url = Connection.audit_url+"/audit_entries/"
friendly_url += self.href.split(/\//).last
friendly_url = friendly_url.gsub("ae-","")
friendly_url
end

def details
self.tasker.show(:view => "extended").detail
end
Expand Down
2 changes: 1 addition & 1 deletion lib/right_chimp/version.rb
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
module Chimp
VERSION = "2.1.14"
VERSION = "2.1.15"
end

0 comments on commit fd1fa83

Please sign in to comment.