default.rb 5.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165
  1. #
  2. # Author:: Noah Kantrowitz <noah@opscode.com>
  3. # Cookbook Name:: application
  4. # Library:: default
  5. #
  6. # Copyright:: 2011, Opscode, Inc <legal@opscode.com>
  7. #
  8. # Licensed under the Apache License, Version 2.0 (the "License");
  9. # you may not use this file except in compliance with the License.
  10. # You may obtain a copy of the License at
  11. #
  12. # http://www.apache.org/licenses/LICENSE-2.0
  13. #
  14. # Unless required by applicable law or agreed to in writing, software
  15. # distributed under the License is distributed on an "AS IS" BASIS,
  16. # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  17. # See the License for the specific language governing permissions and
  18. # limitations under the License.
  19. #
  20. class Chef
  21. class Resource
  22. # Globally update the blocklists to prevent infinite recursion in #to_json and similar
  23. FORBIDDEN_IVARS.concat [:@application, :@application_provider]
  24. HIDDEN_IVARS.concat [:@application, :@application_provider]
  25. class Application
  26. module OptionsCollector
  27. def options
  28. @options ||= {}
  29. end
  30. def method_missing(method_sym, value=nil, &block)
  31. super
  32. rescue NameError
  33. value ||= block
  34. method_sym = method_sym.to_s.chomp('=').to_sym
  35. options[method_sym] = value if value
  36. options[method_sym] ||= nil
  37. end
  38. end
  39. end
  40. module ApplicationBase
  41. def self.included(klass)
  42. klass.actions :before_compile, :before_deploy, :before_migrate, :before_symlink, :before_restart, :after_restart
  43. klass.attribute :id, :kind_of => String, :name_attribute => true
  44. klass.attribute :environment, :kind_of => Hash, :default => {}
  45. klass.attribute :purge_before_symlink, :kind_of => Array, :default => []
  46. klass.attribute :create_dirs_before_symlink, :kind_of => Array, :default => []
  47. klass.attribute :symlinks, :kind_of => Hash, :default => {}
  48. klass.attribute :symlink_before_migrate, :kind_of => Hash, :default => {}
  49. klass.attribute :migration_command, :kind_of => [String, NilClass], :default => nil
  50. klass.attribute :application
  51. klass.attribute :application_provider
  52. klass.attribute :type
  53. end
  54. def restart_command(arg=nil, &block)
  55. arg ||= block
  56. raise "Invalid restart command" unless !arg || arg.is_a?(String) || arg.is_a?(Proc)
  57. @restart_command = arg if arg
  58. @restart_command
  59. end
  60. def method_missing(name, *args)
  61. if application.respond_to? name
  62. application.send(name, *args)
  63. else
  64. super
  65. end
  66. end
  67. def release_path
  68. application_provider.release_path
  69. end
  70. class OptionsBlock
  71. include Chef::Resource::Application::OptionsCollector
  72. end
  73. def options_block(options=nil, &block)
  74. options ||= {}
  75. if block
  76. collector = OptionsBlock.new
  77. collector.instance_eval(&block)
  78. options.update(collector.options)
  79. end
  80. options
  81. end
  82. def find_matching_role(role, single=true, &block)
  83. return nil if !role
  84. nodes = []
  85. if node['roles'].include? role
  86. nodes << node
  87. end
  88. if !single || nodes.empty?
  89. search(:node, "role:#{role} AND chef_environment:#{node.chef_environment}") do |n|
  90. nodes << n
  91. end
  92. end
  93. if block
  94. nodes.each do |n|
  95. yield n
  96. end
  97. else
  98. if single
  99. nodes.first
  100. else
  101. nodes
  102. end
  103. end
  104. end
  105. end
  106. end
  107. class Provider
  108. module ApplicationBase
  109. def self.included(klass)
  110. klass.extend Chef::Mixin::FromFile
  111. end
  112. def release_path
  113. if !@deploy_provider
  114. #@deploy_provider = Chef::Platform.provider_for_resource(@run_context.resource_collection.find(:deploy_revision => @new_resource.id))
  115. @deploy_provider = Chef::Platform.provider_for_resource(@deploy_resource)
  116. @deploy_provider.load_current_resource
  117. end
  118. @deploy_provider.release_path
  119. end
  120. def callback(what, callback_code=nil)
  121. Chef::Log.debug("Got callback #{what}: #{callback_code.inspect}")
  122. @collection = Chef::ResourceCollection.new
  123. case callback_code
  124. when Proc
  125. Chef::Log.info "#{@new_resource} running callback #{what}"
  126. recipe_eval(&callback_code)
  127. when String
  128. callback_file = "#{release_path}/#{callback_code}"
  129. unless ::File.exist?(callback_file)
  130. raise RuntimeError, "Can't find your callback file #{callback_file}"
  131. end
  132. run_callback_from_file(callback_file)
  133. when nil
  134. nil
  135. else
  136. raise RuntimeError, "You gave me a callback I don't know what to do with: #{callback_code.inspect}"
  137. end
  138. end
  139. def run_callback_from_file(callback_file)
  140. if ::File.exist?(callback_file)
  141. Dir.chdir(release_path) do
  142. Chef::Log.info "#{@new_resource} running deploy hook #{callback_file}"
  143. recipe_eval { from_file(callback_file) }
  144. end
  145. end
  146. end
  147. end
  148. end
  149. end