Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse files

Initial commit of munki server

- Server is (probably) functional
- A few things don't quite work
- Server is version-less right now (probably should add a version number soon)
  • Loading branch information...
commit e431c7c5b67c6379dab9a51382898a04b10a0c9e 0 parents
Jordan Raine authored
Showing with 25,331 additions and 0 deletions.
  1. +8 −0 .gitignore
  2. +31 −0 Gemfile
  3. +4 −0 ISSUES
  4. 0  LAST_TIME_WE...
  5. +243 −0 README
  6. +10 −0 Rakefile
  7. +42 −0 app/controllers/application_controller.rb
  8. +70 −0 app/controllers/bundles_controller.rb
  9. +9 −0 app/controllers/catalogs_controller.rb
  10. +70 −0 app/controllers/computer_groups_controller.rb
  11. +105 −0 app/controllers/computers_controller.rb
  12. +90 −0 app/controllers/packages_controller.rb
  13. +38 −0 app/controllers/sessions_controller.rb
  14. +21 −0 app/controllers/unit_settings_controller.rb
  15. +66 −0 app/controllers/units_controller.rb
  16. +21 −0 app/controllers/user_settings_controller.rb
  17. +65 −0 app/controllers/users_controller.rb
  18. +2 −0  app/helpers/ajax_helper.rb
  19. +274 −0 app/helpers/application_helper.rb
  20. +2 −0  app/helpers/bundle_helper.rb
  21. +2 −0  app/helpers/catalogs_helper.rb
  22. +2 −0  app/helpers/computer_groups_helper.rb
  23. +40 −0 app/helpers/computers_helper.rb
  24. +2 −0  app/helpers/groups_helper.rb
  25. +171 −0 app/helpers/packages_helper.rb
  26. +2 −0  app/helpers/pkgs_helper.rb
  27. +2 −0  app/helpers/pkgsinfo_categories_helper.rb
  28. +36 −0 app/helpers/repos_helper.rb
  29. +2 −0  app/helpers/settings_helper.rb
  30. +2 −0  app/helpers/units_helper.rb
  31. +2 −0  app/helpers/users_helper.rb
  32. +13 −0 app/models/catalog.rb
  33. +8 −0 app/models/computer_model.rb
  34. +45 −0 app/models/environment.rb
  35. +24 −0 app/models/icon.rb
  36. +4 −0 app/models/join_models/bundle_item.rb
  37. +3 −0  app/models/join_models/install_item.rb
  38. +20 −0 app/models/join_models/membership.rb
  39. +3 −0  app/models/join_models/require_item.rb
  40. +3 −0  app/models/join_models/uninstall_item.rb
  41. +3 −0  app/models/join_models/update_for_item.rb
  42. +3 −0  app/models/join_models/user_allowed_item.rb
  43. +3 −0  app/models/join_models/user_install_item.rb
  44. +3 −0  app/models/join_models/user_uninstall_item.rb
  45. +30 −0 app/models/magic_mixin/item.rb
  46. +231 −0 app/models/magic_mixin/manifest.rb
  47. +35 −0 app/models/magic_mixin/unit_member.rb
  48. +3 −0  app/models/manifest/bundle.rb
  49. +36 −0 app/models/manifest/computer.rb
  50. +7 −0 app/models/manifest/computer_group.rb
  51. +467 −0 app/models/package.rb
  52. +131 −0 app/models/package_branch.rb
  53. +21 −0 app/models/package_category.rb
  54. +41 −0 app/models/plutil.rb
  55. +121 −0 app/models/service/computer_service.rb
  56. +121 −0 app/models/service/manifest_service.rb
  57. +43 −0 app/models/service/package_service.rb
  58. +32 −0 app/models/service/unit_service.rb
  59. +81 −0 app/models/unit.rb
  60. +23 −0 app/models/unit_setting.rb
  61. +88 −0 app/models/user.rb
  62. +13 −0 app/models/user_setting.rb
  63. +3 −0  app/models/version_tracker.rb
  64. +20 −0 app/views/bundles/edit.html.erb
  65. +12 −0 app/views/bundles/import.html.erb
  66. +27 −0 app/views/bundles/index.html.erb
  67. +17 −0 app/views/bundles/new.html.erb
  68. +12 −0 app/views/bundles/show.html.erb
  69. +13 −0 app/views/computer_groups/edit.html.erb
  70. +28 −0 app/views/computer_groups/index.html.erb
  71. +13 −0 app/views/computer_groups/new.html.erb
  72. +14 −0 app/views/computer_groups/show.html.erb
  73. +2 −0  app/views/computers/_computer_group_link.rhtml
  74. +61 −0 app/views/computers/_computer_listing.html.erb
  75. +30 −0 app/views/computers/_edit_computer_form.html.erb
  76. +11 −0 app/views/computers/_import.html.erb
  77. +6 −0 app/views/computers/edit.html.erb
  78. +25 −0 app/views/computers/import.html.erb
  79. +23 −0 app/views/computers/index.html.erb
  80. +2 −0  app/views/computers/index.js.erb
  81. +36 −0 app/views/computers/new.html.erb
  82. +20 −0 app/views/computers/show.html.erb
  83. +133 −0 app/views/layouts/application.html.erb
  84. +50 −0 app/views/layouts/sessions.html.erb
  85. +8 −0 app/views/sessions/new.html.erb
  86. +4 −0 app/views/shared/AS WE GO NOTES
  87. +12 −0 app/views/shared/_autocomplete_asmselect.rhtml
  88. +19 −0 app/views/shared/_bundle_list.html.erb
  89. +11 −0 app/views/shared/_extra_info_box.html.erb
  90. +11 −0 app/views/shared/_hash_checkboxes.html.erb
  91. +21 −0 app/views/shared/_inventory.html.erb
  92. +6 −0 app/views/shared/_pkg_list.html.erb
  93. +8 −0 app/views/shared/_record_header.rhtml
  94. +4 −0 app/views/shared/_sidebar.rhtml
  95. +9 −0 app/views/shared/_units_menu.rhtml
  96. +17 −0 app/views/unit_settings/edit.html.erb
  97. +3 −0  app/views/units/_edit_members.html.erb
  98. +4 −0 app/views/units/_member.html.erb
  99. +11 −0 app/views/units/edit.html.erb
  100. +22 −0 app/views/units/index.html.erb
  101. +15 −0 app/views/units/new.html.erb
  102. +2 −0  app/views/units/no_access.html.erb
  103. +13 −0 app/views/units/show.html.erb
  104. +11 −0 app/views/user_settings/edit.html.erb
  105. +30 −0 app/views/users/edit.html.erb
  106. +21 −0 app/views/users/index.html.erb
  107. +23 −0 app/views/users/new.html.erb
  108. +21 −0 app/views/users/show.html.erb
  109. +4 −0 config.ru
  110. +58 −0 config/application.rb
  111. +17 −0 config/boot.rb
  112. +22 −0 config/database.yml
  113. +5 −0 config/environment.rb
  114. +19 −0 config/environments/development.rb
  115. +33 −0 config/environments/production.rb
  116. +29 −0 config/environments/test.rb
  117. +31 −0 config/initializers/LocalFile.rb
  118. +57 −0 config/initializers/active_record.rb
  119. +7 −0 config/initializers/backtrace_silencers.rb
  120. +7 −0 config/initializers/cookie_verification_secret.rb
  121. +9 −0 config/initializers/def_each.rb
  122. +9 −0 config/initializers/extend_string.rb
  123. +10 −0 config/initializers/inflections.rb
  124. +5 −0 config/initializers/mime_types.rb
  125. +15 −0 config/initializers/session_store.rb
  126. +31 −0 config/initializers/to_yaml.rb
  127. +5 −0 config/locales/en.yml
  128. +80 −0 config/routes.rb
  129. +14 −0 db/migrate/20100301224607_create_package_branches.rb
  130. +16 −0 db/migrate/20100301224616_create_install_items.rb
  131. +16 −0 db/migrate/20100301224617_create_require_items.rb
  132. +16 −0 db/migrate/20100301224618_create_uninstall_items.rb
  133. +16 −0 db/migrate/20100301224619_create_update_for_items.rb
  134. +16 −0 db/migrate/20100301224620_create_user_allowed_items.rb
  135. +16 −0 db/migrate/20100301224621_create_user_install_items.rb
  136. +16 −0 db/migrate/20100301224622_create_user_uninstall_items.rb
  137. +57 −0 db/migrate/20100301224624_create_packages.rb
  138. +22 −0 db/migrate/20100310211930_create_computers.rb
  139. +20 −0 db/migrate/20100311223133_create_bundles.rb
  140. +17 −0 db/migrate/20100312173823_create_units.rb
  141. +15 −0 db/migrate/20100312181907_create_environments.rb
  142. +14 −0 db/migrate/20100317160345_create_computer_models.rb
  143. +18 −0 db/migrate/20100317160854_create_computer_groups.rb
  144. +37 −0 db/migrate/20100323212823_create_memberships.rb
  145. +17 −0 db/migrate/20100323214847_create_users.rb
  146. +15 −0 db/migrate/20100324153404_create_bundle_items.rb
  147. +19 −0 db/migrate/20100324230111_create_unit_settings.rb
  148. +14 −0 db/migrate/20100324234259_create_user_settings.rb
  149. +15 −0 db/migrate/20100325001619_create_version_trackers.rb
  150. +19 −0 db/migrate/20100330234407_create_icons.rb
  151. +15 −0 db/migrate/20100507220559_create_package_categories.rb
  152. +273 −0 db/schema.rb
  153. +7 −0 db/seeds.rb
  154. +2 −0  doc/README_FOR_APP
  155. +19 −0 gem/bin/memcached_top
  156. +19 −0 gem/bin/minitar
  157. +19 −0 gem/bin/rails
  158. +19 −0 gem/bin/rdebug
  159. BIN  gem/cache/actionmailer-3.0.0.beta.gem
  160. BIN  gem/cache/actionpack-3.0.0.beta.gem
  161. BIN  gem/cache/activemodel-3.0.0.beta.gem
  162. BIN  gem/cache/activerecord-3.0.0.beta.gem
  163. BIN  gem/cache/activeresource-3.0.0.beta.gem
  164. BIN  gem/cache/activesupport-3.0.0.beta.gem
  165. BIN  gem/cache/archive-tar-minitar-0.5.2.gem
  166. BIN  gem/cache/arel-0.2.1.gem
  167. BIN  gem/cache/columnize-0.3.1.gem
  168. BIN  gem/cache/linecache19-0.5.11.gem
  169. BIN  gem/cache/mail-2.1.5.3.gem
  170. BIN  gem/cache/memcache-client-1.8.3.gem
  171. BIN  gem/cache/plist-3.1.0.gem
  172. BIN  gem/cache/rack-mount-0.4.7.gem
  173. BIN  gem/cache/rails-3.0.0.beta.gem
  174. BIN  gem/cache/railties-3.0.0.beta.gem
  175. BIN  gem/cache/ruby-debug-base19-0.11.23.gem
  176. BIN  gem/cache/ruby-debug19-0.11.6.gem
  177. BIN  gem/cache/ruby_core_source-0.1.4.gem
  178. BIN  gem/cache/sqlite3-ruby-1.2.5.gem
  179. BIN  gem/cache/will_paginate-3.0.pre.gem
  180. +384 −0 gem/gems/actionmailer-3.0.0.beta/CHANGELOG
  181. +21 −0 gem/gems/actionmailer-3.0.0.beta/MIT-LICENSE
  182. +167 −0 gem/gems/actionmailer-3.0.0.beta/README
  183. +57 −0 gem/gems/actionmailer-3.0.0.beta/lib/action_mailer.rb
  184. +26 −0 gem/gems/actionmailer-3.0.0.beta/lib/action_mailer/adv_attr_accessor.rb
  185. +616 −0 gem/gems/actionmailer-3.0.0.beta/lib/action_mailer/base.rb
  186. +36 −0 gem/gems/actionmailer-3.0.0.beta/lib/action_mailer/collector.rb
  187. +86 −0 gem/gems/actionmailer-3.0.0.beta/lib/action_mailer/delivery_methods.rb
  188. +139 −0 gem/gems/actionmailer-3.0.0.beta/lib/action_mailer/deprecated_api.rb
  189. +29 −0 gem/gems/actionmailer-3.0.0.beta/lib/action_mailer/mail_helper.rb
  190. +248 −0 gem/gems/actionmailer-3.0.0.beta/lib/action_mailer/old_api.rb
  191. +64 −0 gem/gems/actionmailer-3.0.0.beta/lib/action_mailer/quoting.rb
  192. +25 −0 gem/gems/actionmailer-3.0.0.beta/lib/action_mailer/railtie.rb
  193. +20 −0 gem/gems/actionmailer-3.0.0.beta/lib/action_mailer/railties/subscriber.rb
  194. +62 −0 gem/gems/actionmailer-3.0.0.beta/lib/action_mailer/test_case.rb
  195. +67 −0 gem/gems/actionmailer-3.0.0.beta/lib/action_mailer/test_helper.rb
  196. +34 −0 gem/gems/actionmailer-3.0.0.beta/lib/action_mailer/tmail_compat.rb
  197. +9 −0 gem/gems/actionmailer-3.0.0.beta/lib/action_mailer/version.rb
  198. +5,201 −0 gem/gems/actionpack-3.0.0.beta/CHANGELOG
  199. +21 −0 gem/gems/actionpack-3.0.0.beta/MIT-LICENSE
  200. +400 −0 gem/gems/actionpack-3.0.0.beta/README
  201. +22 −0 gem/gems/actionpack-3.0.0.beta/lib/abstract_controller.rb
  202. +191 −0 gem/gems/actionpack-3.0.0.beta/lib/abstract_controller/base.rb
  203. +113 −0 gem/gems/actionpack-3.0.0.beta/lib/abstract_controller/callbacks.rb
  204. +30 −0 gem/gems/actionpack-3.0.0.beta/lib/abstract_controller/collector.rb
  205. +18 −0 gem/gems/actionpack-3.0.0.beta/lib/abstract_controller/compatibility.rb
  206. +163 −0 gem/gems/actionpack-3.0.0.beta/lib/abstract_controller/helpers.rb
  207. +413 −0 gem/gems/actionpack-3.0.0.beta/lib/abstract_controller/layouts.rb
  208. +49 −0 gem/gems/actionpack-3.0.0.beta/lib/abstract_controller/localized_cache.rb
  209. +13 −0 gem/gems/actionpack-3.0.0.beta/lib/abstract_controller/logger.rb
  210. +238 −0 gem/gems/actionpack-3.0.0.beta/lib/abstract_controller/rendering.rb
  211. +13 −0 gem/gems/actionpack-3.0.0.beta/lib/abstract_controller/translation.rb
  212. +79 −0 gem/gems/actionpack-3.0.0.beta/lib/action_controller.rb
  213. +93 −0 gem/gems/actionpack-3.0.0.beta/lib/action_controller/base.rb
  214. +84 −0 gem/gems/actionpack-3.0.0.beta/lib/action_controller/caching.rb
  215. +163 −0 gem/gems/actionpack-3.0.0.beta/lib/action_controller/caching/actions.rb
  216. +118 −0 gem/gems/actionpack-3.0.0.beta/lib/action_controller/caching/fragments.rb
  217. +158 −0 gem/gems/actionpack-3.0.0.beta/lib/action_controller/caching/pages.rb
  218. +97 −0 gem/gems/actionpack-3.0.0.beta/lib/action_controller/caching/sweeping.rb
  219. +5 −0 gem/gems/actionpack-3.0.0.beta/lib/action_controller/deprecated.rb
  220. +28 −0 gem/gems/actionpack-3.0.0.beta/lib/action_controller/deprecated/dispatcher.rb
  221. +2 −0  gem/gems/actionpack-3.0.0.beta/lib/action_controller/deprecated/integration_test.rb
  222. +1 −0  gem/gems/actionpack-3.0.0.beta/lib/action_controller/deprecated/performance_test.rb
  223. +125 −0 gem/gems/actionpack-3.0.0.beta/lib/action_controller/metal.rb
  224. +141 −0 gem/gems/actionpack-3.0.0.beta/lib/action_controller/metal/compatibility.rb
  225. +86 −0 gem/gems/actionpack-3.0.0.beta/lib/action_controller/metal/conditional_get.rb
  226. +28 −0 gem/gems/actionpack-3.0.0.beta/lib/action_controller/metal/configuration.rb
  227. +17 −0 gem/gems/actionpack-3.0.0.beta/lib/action_controller/metal/cookies.rb
  228. +46 −0 gem/gems/actionpack-3.0.0.beta/lib/action_controller/metal/exceptions.rb
  229. +28 −0 gem/gems/actionpack-3.0.0.beta/lib/action_controller/metal/flash.rb
  230. +33 −0 gem/gems/actionpack-3.0.0.beta/lib/action_controller/metal/head.rb
  231. +116 −0 gem/gems/actionpack-3.0.0.beta/lib/action_controller/metal/helpers.rb
  232. +50 −0 gem/gems/actionpack-3.0.0.beta/lib/action_controller/metal/hide_actions.rb
  233. +312 −0 gem/gems/actionpack-3.0.0.beta/lib/action_controller/metal/http_authentication.rb
  234. +99 −0 gem/gems/actionpack-3.0.0.beta/lib/action_controller/metal/instrumentation.rb
  235. +300 −0 gem/gems/actionpack-3.0.0.beta/lib/action_controller/metal/mime_responds.rb
  236. +35 −0 gem/gems/actionpack-3.0.0.beta/lib/action_controller/metal/rack_delegation.rb
  237. +90 −0 gem/gems/actionpack-3.0.0.beta/lib/action_controller/metal/redirecting.rb
  238. +95 −0 gem/gems/actionpack-3.0.0.beta/lib/action_controller/metal/renderers.rb
  239. +69 −0 gem/gems/actionpack-3.0.0.beta/lib/action_controller/metal/rendering.rb
  240. +115 −0 gem/gems/actionpack-3.0.0.beta/lib/action_controller/metal/request_forgery_protection.rb
  241. +13 −0 gem/gems/actionpack-3.0.0.beta/lib/action_controller/metal/rescue.rb
  242. +220 −0 gem/gems/actionpack-3.0.0.beta/lib/action_controller/metal/responder.rb
  243. +45 −0 gem/gems/actionpack-3.0.0.beta/lib/action_controller/metal/session_management.rb
  244. +182 −0 gem/gems/actionpack-3.0.0.beta/lib/action_controller/metal/streaming.rb
  245. +42 −0 gem/gems/actionpack-3.0.0.beta/lib/action_controller/metal/testing.rb
  246. +157 −0 gem/gems/actionpack-3.0.0.beta/lib/action_controller/metal/url_for.rb
  247. +130 −0 gem/gems/actionpack-3.0.0.beta/lib/action_controller/metal/verification.rb
  248. +38 −0 gem/gems/actionpack-3.0.0.beta/lib/action_controller/middleware.rb
  249. +183 −0 gem/gems/actionpack-3.0.0.beta/lib/action_controller/polymorphic_routes.rb
  250. +30 −0 gem/gems/actionpack-3.0.0.beta/lib/action_controller/railtie.rb
  251. +63 −0 gem/gems/actionpack-3.0.0.beta/lib/action_controller/railties/subscriber.rb
  252. +91 −0 gem/gems/actionpack-3.0.0.beta/lib/action_controller/record_identifier.rb
  253. +347 −0 gem/gems/actionpack-3.0.0.beta/lib/action_controller/test_case.rb
  254. +76 −0 gem/gems/actionpack-3.0.0.beta/lib/action_controller/url_rewriter.rb
  255. +20 −0 gem/gems/actionpack-3.0.0.beta/lib/action_controller/vendor/html-scanner.rb
  256. +68 −0 gem/gems/actionpack-3.0.0.beta/lib/action_controller/vendor/html-scanner/html/document.rb
  257. +537 −0 gem/gems/actionpack-3.0.0.beta/lib/action_controller/vendor/html-scanner/html/node.rb
  258. +176 −0 gem/gems/actionpack-3.0.0.beta/lib/action_controller/vendor/html-scanner/html/sanitizer.rb
  259. +828 −0 gem/gems/actionpack-3.0.0.beta/lib/action_controller/vendor/html-scanner/html/selector.rb
  260. +105 −0 gem/gems/actionpack-3.0.0.beta/lib/action_controller/vendor/html-scanner/html/tokenizer.rb
  261. +11 −0 gem/gems/actionpack-3.0.0.beta/lib/action_controller/vendor/html-scanner/html/version.rb
  262. +88 −0 gem/gems/actionpack-3.0.0.beta/lib/action_dispatch.rb
  263. +123 −0 gem/gems/actionpack-3.0.0.beta/lib/action_dispatch/http/cache.rb
  264. +98 −0 gem/gems/actionpack-3.0.0.beta/lib/action_dispatch/http/filter_parameters.rb
  265. +33 −0 gem/gems/actionpack-3.0.0.beta/lib/action_dispatch/http/headers.rb
  266. +101 −0 gem/gems/actionpack-3.0.0.beta/lib/action_dispatch/http/mime_negotiation.rb
  267. +231 −0 gem/gems/actionpack-3.0.0.beta/lib/action_dispatch/http/mime_type.rb
  268. +23 −0 gem/gems/actionpack-3.0.0.beta/lib/action_dispatch/http/mime_types.rb
  269. +49 −0 gem/gems/actionpack-3.0.0.beta/lib/action_dispatch/http/parameters.rb
  270. +223 −0 gem/gems/actionpack-3.0.0.beta/lib/action_dispatch/http/request.rb
  271. +209 −0 gem/gems/actionpack-3.0.0.beta/lib/action_dispatch/http/response.rb
  272. +48 −0 gem/gems/actionpack-3.0.0.beta/lib/action_dispatch/http/upload.rb
  273. +129 −0 gem/gems/actionpack-3.0.0.beta/lib/action_dispatch/http/url.rb
  274. +50 −0 gem/gems/actionpack-3.0.0.beta/lib/action_dispatch/middleware/callbacks.rb
  275. +29 −0 gem/gems/actionpack-3.0.0.beta/lib/action_dispatch/middleware/cascade.rb
  276. +216 −0 gem/gems/actionpack-3.0.0.beta/lib/action_dispatch/middleware/cookies.rb
  277. +174 −0 gem/gems/actionpack-3.0.0.beta/lib/action_dispatch/middleware/flash.rb
  278. +18 −0 gem/gems/actionpack-3.0.0.beta/lib/action_dispatch/middleware/head.rb
  279. +78 −0 gem/gems/actionpack-3.0.0.beta/lib/action_dispatch/middleware/params_parser.rb
  280. +26 −0 gem/gems/actionpack-3.0.0.beta/lib/action_dispatch/middleware/rescue.rb
  281. +209 −0 gem/gems/actionpack-3.0.0.beta/lib/action_dispatch/middleware/session/abstract_store.rb
  282. +236 −0 gem/gems/actionpack-3.0.0.beta/lib/action_dispatch/middleware/session/cookie_store.rb
  283. +47 −0 gem/gems/actionpack-3.0.0.beta/lib/action_dispatch/middleware/session/mem_cache_store.rb
  284. +173 −0 gem/gems/actionpack-3.0.0.beta/lib/action_dispatch/middleware/show_exceptions.rb
  285. +129 −0 gem/gems/actionpack-3.0.0.beta/lib/action_dispatch/middleware/stack.rb
  286. +44 −0 gem/gems/actionpack-3.0.0.beta/lib/action_dispatch/middleware/static.rb
  287. +31 −0 gem/gems/actionpack-3.0.0.beta/lib/action_dispatch/middleware/templates/rescues/_request_and_response.erb
  288. +26 −0 gem/gems/actionpack-3.0.0.beta/lib/action_dispatch/middleware/templates/rescues/_trace.erb
  289. +10 −0 gem/gems/actionpack-3.0.0.beta/lib/action_dispatch/middleware/templates/rescues/diagnostics.erb
  290. +29 −0 gem/gems/actionpack-3.0.0.beta/lib/action_dispatch/middleware/templates/rescues/layout.erb
  291. +2 −0  gem/gems/actionpack-3.0.0.beta/lib/action_dispatch/middleware/templates/rescues/missing_template.erb
  292. +10 −0 gem/gems/actionpack-3.0.0.beta/lib/action_dispatch/middleware/templates/rescues/routing_error.erb
  293. +21 −0 gem/gems/actionpack-3.0.0.beta/lib/action_dispatch/middleware/templates/rescues/template_error.erb
  294. +2 −0  gem/gems/actionpack-3.0.0.beta/lib/action_dispatch/middleware/templates/rescues/unknown_action.erb
  295. +15 −0 gem/gems/actionpack-3.0.0.beta/lib/action_dispatch/railtie.rb
  296. +217 −0 gem/gems/actionpack-3.0.0.beta/lib/action_dispatch/routing.rb
  297. +877 −0 gem/gems/actionpack-3.0.0.beta/lib/action_dispatch/routing/deprecated_mapper.rb
  298. +649 −0 gem/gems/actionpack-3.0.0.beta/lib/action_dispatch/routing/mapper.rb
  299. +55 −0 gem/gems/actionpack-3.0.0.beta/lib/action_dispatch/routing/route.rb
  300. +445 −0 gem/gems/actionpack-3.0.0.beta/lib/action_dispatch/routing/route_set.rb
Sorry, we could not display the entire diff because too many files (1,789) changed.
8 .gitignore
@@ -0,0 +1,8 @@
+.bundle
+*.DS_Store
+packages
+gem.old
+public/icons
+db/*.sqlite3
+log/*.log
+tmp/**/*
31 Gemfile
@@ -0,0 +1,31 @@
+# Edit this Gemfile to bundle your application's dependencies.
+source 'http://gemcutter.org'
+
+
+gem "rails", "3.0.0.beta3"
+
+## Bundle edge rails:
+# gem "rails", :git => "git://github.com/rails/rails.git"
+
+# ActiveRecord requires a database adapter. By default,
+# Rails has selected sqlite3.
+gem "sqlite3-ruby", :require => "sqlite3"
+
+## Bundle the gems you use:
+# gem "bj"
+# gem "hpricot", "0.6"
+# gem "sqlite3-ruby", :require => "sqlite3"
+# gem "aws-s3", :require => "aws/s3"
+gem "plist", "3.1.0"
+gem "will_paginate", "3.0.pre"
+# Used for ACLs (NOT IMPLEMENTED!)
+# gem "declarative_authorization"
+
+## Bundle gems used only in certain environments:
+# gem "rspec", :group => :test
+# group :test do
+# gem "webrat"
+# end
+group :development do
+ gem "ruby-debug19" , :require => "ruby-debug"
+end
4 ISSUES
@@ -0,0 +1,4 @@
+Issues with the current release
+===
+
+- Installs GUI/text doesn't work in Package#edit
0  LAST_TIME_WE...
No changes.
243 README
@@ -0,0 +1,243 @@
+== Welcome to Rails
+
+Rails is a web-application framework that includes everything needed to create
+database-backed web applications according to the Model-View-Control pattern.
+
+This pattern splits the view (also called the presentation) into "dumb" templates
+that are primarily responsible for inserting pre-built data in between HTML tags.
+The model contains the "smart" domain objects (such as Account, Product, Person,
+Post) that holds all the business logic and knows how to persist themselves to
+a database. The controller handles the incoming requests (such as Save New Account,
+Update Product, Show Post) by manipulating the model and directing data to the view.
+
+In Rails, the model is handled by what's called an object-relational mapping
+layer entitled Active Record. This layer allows you to present the data from
+database rows as objects and embellish these data objects with business logic
+methods. You can read more about Active Record in
+link:files/vendor/rails/activerecord/README.html.
+
+The controller and view are handled by the Action Pack, which handles both
+layers by its two parts: Action View and Action Controller. These two layers
+are bundled in a single package due to their heavy interdependence. This is
+unlike the relationship between the Active Record and Action Pack that is much
+more separate. Each of these packages can be used independently outside of
+Rails. You can read more about Action Pack in
+link:files/vendor/rails/actionpack/README.html.
+
+
+== Getting Started
+
+1. At the command prompt, start a new Rails application using the <tt>rails</tt> command
+ and your application name. Ex: rails myapp
+2. Change directory into myapp and start the web server: <tt>script/server</tt> (run with --help for options)
+3. Go to http://localhost:3000/ and get "Welcome aboard: You're riding the Rails!"
+4. Follow the guidelines to start developing your application
+
+
+== Web Servers
+
+By default, Rails will try to use Mongrel if it's are installed when started with script/server, otherwise Rails will use WEBrick, the webserver that ships with Ruby. But you can also use Rails
+with a variety of other web servers.
+
+Mongrel is a Ruby-based webserver with a C component (which requires compilation) that is
+suitable for development and deployment of Rails applications. If you have Ruby Gems installed,
+getting up and running with mongrel is as easy as: <tt>gem install mongrel</tt>.
+More info at: http://mongrel.rubyforge.org
+
+Say other Ruby web servers like Thin and Ebb or regular web servers like Apache or LiteSpeed or
+Lighttpd or IIS. The Ruby web servers are run through Rack and the latter can either be setup to use
+FCGI or proxy to a pack of Mongrels/Thin/Ebb servers.
+
+== Apache .htaccess example for FCGI/CGI
+
+# General Apache options
+AddHandler fastcgi-script .fcgi
+AddHandler cgi-script .cgi
+Options +FollowSymLinks +ExecCGI
+
+# If you don't want Rails to look in certain directories,
+# use the following rewrite rules so that Apache won't rewrite certain requests
+#
+# Example:
+# RewriteCond %{REQUEST_URI} ^/notrails.*
+# RewriteRule .* - [L]
+
+# Redirect all requests not available on the filesystem to Rails
+# By default the cgi dispatcher is used which is very slow
+#
+# For better performance replace the dispatcher with the fastcgi one
+#
+# Example:
+# RewriteRule ^(.*)$ dispatch.fcgi [QSA,L]
+RewriteEngine On
+
+# If your Rails application is accessed via an Alias directive,
+# then you MUST also set the RewriteBase in this htaccess file.
+#
+# Example:
+# Alias /myrailsapp /path/to/myrailsapp/public
+# RewriteBase /myrailsapp
+
+RewriteRule ^$ index.html [QSA]
+RewriteRule ^([^.]+)$ $1.html [QSA]
+RewriteCond %{REQUEST_FILENAME} !-f
+RewriteRule ^(.*)$ dispatch.cgi [QSA,L]
+
+# In case Rails experiences terminal errors
+# Instead of displaying this message you can supply a file here which will be rendered instead
+#
+# Example:
+# ErrorDocument 500 /500.html
+
+ErrorDocument 500 "<h2>Application error</h2>Rails application failed to start properly"
+
+
+== Debugging Rails
+
+Sometimes your application goes wrong. Fortunately there are a lot of tools that
+will help you debug it and get it back on the rails.
+
+First area to check is the application log files. Have "tail -f" commands running
+on the server.log and development.log. Rails will automatically display debugging
+and runtime information to these files. Debugging info will also be shown in the
+browser on requests from 127.0.0.1.
+
+You can also log your own messages directly into the log file from your code using
+the Ruby logger class from inside your controllers. Example:
+
+ class WeblogController < ActionController::Base
+ def destroy
+ @weblog = Weblog.find(params[:id])
+ @weblog.destroy
+ logger.info("#{Time.now} Destroyed Weblog ID ##{@weblog.id}!")
+ end
+ end
+
+The result will be a message in your log file along the lines of:
+
+ Mon Oct 08 14:22:29 +1000 2007 Destroyed Weblog ID #1
+
+More information on how to use the logger is at http://www.ruby-doc.org/core/
+
+Also, Ruby documentation can be found at http://www.ruby-lang.org/ including:
+
+* The Learning Ruby (Pickaxe) Book: http://www.ruby-doc.org/docs/ProgrammingRuby/
+* Learn to Program: http://pine.fm/LearnToProgram/ (a beginners guide)
+
+These two online (and free) books will bring you up to speed on the Ruby language
+and also on programming in general.
+
+
+== Debugger
+
+Debugger support is available through the debugger command when you start your Mongrel or
+Webrick server with --debugger. This means that you can break out of execution at any point
+in the code, investigate and change the model, AND then resume execution!
+You need to install ruby-debug to run the server in debugging mode. With gems, use 'gem install ruby-debug'
+Example:
+
+ class WeblogController < ActionController::Base
+ def index
+ @posts = Post.find(:all)
+ debugger
+ end
+ end
+
+So the controller will accept the action, run the first line, then present you
+with a IRB prompt in the server window. Here you can do things like:
+
+ >> @posts.inspect
+ => "[#<Post:0x14a6be8 @attributes={\"title\"=>nil, \"body\"=>nil, \"id\"=>\"1\"}>,
+ #<Post:0x14a6620 @attributes={\"title\"=>\"Rails you know!\", \"body\"=>\"Only ten..\", \"id\"=>\"2\"}>]"
+ >> @posts.first.title = "hello from a debugger"
+ => "hello from a debugger"
+
+...and even better is that you can examine how your runtime objects actually work:
+
+ >> f = @posts.first
+ => #<Post:0x13630c4 @attributes={"title"=>nil, "body"=>nil, "id"=>"1"}>
+ >> f.
+ Display all 152 possibilities? (y or n)
+
+Finally, when you're ready to resume execution, you enter "cont"
+
+
+== Console
+
+You can interact with the domain model by starting the console through <tt>script/console</tt>.
+Here you'll have all parts of the application configured, just like it is when the
+application is running. You can inspect domain models, change values, and save to the
+database. Starting the script without arguments will launch it in the development environment.
+Passing an argument will specify a different environment, like <tt>script/console production</tt>.
+
+To reload your controllers and models after launching the console run <tt>reload!</tt>
+
+== dbconsole
+
+You can go to the command line of your database directly through <tt>script/dbconsole</tt>.
+You would be connected to the database with the credentials defined in database.yml.
+Starting the script without arguments will connect you to the development database. Passing an
+argument will connect you to a different database, like <tt>script/dbconsole production</tt>.
+Currently works for mysql, postgresql and sqlite.
+
+== Description of Contents
+
+app
+ Holds all the code that's specific to this particular application.
+
+app/controllers
+ Holds controllers that should be named like weblogs_controller.rb for
+ automated URL mapping. All controllers should descend from ApplicationController
+ which itself descends from ActionController::Base.
+
+app/models
+ Holds models that should be named like post.rb.
+ Most models will descend from ActiveRecord::Base.
+
+app/views
+ Holds the template files for the view that should be named like
+ weblogs/index.html.erb for the WeblogsController#index action. All views use eRuby
+ syntax.
+
+app/views/layouts
+ Holds the template files for layouts to be used with views. This models the common
+ header/footer method of wrapping views. In your views, define a layout using the
+ <tt>layout :default</tt> and create a file named default.html.erb. Inside default.html.erb,
+ call <% yield %> to render the view using this layout.
+
+app/helpers
+ Holds view helpers that should be named like weblogs_helper.rb. These are generated
+ for you automatically when using script/generate for controllers. Helpers can be used to
+ wrap functionality for your views into methods.
+
+config
+ Configuration files for the Rails environment, the routing map, the database, and other dependencies.
+
+db
+ Contains the database schema in schema.rb. db/migrate contains all
+ the sequence of Migrations for your schema.
+
+doc
+ This directory is where your application documentation will be stored when generated
+ using <tt>rake doc:app</tt>
+
+lib
+ Application specific libraries. Basically, any kind of custom code that doesn't
+ belong under controllers, models, or helpers. This directory is in the load path.
+
+public
+ The directory available for the web server. Contains subdirectories for images, stylesheets,
+ and javascripts. Also contains the dispatchers and the default HTML files. This should be
+ set as the DOCUMENT_ROOT of your web server.
+
+script
+ Helper scripts for automation and generation.
+
+test
+ Unit and functional tests along with fixtures. When using the script/generate scripts, template
+ test files will be generated for you and placed in this directory.
+
+vendor
+ External libraries that the application depends on. Also includes the plugins subdirectory.
+ If the app has frozen rails, those gems also go here, under vendor/rails/.
+ This directory is in the load path.
10 Rakefile
@@ -0,0 +1,10 @@
+# Add your own tasks in files placed in lib/tasks ending in .rake,
+# for example lib/tasks/capistrano.rake, and they will automatically be available to Rake.
+
+require File.expand_path('../config/application', __FILE__)
+
+require 'rake'
+require 'rake/testtask'
+require 'rake/rdoctask'
+
+Rails::Application.load_tasks
42 app/controllers/application_controller.rb
@@ -0,0 +1,42 @@
+class ApplicationController < ActionController::Base
+ helper :all
+ protect_from_forgery
+
+ before_filter :require_login
+
+ def super_user?
+ current_user.super_user?
+ end
+
+ def current_unit
+ Unit.find(session[:unit_id])
+ end
+
+ def current_user
+ User.find_by_username(session[:username])
+ end
+
+ def logged_in?
+ current_user != nil
+ end
+
+ # Redirects user to login path if logged_in returns false
+ def require_login
+ unless logged_in?
+ flash[:warning] = "You must be logged in to view that page"
+ redirect_to login_path
+ end
+ end
+
+ def fake_login
+ session[:username] = "jraine"
+ end
+
+ protected
+
+ # Sets the Authorization.current_user to the current_user
+ # This is required by the declarative_authorization gem
+ def set_current_user_for_auth
+ Authorization.current_user = current_user
+ end
+end
70 app/controllers/bundles_controller.rb
@@ -0,0 +1,70 @@
+class BundlesController < ApplicationController
+ def index
+ @bundles = Bundle.unit(current_unit)
+
+ respond_to do |format|
+ format.html
+ end
+ end
+
+ def create
+ @bundle = Bundle.new(params[:bundle])
+ @bundle.unit = current_unit
+
+ respond_to do |format|
+ if @bundle.save
+ flash[:notice] = "Bundle successfully saved"
+ format.html { redirect_to bundles_path }
+ else
+ flash[:error] = "Bundle failed to save!"
+ format.html { render new_bundle_path }
+ end
+ end
+ end
+
+ def destroy
+ @bundle = Bundle.find(params[:id])
+
+ if @bundle.destroy
+ flash[:notice] = "Bundle was destroyed successfully"
+ end
+
+ respond_to do |format|
+ format.html { redirect_to bundles_path }
+ end
+ end
+
+ def edit
+ @bundle = Bundle.find(params[:id])
+ end
+
+ def update
+ @bundle = Bundle.unit(current_unit).find(params[:id])
+ @manifest_service = ManifestService.new(@bundle,params[:bundle])
+
+ respond_to do |format|
+ if @manifest_service.save
+ flash[:notice] = "Bundle was successfully updated."
+ format.html { redirect_to bundle_path(@bundle) }
+ format.xml { head :ok }
+ else
+ flash[:error] = "Could not update bundle!"
+ format.html { redirect_to edit_bundle(@bundle) }
+ format.xml { render :xml => @bundle.errors, :status => :unprocessable_entity }
+ end
+ end
+ end
+
+ def new
+ @bundle = Bundle.new
+ end
+
+ def show
+ @bundle = Bundle.find(params[:id])
+
+ respond_to do |format|
+ format.html
+ format.plist { render :text => @bundle.to_plist }
+ end
+ end
+end
9 app/controllers/catalogs_controller.rb
@@ -0,0 +1,9 @@
+class CatalogsController < ApplicationController
+ def show
+ @catalog = Catalog.generate(params[:unit_id],params[:environment_name])
+
+ respond_to do |format|
+ format.plist { render :text => @catalog.to_plist }
+ end
+ end
+end
70 app/controllers/computer_groups_controller.rb
@@ -0,0 +1,70 @@
+class ComputerGroupsController < ApplicationController
+ def index
+ @computer_groups = ComputerGroup.unit(current_unit)
+
+ respond_to do |format|
+ format.html
+ end
+ end
+
+ def create
+ @computer_group = ComputerGroup.new(params[:computer_group])
+ @computer_group.unit = current_unit
+
+ respond_to do |format|
+ if @computer_group.save
+ flash[:notice] = "Computer group successfully saved"
+ format.html { redirect_to computer_groups_path }
+ else
+ flash[:error] = "Computer group failed to save!"
+ format.html { render new_computer_group_path }
+ end
+ end
+ end
+
+ def destroy
+ @computer_group = ComputerGroup.find(params[:id])
+
+ if @computer_group.destroy
+ flash[:notice] = "Computer group was destroyed successfully"
+ end
+
+ respond_to do |format|
+ format.html { redirect_to computer_groups_path }
+ end
+ end
+
+ def edit
+ @computer_group = ComputerGroup.find(params[:id])
+ end
+
+ def update
+ @computer_group = ComputerGroup.unit(current_unit).find(params[:id])
+ @manifest_service = ManifestService.new(@computer_group,params[:computer_group])
+
+ respond_to do |format|
+ if @manifest_service.save
+ flash[:notice] = "Computer group was successfully updated."
+ format.html { redirect_to computer_group_path(@computer_group) }
+ format.xml { head :ok }
+ else
+ flash[:error] = "Could not update computer group!"
+ format.html { redirect_to edit_computer_group(@computer_group) }
+ format.xml { render :xml => @computer_group.errors, :status => :unprocessable_entity }
+ end
+ end
+ end
+
+ def new
+ @computer_group = ComputerGroup.new
+ end
+
+ def show
+ @computer_group = ComputerGroup.find(params[:id])
+
+ respond_to do |format|
+ format.html
+ format.plist { render :text => @computer_group.to_plist }
+ end
+ end
+end
105 app/controllers/computers_controller.rb
@@ -0,0 +1,105 @@
+class ComputersController < ApplicationController
+ def index
+ @computers = ComputerService.collect(params,current_unit)
+
+ respond_to do |format|
+ format.html # index.html
+ format.js # index.js
+ end
+ end
+
+ def new
+ @computer = Computer.new
+ end
+
+ def create
+ @computer = Computer.new(params[:computer])
+ @computer.unit = current_unit
+
+ respond_to do |format|
+ if @computer.save
+ flash[:notice] = "#{@computer} was successfully created."
+ format.html { redirect_to(@computer) }
+ format.xml { render :xml => @computer, :status => :created }
+ else
+ flash[:error] = "Failed to create #{@computer} computer object!"
+ format.html { render :action => "new"}
+ end
+ end
+ end
+
+ def show
+ @computer = Computer.unit(current_unit).find(params[:id])
+
+ respond_to do |format|
+ format.html
+ format.plist { render :layout => false, :text => @computer.to_plist}
+ end
+ end
+
+ def edit
+ @computer = Computer.unit(current_unit).find(params[:id])
+ end
+
+ def update
+ @computer = Computer.unit(current_unit).find(params[:id])
+ @computer_service = ComputerService.new(@computer,params[:computer])
+ respond_to do |format|
+ if @computer_service.save
+ flash[:notice] = "#{@computer.name} was successfully updated."
+ format.html { redirect_to(@computer) }
+ format.xml { head :ok }
+ else
+ flash[:error] = 'Could not update computer!'
+ format.html { render :action => "edit" }
+ format.xml { render :xml => @computer.errors, :status => :unprocessable_entity }
+ end
+ end
+ end
+
+ def destroy
+ @computer = Computer.find(params[:id])
+
+ if @computer.destroy
+ flash[:notice] = "Computer was destroyed successfully"
+ end
+
+ respond_to do |format|
+ format.html { redirect_to computers_path }
+ end
+ end
+
+
+ # Import an ARD plist form
+ def import
+ end
+
+ # Take ARD plist and create new computer objects
+ # TO-DO when a computer object import fails, tell
+ # the user what went wrong (by print the computer.errors hash)
+ def create_import
+ begin
+ @computers = ComputerService.import(params[:computer],current_unit)
+ rescue NoMethodError
+ end
+
+ unless @computers.nil?
+ @total = @computers.count
+ # Save each computer. If it doesn't save, leave it out of the array
+ @computers = @computers.collect {|e| e if e.save}.compact
+ end
+
+ respond_to do |format|
+ if @computers.nil?
+ flash[:error] = "There was a problem while parsing the plist"
+ format.html { redirect_to import_new_computer_path }
+ elsif @computers.count > 0
+ flash[:notice] = "#{@computers.count} of #{@total} computers imported into #{@computers.first.computer_group}"
+ format.html { redirect_to computers_path }
+ else
+ flash[:warning] = "Zero computers were imported. Did the ARD list have any members?"
+ format.html { redirect_to computers_path }
+ end
+ end
+ end
+end
90 app/controllers/packages_controller.rb
@@ -0,0 +1,90 @@
+class PackagesController < ApplicationController
+ def index
+ # Set environment
+ @env = Environment.find_by_id(params[:eid])
+ @env ||= Environment.first
+ # Get package branches and binds them to the current scope
+ @package_branches = PackageBranch.unit_and_environment(current_unit,@env)
+ @packages = @package_branches.map(&:latest)
+
+ respond_to do |format|
+ format.html
+ end
+ end
+
+ def create
+ begin
+ @h = Package.upload(params[:data])
+ @package = @h[:package]
+ @package.unit = current_unit
+ invalid_package_upload = false
+ rescue InvalidPackageUpload
+ @package = Package.new
+ invalid_package_upload = true
+ end
+
+ respond_to do |format|
+ if invalid_package_upload == false and @package.save
+ flash[:notice] = "Package successfully saved"
+ format.html { redirect_to edit_package_path(@package) }
+ elsif invalid_package_upload
+ flash[:error] = "Invalid package file uploaded!"
+ format.html { render new_package_path }
+ else
+ flash[:error] = "Package failed to save!"
+ format.html { render new_package_path }
+ end
+ end
+ end
+
+ def destroy
+ @package = Package.find(params[:id])
+
+ if @package.destroy
+ flash[:notice] = "Package was destroyed successfully"
+ end
+
+ respond_to do |format|
+ format.html { redirect_to packages_path }
+ end
+ end
+
+ def edit
+ @package = Package.find(params[:id])
+ end
+
+ def update
+ @package = Package.unit(current_unit).find(params[:id])
+ @package_service = PackageService.new(@package,params[:package])
+
+ respond_to do |format|
+ if @package_service.save
+ flash[:notice] = "Package was successfully updated."
+ format.html { redirect_to package_path(@package) }
+ format.xml { head :ok }
+ else
+ flash[:error] = "Could not update package!"
+ format.html { redirect_to edit_package(@package) }
+ format.xml { render :xml => @package.errors, :status => :unprocessable_entity }
+ end
+ end
+ end
+
+ def new
+ @package = Package.new
+ end
+
+ def show
+ @package = Package.find(params[:id])
+
+ respond_to do |format|
+ format.html
+ format.plist { render :text => @package.to_plist }
+ end
+ end
+
+ # Used to download the actual package (typically a .dmg)
+ def download
+ send_file Munki::Application::PACKAGE_DIR + params[:installer_item_location]
+ end
+end
38 app/controllers/sessions_controller.rb
@@ -0,0 +1,38 @@
+class SessionsController < ApplicationController
+ skip_before_filter :require_login, :only => ['new','create']
+
+ def new
+ redirect_to root_path if logged_in?
+ end
+
+ # Creates a new user session
+ def create
+ u = User.authenticate(params[:username],params[:pass])
+ if u.nil?
+ flash[:error] = "Incorrect username or password"
+ redirect_to login_path
+ else
+ session[:username] = u.username
+ session[:unit_id] = u.unit_ids.first
+ redirect_to root_path
+ end
+ end
+
+ # Switches the unit_id session var if the current user is a member of that unit
+ def update
+ new_unit = Unit.find(params[:unit_id])
+ if current_user.member_of(new_unit)
+ session[:unit_id] = params[:unit_id]
+ end
+ # case params[:a]
+ redirect_to :action => params[:a], :controller => params[:c]
+ end
+
+ # Logs the user out of the current session
+ def destroy
+ session[:username] = nil
+ session[:unit_id] = nil
+ flash[:notice] = "You have been logged out of your session"
+ redirect_to login_path
+ end
+end
21 app/controllers/unit_settings_controller.rb
@@ -0,0 +1,21 @@
+class UnitSettingsController < ApplicationController
+ def edit
+ @unit_setting = UnitSetting.find(params[:id])
+ end
+
+ def update
+ @unit_setting = UnitSetting.find(params[:id])
+
+ respond_to do |format|
+ if @unit_setting.update_attributes(params[:unit_setting])
+ flash[:notice] = "Settings successfully updated."
+ format.html { redirect_to(@unit_setting.unit) }
+ format.xml { head :ok }
+ else
+ flash[:error] = 'Could not update settings!'
+ format.html { render :action => "edit" }
+ format.xml { render :xml => @unit_setting.errors, :status => :unprocessable_entity }
+ end
+ end
+ end
+end
66 app/controllers/units_controller.rb
@@ -0,0 +1,66 @@
+class UnitsController < ApplicationController
+ before_filter :super_user?
+
+ def index
+ @units = Unit.all
+ end
+
+ def new
+ @unit = Unit.new
+ end
+
+ def create
+ @unit = Unit.new(params[:unit])
+
+ respond_to do |format|
+ if @unit.save
+ flash[:notice] = "#{@unit.name} was successfully created."
+ format.html { redirect_to(units_path) }
+ format.xml { render :xml => @unit, :status => :created }
+ else
+ flash[:error] = "Failed to create #{@unit.name} unit!"
+ format.html { render :action => "new"}
+ end
+ end
+ end
+
+ def show
+ @unit = Unit.find(params[:id])
+ end
+
+ def edit
+ @unit = Unit.find(params[:id])
+ end
+
+ def update
+ @unit_service = UnitService.new(params)
+
+ respond_to do |format|
+ if @unit_service.save
+ flash[:notice] = "#{@unit_service.name} was successfully updated."
+ format.html { redirect_to(@unit_service.unit) }
+ format.xml { head :ok }
+ else
+ flash[:error] = 'Could not update unit!'
+ format.html { render :action => "edit" }
+ format.xml { render :xml => @unit.errors, :status => :unprocessable_entity }
+ end
+ end
+ end
+
+ def destroy
+ @unit = Unit.find(params[:id])
+ unit_name = @unit.name
+
+ respond_to do |format|
+ if @unit.destroy
+ flash[:notice] = "#{unit_name} was successfully remove"
+ format.html { redirect_to(units_path) }
+ format.xml { head :ok }
+ else
+ flash[:error] = "Failed to removed #{unit_name}!"
+ format.html { render :action => "index" }
+ end
+ end
+ end
+end
21 app/controllers/user_settings_controller.rb
@@ -0,0 +1,21 @@
+class UserSettingsController < ApplicationController
+ def edit
+ @user_setting = UserSetting.find(params[:id])
+ end
+
+ def update
+ @user_setting = UserSetting.find(params[:id])
+
+ respond_to do |format|
+ if @user_setting.update_attributes(params[:user_setting])
+ flash[:notice] = "Settings successfully updated."
+ format.html { redirect_to(@user_setting.user) }
+ format.xml { head :ok }
+ else
+ flash[:error] = 'Could not update settings!'
+ format.html { render :action => "edit" }
+ format.xml { render :xml => @user_setting.errors, :status => :unprocessable_entity }
+ end
+ end
+ end
+end
65 app/controllers/users_controller.rb
@@ -0,0 +1,65 @@
+class UsersController < ApplicationController
+ before_filter :super_user?
+
+ def index
+ @users = User.all
+ end
+
+ def new
+ @user = User.new
+ end
+
+ def create
+ @user = User.new(params[:user])
+
+ respond_to do |format|
+ if @user.save
+ flash[:notice] = "#{@user.username} was successfully created."
+ format.html { redirect_to(users_path) }
+ format.xml { render :xml => @user, :status => :created }
+ else
+ flash[:error] = "Failed to create #{@user.username}!"
+ format.html { render :action => "new"}
+ end
+ end
+ end
+
+ def show
+ @user = User.find(params[:id])
+ end
+
+ def edit
+ @user = User.find(params[:id])
+ end
+
+ def update
+ @user = User.find(params[:id])
+
+ respond_to do |format|
+ if @user.update_attributes(params[:user])
+ flash[:notice] = "#{@user.username} was successfully updated."
+ format.html { redirect_to(@user) }
+ format.xml { head :ok }
+ else
+ flash[:error] = 'Could not update user!'
+ format.html { render :action => "edit" }
+ format.xml { render :xml => @user.errors, :status => :unprocessable_entity }
+ end
+ end
+ end
+
+ def destroy
+ @user = User.find(params[:id])
+ username = @user.username
+
+ respond_to do |format|
+ if @user.destroy
+ flash[:notice] = "#{@user.username} was successfully removed."
+ format.html { redirect_to(users_path) }
+ format.xml { head :ok }
+ else
+ format.html { render :action => "index" }
+ end
+ end
+ end
+end
2  app/helpers/ajax_helper.rb
@@ -0,0 +1,2 @@
+module AjaxHelper
+end
274 app/helpers/application_helper.rb
@@ -0,0 +1,274 @@
+# Methods added to this helper will be available to all templates in the application.
+module ApplicationHelper
+ # Commented...if there is no one using this, it will be removed.
+ # Pass a plist file parse into hash.
+ # def self.parsePlist(plist)
+ # require "plist"
+ # xml_string = plist.read
+ # plistHash = Plist.parse_xml(xml_string)
+ # end
+
+ # Makes from_yaml method available to views / helpers (markup generators)
+ def from_yaml(string,return_type = "default")
+ # Use method added to ActiveRecord by ActiveRecordHelpers plugin
+ ActiveRecord::Base.from_yaml(string,return_type)
+ end
+
+ # Outputs code for pkg list
+ # Replaces html_package_list and build_html_package_list_item method
+ def pkg_list(package_list,rollback = {})
+ empty_list_message = "<p><em>No packages assigned</em></p>"
+ if package_list.empty?
+ empty_list_message.html_safe
+ else
+ render :partial => "shared/pkg_list", :locals => {:package_list => package_list, :rollback => rollback}
+ end
+ end
+
+ # Outputs code for group list
+ def bundle_list(bundle_list,rollback = {})
+ empty_list_message = "<p><em>No bundles assigned</em></p>"
+ if bundle_list.empty?
+ empty_list_message.html_safe
+ else
+ render :partial => "shared/bundle_list", :locals => {:bundle_list => bundle_list, :rollback => rollback}
+ end
+ end
+
+ def inventory(model_obj,rollback_option = false)
+ render :partial => "shared/inventory", :locals => {:model_obj => model_obj, :rollback_option => rollback_option}
+ end
+
+ # Pass an array of group names. Pushes installed package names into second argument and uninstalled package names into third argument. Calls itself for groups of passed groups names (checks fourth argument for already visited group names)
+ def get_group_pkg_names(group_names,installed_pkg_names,uninstalled_pkg_names,visited_groups = [])
+ group_names.each do |group_name|
+ group = Group.first(:conditions => "name = '#{group_name}'")
+ unless group.nil?
+ installed_pkg_names = installed_pkg_names | from_yaml(group.managed_installs,"array")
+ uninstalled_pkg_names = uninstalled_pkg_names | from_yaml(group.managed_uninstalls,"array")
+ end
+
+ # Unless group is not a member of any groups that haven't been visited, get nested group pkgsinfo
+ filtered_groups = from_yaml(group.groups,"array") - visited_groups
+ visited_groups = filtered_groups | visited_groups
+ unless filtered_groups.empty?
+ nested = get_group_pkg_names(from_yaml(group.groups,"array"),installed_pkg_names,uninstalled_pkg_names,visited_groups)
+ installed_pkg_names = installed_pkg_names | nested['installed_pkg_names']
+ uninstalled_pkg_names = uninstalled_pkg_names | nested['uninstalled_pkg_names']
+ end
+ end
+ {"installed_pkg_names" => installed_pkg_names - [nil], "uninstalled_pkg_names" => uninstalled_pkg_names - [nil]} # Sometimes you get a nil in the array...this removes it. I'm not sure why it is there.
+ end
+
+ # Creates a multiple select based on passed params
+ # Parameters is filled with hashes with the following keys:
+ # title, model_name, attribute_name, select_title, options
+ def tabled_asm_select(parameters,table_class = "packagePicker",header_enabled = true)
+ # If parameter is an active record model, get tas_params
+ if parameters.class.superclass == ActiveRecord::Base
+ parameters = parameters.tas_params
+ end
+
+ # Let us know if we're passing blank parameters (we shouldn't be)
+ parameters.each do |section|
+ section.each do |key, val|
+ if section[key].blank?
+ puts "Error: parameters #{key} was blank!"
+ end
+ end
+ end
+
+ htmlcode = "<table class='#{table_class}'>\n"
+
+ # table header
+ if header_enabled
+ htmlcode += "\t<thead>\n"
+ htmlcode += "\t\t<tr>\n"
+ parameters.each do |section|
+ htmlcode += "\t\t\t<th>#{section[:title]} "
+ htmlcode += helpful_info(section[:helpful_string]) unless section[:helpful_string].blank?
+ htmlcode +="</th>\n"
+ end
+ htmlcode += "\t\t</tr>\n"
+ htmlcode += "\t</thead>\n"
+ end
+
+ htmlcode += "\t<tr>\n"
+
+ parameters.each do |section|
+ htmlcode += "\t\t<td>\n"
+ htmlcode += hidden_field_tag("#{section[:model_name]}[#{section[:attribute_name]}][]",'')
+ htmlcode += select_tag("#{section[:model_name]}[#{section[:attribute_name]}]", options_for_select(section[:options],section[:selected_options]), :multiple => true, :title => section[:select_title])
+ #htmlcode += text_field_with_auto_complete(:quickly, section['title'].to_sym, { :size => 20, :class => "quickly_complete_field" }, { :url => formatted_pkgsinfo_index_path(:js), :method => :get, :with => "'search=' + element.value" })
+ htmlcode += autocomplete_asmselect(section[:title],
+ section[:options].collect { |el| el[0] },
+ "type a name...")
+ htmlcode += "\t\t</td>\n"
+ end
+ htmlcode += "\t</tr>\n"
+ htmlcode += "</table>\n"
+ htmlcode.html_safe
+ end
+
+
+ def display_package_version(pkgsinfo)
+ unless Pkgsinfo.latest?(pkgsinfo)
+ "(#{pkgsinfo.version})"
+ end
+ end
+
+ def record_count(model_objs,word = "record")
+ if model_objs.empty?
+ content_tag(:em, "no records")
+ else
+ if model_objs.class == WillPaginate::Collection
+ # If results are paginated
+ per_page = model_objs.per_page
+ records = model_objs.length
+ page = model_objs.current_page
+ total = model_objs.total_entries
+ from = page == 1 ? 1 : ((page - 1) * per_page) + 1
+ to = (from + records) - 1
+ else
+ # If results are normal
+ total = model_objs.length
+ from = 1
+ to = total
+ end
+
+ range = "#{from}-#{to}"
+ content_tag(:em,"displaying #{range} of " + pluralize(total,word))
+ end
+ end
+
+ # Checks if currently logged in user is a super user
+ def super_user?
+ current_user.super_user?
+ end
+
+ def logged_in?
+ current_user != nil
+ end
+
+ def current_user
+ # User.find_by_username(session[:username])
+ @current_user ||= User.find_by_username("jraine")
+ end
+
+ def unit_set?
+ current_unit_id != nil
+ end
+
+ def current_unit_id
+ session[:unit_id]
+ end
+
+ def current_unit
+ @unit_id ||= Unit.find(current_unit_id)
+ end
+
+ def mine?(object)
+ object.unit_id == current_unit_id
+ end
+
+ # Build units menu for currently logged in user
+ def units_menu
+ unless current_unit.nil?
+ units = current_user.units
+ render :partial => "shared/units_menu", :locals => {:units => units, :current_unit => current_unit}
+ end
+ end
+
+ # Creates auto-complete text field for ASM select
+ def autocomplete_asmselect(element_id, choices, default_value = '')
+ element_id = element_id.gsub(" ","_").downcase
+ render :partial => 'shared/autocomplete_asmselect', :locals => {:element_id => element_id, :autocomplete_id => element_id + "_autocomplete", :choices => choices, :default_value => default_value}
+ end
+
+ def field_lock_control(id)
+ link_to('unlock', '#', :onClick => "toggleDisabledTextField('#{id}');return false;", :id => "#{id}_control")
+ end
+
+ def current_link?(string)
+ bool = false
+ case string
+ when "Computers"
+ bool = (params[:controller] == "computers")
+ when "Computer Groups"
+ bool = (params[:controller] == "computer_groups")
+ when "Bundles"
+ bool = (params[:controller] == "groups")
+ when "Packages"
+ bool = (params[:controller] == "pkgsinfo")
+ end
+ bool
+ end
+
+ # Takes int of bytes, returns humanized file size with unit
+ def humanize_bytes(bytes)
+ humanized_string = ''
+ bytes = bytes.to_i
+ kilobytes = bytes / 1024
+ humanize_kilobytes(kilobytes)
+ end
+
+ # Takes int of bytes, returns humanized file size with unit
+ def humanize_kilobytes(kilobytes)
+ humanized_string = ''
+ kilobytes = kilobytes.to_i
+ if kilobytes > 1048576
+ humanized_string = format("%.2f GB",kilobytes / 1048576.0)
+ elsif kilobytes > 1024
+ humanized_string = format("%.2f MB",kilobytes / 1024.0)
+ else
+ humanized_string = format("%.0f KB",kilobytes)
+ end
+ humanized_string
+ end
+
+ # Apply a "subtle value" to an object attribute (or pass static value)
+ def subtle_value(model_obj,attribute,value = nil)
+ model_class = model_obj.class.to_s.downcase
+ attribute = attribute.to_s
+ dom_id = "#{model_class}_#{attribute}"
+ value ||= attribute.humanize
+ subtle_value_tag(dom_id,value)
+ end
+
+ # Apply a "subtle value" to a form element with passed ID and value
+ def subtle_value_tag(dom_id,value)
+ "<script type='text/javascript'>\n\tjQuery('##{dom_id}').subtle_value('#{value}');\n</script>\n".html_safe
+ end
+
+ # Pass dom_id of element for rollover, and content for box
+ def extra_info(dom_id,content,jq_event = 'mouseover')
+ render :partial => 'shared/extra_info_box', :locals => {:dom_id => dom_id, :content => content, :jq_event => jq_event}
+ end
+
+ # Provides a question mark rollover with extra information
+ def helpful_info(content,jq_event = 'click')
+ dom_id = content[0,25].gsub(/[^[:alnum:]]/, '_') + "_" + rand(1001).to_s
+ code = image_tag('question_mark.png', :id => dom_id, :style => "vertical-align:middle;cursor:pointer")
+ code += extra_info(dom_id,content,jq_event)
+ code
+ end
+
+ # Creates a set of tags for a checkbox: the checkbox, a label (with passed string), a hidden tag (to nullify value)
+ def check_box_tag_set(name,label,value)
+ value ||= "0"
+ label = " #{label}"
+ dom_id = name.gsub(/\[|\]| /,'_').gsub(/__|___/,'_').sub(/_$/,'')
+ code = hidden_field_tag(name,'0', :id => dom_id + "_hidden" )
+ code += check_box_tag(name,"1", value.to_bool)
+ code += label_tag(dom_id,label)
+ code
+ end
+
+ # Creates nicely formatted checkbox section from a hash
+ def hash_checkboxes(h, options = {})
+ defaults = {:title => "",:name => ""}
+ options = defaults.merge(options)
+
+ render "shared/hash_checkboxes", :locals => {:options => options, :h => h}
+ end
+end
2  app/helpers/bundle_helper.rb
@@ -0,0 +1,2 @@
+module BundleHelper
+end
2  app/helpers/catalogs_helper.rb
@@ -0,0 +1,2 @@
+module CatalogsHelper
+end
2  app/helpers/computer_groups_helper.rb
@@ -0,0 +1,2 @@
+module ComputerGroupsHelper
+end
40 app/helpers/computers_helper.rb
@@ -0,0 +1,40 @@
+module ComputersHelper
+
+ # Builds a computer page (show/edit) header from a computer object
+ def computer_header(computer)
+ render :partial => 'shared/record_header', :locals => {:title => computer.hostname,
+ :img => computer.icon.public_filename,
+ :soft_info => computer.computer_group.name,
+ :bold_info => computer.mac_address }
+ end
+
+ def computer_group_links
+ computer_groups = ComputerGroup.unit(current_unit)
+ unless computer_groups.empty?
+ render :partial => 'computer_group_link', :collection => computer_groups
+ else
+ render :text => "None", :layout => false
+ end
+ end
+
+ def render_computer_group_header(id)
+ string = ''
+ cg = []
+
+ if id.nil?
+ string = "<h3>All</h3>"
+ else
+ cg = ComputerGroup.of_unit(current_unit_id).find(id)
+ unless cg.nil?
+ string = "<h3>#{cg.name}</h3>"
+ end
+ end
+
+ concat(render :text => string, :layout => false)
+ end
+
+ # Returns options tags for computer groups
+ def computer_group_options
+ options_for_select(ComputerGroup.unit(current_unit).collect {|cg| [cg.name, cg.id] })
+ end
+end
2  app/helpers/groups_helper.rb
@@ -0,0 +1,2 @@
+module GroupsHelper
+end
171 app/helpers/packages_helper.rb
@@ -0,0 +1,171 @@
+module PackagesHelper
+ # Pass an array of builtin icon hash (name => "name", filename => "name.png")
+ def icon_picker(array,current_icon)
+ input_name = "builtin_icon"
+ builtin = false
+ htmlcode = ""
+ array.each { |icon|
+ htmlcode += "<p class ='builtin_icons'>"
+ htmlcode += image_tag("pkgicons/#{icon['filename']}", :height => "30px")
+ if icon['filename'] == current_icon
+ htmlcode += radio_button_tag input_name, icon['filename'], :selected => true
+ builtin = true
+ else
+ htmlcode += radio_button_tag input_name, icon['filename']
+ end
+ htmlcode += label_tag "#{input_name}_#{icon['filename'].gsub('.','')}", icon['name']
+ htmlcode += "</p>"
+ }
+ htmlcode += "<p class ='builtin_icons'>"
+ htmlcode += image_tag("pkgicons/#{current_icon}", :height => "30px")
+ unless builtin
+ htmlcode += radio_button_tag input_name, "custom", :selected => true
+ else
+ htmlcode += radio_button_tag input_name, "custom"
+ end
+ htmlcode += label_tag "#{input_name}_custom", "Custom "
+ htmlcode += file_field_tag 'icon'
+ htmlcode += "</p>"
+ end
+
+ def package_header(package)
+ render :partial => 'shared/record_header', :locals => {
+ :title => package.display_name,
+ :img => package.icon.public_filename,
+ :soft_info => package.name,
+ :bold_info => package.version }
+ end
+
+ def recent_packages
+ pkgs = Package.recent(current_unit)
+ render :partial => 'recent', :locals => { :pkgs => pkgs }
+ end
+
+ def package_table(packages)
+ # Split different categories into different arrays
+ categorized = {}
+ packages.each do |package|
+ category_name = package.package_category.name
+ categorized[category_name] ||= []
+ categorized[category_name] << package
+ end
+
+ output = ""
+ # Render header and table for each category
+ categorized.each_pair do |category_name, packages|
+ output += render :partial => 'packages_of_category_table', :locals => {:category_name => category_name, :packages => packages}
+ end
+ output.html_safe
+ end
+
+ def scrape_latest_version_info(pkg)
+ require 'scrapi'
+
+ # Define scrape for latest version, and download redirect URL
+ scraper = Scraper.define do
+ process "span.appVersion", :version => :text
+ process ".product-quick-links>h2>a", :download_redirect_url => "@href"
+ result :version,:download_redirect_url
+ end
+
+ # Version tracker URL to application page
+ uri = URI.parse("http://www.versiontracker.com/dyn/moreinfo/macosx/#{pkg.version_tracker_id}")
+
+ # Scrape latest version and download redirect URL
+ results = scraper.scrape(uri)
+ latest_version = results.version
+
+ # Define scrape for latest version, and download redirect URL
+ scraper = Scraper.define do
+ process "p.contactDevSite>a", :download_url => "@href"
+ result :download_url
+ end
+
+ unless(results.download_redirect_url == nil)
+ # Version tracker URL to download redirect
+ uri = URI.parse(results.download_redirect_url)
+
+ # Scrape download URL
+ download_url = scraper.scrape(uri)
+ else
+ download_url = nil
+ end
+
+ {'latest_version' => latest_version, 'download_url' => download_url}
+ end
+
+ # Checks when versions were last checked and re-checks if within given time
+ # Sets session[:versions_checked_at]
+ def check_versions?
+ seconds_between_checks = 300
+ if session[:versions_checked_at].nil?
+ # Check versions, if not checked yet
+ session[:versions_checked_at] = Time.now.to_i
+ true
+ elsif session[:versions_checked_at] < (Time.now.to_i - seconds_between_checks)
+ # Check versions, if seconds_between_checks has passed
+ true
+ else
+ # Don't check versions
+ false
+ end
+ end
+
+ # Check version tracker for package updates, display available updates
+ def available_updates
+ version_tracker_url = "http://www.versiontracker.com/dyn/moreinfo/macosx/"
+ # Get the latest version of all version trackable packages
+ pkgs = Pkgsinfo.version_trackable.all(:conditions => {:id => Pkgsinfo.latest_package_ids})
+ newer_available = []
+ if check_versions?
+ session[:newer_versions] = []
+ pkgs.each do |pkg|
+ info = scrape_latest_version_info(pkg)
+
+ # If latest_version or download_url is blank, don't compare versions
+ unless(info['latest_version'].blank? or info['download_url'].blank?)
+ # Strip ".0" from end of version three times
+ formatted_version = pkg.version.sub(/\.0$/,'').sub(/\.0$/,'').sub(/\.0$/,'')
+ if info['latest_version'] > formatted_version
+ newer_available << pkg
+ session[:newer_versions] << {'download_url' => info['download_url'],
+ 'version' => info['latest_version'],
+ 'display_name' => pkg.display_name,
+ 'version_tracker_id' => pkg.version_tracker_id}
+ end
+ end
+ end
+ end
+ render :partial => 'available_updates', :locals => {:pkgs => newer_available,
+ :version_tracker_url => version_tracker_url,
+ :newer_versions => session[:newer_versions]}
+ end
+
+
+ def render_pkgsinfo_category_icon(object, height = "30px")
+ pkgsinfo_category = object.pkgsinfo_category
+ pkgsinfo_category ||= object
+ concat(image_tag("#{PKGSINFO_ICON_REL_PATH}/#{pkgsinfo_category.icon}", :height => height, :style => "vertical-align:middle;"))
+ end
+
+ def render_pkgsinfo_icon(object, height = "30px")
+ concat(image_tag("#{PKGSINFO_ICON_REL_PATH}/#{object.icon}", :height => height, :style => "vertical-align:middle;"))
+ end
+
+ def render_gui_installer_choices(choices_hash)
+ sorted_choices = Pkgsinfo.sort_choices(choices_hash)
+ concat(render :partial => 'gui_installer_choices', :locals => {:sorted_choices => sorted_choices})
+ end
+
+ def render_pkgsinfo_plist_errors
+ all_pkgsinfos = Pkgsinfo.all
+ invalid_plists = []
+ # Collect all errors
+ all_pkgsinfos.each do |pkgsinfo|
+ unless pkgsinfo.plist_valid?
+ invalid_plists << {'errors' => pkgsinfo.plist_validation_results, 'pkgsinfo' => pkgsinfo}
+ end
+ end
+ concat(render :partial => 'pkgsinfo_plist_errors', :locals => {:invalid_plists => invalid_plists })
+ end
+end
2  app/helpers/pkgs_helper.rb
@@ -0,0 +1,2 @@
+module PkgsHelper
+end
2  app/helpers/pkgsinfo_categories_helper.rb
@@ -0,0 +1,2 @@
+module PkgsinfoCategoriesHelper
+end
36 app/helpers/repos_helper.rb
@@ -0,0 +1,36 @@
+module ReposHelper
+ def status_info(repo)
+ # Interprets status hash
+ # Options for status[:state]
+ # => syncing - Sync is currently happening in the background
+ # => synced - Sync has completed successfully
+ # => failed - There was an error syncing
+ status = repo.status
+ short_status = nil
+ long_status = nil
+ case status[:state]
+ when 'syncing'
+ short_status = "#{status[:state].humanize}..."
+ a = ["Sync started on #{status[:sync_started]}"]
+ a << "Copying #{status[:items_to_copy].to_s} files" unless status[:items_to_copy].blank?
+ a << "Total size: #{humanize_bytes(status[:total_size_copied])}" unless status[:total_size_copied].blank?
+ long_status = a.join("<br />")
+ when 'synced'
+ remote_status = repo.remote_status
+ if remote_status[:errors].length != 0
+ short_status = remote_status[:errors].first[:short_description]
+ long_status = remote_status[:errors].first[:long_description]
+ elsif remote_status[:mismatched_checksums].empty? and remote_status[:missing_packages].empty?
+ short_status = "#{status[:state].humanize}"
+ long_status = "Last sync on #{status[:sync_finished]}"
+ else
+ short_status = "Unsynchronized"
+ long_status = render(:partial => "sync_failed_details", :locals => {:remote_status => remote_status, :status => status})
+ end
+ else
+ short_status = "Never synced"
+ end
+
+ render :partial => 'status_info', :locals => {:repo => repo, :short_status => short_status, :long_status => long_status}
+ end
+end
2  app/helpers/settings_helper.rb
@@ -0,0 +1,2 @@
+module SettingsHelper
+end
2  app/helpers/units_helper.rb
@@ -0,0 +1,2 @@
+module UnitsHelper
+end
2  app/helpers/users_helper.rb
@@ -0,0 +1,2 @@
+module UsersHelper
+end
13 app/models/catalog.rb
@@ -0,0 +1,13 @@
+class Catalog
+ # Looks up all package items that belong to unit and environment specified and concatenates
+ # the plist objects together (we end up with an Ruby array). Need to call .to_plist to create a string
+ def self.generate(unit_id,e_name)
+ e = Environment.where(:name => e_name).first
+ if e.nil?
+ raise EnvironmentNotFound
+ end
+
+ packages = Package.where(:unit_id => unit_id, :environment_id => e.id).to_a
+ packages.map(&:serialize_for_plist)
+ end
+end
8 app/models/computer_model.rb
@@ -0,0 +1,8 @@
+class ComputerModel < ActiveRecord::Base
+ has_many :computers
+ belongs_to :icon
+
+ def self.default
+ self.find_by_name("Default")
+ end
+end
45 app/models/environment.rb
@@ -0,0 +1,45 @@
+class EnvironmentNotFound < Exception
+end
+
+class Environment < ActiveRecord::Base
+ has_many :computers
+ has_many :computer_groups
+ has_many :bundles
+ has_many :packages
+
+ serialize :environment_ids, Array
+
+ # Returns the environment that is the logical beginning
+ # for new elements. For example, given a dev, testing,
+ # and production environment, dev is the starting environment
+ def self.start
+ e = Environment.find_by_name("Development")
+ e ||= Environment.find_by_name("Staging")
+ e ||= Environment.find_by_name("Testing")
+ e ||= Environment.first
+ e
+ end
+
+ # Returns an array of environments including the current environment and the environments
+ # specified by the environment_ids attribute
+ def environments
+ environments = []
+ environment_ids.each do |id|
+ e = Environment.find(id)
+ environments << e unless e.nil?
+ end
+
+ environments << self
+ end
+
+ # Returns an array of environment IDs including the current environment ID
+ # and the array returned from the environment_ids attribute
+ def included_environment_ids
+ environment_ids << id
+ end
+
+ # A string representation of the object
+ def to_s
+ name
+ end
+end
24 app/models/icon.rb
@@ -0,0 +1,24 @@
+class Icon < ActiveRecord::Base
+ has_many :packages
+ has_many :computers
+ has_many :bundles
+ has_many :computer_groups
+ has_many :computer_models
+
+ has_attachment :content_type => :image,
+ :storage => :file_system,
+ :resize_to => '512x512>',
+ :thumbnails => {:large => '96x96>',
+ :medium => '64x64>',
+ :small => '32x32>'}
+ validates_as_attachment
+
+ # Make sure we have at least a default icon
+ def self.generic
+ self.find_by_filename("generic.png")
+ end
+
+ def to_s
+ public_filename
+ end
+end
4 app/models/join_models/bundle_item.rb
@@ -0,0 +1,4 @@
+class BundleItem < ActiveRecord::Base
+ belongs_to :bundle
+ belongs_to :manifest, :polymorphic => true
+end
3  app/models/join_models/install_item.rb
@@ -0,0 +1,3 @@
+class InstallItem < ActiveRecord::Base
+ magic_mixin :item
+end
20 app/models/join_models/membership.rb
@@ -0,0 +1,20 @@
+class Membership < ActiveRecord::Base
+ belongs_to :user
+ belongs_to :unit
+
+ # Returns a list of ACLs columns in the DB
+ def self.acls
+ # Stores attributes that do not represent an ACL
+ non_acl_attr = [:id,:unit_id,:updated_at,:user_id,:created_at]
+ column_names.collect(&:to_sym).delete_if {|k,v| non_acl_attr.include?(k) }
+ end
+
+ # Return hash of acl attributes (as keys) and their values
+ def acls
+ h = {}
+ Membership.acls.each do |acl|
+ h[acl] = read_attribute(acl)
+ end
+ h
+ end
+end
3  app/models/join_models/require_item.rb
@@ -0,0 +1,3 @@
+class RequireItem < ActiveRecord::Base
+ magic_mixin :item
+end
3  app/models/join_models/uninstall_item.rb
@@ -0,0 +1,3 @@
+class UninstallItem < ActiveRecord::Base
+ magic_mixin :item
+end
3  app/models/join_models/update_for_item.rb
@@ -0,0 +1,3 @@
+class UpdateForItem < ActiveRecord::Base
+ magic_mixin :item
+end
3  app/models/join_models/user_allowed_item.rb
@@ -0,0 +1,3 @@
+class UserAllowedItem < ActiveRecord::Base
+ magic_mixin :item
+end
3  app/models/join_models/user_install_item.rb
@@ -0,0 +1,3 @@
+class UserInstallItem < ActiveRecord::Base
+ magic_mixin :item
+end
3  app/models/join_models/user_uninstall_item.rb
@@ -0,0 +1,3 @@
+class UserUninstallItem < ActiveRecord::Base
+ magic_mixin :item
+end
30 app/models/magic_mixin/item.rb
@@ -0,0 +1,30 @@
+# Special ActiveRecord::Base mixin module
+module Item
+ # Used to augment the class definition
+ # of the class passed as an argument
+ # Put class customization in here!
+ def self.extend_class(k)
+ k.class_exec do
+ # ====================
+ # = Code start here! =
+ # ====================
+
+ belongs_to :manifest, :polymorphic => true
+ belongs_to :package_branch
+
+ # Returns the appropriate package for this package branch
+ # relationship. It does this by first checking if a package
+ # ID is specified, grabbing a package if it exists. If that fails
+ # it grabs the latest package from the package branch and returns that
+ def package
+ p = Package.find(package_id) if package_id?
+ p ||= package_branch.latest
+ p
+ end
+
+ # ===================
+ # = Code ends here! =
+ # ===================
+ end
+ end
+end
231 app/models/magic_mixin/manifest.rb
@@ -0,0 +1,231 @@
+# Special ActiveRecord::Base mixin module
+module Manifest
+ # Used to augment the class definition
+ # of the class passed as an argument
+ # Put class customization in here!
+ def self.extend_class(k)
+ k.class_exec do
+ # ====================
+ # = Code start here! =
+ # ====================
+
+ # Validations
+ validates_uniqueness_of :name
+ validates_presence_of :name
+
+ # Bundles
+ has_many :bundle_items, :as => :manifest
+ has_many :bundles, :through => :bundle_items
+
+ # Install and uninstall items
+ has_many :install_items, :as => :manifest
+ has_many :uninstall_items, :as => :manifest
+
+ # A list of user allowed install/uninstall items
+ has_many :user_allowed_items, :as => :manifest
+
+ # User specified install and uninstall items
+ has_many :user_install_items, :as => :manifest
+ has_many :user_uninstall_items, :as => :manifest
+
+ attr_is_hash :version_rollback
+
+ magic_mixin :unit_member
+
+ validate :presence_of_icon
+
+ # Ensures that an icon is present
+ # Should be added to all models that
+ # use icons. Eventually add the ability
+ # to ask self for a generic icon, thereby
+ # giving computers a specific "generic" icon
+ def presence_of_icon
+ if icon.blank?
+ icon = Icon.generic
+ end
+ end
+
+ # Return all the environments visible to this object
+ def environments
+ environment.environments
+ end
+
+ # Concatentates installs (specified by admins) and user installs (specified
+ # by users) to create the managed_installs virtual attribute
+ def managed_installs
+ installs + user_installs
+ end
+
+ # Concatentates installs (specified by admins) and user installs (specified
+ # by users) to create the managed_installs virtual attribute
+ def managed_uninstalls
+ uninstalls + user_uninstalls
+ end
+
+ # Assign the list of items to a specific association (assoc)
+ def build_package_association_assignment(assoc,list)
+ # Blank out the association
+ self.send("#{assoc}=",[])
+ unless list.nil?
+ list.each do |item|
+ # Create association for...
+ if item.class == Package
+ # ...a specific package
+ self.send("#{assoc}").build({:package_id => item.id, :package_branch_id => item.package_branch.id})
+ elsif item.class == PackageBranch
+ # ...the latest package from a package branch
+ self.send("#{assoc}").build({:package_branch_id => item.id})
+ end
+ end
+ end
+ end
+
+ # Gets the packages that belong to this manifests installs virtual attribute
+ def installs
+ install_items.collect(&:package)
+ end
+
+ # Pass a list of Package or PackageBranch records and install_item associations will be built
+ def installs=(list)
+ build_package_association_assignment(:install_items,list)
+ end
+
+ def installs_package_branch_ids
+ install_items.collect(&:package_branch).uniq.collect(&:id)
+ end
+
+ # Gets the packages that belong to this manifests uninstalls virtual attribute
+ def uninstalls
+ uninstall_items.collect(&:package)
+ end
+
+ def uninstalls=(list)
+ build_package_association_assignment(:uninstall_items,list)
+ end
+
+ def uninstalls_package_branch_ids
+ uninstall_items.collect(&:package_branch).uniq.collect(&:id)
+ end
+
+ # Gets the packages that belong to this manifests user_installs virtual attribute
+ def user_installs
+ user_install_items.collect(&:package)
+ end
+
+ # Pass a list of Package or PackageBranch records and install_item associations will be built
+ def user_installs=(list)
+ build_package_association_assignment(:user_install_items,list)
+ end
+
+ def user_installs_package_branch_ids
+ user_install_items.collect(&:package_branch).uniq.collect(&:id)
+ end
+
+ # Gets the packages that belong to this manifests user_uninstalls virtual attribute
+ def user_uninstalls
+ user_uninstall_items.collect(&:package)
+ end
+
+ # Pass a list of Package or PackageBranch records and install_item associations will be built
+ def user_uninstalls=(list)
+ build_package_association_assignment(:user_uninstall_items,list)
+ end
+
+ def user_uninstalls_package_branch_ids
+ user_uninstall_items.collect(&:package_branch).uniq.collect(&:id)
+ end
+
+ # Returns all package_branches that belongs to the unit and the environment
+ def assignable_package_branches
+ # Grab all package branches referenced by packages of this unit and environment
+ # TO-DO use include to minimize db queries made for package_branches
+ packages = Package.unit(unit).environments(environments)
+ package_branches = packages.collect { |p| p.package_branch }
+
+ # Remove duplicate package branches from the list of package branches
+ uniq_pb_ids = []
+ uniq_pbs = []
+ package_branches.each do |pb|
+ unless uniq_pb_ids.include?(pb.id)
+ uniq_pbs << pb
+ uniq_pb_ids << pb.id
+ end
+ end
+
+ uniq_pbs
+ end
+
+ def to_s(format = nil)
+ case format
+ when :unique then "#{id}_#{name}"
+ when :path then "#{self.class.to_s.pluralize.tableize}/#{self.to_s(:unique)}"
+ else name
+ end
+ end
+
+ # Create a hash intended for plist output
+ # Won't include the entire object attributes
+ # but only the ones relevant for munki clients
+ def serialize_for_plist
+ h = {}
+ h[:name] = name
+ h[:included_manifests] = included_manifests
+ h[:managed_installs] = managed_installs.collect(&:to_s)
+ h[:managed_uninstalls] = managed_uninstalls.collect(&:to_s)
+ h
+ end
+
+ # Converts serialized object into plist string
+ def to_plist
+ serialize_for_plist.to_plist
+ end
+
+ def included_manifests
+ a = bundles.collect {|e| "#{e.to_s(:path)}.plist"}
+ if self.respond_to?(:computer_group)
+ a << "#{computer_group.to_s(:path)}.plist"
+ end
+ a
+ end
+
+ # Default parameters for the table_asm_select method
+ # Returns values for self
+ def tas_params
+ self.class.tas_params(self)
+ end
+
+ # Default parameters for a tabled_asm_select method
+ # Takes an object of the current class and returns params
+ def self.tas_params(model_obj)
+ # Get all the package branches associated with this unit and environment
+ pkg_branch_options = PackageBranch.unit_member(model_obj).collect { |e| [e.name,e.id] }
+ bundle_options = Bundle.unit_member(model_obj).collect { |e| [e.name,e.id] }
+ model_name = self.to_s.underscore
+
+ # Array for table_asm_select
+ [{:title => "Bundles",
+ :model_name => model_name,
+ :attribute_name => "bundles",
+ :select_title => "Select a bundle",
+ :options => bundle_options,
+ :selected_options => model_obj.bundle_ids },
+ {:title => "Installs",
+ :model_name => model_name,
+ :attribute_name => "installs",
+ :select_title => "Select a package branch",
+ :options => pkg_branch_options,
+ :selected_options => model_obj.installs_package_branch_ids },
+ {:title => "Uninstalls",
+ :model_name => model_name ,
+ :attribute_name => "uninstalls",
+ :select_title => "Select a package branch",
+ :options => pkg_branch_options,
+ :selected_options => model_obj.uninstalls_package_branch_ids }]
+ end
+
+ # ===================
+ # = Code ends here! =
+ # ===================
+ end
+ end
+end
35 app/models/magic_mixin/unit_member.rb
@@ -0,0 +1,35 @@
+# Special ActiveRecord::Base mixin module
+module UnitMember
+ # Used to augment the class definition
+ # of the class passed as an argument
+ # Put class customization in here!
+ def self.extend_class(k)
+ k.class_exec do
+ # ====================
+ # = Code start here! =
+ # ====================
+
+ has_one :icon, :as => :record
+
+ belongs_to :unit
+ belongs_to :environment
+
+ scope :unit, lambda { |u| where(:unit_id => u.id) }
+ scope :environment, lambda { |p| where(:environment_id => p.id) }
+ scope :environment_ids, lambda { |ids| where(:environment_id => ids) }
+ scope :environments, lambda { |p| where(:environment_id => p.collect(&:id)) }
+
+ validates_presence_of :environment_id
+ validates_presence_of :unit_id
+