chef 15.6.10 → 15.7.30
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/Gemfile +1 -1
 - data/README.md +2 -2
 - data/lib/chef/chef_fs/file_system/chef_server/cookbooks_dir.rb +22 -5
 - data/lib/chef/cookbook/cookbook_version_loader.rb +12 -6
 - data/lib/chef/cookbook_loader.rb +55 -2
 - data/lib/chef/cookbook_uploader.rb +2 -0
 - data/lib/chef/cookbook_version.rb +17 -0
 - data/lib/chef/dist.rb +3 -3
 - data/lib/chef/event_loggers/windows_eventlog.rb +1 -1
 - data/lib/chef/knife/bootstrap.rb +5 -0
 - data/lib/chef/knife/bootstrap/templates/chef-full.erb +11 -11
 - data/lib/chef/knife/cookbook_upload.rb +75 -45
 - data/lib/chef/knife/core/bootstrap_context.rb +5 -5
 - data/lib/chef/knife/core/windows_bootstrap_context.rb +1 -1
 - data/lib/chef/knife/supermarket_install.rb +1 -1
 - data/lib/chef/log/winevt.rb +1 -1
 - data/lib/chef/mixin/openssl_helper.rb +21 -0
 - data/lib/chef/monkey_patches/net_http.rb +0 -38
 - data/lib/chef/provider/cron.rb +54 -9
 - data/lib/chef/provider/cron/aix.rb +9 -2
 - data/lib/chef/provider/launchd.rb +1 -1
 - data/lib/chef/provider/user/aix.rb +1 -1
 - data/lib/chef/provider/user/mac.rb +17 -22
 - data/lib/chef/provider/windows_task.rb +2 -2
 - data/lib/chef/resource/archive_file.rb +5 -2
 - data/lib/chef/resource/cron.rb +29 -0
 - data/lib/chef/resource/cron_d.rb +29 -0
 - data/lib/chef/resource/openssl_x509_certificate.rb +32 -21
 - data/lib/chef/resource/sudo.rb +13 -4
 - data/lib/chef/version.rb +2 -2
 - data/lib/chef/version_string.rb +3 -126
 - data/spec/data/cookbooks/apache2/metadata.json +33 -0
 - data/spec/data/cookbooks/java/metadata.json +33 -0
 - data/spec/functional/event_loggers/windows_eventlog_spec.rb +5 -5
 - data/spec/integration/knife/chef_fs_data_store_spec.rb +7 -2
 - data/spec/integration/knife/cookbook_upload_spec.rb +10 -0
 - data/spec/integration/knife/deps_spec.rb +11 -0
 - data/spec/integration/knife/upload_spec.rb +115 -14
 - data/spec/unit/cookbook/cookbook_version_loader_spec.rb +7 -4
 - data/spec/unit/knife/cookbook_upload_spec.rb +79 -18
 - data/spec/unit/mixin/openssl_helper_spec.rb +42 -0
 - data/spec/unit/provider/cron_spec.rb +127 -0
 - data/spec/unit/provider/user/aix_spec.rb +2 -2
 - metadata +8 -6
 
| 
         @@ -158,11 +158,11 @@ class Chef 
     | 
|
| 
       158 
158 
     | 
    
         
             
                      end
         
     | 
| 
       159 
159 
     | 
    
         | 
| 
       160 
160 
     | 
    
         
             
                      if encrypted_data_bag_secret
         
     | 
| 
       161 
     | 
    
         
            -
                        client_rb << %Q{encrypted_data_bag_secret " 
     | 
| 
      
 161 
     | 
    
         
            +
                        client_rb << %Q{encrypted_data_bag_secret "/etc/chef/encrypted_data_bag_secret"\n}
         
     | 
| 
       162 
162 
     | 
    
         
             
                      end
         
     | 
| 
       163 
163 
     | 
    
         | 
| 
       164 
164 
     | 
    
         
             
                      unless trusted_certs.empty?
         
     | 
| 
       165 
     | 
    
         
            -
                        client_rb << %Q{trusted_certs_dir " 
     | 
| 
      
 165 
     | 
    
         
            +
                        client_rb << %Q{trusted_certs_dir "/etc/chef/trusted_certs"\n}
         
     | 
| 
       166 
166 
     | 
    
         
             
                      end
         
     | 
| 
       167 
167 
     | 
    
         | 
| 
       168 
168 
     | 
    
         
             
                      if Chef::Config[:fips]
         
     | 
| 
         @@ -175,7 +175,7 @@ class Chef 
     | 
|
| 
       175 
175 
     | 
    
         
             
                    def start_chef
         
     | 
| 
       176 
176 
     | 
    
         
             
                      # If the user doesn't have a client path configure, let bash use the PATH for what it was designed for
         
     | 
| 
       177 
177 
     | 
    
         
             
                      client_path = @chef_config[:chef_client_path] || "#{Chef::Dist::CLIENT}"
         
     | 
| 
       178 
     | 
    
         
            -
                      s = "#{client_path} -j  
     | 
| 
      
 178 
     | 
    
         
            +
                      s = "#{client_path} -j /etc/chef/first-boot.json"
         
     | 
| 
       179 
179 
     | 
    
         
             
                      if @config[:verbosity] && @config[:verbosity] >= 3
         
     | 
| 
       180 
180 
     | 
    
         
             
                        s << " -l trace"
         
     | 
| 
       181 
181 
     | 
    
         
             
                      elsif @config[:verbosity] && @config[:verbosity] >= 2
         
     | 
| 
         @@ -226,7 +226,7 @@ class Chef 
     | 
|
| 
       226 
226 
     | 
    
         
             
                      content = ""
         
     | 
| 
       227 
227 
     | 
    
         
             
                      if @chef_config[:trusted_certs_dir]
         
     | 
| 
       228 
228 
     | 
    
         
             
                        Dir.glob(File.join(Chef::Util::PathHelper.escape_glob_dir(@chef_config[:trusted_certs_dir]), "*.{crt,pem}")).each do |cert|
         
     | 
| 
       229 
     | 
    
         
            -
                          content << "cat >  
     | 
| 
      
 229 
     | 
    
         
            +
                          content << "cat > /etc/chef/trusted_certs/#{File.basename(cert)} <<'EOP'\n" +
         
     | 
| 
       230 
230 
     | 
    
         
             
                            IO.read(File.expand_path(cert)) + "\nEOP\n"
         
     | 
| 
       231 
231 
     | 
    
         
             
                        end
         
     | 
| 
       232 
232 
     | 
    
         
             
                      end
         
     | 
| 
         @@ -240,7 +240,7 @@ class Chef 
     | 
|
| 
       240 
240 
     | 
    
         
             
                        root.find do |f|
         
     | 
| 
       241 
241 
     | 
    
         
             
                          relative = f.relative_path_from(root)
         
     | 
| 
       242 
242 
     | 
    
         
             
                          if f != root
         
     | 
| 
       243 
     | 
    
         
            -
                            file_on_node = " 
     | 
| 
      
 243 
     | 
    
         
            +
                            file_on_node = "/etc/chef/client.d/#{relative}"
         
     | 
| 
       244 
244 
     | 
    
         
             
                            if f.directory?
         
     | 
| 
       245 
245 
     | 
    
         
             
                              content << "mkdir #{file_on_node}\n"
         
     | 
| 
       246 
246 
     | 
    
         
             
                            else
         
     | 
| 
         @@ -158,7 +158,7 @@ class Chef 
     | 
|
| 
       158 
158 
     | 
    
         | 
| 
       159 
159 
     | 
    
         
             
                    def start_chef
         
     | 
| 
       160 
160 
     | 
    
         
             
                      bootstrap_environment_option = bootstrap_environment.nil? ? "" : " -E #{bootstrap_environment}"
         
     | 
| 
       161 
     | 
    
         
            -
                      start_chef = "SET \"PATH=%SystemRoot%\\system32;%SystemRoot%;%SystemRoot%\\System32\\Wbem;%SYSTEMROOT%\\System32\\WindowsPowerShell\\v1.0\\;C:\\ruby\\bin;C:\\opscode\\chef\\bin;C:\\opscode\\chef\\embedded\\bin 
     | 
| 
      
 161 
     | 
    
         
            +
                      start_chef = "SET \"PATH=%SystemRoot%\\system32;%SystemRoot%;%SystemRoot%\\System32\\Wbem;%SYSTEMROOT%\\System32\\WindowsPowerShell\\v1.0\\;C:\\ruby\\bin;C:\\opscode\\chef\\bin;C:\\opscode\\chef\\embedded\\bin\;%PATH%\"\n"
         
     | 
| 
       162 
162 
     | 
    
         
             
                      start_chef << "chef-client -c c:/chef/client.rb -j c:/chef/first-boot.json#{bootstrap_environment_option}\n"
         
     | 
| 
       163 
163 
     | 
    
         
             
                    end
         
     | 
| 
       164 
164 
     | 
    
         | 
| 
         @@ -137,7 +137,7 @@ class Chef 
     | 
|
| 
       137 
137 
     | 
    
         
             
                  end
         
     | 
| 
       138 
138 
     | 
    
         | 
| 
       139 
139 
     | 
    
         
             
                  def download_cookbook_to(download_path)
         
     | 
| 
       140 
     | 
    
         
            -
                    downloader = Chef::Knife:: 
     | 
| 
      
 140 
     | 
    
         
            +
                    downloader = Chef::Knife::SupermarketDownload.new
         
     | 
| 
       141 
141 
     | 
    
         
             
                    downloader.config[:file] = download_path
         
     | 
| 
       142 
142 
     | 
    
         
             
                    downloader.config[:supermarket_site] = config[:supermarket_site]
         
     | 
| 
       143 
143 
     | 
    
         
             
                    downloader.name_args = name_args
         
     | 
    
        data/lib/chef/log/winevt.rb
    CHANGED
    
    
| 
         @@ -401,6 +401,27 @@ class Chef 
     | 
|
| 
       401 
401 
     | 
    
         
             
                    crl.sign(ca_private_key, ::OpenSSL::Digest::SHA256.new)
         
     | 
| 
       402 
402 
     | 
    
         
             
                    crl
         
     | 
| 
       403 
403 
     | 
    
         
             
                  end
         
     | 
| 
      
 404 
     | 
    
         
            +
             
     | 
| 
      
 405 
     | 
    
         
            +
                  # Return true if a certificate need to be renewed (or doesn't exist) according to the number
         
     | 
| 
      
 406 
     | 
    
         
            +
                  # of days before expiration given
         
     | 
| 
      
 407 
     | 
    
         
            +
                  # @param [string] cert_file path of the cert file or cert content
         
     | 
| 
      
 408 
     | 
    
         
            +
                  # @param [integer] renew_before_expiry number of days before expiration
         
     | 
| 
      
 409 
     | 
    
         
            +
                  # @return [true, false]
         
     | 
| 
      
 410 
     | 
    
         
            +
                  def cert_need_renewall?(cert_file, renew_before_expiry)
         
     | 
| 
      
 411 
     | 
    
         
            +
                    resp = true
         
     | 
| 
      
 412 
     | 
    
         
            +
                    cert_content = ::File.exist?(cert_file) ? File.read(cert_file) : cert_file
         
     | 
| 
      
 413 
     | 
    
         
            +
                    begin
         
     | 
| 
      
 414 
     | 
    
         
            +
                      cert = OpenSSL::X509::Certificate.new cert_content
         
     | 
| 
      
 415 
     | 
    
         
            +
                    rescue ::OpenSSL::X509::CertificateError
         
     | 
| 
      
 416 
     | 
    
         
            +
                      return resp
         
     | 
| 
      
 417 
     | 
    
         
            +
                    end
         
     | 
| 
      
 418 
     | 
    
         
            +
             
     | 
| 
      
 419 
     | 
    
         
            +
                    unless cert.not_after <= Time.now + 3600 * 24 * renew_before_expiry
         
     | 
| 
      
 420 
     | 
    
         
            +
                      resp = false
         
     | 
| 
      
 421 
     | 
    
         
            +
                    end
         
     | 
| 
      
 422 
     | 
    
         
            +
             
     | 
| 
      
 423 
     | 
    
         
            +
                    resp
         
     | 
| 
      
 424 
     | 
    
         
            +
                  end
         
     | 
| 
       404 
425 
     | 
    
         
             
                end
         
     | 
| 
       405 
426 
     | 
    
         
             
              end
         
     | 
| 
       406 
427 
     | 
    
         
             
            end
         
     | 
| 
         @@ -24,41 +24,3 @@ module Net 
     | 
|
| 
       24 
24 
     | 
    
         
             
                include ChefNetHTTPExceptionExtensions
         
     | 
| 
       25 
25 
     | 
    
         
             
              end
         
     | 
| 
       26 
26 
     | 
    
         
             
            end
         
     | 
| 
       27 
     | 
    
         
            -
             
     | 
| 
       28 
     | 
    
         
            -
            if Net::HTTP.instance_methods.map(&:to_s).include?("proxy_uri")
         
     | 
| 
       29 
     | 
    
         
            -
              begin
         
     | 
| 
       30 
     | 
    
         
            -
                # Ruby 2.0 changes the way proxy support is implemented in Net::HTTP.
         
     | 
| 
       31 
     | 
    
         
            -
                # The implementation does not work correctly with IPv6 literals because it
         
     | 
| 
       32 
     | 
    
         
            -
                # concatenates the address into a URI without adding square brackets for
         
     | 
| 
       33 
     | 
    
         
            -
                # IPv6 addresses.
         
     | 
| 
       34 
     | 
    
         
            -
                #
         
     | 
| 
       35 
     | 
    
         
            -
                # If the bug is present, a call to Net::HTTP#proxy_uri when the host is an
         
     | 
| 
       36 
     | 
    
         
            -
                # IPv6 address will fail by creating an invalid URI, like so:
         
     | 
| 
       37 
     | 
    
         
            -
                #
         
     | 
| 
       38 
     | 
    
         
            -
                #    ruby -r'net/http' -e 'Net::HTTP.new("::1", 80).proxy_uri'
         
     | 
| 
       39 
     | 
    
         
            -
                #    /Users/ddeleo/.rbenv/versions/2.0.0-p247/lib/ruby/2.0.0/uri/generic.rb:214:in `initialize': the scheme http does not accept registry part: ::1:80 (or bad hostname?) (URI::InvalidURIError)
         
     | 
| 
       40 
     | 
    
         
            -
                #      from /Users/ddeleo/.rbenv/versions/2.0.0-p247/lib/ruby/2.0.0/uri/http.rb:84:in `initialize'
         
     | 
| 
       41 
     | 
    
         
            -
                #      from /Users/ddeleo/.rbenv/versions/2.0.0-p247/lib/ruby/2.0.0/uri/common.rb:214:in `new'
         
     | 
| 
       42 
     | 
    
         
            -
                #      from /Users/ddeleo/.rbenv/versions/2.0.0-p247/lib/ruby/2.0.0/uri/common.rb:214:in `parse'
         
     | 
| 
       43 
     | 
    
         
            -
                #      from /Users/ddeleo/.rbenv/versions/2.0.0-p247/lib/ruby/2.0.0/uri/common.rb:747:in `parse'
         
     | 
| 
       44 
     | 
    
         
            -
                #      from /Users/ddeleo/.rbenv/versions/2.0.0-p247/lib/ruby/2.0.0/uri/common.rb:994:in `URI'
         
     | 
| 
       45 
     | 
    
         
            -
                #      from /Users/ddeleo/.rbenv/versions/2.0.0-p247/lib/ruby/2.0.0/net/http.rb:1027:in `proxy_uri'
         
     | 
| 
       46 
     | 
    
         
            -
                #      from -e:1:in `<main>'
         
     | 
| 
       47 
     | 
    
         
            -
                #
         
     | 
| 
       48 
     | 
    
         
            -
                # https://bugs.ruby-lang.org/issues/9129
         
     | 
| 
       49 
     | 
    
         
            -
                #
         
     | 
| 
       50 
     | 
    
         
            -
                # NOTE: This should be fixed in Ruby 2.2.0, and backported to Ruby 2.0 and
         
     | 
| 
       51 
     | 
    
         
            -
                # 2.1 (not yet released so the version/patchlevel required isn't known
         
     | 
| 
       52 
     | 
    
         
            -
                # yet).
         
     | 
| 
       53 
     | 
    
         
            -
                Net::HTTP.new("::1", 80).proxy_uri
         
     | 
| 
       54 
     | 
    
         
            -
              rescue URI::InvalidURIError
         
     | 
| 
       55 
     | 
    
         
            -
                class Net::HTTP
         
     | 
| 
       56 
     | 
    
         
            -
             
     | 
| 
       57 
     | 
    
         
            -
                  def proxy_uri # :nodoc:
         
     | 
| 
       58 
     | 
    
         
            -
                    ipv6_safe_addr = address.to_s.include?(":") ? "[#{address}]" : address
         
     | 
| 
       59 
     | 
    
         
            -
                    @proxy_uri ||= URI("http://#{ipv6_safe_addr}:#{port}").find_proxy
         
     | 
| 
       60 
     | 
    
         
            -
                  end
         
     | 
| 
       61 
     | 
    
         
            -
             
     | 
| 
       62 
     | 
    
         
            -
                end
         
     | 
| 
       63 
     | 
    
         
            -
              end
         
     | 
| 
       64 
     | 
    
         
            -
            end
         
     | 
    
        data/lib/chef/provider/cron.rb
    CHANGED
    
    | 
         @@ -216,11 +216,13 @@ class Chef 
     | 
|
| 
       216 
216 
     | 
    
         
             
                    raise Chef::Exceptions::Cron, "Error updating state of #{new_resource.name}, error: #{e}"
         
     | 
| 
       217 
217 
     | 
    
         
             
                  end
         
     | 
| 
       218 
218 
     | 
    
         | 
| 
       219 
     | 
    
         
            -
                   
     | 
| 
       220 
     | 
    
         
            -
             
     | 
| 
       221 
     | 
    
         
            -
             
     | 
| 
      
 219 
     | 
    
         
            +
                  #
         
     | 
| 
      
 220 
     | 
    
         
            +
                  # @return [String] The string of Env Variables containing line breaks.
         
     | 
| 
      
 221 
     | 
    
         
            +
                  #
         
     | 
| 
      
 222 
     | 
    
         
            +
                  def env_var_str
         
     | 
| 
      
 223 
     | 
    
         
            +
                    str = []
         
     | 
| 
       222 
224 
     | 
    
         
             
                    %i{mailto path shell home}.each do |v|
         
     | 
| 
       223 
     | 
    
         
            -
                       
     | 
| 
      
 225 
     | 
    
         
            +
                      str << "#{v.to_s.upcase}=\"#{new_resource.send(v)}\"" if new_resource.send(v)
         
     | 
| 
       224 
226 
     | 
    
         
             
                    end
         
     | 
| 
       225 
227 
     | 
    
         
             
                    new_resource.environment.each do |name, value|
         
     | 
| 
       226 
228 
     | 
    
         
             
                      if ENVIRONMENT_PROPERTIES.include?(name)
         
     | 
| 
         @@ -228,20 +230,63 @@ class Chef 
     | 
|
| 
       228 
230 
     | 
    
         
             
                          logger.warn("#{new_resource.name}: the environment property contains the '#{name}' variable, which should be set separately as a property.")
         
     | 
| 
       229 
231 
     | 
    
         
             
                          new_resource.send(name.downcase.to_sym, value.gsub(/^"|"$/, ""))
         
     | 
| 
       230 
232 
     | 
    
         
             
                          new_resource.environment.delete(name)
         
     | 
| 
       231 
     | 
    
         
            -
                           
     | 
| 
      
 233 
     | 
    
         
            +
                          str << "#{name.to_s.upcase}=\"#{value}\""
         
     | 
| 
       232 
234 
     | 
    
         
             
                        else
         
     | 
| 
       233 
235 
     | 
    
         
             
                          raise Chef::Exceptions::Cron, "#{new_resource.name}: the '#{name}' property is set and environment property also contains the '#{name}' variable. Remove the variable from the environment property."
         
     | 
| 
       234 
236 
     | 
    
         
             
                        end
         
     | 
| 
       235 
237 
     | 
    
         
             
                      else
         
     | 
| 
       236 
     | 
    
         
            -
                         
     | 
| 
      
 238 
     | 
    
         
            +
                        str << "#{name}=#{value}"
         
     | 
| 
       237 
239 
     | 
    
         
             
                      end
         
     | 
| 
       238 
240 
     | 
    
         
             
                    end
         
     | 
| 
      
 241 
     | 
    
         
            +
                    str.join("\n")
         
     | 
| 
      
 242 
     | 
    
         
            +
                  end
         
     | 
| 
      
 243 
     | 
    
         
            +
             
     | 
| 
      
 244 
     | 
    
         
            +
                  #
         
     | 
| 
      
 245 
     | 
    
         
            +
                  # @return [String] The Cron time string consisting five fields that Cron converts into a time interval.
         
     | 
| 
      
 246 
     | 
    
         
            +
                  #
         
     | 
| 
      
 247 
     | 
    
         
            +
                  def duration_str
         
     | 
| 
       239 
248 
     | 
    
         
             
                    if new_resource.time
         
     | 
| 
       240 
     | 
    
         
            -
                       
     | 
| 
      
 249 
     | 
    
         
            +
                      "@#{new_resource.time}"
         
     | 
| 
       241 
250 
     | 
    
         
             
                    else
         
     | 
| 
       242 
     | 
    
         
            -
                       
     | 
| 
      
 251 
     | 
    
         
            +
                      "#{new_resource.minute} #{new_resource.hour} #{new_resource.day} #{new_resource.month} #{new_resource.weekday}"
         
     | 
| 
       243 
252 
     | 
    
         
             
                    end
         
     | 
| 
       244 
     | 
    
         
            -
             
     | 
| 
      
 253 
     | 
    
         
            +
                  end
         
     | 
| 
      
 254 
     | 
    
         
            +
             
     | 
| 
      
 255 
     | 
    
         
            +
                  #
         
     | 
| 
      
 256 
     | 
    
         
            +
                  # @return [String] The timeout command string formed as per time_out property.
         
     | 
| 
      
 257 
     | 
    
         
            +
                  #
         
     | 
| 
      
 258 
     | 
    
         
            +
                  def time_out_str
         
     | 
| 
      
 259 
     | 
    
         
            +
                    return "" if new_resource.time_out.empty?
         
     | 
| 
      
 260 
     | 
    
         
            +
             
     | 
| 
      
 261 
     | 
    
         
            +
                    str = " timeout"
         
     | 
| 
      
 262 
     | 
    
         
            +
                    str << " --preserve-status" if new_resource.time_out["preserve-status"].to_s.downcase == "true"
         
     | 
| 
      
 263 
     | 
    
         
            +
                    str << " --foreground" if new_resource.time_out["foreground"].to_s.downcase == "true"
         
     | 
| 
      
 264 
     | 
    
         
            +
                    str << " --kill-after #{new_resource.time_out["kill-after"]}" if new_resource.time_out["kill-after"]
         
     | 
| 
      
 265 
     | 
    
         
            +
                    str << " --signal #{new_resource.time_out["signal"]}" if new_resource.time_out["signal"]
         
     | 
| 
      
 266 
     | 
    
         
            +
                    str << " #{new_resource.time_out["duration"]};"
         
     | 
| 
      
 267 
     | 
    
         
            +
                    str
         
     | 
| 
      
 268 
     | 
    
         
            +
                  end
         
     | 
| 
      
 269 
     | 
    
         
            +
             
     | 
| 
      
 270 
     | 
    
         
            +
                  #
         
     | 
| 
      
 271 
     | 
    
         
            +
                  # @return [String] The command to be executed. The new line at the end has been added purposefully.
         
     | 
| 
      
 272 
     | 
    
         
            +
                  #
         
     | 
| 
      
 273 
     | 
    
         
            +
                  def cmd_str
         
     | 
| 
      
 274 
     | 
    
         
            +
                    " #{new_resource.command}\n"
         
     | 
| 
      
 275 
     | 
    
         
            +
                  end
         
     | 
| 
      
 276 
     | 
    
         
            +
             
     | 
| 
      
 277 
     | 
    
         
            +
                  # Concatenates various information and formulates a complete string that
         
     | 
| 
      
 278 
     | 
    
         
            +
                  # could be written in the crontab
         
     | 
| 
      
 279 
     | 
    
         
            +
                  #
         
     | 
| 
      
 280 
     | 
    
         
            +
                  # @return [String] A crontab string formed as per the user inputs.
         
     | 
| 
      
 281 
     | 
    
         
            +
                  #
         
     | 
| 
      
 282 
     | 
    
         
            +
                  def get_crontab_entry
         
     | 
| 
      
 283 
     | 
    
         
            +
                    # Initialize
         
     | 
| 
      
 284 
     | 
    
         
            +
                    newcron = []
         
     | 
| 
      
 285 
     | 
    
         
            +
                    newcron << "# Chef Name: #{new_resource.name}"
         
     | 
| 
      
 286 
     | 
    
         
            +
                    newcron << env_var_str unless env_var_str.empty?
         
     | 
| 
      
 287 
     | 
    
         
            +
                    newcron << duration_str + time_out_str + cmd_str
         
     | 
| 
      
 288 
     | 
    
         
            +
             
     | 
| 
      
 289 
     | 
    
         
            +
                    newcron.join("\n")
         
     | 
| 
       245 
290 
     | 
    
         
             
                  end
         
     | 
| 
       246 
291 
     | 
    
         | 
| 
       247 
292 
     | 
    
         
             
                  def weekday_in_crontab
         
     | 
| 
         @@ -33,8 +33,11 @@ class Chef 
     | 
|
| 
       33 
33 
     | 
    
         
             
                        raise Chef::Exceptions::Cron, "Aix cron entry does not support environment variables. Please set them in script and use script in cron."
         
     | 
| 
       34 
34 
     | 
    
         
             
                      end
         
     | 
| 
       35 
35 
     | 
    
         | 
| 
       36 
     | 
    
         
            -
                       
     | 
| 
       37 
     | 
    
         
            -
             
     | 
| 
      
 36 
     | 
    
         
            +
                      if time_out_set?
         
     | 
| 
      
 37 
     | 
    
         
            +
                        raise Chef::Exceptions::Cron, "Aix cron entry does not support timeout."
         
     | 
| 
      
 38 
     | 
    
         
            +
                      end
         
     | 
| 
      
 39 
     | 
    
         
            +
             
     | 
| 
      
 40 
     | 
    
         
            +
                      newcron = "# Chef Name: #{new_resource.name}\n"
         
     | 
| 
       38 
41 
     | 
    
         
             
                      newcron << "#{@new_resource.minute} #{@new_resource.hour} #{@new_resource.day} #{@new_resource.month} #{@new_resource.weekday}"
         
     | 
| 
       39 
42 
     | 
    
         | 
| 
       40 
43 
     | 
    
         
             
                      newcron << " #{@new_resource.command}\n"
         
     | 
| 
         @@ -44,6 +47,10 @@ class Chef 
     | 
|
| 
       44 
47 
     | 
    
         
             
                    def env_vars_are_set?
         
     | 
| 
       45 
48 
     | 
    
         
             
                      @new_resource.environment.length > 0 || !@new_resource.mailto.nil? || !@new_resource.path.nil? || !@new_resource.shell.nil? || !@new_resource.home.nil?
         
     | 
| 
       46 
49 
     | 
    
         
             
                    end
         
     | 
| 
      
 50 
     | 
    
         
            +
             
     | 
| 
      
 51 
     | 
    
         
            +
                    def time_out_set?
         
     | 
| 
      
 52 
     | 
    
         
            +
                      !@new_resource.time_out.empty?
         
     | 
| 
      
 53 
     | 
    
         
            +
                    end
         
     | 
| 
       47 
54 
     | 
    
         
             
                  end
         
     | 
| 
       48 
55 
     | 
    
         
             
                end
         
     | 
| 
       49 
56 
     | 
    
         
             
              end
         
     | 
| 
         @@ -194,7 +194,7 @@ class Chef 
     | 
|
| 
       194 
194 
     | 
    
         
             
                      "environment_variables" => "EnvironmentVariables",
         
     | 
| 
       195 
195 
     | 
    
         
             
                      "exit_timeout" => "ExitTimeout",
         
     | 
| 
       196 
196 
     | 
    
         
             
                      "ld_group" => "GroupName",
         
     | 
| 
       197 
     | 
    
         
            -
                      "hard_resource_limits" => " 
     | 
| 
      
 197 
     | 
    
         
            +
                      "hard_resource_limits" => "HardResourceLimits",
         
     | 
| 
       198 
198 
     | 
    
         
             
                      "inetd_compatibility" => "inetdCompatibility",
         
     | 
| 
       199 
199 
     | 
    
         
             
                      "init_groups" => "InitGroups",
         
     | 
| 
       200 
200 
     | 
    
         
             
                      "keep_alive" => "KeepAlive",
         
     | 
| 
         @@ -110,7 +110,7 @@ class Chef 
     | 
|
| 
       110 
110 
     | 
    
         
             
                      return unless current_resource.password != new_resource.password && new_resource.password
         
     | 
| 
       111 
111 
     | 
    
         | 
| 
       112 
112 
     | 
    
         
             
                      logger.trace("#{new_resource.username} setting password to #{new_resource.password}")
         
     | 
| 
       113 
     | 
    
         
            -
                      command = "echo '#{new_resource.username}:#{new_resource.password}' | chpasswd -e"
         
     | 
| 
      
 113 
     | 
    
         
            +
                      command = "echo '#{new_resource.username}:#{new_resource.password}' | chpasswd -c -e"
         
     | 
| 
       114 
114 
     | 
    
         
             
                      shell_out!(command)
         
     | 
| 
       115 
115 
     | 
    
         
             
                    end
         
     | 
| 
       116 
116 
     | 
    
         | 
| 
         @@ -1,6 +1,6 @@ 
     | 
|
| 
       1 
1 
     | 
    
         
             
            #
         
     | 
| 
       2 
2 
     | 
    
         
             
            # Author:: Ryan Cragun (<ryan@chef.io>)
         
     | 
| 
       3 
     | 
    
         
            -
            # Copyright:: Copyright (c) 2019, Chef Software Inc.
         
     | 
| 
      
 3 
     | 
    
         
            +
            # Copyright:: Copyright (c) 2019-2019, Chef Software Inc.
         
     | 
| 
       4 
4 
     | 
    
         
             
            # License:: Apache License, Version 2.0
         
     | 
| 
       5 
5 
     | 
    
         
             
            #
         
     | 
| 
       6 
6 
     | 
    
         
             
            # Licensed under the Apache License, Version 2.0 (the "License");
         
     | 
| 
         @@ -92,6 +92,8 @@ class Chef 
     | 
|
| 
       92 
92 
     | 
    
         | 
| 
       93 
93 
     | 
    
         
             
                      @user_plist = Plist.new(::Plist.parse_xml(user_xml))
         
     | 
| 
       94 
94 
     | 
    
         | 
| 
      
 95 
     | 
    
         
            +
                      return unless user_plist[:shadow_hash]
         
     | 
| 
      
 96 
     | 
    
         
            +
             
     | 
| 
       95 
97 
     | 
    
         
             
                      shadow_hash_hex = user_plist[:shadow_hash][0]
         
     | 
| 
       96 
98 
     | 
    
         
             
                      return unless shadow_hash_hex && shadow_hash_hex != ""
         
     | 
| 
       97 
99 
     | 
    
         | 
| 
         @@ -148,14 +150,12 @@ class Chef 
     | 
|
| 
       148 
150 
     | 
    
         
             
                        cmd += ["-adminPassword", new_resource.admin_password]
         
     | 
| 
       149 
151 
     | 
    
         
             
                      end
         
     | 
| 
       150 
152 
     | 
    
         | 
| 
       151 
     | 
    
         
            -
                       
     | 
| 
       152 
     | 
    
         
            -
             
     | 
| 
       153 
     | 
    
         
            -
             
     | 
| 
       154 
     | 
    
         
            -
             
     | 
| 
       155 
     | 
    
         
            -
             
     | 
| 
       156 
     | 
    
         
            -
                         
     | 
| 
       157 
     | 
    
         
            -
                          raise Chef::Exceptions::User, "error when creating user: #{res}"
         
     | 
| 
       158 
     | 
    
         
            -
                        end
         
     | 
| 
      
 153 
     | 
    
         
            +
                      # sysadminctl doesn't exit with a non-zero exit code if it encounters
         
     | 
| 
      
 154 
     | 
    
         
            +
                      # a problem. We'll check stderr and make sure we see that it finished
         
     | 
| 
      
 155 
     | 
    
         
            +
                      # correctly.
         
     | 
| 
      
 156 
     | 
    
         
            +
                      res = run_sysadminctl(cmd)
         
     | 
| 
      
 157 
     | 
    
         
            +
                      unless res.downcase =~ /creating user/
         
     | 
| 
      
 158 
     | 
    
         
            +
                        raise Chef::Exceptions::User, "error when creating user: #{res}"
         
     | 
| 
       159 
159 
     | 
    
         
             
                      end
         
     | 
| 
       160 
160 
     | 
    
         | 
| 
       161 
161 
     | 
    
         
             
                      # Wait for the user to show up in the ds cache
         
     | 
| 
         @@ -289,11 +289,9 @@ class Chef 
     | 
|
| 
       289 
289 
     | 
    
         | 
| 
       290 
290 
     | 
    
         
             
                      # sysadminctl doesn't exit with a non-zero exit code if it encounters
         
     | 
| 
       291 
291 
     | 
    
         
             
                      # a problem. We'll check stderr and make sure we see that it finished
         
     | 
| 
       292 
     | 
    
         
            -
                       
     | 
| 
       293 
     | 
    
         
            -
             
     | 
| 
       294 
     | 
    
         
            -
                         
     | 
| 
       295 
     | 
    
         
            -
                          raise Chef::Exceptions::User, "error deleting user: #{res}"
         
     | 
| 
       296 
     | 
    
         
            -
                        end
         
     | 
| 
      
 292 
     | 
    
         
            +
                      res = run_sysadminctl(cmd)
         
     | 
| 
      
 293 
     | 
    
         
            +
                      unless res.downcase =~ /deleting record|not found/
         
     | 
| 
      
 294 
     | 
    
         
            +
                        raise Chef::Exceptions::User, "error deleting user: #{res}"
         
     | 
| 
       297 
295 
     | 
    
         
             
                      end
         
     | 
| 
       298 
296 
     | 
    
         | 
| 
       299 
297 
     | 
    
         
             
                      reload_user_plist
         
     | 
| 
         @@ -301,18 +299,15 @@ class Chef 
     | 
|
| 
       301 
299 
     | 
    
         
             
                    end
         
     | 
| 
       302 
300 
     | 
    
         | 
| 
       303 
301 
     | 
    
         
             
                    def lock_user
         
     | 
| 
       304 
     | 
    
         
            -
                       
     | 
| 
       305 
     | 
    
         
            -
                        run_dscl("append", "/Users/#{new_resource.username}", "AuthenticationAuthority", ";DisabledUser;")
         
     | 
| 
       306 
     | 
    
         
            -
                      end
         
     | 
| 
      
 302 
     | 
    
         
            +
                      run_dscl("append", "/Users/#{new_resource.username}", "AuthenticationAuthority", ";DisabledUser;")
         
     | 
| 
       307 
303 
     | 
    
         | 
| 
       308 
304 
     | 
    
         
             
                      reload_user_plist
         
     | 
| 
       309 
305 
     | 
    
         
             
                    end
         
     | 
| 
       310 
306 
     | 
    
         | 
| 
       311 
307 
     | 
    
         
             
                    def unlock_user
         
     | 
| 
       312 
308 
     | 
    
         
             
                      auth_string = user_plist[:auth_authority].reject! { |tag| tag == ";DisabledUser;" }.join.strip
         
     | 
| 
       313 
     | 
    
         
            -
             
     | 
| 
       314 
     | 
    
         
            -
             
     | 
| 
       315 
     | 
    
         
            -
                      end
         
     | 
| 
      
 309 
     | 
    
         
            +
             
     | 
| 
      
 310 
     | 
    
         
            +
                      run_dscl("create", "/Users/#{new_resource.username}", "AuthenticationAuthority", auth_string)
         
     | 
| 
       316 
311 
     | 
    
         | 
| 
       317 
312 
     | 
    
         
             
                      reload_user_plist
         
     | 
| 
       318 
313 
     | 
    
         
             
                    end
         
     | 
| 
         @@ -483,7 +478,7 @@ class Chef 
     | 
|
| 
       483 
478 
     | 
    
         
             
                        )
         
     | 
| 
       484 
479 
     | 
    
         
             
                      end
         
     | 
| 
       485 
480 
     | 
    
         | 
| 
       486 
     | 
    
         
            -
                      shadow_hash = user_plist[:shadow_hash][0]
         
     | 
| 
      
 481 
     | 
    
         
            +
                      shadow_hash = user_plist[:shadow_hash] ? user_plist[:shadow_hash][0] : {}
         
     | 
| 
       487 
482 
     | 
    
         
             
                      shadow_hash["SALTED-SHA512-PBKDF2"] = {
         
     | 
| 
       488 
483 
     | 
    
         
             
                        "entropy" => entropy,
         
     | 
| 
       489 
484 
     | 
    
         
             
                        "salt" => salt,
         
     | 
| 
         @@ -533,7 +528,7 @@ class Chef 
     | 
|
| 
       533 
528 
     | 
    
         
             
                      run_dsimport(import_file, "/Local/Default", "M")
         
     | 
| 
       534 
529 
     | 
    
         
             
                      run_dscl("create", "/Users/#{new_resource.username}", "Password", "********")
         
     | 
| 
       535 
530 
     | 
    
         
             
                    ensure
         
     | 
| 
       536 
     | 
    
         
            -
                      ::File.delete(import_file) if  
     | 
| 
      
 531 
     | 
    
         
            +
                      ::File.delete(import_file) if import_file && ::File.exist?(import_file)
         
     | 
| 
       537 
532 
     | 
    
         
             
                    end
         
     | 
| 
       538 
533 
     | 
    
         | 
| 
       539 
534 
     | 
    
         
             
                    def wait_for_user
         
     | 
| 
         @@ -328,7 +328,7 @@ class Chef 
     | 
|
| 
       328 
328 
     | 
    
         
             
                    def task_needs_update?(task)
         
     | 
| 
       329 
329 
     | 
    
         
             
                      flag = false
         
     | 
| 
       330 
330 
     | 
    
         
             
                      if new_resource.frequency == :none
         
     | 
| 
       331 
     | 
    
         
            -
                        flag = (task. 
     | 
| 
      
 331 
     | 
    
         
            +
                        flag = (task.author != new_resource.user ||
         
     | 
| 
       332 
332 
     | 
    
         
             
                        task.application_name != new_resource.command ||
         
     | 
| 
       333 
333 
     | 
    
         
             
                        description_needs_update?(task) ||
         
     | 
| 
       334 
334 
     | 
    
         
             
                        task.parameters != new_resource.command_arguments.to_s ||
         
     | 
| 
         @@ -352,7 +352,7 @@ class Chef 
     | 
|
| 
       352 
352 
     | 
    
         
             
                            current_task_trigger[:type] != new_task_trigger[:type] ||
         
     | 
| 
       353 
353 
     | 
    
         
             
                            current_task_trigger[:random_minutes_interval].to_i != new_task_trigger[:random_minutes_interval].to_i ||
         
     | 
| 
       354 
354 
     | 
    
         
             
                            current_task_trigger[:minutes_interval].to_i != new_task_trigger[:minutes_interval].to_i ||
         
     | 
| 
       355 
     | 
    
         
            -
                            task. 
     | 
| 
      
 355 
     | 
    
         
            +
                            task.author.to_s.casecmp(new_resource.user.to_s) != 0 ||
         
     | 
| 
       356 
356 
     | 
    
         
             
                            task.application_name != new_resource.command ||
         
     | 
| 
       357 
357 
     | 
    
         
             
                            description_needs_update?(task) ||
         
     | 
| 
       358 
358 
     | 
    
         
             
                            task.parameters != new_resource.command_arguments.to_s ||
         
     | 
| 
         @@ -102,8 +102,11 @@ class Chef 
     | 
|
| 
       102 
102 
     | 
    
         
             
                    end
         
     | 
| 
       103 
103 
     | 
    
         | 
| 
       104 
104 
     | 
    
         
             
                    if new_resource.owner || new_resource.group
         
     | 
| 
       105 
     | 
    
         
            -
                      converge_by("set owner of #{new_resource.destination} to #{new_resource.owner}:#{new_resource.group}") do
         
     | 
| 
       106 
     | 
    
         
            -
                         
     | 
| 
      
 105 
     | 
    
         
            +
                      converge_by("set owner of files extracted in #{new_resource.destination} to #{new_resource.owner}:#{new_resource.group}") do
         
     | 
| 
      
 106 
     | 
    
         
            +
                        archive = Archive::Reader.open_filename(new_resource.path)
         
     | 
| 
      
 107 
     | 
    
         
            +
                        archive.each_entry do |e|
         
     | 
| 
      
 108 
     | 
    
         
            +
                          FileUtils.chown(new_resource.owner, new_resource.group, "#{new_resource.destination}/#{e.pathname}")
         
     | 
| 
      
 109 
     | 
    
         
            +
                        end
         
     | 
| 
       107 
110 
     | 
    
         
             
                      end
         
     | 
| 
       108 
111 
     | 
    
         
             
                    end
         
     | 
| 
       109 
112 
     | 
    
         
             
                  end
         
     | 
    
        data/lib/chef/resource/cron.rb
    CHANGED
    
    | 
         @@ -162,6 +162,35 @@ class Chef 
     | 
|
| 
       162 
162 
     | 
    
         
             
                    description: "A Hash of environment variables in the form of ({'ENV_VARIABLE' => 'VALUE'}).",
         
     | 
| 
       163 
163 
     | 
    
         
             
                    default: lazy { {} }
         
     | 
| 
       164 
164 
     | 
    
         | 
| 
      
 165 
     | 
    
         
            +
                  TIMEOUT_OPTS = %w{duration preserve-status foreground kill-after signal}.freeze
         
     | 
| 
      
 166 
     | 
    
         
            +
                  TIMEOUT_REGEX = /\A\S+/.freeze
         
     | 
| 
      
 167 
     | 
    
         
            +
             
     | 
| 
      
 168 
     | 
    
         
            +
                  property :time_out, Hash,
         
     | 
| 
      
 169 
     | 
    
         
            +
                    description: "A Hash of timeouts in the form of ({'OPTION' => 'VALUE'}).
         
     | 
| 
      
 170 
     | 
    
         
            +
                    Accepted valid options are:
         
     | 
| 
      
 171 
     | 
    
         
            +
                    preserve-status (BOOL, default: 'false'),
         
     | 
| 
      
 172 
     | 
    
         
            +
                    foreground (BOOL, default: 'false'),
         
     | 
| 
      
 173 
     | 
    
         
            +
                    kill-after (in seconds),
         
     | 
| 
      
 174 
     | 
    
         
            +
                    signal (a name like 'HUP' or a number)",
         
     | 
| 
      
 175 
     | 
    
         
            +
                    default: lazy { {} },
         
     | 
| 
      
 176 
     | 
    
         
            +
                    introduced: "15.7",
         
     | 
| 
      
 177 
     | 
    
         
            +
                    coerce: proc { |h|
         
     | 
| 
      
 178 
     | 
    
         
            +
                      if h.is_a?(Hash)
         
     | 
| 
      
 179 
     | 
    
         
            +
                        invalid_keys = h.keys - TIMEOUT_OPTS
         
     | 
| 
      
 180 
     | 
    
         
            +
                        unless invalid_keys.empty?
         
     | 
| 
      
 181 
     | 
    
         
            +
                          error_msg = "Key of option time_out must be equal to one of: \"#{TIMEOUT_OPTS.join('", "')}\"!  You passed \"#{invalid_keys.join(", ")}\"."
         
     | 
| 
      
 182 
     | 
    
         
            +
                          raise Chef::Exceptions::ValidationFailed, error_msg
         
     | 
| 
      
 183 
     | 
    
         
            +
                        end
         
     | 
| 
      
 184 
     | 
    
         
            +
                        unless h.values.all? { |x| x =~ TIMEOUT_REGEX }
         
     | 
| 
      
 185 
     | 
    
         
            +
                          error_msg = "Values of option time_out should be non-empty string without any leading whitespaces."
         
     | 
| 
      
 186 
     | 
    
         
            +
                          raise Chef::Exceptions::ValidationFailed, error_msg
         
     | 
| 
      
 187 
     | 
    
         
            +
                        end
         
     | 
| 
      
 188 
     | 
    
         
            +
                        h
         
     | 
| 
      
 189 
     | 
    
         
            +
                      elsif h.is_a?(Integer) || h.is_a?(String)
         
     | 
| 
      
 190 
     | 
    
         
            +
                        { "duration" => h }
         
     | 
| 
      
 191 
     | 
    
         
            +
                      end
         
     | 
| 
      
 192 
     | 
    
         
            +
                    }
         
     | 
| 
      
 193 
     | 
    
         
            +
             
     | 
| 
       165 
194 
     | 
    
         
             
                  private
         
     | 
| 
       166 
195 
     | 
    
         | 
| 
       167 
196 
     | 
    
         
             
                  def integerize(integerish)
         
     | 
    
        data/lib/chef/resource/cron_d.rb
    CHANGED
    
    | 
         @@ -206,6 +206,35 @@ class Chef 
     | 
|
| 
       206 
206 
     | 
    
         
             
                    description: "A Hash containing additional arbitrary environment variables under which the cron job will be run in the form of ``({'ENV_VARIABLE' => 'VALUE'})``.",
         
     | 
| 
       207 
207 
     | 
    
         
             
                    default: lazy { {} }
         
     | 
| 
       208 
208 
     | 
    
         | 
| 
      
 209 
     | 
    
         
            +
                  TIMEOUT_OPTS = %w{duration preserve-status foreground kill-after signal}.freeze
         
     | 
| 
      
 210 
     | 
    
         
            +
                  TIMEOUT_REGEX = /\A\S+/.freeze
         
     | 
| 
      
 211 
     | 
    
         
            +
             
     | 
| 
      
 212 
     | 
    
         
            +
                  property :time_out, Hash,
         
     | 
| 
      
 213 
     | 
    
         
            +
                    description: "A Hash of timeouts in the form of ({'OPTION' => 'VALUE'}).
         
     | 
| 
      
 214 
     | 
    
         
            +
                    Accepted valid options are:
         
     | 
| 
      
 215 
     | 
    
         
            +
                    preserve-status (BOOL, default: 'false'),
         
     | 
| 
      
 216 
     | 
    
         
            +
                    foreground (BOOL, default: 'false'),
         
     | 
| 
      
 217 
     | 
    
         
            +
                    kill-after (in seconds),
         
     | 
| 
      
 218 
     | 
    
         
            +
                    signal (a name like 'HUP' or a number)",
         
     | 
| 
      
 219 
     | 
    
         
            +
                    default: lazy { {} },
         
     | 
| 
      
 220 
     | 
    
         
            +
                    introduced: "15.7",
         
     | 
| 
      
 221 
     | 
    
         
            +
                    coerce: proc { |h|
         
     | 
| 
      
 222 
     | 
    
         
            +
                      if h.is_a?(Hash)
         
     | 
| 
      
 223 
     | 
    
         
            +
                        invalid_keys = h.keys - TIMEOUT_OPTS
         
     | 
| 
      
 224 
     | 
    
         
            +
                        unless invalid_keys.empty?
         
     | 
| 
      
 225 
     | 
    
         
            +
                          error_msg = "Key of option time_out must be equal to one of: \"#{TIMEOUT_OPTS.join('", "')}\"!  You passed \"#{invalid_keys.join(", ")}\"."
         
     | 
| 
      
 226 
     | 
    
         
            +
                          raise Chef::Exceptions::ValidationFailed, error_msg
         
     | 
| 
      
 227 
     | 
    
         
            +
                        end
         
     | 
| 
      
 228 
     | 
    
         
            +
                        unless h.values.all? { |x| x =~ TIMEOUT_REGEX }
         
     | 
| 
      
 229 
     | 
    
         
            +
                          error_msg = "Values of option time_out should be non-empty string without any leading whitespaces."
         
     | 
| 
      
 230 
     | 
    
         
            +
                          raise Chef::Exceptions::ValidationFailed, error_msg
         
     | 
| 
      
 231 
     | 
    
         
            +
                        end
         
     | 
| 
      
 232 
     | 
    
         
            +
                        h
         
     | 
| 
      
 233 
     | 
    
         
            +
                      elsif h.is_a?(Integer) || h.is_a?(String)
         
     | 
| 
      
 234 
     | 
    
         
            +
                        { "duration" => h }
         
     | 
| 
      
 235 
     | 
    
         
            +
                      end
         
     | 
| 
      
 236 
     | 
    
         
            +
                    }
         
     | 
| 
      
 237 
     | 
    
         
            +
             
     | 
| 
       209 
238 
     | 
    
         
             
                  property :mode, [String, Integer],
         
     | 
| 
       210 
239 
     | 
    
         
             
                    description: "The octal mode of the generated crontab file.",
         
     | 
| 
       211 
240 
     | 
    
         
             
                    default: "0600"
         
     |