lib/taskr/actions.rb in taskr-0.2.1 vs lib/taskr/actions.rb in taskr-0.3.0
- old
+ new
@@ -11,11 +11,11 @@
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with Taskr. If not, see <http://www.gnu.org/licenses/>.
-require 'openwfe/util/scheduler'
+require 'rufus/scheduler'
#require 'active_resource'
require 'restr'
@@ -37,17 +37,18 @@
end
# The base class for all Actions.
# Extend this to define your own custom Action.
class Base
- include OpenWFE::Schedulable
+ include Rufus::Schedulable
class_inheritable_accessor :parameters
class_inheritable_accessor :description
attr_accessor :parameters
attr_accessor :task
+ attr_accessor :task_action
def initialize(parameters)
self.parameters = HashWithIndifferentAccess.new(parameters)
end
@@ -70,44 +71,65 @@
task.update_attribute(:last_triggered, Time.now)
task.update_attribute(:last_triggered_error, {:type => e.class.to_s, :message => details})
raise e
end
end
+
+ def to_s
+ "#{self.class.name}(#{parameters.inspect})"
+ end
end
# Do not extend this class. It is used internally to schedule multiple
# actions per task.
#
# If you want to define your own custom Action, extend Taskr::Actions::Base
class Multi
- include OpenWFE::Schedulable
+ include Rufus::Schedulable
attr_accessor :actions
attr_accessor :task
def initialize
self.actions = []
end
def trigger(trigger_args = {})
begin
- $LOG.info("Executing task #{self.name}")
+ $LOG.info("Executing task #{self.task.name}")
actions.each do |a|
a.execute
+ LogEntry.info(a, "Action #{a} executed.")
end
# TODO: maybe we should store last_triggered time on a per-action basis?
task.update_attribute(:last_triggered, Time.now)
+ task.update_attribute(:last_triggered_error, nil)
rescue => e
$LOG.error(e)
- $LOG.debug("#{e.stacktrace}")
+ $LOG.debug("#{e.backtrace}")
task.update_attribute(:last_triggered, Time.now)
- task.update_attribute(:last_triggered_error, e)
+ task.update_attribute(:last_triggered_error, {:type => e.class.to_s, :details => "#{e.message}"})
+ # FIXME: Maybe actions should be responseible for logging their errors, otherwise we double-log the same error.
+ LogEntry.error(task, "Task #{task} raised an exception: \n#{e.class}: #{e.message}\n#{e.backtrace}")
raise e
end
end
end
+ class RotateTaskLog < Base
+ self.parameters = ['delete_old_log_entries_after_days']
+ self.description = "Deletes old task log entries from this Taskr server's database."
+
+ def execute
+ num = parameters['delete_old_log_entries_after_days'].to_i
+
+ cond = ['timestamp < ?', Time.now - num.days]
+ LogEntry.delete_all(cond)
+ LogEntry.debug(task_action, "Deleted log entries with conditions: #{cond.inspect}")
+ end
+ end
+
class Shell < Base
self.parameters = ['command', 'as_user']
self.description = "Execute a shell command (be careful!)"
def execute
@@ -116,32 +138,62 @@
cmd = parameters['command']
else
user = nil
end
- if user
- `sudo -u #{user} #{cmd}`
- else
- `#{cmd}`
+ unless user.blank?
+ cmd = "sudo -u #{user} #{cmd}"
end
+ outio = StringIO.new
+ errio = StringIO.new
+ old_stdout, $stdout = $stdout, outio
+ old_stderr, $stderr = $stderr, errio
+
+ out = `#{cmd}`
+
+ err = errio.string
+ out = outio.string
+ LogEntry.debug(task_action, out) unless out.blank?
+ LogEntry.error(task_action, err) unless err.blank?
+
+ $stdout = old_stdout
+ $stderr = old_stderr
+
unless $?.success?
- raise "Shell command failed (#{$?}): #{cmd}"
+ msg = "Shell command #{cmd.inspect} failed (returned code #{$?}): #{out}"
+ LogEntry.error(task_action, msg)
+ raise msg
end
end
end
class Ruby < Base
self.parameters = ['code']
self.description = "Execute some Ruby code."
def execute
+ outio = StringIO.new
+ errio = StringIO.new
+ old_stdout, $stdout = $stdout, outio
+ old_stderr, $stderr = $stderr, errio
+
code = parameters['code']
- eval code
+ eval(code)
+
+ err = errio.string
+ out = outio.string
+ LogEntry.debug(task_action, out) unless out.blank?
+ LogEntry.error(task_action, err) unless err.blank?
+
+ $stdout = old_stdout
+ $stderr = old_stderr
end
end
-
+
+
+# This is too complicated... we use Restr instead.
# class ActiveResource < Base
# self.parameters = ['site', 'resource', 'action', 'parameters']
# self.description = "Perform a REST call on a remote service using ActiveResource."
#
# def execute
@@ -205,12 +257,21 @@
auth = {}
auth['username'] = parameters['username'] if parameters['username']
auth['password'] = parameters['password'] if parameters['password']
end
- Restr.logger = $LOG
- Restr.do(parameters['method'], parameters['url'], parameters['params'], auth)
+ if parameters['params'].kind_of? String
+ params2 = {}
+ parameters['params'].split('&').collect do |p|
+ key, value = p.split('=')
+ params2[key] = value
+ end
+ parameters['params'] = params2
+ end
+
+ Restr.logger = LogEntry.logger_for_action(task_action)
+ Restr.do(parameters['method'], parameters['url'], (parameters['params'] unless parameters['params'].blank?), auth)
end
end
class Howlr < Rest
self.parameters = ['url', 'from', 'recipients', 'subject', 'body', 'username', 'password', 'content_type']
@@ -244,10 +305,10 @@
:ruby_code => parameters['ruby_code']#,
#:shell_command => parameters['shell_command']
}
- Restr.logger = $LOG
+ Restr.logger = LogEntry.logger_for_action(task_action)
Restr.post(parameters['url'], data)
end
end
end
end
\ No newline at end of file