chef 17.0.242 → 17.1.35

Sign up to get free protection for your applications and to get access to all the features.
Files changed (83) hide show
  1. checksums.yaml +4 -4
  2. data/Gemfile +0 -12
  3. data/Rakefile +2 -2
  4. data/chef.gemspec +9 -20
  5. data/lib/chef/chef_fs/file_pattern.rb +2 -2
  6. data/lib/chef/compliance/default_attributes.rb +1 -1
  7. data/lib/chef/compliance/reporter/automate.rb +1 -1
  8. data/lib/chef/compliance/runner.rb +2 -2
  9. data/lib/chef/cookbook/cookbook_version_loader.rb +3 -3
  10. data/lib/chef/cookbook/gem_installer.rb +5 -1
  11. data/lib/chef/dsl/declare_resource.rb +5 -10
  12. data/lib/chef/formatters/doc.rb +2 -1
  13. data/lib/chef/node.rb +1 -1
  14. data/lib/chef/provider/directory.rb +6 -6
  15. data/lib/chef/provider/link.rb +1 -1
  16. data/lib/chef/provider/package/dnf/dnf_helper.py +11 -10
  17. data/lib/chef/provider/package/dnf/python_helper.rb +9 -8
  18. data/lib/chef/provider/package/yum.rb +1 -4
  19. data/lib/chef/provider/package/yum/python_helper.rb +15 -10
  20. data/lib/chef/provider/package/yum/yum_helper.py +46 -62
  21. data/lib/chef/provider/registry_key.rb +1 -1
  22. data/lib/chef/provider/service/systemd.rb +1 -1
  23. data/lib/chef/provider/systemd_unit.rb +1 -1
  24. data/lib/chef/provider/template/content.rb +1 -1
  25. data/lib/chef/provider/windows_script.rb +1 -1
  26. data/lib/chef/resource.rb +6 -7
  27. data/lib/chef/resource/execute.rb +2 -2
  28. data/lib/chef/resource/inspec_waiver_file_entry.rb +155 -0
  29. data/lib/chef/resource/lwrp_base.rb +17 -2
  30. data/lib/chef/resource/remote_file.rb +2 -2
  31. data/lib/chef/resource/windows_env.rb +1 -1
  32. data/lib/chef/resource/windows_font.rb +1 -1
  33. data/lib/chef/resource/windows_pagefile.rb +2 -2
  34. data/lib/chef/resource/windows_path.rb +2 -2
  35. data/lib/chef/resource/windows_security_policy.rb +5 -2
  36. data/lib/chef/resource/windows_task.rb +1 -1
  37. data/lib/chef/resource_builder.rb +8 -2
  38. data/lib/chef/resources.rb +1 -0
  39. data/lib/chef/run_lock.rb +1 -1
  40. data/lib/chef/runner.rb +1 -1
  41. data/lib/chef/shell/ext.rb +3 -3
  42. data/lib/chef/version.rb +1 -1
  43. data/lib/chef/win32/api.rb +9 -2
  44. data/spec/data/knife-home/.chef/plugins/knife/example_home_subcommand.rb +0 -0
  45. data/spec/data/knife-site-subcommands/plugins/knife/example_subcommand.rb +0 -0
  46. data/spec/data/knife_subcommand/test_explicit_category.rb +7 -0
  47. data/spec/data/knife_subcommand/test_name_mapping.rb +4 -0
  48. data/spec/data/knife_subcommand/test_yourself.rb +21 -0
  49. data/spec/functional/resource/dnf_package_spec.rb +857 -537
  50. data/spec/functional/resource/group_spec.rb +1 -1
  51. data/spec/functional/resource/link_spec.rb +1 -1
  52. data/spec/functional/resource/remote_file_spec.rb +1 -1
  53. data/spec/functional/resource/windows_env_spec.rb +2 -2
  54. data/spec/functional/resource/yum_package_spec.rb +495 -428
  55. data/spec/integration/client/client_spec.rb +0 -20
  56. data/spec/integration/recipes/unified_mode_spec.rb +70 -0
  57. data/spec/spec_helper.rb +3 -0
  58. data/spec/support/chef_helpers.rb +1 -1
  59. data/spec/support/shared/functional/execute_resource.rb +1 -1
  60. data/spec/support/shared/functional/knife.rb +37 -0
  61. data/spec/support/shared/integration/knife_support.rb +192 -0
  62. data/spec/support/shared/unit/knife_shared.rb +39 -0
  63. data/spec/support/shared/unit/provider/file.rb +1 -1
  64. data/spec/unit/chef_fs/file_system/repository/directory_spec.rb +1 -1
  65. data/spec/unit/compliance/runner_spec.rb +1 -1
  66. data/spec/unit/provider/link_spec.rb +1 -1
  67. data/spec/unit/provider/package/dnf/python_helper_spec.rb +1 -0
  68. data/spec/unit/provider/package/yum/python_helper_spec.rb +1 -0
  69. data/spec/unit/provider/service/systemd_service_spec.rb +2 -2
  70. data/spec/unit/provider/systemd_unit_spec.rb +2 -2
  71. data/spec/unit/resource/inspec_waiver_file_entry_spec.rb +80 -0
  72. data/tasks/rspec.rb +4 -9
  73. metadata +16 -160
  74. data/lib/chef/provider/package/yum/simplejson/LICENSE.txt +0 -79
  75. data/lib/chef/provider/package/yum/simplejson/__init__.py +0 -318
  76. data/lib/chef/provider/package/yum/simplejson/__init__.pyc +0 -0
  77. data/lib/chef/provider/package/yum/simplejson/decoder.py +0 -354
  78. data/lib/chef/provider/package/yum/simplejson/decoder.pyc +0 -0
  79. data/lib/chef/provider/package/yum/simplejson/encoder.py +0 -440
  80. data/lib/chef/provider/package/yum/simplejson/encoder.pyc +0 -0
  81. data/lib/chef/provider/package/yum/simplejson/scanner.py +0 -65
  82. data/lib/chef/provider/package/yum/simplejson/scanner.pyc +0 -0
  83. data/lib/chef/provider/package/yum/simplejson/tool.py +0 -37
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 76e8bbb87457ae55ce29900a8a7686dbefcb4816c50fa818979bb83f6fab76c8
4
- data.tar.gz: c6a402cf50ba0ec056631b412d5887c503d3ce177fc7f869692a64c487b26ef1
3
+ metadata.gz: b92d0b0a8777142e81fac5c879381f6ea5212a3c068a2e721d736cdc550d1c85
4
+ data.tar.gz: 742765962f825f43c67be4a2781ea5cca930a2daba4ad69c0a9fbe231423cc44
5
5
  SHA512:
6
- metadata.gz: 278aff6f45d8a41f323677c768efa94d9e337a60add1445d598de6b15fa9d3cce3a308ce8e27ec9465e557a97bae37d6d29a7c254f35a52d47bba82d928142b5
7
- data.tar.gz: caa051215e2ac1116cc818a6ba0bc0d6dd15683aaef9a26e9d08e7063e4a1263d5177baf30e56c08e13f60f8d5e515cfd632632397cd6f348902d38b01a59856
6
+ metadata.gz: 2b2e4f77b2b34aea3209fb5c22453b1238f1b63bcb967cc56d0829371b9bf7a71169e1b3e98dbaf424eb7f1e902393dd18940770f3801242c07c7780adc156f9
7
+ data.tar.gz: 95ae0ac8453576d18c2e5c5d9a06fd893e3a4e29f06062acea963ecaf8a33b2b32988d24a369f4decae7b17e4840020161f65cdbcd9d8cbd9069397f8f513f90
data/Gemfile CHANGED
@@ -1,10 +1,5 @@
1
1
  source "https://rubygems.org"
2
2
 
3
- # Note we do not use the gemspec DSL which restricts to the
4
- # gemspec for the current platform and filters out other platforms
5
- # during a bundle lock operation. We actually want dependencies from
6
- # both of our gemspecs. Also note this this mimics gemspec behavior
7
- # of bundler versions prior to 1.12.0 (https://github.com/bundler/bundler/commit/193a14fe5e0d56294c7b370a0e59f93b2c216eed)
8
3
  gem "chef", path: "."
9
4
 
10
5
  gem "ohai", git: "https://github.com/chef/ohai.git", branch: "master"
@@ -22,8 +17,6 @@ end
22
17
 
23
18
  gem "cheffish", ">= 17"
24
19
 
25
- gem "chef-telemetry", ">=1.0.8" # 1.0.8 removes the http dep
26
-
27
20
  group(:omnibus_package) do
28
21
  gem "appbundler"
29
22
  gem "rb-readline"
@@ -38,11 +31,6 @@ group(:omnibus_package, :pry) do
38
31
  gem "pry-stack_explorer"
39
32
  end
40
33
 
41
- # Everything except AIX
42
- group(:ruby_prof) do
43
- gem "ruby-prof"
44
- end
45
-
46
34
  # Everything except AIX and Windows
47
35
  group(:ruby_shadow) do
48
36
  # if ruby-shadow does a release that supports ruby-3.0 this can be removed
data/Rakefile CHANGED
@@ -108,8 +108,8 @@ task :update_chef_exec_dll do
108
108
 
109
109
  sh("hab pkg install chef/chef-powershell-shim")
110
110
  sh("hab pkg install chef/chef-powershell-shim-x86")
111
- x64 = `hab pkg path chef/chef-powershell-shim`.chomp.tr('\\', "/")
112
- x86 = `hab pkg path chef/chef-powershell-shim-x86`.chomp.tr('\\', "/")
111
+ x64 = `hab pkg path chef/chef-powershell-shim`.chomp.tr("\\", "/")
112
+ x86 = `hab pkg path chef/chef-powershell-shim-x86`.chomp.tr("\\", "/")
113
113
  FileUtils.rm_rf(Dir["distro/ruby_bin_folder/AMD64/*"])
114
114
  FileUtils.rm_rf(Dir["distro/ruby_bin_folder/x86/*"])
115
115
  puts "Copying #{x64}/bin/* to distro/ruby_bin_folder/AMD64"
data/chef.gemspec CHANGED
@@ -40,27 +40,18 @@ Gem::Specification.new do |s|
40
40
 
41
41
  s.add_dependency "ffi", ">= 1.5.0"
42
42
  s.add_dependency "ffi-yajl", "~> 2.2"
43
- s.add_dependency "net-ssh", ">= 5.1", "< 7"
44
- s.add_dependency "net-ssh-multi", "~> 1.2", ">= 1.2.1"
45
- s.add_dependency "net-sftp", ">= 2.1.2", "< 4.0"
46
- s.add_dependency "ed25519", "~> 1.2" # ed25519 ssh key support
47
- s.add_dependency "bcrypt_pbkdf", "~> 1.1" # ed25519 ssh key support
48
- s.add_dependency "highline", ">= 1.6.9", "< 3"
49
- s.add_dependency "tty-prompt", "~> 0.21" # knife ui.ask prompt
50
- s.add_dependency "tty-screen", "~> 0.6" # knife list
51
- s.add_dependency "tty-table", "~> 0.11" # knife render table output.
52
- s.add_dependency "pastel" # knife ui.color
53
- s.add_dependency "erubis", "~> 2.7"
54
- s.add_dependency "diff-lcs", ">= 1.2.4", "< 1.4.0" # 1.4 breaks output
55
- s.add_dependency "ffi-libarchive", "~> 1.0", ">= 1.0.3"
43
+ s.add_dependency "net-sftp", ">= 2.1.2", "< 4.0" # remote_file resource
44
+ s.add_dependency "erubis", "~> 2.7" # template resource / cookbook syntax check
45
+ s.add_dependency "diff-lcs", ">= 1.2.4", "< 1.4.0" # 1.4 breaks output. Used in lib/chef/util/diff
46
+ s.add_dependency "ffi-libarchive", "~> 1.0", ">= 1.0.3" # archive_file resource
56
47
  s.add_dependency "chef-zero", ">= 14.0.11"
57
- s.add_dependency "chef-vault"
48
+ s.add_dependency "chef-vault" # chef-vault resources and helpers
58
49
 
59
- s.add_dependency "plist", "~> 3.2"
60
- s.add_dependency "iniparse", "~> 1.4"
50
+ s.add_dependency "plist", "~> 3.2" # launchd, dscl/mac user, macos_userdefaults, osx_profile and plist resources
51
+ s.add_dependency "iniparse", "~> 1.4" # systemd_unit resource
61
52
  s.add_dependency "addressable"
62
53
  s.add_dependency "syslog-logger", "~> 1.6"
63
- s.add_dependency "uuidtools", ">= 2.1.5", "< 3.0"
54
+ s.add_dependency "uuidtools", ">= 2.1.5", "< 3.0" # osx_profile resource
64
55
 
65
56
  s.add_dependency "proxifier", "~> 1.0"
66
57
 
@@ -69,9 +60,7 @@ Gem::Specification.new do |s|
69
60
 
70
61
  s.require_paths = %w{ lib }
71
62
  s.files = %w{Gemfile Rakefile LICENSE README.md} +
72
- Dir.glob("{lib,spec}/**/*", File::FNM_DOTMATCH).reject do |f|
73
- File.directory?(f) || File.path(f).match(/knife*/)
74
- end +
63
+ Dir.glob("{lib,spec}/**/*", File::FNM_DOTMATCH).reject { |f| File.directory?(f) } +
75
64
  Dir.glob("*.gemspec") +
76
65
  Dir.glob("tasks/rspec.rb")
77
66
 
@@ -255,7 +255,7 @@ class Chef
255
255
  end
256
256
 
257
257
  def self.regexp_escape_characters
258
- [ "[", '\\', "^", "$", ".", "|", "?", "*", "+", "(", ")", "{", "}" ]
258
+ [ "[", "\\", "^", "$", ".", "|", "?", "*", "+", "(", ")", "{", "}" ]
259
259
  end
260
260
 
261
261
  def self.pattern_to_regexp(pattern)
@@ -281,7 +281,7 @@ class Chef
281
281
  exact = nil
282
282
  regexp << "."
283
283
  else
284
- if part[0, 1] == '\\' && part.length == 2
284
+ if part[0, 1] == "\\" && part.length == 2
285
285
  # backslash escapes are only supported on Unix, and are handled here by leaving the escape on (it means the same thing in a regex)
286
286
  exact << part[1, 1] unless exact.nil?
287
287
  if regexp_escape_characters.include?(part[1, 1])
@@ -28,7 +28,7 @@ class Chef
28
28
  # Controls what is done with the resulting report after the Chef InSpec run.
29
29
  # Accepts a single string value or an array of multiple values.
30
30
  # Accepted values: 'chef-server-automate', 'chef-automate', 'json-file', 'audit-enforcer', 'cli'
31
- "reporter" => "json-file",
31
+ "reporter" => %w{json-file cli},
32
32
 
33
33
  # Controls if Chef InSpec profiles should be fetched from Chef Automate or Chef Infra Server
34
34
  # in addition to the default fetch locations provided by Chef Inspec.
@@ -44,7 +44,7 @@ class Chef
44
44
  end
45
45
 
46
46
  unless @url && @token
47
- raise "CMPL006: data_collector.token and data_collector.server_url must be configured in client.rb! Further information: https://docs.chef.io/chef_compliance_phase/#direct-reporting-to-chef-automate"
47
+ raise "CMPL006: data_collector.token and data_collector.server_url must be configured in client.rb! Further information: https://docs.chef.io/automate/data_collection/#configure-your-chef-infra-client-to-send-data-to-chef-automate-without-chef-infra-server"
48
48
  end
49
49
  end
50
50
 
@@ -288,7 +288,7 @@ class Chef
288
288
  # supports it.
289
289
  Array(node["audit"]["reporter"]).each do |type|
290
290
  unless SUPPORTED_REPORTERS.include? type
291
- raise "CMPL003: '#{type}' found in node['audit']['reporter'] is not a supported reporter for Compliance Phase. Supported reporters are: #{SUPPORTED_REPORTERS.join(", ")}. For more information, see the documentation at https://docs.chef.io/chef_compliance_phase/chef_compliance_runners/#reporters"
291
+ raise "CMPL003: '#{type}' found in node['audit']['reporter'] is not a supported reporter for Compliance Phase. Supported reporters are: #{SUPPORTED_REPORTERS.join(", ")}. For more information, see the documentation at https://docs.chef.io/chef_compliance_phase#reporters"
292
292
  end
293
293
 
294
294
  @reporters[type] = reporter(type)
@@ -297,7 +297,7 @@ class Chef
297
297
 
298
298
  unless (fetcher = node["audit"]["fetcher"]).nil?
299
299
  unless SUPPORTED_FETCHERS.include? fetcher
300
- raise "CMPL002: Unrecognized Compliance Phase fetcher (node['audit']['fetcher'] = #{fetcher}). Supported fetchers are: #{SUPPORTED_FETCHERS.join(", ")}, or nil. For more information, see the documentation at https://docs.chef.io/chef_compliance_phase/chef_compliance_runners/#fetchers"
300
+ raise "CMPL002: Unrecognized Compliance Phase fetcher (node['audit']['fetcher'] = #{fetcher}). Supported fetchers are: #{SUPPORTED_FETCHERS.join(", ")}, or nil. For more information, see the documentation at https://docs.chef.io/chef_compliance_phase#fetch-profiles"
301
301
  end
302
302
  end
303
303
  @validation_passed = true
@@ -160,13 +160,13 @@ class Chef
160
160
  def metadata_filenames
161
161
  return @metadata_filenames unless @metadata_filenames.empty?
162
162
 
163
- if File.exists?(File.join(cookbook_path, UPLOADED_COOKBOOK_VERSION_FILE))
163
+ if File.exist?(File.join(cookbook_path, UPLOADED_COOKBOOK_VERSION_FILE))
164
164
  @uploaded_cookbook_version_file = File.join(cookbook_path, UPLOADED_COOKBOOK_VERSION_FILE)
165
165
  end
166
166
 
167
- if File.exists?(File.join(cookbook_path, "metadata.json"))
167
+ if File.exist?(File.join(cookbook_path, "metadata.json"))
168
168
  @metadata_filenames << File.join(cookbook_path, "metadata.json")
169
- elsif File.exists?(File.join(cookbook_path, "metadata.rb"))
169
+ elsif File.exist?(File.join(cookbook_path, "metadata.rb"))
170
170
  @metadata_filenames << File.join(cookbook_path, "metadata.rb")
171
171
  elsif uploaded_cookbook_version_file
172
172
  @metadata_filenames << uploaded_cookbook_version_file
@@ -70,7 +70,11 @@ class Chef
70
70
  unless Chef::Config[:skip_gem_metadata_installation]
71
71
  # Add additional options to bundle install
72
72
  cmd = [ "bundle", "install", Chef::Config[:gem_installer_bundler_options] ]
73
- so = shell_out!(cmd, cwd: dir, env: { "PATH" => path_with_prepended_ruby_bin })
73
+ env = {
74
+ "PATH" => path_with_prepended_ruby_bin,
75
+ "BUNDLE_SILENCE_ROOT_WARNING" => "1",
76
+ }
77
+ so = shell_out!(cmd, cwd: dir, env: env)
74
78
  Chef::Log.info(so.stdout)
75
79
  end
76
80
  end
@@ -156,15 +156,7 @@ class Chef
156
156
  def edit_resource(type, name, created_at: nil, run_context: self.run_context, &resource_attrs_block)
157
157
  edit_resource!(type, name, created_at: created_at, run_context: run_context, &resource_attrs_block)
158
158
  rescue Chef::Exceptions::ResourceNotFound
159
- resource = declare_resource(type, name, created_at: created_at, run_context: run_context)
160
- if resource_attrs_block
161
- if defined?(new_resource)
162
- resource.instance_exec(new_resource, &resource_attrs_block)
163
- else
164
- resource.instance_exec(&resource_attrs_block)
165
- end
166
- end
167
- resource
159
+ declare_resource(type, name, created_at: created_at, run_context: run_context, &resource_attrs_block)
168
160
  end
169
161
 
170
162
  # Find existing resources by searching the list of existing resources. Possible
@@ -306,6 +298,8 @@ class Chef
306
298
 
307
299
  enclosing_provider ||= self if is_a?(Chef::Provider)
308
300
 
301
+ nr = new_resource if defined?(new_resource)
302
+
309
303
  Chef::ResourceBuilder.new(
310
304
  type: type,
311
305
  name: name,
@@ -314,7 +308,8 @@ class Chef
314
308
  run_context: run_context,
315
309
  cookbook_name: cookbook_name,
316
310
  recipe_name: recipe_name,
317
- enclosing_provider: enclosing_provider
311
+ enclosing_provider: enclosing_provider,
312
+ new_resource: nr
318
313
  ).build(&resource_attrs_block)
319
314
  end
320
315
 
@@ -56,7 +56,8 @@ class Chef
56
56
  # Print out deprecations.
57
57
  unless deprecations.empty?
58
58
  puts_line ""
59
- puts_line "Deprecated features used!"
59
+ puts_line "Deprecation warnings that must be addressed before upgrading to Chef Infra #{Chef::VERSION.to_i + 1}:"
60
+ puts_line ""
60
61
  deprecations.each do |message, details|
61
62
  locations = details[:locations]
62
63
  if locations.size == 1
data/lib/chef/node.rb CHANGED
@@ -761,7 +761,7 @@ class Chef
761
761
  path = File.expand_path(Chef::Config[:chef_guid_path])
762
762
  dir = File.dirname(path)
763
763
 
764
- unless File.exists?(path)
764
+ unless File.exist?(path)
765
765
  FileUtils.mkdir_p(dir)
766
766
  File.write(path, SecureRandom.uuid)
767
767
  end
@@ -32,7 +32,7 @@ class Chef
32
32
  def load_current_resource
33
33
  @current_resource = Chef::Resource::Directory.new(new_resource.name)
34
34
  current_resource.path(new_resource.path)
35
- if ::File.exists?(current_resource.path) && @action != :create_if_missing
35
+ if ::File.exist?(current_resource.path) && @action != :create_if_missing
36
36
  load_resource_attributes_from_file(current_resource)
37
37
  end
38
38
  current_resource
@@ -73,7 +73,7 @@ class Chef
73
73
  # make sure we have write permissions to that directory
74
74
  is_parent_writable = lambda do |base_dir|
75
75
  base_dir = ::File.dirname(base_dir)
76
- if ::File.exists?(base_dir)
76
+ if ::File.exist?(base_dir)
77
77
  if Chef::FileAccessControl.writable?(base_dir)
78
78
  true
79
79
  elsif Chef::Util::PathHelper.is_sip_path?(base_dir, node)
@@ -89,7 +89,7 @@ class Chef
89
89
  else
90
90
  # in why run mode & parent directory does not exist no permissions check is required
91
91
  # If not in why run, permissions must be valid and we rely on prior assertion that dir exists
92
- if !whyrun_mode? || ::File.exists?(parent_directory)
92
+ if !whyrun_mode? || ::File.exist?(parent_directory)
93
93
  if Chef::FileAccessControl.writable?(parent_directory)
94
94
  true
95
95
  elsif Chef::Util::PathHelper.is_sip_path?(parent_directory, node)
@@ -108,7 +108,7 @@ class Chef
108
108
 
109
109
  requirements.assert(:delete) do |a|
110
110
  a.assertion do
111
- if ::File.exists?(new_resource.path)
111
+ if ::File.exist?(new_resource.path)
112
112
  ::File.directory?(new_resource.path) && Chef::FileAccessControl.writable?(new_resource.path)
113
113
  else
114
114
  true
@@ -122,7 +122,7 @@ class Chef
122
122
  end
123
123
 
124
124
  action :create do
125
- unless ::File.exists?(new_resource.path)
125
+ unless ::File.exist?(new_resource.path)
126
126
  converge_by("create new directory #{new_resource.path}") do
127
127
  if new_resource.recursive == true
128
128
  ::FileUtils.mkdir_p(new_resource.path)
@@ -138,7 +138,7 @@ class Chef
138
138
  end
139
139
 
140
140
  action :delete do
141
- if ::File.exists?(new_resource.path)
141
+ if ::File.exist?(new_resource.path)
142
142
  converge_by("delete existing directory #{new_resource.path}") do
143
143
  if new_resource.recursive == true
144
144
  # we don't use rm_rf here because it masks all errors, including
@@ -73,7 +73,7 @@ class Chef
73
73
  end
74
74
 
75
75
  def canonicalize(path)
76
- ChefUtils.windows? ? path.tr("/", '\\') : path
76
+ ChefUtils.windows? ? path.tr("/", "\\") : path
77
77
  end
78
78
 
79
79
  action :create do
@@ -78,12 +78,12 @@ def version_tuple(versionstr):
78
78
  def versioncompare(versions):
79
79
  sack = get_sack()
80
80
  if (versions[0] is None) or (versions[1] is None):
81
- outpipe.write('0\n')
82
- outpipe.flush()
81
+ outpipe.write('0\n')
82
+ outpipe.flush()
83
83
  else:
84
- evr_comparison = dnf.rpm.rpm.labelCompare(version_tuple(versions[0]), version_tuple(versions[1]))
85
- outpipe.write('{}\n'.format(evr_comparison))
86
- outpipe.flush()
84
+ evr_comparison = dnf.rpm.rpm.labelCompare(version_tuple(versions[0]), version_tuple(versions[1]))
85
+ outpipe.write('{}\n'.format(evr_comparison))
86
+ outpipe.flush()
87
87
 
88
88
  def query(command):
89
89
  sack = get_sack()
@@ -152,20 +152,21 @@ def setup_exit_handler():
152
152
  signal.signal(signal.SIGQUIT, exit_handler)
153
153
 
154
154
  if len(sys.argv) < 3:
155
- inpipe = sys.stdin
156
- outpipe = sys.stdout
155
+ inpipe = sys.stdin
156
+ outpipe = sys.stdout
157
157
  else:
158
- inpipe = os.fdopen(int(sys.argv[1]), "r")
159
- outpipe = os.fdopen(int(sys.argv[2]), "w")
158
+ os.set_blocking(int(sys.argv[1]), True)
159
+ inpipe = os.fdopen(int(sys.argv[1]), "r")
160
+ outpipe = os.fdopen(int(sys.argv[2]), "w")
160
161
 
161
162
  try:
163
+ setup_exit_handler()
162
164
  while 1:
163
165
  # stop the process if the parent proc goes away
164
166
  ppid = os.getppid()
165
167
  if ppid == 1:
166
168
  raise RuntimeError("orphaned")
167
169
 
168
- setup_exit_handler()
169
170
  line = inpipe.readline()
170
171
 
171
172
  # only way to detect EOF in python
@@ -52,7 +52,6 @@ class Chef
52
52
  end
53
53
 
54
54
  def start
55
- ENV["PYTHONUNBUFFERED"] = "1"
56
55
  @inpipe, inpipe_write = IO.pipe
57
56
  outpipe_read, @outpipe = IO.pipe
58
57
  @stdin, @stdout, @stderr, @wait_thr = Open3.popen3("#{dnf_command} #{outpipe_read.fileno} #{inpipe_write.fileno}", outpipe_read.fileno => outpipe_read, inpipe_write.fileno => inpipe_write, close_others: false)
@@ -75,6 +74,7 @@ class Chef
75
74
  stderr.close unless stderr.nil?
76
75
  inpipe.close unless inpipe.nil?
77
76
  outpipe.close unless outpipe.nil?
77
+ @stdin = @stdout = @stderr = @inpipe = @outpipe = @wait_thr = nil
78
78
  end
79
79
  end
80
80
 
@@ -114,7 +114,7 @@ class Chef
114
114
  query_output = query(action, parameters)
115
115
  version = parse_response(query_output.lines.last)
116
116
  Chef::Log.trace "parsed #{version} from python helper"
117
- restart unless repo_opts.empty?
117
+ reap unless repo_opts.empty?
118
118
  version
119
119
  end
120
120
 
@@ -148,10 +148,11 @@ class Chef
148
148
  with_helper do
149
149
  json = build_query(action, parameters)
150
150
  Chef::Log.trace "sending '#{json}' to python helper"
151
- outpipe.syswrite json + "\n"
152
- output = inpipe.sysread(4096).chomp
151
+ outpipe.puts json
152
+ outpipe.flush
153
+ output = inpipe.readline.chomp
153
154
  Chef::Log.trace "got '#{output}' from python helper"
154
- return output
155
+ output
155
156
  end
156
157
  end
157
158
 
@@ -199,13 +200,13 @@ class Chef
199
200
  Chef::Log.trace "discarding output on stderr/stdout from python helper: #{output}"
200
201
  end
201
202
  ret
202
- rescue EOFError, Errno::EPIPE, Timeout::Error, Errno::ESRCH => e
203
+ rescue => e
203
204
  output = drain_fds
204
- if ( max_retries -= 1 ) > 0
205
+ restart
206
+ if ( max_retries -= 1 ) > 0 && !ENV["DNF_HELPER_NO_RETRIES"]
205
207
  unless output.empty?
206
208
  Chef::Log.trace "discarding output on stderr/stdout from python helper: #{output}"
207
209
  end
208
- restart
209
210
  retry
210
211
  else
211
212
  raise e if output.empty?
@@ -237,11 +237,8 @@ class Chef
237
237
  @installed_version[index]
238
238
  end
239
239
 
240
- # cache flushing is accomplished by simply restarting the python helper. this produces a roughly
241
- # 15% hit to the runtime of installing/removing/upgrading packages. correctly using multipackage
242
- # array installs (and the multipackage cookbook) can produce 600% improvements in runtime.
243
240
  def flushcache
244
- python_helper.restart
241
+ python_helper.close_rpmdb
245
242
  end
246
243
 
247
244
  def yum_binary
@@ -51,7 +51,6 @@ class Chef
51
51
  end
52
52
 
53
53
  def start
54
- ENV["PYTHONUNBUFFERED"] = "1"
55
54
  @inpipe, inpipe_write = IO.pipe
56
55
  outpipe_read, @outpipe = IO.pipe
57
56
  @stdin, @stdout, @stderr, @wait_thr = Open3.popen3("#{yum_command} #{outpipe_read.fileno} #{inpipe_write.fileno}", outpipe_read.fileno => outpipe_read, inpipe_write.fileno => inpipe_write, close_others: false)
@@ -74,6 +73,7 @@ class Chef
74
73
  stderr.close unless stderr.nil?
75
74
  inpipe.close unless inpipe.nil?
76
75
  outpipe.close unless outpipe.nil?
76
+ @stdin = @stdout = @stderr = @inpipe = @outpipe = @wait_thr = nil
77
77
  end
78
78
  end
79
79
 
@@ -81,6 +81,10 @@ class Chef
81
81
  start if stdin.nil?
82
82
  end
83
83
 
84
+ def close_rpmdb
85
+ query("close_rpmdb", {})
86
+ end
87
+
84
88
  def compare_versions(version1, version2)
85
89
  query("versioncompare", { "versions" => [version1, version2] }).to_i
86
90
  end
@@ -117,12 +121,12 @@ class Chef
117
121
  parameters = { "provides" => provides, "version" => version, "arch" => arch }
118
122
  repo_opts = options_params(options || {})
119
123
  parameters.merge!(repo_opts)
120
- # XXX: for now we restart before and after every query with an enablerepo/disablerepo to clean the helpers internal state
121
- restart unless repo_opts.empty?
124
+ # XXX: for now we close the rpmdb before and after every query with an enablerepo/disablerepo to clean the helpers internal state
125
+ close_rpmdb unless repo_opts.empty?
122
126
  query_output = query(action, parameters)
123
127
  version = parse_response(query_output.lines.last)
124
128
  Chef::Log.trace "parsed #{version} from python helper"
125
- restart unless repo_opts.empty?
129
+ close_rpmdb unless repo_opts.empty?
126
130
  version
127
131
  end
128
132
 
@@ -156,10 +160,11 @@ class Chef
156
160
  with_helper do
157
161
  json = build_query(action, parameters)
158
162
  Chef::Log.trace "sending '#{json}' to python helper"
159
- outpipe.syswrite json + "\n"
160
- output = inpipe.sysread(4096).chomp
163
+ outpipe.puts json
164
+ outpipe.flush
165
+ output = inpipe.readline.chomp
161
166
  Chef::Log.trace "got '#{output}' from python helper"
162
- return output
167
+ output
163
168
  end
164
169
  end
165
170
 
@@ -207,13 +212,13 @@ class Chef
207
212
  Chef::Log.trace "discarding output on stderr/stdout from python helper: #{output}"
208
213
  end
209
214
  ret
210
- rescue EOFError, Errno::EPIPE, Timeout::Error, Errno::ESRCH => e
215
+ rescue => e
211
216
  output = drain_fds
212
- if ( max_retries -= 1 ) > 0
217
+ restart
218
+ if ( max_retries -= 1 ) > 0 && !ENV["YUM_HELPER_NO_RETRIES"]
213
219
  unless output.empty?
214
220
  Chef::Log.trace "discarding output on stderr/stdout from python helper: #{output}"
215
221
  end
216
- restart
217
222
  retry
218
223
  else
219
224
  raise e if output.empty?