summaryrefslogtreecommitdiff
path: root/lib/chef/provider
diff options
context:
space:
mode:
authormarkgibbons <mark.gibbons@nordstrom.com>2017-02-06 07:45:14 -0800
committermarkgibbons <mark.gibbons@nordstrom.com>2017-02-06 07:45:14 -0800
commit87e4d14ccb06053cf2837f5df1f629ae37f6e956 (patch)
treec320961ca9d052a39c852c102d12ff2a30b68f17 /lib/chef/provider
parent86713023f8c1f2f0ccc4c96aeb7e43c4ffb10aeb (diff)
parent58f73322224ecbb363468b81e9169a344ee3f5cf (diff)
downloadchef-87e4d14ccb06053cf2837f5df1f629ae37f6e956.tar.gz
Merge branch 'master' of https://github.com/chef/chef into smf_recursive_dependencies
Diffstat (limited to 'lib/chef/provider')
-rw-r--r--lib/chef/provider/directory.rb2
-rw-r--r--lib/chef/provider/dsc_resource.rb18
-rw-r--r--lib/chef/provider/env/windows.rb2
-rw-r--r--lib/chef/provider/file.rb2
-rw-r--r--lib/chef/provider/git.rb2
-rw-r--r--lib/chef/provider/group.rb87
-rw-r--r--lib/chef/provider/group/aix.rb31
-rw-r--r--lib/chef/provider/group/dscl.rb89
-rw-r--r--lib/chef/provider/group/gpasswd.rb14
-rw-r--r--lib/chef/provider/group/groupadd.rb63
-rw-r--r--lib/chef/provider/group/groupmod.rb57
-rw-r--r--lib/chef/provider/group/pw.rb59
-rw-r--r--lib/chef/provider/group/suse.rb18
-rw-r--r--lib/chef/provider/group/usermod.rb21
-rw-r--r--lib/chef/provider/group/windows.rb38
-rw-r--r--lib/chef/provider/ifconfig.rb115
-rw-r--r--lib/chef/provider/ifconfig/aix.rb51
-rw-r--r--lib/chef/provider/ifconfig/debian.rb45
-rw-r--r--lib/chef/provider/ifconfig/redhat.rb24
-rw-r--r--lib/chef/provider/launchd.rb2
-rw-r--r--lib/chef/provider/link.rb6
-rw-r--r--lib/chef/provider/mount.rb2
-rw-r--r--lib/chef/provider/mount/mount.rb4
-rw-r--r--lib/chef/provider/ohai.rb8
-rw-r--r--lib/chef/provider/osx_profile.rb6
-rw-r--r--lib/chef/provider/package.rb23
-rw-r--r--lib/chef/provider/package/aix.rb59
-rw-r--r--lib/chef/provider/package/cab.rb44
-rw-r--r--lib/chef/provider/package/chocolatey.rb8
-rw-r--r--lib/chef/provider/package/dnf.rb183
-rw-r--r--lib/chef/provider/package/dnf/dnf_helper.py91
-rw-r--r--lib/chef/provider/package/dnf/python_helper.rb120
-rw-r--r--lib/chef/provider/package/dnf/version.rb56
-rw-r--r--lib/chef/provider/package/easy_install.rb6
-rw-r--r--lib/chef/provider/package/freebsd/base.rb2
-rw-r--r--lib/chef/provider/package/freebsd/pkgng.rb2
-rw-r--r--lib/chef/provider/package/ips.rb2
-rw-r--r--lib/chef/provider/package/msu.rb162
-rw-r--r--lib/chef/provider/package/powershell.rb6
-rw-r--r--lib/chef/provider/package/windows.rb2
-rw-r--r--lib/chef/provider/package/yum.rb2
-rw-r--r--lib/chef/provider/package/zypper.rb2
-rw-r--r--lib/chef/provider/route.rb370
-rw-r--r--lib/chef/provider/service/arch.rb4
-rw-r--r--lib/chef/provider/service/freebsd.rb2
-rw-r--r--lib/chef/provider/service/gentoo.rb4
-rw-r--r--lib/chef/provider/service/insserv.rb4
-rw-r--r--lib/chef/provider/service/macosx.rb4
-rw-r--r--lib/chef/provider/service/openbsd.rb2
-rw-r--r--lib/chef/provider/service/redhat.rb4
-rw-r--r--lib/chef/provider/support/yum_repo.erb13
-rw-r--r--lib/chef/provider/systemd_unit.rb2
-rw-r--r--lib/chef/provider/user.rb37
-rw-r--r--lib/chef/provider/user/aix.rb47
-rw-r--r--lib/chef/provider/user/dscl.rb109
-rw-r--r--lib/chef/provider/user/linux.rb29
-rw-r--r--lib/chef/provider/user/pw.rb56
-rw-r--r--lib/chef/provider/user/solaris.rb23
-rw-r--r--lib/chef/provider/user/useradd.rb42
-rw-r--r--lib/chef/provider/user/windows.rb41
60 files changed, 1485 insertions, 844 deletions
diff --git a/lib/chef/provider/directory.rb b/lib/chef/provider/directory.rb
index 619ab5d8b6..1cacc3fcb9 100644
--- a/lib/chef/provider/directory.rb
+++ b/lib/chef/provider/directory.rb
@@ -138,7 +138,7 @@ class Chef
end
do_acl_changes
do_selinux(true)
- load_resource_attributes_from_file(@new_resource)
+ load_resource_attributes_from_file(@new_resource) unless Chef::Config[:why_run]
end
def action_delete
diff --git a/lib/chef/provider/dsc_resource.rb b/lib/chef/provider/dsc_resource.rb
index 0f25065925..026d2ef104 100644
--- a/lib/chef/provider/dsc_resource.rb
+++ b/lib/chef/provider/dsc_resource.rb
@@ -29,6 +29,7 @@ class Chef
super
@new_resource = new_resource
@module_name = new_resource.module_name
+ @module_version = new_resource.module_version
@reboot_resource = nil
end
@@ -65,6 +66,13 @@ class Chef
a.whyrun err + ["Assuming a previous resource sets the RefreshMode."]
a.block_action!
end
+ requirements.assert(:run) do |a|
+ a.assertion { module_usage_valid? }
+ err = ["module_name must be supplied along with module_version."]
+ a.failure_message Chef::Exceptions::DSCModuleNameMissing,
+ err
+ a.block_action!
+ end
end
protected
@@ -92,6 +100,10 @@ class Chef
Chef::Platform.supports_refresh_mode_enabled?(node)
end
+ def module_usage_valid?
+ !(!@module_name && @module_version)
+ end
+
def generate_description
@converge_description
end
@@ -148,10 +160,14 @@ class Chef
end
end
+ def module_info_object
+ @module_version.nil? ? module_name : "@{ModuleName='#{module_name}';ModuleVersion='#{@module_version}'}"
+ end
+
def invoke_resource(method, output_format = :object)
properties = translate_type(@new_resource.properties)
switches = "-Method #{method} -Name #{@new_resource.resource}"\
- " -Property #{properties} -Module #{module_name} -Verbose"
+ " -Property #{properties} -Module #{module_info_object} -Verbose"
cmdlet = Chef::Util::Powershell::Cmdlet.new(
node,
"Invoke-DscResource #{switches}",
diff --git a/lib/chef/provider/env/windows.rb b/lib/chef/provider/env/windows.rb
index a68c8276e0..a217590af5 100644
--- a/lib/chef/provider/env/windows.rb
+++ b/lib/chef/provider/env/windows.rb
@@ -36,7 +36,7 @@ class Chef
obj.variablevalue = @new_resource.value
obj.put_
value = @new_resource.value
- value = expand_path(value) if @new_resource.key_name.casecmp("PATH").zero?
+ value = expand_path(value) if @new_resource.key_name.casecmp("PATH") == 0
ENV[@new_resource.key_name] = value
broadcast_env_change
end
diff --git a/lib/chef/provider/file.rb b/lib/chef/provider/file.rb
index 84bb4d1c94..f77986fa03 100644
--- a/lib/chef/provider/file.rb
+++ b/lib/chef/provider/file.rb
@@ -154,7 +154,7 @@ class Chef
do_contents_changes
do_acl_changes
do_selinux
- load_resource_attributes_from_file(@new_resource)
+ load_resource_attributes_from_file(@new_resource) unless Chef::Config[:why_run]
end
def action_create_if_missing
diff --git a/lib/chef/provider/git.rb b/lib/chef/provider/git.rb
index d051bb1d92..a5c5e0d267 100644
--- a/lib/chef/provider/git.rb
+++ b/lib/chef/provider/git.rb
@@ -65,7 +65,7 @@ class Chef
# this can't be recovered from in why-run mode, because nothing that
# we do in the course of a run is likely to create a valid target_revision
# if we can't resolve it up front.
- a.assertion { target_revision != nil }
+ a.assertion { !target_revision.nil? }
a.failure_message Chef::Exceptions::UnresolvableGitReference,
"Unable to parse SHA reference for '#{@new_resource.revision}' in repository '#{@new_resource.repository}'. " +
"Verify your (case-sensitive) repository URL and revision.\n" +
diff --git a/lib/chef/provider/group.rb b/lib/chef/provider/group.rb
index 8936bd2031..6751052ae4 100644
--- a/lib/chef/provider/group.rb
+++ b/lib/chef/provider/group.rb
@@ -39,38 +39,38 @@ class Chef
end
def load_current_resource
- @current_resource = Chef::Resource::Group.new(@new_resource.name)
- @current_resource.group_name(@new_resource.group_name)
+ @current_resource = Chef::Resource::Group.new(new_resource.name)
+ current_resource.group_name(new_resource.group_name)
group_info = nil
begin
- group_info = Etc.getgrnam(@new_resource.group_name)
- rescue ArgumentError => e
+ group_info = Etc.getgrnam(new_resource.group_name)
+ rescue ArgumentError
@group_exists = false
- Chef::Log.debug("#{@new_resource} group does not exist")
+ Chef::Log.debug("#{new_resource} group does not exist")
end
if group_info
- @new_resource.gid(group_info.gid) unless @new_resource.gid
- @current_resource.gid(group_info.gid)
- @current_resource.members(group_info.mem)
+ new_resource.gid(group_info.gid) unless new_resource.gid
+ current_resource.gid(group_info.gid)
+ current_resource.members(group_info.mem)
end
- @current_resource
+ current_resource
end
def define_resource_requirements
requirements.assert(:modify) do |a|
a.assertion { @group_exists }
- a.failure_message(Chef::Exceptions::Group, "Cannot modify #{@new_resource} - group does not exist!")
- a.whyrun("Group #{@new_resource} does not exist. Unless it would have been created earlier in this run, this attempt to modify it would fail.")
+ a.failure_message(Chef::Exceptions::Group, "Cannot modify #{new_resource} - group does not exist!")
+ a.whyrun("Group #{new_resource} does not exist. Unless it would have been created earlier in this run, this attempt to modify it would fail.")
end
requirements.assert(:all_actions) do |a|
# Make sure that the resource doesn't contain any common
# user names in the members and exclude_members properties.
- if !@new_resource.members.nil? && !@new_resource.excluded_members.nil?
- common_members = @new_resource.members & @new_resource.excluded_members
+ if !new_resource.members.nil? && !new_resource.excluded_members.nil?
+ common_members = new_resource.members & new_resource.excluded_members
a.assertion { common_members.empty? }
a.failure_message(Chef::Exceptions::ConflictingMembersInGroup, "Attempting to both add and remove users from a group: '#{common_members.join(', ')}'")
# No why-run alternative
@@ -86,41 +86,39 @@ class Chef
# <false>:: If a change is not required
def compare_group
@change_desc = [ ]
- if @new_resource.gid.to_s != @current_resource.gid.to_s
- @change_desc << "change gid #{@current_resource.gid} to #{@new_resource.gid}"
+ if new_resource.gid.to_s != current_resource.gid.to_s
+ @change_desc << "change gid #{current_resource.gid} to #{new_resource.gid}"
end
- if @new_resource.append
+ if new_resource.append
missing_members = []
- @new_resource.members.each do |member|
+ new_resource.members.each do |member|
next if has_current_group_member?(member)
validate_member!(member)
missing_members << member
end
- if missing_members.length > 0
- @change_desc << "add missing member(s): #{missing_members.join(", ")}"
+ unless missing_members.empty?
+ @change_desc << "add missing member(s): #{missing_members.join(', ')}"
end
members_to_be_removed = []
- @new_resource.excluded_members.each do |member|
+ new_resource.excluded_members.each do |member|
if has_current_group_member?(member)
members_to_be_removed << member
end
end
- if members_to_be_removed.length > 0
- @change_desc << "remove existing member(s): #{members_to_be_removed.join(", ")}"
- end
- else
- if @new_resource.members != @current_resource.members
- @change_desc << "replace group members with new list of members"
+ unless members_to_be_removed.empty?
+ @change_desc << "remove existing member(s): #{members_to_be_removed.join(', ')}"
end
+ elsif new_resource.members != current_resource.members
+ @change_desc << "replace group members with new list of members"
end
!@change_desc.empty?
end
def has_current_group_member?(member)
- @current_resource.members.include?(member)
+ current_resource.members.include?(member)
end
def validate_member!(member)
@@ -132,44 +130,41 @@ class Chef
def action_create
case @group_exists
when false
- converge_by("create group #{@new_resource.group_name}") do
+ converge_by("create group #{new_resource.group_name}") do
create_group
- Chef::Log.info("#{@new_resource} created")
+ Chef::Log.info("#{new_resource} created")
end
else
if compare_group
- converge_by(["alter group #{@new_resource.group_name}"] + change_desc) do
+ converge_by(["alter group #{new_resource.group_name}"] + change_desc) do
manage_group
- Chef::Log.info("#{@new_resource} altered")
+ Chef::Log.info("#{new_resource} altered")
end
end
end
end
def action_remove
- if @group_exists
- converge_by("remove group #{@new_resource.group_name}") do
- remove_group
- Chef::Log.info("#{@new_resource} removed")
- end
+ return unless @group_exists
+ converge_by("remove group #{new_resource.group_name}") do
+ remove_group
+ Chef::Log.info("#{new_resource} removed")
end
end
def action_manage
- if @group_exists && compare_group
- converge_by(["manage group #{@new_resource.group_name}"] + change_desc) do
- manage_group
- Chef::Log.info("#{@new_resource} managed")
- end
+ return unless @group_exists && compare_group
+ converge_by(["manage group #{new_resource.group_name}"] + change_desc) do
+ manage_group
+ Chef::Log.info("#{new_resource} managed")
end
end
def action_modify
- if compare_group
- converge_by(["modify group #{@new_resource.group_name}"] + change_desc) do
- manage_group
- Chef::Log.info("#{@new_resource} modified")
- end
+ return unless compare_group
+ converge_by(["modify group #{new_resource.group_name}"] + change_desc) do
+ manage_group
+ Chef::Log.info("#{new_resource} modified")
end
end
diff --git a/lib/chef/provider/group/aix.rb b/lib/chef/provider/group/aix.rb
index 4a02d5ef8c..2db6dc32a7 100644
--- a/lib/chef/provider/group/aix.rb
+++ b/lib/chef/provider/group/aix.rb
@@ -17,7 +17,6 @@
#
require "chef/provider/group/groupadd"
-require "chef/mixin/shell_out"
class Chef
class Provider
@@ -33,48 +32,42 @@ class Chef
end
def create_group
- command = "mkgroup"
- command << set_options << " #{@new_resource.group_name}"
- run_command(:command => command)
+ shell_out_compact!("mkgroup", set_options, new_resource.group_name)
modify_group_members
end
def manage_group
- command = "chgroup"
options = set_options
- #Usage: chgroup [-R load_module] "attr=value" ... group
if options.size > 0
- command << options << " #{@new_resource.group_name}"
- run_command(:command => command)
+ shell_out_compact!("chgroup", options, new_resource.group_name)
end
modify_group_members
end
def remove_group
- run_command(:command => "rmgroup #{@new_resource.group_name}")
+ shell_out_compact!("rmgroup", new_resource.group_name)
end
def add_member(member)
- shell_out!("chgrpmem -m + #{member} #{@new_resource.group_name}")
+ shell_out_compact!("chgrpmem", "-m", "+", member, new_resource.group_name)
end
def set_members(members)
return if members.empty?
- shell_out!("chgrpmem -m = #{members.join(',')} #{@new_resource.group_name}")
+ shell_out_compact!("chgrpmem", "-m", "=", members.join(","), new_resource.group_name)
end
def remove_member(member)
- shell_out!("chgrpmem -m - #{member} #{@new_resource.group_name}")
+ shell_out_compact!("chgrpmem", "-m", "-", member, new_resource.group_name)
end
def set_options
- opts = ""
- { :gid => "id" }.sort { |a, b| a[0] <=> b[0] }.each do |field, option|
- if @current_resource.send(field) != @new_resource.send(field)
- if @new_resource.send(field)
- Chef::Log.debug("#{@new_resource} setting #{field} to #{@new_resource.send(field)}")
- opts << " '#{option}=#{@new_resource.send(field)}'"
- end
+ opts = []
+ { gid: "id" }.sort { |a, b| a[0] <=> b[0] }.each do |field, option|
+ next unless current_resource.send(field) != new_resource.send(field)
+ if new_resource.send(field)
+ Chef::Log.debug("#{new_resource} setting #{field} to #{new_resource.send(field)}")
+ opts << "#{option}=#{new_resource.send(field)}"
end
end
opts
diff --git a/lib/chef/provider/group/dscl.rb b/lib/chef/provider/group/dscl.rb
index 00b4ce2b93..71e42b36ba 100644
--- a/lib/chef/provider/group/dscl.rb
+++ b/lib/chef/provider/group/dscl.rb
@@ -24,12 +24,15 @@ class Chef
provides :group, os: "darwin"
def dscl(*args)
- host = "."
- stdout_result = ""; stderr_result = ""; cmd = "dscl #{host} -#{args.join(' ')}"
- status = shell_out(cmd)
+ argdup = args.dup
+ cmd = argdup.shift
+ shellcmd = [ "dscl", ".", "-#{cmd}", argdup ]
+ status = shell_out_compact(shellcmd)
+ stdout_result = ""
+ stderr_result = ""
status.stdout.each_line { |line| stdout_result << line }
status.stderr.each_line { |line| stderr_result << line }
- return [cmd, status, stdout_result, stderr_result]
+ [shellcmd.flatten.compact.join(" "), status, stdout_result, stderr_result]
end
def safe_dscl(*args)
@@ -37,18 +40,18 @@ class Chef
return "" if ( args.first =~ /^delete/ ) && ( result[1].exitstatus != 0 )
raise(Chef::Exceptions::Group, "dscl error: #{result.inspect}") unless result[1].exitstatus == 0
raise(Chef::Exceptions::Group, "dscl error: #{result.inspect}") if result[2] =~ /No such key: /
- return result[2]
+ result[2]
end
def load_current_resource
- @current_resource = Chef::Resource::Group.new(@new_resource.name)
- @current_resource.group_name(@new_resource.group_name)
+ @current_resource = Chef::Resource::Group.new(new_resource.name)
+ current_resource.group_name(new_resource.group_name)
group_info = nil
begin
- group_info = safe_dscl("read /Groups/#{@new_resource.group_name}")
+ group_info = safe_dscl("read", "/Groups/#{new_resource.group_name}")
rescue Chef::Exceptions::Group
@group_exists = false
- Chef::Log.debug("#{@new_resource} group does not exist")
+ Chef::Log.debug("#{new_resource} group does not exist")
end
if group_info
@@ -57,21 +60,21 @@ class Chef
val.strip! if val
case key.downcase
when "primarygroupid"
- @new_resource.gid(val) unless @new_resource.gid
- @current_resource.gid(val)
+ new_resource.gid(val) unless new_resource.gid
+ current_resource.gid(val)
when "groupmembership"
- @current_resource.members(val.split(" "))
+ current_resource.members(val.split(" "))
end
end
end
- @current_resource
+ current_resource
end
# get a free GID greater than 200
def get_free_gid(search_limit = 1000)
gid = nil; next_gid_guess = 200
- groups_gids = safe_dscl("list /Groups gid")
+ groups_gids = safe_dscl("list", "/Groups", "gid")
while next_gid_guess < search_limit + 200
if groups_gids =~ Regexp.new("#{Regexp.escape(next_gid_guess.to_s)}\n")
next_gid_guess += 1
@@ -80,51 +83,51 @@ class Chef
break
end
end
- return gid || raise("gid not found. Exhausted. Searched #{search_limit} times")
+ gid || raise("gid not found. Exhausted. Searched #{search_limit} times")
end
def gid_used?(gid)
return false unless gid
- groups_gids = safe_dscl("list /Groups gid")
- !! ( groups_gids =~ Regexp.new("#{Regexp.escape(gid.to_s)}\n") )
+ groups_gids = safe_dscl("list", "/Groups", "gid")
+ !!( groups_gids =~ Regexp.new("#{Regexp.escape(gid.to_s)}\n") )
end
def set_gid
- @new_resource.gid(get_free_gid) if [nil, ""].include? @new_resource.gid
- raise(Chef::Exceptions::Group, "gid is already in use") if gid_used?(@new_resource.gid)
- safe_dscl("create /Groups/#{@new_resource.group_name} PrimaryGroupID #{@new_resource.gid}")
+ new_resource.gid(get_free_gid) if [nil, ""].include? new_resource.gid
+ raise(Chef::Exceptions::Group, "gid is already in use") if gid_used?(new_resource.gid)
+ safe_dscl("create", "/Groups/#{new_resource.group_name}", "PrimaryGroupID", new_resource.gid)
end
def set_members
# First reset the memberships if the append is not set
- unless @new_resource.append
- Chef::Log.debug("#{@new_resource} removing group members #{@current_resource.members.join(' ')}") unless @current_resource.members.empty?
- safe_dscl("create /Groups/#{@new_resource.group_name} GroupMembers ''") # clear guid list
- safe_dscl("create /Groups/#{@new_resource.group_name} GroupMembership ''") # clear user list
- @current_resource.members([ ])
+ unless new_resource.append
+ Chef::Log.debug("#{new_resource} removing group members #{current_resource.members.join(' ')}") unless current_resource.members.empty?
+ safe_dscl("create", "/Groups/#{new_resource.group_name}", "GroupMembers", "") # clear guid list
+ safe_dscl("create", "/Groups/#{new_resource.group_name}", "GroupMembership", "") # clear user list
+ current_resource.members([ ])
end
# Add any members that need to be added
- if @new_resource.members && !@new_resource.members.empty?
+ if new_resource.members && !new_resource.members.empty?
members_to_be_added = [ ]
- @new_resource.members.each do |member|
- members_to_be_added << member if !@current_resource.members.include?(member)
+ new_resource.members.each do |member|
+ members_to_be_added << member unless current_resource.members.include?(member)
end
unless members_to_be_added.empty?
- Chef::Log.debug("#{@new_resource} setting group members #{members_to_be_added.join(', ')}")
- safe_dscl("append /Groups/#{@new_resource.group_name} GroupMembership #{members_to_be_added.join(' ')}")
+ Chef::Log.debug("#{new_resource} setting group members #{members_to_be_added.join(', ')}")
+ safe_dscl("append", "/Groups/#{new_resource.group_name}", "GroupMembership", *members_to_be_added)
end
end
# Remove any members that need to be removed
- if @new_resource.excluded_members && !@new_resource.excluded_members.empty?
+ if new_resource.excluded_members && !new_resource.excluded_members.empty?
members_to_be_removed = [ ]
- @new_resource.excluded_members.each do |member|
- members_to_be_removed << member if @current_resource.members.include?(member)
+ new_resource.excluded_members.each do |member|
+ members_to_be_removed << member if current_resource.members.include?(member)
end
unless members_to_be_removed.empty?
- Chef::Log.debug("#{@new_resource} removing group members #{members_to_be_removed.join(', ')}")
- safe_dscl("delete /Groups/#{@new_resource.group_name} GroupMembership #{members_to_be_removed.join(' ')}")
+ Chef::Log.debug("#{new_resource} removing group members #{members_to_be_removed.join(', ')}")
+ safe_dscl("delete", "/Groups/#{new_resource.group_name}", "GroupMembership", *members_to_be_removed)
end
end
end
@@ -132,8 +135,8 @@ class Chef
def define_resource_requirements
super
requirements.assert(:all_actions) do |a|
- a.assertion { ::File.exists?("/usr/bin/dscl") }
- a.failure_message Chef::Exceptions::Group, "Could not find binary /usr/bin/dscl for #{@new_resource.name}"
+ a.assertion { ::File.exist?("/usr/bin/dscl") }
+ a.failure_message Chef::Exceptions::Group, "Could not find binary /usr/bin/dscl for #{new_resource.name}"
# No whyrun alternative: this component should be available in the base install of any given system that uses it
end
end
@@ -145,24 +148,24 @@ class Chef
end
def manage_group
- if @new_resource.group_name && (@current_resource.group_name != @new_resource.group_name)
+ if new_resource.group_name && (current_resource.group_name != new_resource.group_name)
dscl_create_group
end
- if @new_resource.gid && (@current_resource.gid != @new_resource.gid)
+ if new_resource.gid && (current_resource.gid != new_resource.gid)
set_gid
end
- if @new_resource.members || @new_resource.excluded_members
+ if new_resource.members || new_resource.excluded_members
set_members
end
end
def dscl_create_group
- safe_dscl("create /Groups/#{@new_resource.group_name}")
- safe_dscl("create /Groups/#{@new_resource.group_name} Password '*'")
+ safe_dscl("create", "/Groups/#{new_resource.group_name}")
+ safe_dscl("create", "/Groups/#{new_resource.group_name}", "Password", "*")
end
def remove_group
- safe_dscl("delete /Groups/#{@new_resource.group_name}")
+ safe_dscl("delete", "/Groups/#{new_resource.group_name}")
end
end
end
diff --git a/lib/chef/provider/group/gpasswd.rb b/lib/chef/provider/group/gpasswd.rb
index dcf526b211..d8aff10d5b 100644
--- a/lib/chef/provider/group/gpasswd.rb
+++ b/lib/chef/provider/group/gpasswd.rb
@@ -31,26 +31,26 @@ class Chef
def define_resource_requirements
super
requirements.assert(:all_actions) do |a|
- a.assertion { ::File.exists?("/usr/bin/gpasswd") }
- a.failure_message Chef::Exceptions::Group, "Could not find binary /usr/bin/gpasswd for #{@new_resource}"
+ a.assertion { ::File.exist?("/usr/bin/gpasswd") }
+ a.failure_message Chef::Exceptions::Group, "Could not find binary /usr/bin/gpasswd for #{new_resource}"
# No whyrun alternative: this component should be available in the base install of any given system that uses it
end
end
def set_members(members)
- unless members.empty?
- shell_out!("gpasswd -M #{members.join(',')} #{@new_resource.group_name}")
+ if members.empty?
+ shell_out_compact!("gpasswd", "-M", "", new_resource.group_name)
else
- shell_out!("gpasswd -M \"\" #{@new_resource.group_name}")
+ shell_out_compact!("gpasswd", "-M", members.join(","), new_resource.group_name)
end
end
def add_member(member)
- shell_out!("gpasswd -a #{member} #{@new_resource.group_name}")
+ shell_out_compact!("gpasswd", "-a", member, new_resource.group_name)
end
def remove_member(member)
- shell_out!("gpasswd -d #{member} #{@new_resource.group_name}")
+ shell_out_compact!("gpasswd", "-d", member, new_resource.group_name)
end
end
end
diff --git a/lib/chef/provider/group/groupadd.rb b/lib/chef/provider/group/groupadd.rb
index 162875f9f1..f73c3b3be9 100644
--- a/lib/chef/provider/group/groupadd.rb
+++ b/lib/chef/provider/group/groupadd.rb
@@ -35,8 +35,8 @@ class Chef
super
required_binaries.each do |required_binary|
requirements.assert(:all_actions) do |a|
- a.assertion { ::File.exists?(required_binary) }
- a.failure_message Chef::Exceptions::Group, "Could not find binary #{required_binary} for #{@new_resource}"
+ a.assertion { ::File.exist?(required_binary) }
+ a.failure_message Chef::Exceptions::Group, "Could not find binary #{required_binary} for #{new_resource}"
# No whyrun alternative: this component should be available in the base install of any given system that uses it
end
end
@@ -44,54 +44,49 @@ class Chef
# Create the group
def create_group
- command = "groupadd"
- command << set_options
- command << groupadd_options
- run_command(:command => command)
+ shell_out_compact!("groupadd", set_options, groupadd_options)
modify_group_members
end
# Manage the group when it already exists
def manage_group
- command = "groupmod"
- command << set_options
- run_command(:command => command)
+ shell_out_compact!("groupmod", set_options)
modify_group_members
end
# Remove the group
def remove_group
- run_command(:command => "groupdel #{@new_resource.group_name}")
+ shell_out_compact!("groupdel", new_resource.group_name)
end
def modify_group_members
- if @new_resource.append
- if @new_resource.members && !@new_resource.members.empty?
+ if new_resource.append
+ if new_resource.members && !new_resource.members.empty?
members_to_be_added = [ ]
- @new_resource.members.each do |member|
- members_to_be_added << member if !@current_resource.members.include?(member)
+ new_resource.members.each do |member|
+ members_to_be_added << member unless current_resource.members.include?(member)
end
members_to_be_added.each do |member|
- Chef::Log.debug("#{@new_resource} appending member #{member} to group #{@new_resource.group_name}")
+ Chef::Log.debug("#{new_resource} appending member #{member} to group #{new_resource.group_name}")
add_member(member)
end
end
- if @new_resource.excluded_members && !@new_resource.excluded_members.empty?
+ if new_resource.excluded_members && !new_resource.excluded_members.empty?
members_to_be_removed = [ ]
- @new_resource.excluded_members.each do |member|
- members_to_be_removed << member if @current_resource.members.include?(member)
+ new_resource.excluded_members.each do |member|
+ members_to_be_removed << member if current_resource.members.include?(member)
end
members_to_be_removed.each do |member|
- Chef::Log.debug("#{@new_resource} removing member #{member} from group #{@new_resource.group_name}")
+ Chef::Log.debug("#{new_resource} removing member #{member} from group #{new_resource.group_name}")
remove_member(member)
end
end
else
- members_description = @new_resource.members.empty? ? "none" : @new_resource.members.join(", ")
- Chef::Log.debug("#{@new_resource} setting group members to: #{members_description}")
- set_members(@new_resource.members)
+ members_description = new_resource.members.empty? ? "none" : new_resource.members.join(", ")
+ Chef::Log.debug("#{new_resource} setting group members to: #{members_description}")
+ set_members(new_resource.members)
end
end
@@ -112,23 +107,23 @@ class Chef
# ==== Returns
# <string>:: A string containing the option and then the quoted value
def set_options
- opts = ""
- { :gid => "-g" }.sort { |a, b| a[0] <=> b[0] }.each do |field, option|
- if @current_resource.send(field) != @new_resource.send(field)
- if @new_resource.send(field)
- opts << " #{option} '#{@new_resource.send(field)}'"
- Chef::Log.debug("#{@new_resource} set #{field} to #{@new_resource.send(field)}")
- end
- end
+ opts = []
+ { gid: "-g" }.sort { |a, b| a[0] <=> b[0] }.each do |field, option|
+ next unless current_resource.send(field) != new_resource.send(field)
+ next unless new_resource.send(field)
+ opts << option
+ opts << new_resource.send(field)
+ Chef::Log.debug("#{new_resource} set #{field} to #{new_resource.send(field)}")
end
- opts << " #{@new_resource.group_name}"
+ opts << new_resource.group_name
+ opts
end
def groupadd_options
- opts = ""
+ opts = []
# Solaris doesn't support system groups.
- opts << " -r" if @new_resource.system && !node.platform?("solaris2")
- opts << " -o" if @new_resource.non_unique
+ opts << "-r" if new_resource.system && !node.platform?("solaris2")
+ opts << "-o" if new_resource.non_unique
opts
end
diff --git a/lib/chef/provider/group/groupmod.rb b/lib/chef/provider/group/groupmod.rb
index 295d3b3425..01581e4863 100644
--- a/lib/chef/provider/group/groupmod.rb
+++ b/lib/chef/provider/group/groupmod.rb
@@ -26,28 +26,26 @@ class Chef
def load_current_resource
super
%w{group user}.each do |binary|
- raise Chef::Exceptions::Group, "Could not find binary /usr/sbin/#{binary} for #{@new_resource}" unless ::File.exists?("/usr/sbin/#{binary}")
+ raise Chef::Exceptions::Group, "Could not find binary /usr/sbin/#{binary} for #{new_resource}" unless ::File.exist?("/usr/sbin/#{binary}")
end
end
# Create the group
def create_group
- command = "group add"
- command << set_options
- shell_out!(command)
+ shell_out_compact!("group", "add", set_options)
- add_group_members(@new_resource.members)
+ add_group_members(new_resource.members)
end
# Manage the group when it already exists
def manage_group
- if @new_resource.append
+ if new_resource.append
members_to_be_added = [ ]
- if @new_resource.excluded_members && !@new_resource.excluded_members.empty?
+ if new_resource.excluded_members && !new_resource.excluded_members.empty?
# First find out if any member needs to be removed
members_to_be_removed = [ ]
- @new_resource.excluded_members.each do |member|
- members_to_be_removed << member if @current_resource.members.include?(member)
+ new_resource.excluded_members.each do |member|
+ members_to_be_removed << member if current_resource.members.include?(member)
end
unless members_to_be_removed.empty?
@@ -56,39 +54,39 @@ class Chef
# Capture the members we need to add in
# members_to_be_added to be added later on.
- @current_resource.members.each do |member|
+ current_resource.members.each do |member|
members_to_be_added << member unless members_to_be_removed.include?(member)
end
end
end
- if @new_resource.members && !@new_resource.members.empty?
- @new_resource.members.each do |member|
- members_to_be_added << member if !@current_resource.members.include?(member)
+ if new_resource.members && !new_resource.members.empty?
+ new_resource.members.each do |member|
+ members_to_be_added << member unless current_resource.members.include?(member)
end
end
- Chef::Log.debug("#{@new_resource} not changing group members, the group has no members to add") if members_to_be_added.empty?
+ Chef::Log.debug("#{new_resource} not changing group members, the group has no members to add") if members_to_be_added.empty?
add_group_members(members_to_be_added)
else
# We are resetting the members of a group so use the same trick
reset_group_membership
- Chef::Log.debug("#{@new_resource} setting group members to: none") if @new_resource.members.empty?
- add_group_members(@new_resource.members)
+ Chef::Log.debug("#{new_resource} setting group members to: none") if new_resource.members.empty?
+ add_group_members(new_resource.members)
end
end
# Remove the group
def remove_group
- shell_out!("group del #{@new_resource.group_name}")
+ shell_out_compact!("group", "del", new_resource.group_name)
end
# Adds a list of usernames to the group using `user mod`
def add_group_members(members)
- Chef::Log.debug("#{@new_resource} adding members #{members.join(', ')}") if !members.empty?
+ Chef::Log.debug("#{new_resource} adding members #{members.join(', ')}") unless members.empty?
members.each do |user|
- shell_out!("user mod -G #{@new_resource.group_name} #{user}")
+ shell_out_compact!("user", "mod", "-G", new_resource.group_name, user)
end
end
@@ -96,15 +94,11 @@ class Chef
# "<name>_bak", create a new group with the same GID and
# "<name>", then set correct members on that group
def reset_group_membership
- rename = "group mod -n #{@new_resource.group_name}_bak #{@new_resource.group_name}"
- shell_out!(rename)
+ shell_out_compact!("group", "mod", "-n", "#{new_resource.group_name}_bak", new_resource.group_name)
- create = "group add"
- create << set_options(:overwrite_gid => true)
- shell_out!(create)
+ shell_out_compact!("group", "add", set_options(overwrite_gid: true))
- remove = "group del #{@new_resource.group_name}_bak"
- shell_out!(remove)
+ shell_out_compact!("group", "del", "#{new_resource.group_name}_bak")
end
# Little bit of magic as per Adam's useradd provider to pull and assign the command line flags
@@ -112,14 +106,15 @@ class Chef
# ==== Returns
# <string>:: A string containing the option and then the quoted value
def set_options(overwrite_gid = false)
- opts = ""
- if overwrite_gid || @new_resource.gid && (@current_resource.gid != @new_resource.gid)
- opts << " -g '#{@new_resource.gid}'"
+ opts = []
+ if overwrite_gid || new_resource.gid && (current_resource.gid != new_resource.gid)
+ opts << "-g"
+ opts << new_resource.gid
end
if overwrite_gid
- opts << " -o"
+ opts << "-o"
end
- opts << " #{@new_resource.group_name}"
+ opts << new_resource.group_name
opts
end
end
diff --git a/lib/chef/provider/group/pw.rb b/lib/chef/provider/group/pw.rb
index 4fd78b6b31..115ccf3714 100644
--- a/lib/chef/provider/group/pw.rb
+++ b/lib/chef/provider/group/pw.rb
@@ -30,46 +30,42 @@ class Chef
super
requirements.assert(:all_actions) do |a|
- a.assertion { ::File.exists?("/usr/sbin/pw") }
- a.failure_message Chef::Exceptions::Group, "Could not find binary /usr/sbin/pw for #{@new_resource}"
+ a.assertion { ::File.exist?("/usr/sbin/pw") }
+ a.failure_message Chef::Exceptions::Group, "Could not find binary /usr/sbin/pw for #{new_resource}"
# No whyrun alternative: this component should be available in the base install of any given system that uses it
end
end
# Create the group
def create_group
- command = "pw groupadd"
- command << set_options
-
- unless @new_resource.members.empty?
+ command = [ "pw", "groupadd", set_options ]
+ unless new_resource.members.empty?
# pw group[add|mod] -M is used to set the full membership list on a
# new or existing group. Because pw groupadd does not support the -m
# and -d options used by manage_group, we treat group creation as a
# special case and use -M.
- Chef::Log.debug("#{@new_resource} setting group members: #{@new_resource.members.join(',')}")
- command += " -M #{@new_resource.members.join(',')}"
+ Chef::Log.debug("#{new_resource} setting group members: #{new_resource.members.join(',')}")
+ command += [ "-M", new_resource.members.join(",") ]
end
- run_command(:command => command)
+ shell_out_compact!(command)
end
# Manage the group when it already exists
def manage_group
- command = "pw groupmod"
- command << set_options
member_options = set_members_options
if member_options.empty?
- run_command(:command => command)
+ shell_out_compact!("pw", "groupmod", set_options)
else
member_options.each do |option|
- run_command(:command => command + option)
+ shell_out_compact!("pw", "groupmod", set_options, option)
end
end
end
# Remove the group
def remove_group
- run_command(:command => "pw groupdel #{@new_resource.group_name}")
+ shell_out_compact!("pw", "groupdel", new_resource.group_name)
end
# Little bit of magic as per Adam's useradd provider to pull and assign the command line flags
@@ -77,10 +73,11 @@ class Chef
# ==== Returns
# <string>:: A string containing the option and then the quoted value
def set_options
- opts = " #{@new_resource.group_name}"
- if @new_resource.gid && (@current_resource.gid != @new_resource.gid)
- Chef::Log.debug("#{@new_resource}: current gid (#{@current_resource.gid}) doesnt match target gid (#{@new_resource.gid}), changing it")
- opts << " -g '#{@new_resource.gid}'"
+ opts = [ new_resource.group_name ]
+ if new_resource.gid && (current_resource.gid != new_resource.gid)
+ Chef::Log.debug("#{new_resource}: current gid (#{current_resource.gid}) doesnt match target gid (#{new_resource.gid}), changing it")
+ opts << "-g"
+ opts << new_resource.gid
end
opts
end
@@ -91,26 +88,26 @@ class Chef
members_to_be_added = [ ]
members_to_be_removed = [ ]
- if @new_resource.append
+ if new_resource.append
# Append is set so we will only add members given in the
# members list and remove members given in the
# excluded_members list.
- if @new_resource.members && !@new_resource.members.empty?
- @new_resource.members.each do |member|
- members_to_be_added << member if !@current_resource.members.include?(member)
+ if new_resource.members && !new_resource.members.empty?
+ new_resource.members.each do |member|
+ members_to_be_added << member unless current_resource.members.include?(member)
end
end
- if @new_resource.excluded_members && !@new_resource.excluded_members.empty?
- @new_resource.excluded_members.each do |member|
- members_to_be_removed << member if @current_resource.members.include?(member)
+ if new_resource.excluded_members && !new_resource.excluded_members.empty?
+ new_resource.excluded_members.each do |member|
+ members_to_be_removed << member if current_resource.members.include?(member)
end
end
else
# Append is not set so we're resetting the membership of
# the group to the given members.
- members_to_be_added = @new_resource.members.dup
- @current_resource.members.each do |member|
+ members_to_be_added = new_resource.members.dup
+ current_resource.members.each do |member|
# No need to re-add a member if it's present in the new
# list of members
if members_to_be_added.include? member
@@ -122,13 +119,13 @@ class Chef
end
unless members_to_be_added.empty?
- Chef::Log.debug("#{@new_resource} adding group members: #{members_to_be_added.join(',')}")
- opts << " -m #{members_to_be_added.join(',')}"
+ Chef::Log.debug("#{new_resource} adding group members: #{members_to_be_added.join(',')}")
+ opts << [ "-m", members_to_be_added.join(",") ]
end
unless members_to_be_removed.empty?
- Chef::Log.debug("#{@new_resource} removing group members: #{members_to_be_removed.join(',')}")
- opts << " -d #{members_to_be_removed.join(',')}"
+ Chef::Log.debug("#{new_resource} removing group members: #{members_to_be_removed.join(',')}")
+ opts << [ "-d", members_to_be_removed.join(",") ]
end
opts
diff --git a/lib/chef/provider/group/suse.rb b/lib/chef/provider/group/suse.rb
index 71336f9311..0790d2c2d9 100644
--- a/lib/chef/provider/group/suse.rb
+++ b/lib/chef/provider/group/suse.rb
@@ -33,21 +33,21 @@ class Chef
def define_resource_requirements
super
requirements.assert(:all_actions) do |a|
- a.assertion { ::File.exists?("/usr/sbin/groupmod") }
- a.failure_message Chef::Exceptions::Group, "Could not find binary /usr/sbin/groupmod for #{@new_resource.name}"
+ a.assertion { ::File.exist?("/usr/sbin/groupmod") }
+ a.failure_message Chef::Exceptions::Group, "Could not find binary /usr/sbin/groupmod for #{new_resource.name}"
# No whyrun alternative: this component should be available in the base install of any given system that uses it
end
requirements.assert(:create, :manage, :modify) do |a|
a.assertion do
begin
- to_add(@new_resource.members).all? { |member| Etc.getpwnam(member) }
+ to_add(new_resource.members).all? { |member| Etc.getpwnam(member) }
rescue
false
end
end
- a.failure_message Chef::Exceptions::Group, "Could not add users #{to_add(@new_resource.members).join(", ")} to #{@new_resource.group_name}: one of these users does not exist"
- a.whyrun "Could not find one of these users: #{to_add(@new_resource.members).join(", ")}. Assuming it will be created by a prior step"
+ a.failure_message Chef::Exceptions::Group, "Could not add users #{to_add(new_resource.members).join(', ')} to #{new_resource.group_name}: one of these users does not exist"
+ a.whyrun "Could not find one of these users: #{to_add(new_resource.members).join(', ')}. Assuming it will be created by a prior step"
end
end
@@ -62,19 +62,19 @@ class Chef
end
def to_add(members)
- members - @current_resource.members
+ members - current_resource.members
end
def add_member(member)
- shell_out!("groupmod -A #{member} #{@new_resource.group_name}")
+ shell_out_compact!("groupmod", "-A", member, new_resource.group_name)
end
def to_remove(members)
- @current_resource.members - members
+ current_resource.members - members
end
def remove_member(member)
- shell_out!("groupmod -R #{member} #{@new_resource.group_name}")
+ shell_out_compact!("groupmod", "-R", member, new_resource.group_name)
end
end
diff --git a/lib/chef/provider/group/usermod.rb b/lib/chef/provider/group/usermod.rb
index bef4b667a2..3874f7b4de 100644
--- a/lib/chef/provider/group/usermod.rb
+++ b/lib/chef/provider/group/usermod.rb
@@ -34,19 +34,19 @@ class Chef
super
requirements.assert(:all_actions) do |a|
- a.assertion { ::File.exists?("/usr/sbin/usermod") }
- a.failure_message Chef::Exceptions::Group, "Could not find binary /usr/sbin/usermod for #{@new_resource}"
+ a.assertion { ::File.exist?("/usr/sbin/usermod") }
+ a.failure_message Chef::Exceptions::Group, "Could not find binary /usr/sbin/usermod for #{new_resource}"
# No whyrun alternative: this component should be available in the base install of any given system that uses it
end
requirements.assert(:modify, :manage) do |a|
- a.assertion { @new_resource.members.empty? || @new_resource.append }
+ a.assertion { new_resource.members.empty? || new_resource.append }
a.failure_message Chef::Exceptions::Group, "setting group members directly is not supported by #{self}, must set append true in group"
# No whyrun alternative - this action is simply not supported.
end
requirements.assert(:all_actions) do |a|
- a.assertion { @new_resource.excluded_members.empty? }
+ a.assertion { new_resource.excluded_members.empty? }
a.failure_message Chef::Exceptions::Group, "excluded_members is not supported by #{self}"
# No whyrun alternative - this action is simply not supported.
end
@@ -57,17 +57,16 @@ class Chef
# This provider only supports adding members with
# append. Only if the action is create we will go
# ahead and add members.
- if @new_resource.action.include?(:create)
- members.each do |member|
- add_member(member)
- end
- else
+ unless new_resource.action.include?(:create)
raise Chef::Exceptions::UnsupportedAction, "Setting members directly is not supported by #{self}"
end
+ members.each do |member|
+ add_member(member)
+ end
end
def add_member(member)
- shell_out!("usermod #{append_flags} #{@new_resource.group_name} #{member}")
+ shell_out_compact!("usermod", append_flags, new_resource.group_name, member)
end
def remove_member(member)
@@ -81,7 +80,7 @@ class Chef
when "openbsd", "netbsd", "aix", "solaris2", "smartos", "omnios"
"-G"
when "solaris", "suse", "opensuse"
- "-a -G"
+ [ "-a", "-G" ]
end
end
diff --git a/lib/chef/provider/group/windows.rb b/lib/chef/provider/group/windows.rb
index 5873e42a6b..c0026bf368 100644
--- a/lib/chef/provider/group/windows.rb
+++ b/lib/chef/provider/group/windows.rb
@@ -30,26 +30,26 @@ class Chef
def initialize(new_resource, run_context)
super
- @net_group = Chef::Util::Windows::NetGroup.new(@new_resource.group_name)
+ @net_group = Chef::Util::Windows::NetGroup.new(new_resource.group_name)
end
def load_current_resource
- @current_resource = Chef::Resource::Group.new(@new_resource.name)
- @current_resource.group_name(@new_resource.group_name)
+ @current_resource = Chef::Resource::Group.new(new_resource.name)
+ current_resource.group_name(new_resource.group_name)
members = nil
begin
members = @net_group.local_get_members
- rescue => e
+ rescue
@group_exists = false
- Chef::Log.debug("#{@new_resource} group does not exist")
+ Chef::Log.debug("#{new_resource} group does not exist")
end
if members
- @current_resource.members(members)
+ current_resource.members(members)
end
- @current_resource
+ current_resource
end
def create_group
@@ -58,10 +58,10 @@ class Chef
end
def manage_group
- if @new_resource.append
+ if new_resource.append
members_to_be_added = [ ]
- @new_resource.members.each do |member|
- members_to_be_added << member if ! has_current_group_member?(member) && validate_member!(member)
+ new_resource.members.each do |member|
+ members_to_be_added << member if !has_current_group_member?(member) && validate_member!(member)
end
# local_add_members will raise ERROR_MEMBER_IN_ALIAS if a
@@ -69,19 +69,19 @@ class Chef
@net_group.local_add_members(members_to_be_added) unless members_to_be_added.empty?
members_to_be_removed = [ ]
- @new_resource.excluded_members.each do |member|
- member_sid = lookup_account_name(member)
+ new_resource.excluded_members.each do |member|
+ lookup_account_name(member)
members_to_be_removed << member if has_current_group_member?(member)
end
@net_group.local_delete_members(members_to_be_removed) unless members_to_be_removed.empty?
else
- @net_group.local_set_members(@new_resource.members)
+ @net_group.local_set_members(new_resource.members)
end
end
def has_current_group_member?(member)
member_sid = lookup_account_name(member)
- @current_resource.members.include?(member_sid)
+ current_resource.members.include?(member_sid)
end
def remove_group
@@ -97,12 +97,10 @@ class Chef
end
def lookup_account_name(account_name)
- begin
- Chef::ReservedNames::Win32::Security.lookup_account_name(locally_qualified_name(account_name))[1].to_s
- rescue Chef::Exceptions::Win32APIError
- Chef::Log.warn("SID for '#{locally_qualified_name(account_name)}' could not be found")
- ""
- end
+ Chef::ReservedNames::Win32::Security.lookup_account_name(locally_qualified_name(account_name))[1].to_s
+ rescue Chef::Exceptions::Win32APIError
+ Chef::Log.warn("SID for '#{locally_qualified_name(account_name)}' could not be found")
+ ""
end
end
diff --git a/lib/chef/provider/ifconfig.rb b/lib/chef/provider/ifconfig.rb
index 4cfb257bb9..4f32baaadb 100644
--- a/lib/chef/provider/ifconfig.rb
+++ b/lib/chef/provider/ifconfig.rb
@@ -58,7 +58,7 @@ class Chef
end
def load_current_resource
- @current_resource = Chef::Resource::Ifconfig.new(@new_resource.name)
+ @current_resource = Chef::Resource::Ifconfig.new(new_resource.name)
@ifconfig_success = true
@interfaces = {}
@@ -69,27 +69,26 @@ class Chef
@int_name = line[0..9].strip
@interfaces[@int_name] = { "hwaddr" => (line =~ /(HWaddr)/ ? ($') : "nil").strip.chomp }
else
- @interfaces[@int_name]["inet_addr"] = (line =~ /inet addr:(\S+)/ ? ($1) : "nil") if line =~ /inet addr:/
- @interfaces[@int_name]["bcast"] = (line =~ /Bcast:(\S+)/ ? ($1) : "nil") if line =~ /Bcast:/
- @interfaces[@int_name]["mask"] = (line =~ /Mask:(\S+)/ ? ($1) : "nil") if line =~ /Mask:/
- @interfaces[@int_name]["mtu"] = (line =~ /MTU:(\S+)/ ? ($1) : "nil") if line =~ /MTU:/
- @interfaces[@int_name]["metric"] = (line =~ /Metric:(\S+)/ ? ($1) : "nil") if line =~ /Metric:/
+ @interfaces[@int_name]["inet_addr"] = (line =~ /inet addr:(\S+)/ ? Regexp.last_match(1) : "nil") if line =~ /inet addr:/
+ @interfaces[@int_name]["bcast"] = (line =~ /Bcast:(\S+)/ ? Regexp.last_match(1) : "nil") if line =~ /Bcast:/
+ @interfaces[@int_name]["mask"] = (line =~ /Mask:(\S+)/ ? Regexp.last_match(1) : "nil") if line =~ /Mask:/
+ @interfaces[@int_name]["mtu"] = (line =~ /MTU:(\S+)/ ? Regexp.last_match(1) : "nil") if line =~ /MTU:/
+ @interfaces[@int_name]["metric"] = (line =~ /Metric:(\S+)/ ? Regexp.last_match(1) : "nil") if line =~ /Metric:/
end
- if @interfaces.has_key?(@new_resource.device)
- @interface = @interfaces.fetch(@new_resource.device)
-
- @current_resource.target(@new_resource.target)
- @current_resource.device(@new_resource.device)
- @current_resource.inet_addr(@interface["inet_addr"])
- @current_resource.hwaddr(@interface["hwaddr"])
- @current_resource.bcast(@interface["bcast"])
- @current_resource.mask(@interface["mask"])
- @current_resource.mtu(@interface["mtu"])
- @current_resource.metric(@interface["metric"])
- end
+ next unless @interfaces.key?(new_resource.device)
+ @interface = @interfaces.fetch(new_resource.device)
+
+ current_resource.target(new_resource.target)
+ current_resource.device(new_resource.device)
+ current_resource.inet_addr(@interface["inet_addr"])
+ current_resource.hwaddr(@interface["hwaddr"])
+ current_resource.bcast(@interface["bcast"])
+ current_resource.mask(@interface["mask"])
+ current_resource.mtu(@interface["mtu"])
+ current_resource.metric(@interface["metric"])
end
- @current_resource
+ current_resource
end
def define_resource_requirements
@@ -104,14 +103,12 @@ class Chef
def action_add
# check to see if load_current_resource found interface in ifconfig
- unless @current_resource.inet_addr
- unless @new_resource.device == loopback_device
+ unless current_resource.inet_addr
+ unless new_resource.device == loopback_device
command = add_command
- converge_by ("run #{command} to add #{@new_resource}") do
- run_command(
- :command => command
- )
- Chef::Log.info("#{@new_resource} added")
+ converge_by("run #{command.join(' ')} to add #{new_resource}") do
+ shell_out_compact!(command)
+ Chef::Log.info("#{new_resource} added")
end
end
end
@@ -122,31 +119,25 @@ class Chef
def action_enable
# check to see if load_current_resource found ifconfig
# enables, but does not manage config files
- unless @current_resource.inet_addr
- unless @new_resource.device == loopback_device
- command = enable_command
- converge_by ("run #{command} to enable #{@new_resource}") do
- run_command(
- :command => command
- )
- Chef::Log.info("#{@new_resource} enabled")
- end
- end
+ return if current_resource.inet_addr
+ return if new_resource.device == loopback_device
+ command = enable_command
+ converge_by("run #{command.join(' ')} to enable #{new_resource}") do
+ shell_out_compact!(command)
+ Chef::Log.info("#{new_resource} enabled")
end
end
def action_delete
# check to see if load_current_resource found the interface
- if @current_resource.device
+ if current_resource.device
command = delete_command
- converge_by ("run #{command} to delete #{@new_resource}") do
- run_command(
- :command => command
- )
- Chef::Log.info("#{@new_resource} deleted")
+ converge_by("run #{command.join(' ')} to delete #{new_resource}") do
+ shell_out_compact!(command)
+ Chef::Log.info("#{new_resource} deleted")
end
else
- Chef::Log.debug("#{@new_resource} does not exist - nothing to do")
+ Chef::Log.debug("#{new_resource} does not exist - nothing to do")
end
delete_config
end
@@ -154,21 +145,19 @@ class Chef
def action_disable
# check to see if load_current_resource found the interface
# disables, but leaves config files in place.
- if @current_resource.device
+ if current_resource.device
command = disable_command
- converge_by ("run #{command} to disable #{@new_resource}") do
- run_command(
- :command => command
- )
- Chef::Log.info("#{@new_resource} disabled")
+ converge_by("run #{command.join(' ')} to disable #{new_resource}") do
+ shell_out_compact!(command)
+ Chef::Log.info("#{new_resource} disabled")
end
else
- Chef::Log.debug("#{@new_resource} does not exist - nothing to do")
+ Chef::Log.debug("#{new_resource} does not exist - nothing to do")
end
end
def can_generate_config?
- ! @config_template.nil? && ! @config_path.nil?
+ !@config_template.nil? && !@config_path.nil?
end
def resource_for_config(path)
@@ -182,40 +171,40 @@ class Chef
config = resource_for_config(@config_path)
config.content(template.result(b))
config.run_action(:create)
- @new_resource.updated_by_last_action(true) if config.updated?
+ new_resource.updated_by_last_action(true) if config.updated?
end
def delete_config
return unless can_generate_config?
config = resource_for_config(@config_path)
config.run_action(:delete)
- @new_resource.updated_by_last_action(true) if config.updated?
+ new_resource.updated_by_last_action(true) if config.updated?
end
private
def add_command
- command = "ifconfig #{@new_resource.device} #{@new_resource.target}"
- command << " netmask #{@new_resource.mask}" if @new_resource.mask
- command << " metric #{@new_resource.metric}" if @new_resource.metric
- command << " mtu #{@new_resource.mtu}" if @new_resource.mtu
+ command = [ "ifconfig", new_resource.device, new_resource.target ]
+ command += [ "netmask", new_resource.mask ] if new_resource.mask
+ command += [ "metric", new_resource.metric ] if new_resource.metric
+ command += [ "mtu", new_resource.mtu ] if new_resource.mtu
command
end
def enable_command
- command = "ifconfig #{@new_resource.device} #{@new_resource.target}"
- command << " netmask #{@new_resource.mask}" if @new_resource.mask
- command << " metric #{@new_resource.metric}" if @new_resource.metric
- command << " mtu #{@new_resource.mtu}" if @new_resource.mtu
+ command = [ "ifconfig", new_resource.device, new_resource.target ]
+ command += [ "netmask", new_resource.mask ] if new_resource.mask
+ command += [ "metric", new_resource.metric ] if new_resource.metric
+ command += [ "mtu", new_resource.mtu ] if new_resource.mtu
command
end
def disable_command
- "ifconfig #{@new_resource.device} down"
+ [ "ifconfig", new_resource.device, "down" ]
end
def delete_command
- "ifconfig #{@new_resource.device} down"
+ [ "ifconfig", new_resource.device, "down" ]
end
def loopback_device
diff --git a/lib/chef/provider/ifconfig/aix.rb b/lib/chef/provider/ifconfig/aix.rb
index 81164db304..788b609fcf 100644
--- a/lib/chef/provider/ifconfig/aix.rb
+++ b/lib/chef/provider/ifconfig/aix.rb
@@ -25,61 +25,56 @@ class Chef
provides :ifconfig, platform: %w{aix}
def load_current_resource
- @current_resource = Chef::Resource::Ifconfig.new(@new_resource.name)
+ @current_resource = Chef::Resource::Ifconfig.new(new_resource.name)
@interface_exists = false
found_interface = false
interface = {}
- @status = shell_out("ifconfig -a")
+ @status = shell_out_compact("ifconfig", "-a")
@status.stdout.each_line do |line|
if !found_interface
if line =~ /^(\S+):\sflags=(\S+)/
- # We have interface name, if this is the interface for @current_resource, load info else skip till next interface is found.
- if $1 == @new_resource.device
+ # We have interface name, if this is the interface for current_resource, load info else skip till next interface is found.
+ if Regexp.last_match(1) == new_resource.device
# Found interface
found_interface = true
@interface_exists = true
- @current_resource.target(@new_resource.target)
- @current_resource.device($1)
- interface[:flags] = $2
- @current_resource.metric($1) if line =~ /metric\s(\S+)/
- end
- end
- else
- # parse interface related information, stop when next interface is found.
- if line =~ /^(\S+):\sflags=(\S+)/
- # we are done parsing interface info and hit another one, so stop.
- found_interface = false
- break
- else
- if found_interface
- # read up interface info
- @current_resource.inet_addr($1) if line =~ /inet\s(\S+)\s/
- @current_resource.bcast($1) if line =~ /broadcast\s(\S+)/
- @current_resource.mask(hex_to_dec_netmask($1)) if line =~ /netmask\s(\S+)\s/
+ current_resource.target(new_resource.target)
+ current_resource.device(Regexp.last_match(1))
+ interface[:flags] = Regexp.last_match(2)
+ current_resource.metric(Regexp.last_match(1)) if line =~ /metric\s(\S+)/
end
end
+ elsif line =~ /^(\S+):\sflags=(\S+)/
+ # we are done parsing interface info and hit another one, so stop.
+ found_interface = false
+ break
+ elsif found_interface
+ # read up interface info
+ current_resource.inet_addr(Regexp.last_match(1)) if line =~ /inet\s(\S+)\s/
+ current_resource.bcast(Regexp.last_match(1)) if line =~ /broadcast\s(\S+)/
+ current_resource.mask(hex_to_dec_netmask(Regexp.last_match(1))) if line =~ /netmask\s(\S+)\s/
end
end
- @current_resource
+ current_resource
end
private
def add_command
# ifconfig changes are temporary, chdev persist across reboots.
- raise Chef::Exceptions::Ifconfig, "interface metric attribute cannot be set for :add action" if @new_resource.metric
- command = "chdev -l #{@new_resource.device} -a netaddr=#{@new_resource.name}"
- command << " -a netmask=#{@new_resource.mask}" if @new_resource.mask
- command << " -a mtu=#{@new_resource.mtu}" if @new_resource.mtu
+ raise Chef::Exceptions::Ifconfig, "interface metric attribute cannot be set for :add action" if new_resource.metric
+ command = [ "chdev", "-l", new_resource.device, "-a", "netaddr=#{new_resource.name}" ]
+ command += [ "-a", "netmask=#{new_resource.mask}" ] if new_resource.mask
+ command += [ "-a", "mtu=#{new_resource.mtu}" ] if new_resource.mtu
command
end
def delete_command
# ifconfig changes are temporary, chdev persist across reboots.
- "chdev -l #{@new_resource.device} -a state=down"
+ [ "chdev", "-l", new_resource.device, "-a", "state=down" ]
end
def loopback_device
diff --git a/lib/chef/provider/ifconfig/debian.rb b/lib/chef/provider/ifconfig/debian.rb
index 872b0db152..369c222b7a 100644
--- a/lib/chef/provider/ifconfig/debian.rb
+++ b/lib/chef/provider/ifconfig/debian.rb
@@ -26,32 +26,32 @@ class Chef
provides :ifconfig, platform: %w{ubuntu}, platform_version: ">= 11.10"
provides :ifconfig, platform: %w{debian}, platform_version: ">= 7.0"
- INTERFACES_FILE = "/etc/network/interfaces"
- INTERFACES_DOT_D_DIR = "/etc/network/interfaces.d"
+ INTERFACES_FILE = "/etc/network/interfaces".freeze
+ INTERFACES_DOT_D_DIR = "/etc/network/interfaces.d".freeze
def initialize(new_resource, run_context)
super(new_resource, run_context)
@config_template = %{
-<% if @new_resource.device %>
-<% if @new_resource.onboot == "yes" %>auto <%= @new_resource.device %><% end %>
-<% case @new_resource.bootproto
+<% if new_resource.device %>
+<% if new_resource.onboot == "yes" %>auto <%= new_resource.device %><% end %>
+<% case new_resource.bootproto
when "dhcp" %>
-iface <%= @new_resource.device %> inet dhcp
+iface <%= new_resource.device %> inet dhcp
<% when "bootp" %>
-iface <%= @new_resource.device %> inet bootp
+iface <%= new_resource.device %> inet bootp
<% else %>
-iface <%= @new_resource.device %> inet static
- <% if @new_resource.target %>address <%= @new_resource.target %><% end %>
- <% if @new_resource.mask %>netmask <%= @new_resource.mask %><% end %>
- <% if @new_resource.network %>network <%= @new_resource.network %><% end %>
- <% if @new_resource.bcast %>broadcast <%= @new_resource.bcast %><% end %>
- <% if @new_resource.metric %>metric <%= @new_resource.metric %><% end %>
- <% if @new_resource.hwaddr %>hwaddress <%= @new_resource.hwaddr %><% end %>
- <% if @new_resource.mtu %>mtu <%= @new_resource.mtu %><% end %>
+iface <%= new_resource.device %> inet static
+ <% if new_resource.target %>address <%= new_resource.target %><% end %>
+ <% if new_resource.mask %>netmask <%= new_resource.mask %><% end %>
+ <% if new_resource.network %>network <%= new_resource.network %><% end %>
+ <% if new_resource.bcast %>broadcast <%= new_resource.bcast %><% end %>
+ <% if new_resource.metric %>metric <%= new_resource.metric %><% end %>
+ <% if new_resource.hwaddr %>hwaddress <%= new_resource.hwaddr %><% end %>
+ <% if new_resource.mtu %>mtu <%= new_resource.mtu %><% end %>
<% end %>
<% end %>
}
- @config_path = "#{INTERFACES_DOT_D_DIR}/ifcfg-#{@new_resource.device}"
+ @config_path = "#{INTERFACES_DOT_D_DIR}/ifcfg-#{new_resource.device}"
end
def generate_config
@@ -69,12 +69,13 @@ iface <%= @new_resource.device %> inet static
# roll our own file_edit resource, this will not get reported until we have a file_edit resource
interfaces_dot_d_for_regexp = INTERFACES_DOT_D_DIR.gsub(/\./, '\.') # escape dots for the regexp
regexp = %r{^\s*source\s+#{interfaces_dot_d_for_regexp}/\*\s*$}
- unless ::File.exists?(INTERFACES_FILE) && regexp.match(IO.read(INTERFACES_FILE))
- converge_by("modifying #{INTERFACES_FILE} to source #{INTERFACES_DOT_D_DIR}") do
- conf = Chef::Util::FileEdit.new(INTERFACES_FILE)
- conf.insert_line_if_no_match(regexp, "source #{INTERFACES_DOT_D_DIR}/*")
- conf.write_file
- end
+
+ return if ::File.exist?(INTERFACES_FILE) && regexp.match(IO.read(INTERFACES_FILE))
+
+ converge_by("modifying #{INTERFACES_FILE} to source #{INTERFACES_DOT_D_DIR}") do
+ conf = Chef::Util::FileEdit.new(INTERFACES_FILE)
+ conf.insert_line_if_no_match(regexp, "source #{INTERFACES_DOT_D_DIR}/*")
+ conf.write_file
end
end
diff --git a/lib/chef/provider/ifconfig/redhat.rb b/lib/chef/provider/ifconfig/redhat.rb
index 0c28e6407a..841e725b94 100644
--- a/lib/chef/provider/ifconfig/redhat.rb
+++ b/lib/chef/provider/ifconfig/redhat.rb
@@ -27,19 +27,19 @@ class Chef
def initialize(new_resource, run_context)
super(new_resource, run_context)
@config_template = %{
-<% if @new_resource.device %>DEVICE=<%= @new_resource.device %><% end %>
-<% if @new_resource.onboot == "yes" %>ONBOOT=<%= @new_resource.onboot %><% end %>
-<% if @new_resource.bootproto %>BOOTPROTO=<%= @new_resource.bootproto %><% end %>
-<% if @new_resource.target %>IPADDR=<%= @new_resource.target %><% end %>
-<% if @new_resource.mask %>NETMASK=<%= @new_resource.mask %><% end %>
-<% if @new_resource.network %>NETWORK=<%= @new_resource.network %><% end %>
-<% if @new_resource.bcast %>BROADCAST=<%= @new_resource.bcast %><% end %>
-<% if @new_resource.onparent %>ONPARENT=<%= @new_resource.onparent %><% end %>
-<% if @new_resource.hwaddr %>HWADDR=<%= @new_resource.hwaddr %><% end %>
-<% if @new_resource.metric %>METRIC=<%= @new_resource.metric %><% end %>
-<% if @new_resource.mtu %>MTU=<%= @new_resource.mtu %><% end %>
+<% if new_resource.device %>DEVICE=<%= new_resource.device %><% end %>
+<% if new_resource.onboot == "yes" %>ONBOOT=<%= new_resource.onboot %><% end %>
+<% if new_resource.bootproto %>BOOTPROTO=<%= new_resource.bootproto %><% end %>
+<% if new_resource.target %>IPADDR=<%= new_resource.target %><% end %>
+<% if new_resource.mask %>NETMASK=<%= new_resource.mask %><% end %>
+<% if new_resource.network %>NETWORK=<%= new_resource.network %><% end %>
+<% if new_resource.bcast %>BROADCAST=<%= new_resource.bcast %><% end %>
+<% if new_resource.onparent %>ONPARENT=<%= new_resource.onparent %><% end %>
+<% if new_resource.hwaddr %>HWADDR=<%= new_resource.hwaddr %><% end %>
+<% if new_resource.metric %>METRIC=<%= new_resource.metric %><% end %>
+<% if new_resource.mtu %>MTU=<%= new_resource.mtu %><% end %>
}
- @config_path = "/etc/sysconfig/network-scripts/ifcfg-#{@new_resource.device}"
+ @config_path = "/etc/sysconfig/network-scripts/ifcfg-#{new_resource.device}"
end
end
diff --git a/lib/chef/provider/launchd.rb b/lib/chef/provider/launchd.rb
index 0ec8d0cfe1..f3e0a00758 100644
--- a/lib/chef/provider/launchd.rb
+++ b/lib/chef/provider/launchd.rb
@@ -150,7 +150,7 @@ class Chef
end
def content
- plist_hash = new_resource.hash || gen_hash
+ plist_hash = new_resource.plist_hash || gen_hash
Plist::Emit.dump(plist_hash) unless plist_hash.nil?
end
diff --git a/lib/chef/provider/link.rb b/lib/chef/provider/link.rb
index 16d30319b3..5add453072 100644
--- a/lib/chef/provider/link.rb
+++ b/lib/chef/provider/link.rb
@@ -121,6 +121,12 @@ class Chef
file_class.symlink(canonicalize(@new_resource.to), @new_resource.target_file)
Chef::Log.debug("#{@new_resource} created #{@new_resource.link_type} link from #{@new_resource.target_file} -> #{@new_resource.to}")
Chef::Log.info("#{@new_resource} created")
+ # file_class.symlink will create the link with default access controls.
+ # This means that the access controls of the file could be different
+ # than those captured during the initial evaluation of current_resource.
+ # We need to re-evaluate the current_resource to ensure that the desired
+ # access controls are applied.
+ ScanAccessControl.new(@new_resource, @current_resource).set_all!
end
elsif @new_resource.link_type == :hard
converge_by("create hard link at #{@new_resource.target_file} to #{@new_resource.to}") do
diff --git a/lib/chef/provider/mount.rb b/lib/chef/provider/mount.rb
index 9e9ee29bde..5168c93348 100644
--- a/lib/chef/provider/mount.rb
+++ b/lib/chef/provider/mount.rb
@@ -108,6 +108,8 @@ class Chef
end
end
+ alias :action_unmount :action_umount
+
#
# Abstract Methods to be implemented by subclasses
#
diff --git a/lib/chef/provider/mount/mount.rb b/lib/chef/provider/mount/mount.rb
index 07da6ac361..e00f3290fa 100644
--- a/lib/chef/provider/mount/mount.rb
+++ b/lib/chef/provider/mount/mount.rb
@@ -193,7 +193,7 @@ class Chef
def device_should_exist?
( @new_resource.device != "none" ) &&
( not network_device? ) &&
- ( not %w{ cgroup tmpfs fuse vboxsf }.include? @new_resource.fstype )
+ ( not %w{ cgroup tmpfs fuse vboxsf zfs }.include? @new_resource.fstype )
end
private
@@ -210,7 +210,7 @@ class Chef
end
def device_real
- if @real_device == nil
+ if @real_device.nil?
if @new_resource.device_type == :device
@real_device = @new_resource.device
else
diff --git a/lib/chef/provider/ohai.rb b/lib/chef/provider/ohai.rb
index 6b5a605ed5..8f1939af6d 100644
--- a/lib/chef/provider/ohai.rb
+++ b/lib/chef/provider/ohai.rb
@@ -21,6 +21,8 @@ require "ohai"
class Chef
class Provider
class Ohai < Chef::Provider
+ use_inline_resources
+
provides :ohai
def whyrun_supported?
@@ -31,7 +33,7 @@ class Chef
true
end
- def action_reload
+ action :reload do
converge_by("re-run ohai and merge results into node attributes") do
ohai = ::Ohai::System.new
@@ -39,9 +41,9 @@ class Chef
# Otherwise it will only reload the specified plugin
# Note that any changes to plugins, or new plugins placed on
# the path are picked up by ohai.
- ohai.all_plugins @new_resource.plugin
+ ohai.all_plugins new_resource.plugin
node.automatic_attrs.merge! ohai.data
- Chef::Log.info("#{@new_resource} reloaded")
+ Chef::Log.info("#{new_resource} reloaded")
end
end
end
diff --git a/lib/chef/provider/osx_profile.rb b/lib/chef/provider/osx_profile.rb
index 69ecf2ddb9..a25ac9539f 100644
--- a/lib/chef/provider/osx_profile.rb
+++ b/lib/chef/provider/osx_profile.rb
@@ -44,8 +44,10 @@ class Chef
)
@new_profile_hash = get_profile_hash(@new_resource.profile)
- @new_profile_hash["PayloadUUID"] =
- config_uuid(@new_profile_hash) if @new_profile_hash
+ if @new_profile_hash
+ @new_profile_hash["PayloadUUID"] =
+ config_uuid(@new_profile_hash)
+ end
if @new_profile_hash
@new_profile_identifier = @new_profile_hash["PayloadIdentifier"]
diff --git a/lib/chef/provider/package.rb b/lib/chef/provider/package.rb
index 048807dd05..f52614672a 100644
--- a/lib/chef/provider/package.rb
+++ b/lib/chef/provider/package.rb
@@ -37,6 +37,9 @@ class Chef
subclass_directive :use_multipackage_api
# subclasses declare this if they want sources (filenames) pulled from their package names
subclass_directive :use_package_name_for_source
+ # keeps package_names_for_targets and versions_for_targets indexed the same as package_name at
+ # the cost of having the subclass needing to deal with nils
+ subclass_directive :allow_nils
#
# Hook that subclasses use to populate the candidate_version(s)
@@ -56,7 +59,7 @@ class Chef
def check_resource_semantics!
# FIXME: this is not universally true and subclasses are needing to override this and no-ops it. It should be turned into
# another "subclass_directive" and the apt and yum providers should declare that they need this behavior.
- if new_resource.package_name.is_a?(Array) && new_resource.source != nil
+ if new_resource.package_name.is_a?(Array) && !new_resource.source.nil?
raise Chef::Exceptions::InvalidResourceSpecification, "You may not specify both multipackage and source"
end
end
@@ -196,7 +199,7 @@ class Chef
end
action :reconfig do
- if @current_resource.version == nil
+ if @current_resource.version.nil?
Chef::Log.debug("#{@new_resource} is NOT installed - nothing to do")
return
end
@@ -390,9 +393,12 @@ class Chef
def package_names_for_targets
package_names_for_targets = []
target_version_array.each_with_index do |target_version, i|
- next if target_version.nil?
- package_name = package_name_array[i]
- package_names_for_targets.push(package_name)
+ if !target_version.nil?
+ package_name = package_name_array[i]
+ package_names_for_targets.push(package_name)
+ else
+ package_names_for_targets.push(nil) if allow_nils?
+ end
end
multipackage? ? package_names_for_targets : package_names_for_targets[0]
end
@@ -407,8 +413,11 @@ class Chef
def versions_for_targets
versions_for_targets = []
target_version_array.each_with_index do |target_version, i|
- next if target_version.nil?
- versions_for_targets.push(target_version)
+ if !target_version.nil?
+ versions_for_targets.push(target_version)
+ else
+ versions_for_targets.push(nil) if allow_nils?
+ end
end
multipackage? ? versions_for_targets : versions_for_targets[0]
end
diff --git a/lib/chef/provider/package/aix.rb b/lib/chef/provider/package/aix.rb
index 728f181055..12bf11ad0f 100644
--- a/lib/chef/provider/package/aix.rb
+++ b/lib/chef/provider/package/aix.rb
@@ -38,7 +38,7 @@ class Chef
a.failure_message Chef::Exceptions::Package, "Source for package #{@new_resource.name} required for action install"
end
requirements.assert(:all_actions) do |a|
- a.assertion { !@new_resource.source || @package_source_found }
+ a.assertion { !@new_resource.source || package_source_found? }
a.failure_message Chef::Exceptions::Package, "Package #{@new_resource.name} not found: #{@new_resource.source}"
a.whyrun "would assume #{@new_resource.source} would be have previously been made available"
end
@@ -48,24 +48,21 @@ class Chef
@current_resource = Chef::Resource::Package.new(@new_resource.name)
@current_resource.package_name(@new_resource.package_name)
- if @new_resource.source
- @package_source_found = ::File.exists?(@new_resource.source)
- if @package_source_found
- Chef::Log.debug("#{@new_resource} checking pkg status")
- ret = shell_out_with_timeout("installp -L -d #{@new_resource.source}")
- ret.stdout.each_line do |line|
- case line
- when /:#{@new_resource.package_name}:/
- fields = line.split(":")
- @new_resource.version(fields[2])
- when /^#{@new_resource.package_name}:/
- Chef::Log.warn("You are installing a bff package by product name. For idempotent installs, please install individual filesets")
- fields = line.split(":")
- @new_resource.version(fields[2])
- end
+ if package_source_found?
+ Chef::Log.debug("#{@new_resource} checking pkg status")
+ ret = shell_out_with_timeout("installp -L -d #{@new_resource.source}")
+ ret.stdout.each_line do |line|
+ case line
+ when /:#{@new_resource.package_name}:/
+ fields = line.split(":")
+ @new_resource.version(fields[2])
+ when /^#{@new_resource.package_name}:/
+ Chef::Log.warn("You are installing a bff package by product name. For idempotent installs, please install individual filesets")
+ fields = line.split(":")
+ @new_resource.version(fields[2])
end
- raise Chef::Exceptions::Package, "package source #{@new_resource.source} does not provide package #{@new_resource.package_name}" unless @new_resource.version
end
+ raise Chef::Exceptions::Package, "package source #{@new_resource.source} does not provide package #{@new_resource.package_name}" unless @new_resource.version
end
Chef::Log.debug("#{@new_resource} checking install state")
@@ -88,18 +85,20 @@ class Chef
def candidate_version
return @candidate_version if @candidate_version
- ret = shell_out_with_timeout("installp -L -d #{@new_resource.source}")
- ret.stdout.each_line do |line|
- case line
- when /\w:#{Regexp.escape(@new_resource.package_name)}:(.*)/
- fields = line.split(":")
- @candidate_version = fields[2]
- @new_resource.version(fields[2])
- Chef::Log.debug("#{@new_resource} setting install candidate version to #{@candidate_version}")
+ if package_source_found?
+ ret = shell_out_with_timeout("installp -L -d #{@new_resource.source}")
+ ret.stdout.each_line do |line|
+ case line
+ when /\w:#{Regexp.escape(@new_resource.package_name)}:(.*)/
+ fields = line.split(":")
+ @candidate_version = fields[2]
+ @new_resource.version(fields[2])
+ Chef::Log.debug("#{@new_resource} setting install candidate version to #{@candidate_version}")
+ end
+ end
+ unless ret.exitstatus == 0
+ raise Chef::Exceptions::Package, "installp -L -d #{@new_resource.source} - #{ret.format_for_exception}!"
end
- end
- unless ret.exitstatus == 0
- raise Chef::Exceptions::Package, "installp -L -d #{@new_resource.source} - #{ret.format_for_exception}!"
end
@candidate_version
end
@@ -134,6 +133,10 @@ class Chef
end
end
+ def package_source_found?
+ @package_source_found ||= @new_resource.source && ::File.exists?(@new_resource.source)
+ end
+
end
end
end
diff --git a/lib/chef/provider/package/cab.rb b/lib/chef/provider/package/cab.rb
index 4e2054fbc2..a281100f8b 100644
--- a/lib/chef/provider/package/cab.rb
+++ b/lib/chef/provider/package/cab.rb
@@ -19,40 +19,70 @@
require "chef/provider/package"
require "chef/resource/cab_package"
require "chef/mixin/shell_out"
+require "chef/mixin/uris"
+require "chef/mixin/checksum"
class Chef
class Provider
class Package
class Cab < Chef::Provider::Package
+ use_inline_resources
include Chef::Mixin::ShellOut
+ include Chef::Mixin::Uris
+ include Chef::Mixin::Checksum
provides :cab_package, os: "windows"
def load_current_resource
@current_resource = Chef::Resource::CabPackage.new(new_resource.name)
- current_resource.source(new_resource.source)
+ current_resource.source(cab_file_source)
new_resource.version(package_version)
current_resource.version(installed_version)
current_resource
end
+ def cab_file_source
+ @cab_file_source ||= uri_scheme?(new_resource.source) ? download_source_file : new_resource.source
+ end
+
+ def download_source_file
+ source_resource.run_action(:create)
+ Chef::Log.debug("#{new_resource} fetched source file to #{source_resource.path}")
+ source_resource.path
+ end
+
+ def source_resource
+ @source_resource ||= declare_resource(:remote_file, new_resource.name) do
+ path default_download_cache_path
+ source new_resource.source
+ backup false
+ end
+ end
+
+ def default_download_cache_path
+ uri = ::URI.parse(new_resource.source)
+ filename = ::File.basename(::URI.unescape(uri.path))
+ file_cache_dir = Chef::FileCache.create_cache_path("package/")
+ Chef::Util::PathHelper.cleanpath("#{file_cache_dir}/#{filename}")
+ end
+
def install_package(name, version)
- dism_command("/Add-Package /PackagePath:\"#{@new_resource.source}\"")
+ dism_command("/Add-Package /PackagePath:\"#{cab_file_source}\"")
end
def remove_package(name, version)
- dism_command("/Remove-Package /PackagePath:\"#{@new_resource.source}\"")
+ dism_command("/Remove-Package /PackagePath:\"#{cab_file_source}\"")
end
def dism_command(command)
- shellout = Mixlib::ShellOut.new("dism.exe /Online #{command} /NoRestart", { :timeout => @new_resource.timeout })
+ shellout = Mixlib::ShellOut.new("dism.exe /Online /English #{command} /NoRestart", { :timeout => @new_resource.timeout })
with_os_architecture(nil) do
shellout.run_command
end
end
def installed_version
- stdout = dism_command("/Get-PackageInfo /PackagePath:\"#{@new_resource.source}\"").stdout
+ stdout = dism_command("/Get-PackageInfo /PackagePath:\"#{cab_file_source}\"").stdout
package_info = parse_dism_get_package_info(stdout)
# e.g. Package_for_KB2975719~31bf3856ad364e35~amd64~~6.3.1.8
package = split_package_identity(package_info["package_information"]["package_identity"])
@@ -71,8 +101,8 @@ class Chef
end
def package_version
- Chef::Log.debug("#{@new_resource} getting product version for package at #{@new_resource.source}")
- stdout = dism_command("/Get-PackageInfo /PackagePath:\"#{@new_resource.source}\"").stdout
+ Chef::Log.debug("#{@new_resource} getting product version for package at #{cab_file_source}")
+ stdout = dism_command("/Get-PackageInfo /PackagePath:\"#{cab_file_source}\"").stdout
find_version(stdout)
end
diff --git a/lib/chef/provider/package/chocolatey.rb b/lib/chef/provider/package/chocolatey.rb
index 36bc170590..02a196fa8c 100644
--- a/lib/chef/provider/package/chocolatey.rb
+++ b/lib/chef/provider/package/chocolatey.rb
@@ -84,7 +84,7 @@ EOS
# choco does not support installing multiple packages with version pins
name_has_versions.each do |name, version|
- choco_command("install -y -version", version, cmd_args, name)
+ choco_command("install -y --version", version, cmd_args, name)
end
# but we can do all the ones without version pins at once
@@ -106,7 +106,7 @@ EOS
# choco does not support installing multiple packages with version pins
name_has_versions.each do |name, version|
- choco_command("upgrade -y -version", version, cmd_args, name)
+ choco_command("upgrade -y --version", version, cmd_args, name)
end
# but we can do all the ones without version pins at once
@@ -169,7 +169,7 @@ EOS
# @param args [String] variable number of string arguments
# @return [Mixlib::ShellOut] object returned from shell_out!
def choco_command(*args)
- shell_out_with_timeout!(args_to_string(choco_exe, *args))
+ shell_out_with_timeout!(args_to_string(choco_exe, *args), { :returns => new_resource.returns })
end
# Use the available_packages Hash helper to create an array suitable for
@@ -236,6 +236,7 @@ EOS
available[name] = desired_name_versions[name] || raw[name]
end
end
+ @available_packages
end
# Installed packages in chocolatey as a Hash of names mapped to versions
@@ -244,6 +245,7 @@ EOS
# @return [Hash] name-to-version mapping of installed packages
def installed_packages
@installed_packages ||= Hash[*parse_list_output("list -l -r").flatten]
+ @installed_packages
end
# Helper to convert choco.exe list output to a Hash
diff --git a/lib/chef/provider/package/dnf.rb b/lib/chef/provider/package/dnf.rb
new file mode 100644
index 0000000000..bf6aa2438f
--- /dev/null
+++ b/lib/chef/provider/package/dnf.rb
@@ -0,0 +1,183 @@
+#
+# Copyright:: Copyright 2016, Chef Software, Inc.
+# License:: Apache License, Version 2.0
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+
+require "chef/provider/package"
+require "chef/resource/dnf_package"
+require "chef/mixin/which"
+require "chef/mixin/get_source_from_package"
+require "chef/provider/package/dnf/python_helper"
+require "chef/provider/package/dnf/version"
+
+class Chef
+ class Provider
+ class Package
+ class Dnf < Chef::Provider::Package
+ extend Chef::Mixin::Which
+ include Chef::Mixin::GetSourceFromPackage
+
+ allow_nils
+ use_multipackage_api
+ use_package_name_for_source
+
+ provides :package, platform_family: %w{rhel fedora} do
+ which("dnf")
+ end
+
+ provides :dnf_package, os: "linux"
+
+ #
+ # Most of the magic in this class happens in the python helper script. The ruby side of this
+ # provider knows only enough to translate Chef-style new_resource name+package+version into
+ # a request to the python side. The python side is then responsible for knowing everything
+ # about RPMs and what is installed and what is available. The ruby side of this class should
+ # remain a lightweight translation layer to translate Chef requests into RPC requests to
+ # python. This class knows nothing about how to compare RPM versions, and does not maintain
+ # any cached state of installed/available versions and should be kept that way.
+ #
+ def python_helper
+ @python_helper ||= PythonHelper.instance
+ end
+
+ def load_current_resource
+ flushcache if new_resource.flush_cache[:before]
+
+ @current_resource = Chef::Resource::DnfPackage.new(new_resource.name)
+ current_resource.package_name(new_resource.package_name)
+ current_resource.version(get_current_versions)
+
+ current_resource
+ end
+
+ def define_resource_requirements
+ requirements.assert(:install, :upgrade, :remove, :purge) do |a|
+ a.assertion { !new_resource.source || ::File.exist?(new_resource.source) }
+ a.failure_message Chef::Exceptions::Package, "Package #{new_resource.package_name} not found: #{new_resource.source}"
+ a.whyrun "assuming #{new_resource.source} would have previously been created"
+ end
+
+ super
+ end
+
+ def candidate_version
+ package_name_array.each_with_index.map do |pkg, i|
+ available_version(i).version_with_arch
+ end
+ end
+
+ def get_current_versions
+ package_name_array.each_with_index.map do |pkg, i|
+ installed_version(i).version_with_arch
+ end
+ end
+
+ def install_package(names, versions)
+ if new_resource.source
+ dnf(new_resource.options, "-y install", new_resource.source)
+ else
+ resolved_names = names.each_with_index.map { |name, i| available_version(i).to_s unless name.nil? }
+ dnf(new_resource.options, "-y install", resolved_names)
+ end
+ flushcache
+ end
+
+ # dnf upgrade does not work on uninstalled packaged, while install will upgrade
+ alias_method :upgrade_package, :install_package
+
+ def remove_package(names, versions)
+ resolved_names = names.each_with_index.map { |name, i| installed_version(i).to_s unless name.nil? }
+ dnf(new_resource.options, "-y remove", resolved_names)
+ flushcache
+ end
+
+ alias_method :purge_package, :remove_package
+
+ action :flush_cache do
+ flushcache
+ end
+
+ private
+
+ def resolve_source_to_version_obj
+ shell_out_with_timeout!("rpm -qp --queryformat '%{NAME} %{EPOCH} %{VERSION} %{RELEASE} %{ARCH}\n' #{new_resource.source}").stdout.each_line do |line|
+ # 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
+ # does not match what the dnf library accepts.
+ case line
+ when /^(\S+)\s+(\S+)\s+(\S+)\s+(\S+)\s+(\S+)$/
+ return Version.new($1, "#{$2 == "(none)" ? "0" : $2}:#{$3}-#{$4}", $5)
+ end
+ end
+ end
+
+ # @returns Array<Version>
+ def available_version(index)
+ @available_version ||= []
+
+ if new_resource.source
+ @available_version[index] ||= resolve_source_to_version_obj
+ else
+ @available_version[index] ||= python_helper.query(:whatavailable, package_name_array[index], safe_version_array[index], safe_arch_array[index])
+ end
+
+ @available_version[index]
+ end
+
+ # @returns Array<Version>
+ def installed_version(index)
+ @installed_version ||= []
+ if new_resource.source
+ @installed_version[index] ||= python_helper.query(:whatinstalled, available_version(index).name, safe_version_array[index], safe_arch_array[index])
+ else
+ @installed_version[index] ||= python_helper.query(:whatinstalled, package_name_array[index], safe_version_array[index], safe_arch_array[index])
+ end
+ @installed_version[index]
+ end
+
+ # cache flushing is accomplished by simply restarting the python helper. this produces a roughly
+ # 15% hit to the runtime of installing/removing/upgrading packages. correctly using multipackage
+ # array installs (and the multipackage cookbook) can produce 600% improvements in runtime.
+ def flushcache
+ python_helper.restart
+ end
+
+ def dnf(*args)
+ shell_out_with_timeout!(a_to_s("dnf", *args))
+ end
+
+ def safe_version_array
+ if new_resource.version.is_a?(Array)
+ new_resource.version
+ elsif new_resource.version.nil?
+ package_name_array.map { nil }
+ else
+ [ new_resource.version ]
+ end
+ end
+
+ def safe_arch_array
+ if new_resource.arch.is_a?(Array)
+ new_resource.arch
+ elsif new_resource.arch.nil?
+ package_name_array.map { nil }
+ else
+ [ new_resource.arch ]
+ end
+ end
+
+ end
+ end
+ end
+end
diff --git a/lib/chef/provider/package/dnf/dnf_helper.py b/lib/chef/provider/package/dnf/dnf_helper.py
new file mode 100644
index 0000000000..236b967710
--- /dev/null
+++ b/lib/chef/provider/package/dnf/dnf_helper.py
@@ -0,0 +1,91 @@
+#!/usr/bin/env python3
+# vim: tabstop=8 expandtab shiftwidth=4 softtabstop=4
+
+import sys
+import dnf
+import hawkey
+import signal
+import os
+import json
+
+base = None
+
+def get_sack():
+ global base
+ if base is None:
+ base = dnf.Base()
+ base.read_all_repos()
+ base.fill_sack()
+ return base.sack
+
+# FIXME: leaks memory and does not work
+def flushcache():
+ try:
+ os.remove('/var/cache/dnf/@System.solv')
+ except OSError:
+ pass
+ get_sack().load_system_repo(build_cache=True)
+
+def query(command):
+ sack = get_sack()
+
+ subj = dnf.subject.Subject(command['provides'])
+ q = subj.get_best_query(sack, with_provides=True)
+
+ if command['action'] == "whatinstalled":
+ q = q.installed()
+
+ if command['action'] == "whatavailable":
+ q = q.available()
+
+ if 'epoch' in command:
+ q = q.filterm(epoch=int(command['epoch']))
+ if 'version' in command:
+ q = q.filterm(version__glob=command['version'])
+ if 'release' in command:
+ q = q.filterm(release__glob=command['release'])
+
+ if 'arch' in command:
+ q = q.filterm(arch__glob=command['arch'])
+
+ # only apply the default arch query filter if it returns something
+ archq = q.filter(arch=[ 'noarch', hawkey.detect_arch() ])
+ if len(archq.run()) > 0:
+ q = archq
+
+ pkgs = dnf.query.latest_limit_pkgs(q, 1)
+
+ if not pkgs:
+ sys.stdout.write('{} nil nil\n'.format(command['provides'].split().pop(0)))
+ else:
+ # make sure we picked the package with the highest version
+ pkgs.sort
+ pkg = pkgs.pop()
+ sys.stdout.write('{} {}:{}-{} {}\n'.format(pkg.name, pkg.epoch, pkg.version, pkg.release, pkg.arch))
+
+# the design of this helper is that it should try to be 'brittle' and fail hard and exit in order
+# to keep process tables clean. additional error handling should probably be added to the retry loop
+# on the ruby side.
+def exit_handler(signal, frame):
+ sys.exit(0)
+
+signal.signal(signal.SIGINT, exit_handler)
+signal.signal(signal.SIGHUP, exit_handler)
+signal.signal(signal.SIGPIPE, exit_handler)
+signal.signal(signal.SIGCHLD, exit_handler)
+
+while 1:
+ # kill self if we get orphaned (tragic)
+ ppid = os.getppid()
+ if ppid == 1:
+ sys.exit(0)
+ line = sys.stdin.readline()
+ command = json.loads(line)
+ if command['action'] == "whatinstalled":
+ query(command)
+ elif command['action'] == "whatavailable":
+ query(command)
+ elif command['action'] == "flushcache":
+ flushcache()
+ else:
+ raise RuntimeError("bad command")
diff --git a/lib/chef/provider/package/dnf/python_helper.rb b/lib/chef/provider/package/dnf/python_helper.rb
new file mode 100644
index 0000000000..466114b339
--- /dev/null
+++ b/lib/chef/provider/package/dnf/python_helper.rb
@@ -0,0 +1,120 @@
+#
+# Copyright:: Copyright 2016, Chef Software, Inc.
+# License:: Apache License, Version 2.0
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+
+require "chef/provider/package/dnf/version"
+require "timeout"
+
+class Chef
+ class Provider
+ class Package
+ class Dnf < Chef::Provider::Package
+ class PythonHelper
+ include Singleton
+ extend Chef::Mixin::Which
+
+ attr_accessor :stdin
+ attr_accessor :stdout
+ attr_accessor :stderr
+ attr_accessor :wait_thr
+
+ DNF_HELPER = ::File.expand_path(::File.join(::File.dirname(__FILE__), "dnf_helper.py")).freeze
+ DNF_COMMAND = "#{which("python3")} #{DNF_HELPER}"
+
+ def start
+ ENV["PYTHONUNBUFFERED"] = "1"
+ @stdin, @stdout, @stderr, @wait_thr = Open3.popen3(DNF_COMMAND)
+ end
+
+ def reap
+ unless wait_thr.nil?
+ Process.kill("KILL", wait_thr.pid) rescue nil
+ stdin.close unless stdin.nil?
+ stdout.close unless stdout.nil?
+ stderr.close unless stderr.nil?
+ wait_thr.value # this calls waitpit()
+ end
+ end
+
+ def check
+ start if stdin.nil?
+ end
+
+ # i couldn't figure out how to decompose an evr on the python side, it seems reasonably
+ # painless to do it in ruby (generally massaging nevras in the ruby side is HIGHLY
+ # discouraged -- this is an "every rule has an exception" exception -- any additional
+ # functionality should probably trigger moving this regexp logic into python)
+ def add_version(hash, version)
+ epoch = nil
+ if version =~ /(\S+):(\S+)/
+ epoch, version = $1, $2
+ end
+ if version =~ /(\S+)-(\S+)/
+ version, release = $1, $2
+ end
+ hash["epoch"] = epoch unless epoch.nil?
+ hash["release"] = release unless release.nil?
+ hash["version"] = version
+ end
+
+ def build_query(action, provides, version, arch)
+ hash = { "action" => action }
+ hash["provides"] = provides
+ add_version(hash, version) unless version.nil?
+ hash["arch" ] = arch unless arch.nil?
+ FFI_Yajl::Encoder.encode(hash)
+ end
+
+ def parse_response(output)
+ array = output.split.map { |x| x == "nil" ? nil : x }
+ array.each_slice(3).map { |x| Version.new(*x) }.first
+ end
+
+ # @returns Array<Version>
+ def query(action, provides, version = nil, arch = nil)
+ with_helper do
+ json = build_query(action, provides, version, arch)
+ Chef::Log.debug "sending '#{json}' to python helper"
+ stdin.syswrite json + "\n"
+ output = stdout.sysread(4096).chomp
+ Chef::Log.debug "got '#{output}' from python helper"
+ version = parse_response(output)
+ Chef::Log.debug "parsed #{version} from python helper"
+ version
+ end
+ end
+
+ def restart
+ reap
+ start
+ end
+
+ def with_helper
+ max_retries ||= 5
+ Timeout.timeout(600) do
+ check
+ yield
+ end
+ rescue EOFError, Errno::EPIPE, Timeout::Error, Errno::ESRCH => e
+ raise e unless ( max_retries -= 1 ) > 0
+ restart
+ retry
+ end
+ end
+ end
+ end
+ end
+end
diff --git a/lib/chef/provider/package/dnf/version.rb b/lib/chef/provider/package/dnf/version.rb
new file mode 100644
index 0000000000..b326913c3a
--- /dev/null
+++ b/lib/chef/provider/package/dnf/version.rb
@@ -0,0 +1,56 @@
+#
+# Copyright:: Copyright 2016, Chef Software, Inc.
+# License:: Apache License, Version 2.0
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+
+class Chef
+ class Provider
+ class Package
+ class Dnf < Chef::Provider::Package
+
+ # helper class to assist in passing around name/version/arch triples
+ class Version
+ attr_accessor :name
+ attr_accessor :version
+ attr_accessor :arch
+
+ def initialize(name, version, arch)
+ @name = name
+ @version = version
+ @arch = arch
+ end
+
+ def to_s
+ "#{name}-#{version}.#{arch}"
+ end
+
+ def version_with_arch
+ "#{version}.#{arch}" unless version.nil?
+ end
+
+ def matches_name_and_arch?(other)
+ other.version == version && other.arch == arch
+ end
+
+ def ==(other)
+ name == other.name && version == other.version && arch == other.arch
+ end
+
+ alias_method :eql?, :==
+ end
+ end
+ end
+ end
+end
diff --git a/lib/chef/provider/package/easy_install.rb b/lib/chef/provider/package/easy_install.rb
index 989f2ab9d2..a9c6e2a792 100644
--- a/lib/chef/provider/package/easy_install.rb
+++ b/lib/chef/provider/package/easy_install.rb
@@ -112,7 +112,7 @@ class Chef
end
def install_package(name, version)
- Chef.log_deprecation("The easy_install package provider is deprecated and will be removed in Chef 13.")
+ Chef.deprecated(:easy_install, "The easy_install package provider is deprecated and will be removed in Chef 13.")
run_command(:command => "#{easy_install_binary_path}#{expand_options(@new_resource.options)} \"#{name}==#{version}\"")
end
@@ -121,8 +121,8 @@ class Chef
end
def remove_package(name, version)
- Chef.log_deprecation("The easy_install package provider is deprecated and will be removed in Chef 13.")
- run_command(:command => "#{easy_install_binary_path }#{expand_options(@new_resource.options)} -m #{name}")
+ Chef.deprecated(:easy_install, "The easy_install package provider is deprecated and will be removed in Chef 13.")
+ run_command(:command => "#{easy_install_binary_path}#{expand_options(@new_resource.options)} -m #{name}")
end
def purge_package(name, version)
diff --git a/lib/chef/provider/package/freebsd/base.rb b/lib/chef/provider/package/freebsd/base.rb
index 7104a71f70..0996a38c75 100644
--- a/lib/chef/provider/package/freebsd/base.rb
+++ b/lib/chef/provider/package/freebsd/base.rb
@@ -58,7 +58,7 @@ class Chef
def makefile_variable_value(variable, dir = nil)
options = dir ? { :cwd => dir } : {}
make_v = shell_out_with_timeout!("make -V #{variable}", options.merge!(:env => nil, :returns => [0, 1]))
- make_v.exitstatus.zero? ? make_v.stdout.strip.split($\).first : nil # $\ is the line separator, i.e. newline.
+ make_v.exitstatus == 0 ? make_v.stdout.strip.split($\).first : nil # $\ is the line separator, i.e. newline.
end
end
diff --git a/lib/chef/provider/package/freebsd/pkgng.rb b/lib/chef/provider/package/freebsd/pkgng.rb
index de7bea6387..56e87f6be9 100644
--- a/lib/chef/provider/package/freebsd/pkgng.rb
+++ b/lib/chef/provider/package/freebsd/pkgng.rb
@@ -64,7 +64,7 @@ class Chef
end
pkg_query = shell_out_with_timeout!("pkg rquery#{expand_options(options)} '%v' #{@new_resource.package_name}", :env => nil)
- pkg_query.exitstatus.zero? ? pkg_query.stdout.strip.split(/\n/).last : nil
+ pkg_query.exitstatus == 0 ? pkg_query.stdout.strip.split(/\n/).last : nil
end
def repo_regex
diff --git a/lib/chef/provider/package/ips.rb b/lib/chef/provider/package/ips.rb
index 85053d47f2..bc5b9fff77 100644
--- a/lib/chef/provider/package/ips.rb
+++ b/lib/chef/provider/package/ips.rb
@@ -74,7 +74,7 @@ class Chef
else
normal_command
end
- shell_out_with_timeout(command)
+ shell_out_with_timeout!(command)
end
def upgrade_package(name, version)
diff --git a/lib/chef/provider/package/msu.rb b/lib/chef/provider/package/msu.rb
new file mode 100644
index 0000000000..3146ecb04d
--- /dev/null
+++ b/lib/chef/provider/package/msu.rb
@@ -0,0 +1,162 @@
+#
+# Author:: Nimisha Sharad (<nimisha.sharad@msystechnologies.com>)
+# Copyright:: Copyright 2015-2016, Chef Software, Inc.
+# License:: Apache License, Version 2.0
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+
+# msu_package leverages cab_package
+# The contents of msu file are extracted, which contains one or more cab files.
+# The extracted cab files are installed using Chef::Resource::Package::CabPackage
+# Reference: https://support.microsoft.com/en-in/kb/934307
+require "chef/provider/package"
+require "chef/resource/msu_package"
+require "chef/mixin/shell_out"
+require "chef/provider/package/cab"
+require "chef/util/path_helper"
+require "chef/mixin/uris"
+require "chef/mixin/checksum"
+
+class Chef
+ class Provider
+ class Package
+ class Msu < Chef::Provider::Package
+ use_inline_resources
+ include Chef::Mixin::ShellOut
+ include Chef::Mixin::Uris
+ include Chef::Mixin::Checksum
+
+ provides :msu_package, os: "windows"
+
+ def load_current_resource
+ @current_resource = Chef::Resource::MsuPackage.new(new_resource.name)
+
+ # download file if source is a url
+ msu_file = uri_scheme?(new_resource.source) ? download_source_file : @new_resource.source
+
+ # temp directory where the contents of msu file get extracted
+ @temp_directory = Dir.mktmpdir("chef")
+ extract_msu_contents(msu_file, @temp_directory)
+ @cab_files = read_cab_files_from_xml(@temp_directory)
+
+ unless @cab_files.empty?
+ current_resource.version(get_current_versions)
+ else
+ raise Chef::Exceptions::Package, "Corrupt MSU package: MSU package XML does not contain any cab file"
+ end
+ current_resource
+ end
+
+ def get_current_versions
+ @cab_files.map do |cabfile|
+ cab_pkg = get_cab_package(cabfile)
+ cab_pkg.installed_version
+ end
+ end
+
+ def get_candidate_versions
+ @cab_files.map do |cabfile|
+ cab_pkg = get_cab_package(cabfile)
+ cab_pkg.package_version
+ end
+ end
+
+ def candidate_version
+ @candidate_version ||= get_candidate_versions
+ end
+
+ def get_cab_package(cab_file)
+ cab_resource = @new_resource
+ cab_resource.source = cab_file
+ cab_pkg = Chef::Provider::Package::Cab.new(cab_resource, nil)
+ end
+
+ def download_source_file
+ source_resource.run_action(:create)
+ Chef::Log.debug("#{new_resource} fetched source file to #{source_resource.path}")
+ source_resource.path
+ end
+
+ def source_resource
+ @source_resource ||= declare_resource(:remote_file, new_resource.name) do
+ path default_download_cache_path
+ source new_resource.source
+ checksum new_resource.checksum
+ backup false
+ end
+ end
+
+ def default_download_cache_path
+ uri = ::URI.parse(new_resource.source)
+ filename = ::File.basename(::URI.unescape(uri.path))
+ file_cache_dir = Chef::FileCache.create_cache_path("package/")
+ Chef::Util::PathHelper.cleanpath("#{file_cache_dir}/#{filename}")
+ end
+
+ def install_package(name, version)
+ #use cab_package resource to install the extracted cab packages
+ @cab_files.each do |cab_file|
+ declare_resource(:cab_package, @new_resource.name) do
+ source cab_file
+ action :install
+ end
+ end
+ end
+
+ def remove_package(name, version)
+ #use cab_package provider to remove the extracted cab packages
+ @cab_files.each do |cab_file|
+ declare_resource(:cab_package, @new_resource.name) do
+ source cab_file
+ action :remove
+ end
+ end
+ end
+
+ def extract_msu_contents(msu_file, destination)
+ with_os_architecture(nil) do
+ shell_out_with_timeout!("#{ENV['SYSTEMROOT']}\\system32\\expand.exe -f:* #{msu_file} #{destination}")
+ end
+ end
+
+ # msu package can contain multiple cab files
+ # Reading cab files from xml to ensure the order of installation in case of multiple cab files
+ def read_cab_files_from_xml(msu_dir)
+ # get the file with .xml extension
+ xml_files = Dir.glob("#{msu_dir}/*.xml")
+ cab_files = []
+
+ if xml_files.empty?
+ raise Chef::Exceptions::Package, "Corrupt MSU package: MSU package doesn't contain any xml file"
+ else
+ # msu package contains only single xml file. So using xml_files.first is sufficient
+ doc = ::File.open("#{xml_files.first}") { |f| REXML::Document.new f }
+ locations = doc.elements.each("unattend/servicing/package/source") { |element| puts element.attributes["location"] }
+ locations.each do |loc|
+ cab_files << msu_dir + "/" + loc.attribute("location").value.split("\\")[1]
+ end
+
+ cab_files
+ end
+ cab_files
+ end
+
+ def cleanup_after_converge
+ # delete the temp directory where the contents of msu file are extracted
+ FileUtils.rm_rf(@temp_directory) if Dir.exists?(@temp_directory)
+ end
+ end
+ end
+ end
+end
diff --git a/lib/chef/provider/package/powershell.rb b/lib/chef/provider/package/powershell.rb
index 5206b5b696..caeda6d412 100644
--- a/lib/chef/provider/package/powershell.rb
+++ b/lib/chef/provider/package/powershell.rb
@@ -60,7 +60,7 @@ class Chef
# Removes the package for the version passed and if no version is passed, then all installed versions of the package are removed
def remove_package(names, versions)
names.each_with_index do |name, index|
- if versions && versions[index] != nil
+ if versions && !versions[index].nil?
powershell_out( "Uninstall-Package '#{name}' -Force -ForceBootstrap -RequiredVersion #{versions[index]}", { :timeout => @new_resource.timeout })
else
version = "0"
@@ -78,7 +78,7 @@ class Chef
def build_candidate_versions
versions = []
new_resource.package_name.each_with_index do |name, index|
- if new_resource.version && new_resource.version[index] != nil
+ if new_resource.version && !new_resource.version[index].nil?
version = powershell_out("(Find-Package '#{name}' -RequiredVersion #{new_resource.version[index]} -ForceBootstrap -Force | select version | Format-Table -HideTableHeaders | Out-String).Trim()", { :timeout => @new_resource.timeout }).stdout.strip()
else
version = powershell_out("(Find-Package '#{name}' -ForceBootstrap -Force | select version | Format-Table -HideTableHeaders | Out-String).Trim()", { :timeout => @new_resource.timeout }).stdout.strip()
@@ -95,7 +95,7 @@ class Chef
def build_current_versions
version_list = []
new_resource.package_name.each_with_index do |name, index|
- if new_resource.version && new_resource.version[index] != nil
+ if new_resource.version && !new_resource.version[index].nil?
version = powershell_out("(Get-Package -Name '#{name}' -RequiredVersion #{new_resource.version[index]} -ForceBootstrap -Force | select version | Format-Table -HideTableHeaders | Out-String).Trim()", { :timeout => @new_resource.timeout }).stdout.strip()
else
version = powershell_out("(Get-Package -Name '#{name}' -ForceBootstrap -Force | select version | Format-Table -HideTableHeaders | Out-String).Trim()", { :timeout => @new_resource.timeout }).stdout.strip()
diff --git a/lib/chef/provider/package/windows.rb b/lib/chef/provider/package/windows.rb
index b11bcf5192..504d5d394a 100644
--- a/lib/chef/provider/package/windows.rb
+++ b/lib/chef/provider/package/windows.rb
@@ -262,7 +262,7 @@ class Chef
if source_location.nil?
inferred_registry_type == :msi
else
- ::File.extname(source_location).casecmp(".msi").zero?
+ ::File.extname(source_location).casecmp(".msi") == 0
end
end
end
diff --git a/lib/chef/provider/package/yum.rb b/lib/chef/provider/package/yum.rb
index 022fdcae09..8b7d7a5083 100644
--- a/lib/chef/provider/package/yum.rb
+++ b/lib/chef/provider/package/yum.rb
@@ -197,7 +197,7 @@ class Chef
Chef::Log.debug("#{@new_resource} checking rpm status")
shell_out_with_timeout!("rpm -qp --queryformat '%{NAME} %{VERSION}-%{RELEASE}\n' #{@new_resource.source}", :timeout => Chef::Config[:yum_timeout]).stdout.each_line do |line|
case line
- when /([\w\d_.-]+)\s([\w\d_.-]+)/
+ when /^(\S+)\s(\S+)$/
@current_resource.package_name($1)
@new_resource.version($2)
end
diff --git a/lib/chef/provider/package/zypper.rb b/lib/chef/provider/package/zypper.rb
index edad45c3e4..6965052723 100644
--- a/lib/chef/provider/package/zypper.rb
+++ b/lib/chef/provider/package/zypper.rb
@@ -144,7 +144,7 @@ class Chef
end
end
- def gpg_checks()
+ def gpg_checks
case Chef::Config[:zypper_check_gpg]
when true
""
diff --git a/lib/chef/provider/route.rb b/lib/chef/provider/route.rb
index 64c89aac6d..5e20fdf11e 100644
--- a/lib/chef/provider/route.rb
+++ b/lib/chef/provider/route.rb
@@ -21,209 +21,211 @@ require "chef/mixin/command"
require "chef/provider"
require "ipaddr"
-class Chef::Provider::Route < Chef::Provider
- include Chef::Mixin::Command
-
- provides :route
-
- attr_accessor :is_running
-
- MASK = { "0.0.0.0" => "0",
- "128.0.0.0" => "1",
- "192.0.0.0" => "2",
- "224.0.0.0" => "3",
- "240.0.0.0" => "4",
- "248.0.0.0" => "5",
- "252.0.0.0" => "6",
- "254.0.0.0" => "7",
- "255.0.0.0" => "8",
- "255.128.0.0" => "9",
- "255.192.0.0" => "10",
- "255.224.0.0" => "11",
- "255.240.0.0" => "12",
- "255.248.0.0" => "13",
- "255.252.0.0" => "14",
- "255.254.0.0" => "15",
- "255.255.0.0" => "16",
- "255.255.128.0" => "17",
- "255.255.192.0" => "18",
- "255.255.224.0" => "19",
- "255.255.240.0" => "20",
- "255.255.248.0" => "21",
- "255.255.252.0" => "22",
- "255.255.254.0" => "23",
- "255.255.255.0" => "24",
- "255.255.255.128" => "25",
- "255.255.255.192" => "26",
- "255.255.255.224" => "27",
- "255.255.255.240" => "28",
- "255.255.255.248" => "29",
- "255.255.255.252" => "30",
- "255.255.255.254" => "31",
- "255.255.255.255" => "32" }
-
- def hex2ip(hex_data)
- # Cleanup hex data
- hex_ip = hex_data.to_s.downcase.gsub(/[^0-9a-f]/, "")
-
- # Check hex data format (IP is a 32bit integer, so should be 8 chars long)
- return nil if hex_ip.length != hex_data.length || hex_ip.length != 8
-
- # Extract octets from hex data
- octets = hex_ip.scan(/../).reverse.collect { |octet| [octet].pack("H2").unpack("C").first }
-
- # Validate IP
- ip = octets.join(".")
- begin
- IPAddr.new(ip, Socket::AF_INET).to_s
- rescue ArgumentError
- Chef::Log.debug("Invalid IP address data: hex=#{hex_ip}, ip=#{ip}")
- return nil
- end
- end
-
- def whyrun_supported?
- true
- end
+class Chef
+ class Provider
+ class Route < Chef::Provider
+ include Chef::Mixin::Command
+
+ provides :route
+
+ attr_accessor :is_running
+
+ MASK = { "0.0.0.0" => "0",
+ "128.0.0.0" => "1",
+ "192.0.0.0" => "2",
+ "224.0.0.0" => "3",
+ "240.0.0.0" => "4",
+ "248.0.0.0" => "5",
+ "252.0.0.0" => "6",
+ "254.0.0.0" => "7",
+ "255.0.0.0" => "8",
+ "255.128.0.0" => "9",
+ "255.192.0.0" => "10",
+ "255.224.0.0" => "11",
+ "255.240.0.0" => "12",
+ "255.248.0.0" => "13",
+ "255.252.0.0" => "14",
+ "255.254.0.0" => "15",
+ "255.255.0.0" => "16",
+ "255.255.128.0" => "17",
+ "255.255.192.0" => "18",
+ "255.255.224.0" => "19",
+ "255.255.240.0" => "20",
+ "255.255.248.0" => "21",
+ "255.255.252.0" => "22",
+ "255.255.254.0" => "23",
+ "255.255.255.0" => "24",
+ "255.255.255.128" => "25",
+ "255.255.255.192" => "26",
+ "255.255.255.224" => "27",
+ "255.255.255.240" => "28",
+ "255.255.255.248" => "29",
+ "255.255.255.252" => "30",
+ "255.255.255.254" => "31",
+ "255.255.255.255" => "32" }.freeze
+
+ def hex2ip(hex_data)
+ # Cleanup hex data
+ hex_ip = hex_data.to_s.downcase.gsub(/[^0-9a-f]/, "")
+
+ # Check hex data format (IP is a 32bit integer, so should be 8 chars long)
+ return nil if hex_ip.length != hex_data.length || hex_ip.length != 8
+
+ # Extract octets from hex data
+ octets = hex_ip.scan(/../).reverse.collect { |octet| [octet].pack("H2").unpack("C").first }
+
+ # Validate IP
+ ip = octets.join(".")
+ begin
+ IPAddr.new(ip, Socket::AF_INET).to_s
+ rescue ArgumentError
+ Chef::Log.debug("Invalid IP address data: hex=#{hex_ip}, ip=#{ip}")
+ return nil
+ end
+ end
- def load_current_resource
- self.is_running = false
+ def whyrun_supported?
+ true
+ end
- # cidr or quad dot mask
- if @new_resource.netmask
- new_ip = IPAddr.new("#{@new_resource.target}/#{@new_resource.netmask}")
- else
- new_ip = IPAddr.new(@new_resource.target)
- end
+ def load_current_resource
+ self.is_running = false
+
+ # cidr or quad dot mask
+ new_ip = if new_resource.netmask
+ IPAddr.new("#{new_resource.target}/#{new_resource.netmask}")
+ else
+ IPAddr.new(new_resource.target)
+ end
+
+ # For linux, we use /proc/net/route file to read proc table info
+ return if node[:os] != "linux"
+
+ route_file = ::File.open("/proc/net/route", "r")
+
+ # Read all routes
+ while (line = route_file.gets)
+ # Get all the fields for a route
+ _, destination, gateway, _, _, _, _, mask = line.split
+
+ # Convert hex-encoded values to quad-dotted notation (e.g. 0064A8C0 => 192.168.100.0)
+ destination = hex2ip(destination)
+ gateway = hex2ip(gateway)
+ mask = hex2ip(mask)
+
+ # Skip formatting lines (header, etc)
+ next unless destination && gateway && mask
+ Chef::Log.debug("#{new_resource} system has route: dest=#{destination} mask=#{mask} gw=#{gateway}")
+
+ # check if what were trying to configure is already there
+ # use an ipaddr object with ip/mask this way we can have
+ # a new resource be in cidr format (i don't feel like
+ # expanding bitmask by hand.
+ #
+ running_ip = IPAddr.new("#{destination}/#{mask}")
+ Chef::Log.debug("#{new_resource} new ip: #{new_ip.inspect} running ip: #{running_ip.inspect}")
+ self.is_running = true if running_ip == new_ip && gateway == new_resource.gateway
+ end
- # For linux, we use /proc/net/route file to read proc table info
- if node[:os] == "linux"
- route_file = ::File.open("/proc/net/route", "r")
-
- # Read all routes
- while (line = route_file.gets)
- # Get all the fields for a route
- iface, destination, gateway, flags, refcnt, use, metric, mask, mtu, window, irtt = line.split
-
- # Convert hex-encoded values to quad-dotted notation (e.g. 0064A8C0 => 192.168.100.0)
- destination = hex2ip(destination)
- gateway = hex2ip(gateway)
- mask = hex2ip(mask)
-
- # Skip formatting lines (header, etc)
- next unless destination && gateway && mask
- Chef::Log.debug("#{@new_resource} system has route: dest=#{destination} mask=#{mask} gw=#{gateway}")
-
- # check if what were trying to configure is already there
- # use an ipaddr object with ip/mask this way we can have
- # a new resource be in cidr format (i don't feel like
- # expanding bitmask by hand.
- #
- running_ip = IPAddr.new("#{destination}/#{mask}")
- Chef::Log.debug("#{@new_resource} new ip: #{new_ip.inspect} running ip: #{running_ip.inspect}")
- self.is_running = true if running_ip == new_ip && gateway == @new_resource.gateway
+ route_file.close
end
- route_file.close
- end
- end
+ def action_add
+ # check to see if load_current_resource found the route
+ if is_running
+ Chef::Log.debug("#{new_resource} route already active - nothing to do")
+ else
+ command = generate_command(:add)
+ converge_by("run #{command.join(' ')} to add route") do
+ shell_out_compact!(command)
+ Chef::Log.info("#{new_resource} added")
+ end
+ end
- def action_add
- # check to see if load_current_resource found the route
- if is_running
- Chef::Log.debug("#{@new_resource} route already active - nothing to do")
- else
- command = generate_command(:add)
- converge_by ("run #{ command } to add route") do
- run_command( :command => command )
- Chef::Log.info("#{@new_resource} added")
+ # for now we always write the file (ugly but its what it is)
+ generate_config
end
- end
- #for now we always write the file (ugly but its what it is)
- generate_config
- end
+ def action_delete
+ if is_running
+ command = generate_command(:delete)
+ converge_by("run #{command.join(' ')} to delete route ") do
+ shell_out_compact!(command)
+ Chef::Log.info("#{new_resource} removed")
+ end
+ else
+ Chef::Log.debug("#{new_resource} route does not exist - nothing to do")
+ end
- def action_delete
- if is_running
- command = generate_command(:delete)
- converge_by ("run #{ command } to delete route ") do
- run_command( :command => command )
- Chef::Log.info("#{@new_resource} removed")
+ # for now we always write the file (ugly but its what it is)
+ generate_config
end
- else
- Chef::Log.debug("#{@new_resource} route does not exist - nothing to do")
- end
-
- #for now we always write the file (ugly but its what it is)
- generate_config
- end
- def generate_config
- conf = Hash.new
- case node[:platform]
- when "centos", "redhat", "fedora"
- # walk the collection
- run_context.resource_collection.each do |resource|
- if resource.is_a? Chef::Resource::Route
- # default to eth0
- if resource.device
- dev = resource.device
- else
- dev = "eth0"
+ def generate_config
+ conf = {}
+ case node[:platform]
+ when "centos", "redhat", "fedora"
+ # walk the collection
+ run_context.resource_collection.each do |resource|
+ next unless resource.is_a? Chef::Resource::Route
+ # default to eth0
+ dev = if resource.device
+ resource.device
+ else
+ "eth0"
+ end
+
+ conf[dev] = "" if conf[dev].nil?
+ case @action
+ when :add
+ conf[dev] << config_file_contents(:add, target: resource.target, netmask: resource.netmask, gateway: resource.gateway) if resource.action == [:add]
+ when :delete
+ # need to do this for the case when the last route on an int
+ # is removed
+ conf[dev] << config_file_contents(:delete)
+ end
end
-
- conf[dev] = String.new if conf[dev].nil?
- case @action
- when :add
- conf[dev] << config_file_contents(:add, :target => resource.target, :netmask => resource.netmask, :gateway => resource.gateway) if resource.action == [:add]
- when :delete
- # need to do this for the case when the last route on an int
- # is removed
- conf[dev] << config_file_contents(:delete)
+ conf.each do |k, v|
+ network_file_name = "/etc/sysconfig/network-scripts/route-#{k}"
+ converge_by("write route route.#{k}\n#{conf[k]} to #{network_file_name}") do
+ network_file = ::File.new(network_file_name, "w")
+ network_file.puts(conf[k])
+ Chef::Log.debug("#{new_resource} writing route.#{k}\n#{conf[k]}")
+ network_file.close
+ end
end
end
end
- conf.each do |k, v|
- network_file_name = "/etc/sysconfig/network-scripts/route-#{k}"
- converge_by ("write route route.#{k}\n#{conf[k]} to #{ network_file_name }") do
- network_file = ::File.new(network_file_name, "w")
- network_file.puts(conf[k])
- Chef::Log.debug("#{@new_resource} writing route.#{k}\n#{conf[k]}")
- network_file.close
+
+ def generate_command(action)
+ target = new_resource.target
+ target = "#{target}/#{MASK[new_resource.netmask.to_s]}" if new_resource.netmask
+
+ case action
+ when :add
+ command = [ "ip", "route", "replace", target ]
+ command += [ "via", new_resource.gateway ] if new_resource.gateway
+ command += [ "dev", new_resource.device ] if new_resource.device
+ when :delete
+ command = [ "ip", "route", "delete", target ]
+ command += [ "via", new_resource.gateway ] if new_resource.gateway
end
- end
- end
- end
- def generate_command(action)
- common_route_items = ""
- common_route_items << "/#{MASK[@new_resource.netmask.to_s]}" if @new_resource.netmask
- common_route_items << " via #{@new_resource.gateway} " if @new_resource.gateway
-
- case action
- when :add
- command = "ip route replace #{@new_resource.target}"
- command << common_route_items
- command << " dev #{@new_resource.device} " if @new_resource.device
- when :delete
- command = "ip route delete #{@new_resource.target}"
- command << common_route_items
- end
+ command
+ end
- return command
- end
+ def config_file_contents(action, options = {})
+ content = ""
+ case action
+ when :add
+ content << (options[:target]).to_s
+ content << "/#{MASK[options[:netmask].to_s]}" if options[:netmask]
+ content << " via #{options[:gateway]}" if options[:gateway]
+ content << "\n"
+ end
- def config_file_contents(action, options = {})
- content = ""
- case action
- when :add
- content << "#{options[:target]}"
- content << "/#{options[:netmask]}" if options[:netmask]
- content << " via #{options[:gateway]}" if options[:gateway]
- content << "\n"
+ content
+ end
end
-
- return content
end
end
diff --git a/lib/chef/provider/service/arch.rb b/lib/chef/provider/service/arch.rb
index 2fd32e37aa..e34227036a 100644
--- a/lib/chef/provider/service/arch.rb
+++ b/lib/chef/provider/service/arch.rb
@@ -66,7 +66,7 @@ class Chef::Provider::Service::Arch < Chef::Provider::Service::Init
end
end
- def enable_service()
+ def enable_service
new_daemons = []
entries = daemons
@@ -92,7 +92,7 @@ class Chef::Provider::Service::Arch < Chef::Provider::Service::Init
end
end
- def disable_service()
+ def disable_service
new_daemons = []
entries = daemons
diff --git a/lib/chef/provider/service/freebsd.rb b/lib/chef/provider/service/freebsd.rb
index 76d8c1d17b..9746dfdef0 100644
--- a/lib/chef/provider/service/freebsd.rb
+++ b/lib/chef/provider/service/freebsd.rb
@@ -74,7 +74,7 @@ class Chef
end
requirements.assert(:start, :enable, :reload, :restart) do |a|
- a.assertion { service_enable_variable_name != nil }
+ a.assertion { !service_enable_variable_name.nil? }
a.failure_message Chef::Exceptions::Service, "Could not find the service name in #{init_command} and rcvar"
# No recovery in whyrun mode - the init file is present but not correct.
end
diff --git a/lib/chef/provider/service/gentoo.rb b/lib/chef/provider/service/gentoo.rb
index 8fb6d1f9af..7bb57113ac 100644
--- a/lib/chef/provider/service/gentoo.rb
+++ b/lib/chef/provider/service/gentoo.rb
@@ -61,11 +61,11 @@ class Chef::Provider::Service::Gentoo < Chef::Provider::Service::Init
end
end
- def enable_service()
+ def enable_service
shell_out!("/sbin/rc-update add #{@new_resource.service_name} default")
end
- def disable_service()
+ def disable_service
shell_out!("/sbin/rc-update del #{@new_resource.service_name} default")
end
end
diff --git a/lib/chef/provider/service/insserv.rb b/lib/chef/provider/service/insserv.rb
index 76b2ee7477..c3dca10495 100644
--- a/lib/chef/provider/service/insserv.rb
+++ b/lib/chef/provider/service/insserv.rb
@@ -45,12 +45,12 @@ class Chef
current_resource
end
- def enable_service()
+ def enable_service
shell_out!("/sbin/insserv -r -f #{new_resource.service_name}")
shell_out!("/sbin/insserv -d -f #{new_resource.service_name}")
end
- def disable_service()
+ def disable_service
shell_out!("/sbin/insserv -r -f #{new_resource.service_name}")
end
end
diff --git a/lib/chef/provider/service/macosx.rb b/lib/chef/provider/service/macosx.rb
index 648cd9748b..4056b72649 100644
--- a/lib/chef/provider/service/macosx.rb
+++ b/lib/chef/provider/service/macosx.rb
@@ -181,7 +181,7 @@ class Chef
end
def set_service_status
- return if @plist == nil || @service_label.to_s.empty?
+ return if @plist.nil? || @service_label.to_s.empty?
cmd = "launchctl list #{@service_label}"
res = shell_out_as_user(cmd)
@@ -197,7 +197,7 @@ class Chef
case line.downcase
when /\s+\"pid\"\s+=\s+(\d+).*/
pid = $1
- @current_resource.running(!pid.to_i.zero?)
+ @current_resource.running(pid.to_i != 0)
Chef::Log.debug("Current PID for #{@service_label} is #{pid}")
end
end
diff --git a/lib/chef/provider/service/openbsd.rb b/lib/chef/provider/service/openbsd.rb
index c60bbf170c..780337e1b6 100644
--- a/lib/chef/provider/service/openbsd.rb
+++ b/lib/chef/provider/service/openbsd.rb
@@ -72,7 +72,7 @@ class Chef
end
requirements.assert(:start, :enable, :reload, :restart) do |a|
- a.assertion { init_command && builtin_service_enable_variable_name != nil }
+ a.assertion { init_command && !builtin_service_enable_variable_name.nil? }
a.failure_message Chef::Exceptions::Service, "Could not find the service name in #{init_command} and rcvar"
# No recovery in whyrun mode - the init file is present but not correct.
end
diff --git a/lib/chef/provider/service/redhat.rb b/lib/chef/provider/service/redhat.rb
index 200a2d3400..21ab678706 100644
--- a/lib/chef/provider/service/redhat.rb
+++ b/lib/chef/provider/service/redhat.rb
@@ -109,7 +109,7 @@ class Chef
(run_levels.nil? || run_levels.empty?) ? "" : "--level #{run_levels.join('')} "
end
- def enable_service()
+ def enable_service
unless run_levels.nil? || run_levels.empty?
disable_levels = current_run_levels - run_levels
shell_out! "/sbin/chkconfig --level #{disable_levels.join('')} #{new_resource.service_name} off" unless disable_levels.empty?
@@ -117,7 +117,7 @@ class Chef
shell_out! "/sbin/chkconfig #{levels}#{new_resource.service_name} on"
end
- def disable_service()
+ def disable_service
shell_out! "/sbin/chkconfig #{levels}#{new_resource.service_name} off"
end
end
diff --git a/lib/chef/provider/support/yum_repo.erb b/lib/chef/provider/support/yum_repo.erb
index 7d9a2d09e2..6f1325573d 100644
--- a/lib/chef/provider/support/yum_repo.erb
+++ b/lib/chef/provider/support/yum_repo.erb
@@ -4,8 +4,13 @@
[<%= @config.repositoryid %>]
name=<%= @config.description %>
<% if @config.baseurl %>
-baseurl=<%= @config.baseurl %>
-<% end %>
+baseurl=<%= case @config.baseurl
+ when Array
+ @config.baseurl.join("\n")
+ else
+ @config.baseurl
+ end %>
+<% end -%>
<% if @config.cost %>
cost=<%= @config.cost %>
<% end %>
@@ -24,7 +29,9 @@ exclude=<%= @config.exclude %>
failovermethod=<%= @config.failovermethod %>
<% end %>
<% if @config.fastestmirror_enabled %>
-fastestmirror_enabled=<%= @config.fastestmirror_enabled %>
+fastestmirror_enabled=1
+<% else %>
+fastestmirror_enabled=0
<% end %>
<% if @config.gpgcheck %>
gpgcheck=1
diff --git a/lib/chef/provider/systemd_unit.rb b/lib/chef/provider/systemd_unit.rb
index a656fbbf80..5175dc6be9 100644
--- a/lib/chef/provider/systemd_unit.rb
+++ b/lib/chef/provider/systemd_unit.rb
@@ -20,6 +20,7 @@ require "chef/provider"
require "chef/mixin/which"
require "chef/mixin/shell_out"
require "chef/resource/file"
+require "chef/resource/file/verification/systemd_unit"
require "iniparse"
class Chef
@@ -193,6 +194,7 @@ class Chef
f.group "root"
f.mode "0644"
f.content new_resource.to_ini
+ f.verify :systemd_unit
end.run_action(action)
end
diff --git a/lib/chef/provider/user.rb b/lib/chef/provider/user.rb
index 4b05ac8f5e..de94871a87 100644
--- a/lib/chef/provider/user.rb
+++ b/lib/chef/provider/user.rb
@@ -39,7 +39,7 @@ class Chef
if @new_resource.gid.is_a? String
@new_resource.gid(Etc.getgrnam(@new_resource.gid).gid)
end
- rescue ArgumentError => e
+ rescue ArgumentError
@group_name_resolved = false
end
@@ -53,7 +53,7 @@ class Chef
begin
user_info = Etc.getpwnam(@new_resource.username)
- rescue ArgumentError => e
+ rescue ArgumentError
@user_exists = false
Chef::Log.debug("#{@new_resource} user does not exist")
user_info = nil
@@ -97,7 +97,7 @@ class Chef
requirements.assert(:all_actions) do |a|
a.assertion { @shadow_lib_ok }
a.failure_message Chef::Exceptions::MissingLibrary, "You must have ruby-shadow installed for password support!"
- a.whyrun "ruby-shadow is not installed. Attempts to set user password will cause failure. Assuming that this gem will have been previously installed." +
+ a.whyrun "ruby-shadow is not installed. Attempts to set user password will cause failure. Assuming that this gem will have been previously installed." \
"Note that user update converge may report false-positive on the basis of mismatched password. "
end
requirements.assert(:modify, :lock, :unlock) do |a|
@@ -137,34 +137,31 @@ class Chef
end
def action_remove
- if @user_exists
- converge_by("remove user #{@new_resource.username}") do
- remove_user
- Chef::Log.info("#{@new_resource} removed")
- end
+ return unless @user_exists
+ converge_by("remove user #{@new_resource.username}") do
+ remove_user
+ Chef::Log.info("#{@new_resource} removed")
end
end
def action_manage
- if @user_exists && compare_user
- converge_by("manage user #{@new_resource.username}") do
- manage_user
- Chef::Log.info("#{@new_resource} managed")
- end
+ return unless @user_exists && compare_user
+ converge_by("manage user #{@new_resource.username}") do
+ manage_user
+ Chef::Log.info("#{@new_resource} managed")
end
end
def action_modify
- if compare_user
- converge_by("modify user #{@new_resource.username}") do
- manage_user
- Chef::Log.info("#{@new_resource} modified")
- end
+ return unless compare_user
+ converge_by("modify user #{@new_resource.username}") do
+ manage_user
+ Chef::Log.info("#{@new_resource} modified")
end
end
def action_lock
- if check_lock() == false
+ if check_lock == false
converge_by("lock the user #{@new_resource.username}") do
lock_user
Chef::Log.info("#{@new_resource} locked")
@@ -175,7 +172,7 @@ class Chef
end
def action_unlock
- if check_lock() == true
+ if check_lock == true
converge_by("unlock user #{@new_resource.username}") do
unlock_user
Chef::Log.info("#{@new_resource} unlocked")
diff --git a/lib/chef/provider/user/aix.rb b/lib/chef/provider/user/aix.rb
index 8ac229ae4d..0e81c76bbc 100644
--- a/lib/chef/provider/user/aix.rb
+++ b/lib/chef/provider/user/aix.rb
@@ -23,7 +23,7 @@ class Chef
provides :user, os: "aix"
provides :aix_user
- UNIVERSAL_OPTIONS = [[:comment, "-c"], [:gid, "-g"], [:shell, "-s"], [:uid, "-u"]]
+ UNIVERSAL_OPTIONS = [[:comment, "-c"], [:gid, "-g"], [:shell, "-s"], [:uid, "-u"]].freeze
def create_user
super
@@ -44,53 +44,52 @@ class Chef
end
def check_lock
- lock_info = shell_out!("lsuser -a account_locked #{new_resource.username}")
+ lock_info = shell_out_compact!("lsuser", "-a", "account_locked", new_resource.username)
if whyrun_mode? && passwd_s.stdout.empty? && lock_info.stderr.match(/does not exist/)
# if we're in whyrun mode and the user is not yet created we assume it would be
return false
end
- raise Chef::Exceptions::User, "Cannot determine if #{@new_resource} is locked!" if lock_info.stdout.empty?
+ raise Chef::Exceptions::User, "Cannot determine if #{new_resource} is locked!" if lock_info.stdout.empty?
status = /\S+\s+account_locked=(\S+)/.match(lock_info.stdout)
- if status && status[1] == "true"
- @locked = true
- else
- @locked = false
- end
+ @locked =
+ if status && status[1] == "true"
+ true
+ else
+ false
+ end
@locked
end
def lock_user
- shell_out!("chuser account_locked=true #{new_resource.username}")
+ shell_out_compact!("chuser", "account_locked=true", new_resource.username)
end
def unlock_user
- shell_out!("chuser account_locked=false #{new_resource.username}")
+ shell_out_compact!("chuser", "account_locked=false", new_resource.username)
end
private
def add_password
- if @current_resource.password != @new_resource.password && @new_resource.password
- Chef::Log.debug("#{@new_resource.username} setting password to #{@new_resource.password}")
- command = "echo '#{@new_resource.username}:#{@new_resource.password}' | chpasswd -e"
- shell_out!(command)
- end
+ return unless current_resource.password != new_resource.password && new_resource.password
+ Chef::Log.debug("#{new_resource.username} setting password to #{new_resource.password}")
+ command = "echo '#{new_resource.username}:#{new_resource.password}' | chpasswd -e"
+ shell_out!(command)
end
# Aix specific handling to update users home directory.
def manage_home
+ return unless updating_home? && managing_home_dir?
# -m option does not work on aix, so move dir.
- if updating_home? && managing_home_dir?
- universal_options.delete("-m")
- if ::File.directory?(@current_resource.home)
- Chef::Log.debug("Changing users home directory from #{@current_resource.home} to #{new_resource.home}")
- shell_out!("mv #{@current_resource.home} #{new_resource.home}")
- else
- Chef::Log.debug("Creating users home directory #{new_resource.home}")
- shell_out!("mkdir -p #{new_resource.home}")
- end
+ universal_options.delete("-m")
+ if ::File.directory?(current_resource.home)
+ Chef::Log.debug("Changing users home directory from #{current_resource.home} to #{new_resource.home}")
+ FileUtils.mv current_resource.home, new_resource.home
+ else
+ Chef::Log.debug("Creating users home directory #{new_resource.home}")
+ FileUtils.mkdir_p new_resource.home
end
end
diff --git a/lib/chef/provider/user/dscl.rb b/lib/chef/provider/user/dscl.rb
index 16d60ba116..2302a874e2 100644
--- a/lib/chef/provider/user/dscl.rb
+++ b/lib/chef/provider/user/dscl.rb
@@ -65,12 +65,12 @@ class Chef
end
requirements.assert(:all_actions) do |a|
- a.assertion { ::File.exists?("/usr/bin/dscl") }
+ a.assertion { ::File.exist?("/usr/bin/dscl") }
a.failure_message(Chef::Exceptions::User, "Cannot find binary '/usr/bin/dscl' on the system for #{new_resource}!")
end
requirements.assert(:all_actions) do |a|
- a.assertion { ::File.exists?("/usr/bin/plutil") }
+ a.assertion { ::File.exist?("/usr/bin/plutil") }
a.failure_message(Chef::Exceptions::User, "Cannot find binary '/usr/bin/plutil' on the system for #{new_resource}!")
end
@@ -199,7 +199,7 @@ user password using shadow hash.")
# Create a user using dscl
#
def dscl_create_user
- run_dscl("create /Users/#{new_resource.username}")
+ run_dscl("create", "/Users/#{new_resource.username}")
end
#
@@ -208,7 +208,7 @@ user password using shadow hash.")
#
def dscl_create_comment
comment = new_resource.comment || new_resource.username
- run_dscl("create /Users/#{new_resource.username} RealName '#{comment}'")
+ run_dscl("create", "/Users/#{new_resource.username}", "RealName", comment)
end
#
@@ -224,7 +224,7 @@ user password using shadow hash.")
raise(Chef::Exceptions::RequestedUIDUnavailable, "uid #{new_resource.uid} is already in use")
end
- run_dscl("create /Users/#{new_resource.username} UniqueID #{new_resource.uid}")
+ run_dscl("create", "/Users/#{new_resource.username}", "UniqueID", new_resource.uid)
end
#
@@ -235,7 +235,7 @@ user password using shadow hash.")
uid = nil
base_uid = new_resource.system ? 200 : 500
next_uid_guess = base_uid
- users_uids = run_dscl("list /Users uid")
+ users_uids = run_dscl("list", "/Users", "uid")
while next_uid_guess < search_limit + base_uid
if users_uids =~ Regexp.new("#{Regexp.escape(next_uid_guess.to_s)}\n")
next_uid_guess += 1
@@ -244,7 +244,7 @@ user password using shadow hash.")
break
end
end
- return uid || raise("uid not found. Exhausted. Searched #{search_limit} times")
+ uid || raise("uid not found. Exhausted. Searched #{search_limit} times")
end
#
@@ -252,18 +252,18 @@ user password using shadow hash.")
#
def uid_used?(uid)
return false unless uid
- users_uids = run_dscl("list /Users uid").split("\n")
- uid_map = users_uids.inject({}) do |tmap, tuid|
+ users_uids = run_dscl("list", "/Users", "uid").split("\n")
+ uid_map = users_uids.each_with_object({}) do |tuid, tmap|
x = tuid.split
tmap[x[1]] = x[0]
tmap
end
if uid_map[uid.to_s]
- unless uid_map[uid.to_s] == new_resource.username.to_s
+ unless uid_map[uid.to_s] == new_resource.username
return true
end
end
- return false
+ false
end
#
@@ -277,14 +277,14 @@ user password using shadow hash.")
new_resource.gid(STAFF_GROUP_ID)
elsif !new_resource.gid.to_s.match(/^\d+$/)
begin
- possible_gid = run_dscl("read /Groups/#{new_resource.gid} PrimaryGroupID").split(" ").last
- rescue Chef::Exceptions::DsclCommandFailed => e
- raise Chef::Exceptions::GroupIDNotFound.new("Group not found for #{new_resource.gid} when creating user #{new_resource.username}")
+ possible_gid = run_dscl("read", "/Groups/#{new_resource.gid}", "PrimaryGroupID").split(" ").last
+ rescue Chef::Exceptions::DsclCommandFailed
+ raise Chef::Exceptions::GroupIDNotFound, "Group not found for #{new_resource.gid} when creating user #{new_resource.username}"
end
# XXX: mutates the new resource
new_resource.gid(possible_gid) if possible_gid && possible_gid.match(/^\d+$/)
end
- run_dscl("create /Users/#{new_resource.username} PrimaryGroupID '#{new_resource.gid}'")
+ run_dscl("create", "/Users/#{new_resource.username}", "PrimaryGroupID", new_resource.gid)
end
#
@@ -293,7 +293,7 @@ user password using shadow hash.")
#
def dscl_set_home
if new_resource.home.nil? || new_resource.home.empty?
- run_dscl("delete /Users/#{new_resource.username} NFSHomeDirectory")
+ run_dscl("delete", "/Users/#{new_resource.username}", "NFSHomeDirectory")
return
end
@@ -308,7 +308,7 @@ user password using shadow hash.")
move_home
end
end
- run_dscl("create /Users/#{new_resource.username} NFSHomeDirectory '#{new_resource.home}'")
+ run_dscl("create", "/Users/#{new_resource.username}", "NFSHomeDirectory", new_resource.home)
end
def validate_home_dir_specification!
@@ -318,17 +318,17 @@ user password using shadow hash.")
end
def current_home_exists?
- ::File.exist?("#{current_resource.home}")
+ ::File.exist?(current_resource.home)
end
def new_home_exists?
- ::File.exist?("#{new_resource.home}")
+ ::File.exist?(new_resource.home)
end
def ditto_home
skel = "/System/Library/User Template/English.lproj"
- raise(Chef::Exceptions::User, "can't find skel at: #{skel}") unless ::File.exists?(skel)
- shell_out! "ditto '#{skel}' '#{new_resource.home}'"
+ raise(Chef::Exceptions::User, "can't find skel at: #{skel}") unless ::File.exist?(skel)
+ shell_out_compact!("ditto", skel, new_resource.home)
::FileUtils.chown_R(new_resource.username, new_resource.gid.to_s, new_resource.home)
end
@@ -338,7 +338,7 @@ user password using shadow hash.")
src = current_resource.home
FileUtils.mkdir_p(new_resource.home)
files = ::Dir.glob("#{Chef::Util::PathHelper.escape_glob_dir(src)}/*", ::File::FNM_DOTMATCH) - ["#{src}/.", "#{src}/.."]
- ::FileUtils.mv(files, new_resource.home, :force => true)
+ ::FileUtils.mv(files, new_resource.home, force: true)
::FileUtils.rmdir(src)
::FileUtils.chown_R(new_resource.username, new_resource.gid.to_s, new_resource.home)
end
@@ -347,10 +347,10 @@ user password using shadow hash.")
# Sets the shell for the user using dscl.
#
def dscl_set_shell
- if new_resource.shell || ::File.exists?("#{new_resource.shell}")
- run_dscl("create /Users/#{new_resource.username} UserShell '#{new_resource.shell}'")
+ if new_resource.shell
+ run_dscl("create", "/Users/#{new_resource.username}", "UserShell", new_resource.shell)
else
- run_dscl("create /Users/#{new_resource.username} UserShell '/usr/bin/false'")
+ run_dscl("create", "/Users/#{new_resource.username}", "UserShell", "/usr/bin/false")
end
end
@@ -367,9 +367,8 @@ user password using shadow hash.")
# Shadow info is saved as binary plist. Convert the info to binary plist.
shadow_info_binary = StringIO.new
- command = Mixlib::ShellOut.new("plutil -convert binary1 -o - -",
- :input => shadow_info.to_plist, :live_stream => shadow_info_binary)
- command.run_command
+ shell_out_compact("plutil", "-convert", "binary1", "-o", "-", "-",
+ input: shadow_info.to_plist, live_stream: shadow_info_binary)
if user_info.nil?
# User is just created. read_user_info() will read the fresh information
@@ -401,7 +400,7 @@ user password using shadow hash.")
# Create a random 4 byte salt
salt = OpenSSL::Random.random_bytes(4)
encoded_password = OpenSSL::Digest::SHA512.hexdigest(salt + new_resource.password)
- hash_value = salt.unpack("H*").first + encoded_password
+ salt.unpack("H*").first + encoded_password
end
shadow_info["SALTED-SHA512"] = StringIO.new
@@ -449,21 +448,21 @@ user password using shadow hash.")
end
# Remove the user from its groups
- run_dscl("list /Groups").each_line do |group|
+ run_dscl("list", "/Groups").each_line do |group|
if member_of_group?(group.chomp)
- run_dscl("delete /Groups/#{group.chomp} GroupMembership '#{new_resource.username}'")
+ run_dscl("delete", "/Groups/#{group.chomp}", "GroupMembership", new_resource.username)
end
end
# Remove user account
- run_dscl("delete /Users/#{new_resource.username}")
+ run_dscl("delete", "/Users/#{new_resource.username}")
end
#
# Locks the user.
#
def lock_user
- run_dscl("append /Users/#{new_resource.username} AuthenticationAuthority ';DisabledUser;'")
+ run_dscl("append", "/Users/#{new_resource.username}", "AuthenticationAuthority", ";DisabledUser;")
end
#
@@ -471,7 +470,7 @@ user password using shadow hash.")
#
def unlock_user
auth_string = authentication_authority.gsub(/AuthenticationAuthority: /, "").gsub(/;DisabledUser;/, "").strip
- run_dscl("create /Users/#{new_resource.username} AuthenticationAuthority '#{auth_string}'")
+ run_dscl("create", "/Users/#{new_resource.username}", "AuthenticationAuthority", auth_string)
end
#
@@ -489,7 +488,7 @@ user password using shadow hash.")
# This is the interface base User provider requires to provide idempotency.
#
def check_lock
- return @locked = locked?
+ @locked = locked?
end
#
@@ -501,11 +500,11 @@ user password using shadow hash.")
# given attribute.
#
def diverged?(parameter)
- parameter_updated?(parameter) && (not new_resource.send(parameter).nil?)
+ parameter_updated?(parameter) && !new_resource.send(parameter).nil?
end
def parameter_updated?(parameter)
- not (new_resource.send(parameter) == current_resource.send(parameter))
+ !(new_resource.send(parameter) == current_resource.send(parameter))
end
#
@@ -551,7 +550,7 @@ user password using shadow hash.")
def member_of_group?(group_name)
membership_info = ""
begin
- membership_info = run_dscl("read /Groups/#{group_name}")
+ membership_info = run_dscl("read", "/Groups/#{group_name}")
rescue Chef::Exceptions::DsclCommandFailed
# Raised if the group doesn't contain any members
end
@@ -568,14 +567,14 @@ user password using shadow hash.")
# A simple map of Chef's terms to DSCL's terms.
DSCL_PROPERTY_MAP = {
- :uid => "uid",
- :gid => "gid",
- :home => "home",
- :shell => "shell",
- :comment => "realname",
- :password => "passwd",
- :auth_authority => "authentication_authority",
- :shadow_hash => "ShadowHashData",
+ uid: "uid",
+ gid: "gid",
+ home: "home",
+ shell: "shell",
+ comment: "realname",
+ password: "passwd",
+ auth_authority: "authentication_authority",
+ shadow_hash: "ShadowHashData",
}.freeze
# Directory where the user plist files are stored for versions 10.7 and above
@@ -590,11 +589,11 @@ user password using shadow hash.")
# We flush the cache here in order to make sure that we read fresh information
# for the user.
- shell_out("dscacheutil '-flushcache'")
+ shell_out_compact("dscacheutil", "-flushcache") # FIXME: this is MacOS version dependent
begin
user_plist_file = "#{USER_PLIST_DIRECTORY}/#{new_resource.username}.plist"
- user_plist_info = run_plutil("convert xml1 -o - #{user_plist_file}")
+ user_plist_info = run_plutil("convert", "xml1", "-o", "-", user_plist_file)
user_info = Plist.parse_xml(user_plist_info)
rescue Chef::Exceptions::PlistUtilCommandFailed
end
@@ -609,7 +608,7 @@ user password using shadow hash.")
def save_user_info(user_info)
user_plist_file = "#{USER_PLIST_DIRECTORY}/#{new_resource.username}.plist"
Plist::Emit.save_plist(user_info, user_plist_file)
- run_plutil("convert binary1 #{user_plist_file}")
+ run_plutil("convert", "binary1", user_plist_file)
end
#
@@ -658,7 +657,9 @@ user password using shadow hash.")
end
def run_dscl(*args)
- result = shell_out("dscl . -#{args.join(' ')}")
+ argdup = args.dup
+ cmd = argdup.shift
+ result = shell_out_compact("dscl", ".", "-#{cmd}", argdup)
return "" if ( args.first =~ /^delete/ ) && ( result.exitstatus != 0 )
raise(Chef::Exceptions::DsclCommandFailed, "dscl error: #{result.inspect}") unless result.exitstatus == 0
raise(Chef::Exceptions::DsclCommandFailed, "dscl error: #{result.inspect}") if result.stdout =~ /No such key: /
@@ -666,17 +667,19 @@ user password using shadow hash.")
end
def run_plutil(*args)
- result = shell_out("plutil -#{args.join(' ')}")
+ argdup = args.dup
+ cmd = argdup.shift
+ result = shell_out_compact("plutil", "-#{cmd}", argdup)
raise(Chef::Exceptions::PlistUtilCommandFailed, "plutil error: #{result.inspect}") unless result.exitstatus == 0
if result.stdout.encoding == Encoding::ASCII_8BIT
- result.stdout.encode("utf-8", "binary", :undef => :replace, :invalid => :replace, :replace => "?")
+ result.stdout.encode("utf-8", "binary", undef: :replace, invalid: :replace, replace: "?")
else
result.stdout
end
end
def convert_binary_plist_to_xml(binary_plist_string)
- Mixlib::ShellOut.new("plutil -convert xml1 -o - -", :input => binary_plist_string).run_command.stdout
+ shell_out_compact("plutil", "-convert", "xml1", "-o", "-", "-", input: binary_plist_string).stdout
end
def convert_to_binary(string)
diff --git a/lib/chef/provider/user/linux.rb b/lib/chef/provider/user/linux.rb
index 968cf771e4..445421ad38 100644
--- a/lib/chef/provider/user/linux.rb
+++ b/lib/chef/provider/user/linux.rb
@@ -24,23 +24,23 @@ class Chef
provides :user, os: "linux"
def create_user
- shell_out!(*clean_array("useradd", universal_options, useradd_options, new_resource.username))
+ shell_out_compact!("useradd", universal_options, useradd_options, new_resource.username)
end
def manage_user
- shell_out!(*clean_array("usermod", universal_options, usermod_options, new_resource.username))
+ shell_out_compact!("usermod", universal_options, usermod_options, new_resource.username)
end
def remove_user
- shell_out!(*clean_array("userdel", userdel_options, new_resource.username))
+ shell_out_compact!("userdel", userdel_options, new_resource.username)
end
def lock_user
- shell_out!(*clean_array("usermod", "-L", new_resource.username))
+ shell_out_compact!("usermod", "-L", new_resource.username)
end
def unlock_user
- shell_out!(*clean_array("usermod", "-U", new_resource.username))
+ shell_out_compact!("usermod", "-U", new_resource.username)
end
# common to usermod and useradd
@@ -69,11 +69,11 @@ class Chef
def useradd_options
opts = []
opts << "-r" if new_resource.system
- if managing_home_dir?
- opts << "-m"
- else
- opts << "-M"
- end
+ opts << if managing_home_dir?
+ "-m"
+ else
+ "-M"
+ end
opts
end
@@ -97,15 +97,12 @@ class Chef
def check_lock
# there's an old bug in rhel (https://bugzilla.redhat.com/show_bug.cgi?id=578534)
# which means that both 0 and 1 can be success.
- passwd_s = shell_out("passwd", "-S", new_resource.username, returns: [ 0, 1 ])
+ passwd_s = shell_out_compact("passwd", "-S", new_resource.username, returns: [ 0, 1 ])
# checking "does not exist" has to come before exit code handling since centos and ubuntu differ in exit codes
if passwd_s.stderr =~ /does not exist/
- if whyrun_mode?
- return false
- else
- raise Chef::Exceptions::User, "User #{new_resource.username} does not exist when checking lock status for #{new_resource}"
- end
+ return false if whyrun_mode?
+ raise Chef::Exceptions::User, "User #{new_resource.username} does not exist when checking lock status for #{new_resource}"
end
# now raise if we didn't get a 0 or 1 (see above)
diff --git a/lib/chef/provider/user/pw.rb b/lib/chef/provider/user/pw.rb
index b210374eb9..42d862a983 100644
--- a/lib/chef/provider/user/pw.rb
+++ b/lib/chef/provider/user/pw.rb
@@ -27,49 +27,45 @@ class Chef
def load_current_resource
super
- raise Chef::Exceptions::User, "Could not find binary /usr/sbin/pw for #{@new_resource}" unless ::File.exists?("/usr/sbin/pw")
+ raise Chef::Exceptions::User, "Could not find binary /usr/sbin/pw for #{new_resource}" unless ::File.exist?("/usr/sbin/pw")
end
def create_user
- command = "pw useradd"
- command << set_options
- run_command(:command => command)
+ shell_out_compact!("pw", "useradd", set_options)
modify_password
end
def manage_user
- command = "pw usermod"
- command << set_options
- run_command(:command => command)
+ shell_out_compact!("pw", "usermod", set_options)
modify_password
end
def remove_user
- command = "pw userdel #{@new_resource.username}"
- command << " -r" if managing_home_dir?
- run_command(:command => command)
+ command = [ "pw", "userdel", new_resource.username ]
+ command << "-r" if managing_home_dir?
+ shell_out_compact!(command)
end
def check_lock
- case @current_resource.password
- when /^\*LOCKED\*/
- @locked = true
- else
- @locked = false
- end
+ @locked = case current_resource.password
+ when /^\*LOCKED\*/
+ true
+ else
+ false
+ end
@locked
end
def lock_user
- run_command(:command => "pw lock #{@new_resource.username}")
+ shell_out_compact!("pw", "lock", new_resource.username)
end
def unlock_user
- run_command(:command => "pw unlock #{@new_resource.username}")
+ shell_out_compact!("pw", "unlock", new_resource.username)
end
def set_options
- opts = " #{@new_resource.username}"
+ opts = [ new_resource.username ]
field_list = {
"comment" => "-c",
@@ -80,26 +76,26 @@ class Chef
}
field_list.sort { |a, b| a[0] <=> b[0] }.each do |field, option|
field_symbol = field.to_sym
- if @current_resource.send(field_symbol) != @new_resource.send(field_symbol)
- if @new_resource.send(field_symbol)
- Chef::Log.debug("#{@new_resource} setting #{field} to #{@new_resource.send(field_symbol)}")
- opts << " #{option} '#{@new_resource.send(field_symbol)}'"
- end
+ next unless current_resource.send(field_symbol) != new_resource.send(field_symbol)
+ if new_resource.send(field_symbol)
+ Chef::Log.debug("#{new_resource} setting #{field} to #{new_resource.send(field_symbol)}")
+ opts << option
+ opts << new_resource.send(field_symbol)
end
end
if managing_home_dir?
- Chef::Log.debug("#{@new_resource} is managing the users home directory")
- opts << " -m"
+ Chef::Log.debug("#{new_resource} is managing the users home directory")
+ opts << "-m"
end
opts
end
def modify_password
- if (not @new_resource.password.nil?) && (@current_resource.password != @new_resource.password)
+ if !new_resource.password.nil? && (current_resource.password != new_resource.password)
Chef::Log.debug("#{new_resource} updating password")
- command = "pw usermod #{@new_resource.username} -H 0"
- status = popen4(command, :waitlast => true) do |pid, stdin, stdout, stderr|
- stdin.puts "#{@new_resource.password}"
+ command = "pw usermod #{new_resource.username} -H 0"
+ status = popen4(command, waitlast: true) do |pid, stdin, stdout, stderr|
+ stdin.puts new_resource.password.to_s
end
unless status.exitstatus == 0
diff --git a/lib/chef/provider/user/solaris.rb b/lib/chef/provider/user/solaris.rb
index 7aa0ceb93a..4e772312ae 100644
--- a/lib/chef/provider/user/solaris.rb
+++ b/lib/chef/provider/user/solaris.rb
@@ -26,7 +26,7 @@ class Chef
class Solaris < Chef::Provider::User::Useradd
provides :solaris_user
provides :user, os: %w{omnios solaris2}
- UNIVERSAL_OPTIONS = [[:comment, "-c"], [:gid, "-g"], [:shell, "-s"], [:uid, "-u"]]
+ UNIVERSAL_OPTIONS = [[:comment, "-c"], [:gid, "-g"], [:shell, "-s"], [:uid, "-u"]].freeze
attr_writer :password_file
@@ -46,22 +46,22 @@ class Chef
end
def check_lock
- user = IO.read(@password_file).match(/^#{Regexp.escape(@new_resource.username)}:([^:]*):/)
+ user = IO.read(@password_file).match(/^#{Regexp.escape(new_resource.username)}:([^:]*):/)
# If we're in whyrun mode, and the user is not created, we assume it will be
return false if whyrun_mode? && user.nil?
- raise Chef::Exceptions::User, "Cannot determine if #{@new_resource} is locked!" if user.nil?
+ raise Chef::Exceptions::User, "Cannot determine if #{new_resource} is locked!" if user.nil?
@locked = user[1].start_with?("*LK*")
end
def lock_user
- shell_out!("passwd", "-l", new_resource.username)
+ shell_out_compact!("passwd", "-l", new_resource.username)
end
def unlock_user
- shell_out!("passwd", "-u", new_resource.username)
+ shell_out_compact!("passwd", "-u", new_resource.username)
end
private
@@ -82,10 +82,9 @@ class Chef
end
def manage_password
- if @current_resource.password != @new_resource.password && @new_resource.password
- Chef::Log.debug("#{@new_resource} setting password to #{@new_resource.password}")
- write_shadow_file
- end
+ return unless current_resource.password != new_resource.password && new_resource.password
+ Chef::Log.debug("#{new_resource} setting password to #{new_resource.password}")
+ write_shadow_file
end
def write_shadow_file
@@ -93,7 +92,7 @@ class Chef
::File.open(@password_file) do |shadow_file|
shadow_file.each do |entry|
user = entry.split(":").first
- if user == @new_resource.username
+ if user == new_resource.username
buffer.write(updated_password(entry))
else
buffer.write(entry)
@@ -104,7 +103,7 @@ class Chef
# FIXME: mostly duplicates code with file provider deploying a file
s = ::File.stat(@password_file)
- mode = s.mode & 07777
+ mode = s.mode & 0o7777
uid = s.uid
gid = s.gid
@@ -116,7 +115,7 @@ class Chef
def updated_password(entry)
fields = entry.split(":")
- fields[1] = @new_resource.password
+ fields[1] = new_resource.password
fields[2] = days_since_epoch
fields.join(":")
end
diff --git a/lib/chef/provider/user/useradd.rb b/lib/chef/provider/user/useradd.rb
index 35a106b0b6..cf6f4e727f 100644
--- a/lib/chef/provider/user/useradd.rb
+++ b/lib/chef/provider/user/useradd.rb
@@ -23,25 +23,25 @@ class Chef
class Provider
class User
class Useradd < Chef::Provider::User
- # MAJOR XXX: this should become the base class of all Useradd providers instead of the linux implementation
+ # the linux version of this has been forked off, this is the base class now of solaris and AIX and should be abandoned
+ # and those provider should be rewritten like the linux version.
- UNIVERSAL_OPTIONS = [[:comment, "-c"], [:gid, "-g"], [:password, "-p"], [:shell, "-s"], [:uid, "-u"]]
+ UNIVERSAL_OPTIONS = [[:comment, "-c"], [:gid, "-g"], [:password, "-p"], [:shell, "-s"], [:uid, "-u"]].freeze
def create_user
command = compile_command("useradd") do |useradd|
useradd.concat(universal_options)
useradd.concat(useradd_options)
end
- shell_out!(*command)
+ shell_out_compact!(command)
end
def manage_user
- unless universal_options.empty?
- command = compile_command("usermod") do |u|
- u.concat(universal_options)
- end
- shell_out!(*command)
+ return if universal_options.empty?
+ command = compile_command("usermod") do |u|
+ u.concat(universal_options)
end
+ shell_out_compact!(command)
end
def remove_user
@@ -49,19 +49,19 @@ class Chef
command << "-r" if managing_home_dir?
command << "-f" if new_resource.force
command << new_resource.username
- shell_out!(*command)
+ shell_out_compact!(command)
end
def check_lock
# we can get an exit code of 1 even when it's successful on
# rhel/centos (redhat bug 578534). See additional error checks below.
- passwd_s = shell_out!("passwd", "-S", new_resource.username, :returns => [0, 1])
+ passwd_s = shell_out_compact!("passwd", "-S", new_resource.username, returns: [0, 1])
if whyrun_mode? && passwd_s.stdout.empty? && passwd_s.stderr.match(/does not exist/)
# if we're in whyrun mode and the user is not yet created we assume it would be
return false
end
- raise Chef::Exceptions::User, "Cannot determine if #{@new_resource} is locked!" if passwd_s.stdout.empty?
+ raise Chef::Exceptions::User, "Cannot determine if #{new_resource} is locked!" if passwd_s.stdout.empty?
status_line = passwd_s.stdout.split(" ")
case status_line[1]
@@ -76,7 +76,7 @@ class Chef
unless passwd_s.exitstatus == 0
raise_lock_error = false
if %w{redhat centos}.include?(node[:platform])
- passwd_version_check = shell_out!("rpm -q passwd")
+ passwd_version_check = shell_out_compact!("rpm", "-q", "passwd")
passwd_version = passwd_version_check.stdout.chomp
unless passwd_version == "passwd-0.73-1"
@@ -93,11 +93,11 @@ class Chef
end
def lock_user
- shell_out!("usermod", "-L", new_resource.username)
+ shell_out_compact!("usermod", "-L", new_resource.username)
end
def unlock_user
- shell_out!("usermod", "-U", new_resource.username)
+ shell_out_compact!("usermod", "-U", new_resource.username)
end
def compile_command(base_command)
@@ -130,12 +130,10 @@ class Chef
end
def update_options(field, option, opts)
- if @current_resource.send(field).to_s != new_resource.send(field).to_s
- if new_resource.send(field)
- Chef::Log.debug("#{new_resource} setting #{field} to #{new_resource.send(field)}")
- opts << option << new_resource.send(field).to_s
- end
- end
+ return unless current_resource.send(field).to_s != new_resource.send(field).to_s
+ return unless new_resource.send(field)
+ Chef::Log.debug("#{new_resource} setting #{field} to #{new_resource.send(field)}")
+ opts << option << new_resource.send(field).to_s
end
def useradd_options
@@ -150,8 +148,8 @@ class Chef
# Pathname#cleanpath does a better job than ::File::expand_path (on both unix and windows)
# ::File.expand_path("///tmp") == ::File.expand_path("/tmp") => false
# ::File.expand_path("\\tmp") => "C:/tmp"
- return true if @current_resource.home.nil? && new_resource.home
- new_resource.home && Pathname.new(@current_resource.home).cleanpath != Pathname.new(new_resource.home).cleanpath
+ return true if current_resource.home.nil? && new_resource.home
+ new_resource.home && Pathname.new(current_resource.home).cleanpath != Pathname.new(new_resource.home).cleanpath
end
end
diff --git a/lib/chef/provider/user/windows.rb b/lib/chef/provider/user/windows.rb
index b086a1e32b..0afa8fa14a 100644
--- a/lib/chef/provider/user/windows.rb
+++ b/lib/chef/provider/user/windows.rb
@@ -31,31 +31,30 @@ class Chef
def initialize(new_resource, run_context)
super
- @net_user = Chef::Util::Windows::NetUser.new(@new_resource.username)
+ @net_user = Chef::Util::Windows::NetUser.new(new_resource.username)
end
def load_current_resource
- if @new_resource.gid
+ if new_resource.gid
Chef::Log.warn("The 'gid' attribute is not implemented by the Windows platform. Please use the 'group' resource to assign a user to a group.")
end
- @current_resource = Chef::Resource::User.new(@new_resource.name)
- @current_resource.username(@new_resource.username)
- user_info = nil
+ @current_resource = Chef::Resource::User.new(new_resource.name)
+ current_resource.username(new_resource.username)
begin
user_info = @net_user.get_info
- @current_resource.uid(user_info[:user_id])
- @current_resource.comment(user_info[:full_name])
- @current_resource.home(user_info[:home_dir])
- @current_resource.shell(user_info[:script_path])
+ current_resource.uid(user_info[:user_id])
+ current_resource.comment(user_info[:full_name])
+ current_resource.home(user_info[:home_dir])
+ current_resource.shell(user_info[:script_path])
rescue Chef::Exceptions::UserIDNotFound => e
# e.message should be "The user name could not be found" but checking for that could cause a localization bug
@user_exists = false
- Chef::Log.debug("#{@new_resource} does not exist (#{e.message})")
+ Chef::Log.debug("#{new_resource} does not exist (#{e.message})")
end
- @current_resource
+ current_resource
end
# Check to see if the user needs any changes
@@ -64,12 +63,12 @@ class Chef
# <true>:: If a change is required
# <false>:: If the users are identical
def compare_user
- unless @net_user.validate_credentials(@new_resource.password)
- Chef::Log.debug("#{@new_resource} password has changed")
+ unless @net_user.validate_credentials(new_resource.password)
+ Chef::Log.debug("#{new_resource} password has changed")
return true
end
[ :uid, :comment, :home, :shell ].any? do |user_attrib|
- !@new_resource.send(user_attrib).nil? && @new_resource.send(user_attrib) != @current_resource.send(user_attrib)
+ !new_resource.send(user_attrib).nil? && new_resource.send(user_attrib) != current_resource.send(user_attrib)
end
end
@@ -98,7 +97,7 @@ class Chef
end
def set_options
- opts = { :name => @new_resource.username }
+ opts = { name: new_resource.username }
field_list = {
"comment" => "full_name",
@@ -110,14 +109,12 @@ class Chef
field_list.sort { |a, b| a[0] <=> b[0] }.each do |field, option|
field_symbol = field.to_sym
- if @current_resource.send(field_symbol) != @new_resource.send(field_symbol)
- if @new_resource.send(field_symbol)
- unless field_symbol == :password
- Chef::Log.debug("#{@new_resource} setting #{field} to #{@new_resource.send(field_symbol)}")
- end
- opts[option.to_sym] = @new_resource.send(field_symbol)
- end
+ next unless current_resource.send(field_symbol) != new_resource.send(field_symbol)
+ next unless new_resource.send(field_symbol)
+ unless field_symbol == :password
+ Chef::Log.debug("#{new_resource} setting #{field} to #{new_resource.send(field_symbol)}")
end
+ opts[option.to_sym] = new_resource.send(field_symbol)
end
opts
end