PageRenderTime 25ms CodeModel.GetById 23ms RepoModel.GetById 1ms app.codeStats 0ms

/cookbooks/python/providers/pip.rb

https://github.com/flaccid/cookbooks
Ruby | 168 lines | 110 code | 22 blank | 36 comment | 20 complexity | b7206b3b0bfa23b18235df7281048d75 MD5 | raw file
  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. # the logic in all action methods mirror that of
  24. # the Chef::Provider::Package which will make
  25. # refactoring into core chef easy
  26. action :install do
  27. # If we specified a version, and it's not the current version, move to the specified version
  28. if @new_resource.version != nil && @new_resource.version != @current_resource.version
  29. install_version = @new_resource.version
  30. # If it's not installed at all, install it
  31. elsif @current_resource.version == nil
  32. install_version = candidate_version
  33. end
  34. # Set the timeout (units in seconds)
  35. timeout = 900
  36. if @new_resource.timeout
  37. timeout = @new_resource.timeout
  38. end
  39. if install_version
  40. Chef::Log.info("Installing #{@new_resource} version #{install_version}")
  41. status = install_package(@new_resource.package_name, install_version, timeout)
  42. if status
  43. @new_resource.updated_by_last_action(true)
  44. end
  45. end
  46. end
  47. action :upgrade do
  48. # Set the timeout (units in seconds)
  49. timeout = 900
  50. if @new_resource.timeout
  51. timeout = @new_resource.timeout
  52. end
  53. if @current_resource.version != candidate_version
  54. orig_version = @current_resource.version || "uninstalled"
  55. Chef::Log.info("Upgrading #{@new_resource} version from #{orig_version} to #{candidate_version}")
  56. status = upgrade_package(@new_resource.package_name, candidate_version, timeout)
  57. if status
  58. @new_resource.updated_by_last_action(true)
  59. end
  60. end
  61. end
  62. action :remove do
  63. # Set the timeout (units in seconds)
  64. timeout = 900
  65. if @new_resource.timeout
  66. timeout = @new_resource.timeout
  67. end
  68. if removing_package?
  69. Chef::Log.info("Removing #{@new_resource}")
  70. remove_package(@current_resource.package_name, @new_resource.version, timeout)
  71. @new_resource.updated_by_last_action(true)
  72. else
  73. end
  74. end
  75. def removing_package?
  76. if @current_resource.version.nil?
  77. false # nothing to remove
  78. elsif @new_resource.version.nil?
  79. true # remove any version of a package
  80. elsif @new_resource.version == @current_resource.version
  81. true # remove the version we have
  82. else
  83. false # we don't have the version we want to remove
  84. end
  85. end
  86. def expand_options(options)
  87. options ? " #{options}" : ""
  88. end
  89. # these methods are the required overrides of
  90. # a provider that extends from Chef::Provider::Package
  91. # so refactoring into core Chef should be easy
  92. def load_current_resource
  93. @current_resource = Chef::Resource::PythonPip.new(@new_resource.name)
  94. @current_resource.package_name(@new_resource.package_name)
  95. @current_resource.version(nil)
  96. unless current_installed_version.nil?
  97. @current_resource.version(current_installed_version)
  98. end
  99. @current_resource
  100. end
  101. def current_installed_version
  102. @current_installed_version ||= begin
  103. delimeter = /==/
  104. version_check_cmd = "#{pip_cmd(@new_resource)} freeze | grep -i '^#{@new_resource.package_name}=='"
  105. # incase you upgrade pip with pip!
  106. if @new_resource.package_name.eql?('pip')
  107. delimeter = /\s/
  108. version_check_cmd = "pip --version"
  109. end
  110. p = shell_out(version_check_cmd)
  111. unless p.stdout.split(delimeter).count < 2
  112. p.stdout.split(delimeter)[1].strip
  113. end
  114. rescue Chef::Exceptions::ShellCommandFailed, Mixlib::ShellOut::ShellCommandFailed
  115. end
  116. end
  117. def candidate_version
  118. @candidate_version ||= begin
  119. # `pip search` doesn't return versions yet
  120. # `pip list` may be coming soon:
  121. # https://bitbucket.org/ianb/pip/issue/197/option-to-show-what-version-would-be
  122. @new_resource.version||'latest'
  123. end
  124. end
  125. def install_package(name, version, timeout)
  126. v = "==#{version}" unless version.eql?('latest')
  127. shell_out!("#{pip_cmd(@new_resource)} install#{expand_options(@new_resource.options)} #{name}#{v}", :timeout => timeout)
  128. end
  129. def upgrade_package(name, version, timeout)
  130. v = "==#{version}" unless version.eql?('latest')
  131. shell_out!("#{pip_cmd(@new_resource)} install --upgrade#{expand_options(@new_resource.options)} #{@new_resource.name}#{v}", :timeout => timeout)
  132. end
  133. def remove_package(name, version, timeout)
  134. shell_out!("#{pip_cmd(@new_resource)} uninstall -y#{expand_options(@new_resource.options)} #{@new_resource.name}", :timeout => timeout)
  135. end
  136. # TODO remove when provider is moved into Chef core
  137. # this allows PythonPip to work with Chef::Resource::Package
  138. def pip_cmd(nr)
  139. if (nr.respond_to?("virtualenv") && nr.virtualenv)
  140. ::File.join(nr.virtualenv,'/bin/pip')
  141. elsif "#{node['python']['install_method']}".eql?("source")
  142. ::File.join("#{node['python']['prefix_dir']}","/bin/pip")
  143. else
  144. 'pip'
  145. end
  146. end