naf 1.1.0

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.
Files changed (295) hide show
  1. data/.gitignore +16 -0
  2. data/.rspec +1 -0
  3. data/.travis.yml +17 -0
  4. data/Gemfile +17 -0
  5. data/LICENSE +2 -0
  6. data/README.rdoc +22 -0
  7. data/RELEASE_NOTES.rdoc +18 -0
  8. data/Rakefile +43 -0
  9. data/app/assets/images/bg-grad.png +0 -0
  10. data/app/assets/images/clock.png +0 -0
  11. data/app/assets/images/control_play_blue.png +0 -0
  12. data/app/assets/images/down_arrow.gif +0 -0
  13. data/app/assets/images/papertrail_job.png +0 -0
  14. data/app/assets/images/papertrail_machine.png +0 -0
  15. data/app/assets/images/papertrail_machine_runner.png +0 -0
  16. data/app/assets/images/terminate.png +0 -0
  17. data/app/assets/images/ui-bg_flat_0_aaaaaa_40x100.png +0 -0
  18. data/app/assets/images/ui-bg_flat_0_ffffff_40x100.png +0 -0
  19. data/app/assets/images/ui-bg_flat_75_ffffff_40x100.png +0 -0
  20. data/app/assets/images/ui-bg_glass_0_f4f4f4_1x400.png +0 -0
  21. data/app/assets/images/ui-bg_glass_55_fbf9ee_1x400.png +0 -0
  22. data/app/assets/images/ui-bg_glass_65_f4f4f4_1x400.png +0 -0
  23. data/app/assets/images/ui-bg_glass_65_ffffff_1x400.png +0 -0
  24. data/app/assets/images/ui-bg_glass_75_dadada_1x400.png +0 -0
  25. data/app/assets/images/ui-bg_glass_75_e6e6e6_1x400.png +0 -0
  26. data/app/assets/images/ui-bg_glass_75_f4f4f4_1x400.png +0 -0
  27. data/app/assets/images/ui-bg_glass_95_fef1ec_1x400.png +0 -0
  28. data/app/assets/images/ui-bg_highlight-soft_0_f4f4f4_1x100.png +0 -0
  29. data/app/assets/images/ui-bg_highlight-soft_75_cccccc_1x100.png +0 -0
  30. data/app/assets/images/ui-icons_222222_256x240.png +0 -0
  31. data/app/assets/images/ui-icons_2e83ff_256x240.png +0 -0
  32. data/app/assets/images/ui-icons_454545_256x240.png +0 -0
  33. data/app/assets/images/ui-icons_888888_256x240.png +0 -0
  34. data/app/assets/images/ui-icons_cd0a0a_256x240.png +0 -0
  35. data/app/assets/images/up_arrow.gif +0 -0
  36. data/app/assets/javascripts/dataTablesTemplates/applications.js +94 -0
  37. data/app/assets/javascripts/dataTablesTemplates/jobs.js +163 -0
  38. data/app/assets/javascripts/dataTablesTemplates/machine_runner_invocations.js +60 -0
  39. data/app/assets/javascripts/dataTablesTemplates/machine_runners.js +82 -0
  40. data/app/assets/javascripts/dataTablesTemplates/machines.js +93 -0
  41. data/app/assets/javascripts/date.js +104 -0
  42. data/app/assets/javascripts/iso8601.js +41 -0
  43. data/app/assets/javascripts/jquery.dataTables.custom.js +62 -0
  44. data/app/assets/javascripts/jquery.dataTables.js +6862 -0
  45. data/app/assets/javascripts/naf.js +30 -0
  46. data/app/assets/javascripts/underscore.js +713 -0
  47. data/app/assets/stylesheets/jquery_ui/jquery-ui-1.8.5.custom.css.erb +572 -0
  48. data/app/assets/stylesheets/min_naf.css +14 -0
  49. data/app/assets/stylesheets/min_naf/layout.css.scss +355 -0
  50. data/app/assets/stylesheets/naf.css +14 -0
  51. data/app/assets/stylesheets/naf/layout.css.scss +497 -0
  52. data/app/controllers/naf/affinities_controller.rb +61 -0
  53. data/app/controllers/naf/application_controller.rb +43 -0
  54. data/app/controllers/naf/application_schedule_affinity_tabs_controller.rb +75 -0
  55. data/app/controllers/naf/applications_controller.rb +153 -0
  56. data/app/controllers/naf/historical_job_affinity_tabs_controller.rb +65 -0
  57. data/app/controllers/naf/historical_jobs_controller.rb +159 -0
  58. data/app/controllers/naf/janitorial_assignments_controller.rb +77 -0
  59. data/app/controllers/naf/logger_names_controller.rb +58 -0
  60. data/app/controllers/naf/logger_styles_controller.rb +59 -0
  61. data/app/controllers/naf/machine_affinity_slots_controller.rb +69 -0
  62. data/app/controllers/naf/machine_runner_invocations_controller.rb +59 -0
  63. data/app/controllers/naf/machine_runners_controller.rb +26 -0
  64. data/app/controllers/naf/machines_controller.rb +95 -0
  65. data/app/helpers/naf/application_helper.rb +275 -0
  66. data/app/models/log4r/papertrail_outputter.rb +19 -0
  67. data/app/models/logical/naf/application.rb +183 -0
  68. data/app/models/logical/naf/construction_zone/ad_hoc_work_order.rb +22 -0
  69. data/app/models/logical/naf/construction_zone/application_schedule_work_order.rb +15 -0
  70. data/app/models/logical/naf/construction_zone/application_work_order.rb +25 -0
  71. data/app/models/logical/naf/construction_zone/boss.rb +123 -0
  72. data/app/models/logical/naf/construction_zone/foreman.rb +53 -0
  73. data/app/models/logical/naf/construction_zone/proletariat.rb +40 -0
  74. data/app/models/logical/naf/construction_zone/work_order.rb +100 -0
  75. data/app/models/logical/naf/create_infrastructure.rb +48 -0
  76. data/app/models/logical/naf/job.rb +357 -0
  77. data/app/models/logical/naf/job_creator.rb +155 -0
  78. data/app/models/logical/naf/job_fetcher.rb +167 -0
  79. data/app/models/logical/naf/job_statuses/errored.rb +27 -0
  80. data/app/models/logical/naf/job_statuses/finished.rb +26 -0
  81. data/app/models/logical/naf/job_statuses/finished_less_minute.rb +25 -0
  82. data/app/models/logical/naf/job_statuses/queued.rb +32 -0
  83. data/app/models/logical/naf/job_statuses/running.rb +34 -0
  84. data/app/models/logical/naf/job_statuses/terminated.rb +25 -0
  85. data/app/models/logical/naf/job_statuses/waiting.rb +43 -0
  86. data/app/models/logical/naf/machine.rb +85 -0
  87. data/app/models/logical/naf/machine_runner.rb +46 -0
  88. data/app/models/logical/naf/machine_runner_invocation.rb +50 -0
  89. data/app/models/logical/naf/pickler.rb +74 -0
  90. data/app/models/logical/naf/unpickler.rb +98 -0
  91. data/app/models/naf/affinity.rb +145 -0
  92. data/app/models/naf/affinity_classification.rb +44 -0
  93. data/app/models/naf/application.rb +100 -0
  94. data/app/models/naf/application_run_group_restriction.rb +39 -0
  95. data/app/models/naf/application_schedule.rb +181 -0
  96. data/app/models/naf/application_schedule_affinity_tab.rb +86 -0
  97. data/app/models/naf/application_schedule_prerequisite.rb +50 -0
  98. data/app/models/naf/application_type.rb +72 -0
  99. data/app/models/naf/by_historical_job_id.rb +86 -0
  100. data/app/models/naf/historical_job.rb +334 -0
  101. data/app/models/naf/historical_job_affinity_tab.rb +61 -0
  102. data/app/models/naf/historical_job_prerequisite.rb +19 -0
  103. data/app/models/naf/janitorial_archive_assignment.rb +36 -0
  104. data/app/models/naf/janitorial_assignment.rb +37 -0
  105. data/app/models/naf/janitorial_create_assignment.rb +36 -0
  106. data/app/models/naf/janitorial_drop_assignment.rb +36 -0
  107. data/app/models/naf/logger_level.rb +21 -0
  108. data/app/models/naf/logger_name.rb +23 -0
  109. data/app/models/naf/logger_style.rb +58 -0
  110. data/app/models/naf/logger_style_name.rb +28 -0
  111. data/app/models/naf/machine.rb +257 -0
  112. data/app/models/naf/machine_affinity_slot.rb +78 -0
  113. data/app/models/naf/machine_runner.rb +51 -0
  114. data/app/models/naf/machine_runner_invocation.rb +71 -0
  115. data/app/models/naf/naf_base.rb +9 -0
  116. data/app/models/naf/queued_job.rb +164 -0
  117. data/app/models/naf/running_job.rb +80 -0
  118. data/app/models/process/naf/application.rb +164 -0
  119. data/app/models/process/naf/janitor.rb +117 -0
  120. data/app/models/process/naf/machine_manager.rb +150 -0
  121. data/app/models/process/naf/machine_upgrader.rb +112 -0
  122. data/app/models/process/naf/runner.rb +539 -0
  123. data/app/views/naf/affinities/_form.html.erb +50 -0
  124. data/app/views/naf/affinities/edit.html.erb +11 -0
  125. data/app/views/naf/affinities/index.html.erb +57 -0
  126. data/app/views/naf/affinities/new.html.erb +15 -0
  127. data/app/views/naf/affinities/show.html.erb +48 -0
  128. data/app/views/naf/application_schedule_affinity_tabs/_form.html.erb +31 -0
  129. data/app/views/naf/application_schedule_affinity_tabs/edit.html.erb +12 -0
  130. data/app/views/naf/application_schedule_affinity_tabs/new.html.erb +11 -0
  131. data/app/views/naf/applications/_application_schedule.html.erb +80 -0
  132. data/app/views/naf/applications/_application_schedule_prerequisites.html.erb +14 -0
  133. data/app/views/naf/applications/_form.html.erb +109 -0
  134. data/app/views/naf/applications/_search_container.html.erb +94 -0
  135. data/app/views/naf/applications/_show.html.erb +34 -0
  136. data/app/views/naf/applications/edit.html.erb +11 -0
  137. data/app/views/naf/applications/index.html.erb +51 -0
  138. data/app/views/naf/applications/index.json.erb +11 -0
  139. data/app/views/naf/applications/new.html.erb +11 -0
  140. data/app/views/naf/applications/show.html.erb +203 -0
  141. data/app/views/naf/datatable.html.erb +49 -0
  142. data/app/views/naf/historical_job_affinity_tabs/_form.html.erb +36 -0
  143. data/app/views/naf/historical_job_affinity_tabs/edit.html.erb +11 -0
  144. data/app/views/naf/historical_job_affinity_tabs/new.html.erb +11 -0
  145. data/app/views/naf/historical_jobs/_form.html.erb +94 -0
  146. data/app/views/naf/historical_jobs/_runners.html.erb +22 -0
  147. data/app/views/naf/historical_jobs/_search_container.html.erb +140 -0
  148. data/app/views/naf/historical_jobs/edit.html.erb +11 -0
  149. data/app/views/naf/historical_jobs/index.html.erb +48 -0
  150. data/app/views/naf/historical_jobs/index.json.erb +26 -0
  151. data/app/views/naf/historical_jobs/new.html.erb +61 -0
  152. data/app/views/naf/historical_jobs/show.html.erb +201 -0
  153. data/app/views/naf/janitorial_assignments/_form.html.erb +38 -0
  154. data/app/views/naf/janitorial_assignments/_rows.html.erb +17 -0
  155. data/app/views/naf/janitorial_assignments/edit.html.erb +11 -0
  156. data/app/views/naf/janitorial_assignments/index.html.erb +56 -0
  157. data/app/views/naf/janitorial_assignments/index.js.erb +1 -0
  158. data/app/views/naf/janitorial_assignments/new.html.erb +11 -0
  159. data/app/views/naf/layouts/jquery_datatables.json.erb +6 -0
  160. data/app/views/naf/logger_names/_form.html.erb +18 -0
  161. data/app/views/naf/logger_names/edit.html.erb +11 -0
  162. data/app/views/naf/logger_names/new.html.erb +11 -0
  163. data/app/views/naf/logger_names/show.html.erb +44 -0
  164. data/app/views/naf/logger_styles/_form.html.erb +30 -0
  165. data/app/views/naf/logger_styles/_logger_style_names.html.erb +19 -0
  166. data/app/views/naf/logger_styles/edit.html.erb +11 -0
  167. data/app/views/naf/logger_styles/new.html.erb +11 -0
  168. data/app/views/naf/logger_styles/show.html.erb +48 -0
  169. data/app/views/naf/machine_affinity_slots/_form.html.erb +36 -0
  170. data/app/views/naf/machine_affinity_slots/edit.html.erb +11 -0
  171. data/app/views/naf/machine_affinity_slots/new.html.erb +11 -0
  172. data/app/views/naf/machine_runner_invocations/_filter.html.erb +21 -0
  173. data/app/views/naf/machine_runner_invocations/index.html.erb +36 -0
  174. data/app/views/naf/machine_runner_invocations/index.json.erb +16 -0
  175. data/app/views/naf/machine_runner_invocations/show.html.erb +91 -0
  176. data/app/views/naf/machine_runners/index.html.erb +82 -0
  177. data/app/views/naf/machine_runners/index.json.erb +16 -0
  178. data/app/views/naf/machine_runners/show.html.erb +113 -0
  179. data/app/views/naf/machines/_filter.html.erb +26 -0
  180. data/app/views/naf/machines/_form.html.erb +62 -0
  181. data/app/views/naf/machines/_show.html.erb +169 -0
  182. data/app/views/naf/machines/edit.html.erb +11 -0
  183. data/app/views/naf/machines/index.html.erb +51 -0
  184. data/app/views/naf/machines/index.json.erb +23 -0
  185. data/app/views/naf/machines/new.html.erb +11 -0
  186. data/app/views/naf/machines/show.html.erb +92 -0
  187. data/app/views/naf/record.html.erb +46 -0
  188. data/app/views/naf/shared/_application.html.erb +50 -0
  189. data/app/views/naf/shared/_information_container.html.erb +19 -0
  190. data/app/views/naf/shared/_select_per_page.html.erb +72 -0
  191. data/ci/test-build.sh +17 -0
  192. data/ci/travis.sh +26 -0
  193. data/config/initializers/naf.rb +3 -0
  194. data/config/routes.rb +38 -0
  195. data/db/migrate/20120820023848_naf_schema.rb +413 -0
  196. data/doc/README_FOR_APP +2 -0
  197. data/lib/generators/naf_generator.rb +45 -0
  198. data/lib/generators/templates/config/logging/af.yml +26 -0
  199. data/lib/generators/templates/config/logging/naf.yml +22 -0
  200. data/lib/generators/templates/config/logging/nafjob.yml +16 -0
  201. data/lib/generators/templates/config/logging/nafrunner.yml +17 -0
  202. data/lib/generators/templates/naf.rb +11 -0
  203. data/lib/generators/templates/naf_layout.html.erb +15 -0
  204. data/lib/naf.rb +48 -0
  205. data/lib/naf/configuration.rb +23 -0
  206. data/lib/naf/engine.rb +18 -0
  207. data/lib/naf/version.rb +3 -0
  208. data/lib/tasks/naf_tasks.rake +370 -0
  209. data/naf.gemspec +30 -0
  210. data/script/rails +10 -0
  211. data/spec/controllers/naf/affinities_controller_spec.rb +79 -0
  212. data/spec/controllers/naf/application_controller_spec.rb +10 -0
  213. data/spec/controllers/naf/application_schedule_affinity_tabs_controller_spec.rb +106 -0
  214. data/spec/controllers/naf/applications_controller_spec.rb +109 -0
  215. data/spec/controllers/naf/historical_job_affinity_tabs_controller_spec.rb +96 -0
  216. data/spec/controllers/naf/historical_jobs_controller_spec.rb +19 -0
  217. data/spec/controllers/naf/machine_affinity_slots_controller_spec.rb +109 -0
  218. data/spec/controllers/naf/machines_controller_spec.rb +74 -0
  219. data/spec/dummy/.gitignore +12 -0
  220. data/spec/dummy/README +19 -0
  221. data/spec/dummy/Rakefile +7 -0
  222. data/spec/dummy/app/assets/javascripts/application.js +16 -0
  223. data/spec/dummy/app/assets/stylesheets/application.css +14 -0
  224. data/spec/dummy/app/controllers/application_controller.rb +3 -0
  225. data/spec/dummy/app/helpers/application_helper.rb +2 -0
  226. data/spec/dummy/app/models/my_script.rb +8 -0
  227. data/spec/dummy/app/models/other/base.rb.sample +10 -0
  228. data/spec/dummy/app/views/layouts/application.html.erb +15 -0
  229. data/spec/dummy/app/views/layouts/naf_layout.html.erb +15 -0
  230. data/spec/dummy/config.ru +4 -0
  231. data/spec/dummy/config/application.rb +62 -0
  232. data/spec/dummy/config/boot.rb +10 -0
  233. data/spec/dummy/config/database-non_primary.yml +20 -0
  234. data/spec/dummy/config/database-primary.yml +16 -0
  235. data/spec/dummy/config/environment.rb +5 -0
  236. data/spec/dummy/config/environments/development.rb +37 -0
  237. data/spec/dummy/config/environments/production.rb +67 -0
  238. data/spec/dummy/config/environments/test.rb +37 -0
  239. data/spec/dummy/config/initializers/backtrace_silencers.rb +7 -0
  240. data/spec/dummy/config/initializers/inflections.rb +15 -0
  241. data/spec/dummy/config/initializers/mime_types.rb +5 -0
  242. data/spec/dummy/config/initializers/naf.rb.non_primary +4 -0
  243. data/spec/dummy/config/initializers/naf.rb.primary +3 -0
  244. data/spec/dummy/config/initializers/secret_token.rb +7 -0
  245. data/spec/dummy/config/initializers/session_store.rb +8 -0
  246. data/spec/dummy/config/initializers/wrap_parameters.rb +14 -0
  247. data/spec/dummy/config/locales/en.yml +5 -0
  248. data/spec/dummy/config/logging/af.yml +26 -0
  249. data/spec/dummy/config/logging/naf.yml +22 -0
  250. data/spec/dummy/config/logging/nafjob.yml +16 -0
  251. data/spec/dummy/config/logging/nafrunner.yml +17 -0
  252. data/spec/dummy/config/routes.rb +5 -0
  253. data/spec/dummy/db/.gitignore +2 -0
  254. data/spec/dummy/lib/tasks/dummy.rake +60 -0
  255. data/spec/dummy/public/404.html +26 -0
  256. data/spec/dummy/public/422.html +26 -0
  257. data/spec/dummy/public/500.html +25 -0
  258. data/spec/dummy/public/favicon.ico +0 -0
  259. data/spec/dummy/script/rails +6 -0
  260. data/spec/factories/naf.rb +433 -0
  261. data/spec/helpers/naf/application_helper_spec.rb +0 -0
  262. data/spec/models/logical/naf/application_spec.rb +69 -0
  263. data/spec/models/logical/naf/job_creator_spec.rb +32 -0
  264. data/spec/models/logical/naf/job_fetcher_spec.rb +140 -0
  265. data/spec/models/logical/naf/job_spec.rb +282 -0
  266. data/spec/models/logical/naf/machine_spec.rb +61 -0
  267. data/spec/models/naf/affinity_classification_spec.rb +56 -0
  268. data/spec/models/naf/affinity_spec.rb +100 -0
  269. data/spec/models/naf/application_run_group_restriction_spec.rb +57 -0
  270. data/spec/models/naf/application_schedule_affinity_tab_spec.rb +85 -0
  271. data/spec/models/naf/application_schedule_prerequisite_spec.rb +35 -0
  272. data/spec/models/naf/application_schedule_spec.rb +166 -0
  273. data/spec/models/naf/application_spec.rb +128 -0
  274. data/spec/models/naf/application_type_spec.rb +104 -0
  275. data/spec/models/naf/historical_job_affinity_tab_spec.rb +59 -0
  276. data/spec/models/naf/historical_job_prerequisite_spec.rb +25 -0
  277. data/spec/models/naf/historical_job_spec.rb +334 -0
  278. data/spec/models/naf/logger_level_spec.rb +34 -0
  279. data/spec/models/naf/logger_name_spec.rb +35 -0
  280. data/spec/models/naf/logger_style_name_spec.rb +39 -0
  281. data/spec/models/naf/logger_style_spec.rb +89 -0
  282. data/spec/models/naf/machine_affinity_slot_spec.rb +77 -0
  283. data/spec/models/naf/machine_runner_invocation_spec.rb +38 -0
  284. data/spec/models/naf/machine_runner_spec.rb +37 -0
  285. data/spec/models/naf/machine_spec.rb +425 -0
  286. data/spec/models/naf/naf_base_spec.rb +14 -0
  287. data/spec/models/naf/queued_job_spec.rb +171 -0
  288. data/spec/models/naf/running_job_spec.rb +107 -0
  289. data/spec/models/process/naf/application_spec.rb +8 -0
  290. data/spec/models/process/naf/janitor_spec.rb +10 -0
  291. data/spec/models/process/naf/runner_spec.rb +10 -0
  292. data/spec/spec_helper.rb +32 -0
  293. data/spec/support/engine_routing.rb +27 -0
  294. data/spec/support/script_spec_helper.rb +58 -0
  295. metadata +590 -0
@@ -0,0 +1,25 @@
1
+ module Logical
2
+ module Naf
3
+ module JobStatuses
4
+ class Terminated
5
+
6
+ def self.all(conditions)
7
+ <<-SQL
8
+ (
9
+ SELECT
10
+ hj.*, NULL AS "historical_job_id"
11
+ FROM
12
+ "#{::Naf.schema_name}"."historical_jobs" AS hj
13
+ WHERE
14
+ hj.request_to_terminate IS TRUE AND hj.finished_at IS NULL
15
+ #{conditions}
16
+ ORDER BY
17
+ finished_at DESC NULLS LAST
18
+ )
19
+ SQL
20
+ end
21
+
22
+ end
23
+ end
24
+ end
25
+ end
@@ -0,0 +1,43 @@
1
+ module Logical
2
+ module Naf
3
+ module JobStatuses
4
+ class Waiting
5
+
6
+ def self.all(conditions)
7
+ <<-SQL
8
+ (
9
+ SELECT DISTINCT
10
+ j.*, jp."historical_job_id"
11
+ FROM
12
+ "#{::Naf.schema_name}"."historical_jobs" AS j
13
+ LEFT JOIN
14
+ "#{::Naf.schema_name}"."historical_job_prerequisites" AS jp
15
+ ON j."id" = jp."historical_job_id"
16
+ WHERE
17
+ j.finished_at is NULL AND
18
+ j.request_to_terminate = false AND
19
+ jp.historical_job_id IS NOT NULL
20
+ AND j.started_at is NULL AND
21
+ EXISTS (
22
+ SELECT
23
+ 1
24
+ FROM
25
+ "#{::Naf.schema_name}"."historical_jobs"
26
+ JOIN
27
+ "#{::Naf.schema_name}"."historical_job_prerequisites" ON
28
+ "#{::Naf.schema_name}"."historical_jobs"."id" = "#{::Naf.schema_name}"."historical_job_prerequisites"."prerequisite_historical_job_id"
29
+ WHERE
30
+ "#{::Naf.schema_name}"."historical_job_prerequisites"."historical_job_id" = jp."historical_job_id" AND
31
+ "#{::Naf.schema_name}"."historical_jobs"."finished_at" is NULL
32
+ )
33
+ #{conditions}
34
+ ORDER BY
35
+ created_at DESC
36
+ )
37
+ SQL
38
+ end
39
+
40
+ end
41
+ end
42
+ end
43
+ end
@@ -0,0 +1,85 @@
1
+ # A wrapper around Naf::Machine used for rendering in views
2
+
3
+ module Logical
4
+ module Naf
5
+ class Machine
6
+
7
+ include ActionView::Helpers::DateHelper
8
+
9
+ COLUMNS = [:id,
10
+ :server_name,
11
+ :server_address,
12
+ :server_note,
13
+ :enabled,
14
+ :process_pool_size,
15
+ :last_checked_schedules_at,
16
+ :last_seen_alive_at,
17
+ :log_level,
18
+ :affinities,
19
+ :marked_down]
20
+
21
+ def initialize(naf_machine)
22
+ @machine = naf_machine
23
+ end
24
+
25
+ def method_missing(method_name, *arguments, &block)
26
+ if @machine.respond_to?(method_name)
27
+ @machine.send(method_name, *arguments, &block)
28
+ else
29
+ super
30
+ end
31
+ end
32
+
33
+ def self.all(filter = false)
34
+ ::Naf::Machine.include_deleted(filter).all.map{ |machine| new(machine) }
35
+ end
36
+
37
+ def process_pool_size
38
+ thread_pool_size
39
+ end
40
+
41
+ def last_checked_schedules_at
42
+ if value = @machine.last_checked_schedules_at
43
+ "#{time_ago_in_words(value, true)} ago, #{value.localtime.strftime("%Y-%m-%d %r")}"
44
+ else
45
+ ""
46
+ end
47
+ end
48
+
49
+ def last_seen_alive_at
50
+ if value = @machine.last_seen_alive_at
51
+ "#{time_ago_in_words(value, true)} ago, #{value.localtime.strftime("%Y-%m-%d %r")}"
52
+ else
53
+ ""
54
+ end
55
+ end
56
+
57
+ def to_hash
58
+ Hash[COLUMNS.map{ |m| [m, send(m)] }]
59
+ end
60
+
61
+ def affinities
62
+ @machine.machine_affinity_slots.map do |slot|
63
+ if slot.affinity_short_name
64
+ slot.affinity_short_name
65
+ else
66
+ name = slot.affinity_classification_name + '_' + slot.affinity_name
67
+ name = name + '_required' if slot.required
68
+ name
69
+ end
70
+ end.join(", \n")
71
+ end
72
+
73
+ def name
74
+ if @machine.short_name
75
+ @machine.short_name
76
+ elsif @machine.server_name
77
+ @machine.server_name
78
+ else
79
+ @machine.server_address
80
+ end
81
+ end
82
+
83
+ end
84
+ end
85
+ end
@@ -0,0 +1,46 @@
1
+ # A wrapper around Naf::MachineRunner used for rendering in views
2
+
3
+ module Logical
4
+ module Naf
5
+ class MachineRunner
6
+
7
+ COLUMNS = [
8
+ 'id',
9
+ 'created_at',
10
+ 'server_name',
11
+ 'runner_cwd'
12
+ ]
13
+
14
+ def self.to_array(column, order)
15
+ machine_runners = []
16
+ order_by = COLUMNS[column].to_s + ' ' + order
17
+ ::Naf::MachineRunner.enabled.order(order_by).all.each do |runner|
18
+ values = []
19
+ runner.attributes.each do |key, value|
20
+ if key == 'created_at'
21
+ values << value.to_s
22
+ else
23
+ values << value
24
+ end
25
+ end
26
+
27
+ invocation = runner.machine_runner_invocations.last
28
+ values << invocation.id
29
+ values << invocation.pid
30
+ values << invocation.status.gsub('-', ' ').split.map(&:capitalize).join(' ')
31
+
32
+ values << ::Naf::HistoricalJob.
33
+ joins("inner join #{::Naf.schema_name}.running_jobs nj on nj.id = #{::Naf.schema_name}.historical_jobs.id").
34
+ joins(:machine_runner_invocation).
35
+ where("#{::Naf.schema_name}.machine_runner_invocations.machine_runner_id = ?", runner.id).count
36
+ values << ''
37
+
38
+ machine_runners << values
39
+ end
40
+
41
+ machine_runners
42
+ end
43
+
44
+ end
45
+ end
46
+ end
@@ -0,0 +1,50 @@
1
+ # A wrapper around Naf::MachineRunnerInvocation used for rendering in views
2
+
3
+ module Logical
4
+ module Naf
5
+ class MachineRunnerInvocation
6
+
7
+ COLUMNS = [
8
+ 'id',
9
+ 'created_at',
10
+ 'machine_runner_id',
11
+ 'server_name',
12
+ 'pid',
13
+ 'status',
14
+ 'commit_information',
15
+ 'deployment_tag',
16
+ 'repository_name'
17
+ ]
18
+
19
+ def self.to_array(column, order, filter)
20
+ machine_runner_invocations = []
21
+ order_by = COLUMNS[column].to_s + ' ' + order
22
+
23
+ if order_by =~ /status/
24
+ order_by = "dead_at #{order}, wind_down_at #{order}"
25
+ end
26
+
27
+ ::Naf::MachineRunnerInvocation.joins(machine_runner: :machine).choose(filter).order(order_by).all.each do |invocation|
28
+ values = []
29
+ invocation_hash = invocation.attributes
30
+ COLUMNS.each do |key|
31
+ if key == 'created_at'
32
+ values << invocation_hash[key].to_s
33
+ elsif key == 'server_name'
34
+ machine_runner = ::Naf::MachineRunner.find_by_id(invocation_hash['machine_runner_id'])
35
+ values << [machine_runner.machine.id, ::Logical::Naf::Machine.new(machine_runner.machine).name.to_s]
36
+ elsif key == 'status'
37
+ values << invocation.status.gsub('-', ' ').split.map(&:capitalize).join(' ')
38
+ else
39
+ values << invocation_hash[key]
40
+ end
41
+ end
42
+ machine_runner_invocations << values
43
+ end
44
+
45
+ machine_runner_invocations
46
+ end
47
+
48
+ end
49
+ end
50
+ end
@@ -0,0 +1,74 @@
1
+ module ::Logical::Naf
2
+ class Pickler
3
+ include ::Af::Application::Component
4
+
5
+ create_proxy_logger
6
+ attr_reader :preserves,
7
+ :preservables,
8
+ :naf_version,
9
+ :context
10
+
11
+ def initialize(naf_version, preservables)
12
+ @preservables = preservables
13
+ @naf_version = naf_version
14
+ @preserves = {}
15
+ @context = {}
16
+ end
17
+
18
+ def generic_pickle(instance, associations = nil, ignored_attributes = [:created_at, :updated_at])
19
+ instance_attributes = instance.attributes.symbolize_keys
20
+ ignored_attributes.each do |ignored_attribute|
21
+ instance_attributes.delete(ignored_attribute.to_sym)
22
+ end
23
+
24
+ unless associations
25
+ associations = {}
26
+ instance_attributes.keys.select{|key| key.to_s =~ /_id$/}.each do |key|
27
+ association_name = key.to_s[0..-4].to_sym
28
+ association = instance.association(association_name) rescue nil
29
+ if association
30
+ associations[key] = association.options[:class_name].constantize.name
31
+ end
32
+ end
33
+ end
34
+
35
+ return Hash[instance_attributes.map { |key,value|
36
+ if associations[key]
37
+ [key, { association_model_name: associations[key], association_value: value }]
38
+ else
39
+ [key,value]
40
+ end
41
+ } ]
42
+ end
43
+
44
+ def preserve
45
+ @preservables.each do |model|
46
+ preserve_model(model)
47
+ end
48
+ end
49
+
50
+ def preserve_model(model)
51
+ if model.respond_to?(:pickleables)
52
+ pickables = model.pickleables(self)
53
+ else
54
+ pickables = model.all
55
+ end
56
+
57
+ @preserves[model.name] = pickables.map do |instance|
58
+ if instance.respond_to?(:pickle)
59
+ instance.pickle(self)
60
+ else
61
+ generic_pickle(instance)
62
+ end
63
+ end
64
+ end
65
+
66
+ def pickle_jar
67
+ {
68
+ version: @naf_version,
69
+ preserved_at: Time.now,
70
+ preserves: @preserves
71
+ }
72
+ end
73
+ end
74
+ end
@@ -0,0 +1,98 @@
1
+ module ::Logical::Naf
2
+ class Unpickler
3
+ include ::Af::Application::Component
4
+
5
+ create_proxy_logger
6
+ attr_reader :preserves,
7
+ :preservables,
8
+ :input_version,
9
+ :references,
10
+ :context
11
+
12
+ def initialize(preserves, preservables, input_version)
13
+ @preserves = preserves
14
+ @preservables = preservables
15
+ @input_version = input_version
16
+ @references = {}
17
+ @context = {}
18
+ end
19
+
20
+ def cache_all_models(model)
21
+ references.merge!(Hash[model.all.map do |m|
22
+ logger.detail "caching: #{m.inspect}"
23
+ [{ association_model_name: model.name, association_value: m.id }, m]
24
+ end
25
+ ])
26
+ end
27
+
28
+ def retrieve_reference(reference)
29
+ references[reference.symbolize_keys]
30
+ end
31
+
32
+ def generic_unpickle(model, preserve, id_method_name = :id)
33
+ if references[{ association_model_name: model.name, association_value: preserve[id_method_name.to_s] }]
34
+ return {}
35
+ end
36
+
37
+ attributes = {}
38
+
39
+ reference_methods = []
40
+ preserve.each do |method_name, value|
41
+ id_method = method_name.to_sym
42
+ unless id_method_name == id_method
43
+ if value.is_a?(Hash)
44
+ # this is a reference
45
+ reference_instance = retrieve_reference(value)
46
+ if reference_instance.nil?
47
+ logger.error value.inspect
48
+ logger.error { references.map{|r| r.inspect}.join("\n") }
49
+ logger.error { references.map{ |r| r.inspect }.join("\n") }
50
+ raise "couldn't find reference for #{value.inspect} in #{preserve.inspect}"
51
+ end
52
+ attributes[method_name.to_sym] = reference_instance.id
53
+ else
54
+ attributes[method_name.to_sym] = value
55
+ end
56
+ end
57
+ end
58
+
59
+ instance = model.new
60
+ attributes.each do |method, value|
61
+ instance.send("#{method}=".to_sym, value)
62
+ end
63
+ instance.save!
64
+ logger.info "created #{instance.inspect}"
65
+
66
+ return { { association_model_name: model.name,
67
+ association_value: preserve[id_method_name.to_s] } => instance }
68
+ end
69
+
70
+ def reconstitute
71
+ preservables.each do |model|
72
+ if model.respond_to?(:pre_unpickle)
73
+ model.pre_unpickle(self)
74
+ else
75
+ cache_all_models(model)
76
+ end
77
+ end
78
+
79
+ preservables.each do |model|
80
+ model_preserves = preserves[model.name]
81
+ if model_preserves
82
+ model_preserves.each do |model_preserve|
83
+ if model.respond_to?(:unpickle)
84
+ additional_references = model.unpickle(model_preserve, self)
85
+ else
86
+ additional_references = generic_unpickle(model, model_preserve)
87
+ end
88
+ references.merge!(additional_references)
89
+ end
90
+ end
91
+ end
92
+
93
+ preservables.each do |model|
94
+ model.post_unpickle(self) if model.respond_to?(:post_unpickle)
95
+ end
96
+ end
97
+ end
98
+ end
@@ -0,0 +1,145 @@
1
+ module Naf
2
+ class Affinity < NafBase
3
+ # Protect from mass-assignment issue
4
+ attr_accessible :affinity_classification_id,
5
+ :affinity_name,
6
+ :selectable,
7
+ :affinity_short_name,
8
+ :affinity_note
9
+
10
+ #---------------------
11
+ # *** Associations ***
12
+ #+++++++++++++++++++++
13
+
14
+ belongs_to :affinity_classification,
15
+ class_name: '::Naf::AffinityClassification'
16
+ has_many :application_schedule_affinity_tabs,
17
+ class_name: '::Naf::ApplicationScheduleAffinityTab',
18
+ dependent: :destroy
19
+ has_many :machine_affinity_slots,
20
+ class_name: '::Naf::MachineAffinitySlot',
21
+ dependent: :destroy
22
+
23
+ #--------------------
24
+ # *** Validations ***
25
+ #++++++++++++++++++++
26
+
27
+ validates :affinity_classification_id,
28
+ :affinity_name, presence: true
29
+ validates :affinity_name, length: { minimum: 1 }
30
+ validates :affinity_short_name, uniqueness: true,
31
+ allow_blank: true,
32
+ allow_nil: true,
33
+ format: {
34
+ with: /^[a-zA-Z_][a-zA-Z0-9_]*$/,
35
+ message: 'letters should be first'
36
+ }
37
+
38
+ before_save :check_blank_values
39
+
40
+ #--------------------
41
+ # *** Delegations ***
42
+ #++++++++++++++++++++
43
+
44
+ delegate :affinity_classification_name, to: :affinity_classification
45
+
46
+ #----------------------
47
+ # *** Class Methods ***
48
+ #++++++++++++++++++++++
49
+
50
+ def self.selectable
51
+ where(selectable: true)
52
+ end
53
+
54
+ def self.pre_unpickle(unpickler)
55
+ unpickler.references.merge!(Hash[::Naf::Affinity.all.map do |m|
56
+ [{ association_model_name: ::Naf::Affinity.name,
57
+ association_classification_value: m.affinity_classification_id,
58
+ association_affinity_value: m.affinity_name }, m]
59
+ end
60
+ ])
61
+ end
62
+
63
+ def self.unpickle(preserve, unpickler)
64
+ reference = unpickler.references[{ association_model_name: self.name,
65
+ association_classification_value: preserve['affinity_classification_id']['association_value'],
66
+ association_affinity_value: preserve['affinity_name'] }]
67
+ if reference.present?
68
+ return {}
69
+ end
70
+
71
+ attributes = {}
72
+ reference_methods = []
73
+ preserve.each do |method_name, value|
74
+ unless method_name == 'id'
75
+ if value.is_a?(Hash)
76
+ # this is a reference
77
+ reference_instance = unpickler.retrieve_reference(value)
78
+ if reference_instance.nil?
79
+ logger.error value.inspect
80
+ logger.error { unpickler.references.map{ |r| r.inspect }.join("\n") }
81
+ raise "couldn't find reference for #{value.inspect} in #{preserve.inspect}"
82
+ end
83
+ attributes[method_name.to_sym] = reference_instance.id
84
+ else
85
+ attributes[method_name.to_sym] = value
86
+ end
87
+ end
88
+ end
89
+
90
+ instance = self.new
91
+ attributes.each do |method, value|
92
+ instance.send("#{method}=".to_sym, value)
93
+ end
94
+ instance.save!
95
+ logger.info "created #{instance.inspect}"
96
+
97
+ return { { association_model_name: self.name,
98
+ association_classification_value: preserve['affinity_classification_id']['association_value'],
99
+ association_affinity_value: preserve['affinity_name'] } => instance }
100
+ end
101
+
102
+ #-------------------------
103
+ # *** Instance Methods ***
104
+ #+++++++++++++++++++++++++
105
+
106
+ def to_s
107
+ components = []
108
+ components << "UNSELECTABLE" unless selectable
109
+ components << "classification: \"#{affinity_classification_name}\""
110
+ components << "name: \"#{affinity_name}\""
111
+
112
+ return "::Naf::Affinity<#{components.join(', ')}>"
113
+ end
114
+
115
+ def validate_affinity_name
116
+ if affinity_classification.present? &&
117
+ affinity_classification.affinity_classification_name == 'machine'
118
+
119
+ machine = ::Naf::Machine.find_by_id(affinity_name)
120
+ if machine.blank?
121
+ return "There isn't a machine with that id!"
122
+ end
123
+
124
+ count = ::Naf::Affinity.
125
+ where(affinity_classification_id: ::Naf::AffinityClassification.
126
+ find_by_affinity_classification_name('machine').id,
127
+ affinity_name: machine.id.to_s).count
128
+
129
+ if count > 0
130
+ return 'An affinity with the pair value (affinity_classification_id, affinity_name) already exists!'
131
+ end
132
+ end
133
+
134
+ nil
135
+ end
136
+
137
+ private
138
+
139
+ def check_blank_values
140
+ self.affinity_short_name = nil if self.affinity_short_name.blank?
141
+ self.affinity_note = nil if self.affinity_note.blank?
142
+ end
143
+
144
+ end
145
+ end