PageRenderTime 40ms CodeModel.GetById 30ms RepoModel.GetById 18ms app.codeStats 0ms

/python/providers/pip.rb

https://bitbucket.org/cavneb/cookbooks
Ruby | 146 lines | 93 code | 20 blank | 33 comment | 16 complexity | 61018957c0d93f815ef0b5c49eb1d2db 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. if install_version
  35. Chef::Log.info("Installing #{@new_resource} version #{install_version}")
  36. status = install_package(@new_resource.package_name, install_version)
  37. if status
  38. @new_resource.updated_by_last_action(true)
  39. end
  40. end
  41. end
  42. action :upgrade do
  43. if @current_resource.version != candidate_version
  44. orig_version = @current_resource.version || "uninstalled"
  45. Chef::Log.info("Upgrading #{@new_resource} version from #{orig_version} to #{candidate_version}")
  46. status = upgrade_package(@new_resource.package_name, candidate_version)
  47. if status
  48. @new_resource.updated_by_last_action(true)
  49. end
  50. end
  51. end
  52. action :remove do
  53. if removing_package?
  54. Chef::Log.info("Removing #{@new_resource}")
  55. remove_package(@current_resource.package_name, @new_resource.version)
  56. @new_resource.updated_by_last_action(true)
  57. else
  58. end
  59. end
  60. def removing_package?
  61. if @current_resource.version.nil?
  62. false # nothing to remove
  63. elsif @new_resource.version.nil?
  64. true # remove any version of a package
  65. elsif @new_resource.version == @current_resource.version
  66. true # remove the version we have
  67. else
  68. false # we don't have the version we want to remove
  69. end
  70. end
  71. def expand_options(options)
  72. options ? " #{options}" : ""
  73. end
  74. # these methods are the required overrides of
  75. # a provider that extends from Chef::Provider::Package
  76. # so refactoring into core Chef should be easy
  77. def load_current_resource
  78. @current_resource = Chef::Resource::PythonPip.new(@new_resource.name)
  79. @current_resource.package_name(@new_resource.package_name)
  80. @current_resource.version(nil)
  81. unless current_installed_version.nil?
  82. @current_resource.version(current_installed_version)
  83. end
  84. @current_resource
  85. end
  86. def current_installed_version
  87. @current_installed_version ||= begin
  88. delimeter = /==/
  89. version_check_cmd = "pip freeze#{expand_virtualenv(can_haz_virtualenv(@new_resource))} | grep -i #{@new_resource.package_name}=="
  90. # incase you upgrade pip with pip!
  91. if @new_resource.package_name.eql?('pip')
  92. delimeter = /\s/
  93. version_check_cmd = "pip --version"
  94. end
  95. p = shell_out!(version_check_cmd)
  96. p.stdout.split(delimeter)[1].strip
  97. rescue Chef::Exceptions::ShellCommandFailed
  98. end
  99. end
  100. def candidate_version
  101. @candidate_version ||= begin
  102. # `pip search` doesn't return versions yet
  103. # `pip list` may be coming soon:
  104. # https://bitbucket.org/ianb/pip/issue/197/option-to-show-what-version-would-be
  105. @new_resource.version||'latest'
  106. end
  107. end
  108. def install_package(name,version)
  109. v = "==#{version}" unless version.eql?('latest')
  110. shell_out!("pip install#{expand_options(@new_resource.options)}#{expand_virtualenv(can_haz_virtualenv(@new_resource))} #{name}#{v}")
  111. end
  112. def upgrade_package(name, version)
  113. v = "==#{version}" unless version.eql?('latest')
  114. shell_out!("pip install --upgrade#{expand_options(@new_resource.options)}#{expand_virtualenv(can_haz_virtualenv(@new_resource))} #{@new_resource.name}#{v}")
  115. end
  116. def remove_package(name, version)
  117. shell_out!("pip uninstall -y#{expand_options(@new_resource.options)}#{expand_virtualenv(can_haz_virtualenv(@new_resource))} #{@new_resource.name}")
  118. end
  119. def expand_virtualenv(virtualenv)
  120. virtualenv && " --environment=#{virtualenv}"
  121. end
  122. # TODO remove when provider is moved into Chef core
  123. # this allows PythonPip to work with Chef::Resource::Package
  124. def can_haz_virtualenv(nr)
  125. nr.respond_to?("virtualenv") ? nr.virtualenv : nil
  126. end