PageRenderTime 46ms CodeModel.GetById 19ms RepoModel.GetById 0ms app.codeStats 0ms

/chef-oulima/cookbooks/python/providers/pip.rb

https://bitbucket.org/slashmili/oulima-vagrant
Ruby | 173 lines | 114 code | 23 blank | 36 comment | 18 complexity | 76a81cd7db300a021c96c30eb7e44793 MD5 | raw file
Possible License(s): Apache-2.0
  1. #
  2. # Author:: Seth Chisamore <schisamo@opscode.com>
  3. # Cookbook Name:: python
  4. # Provider:: pip
  5. #
  6. # Copyright:: 2011, Opscode, Inc <legal@opscode.com>
  7. #
  8. # Licensed under the Apache License, Version 2.0 (the "License");
  9. # you may not use this file except in compliance with the License.
  10. # You may obtain a copy of the License at
  11. #
  12. # http://www.apache.org/licenses/LICENSE-2.0
  13. #
  14. # Unless required by applicable law or agreed to in writing, software
  15. # distributed under the License is distributed on an "AS IS" BASIS,
  16. # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  17. # See the License for the specific language governing permissions and
  18. # limitations under the License.
  19. #
  20. require 'chef/mixin/shell_out'
  21. require 'chef/mixin/language'
  22. include Chef::Mixin::ShellOut
  23. def whyrun_supported?
  24. true
  25. end
  26. # the logic in all action methods mirror that of
  27. # the Chef::Provider::Package which will make
  28. # refactoring into core chef easy
  29. action :install do
  30. # If we specified a version, and it's not the current version, move to the specified version
  31. if @new_resource.version != nil && @new_resource.version != @current_resource.version
  32. install_version = @new_resource.version
  33. # If it's not installed at all, install it
  34. elsif @current_resource.version == nil
  35. install_version = candidate_version
  36. end
  37. # Set the timeout (units in seconds)
  38. timeout = 900
  39. if @new_resource.timeout
  40. timeout = @new_resource.timeout
  41. end
  42. if install_version
  43. description = "install package #{@new_resource} version #{install_version}"
  44. converge_by(description) do
  45. Chef::Log.info("Installing #{@new_resource} version #{install_version}")
  46. status = install_package(@new_resource.package_name, install_version, timeout)
  47. end
  48. end
  49. end
  50. action :upgrade do
  51. # Set the timeout (units in seconds)
  52. timeout = 900
  53. if @new_resource.timeout
  54. timeout = @new_resource.timeout
  55. end
  56. if @current_resource.version != candidate_version
  57. orig_version = @current_resource.version || "uninstalled"
  58. description = "upgrade #{@current_resource} version from #{@current_resource.version} to #{candidate_version}"
  59. converge_by(description) do
  60. Chef::Log.info("Upgrading #{@new_resource} version from #{orig_version} to #{candidate_version}")
  61. status = upgrade_package(@new_resource.package_name, candidate_version, timeout)
  62. end
  63. end
  64. end
  65. action :remove do
  66. # Set the timeout (units in seconds)
  67. timeout = 900
  68. if @new_resource.timeout
  69. timeout = @new_resource.timeout
  70. end
  71. if removing_package?
  72. description = "remove package #{@new_resource}"
  73. converge_by(description) do
  74. Chef::Log.info("Removing #{@new_resource}")
  75. remove_package(@current_resource.package_name, @new_resource.version, timeout)
  76. end
  77. else
  78. end
  79. end
  80. def removing_package?
  81. if @current_resource.version.nil?
  82. false # nothing to remove
  83. elsif @new_resource.version.nil?
  84. true # remove any version of a package
  85. elsif @new_resource.version == @current_resource.version
  86. true # remove the version we have
  87. else
  88. false # we don't have the version we want to remove
  89. end
  90. end
  91. def expand_options(options)
  92. options ? " #{options}" : ""
  93. end
  94. # these methods are the required overrides of
  95. # a provider that extends from Chef::Provider::Package
  96. # so refactoring into core Chef should be easy
  97. def load_current_resource
  98. @current_resource = Chef::Resource::PythonPip.new(@new_resource.name)
  99. @current_resource.package_name(@new_resource.package_name)
  100. @current_resource.version(nil)
  101. unless current_installed_version.nil?
  102. @current_resource.version(current_installed_version)
  103. end
  104. @current_resource
  105. end
  106. def current_installed_version
  107. @current_installed_version ||= begin
  108. delimeter = /==/
  109. version_check_cmd = "#{pip_cmd(@new_resource)} freeze | grep -i '^#{@new_resource.package_name}=='"
  110. # incase you upgrade pip with pip!
  111. if @new_resource.package_name.eql?('pip')
  112. delimeter = /\s/
  113. version_check_cmd = "pip --version"
  114. end
  115. p = shell_out!(version_check_cmd)
  116. p.stdout.split(delimeter)[1].strip
  117. rescue Chef::Exceptions::ShellCommandFailed
  118. rescue Mixlib::ShellOut::ShellCommandFailed
  119. end
  120. end
  121. def candidate_version
  122. @candidate_version ||= begin
  123. # `pip search` doesn't return versions yet
  124. # `pip list` may be coming soon:
  125. # https://bitbucket.org/ianb/pip/issue/197/option-to-show-what-version-would-be
  126. @new_resource.version||'latest'
  127. end
  128. end
  129. def install_package(name, version, timeout)
  130. v = "==#{version}" unless version.eql?('latest')
  131. shell_out!("#{pip_cmd(@new_resource)} install#{expand_options(@new_resource.options)} #{name}#{v}", :timeout => timeout)
  132. end
  133. def upgrade_package(name, version, timeout)
  134. v = "==#{version}" unless version.eql?('latest')
  135. shell_out!("#{pip_cmd(@new_resource)} install --upgrade#{expand_options(@new_resource.options)} #{@new_resource.name}#{v}", :timeout => timeout)
  136. end
  137. def remove_package(name, version, timeout)
  138. shell_out!("#{pip_cmd(@new_resource)} uninstall -y#{expand_options(@new_resource.options)} #{@new_resource.name}", :timeout => timeout)
  139. end
  140. # TODO remove when provider is moved into Chef core
  141. # this allows PythonPip to work with Chef::Resource::Package
  142. def pip_cmd(nr)
  143. if (nr.respond_to?("virtualenv") && nr.virtualenv)
  144. ::File.join(nr.virtualenv,'/bin/pip')
  145. elsif "#{node['python']['install_method']}".eql?("source")
  146. ::File.join("#{node['python']['prefix_dir']}","/bin/pip")
  147. else
  148. 'pip'
  149. end
  150. end