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,164 @@
1
+ require 'log4r/formatter/patternformatter'
2
+
3
+ module Process::Naf
4
+ class Application < ::Af::Application
5
+ class TerminationRequest < StandardError
6
+ attr_reader :job, :reason
7
+ def initialize(job, reason)
8
+ @job = job
9
+ @reason = reason
10
+ super("Requested to terminate: #{reason}")
11
+ end
12
+ end
13
+
14
+ #----------------
15
+ # *** Options ***
16
+ #+++++++++++++++++
17
+
18
+ opt :naf_job_id,
19
+ "#{::Naf.schema_name}.historical_jobs.id for communication with scheduling system",
20
+ env: "NAF_JOB_ID",
21
+ type: :int
22
+ opt :do_not_terminate,
23
+ "refuse to terminate by job and machine IPC mechanics"
24
+
25
+ def initialize
26
+ super
27
+ opt :log_configuration_files, default: ["af.yml",
28
+ "af-#{Rails.env}.yml",
29
+ "naf.yml",
30
+ "naf-#{Rails.env}.yml",
31
+ "nafjob.yml",
32
+ "nafjob-#{Rails.env}.yml",
33
+ "#{af_name}.yml",
34
+ "#{af_name}-#{Rails.env}.yml"]
35
+ end
36
+
37
+ def database_application_name
38
+ return "//pid=#{Process.pid}/jid=#{@naf_job_id}/#{af_name}"
39
+ end
40
+
41
+ def fetch_naf_job
42
+ if @naf_job_id.is_a?(Integer) && @naf_job_id > 0
43
+ return ::Naf::HistoricalJob.from_partition(@naf_job_id).find(@naf_job_id)
44
+ end
45
+ return nil
46
+ end
47
+
48
+ def post_command_line_parsing
49
+ super
50
+ Af::Logging::Configurator.log_ignore_configuration = (naf_job_id.blank? && Af::Logging::Configurator.log_console != false)
51
+ end
52
+
53
+ def pre_work
54
+ set_connection_application_name(database_application_name)
55
+
56
+ Log4r::GDC.set(naf_job_id.to_s)
57
+
58
+ super
59
+
60
+ update_job_status
61
+ end
62
+
63
+ def update_job_status
64
+ periodic_application_checkpoint
65
+
66
+ job = fetch_naf_job
67
+ if job
68
+ unless @do_not_terminate
69
+ if job.request_to_terminate
70
+ logger.warn "terminating by request"
71
+ raise TerminationRequest.new(job, "job requested to terminate")
72
+ end
73
+ unless job.started_on_machine
74
+ logger.alarm "terminating: #{job.started_on_machine} is misconfigured"
75
+ raise TerminationRequest.new(job, "machine not configured correctly")
76
+ end
77
+ unless job.started_on_machine.enabled
78
+ logger.alarm "terminating: #{job.started_on_machine} is disabled"
79
+ raise TerminationRequest.new(job, "machine disabled")
80
+ end
81
+ if job.started_on_machine.marked_down
82
+ logger.alarm "terminating: #{job.started_on_machine} is marked down"
83
+ raise TerminationRequest.new(job, "machine marked down")
84
+ end
85
+ end
86
+ if job.log_level != @last_log_level
87
+ @last_log_level = job.log_level
88
+ unless @last_log_level.blank?
89
+ logging_configurator.parse_and_set_logger_levels(@last_log_level)
90
+ end
91
+ end
92
+ end
93
+ end
94
+
95
+ def job_tag_block(*tags, &block)
96
+ job = fetch_naf_job
97
+ begin
98
+ if job
99
+ add_job_tags(*tags)
100
+ end
101
+ yield if block.present?
102
+ ensure
103
+ if job
104
+ remove_job_tags(*tags)
105
+ end
106
+ end
107
+ end
108
+
109
+ def update_job_tags(old_tags, new_tags)
110
+ job = fetch_naf_job
111
+ if job
112
+ job.remove_tags(old_tags.map(&:to_s))
113
+ job.add_tags(new_tags.map(&:to_s))
114
+ end
115
+ end
116
+
117
+ def add_job_tags(*new_tags)
118
+ update_job_tags([], new_tags)
119
+ end
120
+
121
+ def remove_job_tags(*old_tags)
122
+ update_job_tags(old_tags, [])
123
+ end
124
+
125
+ def work
126
+ end
127
+
128
+ module Component
129
+ def self.included(base)
130
+ base.send(:include, ::Af::Application::Component)
131
+ base.extend(ClassMethods)
132
+ end
133
+
134
+ module ClassMethods
135
+ # XXX not used yet
136
+ end
137
+
138
+ def fetch_naf_job
139
+ return af_application.try(:fetch_naf_job)
140
+ end
141
+
142
+ def update_job_status
143
+ return af_application.try(:update_job_status)
144
+ end
145
+
146
+ def job_tag_block(*tags, &block)
147
+ return af_application.try(:job_tag_block, *tags, &block)
148
+ end
149
+
150
+ def update_job_tags(old_tags, new_tags)
151
+ return af_application.try(:update_job_tags, old_tags, new_tags)
152
+ end
153
+
154
+ def add_job_tags(*new_tags)
155
+ return af_application.try(:add_job_tags, *new_tags)
156
+ end
157
+
158
+ def remove_job_tags(*old_tags)
159
+ return af_application.try(:remove_job_tags, *old_tags)
160
+ end
161
+ end
162
+
163
+ end
164
+ end
@@ -0,0 +1,117 @@
1
+ module Process::Naf
2
+ class Janitor < ::Process::Naf::Application
3
+ ASSIGNMENTS = {
4
+ creates: ::Naf::JanitorialCreateAssignment,
5
+ archives: ::Naf::JanitorialArchiveAssignment,
6
+ drops: ::Naf::JanitorialDropAssignment
7
+ }
8
+ ASSIGNMENT_TYPES = ASSIGNMENTS.keys
9
+
10
+ #----------------
11
+ # *** Options ***
12
+ #+++++++++++++++++
13
+
14
+ opt :no_writes,
15
+ "don't modify database"
16
+ opt :list_assignments,
17
+ "list models that would be processed (and exit without processing)",
18
+ short: :L
19
+
20
+ # the following three opt are in specific order because the last sets the default
21
+ opt :all,
22
+ "process all models",
23
+ short: :a,
24
+ var: :assignments,
25
+ set: :all
26
+ opt :assignment,
27
+ "process specific assignment(s)",
28
+ short: :j,
29
+ var: :assignments,
30
+ type: :ints
31
+ opt :all_enabled,
32
+ "process all enabled models",
33
+ short: :E,
34
+ var: :assignments,
35
+ set: :all_enabled,
36
+ default: :all_enabled
37
+
38
+ # the following two opt are in specific order because the last sets the default
39
+ opt :all_types,
40
+ "process all assignment types",
41
+ short: :A,
42
+ var: :assignment_types,
43
+ set: ASSIGNMENT_TYPES
44
+ opt :assignment_type,
45
+ "process specific assignment types(s)",
46
+ short: :t,
47
+ var: :assignment_types,
48
+ type: :choices,
49
+ choices: ASSIGNMENT_TYPES,
50
+ default: ASSIGNMENT_TYPES
51
+ opt :create_infrastructure,
52
+ "create infrastructure for a given model",
53
+ type: :strings
54
+
55
+ def assignments_to_process(assignment_type = ::Naf::JanitorialAssignment)
56
+ if @assignments == :all
57
+ return assignment_type.all.order('type,assignment_order')
58
+ elsif @assignments == :all_enabled
59
+ return assignment_type.where('enabled').order('type,assignment_order')
60
+ else
61
+ return [*assignment_type.find(@assignments).order('type,assignment_order')]
62
+ end
63
+ end
64
+
65
+ def post_command_line_parsing
66
+ if @list_assignments
67
+ assignment_list = [["ID", "TYPE", "ORDER", "MODEL"]]
68
+ [:creates, :archives, :drops].each do |assignment_type_name|
69
+ unless @assignment_types.include? assignment_type_name
70
+ next
71
+ end
72
+ assignment_type_processor = ASSIGNMENTS[assignment_type_name]
73
+ assignments_to_process(assignment_type_processor).each do |a|
74
+ assignment_list << [a.id.to_s, a.type.to_s, a.assignment_order.to_s, a.model_name]
75
+ end
76
+ end
77
+ puts self.class.columnized(assignment_list).join("\n")
78
+ exit 0
79
+ end
80
+ unless @create_infrastructure.blank?
81
+ logger.info "creating infrastructure: #{@create_infrastructure.inspect}"
82
+ ::Logical::Naf::CreateInfrastructure.new(@create_infrastructure).work
83
+ exit 0
84
+ end
85
+ super
86
+ end
87
+
88
+ def work
89
+ logger.info "Janitor STARTED -- let's see what there is to do."
90
+
91
+ # assignment types are handled in this order
92
+ [:creates, :archives, :drops].each do |assignment_type_name|
93
+ unless @assignment_types.include? assignment_type_name
94
+ next
95
+ end
96
+ assignment_type_processor = ASSIGNMENTS[assignment_type_name]
97
+ assignments_to_process(assignment_type_processor).each do |assignment|
98
+ logger.info "#{assignment_type_processor}: #{assignment.model_name} START"
99
+ target_model = assignment.target_model
100
+ if target_model.nil?
101
+ logger.alarm "#{assignment_type_processor}: failed to instantiate target model: #{assignment.model_name}"
102
+ next
103
+ end
104
+ begin
105
+ assignment_type_processor.new.do_janitorial_work(target_model) unless @no_writes
106
+ rescue StandardError => e
107
+ logger.alarm "failed to use #{assignment_type_processor} for partitions model: #{assignment.model_name}"
108
+ logger.alarm e
109
+ end
110
+ logger.info "#{assignment_type_processor}: #{assignment.model_name} DONE"
111
+ end
112
+ end
113
+
114
+ logger.info "janitor DONE"
115
+ end
116
+ end
117
+ end
@@ -0,0 +1,150 @@
1
+ module Process::Naf
2
+ class MachineManager < ::Process::Naf::Application
3
+ opt :server_name, "set the machines server name (use with --update-machine)", type: :string
4
+ opt :server_note, "set the machines server note (use with --update-machine)", type: :string
5
+ opt :server_address, "set the machines server address (use with --update-machine)", default: ::Naf::Machine.machine_ip_address
6
+ opt :update_machine, "create or update an machine entry"
7
+ opt :enabled, "enable machine"
8
+ opt :disabled, "disable machine", var: :enabled, set: :false
9
+ opt :thread_pool_size, "how many scripts can run at once", type: :int
10
+ opt :list_affinities, "show all affinities"
11
+ opt :add_affinities, "add an affinity slot", type: :strings
12
+ opt :add_weight_affinities, "add afffinity weights for cpu and memory", default: true
13
+
14
+ def work
15
+ if @list_affinities
16
+ puts "Affinities:"
17
+ ::Naf::Affinity.all.each do |affinity|
18
+ parts = [
19
+ affinity.affinity_classification_name,
20
+ affinity.affinity_name,
21
+ ]
22
+ puts " #{parts.join('_')}"
23
+ end
24
+ exit 0
25
+ end
26
+
27
+ if @update_machine
28
+ machine = ::Naf::Machine.find_by_server_address(@server_address)
29
+ if machine.blank?
30
+ machine = ::Naf::Machine.create(server_address: @server_address)
31
+ add_default_affinities(machine)
32
+ end
33
+
34
+ machine.server_note = @server_note unless @server_note.nil?
35
+ machine.server_name = @server_name unless @server_name.nil?
36
+ machine.enabled = @enabled unless @enabled.nil?
37
+ machine.thread_pool_size = @thread_pool_size unless @thread_pool_size.nil?
38
+ machine.save!
39
+ else
40
+ machine = ::Naf::Machine.find_by_server_address(@server_address)
41
+
42
+ unless machine.present?
43
+ puts "Machine address #{@server_address} is not present -- use --update-machine"
44
+ exit 1
45
+ end
46
+ end
47
+
48
+ if @add_affinities
49
+ @add_affinities.each do |affinity_string|
50
+ #
51
+ # Parse the argument string. It should consists of 2 or 3 words separated
52
+ # by underscores.
53
+ #
54
+ # Example:
55
+ # - location_1_required
56
+ # - purpose_large
57
+ #
58
+ parts = affinity_string.split('_')
59
+ if parts.length == 2
60
+ classification_name = parts[0]
61
+ affinity_name = parts[1]
62
+ required = false
63
+ elsif parts.length == 3
64
+ classification_name = parts[0]
65
+ affinity_name = parts[1]
66
+ required = true
67
+ else
68
+ puts "no idea how to interpret affinity classification in: '#{affinity_string}'"
69
+ exit 1
70
+ end
71
+
72
+ # Find the Affinity Classification in the Database
73
+ affinity_classification = ::Naf::AffinityClassification.
74
+ find_by_affinity_classification_name(classification_name)
75
+ unless affinity_classification
76
+ puts "could not find affinity classification: '#{classification_name}'"
77
+ exit 1
78
+ end
79
+
80
+ # Find the Affinity in the Database
81
+ affinity = ::Naf::Affinity.
82
+ find_by_affinity_classification_id_and_affinity_name(affinity_classification.id,
83
+ affinity_name)
84
+ unless affinity
85
+ puts "could not find affinity: '#{affinity_name}' with classification: '#{classification_name}'"
86
+ exit 1
87
+ end
88
+
89
+ # Create an affinity slot for the machine
90
+ machine.machine_affinity_slots.create(affinity_id: affinity.id,
91
+ required: required)
92
+ end
93
+ end
94
+
95
+ puts "Address: #{machine.server_address}"
96
+ puts "Name: #{machine.server_name}" unless machine.server_name.nil?
97
+ puts "Note: #{machine.server_note}" unless machine.server_note.nil?
98
+ puts "Enabled: #{machine.enabled}"
99
+ puts "Thread Pool Size: #{machine.thread_pool_size}"
100
+
101
+ if machine.affinities.empty?
102
+ puts "No machine affinity slots"
103
+ else
104
+ puts "Machine Affinity Slots:"
105
+ machine.machine_affinity_slots.each do |affinity_slot|
106
+ affinity = affinity_slot.affinity
107
+ parts = [
108
+ affinity.affinity_classification_name,
109
+ affinity.affinity_name,
110
+ ]
111
+ parts << "required" if affinity_slot.required
112
+ puts " #{parts.join('_')}"
113
+ end
114
+ end
115
+ end
116
+
117
+ private
118
+
119
+ def add_default_affinities(machine)
120
+ # Add Machine Affinity
121
+ classification = ::Naf::AffinityClassification.machine.id
122
+ affinity = ::Naf::Affinity.
123
+ find_or_create_by_affinity_classification_id_and_affinity_name(classification, machine.id.to_s)
124
+ machine.machine_affinity_slots.create(affinity_id: affinity.id)
125
+
126
+ if machine == ::Naf::Machine.current
127
+ # Add Purpose Affinity
128
+ instance_type = `source /var/spool/ec2/meta-data.sh && echo $EC2_INSTANCE_TYPE`
129
+ if instance_type.present?
130
+ classification = ::Naf::AffinityClassification.purpose.id
131
+ affinity = ::Naf::Affinity.
132
+ find_or_create_by_affinity_classification_id_and_affinity_name(classification, instance_type)
133
+ machine.machine_affinity_slots.create(affinity_id: affinity.id)
134
+ end
135
+
136
+ # Add Weight Affinity
137
+ classification = ::Naf::AffinityClassification.weight.id
138
+ machine_cpus = (`cat /proc/cpuinfo | grep processor | wc -l`).strip.to_i
139
+ machine_memory = (`cat /proc/meminfo | grep MemTotal`).slice(/\d+/).to_i / (1024 * 1024)
140
+ cpu_affinity = ::Naf::Affinity.
141
+ find_or_create_by_affinity_classification_id_and_affinity_name(classification, 'cpus')
142
+ memory_affinity = ::Naf::Affinity.
143
+ find_or_create_by_affinity_classification_id_and_affinity_name(classification, 'memory')
144
+ machine.machine_affinity_slots.create(affinity_id: cpu_affinity.id, affinity_parameter: machine_cpus)
145
+ machine.machine_affinity_slots.create(affinity_id: memory_affinity.id, affinity_parameter: machine_memory)
146
+ end
147
+ end
148
+
149
+ end
150
+ end
@@ -0,0 +1,112 @@
1
+ require 'naf/version'
2
+
3
+ module Process::Naf
4
+ class MachineUpgrader < ::Process::Naf::Application
5
+ opt :upgrade_option,
6
+ "what should we do",
7
+ default: :dump,
8
+ choices: [:dump, :restore]
9
+ opt :pretty,
10
+ "make things pretty",
11
+ default: false
12
+ opt :no_updates,
13
+ "don't update the db (via transaction rollback)",
14
+ default: false
15
+ opt :force,
16
+ "run even if system looks unclean",
17
+ default: false
18
+
19
+ PRESERVABLES = [
20
+ ::Naf::ApplicationType,
21
+ ::Naf::Application,
22
+ ::Naf::ApplicationRunGroupRestriction,
23
+ ::Naf::ApplicationSchedule,
24
+ ::Naf::ApplicationSchedulePrerequisite,
25
+ ::Naf::AffinityClassification,
26
+ ::Naf::Affinity,
27
+ ::Naf::ApplicationScheduleAffinityTab,
28
+ ::Naf::LoggerLevel,
29
+ ::Naf::LoggerName,
30
+ ::Naf::LoggerStyle,
31
+ ::Naf::LoggerStyleName,
32
+ ::Naf::Machine,
33
+ ::Naf::MachineAffinitySlot,
34
+ ::Naf::JanitorialAssignment
35
+ ]
36
+
37
+ CLEAN_SYSTEM_MODELS = [
38
+ ::Naf::Machine,
39
+ ::Naf::VERSION == '1.0.3' ? ::Naf::HistoricalJob : ::Naf::Job
40
+ ]
41
+
42
+
43
+ def work
44
+ self.send("work_#{@upgrade_option}")
45
+ end
46
+
47
+ def work_dump
48
+ pickler = ::Logical::Naf::Pickler.new(::Naf::VERSION, PRESERVABLES)
49
+ pickler.preserve
50
+ if @pretty
51
+ puts JSON.pretty_generate(pickler.pickle_jar)
52
+ else
53
+ puts JSON.generate(pickler.pickle_jar)
54
+ end
55
+ end
56
+
57
+ def work_restore
58
+ begin
59
+ pickle_jar = JSON.parse(STDIN.read)
60
+ rescue StandardError => e
61
+ logger.fatal "this doesn't look like a naf upgrade stream to me, it is not json parserable!"
62
+ exit 1
63
+ end
64
+
65
+ unless pickle_jar.is_a?(Hash)
66
+ logger.fatal "this doesn't look like a naf upgrade stream to me, it is of type: #{pickle_jar.class.name}"
67
+ exit 1
68
+ end
69
+
70
+ pickle_jar_version = pickle_jar['version']
71
+ if pickle_jar_version.blank?
72
+ logger.fatal "this doesn't look like a naf upgrade stream to me, it has no version!"
73
+ exit 1
74
+ end
75
+
76
+ preserves = pickle_jar['preserves']
77
+ if preserves.nil?
78
+ logger.fatal "this doesn't look like a naf upgrade stream to me, there are no preserves!"
79
+ exit 1
80
+ end
81
+
82
+ unless preserves.is_a?(Hash)
83
+ logger.fatal "this doesn't look like a naf upgrade stream to me, the preserves are type: #{preserves.class.name}"
84
+ exit 1
85
+ end
86
+
87
+ check_for_clean_system unless @force
88
+
89
+ preserved_at_text = pickle_jar['preserved_at']
90
+ preserved_at = Time.parse(preserved_at_text) rescue "unknown"
91
+
92
+ logger.info "restoring:"
93
+ logger.info " preserved_at: #{preserved_at}"
94
+ logger.info " version: #{pickle_jar_version}"
95
+ logger.info " models: #{preserves.length}"
96
+
97
+ unpickler = ::Logical::Naf::Unpickler.new(preserves, PRESERVABLES, pickle_jar_version)
98
+ ::Naf::NafBase.transaction do
99
+ unpickler.reconstitute
100
+ raise ActiveRecord::Rollback if @no_updates
101
+ end
102
+ logger.info "restoration complete! thank you!"
103
+ end
104
+
105
+ def check_for_clean_system
106
+ CLEAN_SYSTEM_MODELS.each do |model|
107
+ raise "the system is unclean" if model.count > 0
108
+ end
109
+ end
110
+
111
+ end
112
+ end