rearview 1.0.1-jruby → 1.0.2-jruby

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 11f5ed24ea14952ae2f7770322e560c13cfde25e
4
- data.tar.gz: 9519f92f824f2f694605123f3157551db1c659fa
3
+ metadata.gz: 95095d4555cc101716b526ac7d6dc06355c74927
4
+ data.tar.gz: 19b0ead30fe6a686d67f549ddc7d4df99362fa46
5
5
  SHA512:
6
- metadata.gz: 5d17a034492548ae74b58afed3311a1796a6acf7fe0ad7c806ad679ec62a6171ec15c778204761b47bcff57fca562e467127de1592cc71dbd8b699b567edde4c
7
- data.tar.gz: 370232272bd01bdf532e0944b0c7398b6b1d960813e774e946bc5c6e1959c2ef3e79a385a01ddc454b8e7ac34f806c6af62a0efcb0cc05f49cafd896ed84e7e3
6
+ metadata.gz: 86103666d5221fb16a6e53ed8eb5631b01e6392fbfb0895dcfa93779c87ed772dde28be52985abd66ee8f1c28fb95c1e3468b8114fddf4661e2f7de023264ceb
7
+ data.tar.gz: 2029ce7baa091af50b4b160a82025df65ac5eb591bccd5755b20e39f93a90043f4aed355ee48a91ce98c4e524cb3d4449649217afd4b8d142eb113125774bcbb
data/README.md CHANGED
@@ -1 +1,65 @@
1
- Rails engine for ![rearview](http://github.com/livingsocial/rearview). This project is for rearview developers only. For users please go to ![rearview](http://github.com/livingsocial/rearview) project for installation, configuration, and other details.
1
+ Rails engine for [rearview](http://github.com/livingsocial/rearview). This project is for rearview developers only. For users please go to the [rearview](http://github.com/livingsocial/rearview) project for installation, configuration, and other details.
2
+
3
+ # Development Guide
4
+
5
+ Before developing please read how to [contribute](https://github.com/livingsocial/rearview-engine/blob/master/CONTRIBUTING.md).
6
+
7
+ ## Intro
8
+
9
+ Before contributing you should read [Getting Started with Engines](http://guides.rubyonrails.org/engines.html) guide to familiarize yourself with rails engines.
10
+
11
+ Rearview consists of two components:
12
+
13
+ (1) Rearview engine (this repo)
14
+
15
+ The vast majority of any code customizations and bug fixes should be made here.
16
+
17
+ (2) Rearview engine host (https://github.com/livingsocial/rearview)
18
+
19
+ This is mostly a convienience for users so they can quickly get rearview up and running. This also allows users to customize views and other components at well defined extension points without them having to submit them back into the code base.
20
+
21
+ **Note: the rearview engine is not completely isolated (yet) so it cannot be safely multi-tennated with other engines in the same host**
22
+
23
+ ## Getting started
24
+
25
+ #### clone the rearview engine
26
+
27
+ git clone git@github.com:livingsocial/rearview-engine.git
28
+
29
+ #### clone the rearview engine host
30
+
31
+ git clone git@github.com:livingsocial/rearview.git
32
+
33
+ #### edit the engine host Gemfile to point to your local engine clone
34
+
35
+ Change the line simliar to this
36
+
37
+ gem 'rearview', '~> 1.0.0'
38
+
39
+ To point to the path you cloned the engine too, for example
40
+
41
+ gem 'rearview', :path => '~/clone/path/rearview-engine'
42
+
43
+ #### sync the engine host database
44
+
45
+ rake rearview:install:migrations
46
+ rake db:setup
47
+
48
+ #### start the engine host server
49
+
50
+ bin/rails server
51
+
52
+ ## User Interface Guide
53
+
54
+ Rearview does not use the asset pipeline. Instead you'll need to take a look at [public/rearview-src](https://github.com/livingsocial/rearview-engine/tree/master/public/rearview-src). In development mode javascript, css, etc is loaded directly from here. When rearview-engine is bundled as a Gem the various elements are pre-compiled (manually before **gem build**) using require and are loaded from [public/rearview](https://github.com/livingsocial/rearview-engine/tree/master/public/rearview).
55
+
56
+ To compile the ui before distribution, run the following rake task from inside rearview-engine:
57
+
58
+ rake rearview:ui:build
59
+
60
+
61
+
62
+
63
+
64
+
65
+
@@ -37,7 +37,7 @@ module Rearview
37
37
  end
38
38
 
39
39
  def data
40
- @job_data = Rearview::Job.find(params[:id]).try(:job_data)
40
+ @job_data = Rearview::JobData.find_by(job_id:params[:id])
41
41
  unless @job_data.present?
42
42
  head :status => 404
43
43
  end
@@ -0,0 +1,19 @@
1
+ <form class="form-horizontal" method="post" action="<%= session_path(:user) %>">
2
+ <div class="control-group">
3
+ <label class="control-label" for="inputEmail">Email</label>
4
+ <div class="controls">
5
+ <input type="text" id="inputEmail" placeholder="Email" name="user[email]" autofocus="autofocus">
6
+ </div>
7
+ </div>
8
+ <div class="control-group">
9
+ <label class="control-label" for="inputPassword">Password</label>
10
+ <div class="controls">
11
+ <input type="password" id="inputPassword" placeholder="Password" name="user[password]">
12
+ </div>
13
+ </div>
14
+ <div class="control-group">
15
+ <div class="controls">
16
+ <button type="submit" class="btn">Sign in</button>
17
+ </div>
18
+ </div>
19
+ </form>
@@ -0,0 +1,3 @@
1
+ <div class="text-center">
2
+ <%= link_to "Sign in with Google", user_omniauth_authorize_path(:google_oauth2), :class => "btn btn-primary" %>
3
+ </div>
@@ -1,21 +1,10 @@
1
- <form class="form-horizontal" method="post" action="<%= session_path(:user) %>">
2
- <div class="control-group">
3
- <label class="control-label" for="inputEmail">Email</label>
4
- <div class="controls">
5
- <input type="text" id="inputEmail" placeholder="Email" name="user[email]" autofocus="autofocus">
6
- </div>
7
- </div>
8
- <div class="control-group">
9
- <label class="control-label" for="inputPassword">Password</label>
10
- <div class="controls">
11
- <input type="password" id="inputPassword" placeholder="Password" name="user[password]">
12
- </div>
13
- </div>
14
- <div class="control-group">
15
- <div class="controls">
16
- <button type="submit" class="btn">Sign in</button>
17
- </div>
18
- </div>
19
- </form>
20
-
1
+ <% case Rearview.config.authentication[:strategy] %>
2
+ <% when :database %>
3
+ <%= render "database_auth" %>
4
+ <% when :google_oauth2 %>
5
+ <%= render "google_oauth2_auth" %>
6
+ <% else %>
7
+ <h2>Rearview configuration for authentication strategy &quot;<%= Rearview.config.authentication[:strategy] %>&quot;
8
+ requires configuring devise, customizing Rearview::User, and overriding views as appropriate</h2>
9
+ <% end %>
21
10
  <%# <%= render "devise/shared/links" %>
@@ -4,4 +4,4 @@ Monitor: <%= @job.name %>
4
4
  Description: <%= @job.description.nil? ? "None" : @job.description %>
5
5
 
6
6
  Alerted On: <%= @job.last_run %>
7
- Direct Link: <%= Rearview::UriHelper.rearview_uri(@job) %>
7
+ Direct Link: <%= Rearview::UrlHelper.job_url(@job) %>
@@ -0,0 +1,7 @@
1
+ class AddIndexes < ActiveRecord::Migration
2
+ def change
3
+ add_index :jobs, :status
4
+ add_index :job_errors, :status
5
+ add_index :job_data, :job_id
6
+ end
7
+ end
@@ -5,6 +5,20 @@ Rearview.configure do |config|
5
5
  config.logger = Rails.logger
6
6
  config.sandbox_dir = Rails.root + "sandbox"
7
7
 
8
+ # Authentication support
9
+ # Support for authentication in rearview is via devise, so while any devise supported
10
+ # strategies will work, pre-wired support for the following strategies is included:
11
+ #
12
+ # :database - authenticate against the database
13
+ # :google_oauth2 - authenticate using google oauth2
14
+ # :custom - if you want to configure devise and Rearview::User model to use a different strategy
15
+ #
16
+ # For :google_oauth2 you need to include an option for matching email addresses/domains
17
+ # ex:
18
+ # config.authentication = { strategy: :google_oauth2, matching_emails: /@mycompany\.com$/ }
19
+ #
20
+ config.authentication = { strategy: :database }
21
+
8
22
  # Configure the path to a ruby 1.9.3 binary that will be used to execute your
9
23
  # monitor script in the sandbox.
10
24
  # ex:
@@ -25,11 +39,18 @@ Rearview.configure do |config|
25
39
  # config.default_from = "rearview@mycompany.com"
26
40
  config.default_from = "rearview@localhost"
27
41
 
42
+ # The url options for rearview application host. Required to generate
43
+ # proper monitor alerts.
44
+ # ex:
45
+ # config.default_url_options = {:host=>'rearview.mycomopany.com', :protocol=>'https'}
46
+ config.default_url_options = {:host=>'localhost', :port=>'3000'}
47
+
28
48
  case Rails.env
29
49
  when "test"
30
50
  config.preload_jobs = false
31
51
  when "production"
32
- # If you want to make sure your configuration is correct on server startup
52
+ # If you want to make sure your configuration is correct on server startup. This
53
+ # will make http requests that will slow down startup.
33
54
  # config.verify = true
34
55
  end
35
56
 
data/lib/rearview.rb CHANGED
@@ -7,7 +7,7 @@ require 'rearview/cron_helper'
7
7
  require 'rearview/graphite_parser'
8
8
  require 'rearview/results_handler'
9
9
  require 'rearview/alerts_handler'
10
- require 'rearview/uri_helper'
10
+ require 'rearview/url_helper'
11
11
  require 'rearview/alerts'
12
12
  require 'rearview/monitor_runner'
13
13
  require 'rearview/monitor_task'
@@ -15,7 +15,6 @@ require 'rearview/distribute'
15
15
  require 'rearview/monitor_supervisor'
16
16
  require 'rearview/monitor_service'
17
17
  require 'rearview/configuration'
18
- require 'rearview/sandbox'
19
18
  require 'rearview/version'
20
19
 
21
20
  module Rearview
@@ -50,13 +49,10 @@ module Rearview
50
49
  def boot!
51
50
  @logger = config.logger if(config.logger.present?)
52
51
  logger.info "[#{self}] booting..."
53
- logger.info "[#{self}] using configuration: \n#{config}"
52
+ logger.info "[#{self}] using configuration: \n#{config.dump}"
54
53
  if config.verify?
55
- logger.info "[#{self}] verifying sandbox..."
56
- if Rearview::Sandbox.valid?
57
- logger.info "[#{self}] sandbox verified"
58
- else
59
- logger.error "[#{self}] sandbox verification FAILED"
54
+ unless config.valid?
55
+ logger.warn "[#{self}] configuration check FAILED: \n#{config.errors.full_messages.join("\n")}"
60
56
  end
61
57
  end
62
58
  Celluloid.logger = @logger
@@ -19,7 +19,7 @@ module Rearview
19
19
 
20
20
  def alert_msg(job, result)
21
21
  msg = result[:message] ? result[:message] : "Job did not provide an error description"
22
- "#{msg} #{Rearview::UriHelper.rearview_uri(job)}"
22
+ "#{msg} #{Rearview::UrlHelper.job_url(job)}"
23
23
  end
24
24
 
25
25
  def self.params(key)
@@ -10,7 +10,7 @@ module Rearview
10
10
  if PagerDutyAlert.key?(params)
11
11
  logger.info "#{self} send alert for #{job.inspect} and key #{key} with params #{params}"
12
12
  pagerduty_uri = Rearview.config.pagerduty_url
13
- job_uri = Rearview::UriHelper.rearview_uri(job)
13
+ job_uri = Rearview::UrlHelper.job_url(job)
14
14
  msg = result[:message]
15
15
 
16
16
  description = if msg
@@ -11,5 +11,11 @@ module Rearview::Concerns::Models::User
11
11
  validates_uniqueness_of :email
12
12
  validates_presence_of :email
13
13
 
14
+ def self.valid_google_oauth2_email?(email)
15
+ email.present? &&
16
+ Rearview.config.authentication[:matching_emails].present? &&
17
+ !email.match(Rearview.config.authentication[:matching_emails]).nil?
18
+ end
19
+
14
20
  end
15
21
  end
@@ -1,23 +1,76 @@
1
1
  require 'optparse'
2
+ require 'pry'
2
3
 
3
4
  module Rearview
4
- class Configuration < Struct.new(:default_from, :graphite_url, :pagerduty_url, :sandbox_exec,
5
- :sandbox_timeout, :sandbox_dir, :enable_alerts, :preload_jobs, :logger, :enable_monitor, :verify)
6
-
7
- DEFAULTS = {
8
- default_from: "rearview@localhost",
9
- graphite_url: nil,
10
- pagerduty_url: "https://events.pagerduty.com/generic/2010-04-15/create_event.json",
11
- sandbox_timeout: 5,
12
- enable_alerts: true,
13
- preload_jobs: true,
14
- verify: false,
15
- enable_monitor: true
16
- }
17
-
18
- def initialize
5
+ class Configuration
6
+
7
+ include ActiveModel::Model
8
+
9
+ class UrlValidator < ActiveModel::EachValidator
10
+ def validate_each(record, attribute, value)
11
+ if value.present?
12
+ uri = URI.parse(value) rescue nil
13
+ unless uri.present? && uri.scheme.present? && (uri.scheme.downcase=="http" || uri.scheme.downcase=="https")
14
+ record.errors.add attribute, (options[:message] || "is not a valid URL")
15
+ else
16
+ if options[:reachable]
17
+ reachable = ReachableValidator.new(options.dup.merge(attributes: @attributes))
18
+ reachable.validate_each(record,attribute,value)
19
+ end
20
+ end
21
+ end
22
+ end
23
+ end
24
+
25
+ class ReachableValidator < ActiveModel::EachValidator
26
+ def validate_each(record, attribute, value)
27
+ if value.present?
28
+ response = HTTParty.get(value) rescue nil
29
+ unless response.present? && response.code == 200
30
+ record.errors.add attribute, (options[:message] || "is not a reachable URL")
31
+ end
32
+ end
33
+ end
34
+ end
35
+
36
+ class DirectoryValidator < ActiveModel::EachValidator
37
+ def validate_each(record, attribute, value)
38
+ if value.present?
39
+ unless File.directory?(value)
40
+ record.errors.add attribute, (options[:message] || "is not a directory")
41
+ end
42
+ end
43
+ end
44
+ end
45
+
46
+ ATTRIBUTES = [:default_from, :graphite_url, :pagerduty_url, :sandbox_exec,
47
+ :sandbox_timeout, :sandbox_dir, :enable_alerts, :preload_jobs,
48
+ :logger, :enable_monitor, :verify, :default_url_options,
49
+ :authentication]
50
+
51
+ attr_accessor *ATTRIBUTES
52
+
53
+ validates :graphite_url, presence: true, url: { reachable: true }
54
+ validates :pagerduty_url, presence: true, url: true
55
+ validates :default_from, presence: true
56
+ validates :default_url_options, presence: true
57
+ validates :sandbox_dir, presence: true, directory: true
58
+ validates :sandbox_exec, presence: true
59
+ validates :sandbox_timeout, presence: true, numericality: { greater_than: 4 }
60
+ validates :authentication, presence: true
61
+
62
+ validate :validate_sandbox_execution
63
+
64
+ def initialize(attributes={})
65
+ @default_from = "rearview@localhost"
66
+ @sandbox_timeout = 5
67
+ @enable_alerts = true
68
+ @preload_jobs = true
69
+ @verify = false
70
+ @enable_monitor = true
71
+ @authentication = { strategy: :database }
72
+ @pagerduty_url = "https://events.pagerduty.com/generic/2010-04-15/create_event.json"
19
73
  super
20
- set_defaults
21
74
  end
22
75
 
23
76
  def alerts_enabled?
@@ -45,15 +98,23 @@ module Rearview
45
98
  end.parse!(argv)
46
99
  end
47
100
 
48
- def set_defaults
49
- members.each { |member| send("#{member}=", DEFAULTS[member.to_sym]) }
101
+ def validate_sandbox_execution
102
+ script_file = File.join(sandbox_dir,"verify_sandbox.rb")
103
+ cmd = sandbox_exec.clone << script_file
104
+ process_builder = ProcessBuilder.new(cmd).redirectErrorStream(true)
105
+ process_builder.directory(java.io.File.new(sandbox_dir.to_s))
106
+ process_builder.environment.delete("GEM_HOME")
107
+ process_builder.environment.delete("GEM_PATH")
108
+ process = process_builder.start
109
+ exit_code = process.waitFor
110
+ output = process.get_input_stream.to_io.read
111
+ exit_code == 0
50
112
  end
51
113
 
52
- def to_s
53
- @elems = []
54
- members.each { |m| @elems << "Rearview::Configuration #{m} : #{self[m]}" }
55
- @elems.join("\n")
114
+ def dump
115
+ ATTRIBUTES.sort.map { |attrib| "#{attrib.to_s}=#{(self.send(attrib).nil? ? "nil" : self.send(attrib))}" }.join("\n")
56
116
  end
57
117
 
58
118
  end
59
119
  end
120
+
@@ -27,9 +27,9 @@ module Rearview
27
27
  end
28
28
  def run
29
29
  debug "#{self} run"
30
+ @initial_delay = 0
31
+ result = Rearview::MonitorRunner.run(@job.metrics, @job.monitor_expr, @job.minutes)
30
32
  ActiveRecord::Base.connection_pool.with_connection do
31
- @initial_delay = 0
32
- result = Rearview::MonitorRunner.run(@job.metrics, @job.monitor_expr, @job.minutes)
33
33
  @job.last_run = Time.now.utc
34
34
  Rearview::ResultsHandler.new(@job,result).run
35
35
  end
@@ -0,0 +1,7 @@
1
+ module Rearview
2
+ class UrlHelper
3
+ def self.job_url(job)
4
+ Rails.application.routes.url_helpers.rearview_url(Rearview.config.default_url_options) + "/#dash/#{job.app_id}/expand/#{job.id}"
5
+ end
6
+ end
7
+ end
@@ -1,3 +1,3 @@
1
1
  module Rearview
2
- VERSION = "1.0.1"
2
+ VERSION = "1.0.2"
3
3
  end
@@ -1,3 +1,19 @@
1
1
  # Tasks made available to engine host..
2
+
2
3
  namespace :rearview do
4
+ namespace :config do
5
+
6
+ desc "Verify configuration"
7
+ task :verify => [:environment] do
8
+ puts "using \"#{Rails.env}\" configuration:\n#{Rearview.config.dump}"
9
+ print "validating..."
10
+ if Rearview.config.valid?
11
+ puts "PASSED"
12
+ else
13
+ puts "FAILED"
14
+ puts Rearview.config.errors.full_messages.join("\n")
15
+ end
16
+ end
17
+
18
+ end
3
19
  end
@@ -36,3 +36,116 @@
36
36
   (2.0ms) SELECT version FROM `schema_migrations`
37
37
   (2.0ms) INSERT INTO `schema_migrations` (version) VALUES ('20131106162900')
38
38
  ActiveRecord::SchemaMigration Load (1.0ms) SELECT `schema_migrations`.* FROM `schema_migrations`
39
+  (125.0ms) DROP DATABASE IF EXISTS `rearview_dummy_test`
40
+  (1.0ms) CREATE DATABASE `rearview_dummy_test` DEFAULT CHARACTER SET `utf8` COLLATE `utf8_unicode_ci`
41
+  (34.0ms) CREATE TABLE `applications` (`id` int(11) DEFAULT NULL auto_increment PRIMARY KEY, `user_id` int(11), `name` varchar(255) NOT NULL, `created_at` datetime, `updated_at` datetime, `deleted_at` datetime, `ancestry` varchar(255), `description` varchar(255)) ENGINE=InnoDB DEFAULT CHARSET=utf8
42
+  (12.0ms) CREATE INDEX `index_applications_on_ancestry` ON `applications` (`ancestry`)
43
+  (9.0ms) CREATE INDEX `user_id` ON `applications` (`user_id`)
44
+  (15.0ms) CREATE TABLE `job_data` (`id` int(11) DEFAULT NULL auto_increment PRIMARY KEY, `job_id` int(11) DEFAULT 0 NOT NULL, `created_at` datetime, `updated_at` datetime, `data` longtext NOT NULL) ENGINE=InnoDB DEFAULT CHARSET=utf8
45
+  (9.0ms) CREATE TABLE `job_errors` (`id` int(11) DEFAULT NULL auto_increment PRIMARY KEY, `job_id` int(11), `created_at` datetime, `message` longtext, `status` varchar(255), `last_alerted_at` datetime, `updated_at` datetime) ENGINE=InnoDB DEFAULT CHARSET=utf8
46
+  (9.0ms) CREATE INDEX `job_id` ON `job_errors` (`job_id`)
47
+  (21.0ms) CREATE TABLE `jobs` (`id` int(11) DEFAULT NULL auto_increment PRIMARY KEY, `created_at` datetime, `updated_at` datetime, `name` varchar(255) NOT NULL, `active` tinyint(1) DEFAULT 1 NOT NULL, `last_run` datetime, `cron_expr` varchar(1024) NOT NULL, `status` varchar(255), `user_id` int(11), `alert_keys` text, `deleted_at` datetime, `error_timeout` int(11) DEFAULT 60 NOT NULL, `next_run` datetime, `description` text, `app_id` int(11) NOT NULL, `metrics` text NOT NULL, `monitor_expr` text, `minutes` int(11), `to_date` text) ENGINE=InnoDB DEFAULT CHARSET=utf8
48
+  (10.0ms) CREATE INDEX `app_id` ON `jobs` (`app_id`)
49
+  (9.0ms) CREATE UNIQUE INDEX `id_name_version_key` ON `jobs` (`id`, `name`)
50
+  (17.0ms) CREATE INDEX `jobs_ibfk_1` ON `jobs` (`user_id`)
51
+  (13.0ms) CREATE TABLE `users` (`id` int(11) DEFAULT NULL auto_increment PRIMARY KEY, `created_at` datetime, `updated_at` datetime, `encrypted_password` varchar(255) DEFAULT '' NOT NULL, `email` varchar(255) NOT NULL, `first_name` varchar(255), `last_name` varchar(255), `last_login` datetime, `preferences` text) ENGINE=InnoDB DEFAULT CHARSET=utf8
52
+  (8.0ms) CREATE UNIQUE INDEX `email` ON `users` (`email`)
53
+  (12.0ms) CREATE TABLE `schema_migrations` (`version` varchar(255) NOT NULL) ENGINE=InnoDB DEFAULT CHARSET=utf8
54
+  (14.0ms) CREATE UNIQUE INDEX `unique_schema_migrations` ON `schema_migrations` (`version`)
55
+  (1.0ms) SELECT version FROM `schema_migrations`
56
+  (1.0ms) INSERT INTO `schema_migrations` (version) VALUES ('20131106162900')
57
+ ActiveRecord::SchemaMigration Load (5.0ms) SELECT `schema_migrations`.* FROM `schema_migrations`
58
+  (12.0ms) DROP DATABASE IF EXISTS `rearview_dummy_test`
59
+  (2.0ms) CREATE DATABASE `rearview_dummy_test` DEFAULT CHARACTER SET `utf8` COLLATE `utf8_unicode_ci`
60
+  (37.0ms) CREATE TABLE `applications` (`id` int(11) DEFAULT NULL auto_increment PRIMARY KEY, `user_id` int(11), `name` varchar(255) NOT NULL, `created_at` datetime, `updated_at` datetime, `deleted_at` datetime, `ancestry` varchar(255), `description` varchar(255)) ENGINE=InnoDB DEFAULT CHARSET=utf8
61
+  (12.0ms) CREATE INDEX `index_applications_on_ancestry` ON `applications` (`ancestry`)
62
+  (17.0ms) CREATE INDEX `user_id` ON `applications` (`user_id`)
63
+  (14.0ms) CREATE TABLE `job_data` (`id` int(11) DEFAULT NULL auto_increment PRIMARY KEY, `job_id` int(11) DEFAULT 0 NOT NULL, `created_at` datetime, `updated_at` datetime, `data` longtext NOT NULL) ENGINE=InnoDB DEFAULT CHARSET=utf8
64
+  (8.0ms) CREATE TABLE `job_errors` (`id` int(11) DEFAULT NULL auto_increment PRIMARY KEY, `job_id` int(11), `created_at` datetime, `message` longtext, `status` varchar(255), `last_alerted_at` datetime, `updated_at` datetime) ENGINE=InnoDB DEFAULT CHARSET=utf8
65
+  (10.0ms) CREATE INDEX `job_id` ON `job_errors` (`job_id`)
66
+  (12.0ms) CREATE TABLE `jobs` (`id` int(11) DEFAULT NULL auto_increment PRIMARY KEY, `created_at` datetime, `updated_at` datetime, `name` varchar(255) NOT NULL, `active` tinyint(1) DEFAULT 1 NOT NULL, `last_run` datetime, `cron_expr` varchar(1024) NOT NULL, `status` varchar(255), `user_id` int(11), `alert_keys` text, `deleted_at` datetime, `error_timeout` int(11) DEFAULT 60 NOT NULL, `next_run` datetime, `description` text, `app_id` int(11) NOT NULL, `metrics` text NOT NULL, `monitor_expr` text, `minutes` int(11), `to_date` text) ENGINE=InnoDB DEFAULT CHARSET=utf8
67
+  (10.0ms) CREATE INDEX `app_id` ON `jobs` (`app_id`)
68
+  (14.0ms) CREATE UNIQUE INDEX `id_name_version_key` ON `jobs` (`id`, `name`)
69
+  (9.0ms) CREATE INDEX `jobs_ibfk_1` ON `jobs` (`user_id`)
70
+  (11.0ms) CREATE TABLE `users` (`id` int(11) DEFAULT NULL auto_increment PRIMARY KEY, `created_at` datetime, `updated_at` datetime, `encrypted_password` varchar(255) DEFAULT '' NOT NULL, `email` varchar(255) NOT NULL, `first_name` varchar(255), `last_name` varchar(255), `last_login` datetime, `preferences` text) ENGINE=InnoDB DEFAULT CHARSET=utf8
71
+  (9.0ms) CREATE UNIQUE INDEX `email` ON `users` (`email`)
72
+  (15.0ms) CREATE TABLE `schema_migrations` (`version` varchar(255) NOT NULL) ENGINE=InnoDB DEFAULT CHARSET=utf8
73
+  (12.0ms) CREATE UNIQUE INDEX `unique_schema_migrations` ON `schema_migrations` (`version`)
74
+  (2.0ms) SELECT version FROM `schema_migrations`
75
+  (1.0ms) INSERT INTO `schema_migrations` (version) VALUES ('20131106162900')
76
+ ActiveRecord::SchemaMigration Load (1.0ms) SELECT `schema_migrations`.* FROM `schema_migrations`
77
+  (8.0ms) DROP DATABASE IF EXISTS `rearview_dummy_test`
78
+  (1.0ms) CREATE DATABASE `rearview_dummy_test` DEFAULT CHARACTER SET `utf8` COLLATE `utf8_unicode_ci`
79
+  (19.0ms) CREATE TABLE `applications` (`id` int(11) DEFAULT NULL auto_increment PRIMARY KEY, `user_id` int(11), `name` varchar(255) NOT NULL, `created_at` datetime, `updated_at` datetime, `deleted_at` datetime, `ancestry` varchar(255), `description` varchar(255)) ENGINE=InnoDB DEFAULT CHARSET=utf8
80
+  (10.0ms) CREATE INDEX `index_applications_on_ancestry` ON `applications` (`ancestry`)
81
+  (9.0ms) CREATE INDEX `user_id` ON `applications` (`user_id`)
82
+  (25.0ms) CREATE TABLE `job_data` (`id` int(11) DEFAULT NULL auto_increment PRIMARY KEY, `job_id` int(11) DEFAULT 0 NOT NULL, `created_at` datetime, `updated_at` datetime, `data` longtext NOT NULL) ENGINE=InnoDB DEFAULT CHARSET=utf8
83
+  (7.0ms) CREATE TABLE `job_errors` (`id` int(11) DEFAULT NULL auto_increment PRIMARY KEY, `job_id` int(11), `created_at` datetime, `message` longtext, `status` varchar(255), `last_alerted_at` datetime, `updated_at` datetime) ENGINE=InnoDB DEFAULT CHARSET=utf8
84
+  (12.0ms) CREATE INDEX `job_id` ON `job_errors` (`job_id`)
85
+  (11.0ms) CREATE TABLE `jobs` (`id` int(11) DEFAULT NULL auto_increment PRIMARY KEY, `created_at` datetime, `updated_at` datetime, `name` varchar(255) NOT NULL, `active` tinyint(1) DEFAULT 1 NOT NULL, `last_run` datetime, `cron_expr` varchar(1024) NOT NULL, `status` varchar(255), `user_id` int(11), `alert_keys` text, `deleted_at` datetime, `error_timeout` int(11) DEFAULT 60 NOT NULL, `next_run` datetime, `description` text, `app_id` int(11) NOT NULL, `metrics` text NOT NULL, `monitor_expr` text, `minutes` int(11), `to_date` text) ENGINE=InnoDB DEFAULT CHARSET=utf8
86
+  (9.0ms) CREATE INDEX `app_id` ON `jobs` (`app_id`)
87
+  (16.0ms) CREATE UNIQUE INDEX `id_name_version_key` ON `jobs` (`id`, `name`)
88
+  (9.0ms) CREATE INDEX `jobs_ibfk_1` ON `jobs` (`user_id`)
89
+  (16.0ms) CREATE TABLE `users` (`id` int(11) DEFAULT NULL auto_increment PRIMARY KEY, `created_at` datetime, `updated_at` datetime, `encrypted_password` varchar(255) DEFAULT '' NOT NULL, `email` varchar(255) NOT NULL, `first_name` varchar(255), `last_name` varchar(255), `last_login` datetime, `preferences` text) ENGINE=InnoDB DEFAULT CHARSET=utf8
90
+  (10.0ms) CREATE UNIQUE INDEX `email` ON `users` (`email`)
91
+  (15.0ms) CREATE TABLE `schema_migrations` (`version` varchar(255) NOT NULL) ENGINE=InnoDB DEFAULT CHARSET=utf8
92
+  (11.0ms) CREATE UNIQUE INDEX `unique_schema_migrations` ON `schema_migrations` (`version`)
93
+  (1.0ms) SELECT version FROM `schema_migrations`
94
+  (2.0ms) INSERT INTO `schema_migrations` (version) VALUES ('20131106162900')
95
+ ActiveRecord::SchemaMigration Load (1.0ms) SELECT `schema_migrations`.* FROM `schema_migrations`
96
+  (39.0ms) DROP DATABASE IF EXISTS `rearview_dummy_test`
97
+  (7.0ms) CREATE DATABASE `rearview_dummy_test` DEFAULT CHARACTER SET `utf8` COLLATE `utf8_unicode_ci`
98
+  (32.0ms) CREATE TABLE `applications` (`id` int(11) DEFAULT NULL auto_increment PRIMARY KEY, `user_id` int(11), `name` varchar(255) NOT NULL, `created_at` datetime, `updated_at` datetime, `deleted_at` datetime, `ancestry` varchar(255), `description` varchar(255)) ENGINE=InnoDB DEFAULT CHARSET=utf8
99
+  (10.0ms) CREATE INDEX `index_applications_on_ancestry` ON `applications` (`ancestry`)
100
+  (12.0ms) CREATE INDEX `user_id` ON `applications` (`user_id`)
101
+  (9.0ms) CREATE TABLE `job_data` (`id` int(11) DEFAULT NULL auto_increment PRIMARY KEY, `job_id` int(11) DEFAULT 0 NOT NULL, `created_at` datetime, `updated_at` datetime, `data` longtext NOT NULL) ENGINE=InnoDB DEFAULT CHARSET=utf8
102
+  (8.0ms) CREATE TABLE `job_errors` (`id` int(11) DEFAULT NULL auto_increment PRIMARY KEY, `job_id` int(11), `created_at` datetime, `message` longtext, `status` varchar(255), `last_alerted_at` datetime, `updated_at` datetime) ENGINE=InnoDB DEFAULT CHARSET=utf8
103
+  (9.0ms) CREATE INDEX `job_id` ON `job_errors` (`job_id`)
104
+  (17.0ms) CREATE TABLE `jobs` (`id` int(11) DEFAULT NULL auto_increment PRIMARY KEY, `created_at` datetime, `updated_at` datetime, `name` varchar(255) NOT NULL, `active` tinyint(1) DEFAULT 1 NOT NULL, `last_run` datetime, `cron_expr` varchar(1024) NOT NULL, `status` varchar(255), `user_id` int(11), `alert_keys` text, `deleted_at` datetime, `error_timeout` int(11) DEFAULT 60 NOT NULL, `next_run` datetime, `description` text, `app_id` int(11) NOT NULL, `metrics` text NOT NULL, `monitor_expr` text, `minutes` int(11), `to_date` text) ENGINE=InnoDB DEFAULT CHARSET=utf8
105
+  (11.0ms) CREATE INDEX `app_id` ON `jobs` (`app_id`)
106
+  (14.0ms) CREATE UNIQUE INDEX `id_name_version_key` ON `jobs` (`id`, `name`)
107
+  (16.0ms) CREATE INDEX `jobs_ibfk_1` ON `jobs` (`user_id`)
108
+  (12.0ms) CREATE TABLE `users` (`id` int(11) DEFAULT NULL auto_increment PRIMARY KEY, `created_at` datetime, `updated_at` datetime, `encrypted_password` varchar(255) DEFAULT '' NOT NULL, `email` varchar(255) NOT NULL, `first_name` varchar(255), `last_name` varchar(255), `last_login` datetime, `preferences` text) ENGINE=InnoDB DEFAULT CHARSET=utf8
109
+  (10.0ms) CREATE UNIQUE INDEX `email` ON `users` (`email`)
110
+  (14.0ms) CREATE TABLE `schema_migrations` (`version` varchar(255) NOT NULL) ENGINE=InnoDB DEFAULT CHARSET=utf8
111
+  (20.0ms) CREATE UNIQUE INDEX `unique_schema_migrations` ON `schema_migrations` (`version`)
112
+  (2.0ms) SELECT version FROM `schema_migrations`
113
+  (2.0ms) INSERT INTO `schema_migrations` (version) VALUES ('20131106162900')
114
+ ActiveRecord::SchemaMigration Load (2.0ms) SELECT `schema_migrations`.* FROM `schema_migrations`
115
+  (29.0ms) DROP DATABASE IF EXISTS `rearview_dummy_test`
116
+  (2.0ms) CREATE DATABASE `rearview_dummy_test` DEFAULT CHARACTER SET `utf8` COLLATE `utf8_unicode_ci`
117
+  (34.0ms) CREATE TABLE `applications` (`id` int(11) DEFAULT NULL auto_increment PRIMARY KEY, `user_id` int(11), `name` varchar(255) NOT NULL, `created_at` datetime, `updated_at` datetime, `deleted_at` datetime, `ancestry` varchar(255), `description` varchar(255)) ENGINE=InnoDB DEFAULT CHARSET=utf8
118
+  (11.0ms) CREATE INDEX `index_applications_on_ancestry` ON `applications` (`ancestry`)
119
+  (11.0ms) CREATE INDEX `user_id` ON `applications` (`user_id`)
120
+  (12.0ms) CREATE TABLE `job_data` (`id` int(11) DEFAULT NULL auto_increment PRIMARY KEY, `job_id` int(11) DEFAULT 0 NOT NULL, `created_at` datetime, `updated_at` datetime, `data` longtext NOT NULL) ENGINE=InnoDB DEFAULT CHARSET=utf8
121
+  (8.0ms) CREATE TABLE `job_errors` (`id` int(11) DEFAULT NULL auto_increment PRIMARY KEY, `job_id` int(11), `created_at` datetime, `message` longtext, `status` varchar(255), `last_alerted_at` datetime, `updated_at` datetime) ENGINE=InnoDB DEFAULT CHARSET=utf8
122
+  (11.0ms) CREATE INDEX `job_id` ON `job_errors` (`job_id`)
123
+  (8.0ms) CREATE TABLE `jobs` (`id` int(11) DEFAULT NULL auto_increment PRIMARY KEY, `created_at` datetime, `updated_at` datetime, `name` varchar(255) NOT NULL, `active` tinyint(1) DEFAULT 1 NOT NULL, `last_run` datetime, `cron_expr` varchar(1024) NOT NULL, `status` varchar(255), `user_id` int(11), `alert_keys` text, `deleted_at` datetime, `error_timeout` int(11) DEFAULT 60 NOT NULL, `next_run` datetime, `description` text, `app_id` int(11) NOT NULL, `metrics` text NOT NULL, `monitor_expr` text, `minutes` int(11), `to_date` text) ENGINE=InnoDB DEFAULT CHARSET=utf8
124
+  (9.0ms) CREATE INDEX `app_id` ON `jobs` (`app_id`)
125
+  (8.0ms) CREATE UNIQUE INDEX `id_name_version_key` ON `jobs` (`id`, `name`)
126
+  (9.0ms) CREATE INDEX `jobs_ibfk_1` ON `jobs` (`user_id`)
127
+  (13.0ms) CREATE TABLE `users` (`id` int(11) DEFAULT NULL auto_increment PRIMARY KEY, `created_at` datetime, `updated_at` datetime, `encrypted_password` varchar(255) DEFAULT '' NOT NULL, `email` varchar(255) NOT NULL, `first_name` varchar(255), `last_name` varchar(255), `last_login` datetime, `preferences` text) ENGINE=InnoDB DEFAULT CHARSET=utf8
128
+  (10.0ms) CREATE UNIQUE INDEX `email` ON `users` (`email`)
129
+  (8.0ms) CREATE TABLE `schema_migrations` (`version` varchar(255) NOT NULL) ENGINE=InnoDB DEFAULT CHARSET=utf8
130
+  (11.0ms) CREATE UNIQUE INDEX `unique_schema_migrations` ON `schema_migrations` (`version`)
131
+  (2.0ms) SELECT version FROM `schema_migrations`
132
+  (2.0ms) INSERT INTO `schema_migrations` (version) VALUES ('20131106162900')
133
+ ActiveRecord::SchemaMigration Load (2.0ms) SELECT `schema_migrations`.* FROM `schema_migrations`
134
+  (41.0ms) DROP DATABASE IF EXISTS `rearview_dummy_test`
135
+  (2.0ms) CREATE DATABASE `rearview_dummy_test` DEFAULT CHARACTER SET `utf8` COLLATE `utf8_unicode_ci`
136
+  (29.0ms) CREATE TABLE `applications` (`id` int(11) DEFAULT NULL auto_increment PRIMARY KEY, `user_id` int(11), `name` varchar(255) NOT NULL, `created_at` datetime, `updated_at` datetime, `deleted_at` datetime, `ancestry` varchar(255), `description` varchar(255)) ENGINE=InnoDB DEFAULT CHARSET=utf8
137
+  (9.0ms) CREATE INDEX `index_applications_on_ancestry` ON `applications` (`ancestry`)
138
+  (11.0ms) CREATE INDEX `user_id` ON `applications` (`user_id`)
139
+  (16.0ms) CREATE TABLE `job_data` (`id` int(11) DEFAULT NULL auto_increment PRIMARY KEY, `job_id` int(11) DEFAULT 0 NOT NULL, `created_at` datetime, `updated_at` datetime, `data` longtext NOT NULL) ENGINE=InnoDB DEFAULT CHARSET=utf8
140
+  (8.0ms) CREATE TABLE `job_errors` (`id` int(11) DEFAULT NULL auto_increment PRIMARY KEY, `job_id` int(11), `created_at` datetime, `message` longtext, `status` varchar(255), `last_alerted_at` datetime, `updated_at` datetime) ENGINE=InnoDB DEFAULT CHARSET=utf8
141
+  (9.0ms) CREATE INDEX `job_id` ON `job_errors` (`job_id`)
142
+  (12.0ms) CREATE TABLE `jobs` (`id` int(11) DEFAULT NULL auto_increment PRIMARY KEY, `created_at` datetime, `updated_at` datetime, `name` varchar(255) NOT NULL, `active` tinyint(1) DEFAULT 1 NOT NULL, `last_run` datetime, `cron_expr` varchar(1024) NOT NULL, `status` varchar(255), `user_id` int(11), `alert_keys` text, `deleted_at` datetime, `error_timeout` int(11) DEFAULT 60 NOT NULL, `next_run` datetime, `description` text, `app_id` int(11) NOT NULL, `metrics` text NOT NULL, `monitor_expr` text, `minutes` int(11), `to_date` text) ENGINE=InnoDB DEFAULT CHARSET=utf8
143
+  (10.0ms) CREATE INDEX `app_id` ON `jobs` (`app_id`)
144
+  (8.0ms) CREATE UNIQUE INDEX `id_name_version_key` ON `jobs` (`id`, `name`)
145
+  (10.0ms) CREATE INDEX `jobs_ibfk_1` ON `jobs` (`user_id`)
146
+  (14.0ms) CREATE TABLE `users` (`id` int(11) DEFAULT NULL auto_increment PRIMARY KEY, `created_at` datetime, `updated_at` datetime, `encrypted_password` varchar(255) DEFAULT '' NOT NULL, `email` varchar(255) NOT NULL, `first_name` varchar(255), `last_name` varchar(255), `last_login` datetime, `preferences` text) ENGINE=InnoDB DEFAULT CHARSET=utf8
147
+  (8.0ms) CREATE UNIQUE INDEX `email` ON `users` (`email`)
148
+  (15.0ms) CREATE TABLE `schema_migrations` (`version` varchar(255) NOT NULL) ENGINE=InnoDB DEFAULT CHARSET=utf8
149
+  (12.0ms) CREATE UNIQUE INDEX `unique_schema_migrations` ON `schema_migrations` (`version`)
150
+  (2.0ms) SELECT version FROM `schema_migrations`
151
+  (2.0ms) INSERT INTO `schema_migrations` (version) VALUES ('20131106162900')