naf 2.1.9 → 2.1.10

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/Gemfile CHANGED
@@ -10,7 +10,7 @@ end
10
10
  gem 'jquery-ui-rails'
11
11
  gem 'awesome_print'
12
12
  gem 'will_paginate'
13
- gem 'facter'
13
+ gem 'facter', '1.7.5'
14
14
  gem 'shoulda-matchers', '2.0.0'
15
15
  gem 'timecop', '0.4.5'
16
16
  gem 'yajl-ruby'
@@ -1,5 +1,16 @@
1
1
  = Release Notes
2
2
 
3
+ === Version 2.1.10
4
+ Bug fixes:
5
+ * LogArchiver correctly removes files and directories
6
+ * Disabled machine is highlighted in red
7
+ * Custom validation for machine marked as enabled and deleted
8
+ * UI links behave correctly if the engine's mount path is different than '/job_system'
9
+
10
+ Changes:
11
+ * Improved memory management
12
+ * Removed machine log display
13
+
3
14
  === Version 2.1.9
4
15
  Bug fixes:
5
16
  * Logical::Naf::ConstructionZone doesn't properly propagate affinity parameters
@@ -63,12 +63,12 @@ jQuery(document).ready(function() {
63
63
 
64
64
  function addLinkToApplication(nRow, aData) {
65
65
  var id = aData[0];
66
- var row = jQuery('<a href="/job_system/applications/' + id + '">' + id + '</a>' );
66
+ var row = jQuery('<a href="applications/' + id + '">' + id + '</a>' );
67
67
  jQuery('td:nth-child(1)', nRow).empty().append(row);
68
68
  }
69
69
 
70
70
  function colorizationDeletedOrHidden(nRow, aData) {
71
- if (aData[6] == 'true') {
71
+ if (aData[7] == true) {
72
72
  jQuery(nRow).addClass('deleted_or_hidden');
73
73
  }
74
74
  }
@@ -59,19 +59,19 @@ jQuery(document).ready(function() {
59
59
  return false;
60
60
  }
61
61
  var id = jQuery(this).attr('id');
62
- var url = '/job_system/historical_jobs/' + id;
62
+ var url = 'job_system/historical_jobs/' + id;
63
63
  jQuery.ajax({
64
64
  url: url,
65
65
  type: 'POST',
66
66
  dataType: 'json',
67
67
  data: { "historical_job[request_to_terminate]": 1, "historical_job_id": id, "_method": "put" },
68
68
  success:function (data) {
69
- if (data.success) {
70
- var title = data.title ? data.title : data.command
71
- jQuery("<p id='notice'>A Job " + title + " was terminated!</p>").
72
- appendTo('#flash_message').slideDown().delay(5000).slideUp();
73
- jQuery('#datatable').dataTable().fnDraw();
74
- }
69
+ if (data.success) {
70
+ var title = data.title ? data.title : data.command
71
+ jQuery("<p id='notice'>A Job " + title + " was terminated!</p>").
72
+ appendTo('#flash_message').slideDown().delay(5000).slideUp();
73
+ jQuery('#datatable').dataTable().fnDraw();
74
+ }
75
75
  }
76
76
  });
77
77
  });
@@ -79,7 +79,7 @@ jQuery(document).ready(function() {
79
79
 
80
80
  function addLinkToJob(nRow, aData) {
81
81
  var id = aData[0];
82
- var row = jQuery('<a href="/job_system/historical_jobs/' + id + '">' + id + '</a>' );
82
+ var row = jQuery('<a href="job_system/historical_jobs/' + id + '">' + id + '</a>' );
83
83
  jQuery('td:nth-child(1)', nRow).empty().append(row);
84
84
  }
85
85
 
@@ -49,7 +49,7 @@ jQuery(document).ready(function() {
49
49
  return false;
50
50
  }
51
51
  var id = jQuery(this).attr('id');
52
- var url = '/job_system/machine_runner_invocations/' + id;
52
+ var url = 'machine_runner_invocations/' + id;
53
53
  jQuery.ajax({
54
54
  url: url,
55
55
  type: 'POST',
@@ -47,18 +47,18 @@ jQuery(document).ready(function() {
47
47
  return false;
48
48
  }
49
49
  var id = jQuery(this).attr('id');
50
- var url = '/job_system/machines/' + id;
50
+ var url = 'machines/' + id;
51
51
  jQuery.ajax({
52
52
  url: url,
53
53
  type: 'POST',
54
54
  dataType: 'json',
55
55
  data: { "machine[marked_down]": 1, "terminate": true, "_method": "put" },
56
56
  success:function (data) {
57
- if (data.success) {
58
- jQuery("<p id='notice'>Machine was marked down!</p>").
59
- appendTo('#flash_message').slideDown().delay(5000).slideUp();
60
- jQuery('#datatable').dataTable().fnDraw();
61
- }
57
+ if (data.success) {
58
+ jQuery("<p id='notice'>Machine was marked down!</p>").
59
+ appendTo('#flash_message').slideDown().delay(5000).slideUp();
60
+ jQuery('#datatable').dataTable().fnDraw();
61
+ }
62
62
  }
63
63
  });
64
64
  });
@@ -66,12 +66,12 @@ jQuery(document).ready(function() {
66
66
 
67
67
  function addLinkToMachines(nRow, aData) {
68
68
  var id = aData[0];
69
- var row = jQuery('<a href="/job_system/machines/' + id + '">' + id + '</a>' );
69
+ var row = jQuery('<a href="machines/' + id + '">' + id + '</a>' );
70
70
  jQuery('td:nth-child(1)', nRow).empty().append(row);
71
71
  }
72
72
 
73
73
  function colorizationDeletedOrHidden(nRow, aData) {
74
- if (aData[5] == 'true') {
74
+ if (aData[4] == false) {
75
75
  jQuery(nRow).addClass('deleted_or_hidden');
76
76
  }
77
77
  }
@@ -6,9 +6,6 @@ module Naf
6
6
  @job = ::Naf::HistoricalJob.find_by_id(params['record_id'].to_i)
7
7
  @status = ::Logical::Naf::Job.new(@job).status
8
8
  @partial = 'job_logs'
9
- elsif params['record_type'] == 'machine'
10
- @machine = ::Naf::Machine.find_by_id(params['record_id'].to_i)
11
- @partial = 'machine_logs'
12
9
  elsif params['record_type'] == 'runner'
13
10
  @runner = ::Naf::MachineRunner.find_by_id(params['record_id'].to_i)
14
11
  @partial = 'runner_logs'
@@ -94,8 +94,6 @@ module Logical::Naf
94
94
  parser.parse(json) do |log|
95
95
  if self.class.to_s == 'Logical::Naf::LogParser::Runner'
96
96
  log['id'] = get_invocation_id(file.scan(UUID_REGEX).first)
97
- elsif self.class.to_s == 'Logical::Naf::LogParser::Machine'
98
- log['job_id'] = get_job_id(file)
99
97
  end
100
98
  filter_log_messages(log)
101
99
  end
@@ -22,7 +22,7 @@ module Logical::Naf
22
22
  end
23
23
 
24
24
  def invocation_link(id)
25
- "<a href=\"\/job_system\/machine_runner_invocations\/#{id}\" style=\"font-weight:bold; color: #333399\">invocation(#{id})</a>"
25
+ "<a href=\"machine_runner_invocations\/#{id}\" style=\"font-weight:bold; color: #333399\">invocation(#{id})</a>"
26
26
  end
27
27
 
28
28
  def sort_jsons
@@ -35,6 +35,8 @@ module Logical::Naf
35
35
  end
36
36
 
37
37
  def retrieve_log_files_from_s3
38
+ return [] unless record_id.present?
39
+
38
40
  uuids = ::Naf::MachineRunner.
39
41
  joins(:machine_runner_invocations).
40
42
  where("#{Naf.schema_name}.machine_runners.id = ?", record_id).
@@ -7,8 +7,8 @@ module Logical
7
7
  DATE_REGEX = /((\d){4}-(\d){2}-(\d){2} (\d){2}:(\d){2}:(\d){2} UTC)/
8
8
 
9
9
  def log_files
10
- tree = bucket.objects.with_prefix(prefix).as_tree
11
- directories = tree.children.select(&:branch?).collect(&:prefix).uniq
10
+ tree = bucket.objects.with_prefix(job_log_prefix).as_tree
11
+ directories = tree.children.select(&:branch?).collect(&:job_log_prefix).uniq
12
12
 
13
13
  files = []
14
14
  directories.each do |directory|
@@ -21,8 +21,8 @@ module Logical
21
21
  end
22
22
 
23
23
  def runner_log_files
24
- tree = bucket.objects.with_prefix(prefix(true)).as_tree
25
- directories = tree.children.select(&:branch?).collect(&:prefix).uniq
24
+ tree = bucket.objects.with_prefix(runner_log_prefix).as_tree
25
+ directories = tree.children.select(&:branch?).collect(&:runner_log_prefix).uniq
26
26
 
27
27
  files = []
28
28
  directories.each do |directory|
@@ -40,7 +40,8 @@ module Logical
40
40
  end
41
41
 
42
42
  def retrieve_job_files(job_id)
43
- tree = bucket.objects.with_prefix(prefix + "#{job_id}").as_tree
43
+ return [] unless job_id.present?
44
+ tree = bucket.objects.with_prefix(job_log_prefix + "#{job_id}").as_tree
44
45
  sort_files(tree.children.select(&:leaf?).collect(&:key))
45
46
  end
46
47
 
@@ -57,12 +58,12 @@ module Logical
57
58
  @bucket ||= s3.buckets[NAF_BUCKET]
58
59
  end
59
60
 
60
- def prefix(runner_logs = false)
61
- if runner_logs
62
- "#{NAF_LOG_PATH}/#{creation_time}/#{::Naf::NAF_DATABASE_HOSTNAME}/#{::Naf::NAF_DATABASE}/#{::Naf.schema_name}/runners/"
63
- else
64
- "#{NAF_LOG_PATH}/#{creation_time}/#{::Naf::NAF_DATABASE_HOSTNAME}/#{::Naf::NAF_DATABASE}/#{::Naf.schema_name}/jobs/"
65
- end
61
+ def runner_log_prefix
62
+ @runner_log_prefix ||= "#{NAF_LOG_PATH}/#{creation_time}/#{::Naf::NAF_DATABASE_HOSTNAME}/#{::Naf::NAF_DATABASE}/#{::Naf.schema_name}/runners/"
63
+ end
64
+
65
+ def job_log_prefix
66
+ @job_log_prefix ||= "#{NAF_LOG_PATH}/#{creation_time}/#{::Naf::NAF_DATABASE_HOSTNAME}/#{::Naf::NAF_DATABASE}/#{::Naf.schema_name}/jobs/"
66
67
  end
67
68
 
68
69
  def sort_files(files)
@@ -43,6 +43,7 @@ module Naf
43
43
  greater_than: -2147483648,
44
44
  less_than: 2147483647
45
45
  }
46
+ before_save :check_presence_of_enabled_and_deleted
46
47
  before_save :check_blank_values
47
48
 
48
49
  #---------------------
@@ -261,5 +262,14 @@ module Naf
261
262
  self.log_level = nil if self.log_level.blank?
262
263
  end
263
264
 
265
+ def check_presence_of_enabled_and_deleted
266
+ if self.enabled && self.deleted
267
+ self.errors.add(:enabled, 'should not be true when deleted is true')
268
+ return false
269
+ end
270
+
271
+ return true
272
+ end
273
+
264
274
  end
265
275
  end
@@ -8,14 +8,14 @@ module Process::Naf
8
8
  DATE_REGEX = /\d{8}_\d{6}/
9
9
  LOG_RETENTION = 1
10
10
 
11
- def work
12
- # Use AWS credentials to access S3
13
- s3 = AWS::S3.new(access_key_id: AWS_ID,
11
+ def work
12
+ # Use AWS credentials to access S3
13
+ s3 = AWS::S3.new(access_key_id: AWS_ID,
14
14
  secret_access_key: AWS_KEY,
15
15
  ssl_verify_peer: false)
16
16
 
17
- # Each project will have a specific bucket
18
- bucket = s3.buckets[NAF_BUCKET]
17
+ # Each project will have a specific bucket
18
+ bucket = s3.buckets[NAF_BUCKET]
19
19
  files = log_files
20
20
 
21
21
  logger.info 'Starting to save files to s3...'
@@ -31,13 +31,13 @@ module Process::Naf
31
31
 
32
32
  logger.info 'Starting to archive files...'
33
33
  archive_old_files(files)
34
- end
34
+ end
35
35
 
36
- private
36
+ private
37
37
 
38
- def project_name
39
- (`git remote -v`).slice(/\/\S+/).sub('.git','')[1..-1]
40
- end
38
+ def project_name
39
+ (`git remote -v`).slice(/\/\S+/).sub('.git','')[1..-1]
40
+ end
41
41
 
42
42
  def log_files
43
43
  files = Dir[NAF_JOBS_LOG_PATH + "*/*"]
@@ -63,12 +63,22 @@ module Process::Naf
63
63
 
64
64
  def archive_old_files(files)
65
65
  copy_files
66
- today = Time.zone.now.to_date
67
66
  files.each do |file|
68
67
  logger.info "Archived file: #{file}"
69
- directory = `dirname #{file}`
70
- `rm -r #{directory}`
71
68
  end
69
+ File.delete(*files)
70
+
71
+ cleanup(NAF_JOBS_LOG_PATH + '*')
72
+ cleanup(NAF_RUNNERS_LOG_PATH + '*')
73
+ end
74
+
75
+ def cleanup(path)
76
+ Dir[path].select { |d| File.directory? d }. # select only directories
77
+ select { |d| (Dir.entries(d) - %w[ . .. ]).empty? }. # check if directory is empty
78
+ each do |d|
79
+ logger.info "Removing directory #{d}"
80
+ Dir.rmdir d
81
+ end
72
82
  end
73
83
 
74
84
  def copy_files
@@ -241,6 +241,7 @@ module Process::Naf
241
241
  end
242
242
 
243
243
  def check_schedules
244
+ logger.debug escape_html("last time schedules were checked: #{::Naf::Machine.last_time_schedules_were_checked}")
244
245
  if ::Naf::Machine.is_it_time_to_check_schedules?(@check_schedules_period.minutes)
245
246
  logger.debug "it's time to check schedules"
246
247
  if ::Naf::ApplicationSchedule.try_lock_schedules
@@ -544,7 +545,23 @@ module Process::Naf
544
545
  Facter.clear
545
546
  memory_size = Facter.memorysize_mb.to_f
546
547
  memory_free = Facter.memoryfree_mb.to_f
547
- memory_free_percentage = (memory_free / memory_size) * 100.0
548
+
549
+ # Linux breaks out kernel cache-use memory into an SReclaimable stat
550
+ # in /proc/meminfo which should be counted as free, but facter does not.
551
+ sreclaimable = 0.0
552
+ begin
553
+ File.readlines('/proc/meminfo').each do |l|
554
+ if l =~ /^(?:SReclaimable):\s+(\d+)\s+\S+/
555
+ # Convert the memory from Kilobytes to Gigabytes and
556
+ # store it into sreclaimable
557
+ sreclaimable = ('%.2f' % [$1.to_f / 1024.0]).to_f
558
+ break
559
+ end
560
+ end
561
+ rescue
562
+ end
563
+
564
+ memory_free_percentage = ((memory_free + sreclaimable) / memory_size) * 100.0
548
565
 
549
566
  if (memory_free_percentage >= @minimum_memory_free)
550
567
  logger.detail "memory available: #{memory_free_percentage}% (free) >= " +
@@ -186,9 +186,8 @@
186
186
  return false;
187
187
  }
188
188
  var id = <%= @historical_job.id %>;
189
- var url = '/job_system/historical_jobs/' + id;
190
189
  jQuery.ajax({
191
- url: url,
190
+ url: id,
192
191
  type:'POST',
193
192
  dataType:'json',
194
193
  data:{ "historical_job[request_to_terminate]": 1, "historical_job_id": id, "_method": "put" },
@@ -36,7 +36,7 @@
36
36
  jQuery('#deleted').removeAttr('checked');
37
37
  jQuery('#datatable').addDataTable({ "bProcessing": true });
38
38
  jQuery('.datatable_variable').click(function () {
39
- var url = '/job_system/<%= @params_name.to_s + 's' %>';
39
+ var url = '<%= @params_name.to_s + 's' %>';
40
40
  jQuery.ajax({
41
41
  url:url,
42
42
  type:'GET',
@@ -239,10 +239,7 @@
239
239
 
240
240
  function setLogicalType(){
241
241
  logical_type = '::Logical::Naf::LogParser::';
242
- if('<%= record_type %>' == 'machine'){
243
- logical_type += 'Machine';
244
- }
245
- else if('<%= record_type %>' == 'runner'){
242
+ if('<%= record_type %>' == 'runner'){
246
243
  logical_type += 'Runner';
247
244
  }
248
245
  else if('<%= record_type %>' == 'job'){
@@ -29,7 +29,9 @@
29
29
  if (!answer) {
30
30
  return false;
31
31
  }
32
- var url = '/job_system/machine_runner_invocations/';
32
+ var str = window.location.pathname;
33
+ var sub_path = str.substring(0, str.indexOf("job_system"));
34
+ var url = sub_path + 'job_system/machine_runner_invocations/';
33
35
  jQuery.ajax({
34
36
  url: url,
35
37
  type: 'POST',
@@ -103,8 +103,9 @@
103
103
  return false;
104
104
  }
105
105
  var id = <%= @machine_runner.machine_runner_invocations.last.id %>;
106
- var url = '/job_system/machine_runner_invocations/' + id;
107
- jQuery.ajax({
106
+ var str = window.location.pathname;
107
+ var sub_path = str.substring(0, str.indexOf("job_system"));
108
+ var url = sub_path + 'job_system/machine_runner_invocations/' + id; jQuery.ajax({
108
109
  url: url,
109
110
  type: 'POST',
110
111
  dataType: 'json',
@@ -1,15 +1,6 @@
1
1
  <%
2
2
  rows = @machines.each do |machine|
3
- machine[11] = link_to image_tag('machine.png',
4
- class: 'action',
5
- title: "View machine(id: #{machine[0]}, server:#{machine[1].blank? ? machine[2] : machine[1]}) log"),
6
- url_for({ controller: 'log_viewer',
7
- action: 'index',
8
- record_id: machine[0],
9
- record_type: 'machine' }),
10
- { target: '_blank', id: machine[0] }
11
- machine[11] << "&nbsp;&nbsp;".html_safe
12
- machine[11] << (link_to image_tag('machine_runner.png',
3
+ machine[11] = (link_to image_tag('machine_runner.png',
13
4
  class: 'action',
14
5
  title: "View machine(id: #{machine[0]}, server:#{machine[1].blank? ? machine[2] : machine[1]}) runner log"),
15
6
  url_for({ controller: 'log_viewer',
@@ -54,18 +54,10 @@
54
54
  </tbody>
55
55
  </table>
56
56
  </br>
57
- <%= render partial: 'naf/log_viewer/log_layout', locals: { record_id: @machine.id, record_type: 'machine' } %>
58
57
  </div>
59
58
  <% end %>
60
59
 
61
60
  <%= render partial: 'naf/shared/application' %>
62
- <%= render partial: 'naf/shared/auto_resize_width', locals: { div_class: '.scrollable-output' } %>
63
- <%= render partial: 'naf/log_viewer/log_display',
64
- locals: {
65
- logs_url: "#{http_protocol}#{::Logical::Naf::Machine.new(@machine).runner}#{naf.logs_log_parsers_path}",
66
- record_id: @machine.id,
67
- record_type: 'machine'
68
- } %>
69
61
 
70
62
  <% content_for :javascripts do %>
71
63
  <script type='text/javascript'>
@@ -76,9 +68,8 @@
76
68
  return false;
77
69
  }
78
70
  var id = <%= @machine.id %>;
79
- var url = '/job_system/machines/' + id;
80
71
  jQuery.ajax({
81
- url: url,
72
+ url: id,
82
73
  type: 'POST',
83
74
  dataType: 'json',
84
75
  data: { "machine[marked_down]": 1, "terminate": true, "_method": "put" },
@@ -60,7 +60,7 @@
60
60
 
61
61
  function updateRunnerCount() {
62
62
  jQuery.ajax({
63
- url: '/job_system/machine_runners/runner_count',
63
+ url: 'job_system/machine_runners/runner_count',
64
64
  type: 'GET',
65
65
  dataType: 'json',
66
66
  success:function (data) {
@@ -73,7 +73,7 @@
73
73
 
74
74
  function updateLastCheckedScheduleAt() {
75
75
  jQuery.ajax({
76
- url: '/job_system/machines/last_checked_schedule_at',
76
+ url: 'job_system/machines/last_checked_schedule_at',
77
77
  type: 'GET',
78
78
  dataType: 'json',
79
79
  success:function (data) {
@@ -12,15 +12,23 @@ then
12
12
  cp config/database-non_primary.yml config/database.yml
13
13
  cp app/models/other/base.rb.sample app/models/other/base.rb
14
14
  cp config/initializers/naf.rb.non_primary config/initializers/naf.rb
15
- $rake naf:install:migrations naf:isolate:migrations db:create:all naf:db:migrate naf:janitor:infrastructure naf:db:test:clone_structure
15
+ $rake naf:install:migrations
16
+ $rake naf:isolate:migrations
17
+ $rake db:create:all
18
+ $rake naf:db:migrate
19
+ $rake naf:janitor:infrastructure
20
+ $rake naf:db:test:clone_structure
16
21
  else
17
22
  echo 'Testing primary database install'
18
23
  cp config/database-primary.yml config/database.yml
19
24
  cp config/initializers/naf.rb.primary config/initializers/naf.rb
20
- $rake naf:install:migrations db:create db:migrate naf:janitor:infrastructure db:test:clone_structure
25
+ $rake naf:install:migrations
26
+ $rake db:create
27
+ $rake db:migrate
28
+ $rake naf:janitor:infrastructure
29
+ $rake db:test:clone_structure
21
30
  fi
22
31
 
23
32
  cd ../..
24
33
 
25
34
  $rake spec
26
-
@@ -1,3 +1,3 @@
1
1
  module Naf
2
- VERSION = '2.1.9'
2
+ VERSION = '2.1.10'
3
3
  end
@@ -5,29 +5,29 @@ require "naf/version"
5
5
 
6
6
  # Describe your gem and declare its dependencies:
7
7
  Gem::Specification.new do |s|
8
- s.name = "naf"
8
+ s.name = 'naf'
9
9
  s.version = Naf::VERSION
10
10
  s.license = 'New BSD License'
11
- s.date = '2014-03-25'
12
- s.summary = "Creates infrastructure for a customizable and robust Postgres-backed script scheduling/running"
13
- s.description = "A cloud based distributed cron, application framework and operations console. Naf works as a distributed script running " +
14
- "system that provides scheduling, logging, alarming, machine redundancy, and the ability to set constraint during script execution"
15
- s.authors = ["Keith Gabryelski", "Leonardo Meira"]
11
+ s.date = '2014-04-15'
12
+ s.summary = 'Creates infrastructure for a customizable and robust Postgres-backed script scheduling/running'
13
+ s.description = 'A cloud based distributed cron, application framework and operations console. Naf works as a distributed script running ' +
14
+ 'system that provides scheduling, logging, alarming, machine redundancy, and the ability to set constraint during script execution'
15
+ s.authors = ['Keith Gabryelski', 'Leonardo Meira']
16
16
  s.email = ['keith@fiksu.com', 'lmeira@fiksu.com']
17
17
  s.files = `git ls-files`.split("\n")
18
18
  s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
19
19
  s.homepage = 'http://github.com/fiksu/naf'
20
20
 
21
- s.add_dependency "rails", ">= 3.2"
22
- s.add_dependency "partitioned"
23
- s.add_dependency "log4r_remote_syslog_outputter", ">= 0.0.1"
24
- s.add_dependency "jquery-rails"
21
+ s.add_dependency 'rails', '>= 3.2'
22
+ s.add_dependency 'partitioned'
23
+ s.add_dependency 'log4r_remote_syslog_outputter', '>= 0.0.1'
24
+ s.add_dependency 'jquery-rails'
25
25
  s.add_dependency 'will_paginate'
26
- s.add_dependency 'facter'
27
- s.add_development_dependency "pg"
28
- s.add_development_dependency "rspec-rails"
29
- s.add_development_dependency "factory_girl_rails", "~> 4.0.0"
26
+ s.add_dependency 'facter', '~> 1.7.5'
27
+ s.add_development_dependency 'pg'
28
+ s.add_development_dependency 'rspec-rails'
29
+ s.add_development_dependency 'factory_girl_rails', '~> 4.0.0'
30
30
  s.add_development_dependency 'awesome_print'
31
31
 
32
- s.executables = ["naf"]
32
+ s.executables = ['naf']
33
33
  end
@@ -119,6 +119,19 @@ module Naf
119
119
  end
120
120
  end
121
121
 
122
+ context "when updating the machine" do
123
+ it "should not save when enabled and deleted are true" do
124
+ bad_machine = FactoryGirl.build(:machine, enabled: true, deleted: true)
125
+ bad_machine.save.should_not be_true
126
+ bad_machine.errors.messages[:enabled].should_not be_nil
127
+ end
128
+
129
+ it "should save when enabled is true and deleted is false" do
130
+ machine = FactoryGirl.build(:machine, enabled: true, deleted: false)
131
+ machine.save.should be_true
132
+ end
133
+ end
134
+
122
135
  #----------------------
123
136
  # *** Class Methods ***
124
137
  #++++++++++++++++++++++
@@ -126,7 +139,7 @@ module Naf
126
139
  describe "#enabled" do
127
140
  before do
128
141
  machine.update_attributes!(enabled: true)
129
- FactoryGirl.create(:machine_two, enabled: false)
142
+ FactoryGirl.create(:machine_two, enabled: false, deleted: true)
130
143
  end
131
144
 
132
145
  it "return the correct machine" do
@@ -1,10 +1,25 @@
1
1
  require 'spec_helper'
2
2
 
3
3
  module Process::Naf
4
-
5
4
  describe Runner do
5
+ let!(:runner) { ::Process::Naf::Runner.new }
6
+
7
+ describe '#memory_available_to_spawn?' do
8
+ before do
9
+ Facter.should_receive(:memorysize_mb).and_return(100.0)
10
+ runner.instance_variable_set(:@minimum_memory_free, 15.0)
11
+ end
6
12
 
13
+ it 'return true when there is available memory' do
14
+ Facter.should_receive(:memoryfree_mb).and_return(20.0)
15
+ runner.memory_available_to_spawn?.should be_true
16
+ end
7
17
 
18
+ it 'return true when there is available memory' do
19
+ Facter.should_receive(:memoryfree_mb).and_return(10.0)
20
+ runner.memory_available_to_spawn?.should be_false
21
+ end
22
+ end
8
23
 
9
24
  end
10
25
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: naf
3
3
  version: !ruby/object:Gem::Version
4
- version: 2.1.9
4
+ version: 2.1.10
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -10,7 +10,7 @@ authors:
10
10
  autorequire:
11
11
  bindir: bin
12
12
  cert_chain: []
13
- date: 2014-03-25 00:00:00.000000000 Z
13
+ date: 2014-04-15 00:00:00.000000000 Z
14
14
  dependencies:
15
15
  - !ruby/object:Gem::Dependency
16
16
  name: rails
@@ -97,17 +97,17 @@ dependencies:
97
97
  requirement: !ruby/object:Gem::Requirement
98
98
  none: false
99
99
  requirements:
100
- - - ! '>='
100
+ - - ~>
101
101
  - !ruby/object:Gem::Version
102
- version: '0'
102
+ version: 1.7.5
103
103
  type: :runtime
104
104
  prerelease: false
105
105
  version_requirements: !ruby/object:Gem::Requirement
106
106
  none: false
107
107
  requirements:
108
- - - ! '>='
108
+ - - ~>
109
109
  - !ruby/object:Gem::Version
110
- version: '0'
110
+ version: 1.7.5
111
111
  - !ruby/object:Gem::Dependency
112
112
  name: pg
113
113
  requirement: !ruby/object:Gem::Requirement
@@ -278,7 +278,6 @@ files:
278
278
  - app/models/logical/naf/log_file.rb
279
279
  - app/models/logical/naf/log_parser/base.rb
280
280
  - app/models/logical/naf/log_parser/job.rb
281
- - app/models/logical/naf/log_parser/machine.rb
282
281
  - app/models/logical/naf/log_parser/runner.rb
283
282
  - app/models/logical/naf/log_reader.rb
284
283
  - app/models/logical/naf/machine.rb
@@ -371,7 +370,6 @@ files:
371
370
  - app/views/naf/log_viewer/_job_logs.html.erb
372
371
  - app/views/naf/log_viewer/_log_display.html.erb
373
372
  - app/views/naf/log_viewer/_log_layout.html.erb
374
- - app/views/naf/log_viewer/_machine_logs.html.erb
375
373
  - app/views/naf/log_viewer/_runner_logs.html.erb
376
374
  - app/views/naf/log_viewer/_search_options.html.erb
377
375
  - app/views/naf/log_viewer/_update_page_title.html.erb
@@ -1,64 +0,0 @@
1
- require 'yajl'
2
-
3
- module Logical::Naf
4
- module LogParser
5
- class Machine < Base
6
-
7
- def initialize(params)
8
- super(params)
9
- end
10
-
11
- def logs
12
- retrieve_logs
13
- end
14
-
15
- private
16
-
17
- def insert_log_line(elem)
18
- "&nbsp;&nbsp;<span>#{elem['output_time']} <font color='333399'><b>jid(#{elem['job_id']}):</b></font> #{elem['message']}</br></span>"
19
- end
20
-
21
- def sort_jsons
22
- # Sort log lines based on timestamp
23
- @jsons = jsons.sort { |x, y| Time.parse(x['output_time']) <=> Time.parse(y['output_time']) }
24
- end
25
-
26
- def parse_newest_log
27
- if newest_log.scan(/jid\(\d*\)\: /).present?
28
- newest_log.slice!(/jid\(\d*\)\: /)
29
- end
30
- newest_log
31
- end
32
-
33
- def retrieve_log_files_from_s3
34
- s3_log_reader.log_files
35
- end
36
-
37
- def get_files
38
- if log_type == 'old' && read_from_s3 == 'true'
39
- get_s3_files do
40
- @s3_log_reader = ::Logical::Naf::LogReader.new
41
- return retrieve_log_files_from_s3
42
- end
43
- else
44
- files = Dir["#{::Naf::PREFIX_PATH}/#{::Naf.schema_name}/jobs/*/*"]
45
- if files.present?
46
- # Sort log files based on time
47
- return files.sort { |x, y| Time.parse(y.scan(DATE_REGEX)[0][0]) <=> Time.parse(x.scan(DATE_REGEX)[0][0]) }
48
- else
49
- get_s3_files do
50
- @read_from_s3 = 'true'
51
- @s3_log_reader = ::Logical::Naf::LogReader.new
52
- return retrieve_log_files_from_s3
53
- end
54
- end
55
- end
56
- end
57
-
58
- def get_job_id(file)
59
- file.scan(/\d+_\d{8}/).first.split('_').first
60
- end
61
-
62
- end
63
- end
64
- end
@@ -1,62 +0,0 @@
1
- <div id='naf'>
2
- <div id="fluid">
3
- <div id='bd'>
4
- <div id="record">
5
- <FONT FACE= "Courier New">
6
- <div id="stdout" class="scrollable-output-expanded"></div>
7
- </br>
8
- <FONT FACE= "Arial">
9
-
10
- <div id="stdout_header">
11
- <div>
12
- <%= render partial: 'search_options' %>
13
- <div style="width: 100%; display: table;">
14
- <div style="display: table-row">
15
- <div style="width: 600px; display: table-cell;">
16
- <%= label_tag 'From:' %>
17
- <%= render partial: 'naf/shared/date_select', locals: { prefix: 'date_select_from', dropdown_width: 'width: 15%;' } %>
18
- </br>
19
- <%= label_tag 'To:' %>&nbsp;&nbsp;&nbsp;&nbsp;
20
- <%= render partial: 'naf/shared/date_select', locals: { prefix: 'date_select_to', dropdown_width: 'width: 15%;' } %>
21
- </div>
22
- <div style="display: table-cell;">
23
- <strong style="margin-left: 10%; size: 10%">Machine Information</strong>
24
- <table id='naf_table_show' style="margin-left: 10%; width: 75%">
25
- <thead>
26
- <tr>
27
- <td width="7%">ID</td>
28
- <td>Server</td>
29
- <td>Last Seen Alive At</td>
30
- </tr>
31
- </thead>
32
- <tbody>
33
- <tr>
34
- <td><%= @machine.id %></td>
35
- <td><%= @machine.hostname %></td>
36
- <td><%= @machine.last_seen_alive_at %></td>
37
- </tr>
38
- </tbody>
39
- </table>
40
- </div>
41
- </div>
42
- </div>
43
- </br>
44
-
45
- <%= submit_tag("Search the logs", id: 'log_search_submit') %>
46
- &nbsp;&nbsp;&nbsp;
47
- <%= link_to 'Back to Machine', { controller: 'machines', action: 'show', id: @machine.id } %>
48
- </div>
49
- </div>
50
- </div>
51
- </div>
52
- </div>
53
- </div>
54
-
55
- <%= render partial: 'update_page_title', locals: { title: "Machine(#{@machine.id}) Logs" } %>
56
- <%= render partial: 'naf/shared/auto_resize_width', locals: { div_class: '.scrollable-output-expanded' } %>
57
- <%= render partial: 'log_display',
58
- locals: {
59
- logs_url: "#{http_protocol}#{::Logical::Naf::Machine.new(@machine).runner}#{naf.logs_log_parsers_path}",
60
- record_id: @machine.id,
61
- record_type: 'machine'
62
- } %>