compat_resource-12.10.5/0000755000004100000410000000000012724341277015113 5ustar www-datawww-datacompat_resource-12.10.5/Rakefile0000644000004100000410000002003012724341276016552 0ustar www-datawww-datarequire 'bundler/gem_tasks' require 'rspec/core/rake_task' require 'stove/rake_task' require 'fileutils' RSpec::Core::RakeTask.new(:spec) do |t| t.pattern = FileList['files/spec/**/*_spec.rb'] end Stove::RakeTask.new task default: :spec # # "rake update" updates the copied_from_chef files so we can grab bugfixes or new features # CHEF_FILES = %w( chef/constants chef/delayed_evaluator chef/dsl/core chef/dsl/declare_resource chef/dsl/recipe chef/mixin/lazy_module_include chef/mixin/notifying_block chef/mixin/params_validate chef/mixin/powershell_out chef/mixin/properties chef/property chef/provider chef/provider/noop chef/resource chef/resource/action_class chef/resource_builder ) SPEC_FILES = %w( unit/mixin/properties_spec.rb unit/property_spec.rb unit/property/state_spec.rb unit/property/validation_spec.rb integration/recipes/resource_action_spec.rb integration/recipes/resource_converge_if_changed_spec.rb integration/recipes/resource_load_spec.rb ) KEEP_FUNCTIONS = { 'chef/resource' => %w( initialize name resource_name self.use_automatic_resource_name identity state state_for_resource_reporter property_is_set reset_property resource_initializing resource_initializing= to_hash self.properties self.state_properties self.state_attr self.identity_properties self.identity_property self.identity_attrs self.property self.property_type self.lazy action allowed_actions self.allowed_actions self.default_action self.action self.declare_action_class self.action_class load_current_value current_value_does_not_exist self.load_current_value ), 'chef/provider' => %w( initialize converge_if_changed compile_and_converge_action action self.use_inline_resources self.include_resource_dsl self.include_resource_dsl_module ), 'chef/dsl/recipe' => %w(), } KEEP_INCLUDES = { 'chef/resource' => %w(Chef::Mixin::ParamsValidate Chef::Mixin::Properties), 'chef/provider' => %w(Chef::DSL::Core), 'chef/dsl/recipe' => %w(Chef::DSL::Core Chef::DSL::Recipe Chef::Mixin::LazyModuleInclude), } KEEP_CLASSES = { 'chef/provider' => %w(Chef::Provider Chef::Provider::InlineResources Chef::Provider::InlineResources::ClassMethods) } SKIP_LINES = { 'chef/dsl/recipe' => [ /include Chef::Mixin::PowershellOut/ ] } PROCESS_LINES = { } # See chef_compat/resource for def. of resource_name and provider # See chef_compat/monkeypatches/chef/resource for def. of current_value desc "Pull new files from the chef client this is bundled with and update this cookbook" task :update do # Copy files from chef to chef_compat/chef, with a few changes target_path = File.expand_path("../files/lib/chef_compat/copied_from_chef", __FILE__) chef_gem_path = Bundler.environment.specs['chef'].first.full_gem_path CHEF_FILES.each do |file| output = StringIO.new # First lets try to load the original file if it exists output.puts "begin" output.puts " require '#{file}'" output.puts "rescue LoadError; end" output.puts "" # Wrap the whole thing in a ChefCompat module output.puts "require 'chef_compat/copied_from_chef'" output.puts "class Chef" output.puts "module ::ChefCompat" output.puts "module CopiedFromChef" # Bring over the Chef file chef_contents = IO.read(File.join(chef_gem_path, 'lib', "#{file}.rb")) skip_until = nil keep_until = nil in_class = [] chef_contents.lines.each do |line| if keep_until keep_until = nil if keep_until === line else if skip_until skip_until = nil if skip_until === line next end # If this file only keeps certain functions, detect which function we are # in and only keep those. Also strip comments outside functions case line # Skip modules and classes that aren't part of our list when /\A(\s*)def\s+([A-Za-z0-9_.]+)/ if KEEP_FUNCTIONS[file] && !KEEP_FUNCTIONS[file].include?($2) skip_until = /\A#{$1}end\s*$/ next else function = $2 # Keep everything inside a function no matter what it is keep_until = /\A#{$1}end\s*$/ end # Skip comments and whitespace if we're narrowing the file (otherwise it # looks super weird) when /\A\s*#/, /\A\s*$/ next if KEEP_CLASSES[file] || KEEP_FUNCTIONS[file] # Skip aliases/attrs/properties that we're not keeping when /\A\s*(attr_reader|attr_writer|attr_accessor|property|alias)\s*:(\w+)/ next if KEEP_FUNCTIONS[file] && !KEEP_FUNCTIONS[file].include?($2) # Skip includes and extends that we're not keeping when /\A\s*(include|extend)\s*([A-Za-z0-9_:]+)/ next if KEEP_INCLUDES[file] && !KEEP_INCLUDES[file].include?($2) end next if SKIP_LINES[file] && SKIP_LINES[file].any? { |skip| skip === line } end # If we are at the end of a class, pop in_class if in_class[-1] && in_class[-1][:until].match(line) class_name = in_class.pop[:name] # Don't bother printing classes/modules that we're not going to print anything under next if KEEP_CLASSES[file] && !KEEP_CLASSES[file].any? { |c| c.start_with?(class_name) } # Detect class open elsif line =~ /\A(\s*)(class|module)(\s+)([A-Za-z0-9_:]+)(\s*<\s*([A-Za-z0-9_:]+))?.*$/ indent, type, space, class_name, _, superclass_name = $1, $2, $3, $4, $5, $6 full_class_name = in_class[-1] ? "#{in_class[-1][:name]}::#{class_name}" : class_name in_class << { name: full_class_name, until: /\A#{indent}end\s*$/ } superclass_name ||= "Object" # Don't print the class open unless it contains stuff we'll keep next if KEEP_CLASSES[file] && !KEEP_CLASSES[file].any? { |c| c.start_with?(full_class_name) } # Fix the class to extend from its parent original_class = "::#{full_class_name}" if type == 'class' line = "#{indent}#{type}#{space}#{class_name} < (defined?(#{original_class}) ? #{original_class} : #{superclass_name})" else # Modules have a harder time of it because of self methods line += "#{indent} CopiedFromChef.extend_chef_module(#{original_class}, self) if defined?(#{original_class})" end # If we're not in a class we care about, don't print stuff elsif KEEP_CLASSES[file] && in_class[-1] && !KEEP_CLASSES[file].any? { |c| c == in_class[-1][:name] } next end # Modify requires to overridden files to bring in the local version if line =~ /\A(\s*require\s*['"])([^'"]+)(['"].*)/ if CHEF_FILES.include?($2) line = "#{$1}chef_compat/copied_from_chef/#{$2}#{$3}" else next end end line = PROCESS_LINES[file].call(line) if PROCESS_LINES[file] output.puts line # If this was the header for an initialize function, write out "super" if function == 'initialize' output.puts "super if defined?(::#{in_class[-1][:name]})" end end # Close the ChefCompat module declaration from the top output.puts "end" output.puts "end" output.puts "end" # Write out the file in chef_compat target_file = File.join(target_path, "#{file}.rb") if !File.exist?(target_file) || IO.read(target_file) != output.string puts "Writing #{target_file} ..." FileUtils.mkdir_p(File.dirname(target_file)) File.open(target_file, "w") { |f| f.write(output.string) } end end # SPEC_FILES.each do |file| # target_path = File.expand_path("../files/spec/copied_from_chef", __FILE__) # source_file = File.join(chef_gem_path, 'lib', "#{file}.rb") # target_file = File.join(target_path, "#{file}") # end end compat_resource-12.10.5/Gemfile0000644000004100000410000000016012724341276016402 0ustar www-datawww-datasource 'https://rubygems.org' gemspec gem 'stove' if ENV['GEMFILE_MOD'] instance_eval(ENV['GEMFILE_MOD']) end compat_resource-12.10.5/files/0000755000004100000410000000000012724341276016214 5ustar www-datawww-datacompat_resource-12.10.5/files/spec/0000755000004100000410000000000012724341276017146 5ustar www-datawww-datacompat_resource-12.10.5/files/spec/data/0000755000004100000410000000000012724341276020057 5ustar www-datawww-datacompat_resource-12.10.5/files/spec/data/Gemfile0000644000004100000410000000015712724341276021355 0ustar www-datawww-datasource 'https://rubygems.org' if ENV['GEMFILE_MOD'] instance_eval(ENV['GEMFILE_MOD']) else gem 'chef' end compat_resource-12.10.5/files/spec/data/nodes/0000755000004100000410000000000012724341276021167 5ustar www-datawww-datacompat_resource-12.10.5/files/spec/data/nodes/ettores-mbp.lan.json0000644000004100000410000000003712724341276025074 0ustar www-datawww-data{ "name": "ettores-mbp.lan" }compat_resource-12.10.5/files/spec/data/config.rb0000644000004100000410000000011012724341276021641 0ustar www-datawww-datalocal_mode true chef_repo_path File.dirname(__FILE__) #log_level :debug compat_resource-12.10.5/files/spec/data/cookbooks/0000755000004100000410000000000012724341276022050 5ustar www-datawww-datacompat_resource-12.10.5/files/spec/data/cookbooks/hybrid/0000755000004100000410000000000012724341276023331 5ustar www-datawww-datacompat_resource-12.10.5/files/spec/data/cookbooks/hybrid/resources/0000755000004100000410000000000012724341276025343 5ustar www-datawww-datacompat_resource-12.10.5/files/spec/data/cookbooks/hybrid/resources/resource.rb0000644000004100000410000000014112724341276027513 0ustar www-datawww-data actions :create default_action :create attribute :x, kind_of: [ String ], name_attribute: true compat_resource-12.10.5/files/spec/data/cookbooks/hybrid/metadata.rb0000644000004100000410000000017612724341276025442 0ustar www-datawww-dataname "hybrid" description "cookbook that depends on compat_resource, but has LWRPs" version "1.0.0" depends "compat_resource" compat_resource-12.10.5/files/spec/data/cookbooks/hybrid/providers/0000755000004100000410000000000012724341276025346 5ustar www-datawww-datacompat_resource-12.10.5/files/spec/data/cookbooks/hybrid/providers/resource.rb0000644000004100000410000000006712724341276027525 0ustar www-datawww-dataaction :create do converge_by "update!" do end end compat_resource-12.10.5/files/spec/data/cookbooks/hybrid/libraries/0000755000004100000410000000000012724341276025305 5ustar www-datawww-datacompat_resource-12.10.5/files/spec/data/cookbooks/hybrid/libraries/normal_hwrp.rb0000644000004100000410000000070512724341276030164 0ustar www-datawww-dataclass Chef::Resource::NormalHwrp < Chef::Resource def initialize(*args) super @resource_name = :normal_hwrp @allowed_actions = [ :create ] @action = :create end provides :normal_hwrp def x(arg=nil) set_or_return(:x, arg, {}) end end class Chef::Provider::NormalHwrp < Chef::Resource provides :normal_hwrp def load_current_resource end def action_create new_resource.updated_by_last_resource(true) end end compat_resource-12.10.5/files/spec/data/cookbooks/future/0000755000004100000410000000000012724341276023362 5ustar www-datawww-datacompat_resource-12.10.5/files/spec/data/cookbooks/future/resources/0000755000004100000410000000000012724341276025374 5ustar www-datawww-datacompat_resource-12.10.5/files/spec/data/cookbooks/future/resources/super_resource.rb0000644000004100000410000000020412724341276030762 0ustar www-datawww-datainclude FutureCookbook::SuperProperties action :create do file ::File.expand_path('~/y.txt') do content "#{x}#{y}" end end compat_resource-12.10.5/files/spec/data/cookbooks/future/resources/resource.rb0000644000004100000410000000201312724341276027544 0ustar www-datawww-data# Make sure and emit a property that triggers deprecation property :n, name_property: true, default: 5 property :x, String, coerce: proc { |x| x.to_s }, default: lazy { y*y } property :y, Integer, default: 4 class ::Globals @@exists = true def self.exists @@exists end def self.exists=(value) @@exists = value end @@global_x = 'initial_x' def self.global_x @@global_x end def self.global_x=(value) @@global_x = value end @@global_y = 2 def self.global_y @@global_y end def self.global_y=(value) @@global_y = value end end load_current_value do current_value_does_not_exist! if !Globals.exists x Globals.global_x y Globals.global_y end action :create do converge_if_changed do Globals.exists = true Globals.global_x = x Globals.global_y = y end file ::File.expand_path('~/x.txt') do content 'hi' end # return is how people exit from 12.5 actions. Test that it works across versions. return end action :delete do Globals.exists = false end compat_resource-12.10.5/files/spec/data/cookbooks/future/metadata.rb0000644000004100000410000000015712724341276025472 0ustar www-datawww-dataname "future" description "cookbook that depends on compat_resource" version "1.0.0" depends "compat_resource" compat_resource-12.10.5/files/spec/data/cookbooks/future/libraries/0000755000004100000410000000000012724341276025336 5ustar www-datawww-datacompat_resource-12.10.5/files/spec/data/cookbooks/future/libraries/super_properties.rb0000644000004100000410000000023612724341276031276 0ustar www-datawww-datamodule FutureCookbook module SuperProperties include ChefCompat::Mixin::Properties property :x, default: 10 property :y, default: 20 end end compat_resource-12.10.5/files/spec/data/cookbooks/future/libraries/future_custom_resource.rb0000644000004100000410000000045712724341276032504 0ustar www-datawww-dataclass FutureCustomResource < ChefCompat::Resource resource_name :future_custom_resource property :x action :create do converge_if_changed do end future_custom_resource 'hi' do x x # test that a warning is emitted properly (and no crashey) action :nothing end end end compat_resource-12.10.5/files/spec/data/cookbooks/future/recipes/0000755000004100000410000000000012724341276025014 5ustar www-datawww-datacompat_resource-12.10.5/files/spec/data/cookbooks/future/recipes/declare_resource.rb0000644000004100000410000000014412724341276030646 0ustar www-datawww-datadeclare_resource(:ruby_block, 'y', caller[0], create_if_missing: true) do block { puts 'hi' } end compat_resource-12.10.5/files/spec/data/cookbooks/test/0000755000004100000410000000000012724341276023027 5ustar www-datawww-datacompat_resource-12.10.5/files/spec/data/cookbooks/test/metadata.rb0000644000004100000410000000016012724341276025131 0ustar www-datawww-dataname "test" description "le test cookbook" version "1.0.0" depends "normal" depends "future" # depends "hybrid" compat_resource-12.10.5/files/spec/data/cookbooks/test/recipes/0000755000004100000410000000000012724341276024461 5ustar www-datawww-datacompat_resource-12.10.5/files/spec/data/cookbooks/test/recipes/default.rb0000644000004100000410000000032512724341276026432 0ustar www-datawww-datanormal_resource 'blah' do x 'hi' end # normal_hwrp 'blah2' do # x 'hi2' # end future_resource 'blah3' do x 'hi3' end future_custom_resource 'blah4' do x 'hi4' end include_recipe 'future::declare_resource' compat_resource-12.10.5/files/spec/data/cookbooks/test/recipes/test.rb0000644000004100000410000000124112724341276025763 0ustar www-datawww-datafuture_resource 'sets neither x nor y' do end future_resource 'sets both x and y' do x 'hi' y 10 end future_resource 'sets neither x nor y explicitly' do x 'hi' y 10 end future_resource 'sets only y' do y 20 end future_resource 'deletes resource' do action :delete end future_resource 'sets x and y via creation' do x 'hi' y 20 end future_resource 'deletes resource again' do action :delete end future_resource 'sets x and y to their defaults via creation' do end future_super_resource 'brings in its defaults' do end future_super_resource 'lets you set x and y' do x 100 y 200 end ChefCompat::CopiedFromChef::Chef.log_deprecation "hi there" compat_resource-12.10.5/files/spec/data/cookbooks/normal/0000755000004100000410000000000012724341276023340 5ustar www-datawww-datacompat_resource-12.10.5/files/spec/data/cookbooks/normal/resources/0000755000004100000410000000000012724341276025352 5ustar www-datawww-datacompat_resource-12.10.5/files/spec/data/cookbooks/normal/resources/resource.rb0000644000004100000410000000014012724341276027521 0ustar www-datawww-dataactions :create default_action :create attribute :x, kind_of: [ String ], name_attribute: true compat_resource-12.10.5/files/spec/data/cookbooks/normal/metadata.rb0000644000004100000410000000013512724341276025444 0ustar www-datawww-dataname "normal" description "cookbook that does not depend on compat_resource" version "1.0.0" compat_resource-12.10.5/files/spec/data/cookbooks/normal/providers/0000755000004100000410000000000012724341276025355 5ustar www-datawww-datacompat_resource-12.10.5/files/spec/data/cookbooks/normal/providers/resource.rb0000644000004100000410000000021212724341276027524 0ustar www-datawww-dataaction :create do converge_by "update!" do end # next is how people generally exit from actions in traditional providers next end compat_resource-12.10.5/files/spec/data/cookbooks/normal/libraries/0000755000004100000410000000000012724341276025314 5ustar www-datawww-datacompat_resource-12.10.5/files/spec/data/cookbooks/normal/libraries/normal_hwrp.rb0000644000004100000410000000070512724341276030173 0ustar www-datawww-dataclass Chef::Resource::NormalHwrp < Chef::Resource def initialize(*args) super @resource_name = :normal_hwrp @allowed_actions = [ :create ] @action = :create end provides :normal_hwrp def x(arg=nil) set_or_return(:x, arg, {}) end end class Chef::Provider::NormalHwrp < Chef::Resource provides :normal_hwrp def load_current_resource end def action_create new_resource.updated_by_last_resource(true) end end compat_resource-12.10.5/files/spec/data/cookbooks/normal/recipes/0000755000004100000410000000000012724341276024772 5ustar www-datawww-datacompat_resource-12.10.5/files/spec/data/cookbooks/normal/recipes/declare_resource.rb0000644000004100000410000000014412724341276030624 0ustar www-datawww-datadeclare_resource(:ruby_block, 'y', caller[0], create_if_missing: true) do block { puts 'hi' } end compat_resource-12.10.5/files/spec/data/cookbooks/cloning/0000755000004100000410000000000012724341276023501 5ustar www-datawww-datacompat_resource-12.10.5/files/spec/data/cookbooks/cloning/resources/0000755000004100000410000000000012724341276025513 5ustar www-datawww-datacompat_resource-12.10.5/files/spec/data/cookbooks/cloning/resources/resource.rb0000644000004100000410000000005312724341276027665 0ustar www-datawww-dataprovides :resource resource_name :resource compat_resource-12.10.5/files/spec/data/cookbooks/cloning/metadata.rb0000644000004100000410000000013612724341276025606 0ustar www-datawww-dataname "cloning" description "cookbook that DOES NOT depend on compat_resource" version "1.0.0" compat_resource-12.10.5/files/spec/data/cookbooks/cloning/providers/0000755000004100000410000000000012724341276025516 5ustar www-datawww-datacompat_resource-12.10.5/files/spec/data/cookbooks/cloning/providers/resource.rb0000644000004100000410000000015412724341276027672 0ustar www-datawww-dataprovides :resource use_inline_resources action :create do log "stuff" do only_if { true } end end compat_resource-12.10.5/files/spec/data/cookbooks/cloning/recipes/0000755000004100000410000000000012724341276025133 5ustar www-datawww-datacompat_resource-12.10.5/files/spec/data/cookbooks/cloning/recipes/default.rb0000644000004100000410000000003512724341276027102 0ustar www-datawww-datalog "stuff" resource "doit" compat_resource-12.10.5/files/spec/data/cookbooks/notifications/0000755000004100000410000000000012724341276024721 5ustar www-datawww-datacompat_resource-12.10.5/files/spec/data/cookbooks/notifications/resources/0000755000004100000410000000000012724341276026733 5ustar www-datawww-datacompat_resource-12.10.5/files/spec/data/cookbooks/notifications/resources/resource.rb0000644000004100000410000000017712724341276031114 0ustar www-datawww-dataprovides :resource resource_name :resource action :create do log "resource" do notifies :write, "log[recipe]" end end compat_resource-12.10.5/files/spec/data/cookbooks/notifications/metadata.rb0000644000004100000410000000016612724341276027031 0ustar www-datawww-dataname "notifications" description "cookbook that depends on compat_resource" version "1.0.0" depends "compat_resource" compat_resource-12.10.5/files/spec/data/cookbooks/notifications/recipes/0000755000004100000410000000000012724341276026353 5ustar www-datawww-datacompat_resource-12.10.5/files/spec/data/cookbooks/notifications/recipes/default.rb0000644000004100000410000000006712724341276030327 0ustar www-datawww-datalog "recipe" do action :nothing end resource "doit" compat_resource-12.10.5/files/spec/spec_helper.rb0000644000004100000410000000030512724341276021762 0ustar www-datawww-datarequire 'cheffish/rspec' RSpec.configure do |config| config.filter_run :focus => true config.run_all_when_everything_filtered = true config.before :each do Chef::Config.reset end end compat_resource-12.10.5/files/spec/cookbook_spec.rb0000644000004100000410000000711112724341276022313 0ustar www-datawww-datarequire 'tmpdir' require 'chef/version' describe "compat_resource cookbook" do let(:chef_repo_path) { Dir.mktmpdir } let(:cookbooks_path) { path = File.join(chef_repo_path, 'cookbooks'); Dir.mkdir(path); path } before do File.symlink(File.expand_path('../data/config.rb', __FILE__), File.join(chef_repo_path, 'config.rb')) File.symlink(File.expand_path('../../..', __FILE__), File.join(cookbooks_path, 'compat_resource')) File.symlink(File.expand_path('../data/cookbooks/test', __FILE__), File.join(cookbooks_path, 'test')) File.symlink(File.expand_path('../data/cookbooks/future', __FILE__), File.join(cookbooks_path, 'future')) File.symlink(File.expand_path('../data/cookbooks/normal', __FILE__), File.join(cookbooks_path, 'normal')) File.symlink(File.expand_path('../data/cookbooks/hybrid', __FILE__), File.join(cookbooks_path, 'hybrid')) File.symlink(File.expand_path('../data/cookbooks/notifications', __FILE__), File.join(cookbooks_path, 'notifications')) File.symlink(File.expand_path('../data/cookbooks/cloning', __FILE__), File.join(cookbooks_path, 'cloning')) end require 'chef/mixin/shell_out' include Chef::Mixin::ShellOut before :all do FileUtils.rm_f(File.expand_path('../data/Gemfile.lock', __FILE__)) Bundler.with_clean_env do shell_out!("bundle install --gemfile #{File.expand_path('../data/Gemfile', __FILE__)}") end end def run_chef(args) Bundler.with_clean_env do shell_out!("bundle exec chef-client -c #{File.join(chef_repo_path, 'config.rb')} -F doc #{args}", environment: { 'BUNDLE_GEMFILE' => File.expand_path('../data/Gemfile', __FILE__) }) end end it "should handle new-style recursive notifications" do result = run_chef("-o notifications") puts result.stdout puts result.stderr end it "should not clone resources from the outer run context" do result = run_chef("-o future::declare_resource,cloning::default") expect(result.stdout).not_to match(/3694/) end it "when chef-client runs the test recipe, it succeeds" do result = run_chef("-o test::test,test") puts result.stdout puts result.stderr # expect(result.stdout).to match(/ # Recipe: test::test # \* future_resource\[sets neither x nor y\] action create \(up to date\) # \* future_resource\[sets both x and y\] action create # - update sets both x and y # - set x to "hi" \(was "initial_x"\) # - set y to 10 \(was 2\) # \* future_resource\[sets neither x nor y explicitly\] action create \(up to date\) # \* future_resource\[sets only y\] action create # - update sets only y # - set y to 20 (was 10) # \* future_resource\[deletes resource\] action delete \(up to date\) # \* future_resource\[sets x and y via creation\] action create # - create sets x and y via creation # - set x to "hi" # - set y to 20 # \* future_resource\[deletes resource again\] action delete \(up to date\) # \* future_resource\[sets x and y to their defaults via creation\] action create # - create sets x and y to their defaults via creation # - set x to "16" \(default value\) # - set y to 4 \(default value\) # /) end if Gem::Requirement.new("< 12.6").satisfied_by?(Gem::Version.new(Chef::VERSION)) it "when chef-client tries to declare_resource with extra parameters, it fails" do expect { run_chef("-o normal::declare_resource") }.to raise_error(Mixlib::ShellOut::ShellCommandFailed) end end end compat_resource-12.10.5/files/lib/0000755000004100000410000000000012724341276016762 5ustar www-datawww-datacompat_resource-12.10.5/files/lib/compat_resource.rb0000644000004100000410000000153112724341276022501 0ustar www-datawww-dataif Gem::Requirement.new(">= 12.0").satisfied_by?(Gem::Version.new(Chef::VERSION)) require 'compat_resource/version' require 'compat_resource/gemspec' require 'chef_compat/resource' require 'chef_compat/property' require 'chef_compat/mixin/properties' else class Chef class Resource def self.property(args, &block) raise_chef_11_error end def self.resource_name(args, &block) raise_chef_11_error end def self.action(args, &block) raise_chef_11_error end def self.raise_chef_11_error raise "This resource is written with Chef 12.5 custom resources, and requires at least Chef 12.0 used with the compat_resource cookbook, it will not work with Chef 11.x clients, and those users must pin their cookbooks to older versions or upgrade." end end end end compat_resource-12.10.5/files/lib/chef_compat/0000755000004100000410000000000012724341276021232 5ustar www-datawww-datacompat_resource-12.10.5/files/lib/chef_compat/mixin/0000755000004100000410000000000012724341276022356 5ustar www-datawww-datacompat_resource-12.10.5/files/lib/chef_compat/mixin/properties.rb0000644000004100000410000000032212724341276025074 0ustar www-datawww-datarequire 'chef_compat/monkeypatches' require 'chef_compat/copied_from_chef/chef/mixin/properties' module ChefCompat module Mixin Properties = ChefCompat::CopiedFromChef::Chef::Mixin::Properties end end compat_resource-12.10.5/files/lib/chef_compat/resource/0000755000004100000410000000000012724341276023061 5ustar www-datawww-datacompat_resource-12.10.5/files/lib/chef_compat/resource/lwrp_base.rb0000644000004100000410000000251212724341276025364 0ustar www-datawww-datarequire 'chef_compat/resource' require 'chef_compat/copied_from_chef/chef/resource' require 'chef/mixin/convert_to_class_name' require 'chef/mixin/from_file' module ChefCompat class Resource < ChefCompat::CopiedFromChef::Chef::Resource class LWRPBase < ChefCompat::Resource class<] The list of property names and types. # def properties(include_superclass = true) if include_superclass result = {} ancestors.reverse_each { |c| result.merge!(c.properties(false)) if c.respond_to?(:properties) } result else @properties ||= {} end end # # Create a property on this resource class. # # If a superclass has this property, or if this property has already been # defined by this resource, this will *override* the previous value. # # @param name [Symbol] The name of the property. # @param type [Object,Array] The type(s) of this property. # If present, this is prepended to the `is` validation option. # @param options [Hash] Validation options. # @option options [Object,Array] :is An object, or list of # objects, that must match the value using Ruby's `===` operator # (`options[:is].any? { |v| v === value }`). # @option options [Object,Array] :equal_to An object, or list # of objects, that must be equal to the value using Ruby's `==` # operator (`options[:is].any? { |v| v == value }`) # @option options [Regexp,Array] :regex An object, or # list of objects, that must match the value with `regex.match(value)`. # @option options [Class,Array] :kind_of A class, or # list of classes, that the value must be an instance of. # @option options [Hash] :callbacks A hash of # messages -> procs, all of which match the value. The proc must # return a truthy or falsey value (true means it matches). # @option options [Symbol,Array] :respond_to A method # name, or list of method names, the value must respond to. # @option options [Symbol,Array] :cannot_be A property, # or a list of properties, that the value cannot have (such as `:nil` or # `:empty`). The method with a questionmark at the end is called on the # value (e.g. `value.empty?`). If the value does not have this method, # it is considered valid (i.e. if you don't respond to `empty?` we # assume you are not empty). # @option options [Proc] :coerce A proc which will be called to # transform the user input to canonical form. The value is passed in, # and the transformed value returned as output. Lazy values will *not* # be passed to this method until after they are evaluated. Called in the # context of the resource (meaning you can access other properties). # @option options [Boolean] :required `true` if this property # must be present; `false` otherwise. This is checked after the resource # is fully initialized. # @option options [Boolean] :name_property `true` if this # property defaults to the same value as `name`. Equivalent to # `default: lazy { name }`, except that #property_is_set? will # return `true` if the property is set *or* if `name` is set. # @option options [Boolean] :name_attribute Same as `name_property`. # @option options [Object] :default The value this property # will return if the user does not set one. If this is `lazy`, it will # be run in the context of the instance (and able to access other # properties). # @option options [Boolean] :desired_state `true` if this property is # part of desired state. Defaults to `true`. # @option options [Boolean] :identity `true` if this property # is part of object identity. Defaults to `false`. # # @example Bare property # property :x # # @example With just a type # property :x, String # # @example With just options # property :x, default: 'hi' # # @example With type and options # property :x, String, default: 'hi' # def property(name, type = NOT_PASSED, **options) name = name.to_sym options = options.inject({}) { |memo, (key, value)| memo[key.to_sym] = value; memo } options[:instance_variable_name] = :"@#{name}" if !options.has_key?(:instance_variable_name) options[:name] = name options[:declared_in] = self if type == NOT_PASSED # If a type is not passed, the property derives from the # superclass property (if any) if properties.has_key?(name) property = properties[name].derive(**options) else property = property_type(**options) end # If a Property is specified, derive a new one from that. elsif type.is_a?(Property) || (type.is_a?(Class) && type <= Property) property = type.derive(**options) # If a primitive type was passed, combine it with "is" else if options[:is] options[:is] = ([ type ] + [ options[:is] ]).flatten(1) else options[:is] = type end property = property_type(**options) end local_properties = properties(false) local_properties[name] = property property.emit_dsl end # # Create a reusable property type that can be used in multiple properties # in different resources. # # @param options [Hash] Validation options. see #property for # the list of options. # # @example # property_type(default: 'hi') # def property_type(**options) Property.derive(**options) end # # Create a lazy value for assignment to a default value. # # @param block The block to run when the value is retrieved. # # @return [Chef::DelayedEvaluator] The lazy value # def lazy(&block) DelayedEvaluator.new(&block) end # # Get or set the list of desired state properties for this resource. # # State properties are properties that describe the desired state # of the system, such as file permissions or ownership. # In general, state properties are properties that could be populated by # examining the state of the system (e.g., File.stat can tell you the # permissions on an existing file). Contrarily, properties that are not # "state properties" usually modify the way Chef itself behaves, for example # by providing additional options for a package manager to use when # installing a package. # # This list is used by the Chef client auditing system to extract # information from resources to describe changes made to the system. # # This method is unnecessary when declaring properties with `property`; # properties are added to state_properties by default, and can be turned off # with `desired_state: false`. # # ```ruby # property :x # part of desired state # property :y, desired_state: false # not part of desired state # ``` # # @param names [Array] A list of property names to set as desired # state. # # @return [Array] All properties in desired state. # def state_properties(*names) if !names.empty? names = names.map { |name| name.to_sym }.uniq local_properties = properties(false) # Add new properties to the list. names.each do |name| property = properties[name] if !property self.property name, instance_variable_name: false, desired_state: true elsif !property.desired_state? self.property name, desired_state: true end end # If state_attrs *excludes* something which is currently desired state, # mark it as desired_state: false. local_properties.each do |name, property| if property.desired_state? && !names.include?(name) self.property name, desired_state: false end end end properties.values.select { |property| property.desired_state? } end # # Set the identity of this resource to a particular set of properties. # # This drives #identity, which returns data that uniquely refers to a given # resource on the given node (in such a way that it can be correlated # across Chef runs). # # This method is unnecessary when declaring properties with `property`; # properties can be added to identity during declaration with # `identity: true`. # # ```ruby # property :x, identity: true # part of identity # property :y # not part of identity # ``` # # If no properties are marked as identity, "name" is considered the identity. # # @param names [Array] A list of property names to set as the identity. # # @return [Array] All identity properties. # def identity_properties(*names) if !names.empty? names = names.map { |name| name.to_sym } # Add or change properties that are not part of the identity. names.each do |name| property = properties[name] if !property self.property name, instance_variable_name: false, identity: true elsif !property.identity? self.property name, identity: true end end # If identity_properties *excludes* something which is currently part of # the identity, mark it as identity: false. properties.each do |name, property| if property.identity? && !names.include?(name) self.property name, identity: false end end end result = properties.values.select { |property| property.identity? } result = [ properties[:name] ] if result.empty? result end def included(other) other.extend ClassMethods end end def self.included(other) other.extend ClassMethods end include Chef::Mixin::ParamsValidate # # Whether this property has been set (or whether it has a default that has # been retrieved). # # @param name [Symbol] The name of the property. # @return [Boolean] `true` if the property has been set. # def property_is_set?(name) property = self.class.properties[name.to_sym] raise ArgumentError, "Property #{name} is not defined in class #{self}" if !property property.is_set?(self) end # # Clear this property as if it had never been set. It will thereafter return # the default. # been retrieved). # # @param name [Symbol] The name of the property. # def reset_property(name) property = self.class.properties[name.to_sym] raise ArgumentError, "Property #{name} is not defined in class #{self}" if !property property.reset(self) end end end end end end end compat_resource-12.10.5/files/lib/chef_compat/copied_from_chef/chef/mixin/params_validate.rb0000644000004100000410000004374012724341276032227 0ustar www-datawww-databegin require 'chef/mixin/params_validate' rescue LoadError; end require 'chef_compat/copied_from_chef' class Chef module ::ChefCompat module CopiedFromChef # # Author:: Adam Jacob () # Copyright:: Copyright 2008-2016, Chef Software Inc. # License:: Apache License, Version 2.0 # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. require "chef_compat/copied_from_chef/chef/constants" require "chef_compat/copied_from_chef/chef/property" require "chef_compat/copied_from_chef/chef/delayed_evaluator" class Chef < (defined?(::Chef) ? ::Chef : Object) module Mixin CopiedFromChef.extend_chef_module(::Chef::Mixin, self) if defined?(::Chef::Mixin) module ParamsValidate CopiedFromChef.extend_chef_module(::Chef::Mixin::ParamsValidate, self) if defined?(::Chef::Mixin::ParamsValidate) # Takes a hash of options, along with a map to validate them. Returns the original # options hash, plus any changes that might have been made (through things like setting # default values in the validation map) # # For example: # # validate({ :one => "neat" }, { :one => { :kind_of => String }}) # # Would raise an exception if the value of :one above is not a kind_of? string. Valid # map options are: # # @param opts [Hash] Validation opts. # @option opts [Object,Array] :is An object, or list of # objects, that must match the value using Ruby's `===` operator # (`opts[:is].any? { |v| v === value }`). (See #_pv_is.) # @option opts [Object,Array] :equal_to An object, or list # of objects, that must be equal to the value using Ruby's `==` # operator (`opts[:is].any? { |v| v == value }`) (See #_pv_equal_to.) # @option opts [Regexp,Array] :regex An object, or # list of objects, that must match the value with `regex.match(value)`. # (See #_pv_regex) # @option opts [Class,Array] :kind_of A class, or # list of classes, that the value must be an instance of. (See # #_pv_kind_of.) # @option opts [Hash] :callbacks A hash of # messages -> procs, all of which match the value. The proc must # return a truthy or falsey value (true means it matches). (See # #_pv_callbacks.) # @option opts [Symbol,Array] :respond_to A method # name, or list of method names, the value must respond to. (See # #_pv_respond_to.) # @option opts [Symbol,Array] :cannot_be A property, # or a list of properties, that the value cannot have (such as `:nil` or # `:empty`). The method with a questionmark at the end is called on the # value (e.g. `value.empty?`). If the value does not have this method, # it is considered valid (i.e. if you don't respond to `empty?` we # assume you are not empty). (See #_pv_cannot_be.) # @option opts [Proc] :coerce A proc which will be called to # transform the user input to canonical form. The value is passed in, # and the transformed value returned as output. Lazy values will *not* # be passed to this method until after they are evaluated. Called in the # context of the resource (meaning you can access other properties). # (See #_pv_coerce.) (See #_pv_coerce.) # @option opts [Boolean] :required `true` if this property # must be present and not `nil`; `false` otherwise. This is checked # after the resource is fully initialized. (See #_pv_required.) # @option opts [Boolean] :name_property `true` if this # property defaults to the same value as `name`. Equivalent to # `default: lazy { name }`, except that #property_is_set? will # return `true` if the property is set *or* if `name` is set. (See # #_pv_name_property.) # @option opts [Boolean] :name_attribute Same as `name_property`. # @option opts [Object] :default The value this property # will return if the user does not set one. If this is `lazy`, it will # be run in the context of the instance (and able to access other # properties). (See #_pv_default.) # def validate(opts, map) map = map.validation_options if map.is_a?(Property) #-- # validate works by taking the keys in the validation map, assuming it's a hash, and # looking for _pv_:symbol as methods. Assuming it find them, it calls the right # one. #++ raise ArgumentError, "Options must be a hash" unless opts.kind_of?(Hash) raise ArgumentError, "Validation Map must be a hash" unless map.kind_of?(Hash) map.each do |key, validation| unless key.kind_of?(Symbol) || key.kind_of?(String) raise ArgumentError, "Validation map keys must be symbols or strings!" end case validation when true _pv_required(opts, key) when false true when Hash validation.each do |check, carg| check_method = "_pv_#{check}" if self.respond_to?(check_method, true) self.send(check_method, opts, key, carg) else raise ArgumentError, "Validation map has unknown check: #{check}" end end end end opts end def lazy(&block) DelayedEvaluator.new(&block) end def set_or_return(symbol, value, validation) property = SetOrReturnProperty.new(name: symbol, **validation) property.call(self, value) end private def explicitly_allows_nil?(key, validation) validation.has_key?(:is) && _pv_is({ key => nil }, key, validation[:is], raise_error: false) end # Return the value of a parameter, or nil if it doesn't exist. def _pv_opts_lookup(opts, key) if opts.has_key?(key.to_s) opts[key.to_s] elsif opts.has_key?(key.to_sym) opts[key.to_sym] else nil end end # Raise an exception if the parameter is not found. def _pv_required(opts, key, is_required = true, explicitly_allows_nil = false) if is_required return true if opts.has_key?(key.to_s) && (explicitly_allows_nil || !opts[key.to_s].nil?) return true if opts.has_key?(key.to_sym) && (explicitly_allows_nil || !opts[key.to_sym].nil?) raise Exceptions::ValidationFailed, "Required argument #{key.inspect} is missing!" end true end # # List of things values must be equal to. # # Uses Ruby's `==` to evaluate (equal_to == value). At least one must # match for the value to be valid. # # `nil` passes this validation automatically. # # @return [Array,nil] List of things values must be equal to, or nil if # equal_to is unspecified. # def _pv_equal_to(opts, key, to_be) value = _pv_opts_lookup(opts, key) unless value.nil? to_be = Array(to_be) to_be.each do |tb| return true if value == tb end raise Exceptions::ValidationFailed, "Option #{key} must be equal to one of: #{to_be.join(", ")}! You passed #{value.inspect}." end end # # List of things values must be instances of. # # Uses value.kind_of?(kind_of) to evaluate. At least one must match for # the value to be valid. # # `nil` automatically passes this validation. # def _pv_kind_of(opts, key, to_be) value = _pv_opts_lookup(opts, key) unless value.nil? to_be = Array(to_be) to_be.each do |tb| return true if value.kind_of?(tb) end raise Exceptions::ValidationFailed, "Option #{key} must be a kind of #{to_be}! You passed #{value.inspect}." end end # # List of method names values must respond to. # # Uses value.respond_to?(respond_to) to evaluate. At least one must match # for the value to be valid. # def _pv_respond_to(opts, key, method_name_list) value = _pv_opts_lookup(opts, key) unless value.nil? Array(method_name_list).each do |method_name| unless value.respond_to?(method_name) raise Exceptions::ValidationFailed, "Option #{key} must have a #{method_name} method!" end end end end # # List of things that must not be true about the value. # # Calls `value.?` All responses must be false for the value to be # valid. # Values which do not respond to ? are considered valid (because if # a value doesn't respond to `:readable?`, then it probably isn't # readable.) # # @example # ```ruby # property :x, cannot_be: [ :nil, :empty ] # x [ 1, 2 ] #=> valid # x 1 #=> valid # x [] #=> invalid # x nil #=> invalid # ``` # def _pv_cannot_be(opts, key, predicate_method_base_name) value = _pv_opts_lookup(opts, key) if !value.nil? Array(predicate_method_base_name).each do |method_name| predicate_method = :"#{method_name}?" if value.respond_to?(predicate_method) if value.send(predicate_method) raise Exceptions::ValidationFailed, "Option #{key} cannot be #{predicate_method_base_name}" end end end end end # # The default value for a property. # # When the property is not assigned, this will be used. # # If this is a lazy value, it will either be passed the resource as a value, # or if the lazy proc does not take parameters, it will be run in the # context of the instance with instance_eval. # # @example # ```ruby # property :x, default: 10 # ``` # # @example # ```ruby # property :x # property :y, default: lazy { x+2 } # ``` # # @example # ```ruby # property :x # property :y, default: lazy { |r| r.x+2 } # ``` # def _pv_default(opts, key, default_value) value = _pv_opts_lookup(opts, key) if value.nil? default_value = default_value.freeze if !default_value.is_a?(DelayedEvaluator) opts[key] = default_value end end # # List of regexes values that must match. # # Uses regex.match() to evaluate. At least one must match for the value to # be valid. # # `nil` passes regex validation automatically. # # @example # ```ruby # property :x, regex: [ /abc/, /xyz/ ] # ``` # def _pv_regex(opts, key, regex) value = _pv_opts_lookup(opts, key) if !value.nil? Array(regex).flatten.each do |r| return true if r.match(value.to_s) end raise Exceptions::ValidationFailed, "Option #{key}'s value #{value} does not match regular expression #{regex.inspect}" end end # # List of procs we pass the value to. # # All procs must return true for the value to be valid. If any procs do # not return true, the key will be used for the message: `"Property x's # value :y "`. # # @example # ```ruby # property :x, callbacks: { "is bigger than 10" => proc { |v| v <= 10 }, "is not awesome" => proc { |v| !v.awesome }} # ``` # def _pv_callbacks(opts, key, callbacks) raise ArgumentError, "Callback list must be a hash!" unless callbacks.kind_of?(Hash) value = _pv_opts_lookup(opts, key) if !value.nil? callbacks.each do |message, zeproc| unless zeproc.call(value) raise Exceptions::ValidationFailed, "Option #{key}'s value #{value} #{message}!" end end end end # # Allows a parameter to default to the value of the resource name. # # @example # ```ruby # property :x, name_property: true # ``` # def _pv_name_property(opts, key, is_name_property = true) if is_name_property if opts[key].nil? raise CannotValidateStaticallyError, "name_property cannot be evaluated without a resource." if self == Chef::Mixin::ParamsValidate opts[key] = self.instance_variable_get(:"@name") end end end alias :_pv_name_attribute :_pv_name_property # # List of valid things values can be. # # Uses Ruby's `===` to evaluate (is === value). At least one must match # for the value to be valid. # # If a proc is passed, it is instance_eval'd in the resource, passed the # value, and must return a truthy or falsey value. # # @example Class # ```ruby # property :x, String # x 'valid' #=> valid # x 1 #=> invalid # x nil #=> invalid # # @example Value # ```ruby # property :x, [ :a, :b, :c, nil ] # x :a #=> valid # x nil #=> valid # ``` # # @example Regex # ```ruby # property :x, /bar/ # x 'foobar' #=> valid # x 'foo' #=> invalid # x nil #=> invalid # ``` # # @example Proc # ```ruby # property :x, proc { |x| x > y } # property :y, default: 2 # x 3 #=> valid # x 1 #=> invalid # ``` # # @example Property # ```ruby # type = Property.new(is: String) # property :x, type # x 'foo' #=> valid # x 1 #=> invalid # x nil #=> invalid # ``` # # @example RSpec Matcher # ```ruby # include RSpec::Matchers # property :x, a_string_matching /bar/ # x 'foobar' #=> valid # x 'foo' #=> invalid # x nil #=> invalid # ``` # def _pv_is(opts, key, to_be, raise_error: true) return true if !opts.has_key?(key.to_s) && !opts.has_key?(key.to_sym) value = _pv_opts_lookup(opts, key) to_be = [ to_be ].flatten(1) errors = [] passed = to_be.any? do |tb| case tb when Proc raise CannotValidateStaticallyError, "is: proc { } must be evaluated once for each resource" if self == Chef::Mixin::ParamsValidate instance_exec(value, &tb) when Property begin validate(opts, { key => tb.validation_options }) true rescue Exceptions::ValidationFailed # re-raise immediately if there is only one "is" so we get a better stack raise if to_be.size == 1 errors << $! false end else tb === value end end if passed true else message = "Property #{key} must be one of: #{to_be.map { |v| v.inspect }.join(", ")}! You passed #{value.inspect}." unless errors.empty? message << " Errors:\n#{errors.map { |m| "- #{m}" }.join("\n")}" end raise Exceptions::ValidationFailed, message end end # # Method to mess with a value before it is validated and stored. # # Allows you to transform values into a canonical form that is easy to # work with. # # This is passed the value to transform, and is run in the context of the # instance (so it has access to other resource properties). It must return # the value that will be stored in the instance. # # @example # ```ruby # property :x, Integer, coerce: { |v| v.to_i } # ``` # def _pv_coerce(opts, key, coercer) if opts.has_key?(key.to_s) raise CannotValidateStaticallyError, "coerce must be evaluated for each resource." if self == Chef::Mixin::ParamsValidate opts[key.to_s] = instance_exec(opts[key], &coercer) elsif opts.has_key?(key.to_sym) raise CannotValidateStaticallyError, "coerce must be evaluated for each resource." if self == Chef::Mixin::ParamsValidate opts[key.to_sym] = instance_exec(opts[key], &coercer) end end # We allow Chef::Mixin::ParamsValidate.validate(), but we will raise an # error if you try to do anything requiring there to be an actual resource. # This way, you can statically validate things if you have constant validation # (which is the norm). extend self # Used by #set_or_return to avoid emitting a deprecation warning for # "value nil" and to keep default stickiness working exactly the same # @api private class SetOrReturnProperty < (defined?(::Chef::Mixin::ParamsValidate::SetOrReturnProperty) ? ::Chef::Mixin::ParamsValidate::SetOrReturnProperty : Chef::Property) def get(resource, nil_set: false) value = super # All values are sticky, frozen or not if !is_set?(resource) set_value(resource, value) end value end def call(resource, value = NOT_PASSED) # setting to nil does a get if value.nil? && !explicitly_accepts_nil?(resource) get(resource, nil_set: true) else super end end end end end end end end end compat_resource-12.10.5/files/lib/chef_compat/copied_from_chef/chef/mixin/lazy_module_include.rb0000644000004100000410000000467112724341276033122 0ustar www-datawww-databegin require 'chef/mixin/lazy_module_include' rescue LoadError; end require 'chef_compat/copied_from_chef' class Chef module ::ChefCompat module CopiedFromChef # # Copyright:: Copyright 2011-2016, Chef Software Inc. # License:: Apache License, Version 2.0 # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. # class Chef < (defined?(::Chef) ? ::Chef : Object) module Mixin CopiedFromChef.extend_chef_module(::Chef::Mixin, self) if defined?(::Chef::Mixin) # If you have: # # module A # extend LazyModuleInclude # end # # module B # include A # end # # module C # include B # end # # module Monkeypatches # def monkey # puts "monkey!" # end # end # # A.send(:include, Monkeypatches) # # Then B and C and any classes that they're included in will also get the #monkey method patched into them. # module LazyModuleInclude CopiedFromChef.extend_chef_module(::Chef::Mixin::LazyModuleInclude, self) if defined?(::Chef::Mixin::LazyModuleInclude) # Most of the magick is in this hook which creates a closure over the parent class and then builds an # "infector" module which infects all descendants and which is responsible for updating the list of # descendants in the parent class. def included(klass) super parent_klass = self infector = Module.new do define_method(:included) do |subklass| super(subklass) subklass.extend(infector) parent_klass.descendants.push(subklass) end end klass.extend(infector) parent_klass.descendants.push(klass) end def descendants @descendants ||= [] end def include(*classes) super classes.each do |klass| descendants.each do |descendant| descendant.send(:include, klass) end end end end end end end end end compat_resource-12.10.5/files/lib/chef_compat/copied_from_chef/chef/mixin/notifying_block.rb0000644000004100000410000000371512724341276032251 0ustar www-datawww-databegin require 'chef/mixin/notifying_block' rescue LoadError; end require 'chef_compat/copied_from_chef' class Chef module ::ChefCompat module CopiedFromChef #-- # Author:: Lamont Granquist # Copyright:: Copyright 2010-2016, Chef Software Inc. # License:: Apache License, Version 2.0 # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. class Chef < (defined?(::Chef) ? ::Chef : Object) module Mixin CopiedFromChef.extend_chef_module(::Chef::Mixin, self) if defined?(::Chef::Mixin) module NotifyingBlock CopiedFromChef.extend_chef_module(::Chef::Mixin::NotifyingBlock, self) if defined?(::Chef::Mixin::NotifyingBlock) def notifying_block(&block) begin subcontext = subcontext_block(&block) Chef::Runner.new(subcontext).converge ensure # recipes don't have a new_resource if respond_to?(:new_resource) if subcontext && subcontext.resource_collection.any?(&:updated?) new_resource.updated_by_last_action(true) end end end end def subcontext_block(parent_context = nil, &block) parent_context ||= @run_context sub_run_context = parent_context.create_child begin outer_run_context = @run_context @run_context = sub_run_context instance_eval(&block) ensure @run_context = outer_run_context end sub_run_context end end end end end end end compat_resource-12.10.5/files/lib/chef_compat/copied_from_chef/chef/resource/0000755000004100000410000000000012724341276027241 5ustar www-datawww-datacompat_resource-12.10.5/files/lib/chef_compat/copied_from_chef/chef/resource/action_class.rb0000644000004100000410000000666712724341276032247 0ustar www-datawww-databegin require 'chef/resource/action_class' rescue LoadError; end require 'chef_compat/copied_from_chef' class Chef module ::ChefCompat module CopiedFromChef # # Author:: John Keiser ("} action #{action ? action.inspect : ""}" end # # If load_current_value! is defined on the resource, use that. # def load_current_resource if new_resource.respond_to?(:load_current_value!) # dup the resource and then reset desired-state properties. current_resource = new_resource.dup # We clear desired state in the copy, because it is supposed to be actual state. # We keep identity properties and non-desired-state, which are assumed to be # "control" values like `recurse: true` current_resource.class.properties.each do |name, property| if property.desired_state? && !property.identity? && !property.name_property? property.reset(current_resource) end end # Call the actual load_current_value! method. If it raises # CurrentValueDoesNotExist, set current_resource to `nil`. begin # If the user specifies load_current_value do |desired_resource|, we # pass in the desired resource as well as the current one. if current_resource.method(:load_current_value!).arity > 0 current_resource.load_current_value!(new_resource) else current_resource.load_current_value! end rescue Chef::Exceptions::CurrentValueDoesNotExist current_resource = nil end end @current_resource = current_resource end def self.included(other) other.extend(ClassMethods) other.use_inline_resources other.include_resource_dsl true end module ClassMethods CopiedFromChef.extend_chef_module(::Chef::Resource::ActionClass::ClassMethods, self) if defined?(::Chef::Resource::ActionClass::ClassMethods) # # The Chef::Resource class this ActionClass was declared against. # # @return [Class] The Chef::Resource class this ActionClass was declared against. # attr_accessor :resource_class def to_s "#{resource_class} action provider" end def inspect to_s end end end end end end end end compat_resource-12.10.5/files/lib/chef_compat/copied_from_chef/chef/delayed_evaluator.rb0000644000004100000410000000176212724341276031436 0ustar www-datawww-databegin require 'chef/delayed_evaluator' rescue LoadError; end require 'chef_compat/copied_from_chef' class Chef module ::ChefCompat module CopiedFromChef # # Author:: John Keiser # Copyright:: Copyright 2015-2016, Chef Software Inc. # License:: Apache License, Version 2.0 # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. class Chef < (defined?(::Chef) ? ::Chef : Object) class DelayedEvaluator < (defined?(::Chef::DelayedEvaluator) ? ::Chef::DelayedEvaluator : Proc) end end end end end compat_resource-12.10.5/files/lib/chef_compat/copied_from_chef/chef/resource_builder.rb0000644000004100000410000001355312724341276031303 0ustar www-datawww-databegin require 'chef/resource_builder' rescue LoadError; end require 'chef_compat/copied_from_chef' class Chef module ::ChefCompat module CopiedFromChef # # Author:: Lamont Granquist () # Copyright:: Copyright 2015-2016, Chef Software, Inc. # License:: Apache License, Version 2.0 # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. # # NOTE: this was extracted from the Recipe DSL mixin, relevant specs are in spec/unit/recipe_spec.rb class Chef < (defined?(::Chef) ? ::Chef : Object) class ResourceBuilder < (defined?(::Chef::ResourceBuilder) ? ::Chef::ResourceBuilder : Object) attr_reader :type attr_reader :name attr_reader :created_at attr_reader :params attr_reader :run_context attr_reader :cookbook_name attr_reader :recipe_name attr_reader :enclosing_provider attr_reader :resource # FIXME (ruby-2.1 syntax): most of these are mandatory def initialize(type:nil, name:nil, created_at: nil, params: nil, run_context: nil, cookbook_name: nil, recipe_name: nil, enclosing_provider: nil) super if defined?(::Chef::ResourceBuilder) @type = type @name = name @created_at = created_at @params = params @run_context = run_context @cookbook_name = cookbook_name @recipe_name = recipe_name @enclosing_provider = enclosing_provider end def build(&block) raise ArgumentError, "You must supply a name when declaring a #{type} resource" if name.nil? @resource = resource_class.new(name, run_context) if resource.resource_name.nil? raise Chef::Exceptions::InvalidResourceSpecification, "#{resource}.resource_name is `nil`! Did you forget to put `provides :blah` or `resource_name :blah` in your resource class?" end resource.source_line = created_at resource.declared_type = type # If we have a resource like this one, we want to steal its state # This behavior is very counter-intuitive and should be removed. # See CHEF-3694, https://tickets.opscode.com/browse/CHEF-3694 # Moved to this location to resolve CHEF-5052, https://tickets.opscode.com/browse/CHEF-5052 if prior_resource resource.load_from(prior_resource) end resource.cookbook_name = cookbook_name resource.recipe_name = recipe_name # Determine whether this resource is being created in the context of an enclosing Provider resource.enclosing_provider = enclosing_provider # XXX: this is required for definition params inside of the scope of a # subresource to work correctly. resource.params = params # Evaluate resource attribute DSL if block_given? resource.resource_initializing = true begin resource.instance_eval(&block) ensure resource.resource_initializing = false end end # emit a cloned resource warning if it is warranted if prior_resource if is_trivial_resource?(prior_resource) && identicalish_resources?(prior_resource, resource) emit_harmless_cloning_debug else emit_cloned_resource_warning end end # Run optional resource hook resource.after_created resource end private def resource_class # Checks the new platform => short_name => resource mapping initially # then fall back to the older approach (Chef::Resource.const_get) for # backward compatibility @resource_class ||= Chef::Resource.resource_for_node(type, run_context.node) end def is_trivial_resource?(resource) identicalish_resources?(resource_class.new(name, run_context), resource) end # this is an equality test specific to checking for 3694 cloning warnings def identicalish_resources?(first, second) skipped_ivars = [ :@source_line, :@cookbook_name, :@recipe_name, :@params, :@elapsed_time, :@declared_type ] checked_ivars = ( first.instance_variables | second.instance_variables ) - skipped_ivars non_matching_ivars = checked_ivars.reject do |iv| if iv == :@action && ( [first.instance_variable_get(iv)].flatten == [:nothing] || [second.instance_variable_get(iv)].flatten == [:nothing] ) # :nothing action on either side of the comparison always matches true else first.instance_variable_get(iv) == second.instance_variable_get(iv) end end Chef::Log.debug("ivars which did not match with the prior resource: #{non_matching_ivars}") non_matching_ivars.empty? end def emit_cloned_resource_warning Chef::Log.warn("Cloning resource attributes for #{resource} from prior resource (CHEF-3694)") Chef::Log.warn("Previous #{prior_resource}: #{prior_resource.source_line}") if prior_resource.source_line Chef::Log.warn("Current #{resource}: #{resource.source_line}") if resource.source_line end def emit_harmless_cloning_debug Chef::Log.debug("Harmless resource cloning from #{prior_resource}:#{prior_resource.source_line} to #{resource}:#{resource.source_line}") end def prior_resource @prior_resource ||= begin key = "#{type}[#{name}]" run_context.resource_collection.lookup_local(key) rescue Chef::Exceptions::ResourceNotFound nil end end end end require "chef_compat/copied_from_chef/chef/resource" end end end compat_resource-12.10.5/files/lib/chef_compat/copied_from_chef/chef/provider.rb0000644000004100000410000001453212724341276027576 0ustar www-datawww-databegin require 'chef/provider' rescue LoadError; end require 'chef_compat/copied_from_chef' class Chef module ::ChefCompat module CopiedFromChef require "chef_compat/copied_from_chef/chef/dsl/core" class Chef < (defined?(::Chef) ? ::Chef : Object) class Provider < (defined?(::Chef::Provider) ? ::Chef::Provider : Object) include Chef::DSL::Core attr_accessor :action def initialize(new_resource, run_context) super if defined?(::Chef::Provider) @new_resource = new_resource @action = action @current_resource = nil @run_context = run_context @converge_actions = nil @recipe_name = nil @cookbook_name = nil self.class.include_resource_dsl_module(new_resource) end def converge_if_changed(*properties, &converge_block) if !converge_block raise ArgumentError, "converge_if_changed must be passed a block!" end properties = new_resource.class.state_properties.map { |p| p.name } if properties.empty? properties = properties.map { |p| p.to_sym } if current_resource # Collect the list of modified properties specified_properties = properties.select { |property| new_resource.property_is_set?(property) } modified = specified_properties.select { |p| new_resource.send(p) != current_resource.send(p) } if modified.empty? properties_str = if sensitive specified_properties.join(", ") else specified_properties.map { |p| "#{p}=#{new_resource.send(p).inspect}" }.join(", ") end Chef::Log.debug("Skipping update of #{new_resource}: has not changed any of the specified properties #{properties_str}.") return false end # Print the pretty green text and run the block property_size = modified.map { |p| p.size }.max modified.map! do |p| properties_str = if sensitive "(suppressed sensitive property)" else "#{new_resource.send(p).inspect} (was #{current_resource.send(p).inspect})" end " set #{p.to_s.ljust(property_size)} to #{properties_str}" end converge_by([ "update #{current_resource.identity}" ] + modified, &converge_block) else # The resource doesn't exist. Mark that we are *creating* this, and # write down any properties we are setting. property_size = properties.map { |p| p.size }.max created = properties.map do |property| default = " (default value)" unless new_resource.property_is_set?(property) properties_str = if sensitive "(suppressed sensitive property)" else new_resource.send(property).inspect end " set #{property.to_s.ljust(property_size)} to #{properties_str}#{default}" end converge_by([ "create #{new_resource.identity}" ] + created, &converge_block) end true end def self.include_resource_dsl(include_resource_dsl) @include_resource_dsl = include_resource_dsl end def self.include_resource_dsl_module(resource) if @include_resource_dsl && !defined?(@included_resource_dsl_module) provider_class = self @included_resource_dsl_module = Module.new do extend Forwardable define_singleton_method(:to_s) { "forwarder module for #{provider_class}" } define_singleton_method(:inspect) { to_s } # Add a delegator for each explicit property that will get the *current* value # of the property by default instead of the *actual* value. resource.class.properties.each do |name, property| class_eval(<<-EOM, __FILE__, __LINE__) def #{name}(*args, &block) # If no arguments were passed, we process "get" by defaulting # the value to current_resource, not new_resource. This helps # avoid issues where resources accidentally overwrite perfectly # valid stuff with default values. if args.empty? && !block if !new_resource.property_is_set?(__method__) && current_resource return current_resource.public_send(__method__) end end new_resource.public_send(__method__, *args, &block) end EOM end dsl_methods = resource.class.public_instance_methods + resource.class.protected_instance_methods - provider_class.instance_methods - resource.class.properties.keys def_delegators(:new_resource, *dsl_methods) end include @included_resource_dsl_module end end def self.use_inline_resources extend InlineResources::ClassMethods include InlineResources end module InlineResources CopiedFromChef.extend_chef_module(::Chef::Provider::InlineResources, self) if defined?(::Chef::Provider::InlineResources) def compile_and_converge_action(&block) old_run_context = run_context @run_context = run_context.create_child return_value = instance_eval(&block) Chef::Runner.new(run_context).converge return_value ensure if run_context.resource_collection.any? { |r| r.updated? } new_resource.updated_by_last_action(true) end @run_context = old_run_context end module ClassMethods CopiedFromChef.extend_chef_module(::Chef::Provider::InlineResources::ClassMethods, self) if defined?(::Chef::Provider::InlineResources::ClassMethods) def action(name, &block) # We need the block directly in a method so that `super` works define_method("compile_action_#{name}", &block) # We try hard to use `def` because define_method doesn't show the method name in the stack. begin class_eval <<-EOM def action_#{name} compile_and_converge_action { compile_action_#{name} } end EOM rescue SyntaxError define_method("action_#{name}") { send("compile_action_#{name}") } end end end end protected end end end end end compat_resource-12.10.5/files/lib/chef_compat/copied_from_chef/chef/provider/0000755000004100000410000000000012724341276027244 5ustar www-datawww-datacompat_resource-12.10.5/files/lib/chef_compat/copied_from_chef/chef/provider/noop.rb0000644000004100000410000000266412724341276030554 0ustar www-datawww-databegin require 'chef/provider/noop' rescue LoadError; end require 'chef_compat/copied_from_chef' class Chef module ::ChefCompat module CopiedFromChef # # Author:: Thom May () # Copyright:: Copyright (c) 2016 Chef Software, Inc. # License:: Apache License, Version 2.0 # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. # class Chef < (defined?(::Chef) ? ::Chef : Object) class Provider < (defined?(::Chef::Provider) ? ::Chef::Provider : Object) class Noop < (defined?(::Chef::Provider::Noop) ? ::Chef::Provider::Noop : Chef::Provider) def load_current_resource; end def respond_to_missing?(method_sym, include_private = false) method_sym.to_s.start_with?("action_") || super end def method_missing(method_sym, *arguments, &block) if method_sym.to_s =~ /^action_/ Chef::Log.debug("NoOp-ing for #{method_sym}") else super end end end end end end end end compat_resource-12.10.5/files/lib/chef_compat/copied_from_chef/chef/property.rb0000644000004100000410000006063512724341276027635 0ustar www-datawww-databegin require 'chef/property' rescue LoadError; end require 'chef_compat/copied_from_chef' class Chef module ::ChefCompat module CopiedFromChef # # Author:: John Keiser # Copyright:: Copyright 2015-2016, John Keiser. # License:: Apache License, Version 2.0 # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. # require "chef_compat/copied_from_chef/chef/delayed_evaluator" class Chef < (defined?(::Chef) ? ::Chef : Object) # # Type and validation information for a property on a resource. # # A property named "x" manipulates the "@x" instance variable on a # resource. The *presence* of the variable (`instance_variable_defined?(@x)`) # tells whether the variable is defined; it may have any actual value, # constrained only by validation. # # Properties may have validation, defaults, and coercion, and have full # support for lazy values. # # @see Chef::Resource.property # @see Chef::DelayedEvaluator # class Property < (defined?(::Chef::Property) ? ::Chef::Property : Object) # # Create a reusable property type that can be used in multiple properties # in different resources. # # @param options [Hash] Validation options. See Chef::Resource.property for # the list of options. # # @example # Property.derive(default: 'hi') # def self.derive(**options) new(**options) end # # Create a new property. # # @param options [Hash] Property options, including # control options here, as well as validation options (see # Chef::Mixin::ParamsValidate#validate for a description of validation # options). # @option options [Symbol] :name The name of this property. # @option options [Class] :declared_in The class this property comes from. # @option options [Symbol] :instance_variable_name The instance variable # tied to this property. Must include a leading `@`. Defaults to `@`. # `nil` means the property is opaque and not tied to a specific instance # variable. # @option options [Boolean] :desired_state `true` if this property is part of desired # state. Defaults to `true`. # @option options [Boolean] :identity `true` if this property is part of object # identity. Defaults to `false`. # @option options [Boolean] :name_property `true` if this # property defaults to the same value as `name`. Equivalent to # `default: lazy { name }`, except that #property_is_set? will # return `true` if the property is set *or* if `name` is set. # @option options [Boolean] :nillable `true` opt-in to Chef-13 style behavior where # attempting to set a nil value will really set a nil value instead of issuing # a warning and operating like a getter # @option options [Object] :default The value this property # will return if the user does not set one. If this is `lazy`, it will # be run in the context of the instance (and able to access other # properties) and cached. If not, the value will be frozen with Object#freeze # to prevent users from modifying it in an instance. # @option options [Proc] :coerce A proc which will be called to # transform the user input to canonical form. The value is passed in, # and the transformed value returned as output. Lazy values will *not* # be passed to this method until after they are evaluated. Called in the # context of the resource (meaning you can access other properties). # @option options [Boolean] :required `true` if this property # must be present; `false` otherwise. This is checked after the resource # is fully initialized. # def initialize(**options) super if defined?(::Chef::Property) options = options.inject({}) { |memo, (key, value)| memo[key.to_sym] = value; memo } @options = options options[:name] = options[:name].to_sym if options[:name] options[:instance_variable_name] = options[:instance_variable_name].to_sym if options[:instance_variable_name] # Replace name_attribute with name_property if options.has_key?(:name_attribute) # If we have both name_attribute and name_property and they differ, raise an error if options.has_key?(:name_property) raise ArgumentError, "Cannot specify both name_property and name_attribute together on property #{self}." end # replace name_property with name_attribute in place options = Hash[options.map { |k, v| k == :name_attribute ? [ :name_property, v ] : [ k, v ] }] @options = options end # Only pick the first of :default, :name_property and :name_attribute if # more than one is specified. if options.has_key?(:default) && options[:name_property] if options[:default].nil? || options.keys.index(:name_property) < options.keys.index(:default) options.delete(:default) preferred_default = :name_property else options.delete(:name_property) preferred_default = :default end Chef.log_deprecation("Cannot specify both default and name_property together on property #{self}. Only one (#{preferred_default}) will be obeyed. In Chef 13, this will become an error. Please remove one or the other from the property.") end # Validate the default early, so the user gets a good error message, and # cache it so we don't do it again if so begin # If we can validate it all the way to output, do it. @stored_default = input_to_stored_value(nil, default, is_default: true) rescue Chef::Exceptions::CannotValidateStaticallyError # If the validation is not static (i.e. has procs), we will have to # coerce and validate the default each time we run end end def to_s "#{name || ""}#{declared_in ? " of resource #{declared_in.resource_name}" : ""}" end # # The name of this property. # # @return [String] # def name options[:name] end # # The class this property was defined in. # # @return [Class] # def declared_in options[:declared_in] end # # The instance variable associated with this property. # # Defaults to `@` # # @return [Symbol] # def instance_variable_name if options.has_key?(:instance_variable_name) options[:instance_variable_name] elsif name :"@#{name}" end end # # The raw default value for this resource. # # Does not coerce or validate the default. Does not evaluate lazy values. # # Defaults to `lazy { name }` if name_property is true; otherwise defaults to # `nil` # def default return options[:default] if options.has_key?(:default) return Chef::DelayedEvaluator.new { name } if name_property? nil end # # Whether this is part of the resource's natural identity or not. # # @return [Boolean] # def identity? options[:identity] end # # Whether this is part of desired state or not. # # Defaults to true. # # @return [Boolean] # def desired_state? return true if !options.has_key?(:desired_state) options[:desired_state] end # # Whether this is name_property or not. # # @return [Boolean] # def name_property? options[:name_property] end # # Whether this property has a default value. # # @return [Boolean] # def has_default? options.has_key?(:default) || name_property? end # # Whether this property is required or not. # # @return [Boolean] # def required? options[:required] end # # Validation options. (See Chef::Mixin::ParamsValidate#validate.) # # @return [Hash] # def validation_options @validation_options ||= options.reject { |k, v| [:declared_in, :name, :instance_variable_name, :desired_state, :identity, :default, :name_property, :coerce, :required, :nillable].include?(k) } end # # Handle the property being called. # # The base implementation does the property get-or-set: # # ```ruby # resource.myprop # get # resource.myprop value # set # ``` # # Subclasses may implement this with any arguments they want, as long as # the corresponding DSL calls it correctly. # # @param resource [Chef::Resource] The resource to get the property from. # @param value The value to set (or NOT_PASSED if it is a get). # # @return The current value of the property. If it is a `set`, lazy values # will be returned without running, validating or coercing. If it is a # `get`, the non-lazy, coerced, validated value will always be returned. # def call(resource, value = NOT_PASSED) if value == NOT_PASSED return get(resource) end if value.nil? && !nillable? # In Chef 12, value(nil) does a *get* instead of a set, so we # warn if the value would have been changed. In Chef 13, it will be # equivalent to value = nil. result = get(resource, nil_set: true) # Warn about this becoming a set in Chef 13. begin input_to_stored_value(resource, value) # If nil is valid, and it would change the value, warn that this will change to a set. if !result.nil? Chef.log_deprecation("An attempt was made to change #{name} from #{result.inspect} to nil by calling #{name}(nil). In Chef 12, this does a get rather than a set. In Chef 13, this will change to set the value to nil.") end rescue Chef::Exceptions::DeprecatedFeatureError raise rescue # If nil is invalid, warn that this will become an error. Chef.log_deprecation("nil is an invalid value for #{self}. In Chef 13, this warning will change to an error. Error: #{$!}") end result else # Anything else, such as myprop(value) is a set set(resource, value) end end # # Get the property value from the resource, handling lazy values, # defaults, and validation. # # - If the property's value is lazy, it is evaluated, coerced and validated. # - If the property has no value, and is required, raises ValidationFailed. # - If the property has no value, but has a lazy default, it is evaluated, # coerced and validated. If the evaluated value is frozen, the resulting # - If the property has no value, but has a default, the default value # will be returned and frozen. If the default value is lazy, it will be # evaluated, coerced and validated, and the result stored in the property. # - If the property has no value, but is name_property, `resource.name` # is retrieved, coerced, validated and stored in the property. # - Otherwise, `nil` is returned. # # @param resource [Chef::Resource] The resource to get the property from. # # @return The value of the property. # # @raise Chef::Exceptions::ValidationFailed If the value is invalid for # this property, or if the value is required and not set. # def get(resource, nil_set: false) # If it's set, return it (and evaluate any lazy values) if is_set?(resource) value = get_value(resource) value = stored_value_to_output(resource, value) else # We are getting the default value. # If the user does something like this: # # ``` # class MyResource < Chef::Resource # property :content # action :create do # file '/x.txt' do # content content # end # end # end # ``` # # It won't do what they expect. This checks whether you try to *read* # `content` while we are compiling the resource. if !nil_set && resource.respond_to?(:resource_initializing) && resource.resource_initializing && resource.respond_to?(:enclosing_provider) && resource.enclosing_provider && resource.enclosing_provider.new_resource && resource.enclosing_provider.new_resource.respond_to?(name) Chef::Log.warn("#{Chef::Log.caller_location}: property #{name} is declared in both #{resource} and #{resource.enclosing_provider}. Use new_resource.#{name} instead. At #{Chef::Log.caller_location}") end if has_default? # If we were able to cache the stored_default, grab it. if defined?(@stored_default) value = @stored_default else # Otherwise, we have to validate it now. value = input_to_stored_value(resource, default, is_default: true) end value = stored_value_to_output(resource, value, is_default: true) # If the value is mutable (non-frozen), we set it on the instance # so that people can mutate it. (All constant default values are # frozen.) if !value.frozen? && !value.nil? set_value(resource, value) end value elsif required? raise Chef::Exceptions::ValidationFailed, "#{name} is required" end end end # # Set the value of this property in the given resource. # # Non-lazy values are coerced and validated before being set. Coercion # and validation of lazy values is delayed until they are first retrieved. # # @param resource [Chef::Resource] The resource to set this property in. # @param value The value to set. # # @return The value that was set, after coercion (if lazy, still returns # the lazy value) # # @raise Chef::Exceptions::ValidationFailed If the value is invalid for # this property. # def set(resource, value) set_value(resource, input_to_stored_value(resource, value)) end # # Find out whether this property has been set. # # This will be true if: # - The user explicitly set the value # - The property has a default, and the value was retrieved. # # From this point of view, it is worth looking at this as "what does the # user think this value should be." In order words, if the user grabbed # the value, even if it was a default, they probably based calculations on # it. If they based calculations on it and the value changes, the rest of # the world gets inconsistent. # # @param resource [Chef::Resource] The resource to get the property from. # # @return [Boolean] # def is_set?(resource) value_is_set?(resource) end # # Reset the value of this property so that is_set? will return false and the # default will be returned in the future. # # @param resource [Chef::Resource] The resource to get the property from. # def reset(resource) reset_value(resource) end # # Coerce an input value into canonical form for the property. # # After coercion, the value is suitable for storage in the resource. # You must validate values after coercion, however. # # Does no special handling for lazy values. # # @param resource [Chef::Resource] The resource we're coercing against # (to provide context for the coerce). # @param value The value to coerce. # # @return The coerced value. # # @raise Chef::Exceptions::ValidationFailed If the value is invalid for # this property. # def coerce(resource, value) if options.has_key?(:coerce) # If we have no default value, `nil` is never coerced or validated unless !has_default? && value.nil? value = exec_in_resource(resource, options[:coerce], value) end end value end # # Validate a value. # # Calls Chef::Mixin::ParamsValidate#validate with #validation_options as # options. # # @param resource [Chef::Resource] The resource we're validating against # (to provide context for the validate). # @param value The value to validate. # # @raise Chef::Exceptions::ValidationFailed If the value is invalid for # this property. # def validate(resource, value) # If we have no default value, `nil` is never coerced or validated unless value.nil? && !has_default? if resource resource.validate({ name => value }, { name => validation_options }) else name = self.name || :property_type Chef::Mixin::ParamsValidate.validate({ name => value }, { name => validation_options }) end end end # # Derive a new Property that is just like this one, except with some added or # changed options. # # @param options [Hash] List of options that would be passed # to #initialize. # # @return [Property] The new property type. # def derive(**modified_options) # Since name_property, name_attribute and default override each other, # if you specify one of them in modified_options it overrides anything in # the original options. options = self.options if modified_options.has_key?(:name_property) || modified_options.has_key?(:name_attribute) || modified_options.has_key?(:default) options = options.reject { |k, v| k == :name_attribute || k == :name_property || k == :default } end self.class.new(options.merge(modified_options)) end # # Emit the DSL for this property into the resource class (`declared_in`). # # Creates a getter and setter for the property. # def emit_dsl # We don't create the getter/setter if it's a custom property; we will # be using the existing getter/setter to manipulate it instead. return if !instance_variable_name # We prefer this form because the property name won't show up in the # stack trace if you use `define_method`. declared_in.class_eval <<-EOM, __FILE__, __LINE__ + 1 def #{name}(value=NOT_PASSED) raise "Property #{name} of \#{self} cannot be passed a block! If you meant to create a resource named #{name} instead, you'll need to first rename the property." if block_given? self.class.properties[#{name.inspect}].call(self, value) end def #{name}=(value) raise "Property #{name} of \#{self} cannot be passed a block! If you meant to create a resource named #{name} instead, you'll need to first rename the property." if block_given? self.class.properties[#{name.inspect}].set(self, value) end EOM rescue SyntaxError # If the name is not a valid ruby name, we use define_method. declared_in.define_method(name) do |value = NOT_PASSED, &block| raise "Property #{name} of #{self} cannot be passed a block! If you meant to create a resource named #{name} instead, you'll need to first rename the property." if block self.class.properties[name].call(self, value) end declared_in.define_method("#{name}=") do |value, &block| raise "Property #{name} of #{self} cannot be passed a block! If you meant to create a resource named #{name} instead, you'll need to first rename the property." if block self.class.properties[name].set(self, value) end end protected # # The options this Property will use for get/set behavior and validation. # # @see #initialize for a list of valid options. # attr_reader :options # # Find out whether this type accepts nil explicitly. # # A type accepts nil explicitly if "is" allows nil, it validates as nil, *and* is not simply # an empty type. # # A type is presumed to accept nil if it does coercion (which must handle nil). # # These examples accept nil explicitly: # ```ruby # property :a, [ String, nil ] # property :a, [ String, NilClass ] # property :a, [ String, proc { |v| v.nil? } ] # ``` # # This does not (because the "is" doesn't exist or doesn't have nil): # # ```ruby # property :x, String # ``` # # These do not, even though nil would validate fine (because they do not # have "is"): # # ```ruby # property :a # property :a, equal_to: [ 1, 2, 3, nil ] # property :a, kind_of: [ String, NilClass ] # property :a, respond_to: [ ] # property :a, callbacks: { "a" => proc { |v| v.nil? } } # ``` # # @param resource [Chef::Resource] The resource we're coercing against # (to provide context for the coerce). # # @return [Boolean] Whether this value explicitly accepts nil. # # @api private def explicitly_accepts_nil?(resource) options.has_key?(:coerce) || (options.has_key?(:is) && resource.send(:_pv_is, { name => nil }, name, options[:is], raise_error: false)) end def get_value(resource) if instance_variable_name resource.instance_variable_get(instance_variable_name) else resource.send(name) end end def set_value(resource, value) if instance_variable_name resource.instance_variable_set(instance_variable_name, value) else resource.send(name, value) end end def value_is_set?(resource) if instance_variable_name resource.instance_variable_defined?(instance_variable_name) else true end end def reset_value(resource) if instance_variable_name if value_is_set?(resource) resource.remove_instance_variable(instance_variable_name) end else raise ArgumentError, "Property #{name} has no instance variable defined and cannot be reset" end end def exec_in_resource(resource, proc, *args) if resource if proc.arity > args.size value = proc.call(resource, *args) else value = resource.instance_exec(*args, &proc) end else # If we don't have a resource yet, we can't exec in resource! raise Chef::Exceptions::CannotValidateStaticallyError, "Cannot validate or coerce without a resource" end end def input_to_stored_value(resource, value, is_default: false) unless value.is_a?(DelayedEvaluator) value = coerce_and_validate(resource, value, is_default: is_default) end value end def stored_value_to_output(resource, value, is_default: false) # Crack open lazy values before giving the result to the user if value.is_a?(DelayedEvaluator) value = exec_in_resource(resource, value) value = coerce_and_validate(resource, value, is_default: is_default) end value end # Coerces and validates the value. If the value is a default, it will warn # the user that invalid defaults are bad mmkay, and return it as if it were # valid. def coerce_and_validate(resource, value, is_default: false) result = coerce(resource, value) begin # If the input is from a default, we need to emit an invalid default warning on validate. validate(resource, result) rescue Chef::Exceptions::CannotValidateStaticallyError # This one gets re-raised raise rescue # Anything else is just an invalid default: in those cases, we just # warn and return the (possibly coerced) value to the user. if is_default if value.nil? Chef.log_deprecation("Default value nil is invalid for property #{self}. Possible fixes: 1. Remove 'default: nil' if nil means 'undefined'. 2. Set a valid default value if there is a reasonable one. 3. Allow nil as a valid value of your property (for example, 'property #{name.inspect}, [ String, nil ], default: nil'). Error: #{$!}") else Chef.log_deprecation("Default value #{value.inspect} is invalid for property #{self}. In Chef 13 this will become an error: #{$!}.") end else raise end end result end def nillable? !!options[:nillable] end end end end end end compat_resource-12.10.5/files/lib/chef_compat/copied_from_chef/chef/dsl/0000755000004100000410000000000012724341276026174 5ustar www-datawww-datacompat_resource-12.10.5/files/lib/chef_compat/copied_from_chef/chef/dsl/core.rb0000644000004100000410000000406212724341276027453 0ustar www-datawww-databegin require 'chef/dsl/core' rescue LoadError; end require 'chef_compat/copied_from_chef' class Chef module ::ChefCompat module CopiedFromChef #-- # Author:: Adam Jacob () # Author:: Christopher Walters () # Copyright:: Copyright 2008-2016, 2009-2015 Chef Software, Inc. # License:: Apache License, Version 2.0 # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. # require "chef_compat/copied_from_chef/chef/dsl/declare_resource" require "chef_compat/copied_from_chef/chef/mixin/notifying_block" require "chef_compat/copied_from_chef/chef/mixin/powershell_out" class Chef < (defined?(::Chef) ? ::Chef : Object) module DSL CopiedFromChef.extend_chef_module(::Chef::DSL, self) if defined?(::Chef::DSL) # This is the "Core DSL" with various bits of Sugar that are mixed into core providers as well # as user LWRPs. This module deliberately does not mixin the Resources or Defintions DSL bits # so that cookbooks are not injeting random things into the namespace of core providers. # # - If you are writing cookbooks: you have come to the wrong place, please inject things into # Chef::DSL::Recipe instead. # # - If you are writing core chef: you have come to the right place, please drop your DSL modules # into here. # module Core CopiedFromChef.extend_chef_module(::Chef::DSL::Core, self) if defined?(::Chef::DSL::Core) include Chef::DSL::DeclareResource include Chef::Mixin::NotifyingBlock include Chef::Mixin::PowershellOut include Chef::Mixin::ShellOut end end end end end end compat_resource-12.10.5/files/lib/chef_compat/copied_from_chef/chef/dsl/recipe.rb0000644000004100000410000000163312724341276027773 0ustar www-datawww-databegin require 'chef/dsl/recipe' rescue LoadError; end require 'chef_compat/copied_from_chef' class Chef module ::ChefCompat module CopiedFromChef require "chef_compat/copied_from_chef/chef/dsl/core" require "chef_compat/copied_from_chef/chef/mixin/lazy_module_include" class Chef < (defined?(::Chef) ? ::Chef : Object) module DSL CopiedFromChef.extend_chef_module(::Chef::DSL, self) if defined?(::Chef::DSL) module Recipe CopiedFromChef.extend_chef_module(::Chef::DSL::Recipe, self) if defined?(::Chef::DSL::Recipe) include Chef::DSL::Core extend Chef::Mixin::LazyModuleInclude module FullDSL CopiedFromChef.extend_chef_module(::Chef::DSL::Recipe::FullDSL, self) if defined?(::Chef::DSL::Recipe::FullDSL) include Chef::DSL::Recipe extend Chef::Mixin::LazyModuleInclude end end end end require "chef_compat/copied_from_chef/chef/resource" end end end compat_resource-12.10.5/files/lib/chef_compat/copied_from_chef/chef/dsl/declare_resource.rb0000644000004100000410000003134512724341276032035 0ustar www-datawww-databegin require 'chef/dsl/declare_resource' rescue LoadError; end require 'chef_compat/copied_from_chef' class Chef module ::ChefCompat module CopiedFromChef #-- # Author:: Adam Jacob () # Author:: Christopher Walters # Copyright:: Copyright 2008-2016, 2009-2015 Chef Software, Inc. # License:: Apache License, Version 2.0 # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. # class Chef < (defined?(::Chef) ? ::Chef : Object) module DSL CopiedFromChef.extend_chef_module(::Chef::DSL, self) if defined?(::Chef::DSL) module DeclareResource CopiedFromChef.extend_chef_module(::Chef::DSL::DeclareResource, self) if defined?(::Chef::DSL::DeclareResource) # Helper for switching run_contexts. Allows for using :parent or :root in place of # passing the run_context. Executes the block in the run_context. Returns the return # value of the passed block. # # @param rc [Chef::RunContext,Symbol] Either :root, :parent or a Chef::RunContext # # @return return value of the block # # @example # # creates/returns a 'service[foo]' resource in the root run_context # resource = with_run_context(:root) # edit_resource(:service, "foo") do # action :nothing # end # end # def with_run_context(rc) raise ArgumentError, "with_run_context is useless without a block" unless block_given? old_run_context = @run_context @run_context = case rc when Chef::RunContext rc when :root Chef.run_context when :parent run_context.parent_run_context else raise ArgumentError, "bad argument to run_context helper, must be :root, :parent, or a Chef::RunContext" end yield ensure @run_context = old_run_context end # Lookup a resource in the resource collection by name and delete it. This # will raise Chef::Exceptions::ResourceNotFound if the resource is not found. # # @param type [Symbol] The type of resource (e.g. `:file` or `:package`) # @param name [String] The name of the resource (e.g. '/x/y.txt' or 'apache2') # @param run_context [Chef::RunContext] the run_context of the resource collection to operate on # # @return [Chef::Resource] The resource # # @example # delete_resource!(:template, '/x/y.txy') # def delete_resource!(type, name, run_context: self.run_context) run_context.resource_collection.delete("#{type}[#{name}]") end # Lookup a resource in the resource collection by name and delete it. Returns # nil if the resource is not found and should not fail. # # @param type [Symbol] The type of resource (e.g. `:file` or `:package`) # @param name [String] The name of the resource (e.g. '/x/y.txt' or 'apache2') # @param run_context [Chef::RunContext] the run_context of the resource collection to operate on # # @return [Chef::Resource] The resource # # @example # delete_resource(:template, '/x/y.txy') # def delete_resource(type, name, run_context: self.run_context) delete_resource!(type, name, run_context: run_context) rescue Chef::Exceptions::ResourceNotFound nil end # Lookup a resource in the resource collection by name and edit the resource. If the resource is not # found this will raise Chef::Exceptions::ResourceNotFound. This is the correct API to use for # "chef_rewind" functionality. # # @param type [Symbol] The type of resource (e.g. `:file` or `:package`) # @param name [String] The name of the resource (e.g. '/x/y.txt' or 'apache2') # @param run_context [Chef::RunContext] the run_context of the resource collection to operate on # @param resource_attrs_block A block that lets you set attributes of the # resource (it is instance_eval'd on the resource instance). # # @return [Chef::Resource] The updated resource # # @example # edit_resource!(:template, '/x/y.txy') do # cookbook_name: cookbook_name # end # def edit_resource!(type, name, created_at = nil, run_context: self.run_context, &resource_attrs_block) resource = find_resource!(type, name, run_context: run_context) resource.instance_eval(&resource_attrs_block) if block_given? resource end # Lookup a resource in the resource collection by name. If it exists, # return it. If it does not exist, create it. This is a useful function # for accumulator patterns. In CRUD terminology this is an "upsert" operation and is # used to assert that the resource must exist with the specified properties. # # @param type [Symbol] The type of resource (e.g. `:file` or `:package`) # @param name [String] The name of the resource (e.g. '/x/y.txt' or 'apache2') # @param created_at [String] The caller of the resource. Use `caller[0]` # to get the caller of your function. Defaults to the caller of this # function. # @param run_context [Chef::RunContext] the run_context of the resource collection to operate on # @param resource_attrs_block A block that lets you set attributes of the # resource (it is instance_eval'd on the resource instance). # # @return [Chef::Resource] The updated or created resource # # @example # resource = edit_resource(:template, '/x/y.txy') do # source "y.txy.erb" # variables {} # end # resource.variables.merge!({ home: "/home/klowns" }) # def edit_resource(type, name, created_at = nil, run_context: self.run_context, &resource_attrs_block) edit_resource!(type, name, created_at, run_context: run_context, &resource_attrs_block) rescue Chef::Exceptions::ResourceNotFound declare_resource(type, name, created_at, run_context: run_context, &resource_attrs_block) end # Lookup a resource in the resource collection by name. If the resource is not # found this will raise Chef::Exceptions::ResourceNotFound. This API is identical to the # resources() call and while it is a synonym it is not intended to deprecate that call. # # @param type [Symbol] The type of resource (e.g. `:file` or `:package`) # @param name [String] The name of the resource (e.g. '/x/y.txt' or 'apache2') # @param run_context [Chef::RunContext] the run_context of the resource collection to operate on # # @return [Chef::Resource] The updated resource # # @example # resource = find_resource!(:template, '/x/y.txy') # def find_resource!(type, name, run_context: self.run_context) raise ArgumentError, "find_resource! does not take a block" if block_given? run_context.resource_collection.find(type => name) end # Lookup a resource in the resource collection by name. If the resource is not found # the will be no exception raised and the call will return nil. If a block is given and # no resource is found it will create the resource using the block, if the resource is # found then the block will not be applied. The block version is similar to create_if_missing # # @param type [Symbol] The type of resource (e.g. `:file` or `:package`) # @param name [String] The name of the resource (e.g. '/x/y.txt' or 'apache2') # @param run_context [Chef::RunContext] the run_context of the resource collection to operate on # # @return [Chef::Resource] The updated resource # # @example # if ( find_resource(:template, '/x/y.txy') ) # # do something # else # # don't worry about the error # end # # @example # # this API can be used to return a resource from an outer run context, and will only create # # an action :nothing service if one does not already exist. # resource = with_run_context(:root) do # find_resource(:service, 'whatever') do # action :nothing # end # end # def find_resource(type, name, created_at: nil, run_context: self.run_context, &resource_attrs_block) find_resource!(type, name, run_context: run_context) rescue Chef::Exceptions::ResourceNotFound if block_given? declare_resource(type, name, created_at, run_context: run_context, &resource_attrs_block) end # returns nil otherwise end # Instantiates a resource (via #build_resource), then adds it to the # resource collection. Note that resource classes are looked up directly, # so this will create the resource you intended even if the method name # corresponding to that resource has been overridden. # # @param type [Symbol] The type of resource (e.g. `:file` or `:package`) # @param name [String] The name of the resource (e.g. '/x/y.txt' or 'apache2') # @param created_at [String] The caller of the resource. Use `caller[0]` # to get the caller of your function. Defaults to the caller of this # function. # @param run_context [Chef::RunContext] the run_context of the resource collection to operate on # @param resource_attrs_block A block that lets you set attributes of the # resource (it is instance_eval'd on the resource instance). # # @return [Chef::Resource] The new resource. # # @example # declare_resource(:file, '/x/y.txy', caller[0]) do # action :delete # end # # Equivalent to # file '/x/y.txt' do # action :delete # end # def declare_resource(type, name, created_at = nil, run_context: self.run_context, create_if_missing: false, &resource_attrs_block) created_at ||= caller[0] if create_if_missing Chef::Log.deprecation "build_resource with a create_if_missing flag is deprecated, use edit_resource instead" # midly goofy since we call edit_resource only to re-call ourselves, but that's why its deprecated... return edit_resource(type, name, created_at, run_context: run_context, &resource_attrs_block) end resource = build_resource(type, name, created_at, &resource_attrs_block) run_context.resource_collection.insert(resource, resource_type: type, instance_name: name) resource end # Instantiate a resource of the given +type+ with the given +name+ and # attributes as given in the +resource_attrs_block+. # # The resource is NOT added to the resource collection. # # @param type [Symbol] The type of resource (e.g. `:file` or `:package`) # @param name [String] The name of the resource (e.g. '/x/y.txt' or 'apache2') # @param created_at [String] The caller of the resource. Use `caller[0]` # to get the caller of your function. Defaults to the caller of this # function. # @param run_context [Chef::RunContext] the run_context of the resource collection to operate on # @param resource_attrs_block A block that lets you set attributes of the # resource (it is instance_eval'd on the resource instance). # # @return [Chef::Resource] The new resource. # # @example # build_resource(:file, '/x/y.txy', caller[0]) do # action :delete # end # def build_resource(type, name, created_at = nil, run_context: self.run_context, &resource_attrs_block) created_at ||= caller[0] # this needs to be lazy in order to avoid circular dependencies since ResourceBuilder # will requires the entire provider+resolver universe require "chef_compat/copied_from_chef/chef/resource_builder" unless defined?(Chef::ResourceBuilder) Chef::ResourceBuilder.new( type: type, name: name, created_at: created_at, params: @params, run_context: run_context, cookbook_name: cookbook_name, recipe_name: recipe_name, enclosing_provider: self.is_a?(Chef::Provider) ? self : nil ).build(&resource_attrs_block) end end end end end end end compat_resource-12.10.5/files/lib/chef_compat/copied_from_chef/chef/resource.rb0000644000004100000410000001504412724341276027572 0ustar www-datawww-databegin require 'chef/resource' rescue LoadError; end require 'chef_compat/copied_from_chef' class Chef module ::ChefCompat module CopiedFromChef require "chef_compat/copied_from_chef/chef/resource/action_class" require "chef_compat/copied_from_chef/chef/provider" require "chef_compat/copied_from_chef/chef/mixin/properties" require "chef_compat/copied_from_chef/chef/mixin/powershell_out" class Chef < (defined?(::Chef) ? ::Chef : Object) class Resource < (defined?(::Chef::Resource) ? ::Chef::Resource : Object) include Chef::Mixin::Properties property :name, String, coerce: proc { |v| v.is_a?(Array) ? v.join(", ") : v.to_s }, desired_state: false def initialize(name, run_context = nil) super if defined?(::Chef::Resource) name(name) unless name.nil? @run_context = run_context @noop = nil @before = nil @params = Hash.new @provider = nil @allowed_actions = self.class.allowed_actions.to_a @action = self.class.default_action @updated = false @updated_by_last_action = false @supports = {} @ignore_failure = false @retries = 0 @retry_delay = 2 @not_if = [] @only_if = [] @source_line = nil # We would like to raise an error when the user gives us a guard # interpreter and a ruby_block to the guard. In order to achieve this # we need to understand when the user overrides the default guard # interpreter. Therefore we store the default separately in a different # attribute. @guard_interpreter = nil @default_guard_interpreter = :default @elapsed_time = 0 @sensitive = false end def action(arg = nil) if arg arg = Array(arg).map(&:to_sym) arg.each do |action| validate( { action: action }, { action: { kind_of: Symbol, equal_to: allowed_actions } } ) end @action = arg else @action end end alias_method :action=, :action def state_for_resource_reporter state = {} state_properties = self.class.state_properties state_properties.each do |property| if property.identity? || property.is_set?(self) state[property.name] = send(property.name) end end state end alias_method :state, :state_for_resource_reporter def identity result = {} identity_properties = self.class.identity_properties identity_properties.each do |property| result[property.name] = send(property.name) end return result.values.first if identity_properties.size == 1 result end attr_reader :resource_initializing def resource_initializing=(value) if value @resource_initializing = true else remove_instance_variable(:@resource_initializing) end end def to_hash # Grab all current state, then any other ivars (backcompat) result = {} self.class.state_properties.each do |p| result[p.name] = p.get(self) end safe_ivars = instance_variables.map { |ivar| ivar.to_sym } - FORBIDDEN_IVARS safe_ivars.each do |iv| key = iv.to_s.sub(/^@/, "").to_sym next if result.has_key?(key) result[key] = instance_variable_get(iv) end result end def self.identity_property(name = nil) result = identity_properties(*Array(name)) if result.size > 1 raise Chef::Exceptions::MultipleIdentityError, "identity_property cannot be called on an object with more than one identity property (#{result.map { |r| r.name }.join(", ")})." end result.first end attr_accessor :allowed_actions def allowed_actions(value = NOT_PASSED) if value != NOT_PASSED self.allowed_actions = value end @allowed_actions end def resource_name @resource_name || self.class.resource_name end def self.use_automatic_resource_name automatic_name = convert_to_snake_case(self.name.split("::")[-1]) resource_name automatic_name end def self.allowed_actions(*actions) @allowed_actions ||= if superclass.respond_to?(:allowed_actions) superclass.allowed_actions.dup else [ :nothing ] end @allowed_actions |= actions.flatten end def self.allowed_actions=(value) @allowed_actions = value.uniq end def self.default_action(action_name = NOT_PASSED) unless action_name.equal?(NOT_PASSED) @default_action = Array(action_name).map(&:to_sym) self.allowed_actions |= @default_action end if @default_action @default_action elsif superclass.respond_to?(:default_action) superclass.default_action else [:nothing] end end def self.default_action=(action_name) default_action action_name end def self.action(action, &recipe_block) action = action.to_sym declare_action_class action_class.action(action, &recipe_block) self.allowed_actions += [ action ] default_action action if Array(default_action) == [:nothing] end def self.load_current_value(&load_block) define_method(:load_current_value!, &load_block) end def current_value_does_not_exist! raise Chef::Exceptions::CurrentValueDoesNotExist end def self.action_class(&block) return @action_class if @action_class && !block # If the superclass needed one, then we need one as well. if block || (superclass.respond_to?(:action_class) && superclass.action_class) @action_class = declare_action_class(&block) end @action_class end def self.declare_action_class(&block) @action_class ||= begin if superclass.respond_to?(:action_class) base_provider = superclass.action_class end base_provider ||= Chef::Provider resource_class = self Class.new(base_provider) do include ActionClass self.resource_class = resource_class end end @action_class.class_eval(&block) if block @action_class end FORBIDDEN_IVARS = [:@run_context, :@not_if, :@only_if, :@enclosing_provider] HIDDEN_IVARS = [:@allowed_actions, :@resource_name, :@source_line, :@run_context, :@name, :@not_if, :@only_if, :@elapsed_time, :@enclosing_provider] class << self end @@sorted_descendants = nil private end end end end end compat_resource-12.10.5/files/lib/chef_compat/copied_from_chef/chef/constants.rb0000644000004100000410000000200612724341276027751 0ustar www-datawww-databegin require 'chef/constants' rescue LoadError; end require 'chef_compat/copied_from_chef' class Chef module ::ChefCompat module CopiedFromChef # # Author:: John Keiser # Copyright:: Copyright 2015-2016, Chef Software Inc. # License:: Apache License, Version 2.0 # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. class Chef < (defined?(::Chef) ? ::Chef : Object) NOT_PASSED = Object.new def NOT_PASSED.to_s "NOT_PASSED" end def NOT_PASSED.inspect to_s end NOT_PASSED.freeze end end end end compat_resource-12.10.5/files/lib/chef_compat/property.rb0000644000004100000410000000022012724341276023435 0ustar www-datawww-datarequire 'chef_compat/copied_from_chef/chef/property' module ChefCompat class Property < ChefCompat::CopiedFromChef::Chef::Property end end compat_resource-12.10.5/files/lib/chef_compat/monkeypatches/0000755000004100000410000000000012724341276024104 5ustar www-datawww-datacompat_resource-12.10.5/files/lib/chef_compat/monkeypatches/chef/0000755000004100000410000000000012724341276025011 5ustar www-datawww-datacompat_resource-12.10.5/files/lib/chef_compat/monkeypatches/chef/mixin/0000755000004100000410000000000012724341276026135 5ustar www-datawww-datacompat_resource-12.10.5/files/lib/chef_compat/monkeypatches/chef/mixin/params_validate.rb0000644000004100000410000000106112724341276031614 0ustar www-datawww-dataif Chef::VERSION.to_f >= 12.5 && Chef::VERSION.to_f <= 12.8 require 'chef/mixin/params_validate' class Chef module Mixin module ParamsValidate class SetOrReturnProperty < Chef::Property # 12.9 introduced a new optional parameter to `get()` to avoid a nil-set warning. # When their method gets called with 2 args, we need to ignore and call with 1. alias_method :_original_get2, :get def get(resource, *args) _original_get2(resource) end end end end end end compat_resource-12.10.5/files/lib/chef_compat/monkeypatches/chef/resource/0000755000004100000410000000000012724341276026640 5ustar www-datawww-datacompat_resource-12.10.5/files/lib/chef_compat/monkeypatches/chef/resource/lwrp_base.rb0000644000004100000410000000370612724341276031151 0ustar www-datawww-datarequire 'chef_compat/resource/lwrp_base' require 'chef/resource/lwrp_base' module ChefCompat module Monkeypatches # # NOTE: LOTS OF METAPROGRAMMING HERE. NOT FOR FAINT OF HEART. # # Add an empty module to Class so we can temporarily override it in build_from_file module Class end class<<::Class prepend(ChefCompat::Monkeypatches::Class) end module Chef module Resource module LWRPBase def build_from_file(cookbook_name, filename, run_context) # If the cookbook this LWRP is from depends on compat_resource, fix its LWRPs up real good if run_context.cookbook_collection[cookbook_name].metadata.dependencies.has_key?('compat_resource') # All cookbooks do Class.new(Chef::Resource::LWRPBase). Change Class.new # temporarily to translate Chef::Resource::LWRPBase to ChefCompat::Resource ChefCompat::Monkeypatches::Class.module_eval do def new(*args, &block) # Trick it! Use ChefCompat::Resource instead of Chef::Resource::LWRPBase if args == [ ::Chef::Resource::LWRPBase ] ChefCompat::Monkeypatches::Class.module_eval do remove_method(:new) if method_defined?(:new) end args = [ ChefCompat::Resource::LWRPBase ] end super(*args, &block) end end begin # Call the actual build_from_file super ensure class<) # Copyright:: Copyright 2014-2016, Chef Software, Inc. # License:: Apache License, Version 2.0 # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. # require "chef/resource_collection/resource_list" require "chef/exceptions" module ChefCompat module Monkeypatches module Chef module ResourceCollection module ResourceSet module DeleteResource def delete(key) raise ArgumentError, "Must pass a Chef::Resource or String to delete" unless key.is_a?(String) || key.is_a?(Chef::Resource) key = key.to_s res = @resources_by_key.delete(key) if res == @resources_by_key.default raise Chef::Exceptions::ResourceNotFound, "Cannot find a resource matching #{key} (did you define it first?)" end res end end end end end end end class Chef::ResourceCollection::ResourceSet unless method_defined?(:delete) prepend ChefCompat::Monkeypatches::Chef::ResourceCollection::ResourceSet::DeleteResource end end ././@LongLink0000000000000000000000000000014600000000000011566 Lustar rootrootcompat_resource-12.10.5/files/lib/chef_compat/monkeypatches/chef/resource_collection/resource_list.rbcompat_resource-12.10.5/files/lib/chef_compat/monkeypatches/chef/resource_collection/resource_list.r0000644000004100000410000000317312724341276034124 0ustar www-datawww-data# # Author:: Tyler Ball () # Copyright:: Copyright 2014-2016, Chef Software, Inc. # License:: Apache License, Version 2.0 # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. # require "chef/resource_collection/resource_list" require "chef/exceptions" module ChefCompat module Monkeypatches module Chef module ResourceCollection module ResourceList module DeleteResource # Copied verbatim from Chef 12.10.4 def delete(key) raise ArgumentError, "Must pass a Chef::Resource or String to delete" unless key.is_a?(String) || key.is_a?(Chef::Resource) key = key.to_s ret = @resources.reject! { |r| r.to_s == key } if ret.nil? raise ::Chef::Exceptions::ResourceNotFound, "Cannot find a resource matching #{key} (did you define it first?)" end ret end end end end end end end class Chef::ResourceCollection::ResourceList unless method_defined?(:delete) prepend ChefCompat::Monkeypatches::Chef::ResourceCollection::ResourceList::DeleteResource end end compat_resource-12.10.5/files/lib/chef_compat/monkeypatches/chef/run_context.rb0000644000004100000410000000504112724341276027706 0ustar www-datawww-datarequire 'chef/run_context' require 'chef_compat/monkeypatches/chef/resource_collection' if Gem::Requirement.new("< 12.10.24").satisfied_by?(Gem::Version.new(Chef::VERSION)) module ChefCompat module Monkeypatches module Chef module RunContext # for versions after we added intialize_child_state but before 12.10.24 def initialize_child_state(*args) super @resource_collection.run_context = self @delayed_actions = [] end end end end end class Chef class RunContext # # NOTE: The root run_context is created long before we start monkeying around # with patching the class. No child run context has been created yet. This # still patches the root run_context and implements the new behaviors on it. # # This does affect our ability to patch methods like #initialize, since the # root has already been created and initialized, obviously. # unless method_defined?(:parent_run_context) attr_accessor :parent_run_context end unless method_defined?(:delayed_actions) def delayed_actions @delayed_actions ||= [] end end unless method_defined?(:initialize_child_state) # # Copied verbatim from 12.10.24 Chef::RunContext # def initialize_child_state @audits = {} @resource_collection = Chef::ResourceCollection.new(self) @before_notification_collection = Hash.new { |h, k| h[k] = [] } @immediate_notification_collection = Hash.new { |h, k| h[k] = [] } @delayed_notification_collection = Hash.new { |h, k| h[k] = [] } @delayed_actions = [] end else prepend ChefCompat::Monkeypatches::Chef::RunContext end unless method_defined?(:add_delayed_action) def add_delayed_action(notification) if delayed_actions.any? { |existing_notification| existing_notification.duplicates?(notification) } Chef::Log.info( "#{notification.notifying_resource} not queuing delayed action #{notification.action} on #{notification.resource}"\ " (delayed), as it's already been queued") else delayed_actions << notification end end end unless method_defined?(:create_child) def create_child result = dup result.parent_run_context = self result.initialize_child_state result end end end end end compat_resource-12.10.5/files/lib/chef_compat/monkeypatches/chef/resource_builder.rb0000644000004100000410000001640612724341276030702 0ustar www-datawww-data# # Author:: Lamont Granquist () # Copyright:: Copyright 2015-2016, Chef Software, Inc. # License:: Apache License, Version 2.0 # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. # # XXX: we now have two copies of this file in the compat_resource cookbook. I'm uncertain if this is a # bug or a feature, and I suspect it is actually a feature. The point of this file is that for all # resources and cookbooks the global Chef::ResourceBuilder class must be upgraded to at least the # 12.10.24 version. The point of the other copy is that for compat_resource cookbooks all their # resources should be using the lastest version that has been sync'd. So these two files should # diverge as times goes on. I believe that is the correct behavior and that we want to have both # files in this cookbook. # NOTE: this was extracted from the Recipe DSL mixin, relevant specs are in spec/unit/recipe_spec.rb if Gem::Requirement.new("< 12.10.24").satisfied_by?(Gem::Version.new(Chef::VERSION)) begin require 'chef/resource_builder' # we use the LoadError this creates on early 12.x to not monkeypatch chef client versions that don't have Chef::ResourceBuilder # (it is lazily included and doesn't appear until compile time so we can't resolve the symbol during library loading) class Chef class ResourceBuilder attr_reader :type attr_reader :name attr_reader :created_at attr_reader :params attr_reader :run_context attr_reader :cookbook_name attr_reader :recipe_name attr_reader :enclosing_provider attr_reader :resource # FIXME (ruby-2.1 syntax): most of these are mandatory def initialize(type:nil, name:nil, created_at: nil, params: nil, run_context: nil, cookbook_name: nil, recipe_name: nil, enclosing_provider: nil) @type = type @name = name @created_at = created_at @params = params @run_context = run_context @cookbook_name = cookbook_name @recipe_name = recipe_name @enclosing_provider = enclosing_provider end def build(&block) raise ArgumentError, "You must supply a name when declaring a #{type} resource" if name.nil? @resource = resource_class.new(name, run_context) if resource.resource_name.nil? raise Chef::Exceptions::InvalidResourceSpecification, "#{resource}.resource_name is `nil`! Did you forget to put `provides :blah` or `resource_name :blah` in your resource class?" end resource.source_line = created_at resource.declared_type = type # If we have a resource like this one, we want to steal its state # This behavior is very counter-intuitive and should be removed. # See CHEF-3694, https://tickets.opscode.com/browse/CHEF-3694 # Moved to this location to resolve CHEF-5052, https://tickets.opscode.com/browse/CHEF-5052 if prior_resource resource.load_from(prior_resource) end resource.cookbook_name = cookbook_name resource.recipe_name = recipe_name # Determine whether this resource is being created in the context of an enclosing Provider resource.enclosing_provider = enclosing_provider # XXX: this is required for definition params inside of the scope of a # subresource to work correctly. resource.params = params # Evaluate resource attribute DSL if block_given? resource.resource_initializing = true begin resource.instance_eval(&block) ensure resource.resource_initializing = false end end # emit a cloned resource warning if it is warranted if prior_resource if is_trivial_resource?(prior_resource) && identicalish_resources?(prior_resource, resource) emit_harmless_cloning_debug else emit_cloned_resource_warning end end # Run optional resource hook resource.after_created resource end private def resource_class # Checks the new platform => short_name => resource mapping initially # then fall back to the older approach (Chef::Resource.const_get) for # backward compatibility @resource_class ||= Chef::Resource.resource_for_node(type, run_context.node) end def is_trivial_resource?(resource) identicalish_resources?(resource_class.new(name, run_context), resource) end # this is an equality test specific to checking for 3694 cloning warnings def identicalish_resources?(first, second) skipped_ivars = [ :@source_line, :@cookbook_name, :@recipe_name, :@params, :@elapsed_time, :@declared_type ] checked_ivars = ( first.instance_variables | second.instance_variables ) - skipped_ivars non_matching_ivars = checked_ivars.reject do |iv| if iv == :@action && ( [first.instance_variable_get(iv)].flatten == [:nothing] || [second.instance_variable_get(iv)].flatten == [:nothing] ) # :nothing action on either side of the comparison always matches true else first.instance_variable_get(iv) == second.instance_variable_get(iv) end end Chef::Log.debug("ivars which did not match with the prior resource: #{non_matching_ivars}") non_matching_ivars.empty? end def emit_cloned_resource_warning Chef::Log.warn("Cloning resource attributes for #{resource} from prior resource (CHEF-3694)") Chef::Log.warn("Previous #{prior_resource}: #{prior_resource.source_line}") if prior_resource.source_line Chef::Log.warn("Current #{resource}: #{resource.source_line}") if resource.source_line end def emit_harmless_cloning_debug Chef::Log.debug("Harmless resource cloning from #{prior_resource}:#{prior_resource.source_line} to #{resource}:#{resource.source_line}") end def prior_resource @prior_resource ||= begin key = "#{type}[#{name}]" run_context.resource_collection.lookup_local(key) rescue Chef::Exceptions::ResourceNotFound nil end end end end rescue LoadError # cool we're just on early chef 12.x, nothing to do -- we don't have to worry because there's also not parent_run_context pointer, so we don't have to # use lookup_local to avoid resource cloning shit out of the parent run_context. the resource collection's lookup() method will always use lookup_local # over lookup_recursive. end end compat_resource-12.10.5/files/lib/chef_compat/monkeypatches/chef/provider.rb0000644000004100000410000000232512724341276027172 0ustar www-datawww-datarequire 'chef/provider' require 'chef/provider/lwrp_base' class Chef::Provider if !defined?(InlineResources) InlineResources = Chef::Provider::LWRPBase::InlineResources end module InlineResources require 'chef/dsl/recipe' require 'chef/dsl/platform_introspection' require 'chef/dsl/data_query' require 'chef/dsl/include_recipe' include Chef::DSL::Recipe include Chef::DSL::PlatformIntrospection include Chef::DSL::DataQuery include Chef::DSL::IncludeRecipe unless Chef::Provider::InlineResources::ClassMethods.instance_method(:action).source_location[0] =~ /chefspec/ # Don't override action if chefspec is doing its thing module ::ChefCompat module Monkeypatches module InlineResources module ClassMethods def action(name, &block) super(name) { send("compile_action_#{name}") } # We put the action in its own method so that super() works. define_method("compile_action_#{name}", &block) end end end end end module ClassMethods prepend ChefCompat::Monkeypatches::InlineResources::ClassMethods end end end end compat_resource-12.10.5/files/lib/chef_compat/monkeypatches/chef/resource_collection.rb0000644000004100000410000000571112724341276031404 0ustar www-datawww-data# # Author:: Adam Jacob () # Author:: Christopher Walters () # Copyright:: Copyright 2008-2016, Chef Software Inc. # License:: Apache License, Version 2.0 # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. # require "chef/resource_collection/resource_set" require "chef/resource_collection/resource_list" require "chef/resource_collection" require "chef/exceptions" module ChefCompat module Monkeypatches module Chef module ResourceCollection module RecursiveNotificationLookup # # Copied verbatim from Chef 12.10.24 # attr_accessor :run_context def initialize(run_context = nil) super() @run_context = run_context end def lookup_local(key) resource_set.lookup(key) end def find_local(*args) resource_set.find(*args) end def lookup(key) if run_context.nil? lookup_local(key) else lookup_recursive(run_context, key) end end def find(*args) if run_context.nil? find_local(*args) else find_recursive(run_context, *args) end end private def lookup_recursive(rc, key) rc.resource_collection.send(:resource_set).lookup(key) rescue ::Chef::Exceptions::ResourceNotFound raise if !rc.respond_to?(:parent_run_context) || rc.parent_run_context.nil? lookup_recursive(rc.parent_run_context, key) end def find_recursive(rc, *args) rc.resource_collection.send(:resource_set).find(*args) rescue ::Chef::Exceptions::ResourceNotFound raise if !rc.respond_to?(:parent_run_context) || rc.parent_run_context.nil? find_recursive(rc.parent_run_context, *args) end end module DeleteResources # # Copied verbatim from Chef 12.10.24 # def delete(key) resource_list.delete(key) resource_set.delete(key) end end end end end end class Chef::ResourceCollection unless method_defined?(:lookup_local) prepend ChefCompat::Monkeypatches::Chef::ResourceCollection::RecursiveNotificationLookup end unless method_defined?(:delete) prepend ChefCompat::Monkeypatches::Chef::ResourceCollection::DeleteResources end end compat_resource-12.10.5/files/lib/chef_compat/monkeypatches/chef/property.rb0000644000004100000410000000102612724341276027221 0ustar www-datawww-data# 12.9 introduced a new optional parameter to `get()` to avoid a nil-set warning. # We need to mimick it here. if Chef::VERSION.to_f >= 12.5 && Chef::VERSION.to_f <= 12.8 require 'chef/property' class Chef class Property # 12.9 introduced a new optional parameter to `get()` to avoid a nil-set warning. # When their method gets called with 2 args, we need to ignore and call with 1. alias_method :_original_get, :get def get(resource, *args) _original_get(resource) end end end end compat_resource-12.10.5/files/lib/chef_compat/monkeypatches/chef/log.rb0000644000004100000410000000172012724341276026117 0ustar www-datawww-datarequire 'chef/log' module ChefCompat module Monkeypatches module Log def caller_location # Pick the first caller that is *not* part of the Chef gem, that's the # thing the user wrote. @compat_resource_filter_paths ||= Gem.loaded_specs['chef'].require_paths.map { |p| File.join(Gem.loaded_specs['chef'].full_gem_path, p) } + Gem.loaded_specs['compat_resource'].require_paths.map { |p| File.join(Gem.loaded_specs['compat_resource'].full_gem_path, p) } caller.select { |c| !@compat_resource_filter_paths.any? { |path| c.start_with?(path) } }.first end end end end class<<::Chef::Log prepend ChefCompat::Monkeypatches::Log end class Chef class Log unless method_defined?(:deprecation) module ChefCompatDeprecation def deprecation(message, location=nil) Chef.log_deprecation(message, location) end end extend ChefCompatDeprecation end end end compat_resource-12.10.5/files/lib/chef_compat/monkeypatches/chef/resource.rb0000644000004100000410000000221712724341276027167 0ustar www-datawww-datarequire 'chef/resource' class Chef class Resource if !method_defined?(:current_value) # # Get the current actual value of this resource. # # This does not cache--a new value will be returned each time. # # @return A new copy of the resource, with values filled in from the actual # current value. # def current_value provider = provider_for_action(Array(action).first) if provider.whyrun_mode? && !provider.whyrun_supported? raise "Cannot retrieve #{self.class.current_resource} in why-run mode: #{provider} does not support why-run" end provider.load_current_resource provider.current_resource end end # These methods are necessary for new resources to initialize old ones properly if !method_defined?(:resource_initializing) attr_reader :resource_initializing end if !method_defined?(:resource_initializing=) def resource_initializing=(value) if value @resource_initializing = value else remove_instance_variable(:@resource_initializing) end end end end end compat_resource-12.10.5/files/lib/chef_compat/monkeypatches/chef/runner.rb0000644000004100000410000000436512724341276026657 0ustar www-datawww-data#-- # Author:: Adam Jacob () # Author:: Christopher Walters () # Author:: Tim Hinderliter () # Copyright:: Copyright 2008-2016, Chef Software Inc. # License:: Apache License, Version 2.0 # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. # # minimal monkeypatch necessary to implement the notifcation features # of 12.10.x # # if before notifications are also pulled into this monkeypatch then it # may simply be easier to copy the entire Chef::Runner class from 12.10.24 # into this file. # class Chef # == Chef::Runner # This class is responsible for executing the steps in a Chef run. class Runner def delayed_actions @run_context.delayed_actions end # Determine the appropriate provider for the given resource, then # execute it. def run_action(resource, action, notification_type = nil, notifying_resource = nil) # Actually run the action for realsies resource.run_action(action, notification_type, notifying_resource) # Execute any immediate and queue up any delayed notifications # associated with the resource, but only if it was updated *this time* # we ran an action on it. if resource.updated_by_last_action? run_context.immediate_notifications(resource).each do |notification| Chef::Log.info("#{resource} sending #{notification.action} action to #{notification.resource} (immediate)") run_action(notification.resource, notification.action, :immediate, resource) end run_context.delayed_notifications(resource).each do |notification| # send the notification to the run_context of the receiving resource notification.resource.run_context.add_delayed_action(notification) end end end end end compat_resource-12.10.5/files/lib/chef_compat/monkeypatches/chef/recipe.rb0000644000004100000410000000124612724341276026610 0ustar www-datawww-datarequire 'chef/recipe' require 'chef_compat/recipe' class Chef::Recipe # If the cookbook depends on compat_resource, create a ChefCompat::Recipe object # instead of Chef::Recipe, for the extra goodies. def self.new(cookbook_name, recipe_name, run_context) if run_context && cookbook_name && recipe_name && run_context.cookbook_collection && run_context.cookbook_collection[cookbook_name] && run_context.cookbook_collection[cookbook_name].metadata.dependencies.has_key?('compat_resource') && self != ::ChefCompat::Recipe ::ChefCompat::Recipe.new(cookbook_name, recipe_name, run_context) else super end end end compat_resource-12.10.5/files/lib/chef_compat/monkeypatches/chef/exceptions.rb0000644000004100000410000000065112724341276027521 0ustar www-datawww-datarequire 'chef/exceptions' class Chef class Exceptions # Used in Resource::ActionClass#load_current_resource to denote that # the resource doesn't actually exist (for example, the file does not exist) class CurrentValueDoesNotExist < RuntimeError; end unless defined?(CurrentValueDoesNotExist) class CannotValidateStaticallyError < RuntimeError; end unless defined?(CannotValidateStaticallyError) end end compat_resource-12.10.5/files/lib/chef_compat/monkeypatches/chef.rb0000644000004100000410000000201012724341276025327 0ustar www-datawww-dataclass Chef NOT_PASSED = Object.new if !defined?(NOT_PASSED) # Earlier versions of Chef didn't have this message module ChefCompatDeprecation def log_deprecation(message, location=nil) if !location # Pick the first caller that is *not* part of the Chef or ChefCompat gem, # that's the thing the user wrote. chef_compat_gem_path = File.expand_path("../../..", __FILE__) chef_gem_path = File.expand_path("../..",::Chef::Resource.instance_method(:initialize).source_location[0]) caller(0..10).each do |c| if !c.start_with?(chef_gem_path) && !c.start_with?(chef_compat_gem_path) location = c break end end end begin super # Bleagh. `super_method` doesn't exist on older rubies and I haven't # figured out a way to check for its existence otherwise. rescue NoMethodError Chef::Log.warn(message) end end end class<= 0") if s.respond_to? :required_rubygems_version= s.authors = ["John Keiser"] s.bindir = "files/bin" s.date = "2016-06-03" s.description = "Bring some new features of Chef 12.5 to previous 12.X releases" s.email = "john@johnkeiser.com" s.files = ["CHANGELOG.md", "Gemfile", "LICENSE", "README.md", "Rakefile", "files/lib/chef_compat/copied_from_chef.rb", "files/lib/chef_compat/copied_from_chef/chef/constants.rb", "files/lib/chef_compat/copied_from_chef/chef/delayed_evaluator.rb", "files/lib/chef_compat/copied_from_chef/chef/dsl/core.rb", "files/lib/chef_compat/copied_from_chef/chef/dsl/declare_resource.rb", "files/lib/chef_compat/copied_from_chef/chef/dsl/recipe.rb", "files/lib/chef_compat/copied_from_chef/chef/mixin/lazy_module_include.rb", "files/lib/chef_compat/copied_from_chef/chef/mixin/notifying_block.rb", "files/lib/chef_compat/copied_from_chef/chef/mixin/params_validate.rb", "files/lib/chef_compat/copied_from_chef/chef/mixin/powershell_out.rb", "files/lib/chef_compat/copied_from_chef/chef/mixin/properties.rb", "files/lib/chef_compat/copied_from_chef/chef/property.rb", "files/lib/chef_compat/copied_from_chef/chef/provider.rb", "files/lib/chef_compat/copied_from_chef/chef/provider/noop.rb", "files/lib/chef_compat/copied_from_chef/chef/resource.rb", "files/lib/chef_compat/copied_from_chef/chef/resource/action_class.rb", "files/lib/chef_compat/copied_from_chef/chef/resource_builder.rb", "files/lib/chef_compat/mixin/properties.rb", "files/lib/chef_compat/monkeypatches.rb", "files/lib/chef_compat/monkeypatches/chef.rb", "files/lib/chef_compat/monkeypatches/chef/exceptions.rb", "files/lib/chef_compat/monkeypatches/chef/log.rb", "files/lib/chef_compat/monkeypatches/chef/mixin/params_validate.rb", "files/lib/chef_compat/monkeypatches/chef/property.rb", "files/lib/chef_compat/monkeypatches/chef/provider.rb", "files/lib/chef_compat/monkeypatches/chef/recipe.rb", "files/lib/chef_compat/monkeypatches/chef/resource.rb", "files/lib/chef_compat/monkeypatches/chef/resource/lwrp_base.rb", "files/lib/chef_compat/monkeypatches/chef/resource_builder.rb", "files/lib/chef_compat/monkeypatches/chef/resource_collection.rb", "files/lib/chef_compat/monkeypatches/chef/resource_collection/resource_list.rb", "files/lib/chef_compat/monkeypatches/chef/resource_collection/resource_set.rb", "files/lib/chef_compat/monkeypatches/chef/run_context.rb", "files/lib/chef_compat/monkeypatches/chef/runner.rb", "files/lib/chef_compat/property.rb", "files/lib/chef_compat/recipe.rb", "files/lib/chef_compat/resource.rb", "files/lib/chef_compat/resource/lwrp_base.rb", "files/lib/compat_resource.rb", "files/lib/compat_resource/gemspec.rb", "files/lib/compat_resource/version.rb", "files/spec/cookbook_spec.rb", "files/spec/data/Gemfile", "files/spec/data/config.rb", "files/spec/data/cookbooks/cloning/metadata.rb", "files/spec/data/cookbooks/cloning/providers/resource.rb", "files/spec/data/cookbooks/cloning/recipes/default.rb", "files/spec/data/cookbooks/cloning/resources/resource.rb", "files/spec/data/cookbooks/future/libraries/future_custom_resource.rb", "files/spec/data/cookbooks/future/libraries/super_properties.rb", "files/spec/data/cookbooks/future/metadata.rb", "files/spec/data/cookbooks/future/recipes/declare_resource.rb", "files/spec/data/cookbooks/future/resources/resource.rb", "files/spec/data/cookbooks/future/resources/super_resource.rb", "files/spec/data/cookbooks/hybrid/libraries/normal_hwrp.rb", "files/spec/data/cookbooks/hybrid/metadata.rb", "files/spec/data/cookbooks/hybrid/providers/resource.rb", "files/spec/data/cookbooks/hybrid/resources/resource.rb", "files/spec/data/cookbooks/normal/libraries/normal_hwrp.rb", "files/spec/data/cookbooks/normal/metadata.rb", "files/spec/data/cookbooks/normal/providers/resource.rb", "files/spec/data/cookbooks/normal/recipes/declare_resource.rb", "files/spec/data/cookbooks/normal/resources/resource.rb", "files/spec/data/cookbooks/notifications/metadata.rb", "files/spec/data/cookbooks/notifications/recipes/default.rb", "files/spec/data/cookbooks/notifications/resources/resource.rb", "files/spec/data/cookbooks/test/metadata.rb", "files/spec/data/cookbooks/test/recipes/default.rb", "files/spec/data/cookbooks/test/recipes/test.rb", "files/spec/data/nodes/ettores-mbp.lan.json", "files/spec/spec_helper.rb"] s.homepage = "http://chef.io" s.licenses = ["Apache 2.0"] s.require_paths = ["files/lib"] s.rubygems_version = "1.8.23" s.summary = "Bring some new features of Chef 12.5 to previous 12.X releases" if s.respond_to? :specification_version then s.specification_version = 4 if Gem::Version.new(Gem::VERSION) >= Gem::Version.new('1.2.0') then s.add_development_dependency(%q, [">= 0"]) s.add_development_dependency(%q, [">= 0"]) s.add_development_dependency(%q, [">= 0"]) s.add_development_dependency(%q, [">= 0"]) else s.add_dependency(%q, [">= 0"]) s.add_dependency(%q, [">= 0"]) s.add_dependency(%q, [">= 0"]) s.add_dependency(%q, [">= 0"]) end else s.add_dependency(%q, [">= 0"]) s.add_dependency(%q, [">= 0"]) s.add_dependency(%q, [">= 0"]) s.add_dependency(%q, [">= 0"]) end end compat_resource-12.10.5/CHANGELOG.md0000644000004100000410000000000112724341276016712 0ustar www-datawww-data compat_resource-12.10.5/README.md0000644000004100000410000000656112724341276016401 0ustar www-datawww-data# compat_resource cookbook [![Build Status](https://travis-ci.org/chef-cookbooks/compat_resource.svg?branch=master)](https://travis-ci.org/chef-cookbooks/compat_resource) [![Cookbook Version](https://img.shields.io/cookbook/v/compat_resource.svg)](https://supermarket.chef.io/cookbooks/compat_resource) This cookbook brings the custom resource syntax from Chef 12.5 to earlier Chef 12.X releases. ## Converting cookbooks from the old resource model to the new ### Boilerplate 1. Depend on compat_resource - Descend resources from ChefCompat::Resource - Set resource_name in the class instead of the constructor 2. Convert Attributes to Properties - Rename attribute -> property - Move set_or_return -> property - Take kind_of/equal_to/regexes and make them types - Use true/false/nil instead of TrueClass/FalseClass/NilClass - Remove default: nil (it's the default) 3. Convert Top-Level Providers to Actions - Create any resources that don't already exist (for example in multi-provider cases) and descend from the base resource - Remove allowed_actions / @actions - @action -> default_action - Move `provides` and `action :x` to the resource - Remove use_inline_resources and def whyrun_safe? - Move other methods to `action_class.class_eval do` Now you have everything in a resource, are using properties, and have gotten rid of a bunch of boilerplate. Of course, this is just getting it *moved*. Now you can start to really use the new features. And if you're making resources for the first time, congrats--you probably didn't have to do very much of this :) ### Advanced Concepts 1. Resource Inheritance 2. Resources That Are Different On Each OS? 3. Coercion: Handling User Input 4. Lazy Defaults 5. Using Load Current Resource 6. Using Converge If Changed 7. Defaults Are For Creation 8. Shared types: using a type multiple places Requirements ------------ #### Platforms - All platforms supported by Chef #### Chef - Chef 12.0+ #### Cookbooks - none ## Usage To use this cookbook, put `depends 'compat_resource'` in the metadata.rb of your cookbook. Once this is done, you can use all the new custom resource features to define resources. It Just Works. For example, if you create resources/myresource.rb, myresource can use `property`, `load_current_value` and `action` (no need to create a provider). If you want to create Resource classes directly, extend from `ChefCompat::Resource` instead of `Chef::Resource`. Properties, current value loading, converge_if_changed, and resource_name will all function the same across versions. ## Custom Resources? Curious about how to use custom resources? Here are the 12.5 docs: - Docs: https://docs.chef.io/custom_resources.html - Slides: https://docs.chef.io/decks/custom_resources.html ##License & Authors **Author:** John Keiser () **Copyright:** 2015, Chef Software, Inc. ``` Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License.