chef 12.4.3 → 12.5.0.alpha.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
 - data/Rakefile +1 -2
 - data/lib/chef.rb +1 -1
 - data/lib/chef/application/solo.rb +1 -1
 - data/lib/chef/application/windows_service_manager.rb +17 -12
 - data/lib/chef/chef_class.rb +7 -0
 - data/lib/chef/chef_fs/config.rb +22 -24
 - data/lib/chef/chef_fs/file_pattern.rb +4 -15
 - data/lib/chef/chef_fs/file_system/cookbook_dir.rb +1 -0
 - data/lib/chef/chef_fs/knife.rb +35 -7
 - data/lib/chef/chef_fs/path_utils.rb +65 -34
 - data/lib/chef/constants.rb +27 -0
 - data/lib/chef/delayed_evaluator.rb +21 -0
 - data/lib/chef/dsl/recipe.rb +20 -2
 - data/lib/chef/event_dispatch/base.rb +40 -16
 - data/lib/chef/event_dispatch/dsl.rb +64 -0
 - data/lib/chef/exceptions.rb +6 -1
 - data/lib/chef/formatters/doc.rb +3 -1
 - data/lib/chef/guard_interpreter/resource_guard_interpreter.rb +3 -1
 - data/lib/chef/http/http_request.rb +1 -1
 - data/lib/chef/knife/bootstrap/templates/chef-full.erb +1 -1
 - data/lib/chef/knife/ssl_check.rb +3 -2
 - data/lib/chef/knife/user_edit.rb +1 -2
 - data/lib/chef/mixin/params_validate.rb +362 -135
 - data/lib/chef/node.rb +19 -0
 - data/lib/chef/platform/handler_map.rb +0 -5
 - data/lib/chef/platform/rebooter.rb +1 -1
 - data/lib/chef/property.rb +539 -0
 - data/lib/chef/provider.rb +129 -12
 - data/lib/chef/provider/deploy.rb +3 -5
 - data/lib/chef/provider/lwrp_base.rb +1 -75
 - data/lib/chef/provider/package.rb +1 -1
 - data/lib/chef/provider/powershell_script.rb +32 -19
 - data/lib/chef/provider/registry_key.rb +5 -5
 - data/lib/chef/provider/service/macosx.rb +5 -1
 - data/lib/chef/recipe.rb +1 -8
 - data/lib/chef/resource.rb +499 -84
 - data/lib/chef/resource/file/verification.rb +7 -1
 - data/lib/chef/resource/lwrp_base.rb +1 -7
 - data/lib/chef/run_context.rb +404 -83
 - data/lib/chef/version.rb +1 -1
 - data/lib/chef/win32/registry.rb +10 -2
 - data/lib/chef/workstation_config_loader.rb +3 -158
 - data/spec/data/run_context/cookbooks/include/recipes/default.rb +24 -0
 - data/spec/data/run_context/cookbooks/include/recipes/includee.rb +3 -0
 - data/spec/functional/rebooter_spec.rb +1 -1
 - data/spec/functional/resource/{powershell_spec.rb → powershell_script_spec.rb} +3 -3
 - data/spec/functional/win32/registry_helper_spec.rb +12 -0
 - data/spec/functional/win32/service_manager_spec.rb +2 -2
 - data/spec/integration/knife/chef_repo_path_spec.rb +13 -11
 - data/spec/integration/recipes/recipe_dsl_spec.rb +0 -15
 - data/spec/integration/recipes/resource_action_spec.rb +343 -0
 - data/spec/spec_helper.rb +1 -0
 - data/spec/support/shared/functional/win32_service.rb +2 -1
 - data/spec/unit/application/solo_spec.rb +4 -3
 - data/spec/unit/chef_class_spec.rb +23 -0
 - data/spec/unit/chef_fs/path_util_spec.rb +108 -0
 - data/spec/unit/event_dispatch/dsl_spec.rb +87 -0
 - data/spec/unit/json_compat_spec.rb +4 -3
 - data/spec/unit/knife/ssl_check_spec.rb +4 -0
 - data/spec/unit/mixin/params_validate_spec.rb +4 -2
 - data/spec/unit/node_spec.rb +7 -0
 - data/spec/unit/property/state_spec.rb +506 -0
 - data/spec/unit/property/validation_spec.rb +658 -0
 - data/spec/unit/property_spec.rb +968 -0
 - data/spec/unit/provider/{powershell_spec.rb → powershell_script_spec.rb} +0 -0
 - data/spec/unit/provider/registry_key_spec.rb +12 -0
 - data/spec/unit/provider/service/macosx_spec.rb +4 -4
 - data/spec/unit/provider_spec.rb +1 -3
 - data/spec/unit/recipe_spec.rb +0 -4
 - data/spec/unit/registry_helper_spec.rb +15 -1
 - data/spec/unit/resource/file/verification_spec.rb +33 -5
 - data/spec/unit/resource/{powershell_spec.rb → powershell_script_spec.rb} +0 -0
 - data/spec/unit/resource_spec.rb +2 -2
 - data/spec/unit/run_context/child_run_context_spec.rb +133 -0
 - data/spec/unit/run_context_spec.rb +7 -0
 - metadata +25 -25
 - data/spec/unit/workstation_config_loader_spec.rb +0 -283
 
    
        checksums.yaml
    CHANGED
    
    | 
         @@ -1,7 +1,7 @@ 
     | 
|
| 
       1 
1 
     | 
    
         
             
            ---
         
     | 
| 
       2 
2 
     | 
    
         
             
            SHA1:
         
     | 
| 
       3 
     | 
    
         
            -
              metadata.gz:  
     | 
| 
       4 
     | 
    
         
            -
              data.tar.gz:  
     | 
| 
      
 3 
     | 
    
         
            +
              metadata.gz: b878f5f1ff6e11e17f28431bf13983c1eb79b7a8
         
     | 
| 
      
 4 
     | 
    
         
            +
              data.tar.gz: 1a4961de80b9f4f9c76b0c76747a14af12818519
         
     | 
| 
       5 
5 
     | 
    
         
             
            SHA512:
         
     | 
| 
       6 
     | 
    
         
            -
              metadata.gz:  
     | 
| 
       7 
     | 
    
         
            -
              data.tar.gz:  
     | 
| 
      
 6 
     | 
    
         
            +
              metadata.gz: f8d3e8cb4a2f4cd826942d7bf6f7b250964a1197677b30f8a3f64711d568e84241a22ad0effa4e0fe721556a58bf51cf84f418a7ef2d986943a913020f9ee13f
         
     | 
| 
      
 7 
     | 
    
         
            +
              data.tar.gz: 54ab263002c8de538b3167e25b17bbc37808d705c33817b9634d2ad7ba032c8ea9d0b02e84514d70d4178d11ab350f58a4f7a01c04c81e044e1d54ffb4f278ba
         
     | 
    
        data/Rakefile
    CHANGED
    
    | 
         @@ -131,7 +131,7 @@ end 
     | 
|
| 
       131 
131 
     | 
    
         
             
            desc "Build it, tag it and ship it"
         
     | 
| 
       132 
132 
     | 
    
         
             
            task :ship => [:clobber_package, :gem] do
         
     | 
| 
       133 
133 
     | 
    
         
             
              sh("git tag #{VERSION}")
         
     | 
| 
       134 
     | 
    
         
            -
              sh("git push  
     | 
| 
      
 134 
     | 
    
         
            +
              sh("git push chef --tags")
         
     | 
| 
       135 
135 
     | 
    
         
             
              Dir[File.expand_path("../pkg/*.gem", __FILE__)].reverse.each do |built_gem|
         
     | 
| 
       136 
136 
     | 
    
         
             
                sh("gem push #{built_gem}")
         
     | 
| 
       137 
137 
     | 
    
         
             
              end
         
     | 
| 
         @@ -168,4 +168,3 @@ begin 
     | 
|
| 
       168 
168 
     | 
    
         
             
            rescue LoadError
         
     | 
| 
       169 
169 
     | 
    
         
             
              puts "yard is not available. (sudo) gem install yard to generate yard documentation."
         
     | 
| 
       170 
170 
     | 
    
         
             
            end
         
     | 
| 
       171 
     | 
    
         
            -
             
     | 
    
        data/lib/chef.rb
    CHANGED
    
    
| 
         @@ -214,7 +214,7 @@ class Chef::Application::Solo < Chef::Application 
     | 
|
| 
       214 
214 
     | 
    
         
             
                  FileUtils.mkdir_p(recipes_path)
         
     | 
| 
       215 
215 
     | 
    
         
             
                  tarball_path = File.join(recipes_path, 'recipes.tgz')
         
     | 
| 
       216 
216 
     | 
    
         
             
                  fetch_recipe_tarball(Chef::Config[:recipe_url], tarball_path)
         
     | 
| 
       217 
     | 
    
         
            -
                   
     | 
| 
      
 217 
     | 
    
         
            +
                  Mixlib::ShellOut.new("tar zxvf #{tarball_path} -C #{recipes_path}").run_command
         
     | 
| 
       218 
218 
     | 
    
         
             
                end
         
     | 
| 
       219 
219 
     | 
    
         | 
| 
       220 
220 
     | 
    
         
             
                # json_attribs shuld be fetched after recipe_url tarball is unpacked.
         
     | 
| 
         @@ -78,7 +78,7 @@ class Chef 
     | 
|
| 
       78 
78 
     | 
    
         | 
| 
       79 
79 
     | 
    
         
             
                    raise ArgumentError, "Service definition is not provided" if service_options.nil?
         
     | 
| 
       80 
80 
     | 
    
         | 
| 
       81 
     | 
    
         
            -
                    required_options = [:service_name, :service_display_name, : 
     | 
| 
      
 81 
     | 
    
         
            +
                    required_options = [:service_name, :service_display_name, :service_description, :service_file_path]
         
     | 
| 
       82 
82 
     | 
    
         | 
| 
       83 
83 
     | 
    
         
             
                    required_options.each do |req_option|
         
     | 
| 
       84 
84 
     | 
    
         
             
                      if !service_options.has_key?(req_option)
         
     | 
| 
         @@ -92,6 +92,7 @@ class Chef 
     | 
|
| 
       92 
92 
     | 
    
         
             
                    @service_file_path = service_options[:service_file_path]
         
     | 
| 
       93 
93 
     | 
    
         
             
                    @service_start_name = service_options[:run_as_user]
         
     | 
| 
       94 
94 
     | 
    
         
             
                    @password = service_options[:run_as_password]
         
     | 
| 
      
 95 
     | 
    
         
            +
                    @delayed_start = service_options[:delayed_start]
         
     | 
| 
       95 
96 
     | 
    
         
             
                  end
         
     | 
| 
       96 
97 
     | 
    
         | 
| 
       97 
98 
     | 
    
         
             
                  def run(params = ARGV)
         
     | 
| 
         @@ -113,17 +114,21 @@ class Chef 
     | 
|
| 
       113 
114 
     | 
    
         
             
                        cmd = "\"#{ruby}\" \"#{@service_file_path}\" #{opts}".gsub(File::SEPARATOR, File::ALT_SEPARATOR)
         
     | 
| 
       114 
115 
     | 
    
         | 
| 
       115 
116 
     | 
    
         
             
                        ::Win32::Service.new(
         
     | 
| 
       116 
     | 
    
         
            -
             
     | 
| 
       117 
     | 
    
         
            -
             
     | 
| 
       118 
     | 
    
         
            -
             
     | 
| 
       119 
     | 
    
         
            -
             
     | 
| 
       120 
     | 
    
         
            -
             
     | 
| 
       121 
     | 
    
         
            -
             
     | 
| 
       122 
     | 
    
         
            -
             
     | 
| 
       123 
     | 
    
         
            -
             
     | 
| 
       124 
     | 
    
         
            -
             
     | 
| 
       125 
     | 
    
         
            -
             
     | 
| 
       126 
     | 
    
         
            -
             
     | 
| 
      
 117 
     | 
    
         
            +
                          :service_name     => @service_name,
         
     | 
| 
      
 118 
     | 
    
         
            +
                          :display_name     => @service_display_name,
         
     | 
| 
      
 119 
     | 
    
         
            +
                          :description      => @service_description,
         
     | 
| 
      
 120 
     | 
    
         
            +
                          # Prior to 0.8.5, win32-service creates interactive services by default,
         
     | 
| 
      
 121 
     | 
    
         
            +
                          # and we don't want that, so we need to override the service type.
         
     | 
| 
      
 122 
     | 
    
         
            +
                          :service_type     => ::Win32::Service::SERVICE_WIN32_OWN_PROCESS,
         
     | 
| 
      
 123 
     | 
    
         
            +
                          :start_type       => ::Win32::Service::SERVICE_AUTO_START,
         
     | 
| 
      
 124 
     | 
    
         
            +
                          :binary_path_name => cmd,
         
     | 
| 
      
 125 
     | 
    
         
            +
                          :service_start_name => @service_start_name,
         
     | 
| 
      
 126 
     | 
    
         
            +
                          :password => @password,
         
     | 
| 
      
 127 
     | 
    
         
            +
                        )
         
     | 
| 
      
 128 
     | 
    
         
            +
                        ::Win32::Service.configure(
         
     | 
| 
      
 129 
     | 
    
         
            +
                          :service_name     => @service_name,
         
     | 
| 
      
 130 
     | 
    
         
            +
                          :delayed_start    => @delayed_start
         
     | 
| 
      
 131 
     | 
    
         
            +
                        ) unless @delayed_start.nil?
         
     | 
| 
       127 
132 
     | 
    
         
             
                        puts "Service '#{@service_name}' has successfully been installed."
         
     | 
| 
       128 
133 
     | 
    
         
             
                      end
         
     | 
| 
       129 
134 
     | 
    
         
             
                    when 'status'
         
     | 
    
        data/lib/chef/chef_class.rb
    CHANGED
    
    | 
         @@ -52,7 +52,14 @@ class Chef 
     | 
|
| 
       52 
52 
     | 
    
         
             
                #
         
     | 
| 
       53 
53 
     | 
    
         
             
                attr_reader :run_context
         
     | 
| 
       54 
54 
     | 
    
         | 
| 
      
 55 
     | 
    
         
            +
                # Register an event handler with user specified block
         
     | 
| 
       55 
56 
     | 
    
         
             
                #
         
     | 
| 
      
 57 
     | 
    
         
            +
                # @return[Chef::EventDispatch::Base] handler object
         
     | 
| 
      
 58 
     | 
    
         
            +
                def event_handler(&block)
         
     | 
| 
      
 59 
     | 
    
         
            +
                  dsl = Chef::EventDispatch::DSL.new('Chef client DSL')
         
     | 
| 
      
 60 
     | 
    
         
            +
                  dsl.instance_eval(&block)
         
     | 
| 
      
 61 
     | 
    
         
            +
                end
         
     | 
| 
      
 62 
     | 
    
         
            +
             
     | 
| 
       56 
63 
     | 
    
         
             
                # Get the array of providers associated with a resource_name for the current node
         
     | 
| 
       57 
64 
     | 
    
         
             
                #
         
     | 
| 
       58 
65 
     | 
    
         
             
                # @param resource_name [Symbol] name of the resource as a symbol
         
     | 
    
        data/lib/chef/chef_fs/config.rb
    CHANGED
    
    | 
         @@ -111,7 +111,7 @@ class Chef 
     | 
|
| 
       111 
111 
     | 
    
         
             
                  #
         
     | 
| 
       112 
112 
     | 
    
         
             
                  def initialize(chef_config = Chef::Config, cwd = Dir.pwd, options = {}, ui = nil)
         
     | 
| 
       113 
113 
     | 
    
         
             
                    @chef_config = chef_config
         
     | 
| 
       114 
     | 
    
         
            -
                    @cwd = cwd
         
     | 
| 
      
 114 
     | 
    
         
            +
                    @cwd = File.expand_path(cwd)
         
     | 
| 
       115 
115 
     | 
    
         
             
                    @cookbook_version = options[:cookbook_version]
         
     | 
| 
       116 
116 
     | 
    
         | 
| 
       117 
117 
     | 
    
         
             
                    if @chef_config[:repo_mode] == 'everything' && is_hosted? && !ui.nil?
         
     | 
| 
         @@ -166,34 +166,37 @@ class Chef 
     | 
|
| 
       166 
166 
     | 
    
         
             
                  # server_path('/home/jkeiser/chef_repo/cookbooks/blah') == '/cookbooks/blah'
         
     | 
| 
       167 
167 
     | 
    
         
             
                  # server_path('/home/*/chef_repo/cookbooks/blah') == nil
         
     | 
| 
       168 
168 
     | 
    
         
             
                  #
         
     | 
| 
       169 
     | 
    
         
            -
                  # If there are multiple  
     | 
| 
       170 
     | 
    
         
            -
                  # have separate paths), and cwd+the 
     | 
| 
       171 
     | 
    
         
            -
                  #  
     | 
| 
       172 
     | 
    
         
            -
                  #  
     | 
| 
      
 169 
     | 
    
         
            +
                  # If there are multiple different, manually specified paths to object locations
         
     | 
| 
      
 170 
     | 
    
         
            +
                  # (cookbooks, roles, data bags, etc. can all have separate paths), and cwd+the
         
     | 
| 
      
 171 
     | 
    
         
            +
                  # path reaches into one of them, we will return a path relative to the first
         
     | 
| 
      
 172 
     | 
    
         
            +
                  # one to match it.  Otherwise we expect the path provided to be to the chef
         
     | 
| 
      
 173 
     | 
    
         
            +
                  # repo path itself.  Paths that are not available on the server are not supported.
         
     | 
| 
       173 
174 
     | 
    
         
             
                  #
         
     | 
| 
       174 
175 
     | 
    
         
             
                  # Globs are allowed as well, but globs outside server paths are NOT
         
     | 
| 
       175 
176 
     | 
    
         
             
                  # (presently) supported.  See above examples.  TODO support that.
         
     | 
| 
       176 
177 
     | 
    
         
             
                  #
         
     | 
| 
       177 
178 
     | 
    
         
             
                  # If the path does not reach into ANY specified directory, nil is returned.
         
     | 
| 
       178 
179 
     | 
    
         
             
                  def server_path(file_path)
         
     | 
| 
       179 
     | 
    
         
            -
                     
     | 
| 
       180 
     | 
    
         
            -
                    absolute_pwd = Chef::ChefFS::PathUtils.realest_path(File.expand_path(file_path, pwd))
         
     | 
| 
      
 180 
     | 
    
         
            +
                    target_path = Chef::ChefFS::PathUtils.realest_path(file_path, @cwd)
         
     | 
| 
       181 
181 
     | 
    
         | 
| 
       182 
182 
     | 
    
         
             
                    # Check all object paths (cookbooks_dir, data_bags_dir, etc.)
         
     | 
| 
      
 183 
     | 
    
         
            +
                    # These are either manually specified by the user or autogenerated relative
         
     | 
| 
      
 184 
     | 
    
         
            +
                    # to chef_repo_path.
         
     | 
| 
       183 
185 
     | 
    
         
             
                    object_paths.each_pair do |name, paths|
         
     | 
| 
       184 
186 
     | 
    
         
             
                      paths.each do |path|
         
     | 
| 
       185 
     | 
    
         
            -
                         
     | 
| 
       186 
     | 
    
         
            -
                        if PathUtils. 
     | 
| 
       187 
     | 
    
         
            -
                           
     | 
| 
       188 
     | 
    
         
            -
                          return relative_path == '.' ? "/#{name}" : "/#{name}/#{relative_path}"
         
     | 
| 
      
 187 
     | 
    
         
            +
                        object_abs_path = Chef::ChefFS::PathUtils.realest_path(path, @cwd)
         
     | 
| 
      
 188 
     | 
    
         
            +
                        if relative_path = PathUtils.descendant_path(target_path, object_abs_path)
         
     | 
| 
      
 189 
     | 
    
         
            +
                          return Chef::ChefFS::PathUtils.join("/#{name}", relative_path)
         
     | 
| 
       189 
190 
     | 
    
         
             
                        end
         
     | 
| 
       190 
191 
     | 
    
         
             
                      end
         
     | 
| 
       191 
192 
     | 
    
         
             
                    end
         
     | 
| 
       192 
193 
     | 
    
         | 
| 
       193 
194 
     | 
    
         
             
                    # Check chef_repo_path
         
     | 
| 
       194 
195 
     | 
    
         
             
                    Array(@chef_config[:chef_repo_path]).flatten.each do |chef_repo_path|
         
     | 
| 
       195 
     | 
    
         
            -
                       
     | 
| 
       196 
     | 
    
         
            -
                      if  
     | 
| 
      
 196 
     | 
    
         
            +
                      # We're using realest_path here but we really don't need to - we can just expand the
         
     | 
| 
      
 197 
     | 
    
         
            +
                      # path and use realpath because a repo_path if provided *must* exist.
         
     | 
| 
      
 198 
     | 
    
         
            +
                      realest_chef_repo_path = Chef::ChefFS::PathUtils.realest_path(chef_repo_path, @cwd)
         
     | 
| 
      
 199 
     | 
    
         
            +
                      if Chef::ChefFS::PathUtils.os_path_eq?(target_path, realest_chef_repo_path)
         
     | 
| 
       197 
200 
     | 
    
         
             
                        return '/'
         
     | 
| 
       198 
201 
     | 
    
         
             
                      end
         
     | 
| 
       199 
202 
     | 
    
         
             
                    end
         
     | 
| 
         @@ -201,15 +204,10 @@ class Chef 
     | 
|
| 
       201 
204 
     | 
    
         
             
                    nil
         
     | 
| 
       202 
205 
     | 
    
         
             
                  end
         
     | 
| 
       203 
206 
     | 
    
         | 
| 
       204 
     | 
    
         
            -
                  # The current directory, relative to server root
         
     | 
| 
      
 207 
     | 
    
         
            +
                  # The current directory, relative to server root.  This is a case-sensitive server path.
         
     | 
| 
      
 208 
     | 
    
         
            +
                  # It only exists if the current directory is a child of one of the recognized object_paths below.
         
     | 
| 
       205 
209 
     | 
    
         
             
                  def base_path
         
     | 
| 
       206 
     | 
    
         
            -
                    @base_path ||=  
     | 
| 
       207 
     | 
    
         
            -
                      if @chef_config[:chef_repo_path]
         
     | 
| 
       208 
     | 
    
         
            -
                        server_path(File.expand_path(@cwd))
         
     | 
| 
       209 
     | 
    
         
            -
                      else
         
     | 
| 
       210 
     | 
    
         
            -
                        nil
         
     | 
| 
       211 
     | 
    
         
            -
                      end
         
     | 
| 
       212 
     | 
    
         
            -
                    end
         
     | 
| 
      
 210 
     | 
    
         
            +
                    @base_path ||= server_path(@cwd)
         
     | 
| 
       213 
211 
     | 
    
         
             
                  end
         
     | 
| 
       214 
212 
     | 
    
         | 
| 
       215 
213 
     | 
    
         
             
                  # Print the given server path, relative to the current directory
         
     | 
| 
         @@ -217,10 +215,10 @@ class Chef 
     | 
|
| 
       217 
215 
     | 
    
         
             
                    server_path = entry.path
         
     | 
| 
       218 
216 
     | 
    
         
             
                    if base_path && server_path[0,base_path.length] == base_path
         
     | 
| 
       219 
217 
     | 
    
         
             
                      if server_path == base_path
         
     | 
| 
       220 
     | 
    
         
            -
                        return  
     | 
| 
       221 
     | 
    
         
            -
                      elsif server_path[base_path.length,1] ==  
     | 
| 
      
 218 
     | 
    
         
            +
                        return '.'
         
     | 
| 
      
 219 
     | 
    
         
            +
                      elsif server_path[base_path.length,1] == '/'
         
     | 
| 
       222 
220 
     | 
    
         
             
                        return server_path[base_path.length + 1, server_path.length - base_path.length - 1]
         
     | 
| 
       223 
     | 
    
         
            -
                      elsif base_path ==  
     | 
| 
      
 221 
     | 
    
         
            +
                      elsif base_path == '/' && server_path[0,1] == '/'
         
     | 
| 
       224 
222 
     | 
    
         
             
                        return server_path[1, server_path.length - 1]
         
     | 
| 
       225 
223 
     | 
    
         
             
                      end
         
     | 
| 
       226 
224 
     | 
    
         
             
                    end
         
     | 
| 
         @@ -72,7 +72,7 @@ class Chef 
     | 
|
| 
       72 
72 
     | 
    
         
             
                  def could_match_children?(path)
         
     | 
| 
       73 
73 
     | 
    
         
             
                    return false if path == '' # Empty string is not a path
         
     | 
| 
       74 
74 
     | 
    
         | 
| 
       75 
     | 
    
         
            -
                    argument_is_absolute =  
     | 
| 
      
 75 
     | 
    
         
            +
                    argument_is_absolute = Chef::ChefFS::PathUtils::is_absolute?(path)
         
     | 
| 
       76 
76 
     | 
    
         
             
                    return false if is_absolute != argument_is_absolute
         
     | 
| 
       77 
77 
     | 
    
         
             
                    path = path[1,path.length-1] if argument_is_absolute
         
     | 
| 
       78 
78 
     | 
    
         | 
| 
         @@ -111,7 +111,7 @@ class Chef 
     | 
|
| 
       111 
111 
     | 
    
         
             
                  #
         
     | 
| 
       112 
112 
     | 
    
         
             
                  # This method assumes +could_match_children?(path)+ is +true+.
         
     | 
| 
       113 
113 
     | 
    
         
             
                  def exact_child_name_under(path)
         
     | 
| 
       114 
     | 
    
         
            -
                    path = path[1,path.length-1] if  
     | 
| 
      
 114 
     | 
    
         
            +
                    path = path[1,path.length-1] if Chef::ChefFS::PathUtils::is_absolute?(path)
         
     | 
| 
       115 
115 
     | 
    
         
             
                    dirs_in_path = Chef::ChefFS::PathUtils::split(path).length
         
     | 
| 
       116 
116 
     | 
    
         
             
                    return nil if exact_parts.length <= dirs_in_path
         
     | 
| 
       117 
117 
     | 
    
         
             
                    return exact_parts[dirs_in_path]
         
     | 
| 
         @@ -149,7 +149,7 @@ class Chef 
     | 
|
| 
       149 
149 
     | 
    
         
             
                  #   abc/*/def.match?('abc/foo/def') == true
         
     | 
| 
       150 
150 
     | 
    
         
             
                  #   abc/*/def.match?('abc/foo') == false
         
     | 
| 
       151 
151 
     | 
    
         
             
                  def match?(path)
         
     | 
| 
       152 
     | 
    
         
            -
                    argument_is_absolute =  
     | 
| 
      
 152 
     | 
    
         
            +
                    argument_is_absolute = Chef::ChefFS::PathUtils::is_absolute?(path)
         
     | 
| 
       153 
153 
     | 
    
         
             
                    return false if is_absolute != argument_is_absolute
         
     | 
| 
       154 
154 
     | 
    
         
             
                    path = path[1,path.length-1] if argument_is_absolute
         
     | 
| 
       155 
155 
     | 
    
         
             
                    !!regexp.match(path)
         
     | 
| 
         @@ -160,17 +160,6 @@ class Chef 
     | 
|
| 
       160 
160 
     | 
    
         
             
                    pattern
         
     | 
| 
       161 
161 
     | 
    
         
             
                  end
         
     | 
| 
       162 
162 
     | 
    
         | 
| 
       163 
     | 
    
         
            -
                  # Given a relative file pattern and a directory, makes a new file pattern
         
     | 
| 
       164 
     | 
    
         
            -
                  # starting with the directory.
         
     | 
| 
       165 
     | 
    
         
            -
                  #
         
     | 
| 
       166 
     | 
    
         
            -
                  #   FilePattern.relative_to('/usr/local', 'bin/*grok') == FilePattern.new('/usr/local/bin/*grok')
         
     | 
| 
       167 
     | 
    
         
            -
                  #
         
     | 
| 
       168 
     | 
    
         
            -
                  # BUG: this does not support patterns starting with <tt>..</tt>
         
     | 
| 
       169 
     | 
    
         
            -
                  def self.relative_to(dir, pattern)
         
     | 
| 
       170 
     | 
    
         
            -
                    return FilePattern.new(pattern) if pattern =~ /^#{Chef::ChefFS::PathUtils::regexp_path_separator}/
         
     | 
| 
       171 
     | 
    
         
            -
                    FilePattern.new(Chef::ChefFS::PathUtils::join(dir, pattern))
         
     | 
| 
       172 
     | 
    
         
            -
                  end
         
     | 
| 
       173 
     | 
    
         
            -
             
     | 
| 
       174 
163 
     | 
    
         
             
                private
         
     | 
| 
       175 
164 
     | 
    
         | 
| 
       176 
165 
     | 
    
         
             
                  def regexp
         
     | 
| 
         @@ -195,7 +184,7 @@ class Chef 
     | 
|
| 
       195 
184 
     | 
    
         | 
| 
       196 
185 
     | 
    
         
             
                  def calculate
         
     | 
| 
       197 
186 
     | 
    
         
             
                    if !@regexp
         
     | 
| 
       198 
     | 
    
         
            -
                      @is_absolute =  
     | 
| 
      
 187 
     | 
    
         
            +
                      @is_absolute = Chef::ChefFS::PathUtils::is_absolute?(@pattern)
         
     | 
| 
       199 
188 
     | 
    
         | 
| 
       200 
189 
     | 
    
         
             
                      full_regexp_parts = []
         
     | 
| 
       201 
190 
     | 
    
         
             
                      normalized_parts = []
         
     | 
    
        data/lib/chef/chef_fs/knife.rb
    CHANGED
    
    | 
         @@ -17,6 +17,7 @@ 
     | 
|
| 
       17 
17 
     | 
    
         
             
            #
         
     | 
| 
       18 
18 
     | 
    
         | 
| 
       19 
19 
     | 
    
         
             
            require 'chef/knife'
         
     | 
| 
      
 20 
     | 
    
         
            +
            require 'pathname'
         
     | 
| 
       20 
21 
     | 
    
         | 
| 
       21 
22 
     | 
    
         
             
            class Chef
         
     | 
| 
       22 
23 
     | 
    
         
             
              module ChefFS
         
     | 
| 
         @@ -63,7 +64,7 @@ class Chef 
     | 
|
| 
       63 
64 
     | 
    
         
             
                    # --chef-repo-path forcibly overrides all other paths
         
     | 
| 
       64 
65 
     | 
    
         
             
                    if config[:chef_repo_path]
         
     | 
| 
       65 
66 
     | 
    
         
             
                      Chef::Config[:chef_repo_path] = config[:chef_repo_path]
         
     | 
| 
       66 
     | 
    
         
            -
                       
     | 
| 
      
 67 
     | 
    
         
            +
                      Chef::ChefFS::Config::INFLECTIONS.each_value do |variable_name|
         
     | 
| 
       67 
68 
     | 
    
         
             
                        Chef::Config.delete("#{variable_name}_path".to_sym)
         
     | 
| 
       68 
69 
     | 
    
         
             
                      end
         
     | 
| 
       69 
70 
     | 
    
         
             
                    end
         
     | 
| 
         @@ -98,14 +99,41 @@ class Chef 
     | 
|
| 
       98 
99 
     | 
    
         
             
                  end
         
     | 
| 
       99 
100 
     | 
    
         | 
| 
       100 
101 
     | 
    
         
             
                  def pattern_arg_from(arg)
         
     | 
| 
       101 
     | 
    
         
            -
                     
     | 
| 
       102 
     | 
    
         
            -
                     
     | 
| 
       103 
     | 
    
         
            -
             
     | 
| 
       104 
     | 
    
         
            -
                      #  
     | 
| 
       105 
     | 
    
         
            -
                       
     | 
| 
      
 102 
     | 
    
         
            +
                    inferred_path = nil
         
     | 
| 
      
 103 
     | 
    
         
            +
                    if Chef::ChefFS::PathUtils.is_absolute?(arg)
         
     | 
| 
      
 104 
     | 
    
         
            +
                      # We should be able to use this as-is - but the user might have incorrectly provided
         
     | 
| 
      
 105 
     | 
    
         
            +
                      # us with a path that is based off of the OS root path instead of the Chef-FS root.
         
     | 
| 
      
 106 
     | 
    
         
            +
                      # Do a quick and dirty sanity check.
         
     | 
| 
      
 107 
     | 
    
         
            +
                      if possible_server_path = @chef_fs_config.server_path(arg)
         
     | 
| 
      
 108 
     | 
    
         
            +
                        ui.warn("The absolute path provided is suspicious: #{arg}")
         
     | 
| 
      
 109 
     | 
    
         
            +
                        ui.warn("If you wish to refer to a file location, please provide a path that is rooted at the chef-repo.")
         
     | 
| 
      
 110 
     | 
    
         
            +
                        ui.warn("Consider writing '#{possible_server_path}' instead of '#{arg}'")
         
     | 
| 
      
 111 
     | 
    
         
            +
                      end
         
     | 
| 
      
 112 
     | 
    
         
            +
                      # Use the original path because we can't be sure.
         
     | 
| 
      
 113 
     | 
    
         
            +
                      inferred_path = arg
         
     | 
| 
      
 114 
     | 
    
         
            +
                    elsif arg[0,1] == '~'
         
     | 
| 
      
 115 
     | 
    
         
            +
                      # Let's be nice and fix it if possible - but warn the user.
         
     | 
| 
      
 116 
     | 
    
         
            +
                      ui.warn("A path relative to a user home directory has been provided: #{arg}")
         
     | 
| 
      
 117 
     | 
    
         
            +
                      ui.warn("Paths provided need to be rooted at the chef-repo being considered or be relative paths.")
         
     | 
| 
      
 118 
     | 
    
         
            +
                      inferred_path = @chef_fs_config.server_path(arg)
         
     | 
| 
      
 119 
     | 
    
         
            +
                      ui.warn("Using '#{inferred_path}' as the path instead of '#{arg}'.")
         
     | 
| 
      
 120 
     | 
    
         
            +
                    elsif Pathname.new(arg).absolute?
         
     | 
| 
      
 121 
     | 
    
         
            +
                      # It is definitely a system absolute path (such as C:\ or \\foo\bar) but it cannot be
         
     | 
| 
      
 122 
     | 
    
         
            +
                      # interpreted as a Chef-FS absolute path.  Again attempt to be nice but warn the user.
         
     | 
| 
      
 123 
     | 
    
         
            +
                      ui.warn("An absolute file system path that isn't a server path was provided: #{arg}")
         
     | 
| 
      
 124 
     | 
    
         
            +
                      ui.warn("Paths provided need to be rooted at the chef-repo being considered or be relative paths.")
         
     | 
| 
      
 125 
     | 
    
         
            +
                      inferred_path = @chef_fs_config.server_path(arg)
         
     | 
| 
      
 126 
     | 
    
         
            +
                      ui.warn("Using '#{inferred_path}' as the path instead of '#{arg}'.")
         
     | 
| 
      
 127 
     | 
    
         
            +
                    elsif @chef_fs_config.base_path.nil?
         
     | 
| 
      
 128 
     | 
    
         
            +
                      # These are all relative paths.  We can't resolve and root paths unless we are in the
         
     | 
| 
      
 129 
     | 
    
         
            +
                      # chef repo.
         
     | 
| 
      
 130 
     | 
    
         
            +
                      ui.error("Attempt to use relative path '#{arg}' when current directory is outside the repository path.")
         
     | 
| 
      
 131 
     | 
    
         
            +
                      ui.error("Current working directory is '#{@chef_fs_config.cwd}'.")
         
     | 
| 
       106 
132 
     | 
    
         
             
                      exit(1)
         
     | 
| 
      
 133 
     | 
    
         
            +
                    else
         
     | 
| 
      
 134 
     | 
    
         
            +
                      inferred_path = Chef::ChefFS::PathUtils::join(@chef_fs_config.base_path, arg)
         
     | 
| 
       107 
135 
     | 
    
         
             
                    end
         
     | 
| 
       108 
     | 
    
         
            -
                    Chef::ChefFS::FilePattern. 
     | 
| 
      
 136 
     | 
    
         
            +
                    Chef::ChefFS::FilePattern.new(inferred_path)
         
     | 
| 
       109 
137 
     | 
    
         
             
                  end
         
     | 
| 
       110 
138 
     | 
    
         | 
| 
       111 
139 
     | 
    
         
             
                  def format_path(entry)
         
     | 
| 
         @@ -23,31 +23,31 @@ class Chef 
     | 
|
| 
       23 
23 
     | 
    
         
             
              module ChefFS
         
     | 
| 
       24 
24 
     | 
    
         
             
                class PathUtils
         
     | 
| 
       25 
25 
     | 
    
         | 
| 
       26 
     | 
    
         
            -
                  #  
     | 
| 
       27 
     | 
    
         
            -
                  #  
     | 
| 
       28 
     | 
    
         
            -
                  #  
     | 
| 
       29 
     | 
    
         
            -
                   
     | 
| 
       30 
     | 
    
         
            -
             
     | 
| 
       31 
     | 
    
         
            -
             
     | 
| 
       32 
     | 
    
         
            -
             
     | 
| 
       33 
     | 
    
         
            -
             
     | 
| 
       34 
     | 
    
         
            -
             
     | 
| 
       35 
     | 
    
         
            -
             
     | 
| 
       36 
     | 
    
         
            -
             
     | 
| 
       37 
     | 
    
         
            -
             
     | 
| 
       38 
     | 
    
         
            -
             
     | 
| 
       39 
     | 
    
         
            -
             
     | 
| 
       40 
     | 
    
         
            -
             
     | 
| 
       41 
     | 
    
         
            -
                   
     | 
| 
      
 26 
     | 
    
         
            +
                  # A Chef-FS path is a path in a chef-repository that can be used to address
         
     | 
| 
      
 27 
     | 
    
         
            +
                  # both files on a local file-system as well as objects on a chef server.
         
     | 
| 
      
 28 
     | 
    
         
            +
                  # These paths are stricter than file-system paths allowed on various OSes.
         
     | 
| 
      
 29 
     | 
    
         
            +
                  # Absolute Chef-FS paths begin with "/" (on windows, "\" is acceptable as well).
         
     | 
| 
      
 30 
     | 
    
         
            +
                  # "/" is used as the path element separator (on windows, "\" is acceptable as well).
         
     | 
| 
      
 31 
     | 
    
         
            +
                  # No directory/path element may contain a literal "\" character.  Any such characters
         
     | 
| 
      
 32 
     | 
    
         
            +
                  # encountered are either dealt with as separators (on windows) or as escape
         
     | 
| 
      
 33 
     | 
    
         
            +
                  # characters (on POSIX systems).  Relative Chef-FS paths may use ".." or "." but
         
     | 
| 
      
 34 
     | 
    
         
            +
                  # may never use these to back-out of the root of a Chef-FS path.  Any such extraneous
         
     | 
| 
      
 35 
     | 
    
         
            +
                  # ".."s are ignored.
         
     | 
| 
      
 36 
     | 
    
         
            +
                  # Chef-FS paths are case sensitive (since the paths on the server are).
         
     | 
| 
      
 37 
     | 
    
         
            +
                  # On OSes with case insensitive paths, you may be unable to locally deal with two
         
     | 
| 
      
 38 
     | 
    
         
            +
                  # objects whose server paths only differ by case.  OTOH, the case of path segments
         
     | 
| 
      
 39 
     | 
    
         
            +
                  # that are outside the Chef-FS root (such as when looking at a file-system absolute
         
     | 
| 
      
 40 
     | 
    
         
            +
                  # path to discover the Chef-FS root path) are handled in accordance to the rules
         
     | 
| 
      
 41 
     | 
    
         
            +
                  # of the local file-system and OS.
         
     | 
| 
       42 
42 
     | 
    
         | 
| 
       43 
43 
     | 
    
         
             
                  def self.join(*parts)
         
     | 
| 
       44 
44 
     | 
    
         
             
                    return "" if parts.length == 0
         
     | 
| 
       45 
45 
     | 
    
         
             
                    # Determine if it started with a slash
         
     | 
| 
       46 
46 
     | 
    
         
             
                    absolute = parts[0].length == 0 || parts[0].length > 0 && parts[0] =~ /^#{regexp_path_separator}/
         
     | 
| 
       47 
47 
     | 
    
         
             
                    # Remove leading and trailing slashes from each part so that the join will work (and the slash at the end will go away)
         
     | 
| 
       48 
     | 
    
         
            -
                    parts = parts.map { |part| part.gsub( 
     | 
| 
      
 48 
     | 
    
         
            +
                    parts = parts.map { |part| part.gsub(/^#{regexp_path_separator}+|#{regexp_path_separator}+$/, '') }
         
     | 
| 
       49 
49 
     | 
    
         
             
                    # Don't join empty bits
         
     | 
| 
       50 
     | 
    
         
            -
                    result = parts.select { |part| part !=  
     | 
| 
      
 50 
     | 
    
         
            +
                    result = parts.select { |part| part != '' }.join('/')
         
     | 
| 
       51 
51 
     | 
    
         
             
                    # Put the / back on
         
     | 
| 
       52 
52 
     | 
    
         
             
                    absolute ? "/#{result}" : result
         
     | 
| 
       53 
53 
     | 
    
         
             
                  end
         
     | 
| 
         @@ -60,36 +60,67 @@ class Chef 
     | 
|
| 
       60 
60 
     | 
    
         
             
                    Chef::ChefFS::windows? ? '[\/\\\\]' : '/'
         
     | 
| 
       61 
61 
     | 
    
         
             
                  end
         
     | 
| 
       62 
62 
     | 
    
         | 
| 
      
 63 
     | 
    
         
            +
                  # Given a server path, determines if it is absolute.
         
     | 
| 
      
 64 
     | 
    
         
            +
                  def self.is_absolute?(path)
         
     | 
| 
      
 65 
     | 
    
         
            +
                    !!(path =~ /^#{regexp_path_separator}/)
         
     | 
| 
      
 66 
     | 
    
         
            +
                  end
         
     | 
| 
       63 
67 
     | 
    
         
             
                  # Given a path which may only be partly real (i.e. /x/y/z when only /x exists,
         
     | 
| 
       64 
68 
     | 
    
         
             
                  # or /x/y/*/blah when /x/y/z/blah exists), call File.realpath on the biggest
         
     | 
| 
       65 
     | 
    
         
            -
                  # part that actually exists.
         
     | 
| 
      
 69 
     | 
    
         
            +
                  # part that actually exists.  The paths operated on here are not Chef-FS paths.
         
     | 
| 
      
 70 
     | 
    
         
            +
                  # These are OS paths that may contain symlinks but may not also fully exist.
         
     | 
| 
       66 
71 
     | 
    
         
             
                  #
         
     | 
| 
       67 
72 
     | 
    
         
             
                  # If /x is a symlink to /blarghle, and has no subdirectories, then:
         
     | 
| 
       68 
73 
     | 
    
         
             
                  # PathUtils.realest_path('/x/y/z') == '/blarghle/y/z'
         
     | 
| 
       69 
74 
     | 
    
         
             
                  # PathUtils.realest_path('/x/*/z') == '/blarghle/*/z'
         
     | 
| 
       70 
75 
     | 
    
         
             
                  # PathUtils.realest_path('/*/y/z') == '/*/y/z'
         
     | 
| 
       71 
     | 
    
         
            -
                   
     | 
| 
       72 
     | 
    
         
            -
             
     | 
| 
       73 
     | 
    
         
            -
             
     | 
| 
       74 
     | 
    
         
            -
             
     | 
| 
       75 
     | 
    
         
            -
                     
     | 
| 
       76 
     | 
    
         
            -
             
     | 
| 
       77 
     | 
    
         
            -
             
     | 
| 
       78 
     | 
    
         
            -
             
     | 
| 
       79 
     | 
    
         
            -
             
     | 
| 
       80 
     | 
    
         
            -
             
     | 
| 
      
 76 
     | 
    
         
            +
                  #
         
     | 
| 
      
 77 
     | 
    
         
            +
                  # TODO: Move this to wherever util/path_helper is these days.
         
     | 
| 
      
 78 
     | 
    
         
            +
                  def self.realest_path(path, cwd = Dir.pwd)
         
     | 
| 
      
 79 
     | 
    
         
            +
                    path = File.expand_path(path, cwd)
         
     | 
| 
      
 80 
     | 
    
         
            +
                    parent_path = File.dirname(path)
         
     | 
| 
      
 81 
     | 
    
         
            +
                    suffix = []
         
     | 
| 
      
 82 
     | 
    
         
            +
             
     | 
| 
      
 83 
     | 
    
         
            +
                    # File.dirname happens to return the path as its own dirname if you're
         
     | 
| 
      
 84 
     | 
    
         
            +
                    # at the root (such as at \\foo\bar, C:\ or /)
         
     | 
| 
      
 85 
     | 
    
         
            +
                    until parent_path == path do
         
     | 
| 
      
 86 
     | 
    
         
            +
                      # This can occur if a path such as "C:" is given.  Ruby gives the parent as "C:."
         
     | 
| 
      
 87 
     | 
    
         
            +
                      # for reasons only it knows.
         
     | 
| 
      
 88 
     | 
    
         
            +
                      raise ArgumentError "Invalid path segment #{path}" if parent_path.length > path.length
         
     | 
| 
      
 89 
     | 
    
         
            +
                      begin
         
     | 
| 
      
 90 
     | 
    
         
            +
                        path = File.realpath(path)
         
     | 
| 
      
 91 
     | 
    
         
            +
                        break
         
     | 
| 
      
 92 
     | 
    
         
            +
                      rescue Errno::ENOENT
         
     | 
| 
      
 93 
     | 
    
         
            +
                        suffix << File.basename(path)
         
     | 
| 
      
 94 
     | 
    
         
            +
                        path = parent_path
         
     | 
| 
      
 95 
     | 
    
         
            +
                        parent_path = File.dirname(path)
         
     | 
| 
       81 
96 
     | 
    
         
             
                      end
         
     | 
| 
       82 
97 
     | 
    
         
             
                    end
         
     | 
| 
      
 98 
     | 
    
         
            +
                    File.join(path, *suffix.reverse)
         
     | 
| 
       83 
99 
     | 
    
         
             
                  end
         
     | 
| 
       84 
100 
     | 
    
         | 
| 
       85 
     | 
    
         
            -
                   
     | 
| 
       86 
     | 
    
         
            -
             
     | 
| 
       87 
     | 
    
         
            -
             
     | 
| 
      
 101 
     | 
    
         
            +
                  # Compares two path fragments according to the case-sentitivity of the host platform.
         
     | 
| 
      
 102 
     | 
    
         
            +
                  def self.os_path_eq?(left, right)
         
     | 
| 
      
 103 
     | 
    
         
            +
                    Chef::ChefFS::windows? ? left.casecmp(right) == 0 : left == right
         
     | 
| 
       88 
104 
     | 
    
         
             
                  end
         
     | 
| 
       89 
105 
     | 
    
         | 
| 
       90 
     | 
    
         
            -
                   
     | 
| 
       91 
     | 
    
         
            -
             
     | 
| 
      
 106 
     | 
    
         
            +
                  # Given two general OS-dependent file paths, determines the relative path of the
         
     | 
| 
      
 107 
     | 
    
         
            +
                  # child with respect to the ancestor.  Both child and ancestor must exist and be
         
     | 
| 
      
 108 
     | 
    
         
            +
                  # fully resolved - this is strictly a lexical comparison.  No trailing slashes
         
     | 
| 
      
 109 
     | 
    
         
            +
                  # and other shenanigans are allowed.
         
     | 
| 
      
 110 
     | 
    
         
            +
                  #
         
     | 
| 
      
 111 
     | 
    
         
            +
                  # TODO: Move this to util/path_helper.
         
     | 
| 
      
 112 
     | 
    
         
            +
                  def self.descendant_path(path, ancestor)
         
     | 
| 
      
 113 
     | 
    
         
            +
                    candidate_fragment = path[0, ancestor.length]
         
     | 
| 
      
 114 
     | 
    
         
            +
                    return nil unless PathUtils.os_path_eq?(candidate_fragment, ancestor)
         
     | 
| 
      
 115 
     | 
    
         
            +
                    if ancestor.length == path.length
         
     | 
| 
      
 116 
     | 
    
         
            +
                      ''
         
     | 
| 
      
 117 
     | 
    
         
            +
                    elsif path[ancestor.length,1] =~ /#{PathUtils.regexp_path_separator}/
         
     | 
| 
      
 118 
     | 
    
         
            +
                      path[ancestor.length+1..-1]
         
     | 
| 
      
 119 
     | 
    
         
            +
                    else
         
     | 
| 
      
 120 
     | 
    
         
            +
                      nil
         
     | 
| 
      
 121 
     | 
    
         
            +
                    end
         
     | 
| 
       92 
122 
     | 
    
         
             
                  end
         
     | 
| 
      
 123 
     | 
    
         
            +
             
     | 
| 
       93 
124 
     | 
    
         
             
                end
         
     | 
| 
       94 
125 
     | 
    
         
             
              end
         
     | 
| 
       95 
126 
     | 
    
         
             
            end
         
     |