chef 12.17.44 → 12.18.31

Sign up to get free protection for your applications and to get access to all the features.
Files changed (178) hide show
  1. checksums.yaml +4 -4
  2. data/Gemfile +0 -1
  3. data/README.md +3 -2
  4. data/Rakefile +9 -0
  5. data/VERSION +1 -1
  6. data/acceptance/Gemfile.lock +17 -17
  7. data/distro/common/html/knife_environment.html +4 -8
  8. data/distro/common/man/man1/knife-environment.1 +4 -16
  9. data/distro/powershell/chef/chef.psm1 +139 -24
  10. data/lib/chef/application.rb +5 -4
  11. data/lib/chef/application/windows_service_manager.rb +6 -4
  12. data/lib/chef/chef_fs/chef_fs_data_store.rb +1 -1
  13. data/lib/chef/chef_fs/command_line.rb +1 -1
  14. data/lib/chef/chef_fs/file_system/chef_server/rest_list_entry.rb +8 -1
  15. data/lib/chef/chef_fs/file_system/repository/chef_repository_file_system_root_dir.rb +1 -1
  16. data/lib/chef/chef_fs/file_system/repository/nodes_dir.rb +1 -1
  17. data/lib/chef/cookbook/chefignore.rb +1 -1
  18. data/lib/chef/cookbook/cookbook_version_loader.rb +4 -4
  19. data/lib/chef/cookbook/metadata.rb +2 -2
  20. data/lib/chef/cookbook_loader.rb +1 -1
  21. data/lib/chef/data_collector.rb +24 -13
  22. data/lib/chef/data_collector/messages.rb +8 -6
  23. data/lib/chef/data_collector/messages/helpers.rb +1 -1
  24. data/lib/chef/deprecated.rb +30 -0
  25. data/lib/chef/dsl/platform_introspection.rb +2 -2
  26. data/lib/chef/encrypted_data_bag_item.rb +1 -1
  27. data/lib/chef/encrypted_data_bag_item/decryptor.rb +2 -2
  28. data/lib/chef/environment.rb +1 -1
  29. data/lib/chef/exceptions.rb +5 -5
  30. data/lib/chef/file_access_control/unix.rb +5 -5
  31. data/lib/chef/formatters/error_description.rb +1 -1
  32. data/lib/chef/http/basic_client.rb +1 -1
  33. data/lib/chef/http/json_input.rb +2 -2
  34. data/lib/chef/knife.rb +1 -1
  35. data/lib/chef/knife/cookbook_site_install.rb +1 -1
  36. data/lib/chef/knife/core/cookbook_scm_repo.rb +1 -1
  37. data/lib/chef/knife/core/ui.rb +1 -1
  38. data/lib/chef/mixin/command.rb +1 -0
  39. data/lib/chef/mixin/deep_merge.rb +1 -1
  40. data/lib/chef/mixin/shell_out.rb +58 -3
  41. data/lib/chef/mixin/which.rb +5 -9
  42. data/lib/chef/mixin/wide_string.rb +1 -1
  43. data/lib/chef/node.rb +1 -1
  44. data/lib/chef/node/attribute.rb +4 -5
  45. data/lib/chef/node_map.rb +18 -2
  46. data/lib/chef/platform/provider_handler_map.rb +2 -2
  47. data/lib/chef/platform/provider_mapping.rb +5 -0
  48. data/lib/chef/platform/resource_handler_map.rb +2 -2
  49. data/lib/chef/provider/env/windows.rb +1 -1
  50. data/lib/chef/provider/git.rb +1 -1
  51. data/lib/chef/provider/group.rb +41 -46
  52. data/lib/chef/provider/group/aix.rb +12 -19
  53. data/lib/chef/provider/group/dscl.rb +46 -43
  54. data/lib/chef/provider/group/gpasswd.rb +7 -7
  55. data/lib/chef/provider/group/groupadd.rb +29 -34
  56. data/lib/chef/provider/group/groupmod.rb +26 -31
  57. data/lib/chef/provider/group/pw.rb +28 -31
  58. data/lib/chef/provider/group/suse.rb +9 -9
  59. data/lib/chef/provider/group/usermod.rb +10 -11
  60. data/lib/chef/provider/group/windows.rb +18 -20
  61. data/lib/chef/provider/ifconfig.rb +52 -63
  62. data/lib/chef/provider/ifconfig/aix.rb +23 -28
  63. data/lib/chef/provider/ifconfig/debian.rb +23 -22
  64. data/lib/chef/provider/ifconfig/redhat.rb +12 -12
  65. data/lib/chef/provider/mount/mount.rb +1 -1
  66. data/lib/chef/provider/osx_profile.rb +4 -2
  67. data/lib/chef/provider/package.rb +16 -7
  68. data/lib/chef/provider/package/chocolatey.rb +3 -1
  69. data/lib/chef/provider/package/dnf.rb +183 -0
  70. data/lib/chef/provider/package/dnf/dnf_helper.py +91 -0
  71. data/lib/chef/provider/package/dnf/python_helper.rb +120 -0
  72. data/lib/chef/provider/package/dnf/version.rb +56 -0
  73. data/lib/chef/provider/package/easy_install.rb +1 -1
  74. data/lib/chef/provider/package/freebsd/base.rb +1 -1
  75. data/lib/chef/provider/package/freebsd/pkgng.rb +1 -1
  76. data/lib/chef/provider/package/powershell.rb +3 -3
  77. data/lib/chef/provider/package/windows.rb +1 -1
  78. data/lib/chef/provider/package/zypper.rb +1 -1
  79. data/lib/chef/provider/route.rb +186 -184
  80. data/lib/chef/provider/service/arch.rb +2 -2
  81. data/lib/chef/provider/service/freebsd.rb +1 -1
  82. data/lib/chef/provider/service/gentoo.rb +2 -2
  83. data/lib/chef/provider/service/insserv.rb +2 -2
  84. data/lib/chef/provider/service/macosx.rb +2 -2
  85. data/lib/chef/provider/service/openbsd.rb +1 -1
  86. data/lib/chef/provider/service/redhat.rb +2 -2
  87. data/lib/chef/provider/support/yum_repo.erb +10 -3
  88. data/lib/chef/provider/user.rb +17 -20
  89. data/lib/chef/provider/user/aix.rb +23 -24
  90. data/lib/chef/provider/user/dscl.rb +56 -53
  91. data/lib/chef/provider/user/linux.rb +13 -16
  92. data/lib/chef/provider/user/pw.rb +26 -30
  93. data/lib/chef/provider/user/solaris.rb +11 -12
  94. data/lib/chef/provider/user/useradd.rb +20 -22
  95. data/lib/chef/provider/user/windows.rb +19 -22
  96. data/lib/chef/provider_resolver.rb +4 -2
  97. data/lib/chef/providers.rb +1 -0
  98. data/lib/chef/resource.rb +7 -0
  99. data/lib/chef/resource/chocolatey_package.rb +1 -0
  100. data/lib/chef/resource/dnf_package.rb +64 -0
  101. data/lib/chef/resource/file/verification.rb +6 -4
  102. data/lib/chef/resource/yum_package.rb +18 -14
  103. data/lib/chef/resource/yum_repository.rb +1 -1
  104. data/lib/chef/resource_reporter.rb +11 -0
  105. data/lib/chef/resources.rb +1 -0
  106. data/lib/chef/scan_access_control.rb +4 -4
  107. data/lib/chef/util/dsc/resource_store.rb +1 -1
  108. data/lib/chef/version.rb +1 -1
  109. data/lib/chef/win32/memory.rb +1 -1
  110. data/lib/chef/win32/security.rb +2 -2
  111. data/lib/chef/win32/security/sid.rb +2 -2
  112. data/spec/functional/assets/yumrepo/chef_rpm-1.10-1.fc24.i686.rpm +0 -0
  113. data/spec/functional/assets/yumrepo/chef_rpm-1.10-1.fc24.src.rpm +0 -0
  114. data/spec/functional/assets/yumrepo/chef_rpm-1.10-1.fc24.x86_64.rpm +0 -0
  115. data/spec/functional/assets/yumrepo/chef_rpm-1.2-1.fc24.i686.rpm +0 -0
  116. data/spec/functional/assets/yumrepo/chef_rpm-1.2-1.fc24.src.rpm +0 -0
  117. data/spec/functional/assets/yumrepo/chef_rpm-1.2-1.fc24.x86_64.rpm +0 -0
  118. data/spec/functional/assets/yumrepo/repodata/313329137b55fd333b2dc66394a6661a2befa6cc535d8460d92a4a78a9c581f0-primary.sqlite.bz2 +0 -0
  119. data/spec/functional/assets/yumrepo/repodata/31ac4db5d5ac593728fcc26aef82b7b93c4cc4dbec843786b1845b939b658553-other.xml.gz +0 -0
  120. data/spec/functional/assets/yumrepo/repodata/4ac40fa3c6728c1401318e2e20a997436624e83dcf7a5f952b851ef422637773-filelists.sqlite.bz2 +0 -0
  121. data/spec/functional/assets/yumrepo/repodata/66391e53f0510b98b3f0b79f40ba1048026d9a1ef20905d9c40ba6f5411f3243-primary.xml.gz +0 -0
  122. data/spec/functional/assets/yumrepo/repodata/8b34697595fcc87928e12d24644dda9462c3857bd932861e28bc77ae1f31be16-filelists.xml.gz +0 -0
  123. data/spec/functional/assets/yumrepo/repodata/b97cca3fe14bcf06c52be4449b6108f7731239ff221111dcce8aada5467f60dc-other.sqlite.bz2 +0 -0
  124. data/spec/functional/assets/yumrepo/repodata/repomd.xml +55 -0
  125. data/spec/functional/resource/dnf_package_spec.rb +686 -0
  126. data/spec/functional/resource/dsc_script_spec.rb +1 -0
  127. data/spec/functional/resource/user/useradd_spec.rb +10 -1
  128. data/spec/integration/knife/chef_repo_path_spec.rb +2 -2
  129. data/spec/integration/recipes/recipe_dsl_spec.rb +3 -0
  130. data/spec/integration/recipes/resource_load_spec.rb +3 -3
  131. data/spec/spec_helper.rb +5 -3
  132. data/spec/support/lib/chef/provider/snakeoil.rb +1 -0
  133. data/spec/support/lib/chef/resource/cat.rb +1 -0
  134. data/spec/support/lib/chef/resource/one_two_three_four.rb +1 -0
  135. data/spec/support/lib/chef/resource/openldap_includer.rb +2 -0
  136. data/spec/support/lib/chef/resource/with_state.rb +2 -0
  137. data/spec/support/lib/chef/resource/zen_master.rb +1 -0
  138. data/spec/unit/cookbook/metadata_spec.rb +3 -3
  139. data/spec/unit/data_collector/messages/helpers_spec.rb +7 -0
  140. data/spec/unit/data_collector_spec.rb +56 -0
  141. data/spec/unit/decorator/lazy_spec.rb +1 -1
  142. data/spec/unit/environment_spec.rb +1 -1
  143. data/spec/unit/lwrp_spec.rb +3 -4
  144. data/spec/unit/node_spec.rb +23 -2
  145. data/spec/unit/platform_spec.rb +1 -0
  146. data/spec/unit/provider/group/dscl_spec.rb +29 -29
  147. data/spec/unit/provider/group/gpasswd_spec.rb +10 -10
  148. data/spec/unit/provider/group/groupadd_spec.rb +31 -30
  149. data/spec/unit/provider/group/groupmod_spec.rb +16 -16
  150. data/spec/unit/provider/group/pw_spec.rb +11 -11
  151. data/spec/unit/provider/group/suse_spec.rb +5 -5
  152. data/spec/unit/provider/group/usermod_spec.rb +15 -15
  153. data/spec/unit/provider/ifconfig/aix_spec.rb +14 -14
  154. data/spec/unit/provider/ifconfig/debian_spec.rb +10 -22
  155. data/spec/unit/provider/ifconfig/redhat_spec.rb +4 -4
  156. data/spec/unit/provider/ifconfig_spec.rb +18 -19
  157. data/spec/unit/provider/package/chocolatey_spec.rb +21 -21
  158. data/spec/unit/provider/package/msu_spec.rb +1 -1
  159. data/spec/unit/provider/route_spec.rb +21 -21
  160. data/spec/unit/provider/user/dscl_spec.rb +54 -57
  161. data/spec/unit/provider/user/linux_spec.rb +5 -5
  162. data/spec/unit/provider/user/pw_spec.rb +26 -22
  163. data/spec/unit/provider/user/windows_spec.rb +4 -4
  164. data/spec/unit/provider/user_spec.rb +19 -21
  165. data/spec/unit/provider_resolver_spec.rb +1 -0
  166. data/spec/unit/resource/chocolatey_package_spec.rb +12 -0
  167. data/spec/unit/resource/dnf_package_spec.rb +99 -0
  168. data/spec/unit/resource/remote_file_spec.rb +2 -2
  169. data/spec/unit/resource/yum_package_spec.rb +20 -0
  170. data/spec/unit/resource_reporter_spec.rb +24 -0
  171. data/spec/unit/resource_spec.rb +2 -0
  172. data/spec/unit/runner_spec.rb +1 -0
  173. data/tasks/bin/bundle-platform +1 -1
  174. data/tasks/gemfile_util.rb +2 -2
  175. data/tasks/templates/prerelease.md.erb +1 -10
  176. data/tasks/templates/release.md.erb +1 -9
  177. metadata +24 -5
  178. data/lib/chef/platform/handler_map.rb +0 -40
@@ -25,61 +25,56 @@ class Chef
25
25
  provides :ifconfig, platform: %w{aix}
26
26
 
27
27
  def load_current_resource
28
- @current_resource = Chef::Resource::Ifconfig.new(@new_resource.name)
28
+ @current_resource = Chef::Resource::Ifconfig.new(new_resource.name)
29
29
 
30
30
  @interface_exists = false
31
31
  found_interface = false
32
32
  interface = {}
33
33
 
34
- @status = shell_out("ifconfig -a")
34
+ @status = shell_out_compact("ifconfig", "-a")
35
35
  @status.stdout.each_line do |line|
36
36
  if !found_interface
37
37
  if line =~ /^(\S+):\sflags=(\S+)/
38
- # We have interface name, if this is the interface for @current_resource, load info else skip till next interface is found.
39
- if $1 == @new_resource.device
38
+ # We have interface name, if this is the interface for current_resource, load info else skip till next interface is found.
39
+ if Regexp.last_match(1) == new_resource.device
40
40
  # Found interface
41
41
  found_interface = true
42
42
  @interface_exists = true
43
- @current_resource.target(@new_resource.target)
44
- @current_resource.device($1)
45
- interface[:flags] = $2
46
- @current_resource.metric($1) if line =~ /metric\s(\S+)/
47
- end
48
- end
49
- else
50
- # parse interface related information, stop when next interface is found.
51
- if line =~ /^(\S+):\sflags=(\S+)/
52
- # we are done parsing interface info and hit another one, so stop.
53
- found_interface = false
54
- break
55
- else
56
- if found_interface
57
- # read up interface info
58
- @current_resource.inet_addr($1) if line =~ /inet\s(\S+)\s/
59
- @current_resource.bcast($1) if line =~ /broadcast\s(\S+)/
60
- @current_resource.mask(hex_to_dec_netmask($1)) if line =~ /netmask\s(\S+)\s/
43
+ current_resource.target(new_resource.target)
44
+ current_resource.device(Regexp.last_match(1))
45
+ interface[:flags] = Regexp.last_match(2)
46
+ current_resource.metric(Regexp.last_match(1)) if line =~ /metric\s(\S+)/
61
47
  end
62
48
  end
49
+ elsif line =~ /^(\S+):\sflags=(\S+)/
50
+ # we are done parsing interface info and hit another one, so stop.
51
+ found_interface = false
52
+ break
53
+ elsif found_interface
54
+ # read up interface info
55
+ current_resource.inet_addr(Regexp.last_match(1)) if line =~ /inet\s(\S+)\s/
56
+ current_resource.bcast(Regexp.last_match(1)) if line =~ /broadcast\s(\S+)/
57
+ current_resource.mask(hex_to_dec_netmask(Regexp.last_match(1))) if line =~ /netmask\s(\S+)\s/
63
58
  end
64
59
  end
65
60
 
66
- @current_resource
61
+ current_resource
67
62
  end
68
63
 
69
64
  private
70
65
 
71
66
  def add_command
72
67
  # ifconfig changes are temporary, chdev persist across reboots.
73
- raise Chef::Exceptions::Ifconfig, "interface metric attribute cannot be set for :add action" if @new_resource.metric
74
- command = "chdev -l #{@new_resource.device} -a netaddr=#{@new_resource.name}"
75
- command << " -a netmask=#{@new_resource.mask}" if @new_resource.mask
76
- command << " -a mtu=#{@new_resource.mtu}" if @new_resource.mtu
68
+ raise Chef::Exceptions::Ifconfig, "interface metric attribute cannot be set for :add action" if new_resource.metric
69
+ command = [ "chdev", "-l", new_resource.device, "-a", "netaddr=#{new_resource.name}" ]
70
+ command += [ "-a", "netmask=#{new_resource.mask}" ] if new_resource.mask
71
+ command += [ "-a", "mtu=#{new_resource.mtu}" ] if new_resource.mtu
77
72
  command
78
73
  end
79
74
 
80
75
  def delete_command
81
76
  # ifconfig changes are temporary, chdev persist across reboots.
82
- "chdev -l #{@new_resource.device} -a state=down"
77
+ [ "chdev", "-l", new_resource.device, "-a", "state=down" ]
83
78
  end
84
79
 
85
80
  def loopback_device
@@ -26,32 +26,32 @@ class Chef
26
26
  provides :ifconfig, platform: %w{ubuntu}, platform_version: ">= 11.10"
27
27
  provides :ifconfig, platform: %w{debian}, platform_version: ">= 7.0"
28
28
 
29
- INTERFACES_FILE = "/etc/network/interfaces"
30
- INTERFACES_DOT_D_DIR = "/etc/network/interfaces.d"
29
+ INTERFACES_FILE = "/etc/network/interfaces".freeze
30
+ INTERFACES_DOT_D_DIR = "/etc/network/interfaces.d".freeze
31
31
 
32
32
  def initialize(new_resource, run_context)
33
33
  super(new_resource, run_context)
34
34
  @config_template = %{
35
- <% if @new_resource.device %>
36
- <% if @new_resource.onboot == "yes" %>auto <%= @new_resource.device %><% end %>
37
- <% case @new_resource.bootproto
35
+ <% if new_resource.device %>
36
+ <% if new_resource.onboot == "yes" %>auto <%= new_resource.device %><% end %>
37
+ <% case new_resource.bootproto
38
38
  when "dhcp" %>
39
- iface <%= @new_resource.device %> inet dhcp
39
+ iface <%= new_resource.device %> inet dhcp
40
40
  <% when "bootp" %>
41
- iface <%= @new_resource.device %> inet bootp
41
+ iface <%= new_resource.device %> inet bootp
42
42
  <% else %>
43
- iface <%= @new_resource.device %> inet static
44
- <% if @new_resource.target %>address <%= @new_resource.target %><% end %>
45
- <% if @new_resource.mask %>netmask <%= @new_resource.mask %><% end %>
46
- <% if @new_resource.network %>network <%= @new_resource.network %><% end %>
47
- <% if @new_resource.bcast %>broadcast <%= @new_resource.bcast %><% end %>
48
- <% if @new_resource.metric %>metric <%= @new_resource.metric %><% end %>
49
- <% if @new_resource.hwaddr %>hwaddress <%= @new_resource.hwaddr %><% end %>
50
- <% if @new_resource.mtu %>mtu <%= @new_resource.mtu %><% end %>
43
+ iface <%= new_resource.device %> inet static
44
+ <% if new_resource.target %>address <%= new_resource.target %><% end %>
45
+ <% if new_resource.mask %>netmask <%= new_resource.mask %><% end %>
46
+ <% if new_resource.network %>network <%= new_resource.network %><% end %>
47
+ <% if new_resource.bcast %>broadcast <%= new_resource.bcast %><% end %>
48
+ <% if new_resource.metric %>metric <%= new_resource.metric %><% end %>
49
+ <% if new_resource.hwaddr %>hwaddress <%= new_resource.hwaddr %><% end %>
50
+ <% if new_resource.mtu %>mtu <%= new_resource.mtu %><% end %>
51
51
  <% end %>
52
52
  <% end %>
53
53
  }
54
- @config_path = "#{INTERFACES_DOT_D_DIR}/ifcfg-#{@new_resource.device}"
54
+ @config_path = "#{INTERFACES_DOT_D_DIR}/ifcfg-#{new_resource.device}"
55
55
  end
56
56
 
57
57
  def generate_config
@@ -69,12 +69,13 @@ iface <%= @new_resource.device %> inet static
69
69
  # roll our own file_edit resource, this will not get reported until we have a file_edit resource
70
70
  interfaces_dot_d_for_regexp = INTERFACES_DOT_D_DIR.gsub(/\./, '\.') # escape dots for the regexp
71
71
  regexp = %r{^\s*source\s+#{interfaces_dot_d_for_regexp}/\*\s*$}
72
- unless ::File.exists?(INTERFACES_FILE) && regexp.match(IO.read(INTERFACES_FILE))
73
- converge_by("modifying #{INTERFACES_FILE} to source #{INTERFACES_DOT_D_DIR}") do
74
- conf = Chef::Util::FileEdit.new(INTERFACES_FILE)
75
- conf.insert_line_if_no_match(regexp, "source #{INTERFACES_DOT_D_DIR}/*")
76
- conf.write_file
77
- end
72
+
73
+ return if ::File.exist?(INTERFACES_FILE) && regexp.match(IO.read(INTERFACES_FILE))
74
+
75
+ converge_by("modifying #{INTERFACES_FILE} to source #{INTERFACES_DOT_D_DIR}") do
76
+ conf = Chef::Util::FileEdit.new(INTERFACES_FILE)
77
+ conf.insert_line_if_no_match(regexp, "source #{INTERFACES_DOT_D_DIR}/*")
78
+ conf.write_file
78
79
  end
79
80
  end
80
81
 
@@ -27,19 +27,19 @@ class Chef
27
27
  def initialize(new_resource, run_context)
28
28
  super(new_resource, run_context)
29
29
  @config_template = %{
30
- <% if @new_resource.device %>DEVICE=<%= @new_resource.device %><% end %>
31
- <% if @new_resource.onboot == "yes" %>ONBOOT=<%= @new_resource.onboot %><% end %>
32
- <% if @new_resource.bootproto %>BOOTPROTO=<%= @new_resource.bootproto %><% end %>
33
- <% if @new_resource.target %>IPADDR=<%= @new_resource.target %><% end %>
34
- <% if @new_resource.mask %>NETMASK=<%= @new_resource.mask %><% end %>
35
- <% if @new_resource.network %>NETWORK=<%= @new_resource.network %><% end %>
36
- <% if @new_resource.bcast %>BROADCAST=<%= @new_resource.bcast %><% end %>
37
- <% if @new_resource.onparent %>ONPARENT=<%= @new_resource.onparent %><% end %>
38
- <% if @new_resource.hwaddr %>HWADDR=<%= @new_resource.hwaddr %><% end %>
39
- <% if @new_resource.metric %>METRIC=<%= @new_resource.metric %><% end %>
40
- <% if @new_resource.mtu %>MTU=<%= @new_resource.mtu %><% end %>
30
+ <% if new_resource.device %>DEVICE=<%= new_resource.device %><% end %>
31
+ <% if new_resource.onboot == "yes" %>ONBOOT=<%= new_resource.onboot %><% end %>
32
+ <% if new_resource.bootproto %>BOOTPROTO=<%= new_resource.bootproto %><% end %>
33
+ <% if new_resource.target %>IPADDR=<%= new_resource.target %><% end %>
34
+ <% if new_resource.mask %>NETMASK=<%= new_resource.mask %><% end %>
35
+ <% if new_resource.network %>NETWORK=<%= new_resource.network %><% end %>
36
+ <% if new_resource.bcast %>BROADCAST=<%= new_resource.bcast %><% end %>
37
+ <% if new_resource.onparent %>ONPARENT=<%= new_resource.onparent %><% end %>
38
+ <% if new_resource.hwaddr %>HWADDR=<%= new_resource.hwaddr %><% end %>
39
+ <% if new_resource.metric %>METRIC=<%= new_resource.metric %><% end %>
40
+ <% if new_resource.mtu %>MTU=<%= new_resource.mtu %><% end %>
41
41
  }
42
- @config_path = "/etc/sysconfig/network-scripts/ifcfg-#{@new_resource.device}"
42
+ @config_path = "/etc/sysconfig/network-scripts/ifcfg-#{new_resource.device}"
43
43
  end
44
44
 
45
45
  end
@@ -210,7 +210,7 @@ class Chef
210
210
  end
211
211
 
212
212
  def device_real
213
- if @real_device == nil
213
+ if @real_device.nil?
214
214
  if @new_resource.device_type == :device
215
215
  @real_device = @new_resource.device
216
216
  else
@@ -44,8 +44,10 @@ class Chef
44
44
  )
45
45
 
46
46
  @new_profile_hash = get_profile_hash(@new_resource.profile)
47
- @new_profile_hash["PayloadUUID"] =
48
- config_uuid(@new_profile_hash) if @new_profile_hash
47
+ if @new_profile_hash
48
+ @new_profile_hash["PayloadUUID"] =
49
+ config_uuid(@new_profile_hash)
50
+ end
49
51
 
50
52
  if @new_profile_hash
51
53
  @new_profile_identifier = @new_profile_hash["PayloadIdentifier"]
@@ -37,6 +37,9 @@ class Chef
37
37
  subclass_directive :use_multipackage_api
38
38
  # subclasses declare this if they want sources (filenames) pulled from their package names
39
39
  subclass_directive :use_package_name_for_source
40
+ # keeps package_names_for_targets and versions_for_targets indexed the same as package_name at
41
+ # the cost of having the subclass needing to deal with nils
42
+ subclass_directive :allow_nils
40
43
 
41
44
  #
42
45
  # Hook that subclasses use to populate the candidate_version(s)
@@ -56,7 +59,7 @@ class Chef
56
59
  def check_resource_semantics!
57
60
  # FIXME: this is not universally true and subclasses are needing to override this and no-ops it. It should be turned into
58
61
  # another "subclass_directive" and the apt and yum providers should declare that they need this behavior.
59
- if new_resource.package_name.is_a?(Array) && new_resource.source != nil
62
+ if new_resource.package_name.is_a?(Array) && !new_resource.source.nil?
60
63
  raise Chef::Exceptions::InvalidResourceSpecification, "You may not specify both multipackage and source"
61
64
  end
62
65
  end
@@ -196,7 +199,7 @@ class Chef
196
199
  end
197
200
 
198
201
  action :reconfig do
199
- if @current_resource.version == nil
202
+ if @current_resource.version.nil?
200
203
  Chef::Log.debug("#{@new_resource} is NOT installed - nothing to do")
201
204
  return
202
205
  end
@@ -390,9 +393,12 @@ class Chef
390
393
  def package_names_for_targets
391
394
  package_names_for_targets = []
392
395
  target_version_array.each_with_index do |target_version, i|
393
- next if target_version.nil?
394
- package_name = package_name_array[i]
395
- package_names_for_targets.push(package_name)
396
+ if !target_version.nil?
397
+ package_name = package_name_array[i]
398
+ package_names_for_targets.push(package_name)
399
+ else
400
+ package_names_for_targets.push(nil) if allow_nils?
401
+ end
396
402
  end
397
403
  multipackage? ? package_names_for_targets : package_names_for_targets[0]
398
404
  end
@@ -407,8 +413,11 @@ class Chef
407
413
  def versions_for_targets
408
414
  versions_for_targets = []
409
415
  target_version_array.each_with_index do |target_version, i|
410
- next if target_version.nil?
411
- versions_for_targets.push(target_version)
416
+ if !target_version.nil?
417
+ versions_for_targets.push(target_version)
418
+ else
419
+ versions_for_targets.push(nil) if allow_nils?
420
+ end
412
421
  end
413
422
  multipackage? ? versions_for_targets : versions_for_targets[0]
414
423
  end
@@ -169,7 +169,7 @@ EOS
169
169
  # @param args [String] variable number of string arguments
170
170
  # @return [Mixlib::ShellOut] object returned from shell_out!
171
171
  def choco_command(*args)
172
- shell_out_with_timeout!(args_to_string(choco_exe, *args))
172
+ shell_out_with_timeout!(args_to_string(choco_exe, *args), { :returns => new_resource.returns })
173
173
  end
174
174
 
175
175
  # Use the available_packages Hash helper to create an array suitable for
@@ -236,6 +236,7 @@ EOS
236
236
  available[name] = desired_name_versions[name] || raw[name]
237
237
  end
238
238
  end
239
+ @available_packages
239
240
  end
240
241
 
241
242
  # Installed packages in chocolatey as a Hash of names mapped to versions
@@ -244,6 +245,7 @@ EOS
244
245
  # @return [Hash] name-to-version mapping of installed packages
245
246
  def installed_packages
246
247
  @installed_packages ||= Hash[*parse_list_output("list -l -r").flatten]
248
+ @installed_packages
247
249
  end
248
250
 
249
251
  # Helper to convert choco.exe list output to a Hash
@@ -0,0 +1,183 @@
1
+ #
2
+ # Copyright:: Copyright 2016, Chef Software, Inc.
3
+ # License:: Apache License, Version 2.0
4
+ #
5
+ # Licensed under the Apache License, Version 2.0 (the "License");
6
+ # you may not use this file except in compliance with the License.
7
+ # You may obtain a copy of the License at
8
+ #
9
+ # http://www.apache.org/licenses/LICENSE-2.0
10
+ #
11
+ # Unless required by applicable law or agreed to in writing, software
12
+ # distributed under the License is distributed on an "AS IS" BASIS,
13
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14
+ # See the License for the specific language governing permissions and
15
+ # limitations under the License.
16
+ #
17
+
18
+ require "chef/provider/package"
19
+ require "chef/resource/dnf_package"
20
+ require "chef/mixin/which"
21
+ require "chef/mixin/get_source_from_package"
22
+ require "chef/provider/package/dnf/python_helper"
23
+ require "chef/provider/package/dnf/version"
24
+
25
+ class Chef
26
+ class Provider
27
+ class Package
28
+ class Dnf < Chef::Provider::Package
29
+ extend Chef::Mixin::Which
30
+ include Chef::Mixin::GetSourceFromPackage
31
+
32
+ allow_nils
33
+ use_multipackage_api
34
+ use_package_name_for_source
35
+
36
+ provides :package, platform_family: %w{rhel fedora} do
37
+ which("dnf")
38
+ end
39
+
40
+ provides :dnf_package, os: "linux"
41
+
42
+ #
43
+ # Most of the magic in this class happens in the python helper script. The ruby side of this
44
+ # provider knows only enough to translate Chef-style new_resource name+package+version into
45
+ # a request to the python side. The python side is then responsible for knowing everything
46
+ # about RPMs and what is installed and what is available. The ruby side of this class should
47
+ # remain a lightweight translation layer to translate Chef requests into RPC requests to
48
+ # python. This class knows nothing about how to compare RPM versions, and does not maintain
49
+ # any cached state of installed/available versions and should be kept that way.
50
+ #
51
+ def python_helper
52
+ @python_helper ||= PythonHelper.instance
53
+ end
54
+
55
+ def load_current_resource
56
+ flushcache if new_resource.flush_cache[:before]
57
+
58
+ @current_resource = Chef::Resource::DnfPackage.new(new_resource.name)
59
+ current_resource.package_name(new_resource.package_name)
60
+ current_resource.version(get_current_versions)
61
+
62
+ current_resource
63
+ end
64
+
65
+ def define_resource_requirements
66
+ requirements.assert(:install, :upgrade, :remove, :purge) do |a|
67
+ a.assertion { !new_resource.source || ::File.exist?(new_resource.source) }
68
+ a.failure_message Chef::Exceptions::Package, "Package #{new_resource.package_name} not found: #{new_resource.source}"
69
+ a.whyrun "assuming #{new_resource.source} would have previously been created"
70
+ end
71
+
72
+ super
73
+ end
74
+
75
+ def candidate_version
76
+ package_name_array.each_with_index.map do |pkg, i|
77
+ available_version(i).version_with_arch
78
+ end
79
+ end
80
+
81
+ def get_current_versions
82
+ package_name_array.each_with_index.map do |pkg, i|
83
+ installed_version(i).version_with_arch
84
+ end
85
+ end
86
+
87
+ def install_package(names, versions)
88
+ if new_resource.source
89
+ dnf(new_resource.options, "-y install", new_resource.source)
90
+ else
91
+ resolved_names = names.each_with_index.map { |name, i| available_version(i).to_s unless name.nil? }
92
+ dnf(new_resource.options, "-y install", resolved_names)
93
+ end
94
+ flushcache
95
+ end
96
+
97
+ # dnf upgrade does not work on uninstalled packaged, while install will upgrade
98
+ alias_method :upgrade_package, :install_package
99
+
100
+ def remove_package(names, versions)
101
+ resolved_names = names.each_with_index.map { |name, i| installed_version(i).to_s unless name.nil? }
102
+ dnf(new_resource.options, "-y remove", resolved_names)
103
+ flushcache
104
+ end
105
+
106
+ alias_method :purge_package, :remove_package
107
+
108
+ action :flush_cache do
109
+ flushcache
110
+ end
111
+
112
+ private
113
+
114
+ def resolve_source_to_version_obj
115
+ shell_out_with_timeout!("rpm -qp --queryformat '%{NAME} %{EPOCH} %{VERSION} %{RELEASE} %{ARCH}\n' #{new_resource.source}").stdout.each_line do |line|
116
+ # this is another case of committing the sin of doing some lightweight mangling of RPM versions in ruby -- but the output of the rpm command
117
+ # does not match what the dnf library accepts.
118
+ case line
119
+ when /^(\S+)\s+(\S+)\s+(\S+)\s+(\S+)\s+(\S+)$/
120
+ return Version.new($1, "#{$2 == "(none)" ? "0" : $2}:#{$3}-#{$4}", $5)
121
+ end
122
+ end
123
+ end
124
+
125
+ # @returns Array<Version>
126
+ def available_version(index)
127
+ @available_version ||= []
128
+
129
+ if new_resource.source
130
+ @available_version[index] ||= resolve_source_to_version_obj
131
+ else
132
+ @available_version[index] ||= python_helper.query(:whatavailable, package_name_array[index], safe_version_array[index], safe_arch_array[index])
133
+ end
134
+
135
+ @available_version[index]
136
+ end
137
+
138
+ # @returns Array<Version>
139
+ def installed_version(index)
140
+ @installed_version ||= []
141
+ if new_resource.source
142
+ @installed_version[index] ||= python_helper.query(:whatinstalled, available_version(index).name, safe_version_array[index], safe_arch_array[index])
143
+ else
144
+ @installed_version[index] ||= python_helper.query(:whatinstalled, package_name_array[index], safe_version_array[index], safe_arch_array[index])
145
+ end
146
+ @installed_version[index]
147
+ end
148
+
149
+ # cache flushing is accomplished by simply restarting the python helper. this produces a roughly
150
+ # 15% hit to the runtime of installing/removing/upgrading packages. correctly using multipackage
151
+ # array installs (and the multipackage cookbook) can produce 600% improvements in runtime.
152
+ def flushcache
153
+ python_helper.restart
154
+ end
155
+
156
+ def dnf(*args)
157
+ shell_out_with_timeout!(a_to_s("dnf", *args))
158
+ end
159
+
160
+ def safe_version_array
161
+ if new_resource.version.is_a?(Array)
162
+ new_resource.version
163
+ elsif new_resource.version.nil?
164
+ package_name_array.map { nil }
165
+ else
166
+ [ new_resource.version ]
167
+ end
168
+ end
169
+
170
+ def safe_arch_array
171
+ if new_resource.arch.is_a?(Array)
172
+ new_resource.arch
173
+ elsif new_resource.arch.nil?
174
+ package_name_array.map { nil }
175
+ else
176
+ [ new_resource.arch ]
177
+ end
178
+ end
179
+
180
+ end
181
+ end
182
+ end
183
+ end