Class: Chef::Provider::Package

Inherits:
Chef::Provider show all
Includes:
Mixin::Command
Defined in:
lib/chef/provider/package.rb,
lib/chef/provider/package/apt.rb,
lib/chef/provider/package/ips.rb,
lib/chef/provider/package/rpm.rb,
lib/chef/provider/package/yum.rb,
lib/chef/provider/package/dpkg.rb,
lib/chef/provider/package/pacman.rb,
lib/chef/provider/package/zypper.rb,
lib/chef/provider/package/freebsd.rb,
lib/chef/provider/package/portage.rb,
lib/chef/provider/package/smartos.rb,
lib/chef/provider/package/solaris.rb,
lib/chef/provider/package/macports.rb,
lib/chef/provider/package/rubygems.rb,
lib/chef/provider/package/easy_install.rb

Defined Under Namespace

Classes: Apt, Dpkg, EasyInstall, Freebsd, Ips, Macports, Pacman, Portage, Rpm, Rubygems, SmartOS, Solaris, Yum, Zypper

Instance Attribute Summary collapse

Attributes inherited from Chef::Provider

#action, #current_resource, #new_resource, #run_context

Instance Method Summary collapse

Methods included from Mixin::Command

#chdir_or_tmpdir, #handle_command_failures, #output_of_command, #run_command, #run_command_with_systems_locale

Methods included from Mixin::Command::Windows

#popen4

Methods included from Mixin::Command::Unix

#popen4

Methods inherited from Chef::Provider

#action_nothing, build_from_file, #cleanup_after_converge, #converge, #cookbook_name, #events, #node, #process_resource_requirements, #requirements, #resource_collection, #run_action, #whyrun_mode?

Methods included from Mixin::ConvertToClassName

#convert_to_class_name, #convert_to_snake_case, #filename_to_qualified_string, #snake_case_basename

Methods included from Mixin::EnforceOwnershipAndPermissions

#access_controls, #enforce_ownership_and_permissions

Methods included from Mixin::RecipeDefinitionDSLCore

#method_missing

Methods included from Mixin::Language

#data_bag, #data_bag_item, #platform?, #platform_family?, #search, #value_for_platform, #value_for_platform_family

Constructor Details

#initialize(new_resource, run_context) ⇒ Package

Returns a new instance of Package.



31
32
33
34
# File 'lib/chef/provider/package.rb', line 31

def initialize(new_resource, run_context)
  super
  @candidate_version = nil
end

Dynamic Method Handling

This class handles dynamic methods through the method_missing method in the class Chef::Mixin::RecipeDefinitionDSLCore

Instance Attribute Details

#candidate_versionObject

Returns the value of attribute candidate_version.



30
31
32
# File 'lib/chef/provider/package.rb', line 30

def candidate_version
  @candidate_version
end

Instance Method Details

#action_installObject



59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
# File 'lib/chef/provider/package.rb', line 59

def action_install
  # If we specified a version, and it's not the current version, move to the specified version
  if !@new_resource.version.nil? && !(target_version_already_installed?)
    install_version = @new_resource.version
  # If it's not installed at all, install it
  elsif @current_resource.version.nil?
    install_version = candidate_version
  else
    Chef::Log.debug("#{@new_resource} is already installed - nothing to do")
    return
  end

  # We need to make sure we handle the preseed file
  if @new_resource.response_file
    if preseed_file = get_preseed_file(@new_resource.package_name, install_version)
      converge_by("preseed package #{@new_resource.package_name}") do  
        preseed_package(preseed_file)
      end 
    end
  end
  description = install_version ? "version #{install_version} of" : ""
  converge_by("install #{description} package #{@new_resource.package_name}") do
    @new_resource.version(install_version)
    install_package(@new_resource.package_name, install_version)
  end
end

#action_purgeObject



125
126
127
128
129
130
131
132
133
# File 'lib/chef/provider/package.rb', line 125

def action_purge
  if removing_package?
    description = @new_resource.version ? "version #{@new_resource.version} of" : ""
    converge_by("purge #{description} package #{@current_resource.package_name}") do
      purge_package(@current_resource.package_name, @new_resource.version)
      Chef::Log.info("#{@new_resource} purged")
    end
  end
end

#action_reconfigObject



135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
# File 'lib/chef/provider/package.rb', line 135

def action_reconfig
  if @current_resource.version == nil then
    Chef::Log.debug("#{@new_resource} is NOT installed - nothing to do")
    return
  end

  unless @new_resource.response_file then
    Chef::Log.debug("#{@new_resource} no response_file provided - nothing to do")
    return
  end

  if preseed_file = get_preseed_file(@new_resource.package_name, @current_resource.version)
    converge_by("reconfigure package #{@new_resource.package_name}") do
      preseed_package(preseed_file)
      status = reconfig_package(@new_resource.package_name, @current_resource.version)
      Chef::Log.info("#{@new_resource} reconfigured")
    end
  else
    Chef::Log.debug("#{@new_resource} preseeding has not changed - nothing to do")
  end
end

#action_removeObject



101
102
103
104
105
106
107
108
109
110
111
# File 'lib/chef/provider/package.rb', line 101

def action_remove
  if removing_package?
    description = @new_resource.version ? "version #{@new_resource.version} of " :  ""
    converge_by("remove #{description} package #{@current_resource.package_name}") do
      remove_package(@current_resource.package_name, @new_resource.version)
      Chef::Log.info("#{@new_resource} removed")
    end
  else
    Chef::Log.debug("#{@new_resource} package does not exist - nothing to do")
  end
end

#action_upgradeObject



86
87
88
89
90
91
92
93
94
95
96
97
98
99
# File 'lib/chef/provider/package.rb', line 86

def action_upgrade
  if candidate_version.nil?
    Chef::Log.debug("#{@new_resource} no candidate version - nothing to do")
  elsif @current_resource.version == candidate_version
    Chef::Log.debug("#{@new_resource} is at the latest version - nothing to do")
  else
    @new_resource.version(candidate_version)
    orig_version = @current_resource.version || "uninstalled"
    converge_by("upgrade package #{@new_resource.package_name} from #{orig_version} to #{candidate_version}") do
      status = upgrade_package(@new_resource.package_name, candidate_version)
      Chef::Log.info("#{@new_resource} upgraded from #{orig_version} to #{candidate_version}")
    end
  end
end

#define_resource_requirementsObject



43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
# File 'lib/chef/provider/package.rb', line 43

def define_resource_requirements
  requirements.assert(:install) do |a|
    a.assertion { ((@new_resource.version != nil) && !(target_version_already_installed?)) \
      || !(@current_resource.version.nil? && candidate_version.nil?)  }
    a.failure_message(Chef::Exceptions::Package, "No version specified, and no candidate version available for #{@new_resource.package_name}")
    a.whyrun("Assuming a repository that offers #{@new_resource.package_name} would have been configured")
  end

  requirements.assert(:upgrade) do |a|
    # Can't upgrade what we don't have
    a.assertion  { !(@current_resource.version.nil? && candidate_version.nil?) } 
    a.failure_message(Chef::Exceptions::Package, "No candidate version available for #{@new_resource.package_name}")
    a.whyrun("Assuming a repository that offers #{@new_resource.package_name} would have been configured")
  end
end

#expand_options(options) ⇒ Object



219
220
221
# File 'lib/chef/provider/package.rb', line 219

def expand_options(options)
  options ? " #{options}" : ""
end

#get_preseed_file(name, version) ⇒ Object



181
182
183
184
185
186
187
188
189
190
191
# File 'lib/chef/provider/package.rb', line 181

def get_preseed_file(name, version)
  resource = preseed_resource(name, version)
  resource.run_action(:create)
  Chef::Log.debug("#{@new_resource} fetched preseed file to #{resource.path}")

  if resource.updated_by_last_action?
    resource.path
  else
    false
  end
end

#install_package(name, version) ⇒ Object



157
158
159
# File 'lib/chef/provider/package.rb', line 157

def install_package(name, version)
  raise Chef::Exceptions::UnsupportedAction, "#{self.to_s} does not support :install"
end

#load_current_resourceObject



40
41
# File 'lib/chef/provider/package.rb', line 40

def load_current_resource
end

#preseed_package(file) ⇒ Object



173
174
175
# File 'lib/chef/provider/package.rb', line 173

def preseed_package(file)
  raise Chef::Exceptions::UnsupportedAction, "#{self.to_s} does not support pre-seeding package install/upgrade instructions"
end

#preseed_resource(name, version) ⇒ Object



193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
# File 'lib/chef/provider/package.rb', line 193

def preseed_resource(name, version)
  # A directory in our cache to store this cookbook's preseed files in
  file_cache_dir = Chef::FileCache.create_cache_path("preseed/#{@new_resource.cookbook_name}")
  # The full path where the preseed file will be stored
  cache_seed_to = "#{file_cache_dir}/#{name}-#{version}.seed"

  Chef::Log.debug("#{@new_resource} fetching preseed file to #{cache_seed_to}")

  begin
    remote_file = Chef::Resource::Template.new(cache_seed_to, run_context)
    remote_file.cookbook_name = @new_resource.cookbook_name
    remote_file.source(@new_resource.response_file)
    remote_file.backup(false)
    provider = Chef::Platform.provider_for_resource(remote_file, :create)
    provider.template_location
  rescue
    Chef::Log.debug("#{@new_resource} fetching preseed file via Template resource failed, fallback to CookbookFile resource")
    remote_file = Chef::Resource::CookbookFile.new(cache_seed_to, run_context)
    remote_file.cookbook_name = @new_resource.cookbook_name
    remote_file.source(@new_resource.response_file)
    remote_file.backup(false)
  end

  remote_file
end

#purge_package(name, version) ⇒ Object



169
170
171
# File 'lib/chef/provider/package.rb', line 169

def purge_package(name, version)
  raise Chef::Exceptions::UnsupportedAction, "#{self.to_s} does not support :purge"
end

#reconfig_package(name, version) ⇒ Object



177
178
179
# File 'lib/chef/provider/package.rb', line 177

def reconfig_package(name, version)
  raise( Chef::Exceptions::UnsupportedAction, "#{self.to_s} does not support :reconfig" )
end

#remove_package(name, version) ⇒ Object



165
166
167
# File 'lib/chef/provider/package.rb', line 165

def remove_package(name, version)
  raise Chef::Exceptions::UnsupportedAction, "#{self.to_s} does not support :remove"
end

#removing_package?Boolean

Returns:

  • (Boolean)


113
114
115
116
117
118
119
120
121
122
123
# File 'lib/chef/provider/package.rb', line 113

def removing_package?
  if @current_resource.version.nil?
    false # nothing to remove
  elsif @new_resource.version.nil?
    true # remove any version of a package
  elsif @new_resource.version == @current_resource.version
    true # remove the version we have
  else
    false # we don't have the version we want to remove
  end
end

#target_version_already_installed?Boolean

Returns:

  • (Boolean)


223
224
225
# File 'lib/chef/provider/package.rb', line 223

def target_version_already_installed?
  @new_resource.version == @current_resource.version
end

#upgrade_package(name, version) ⇒ Object



161
162
163
# File 'lib/chef/provider/package.rb', line 161

def upgrade_package(name, version)
  raise Chef::Exceptions::UnsupportedAction, "#{self.to_s} does not support :upgrade"
end

#whyrun_supported?Boolean

Returns:

  • (Boolean)


36
37
38
# File 'lib/chef/provider/package.rb', line 36

def whyrun_supported?
  true
end