Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit e0f596c

Browse files
committed
COOK-432, updated python cookbook with pip and virtualenv LWRPs
1 parent 8aa2527 commit e0f596c

File tree

8 files changed

+466
-45
lines changed

8 files changed

+466
-45
lines changed

README.md

Lines changed: 131 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,131 @@
1+
Description
2+
===========
3+
4+
Installs and configures Python 2.6. Also includes LWRPs for managing `pip` packages and `virtualenv` isolated Python environments.
5+
6+
Requirements
7+
============
8+
9+
Platform
10+
--------
11+
12+
* Debian, Ubuntu
13+
* CentOS, Red Hat, Fedora
14+
15+
Cookbooks
16+
---------
17+
18+
Attributes
19+
==========
20+
21+
None at this time.
22+
23+
Resource/Provider
24+
=================
25+
26+
This cookbook includes LWRPs for managing:
27+
28+
* pip packages
29+
* virtualenv isolated Python environments
30+
31+
`python_pip`
32+
------------
33+
34+
Install packages using the new hotness in Python package management...[`pip`](http://pypi.python.org/pypi/pip). Yo dawg...easy_install is so 2009, you better ask your local Pythonista if you don't know! The usage semantics are like that of any normal package provider.
35+
36+
# Actions
37+
38+
- :install: Install a pip package - if version is provided, install that specific version
39+
- :upgrade: Upgrade a pip package - if version is provided, upgrade to that specific version
40+
- :remove: Remove a pip package
41+
- :purge: Purge a pip package (this usually entails removing configuration files as well as the package itself). With pip packages this behaves the same as `:remove`
42+
43+
# Attribute Parameters
44+
45+
- package_name: name attribute. The name of the pip package to install
46+
- version: the version of the package to install/upgrade. If no version is given latest is assumed.
47+
- virtualenv: virtualenv environment to install pip package into
48+
- options: Add additional options to the underlying pip package command
49+
50+
# Example
51+
52+
# install latest gunicorn into system path
53+
python_pip "gunicorn" do
54+
action :install
55+
end
56+
57+
# target a virtualenv
58+
python_pip "gunicorn" do
59+
virtualenv "/home/ubunut/my_ve"
60+
action :install
61+
end
62+
63+
# install Django 1.1.4
64+
python_pip "django" do
65+
version "1.1.4"
66+
action :install
67+
end
68+
69+
# use this provider with the core package resource
70+
package "django" do
71+
provider Chef::Provider::PythonPip
72+
action :install
73+
end
74+
75+
`python_virtualenv`
76+
-------------------
77+
78+
[`virtualenv`](http://pypi.python.org/pypi/virtualenv) is a great tool that creates isolated python environments. Think of it as RVM without all those hipsters and tight jeans.
79+
80+
# Actions
81+
82+
- :create: creates a new virtualenv
83+
- :delete: deletes an existing virtualenv
84+
85+
# Attribute Parameters
86+
87+
- path: name attribute. The path where the virtualenv will be created
88+
- interpreter: The Python interpreter to use. default is `python2.6`
89+
- owner: The owner for the virtualenv
90+
- group: The group owner of the file (string or id)
91+
92+
# Example
93+
94+
# create a 2.6 virtualenv owned by ubuntu user
95+
python_virtualenv "/home/ubuntu/my_cool_ve" do
96+
owner "ubuntu"
97+
group "ubuntu"
98+
action :create
99+
end
100+
101+
# create a Python 2.4 virtualenv
102+
python_virtualenv "/home/ubuntu/my_old_ve" do
103+
interpreter "python2.4"
104+
owner "ubuntu"
105+
group "ubuntu"
106+
action :create
107+
end
108+
109+
Usage
110+
=====
111+
112+
Simply include the recipe where you want Python 2.6 installed.
113+
114+
License and Author
115+
==================
116+
117+
Author:: Seth Chisamore (<[email protected]>)
118+
119+
Copyright:: 2011, Opscode, Inc
120+
121+
Licensed under the Apache License, Version 2.0 (the "License");
122+
you may not use this file except in compliance with the License.
123+
You may obtain a copy of the License at
124+
125+
http://www.apache.org/licenses/LICENSE-2.0
126+
127+
Unless required by applicable law or agreed to in writing, software
128+
distributed under the License is distributed on an "AS IS" BASIS,
129+
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
130+
See the License for the specific language governing permissions and
131+
limitations under the License.

metadata.json

Lines changed: 42 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -1,36 +1,45 @@
11
{
2-
"recommendations": {
3-
},
4-
"attributes": {
5-
},
6-
"maintainer": "Opscode, Inc.",
7-
"suggestions": {
8-
},
9-
"dependencies": {
10-
},
11-
"maintainer_email": "[email protected]",
12-
"conflicting": {
13-
},
14-
"platforms": {
15-
"debian": [
2+
"name": "python",
3+
"description": "Installs python packages",
4+
"long_description": "",
5+
"maintainer": "Opscode, Inc.",
6+
"maintainer_email": "[email protected]",
7+
"license": "Apache 2.0",
8+
"platforms": {
9+
"debian": [
1610

17-
],
18-
"ubuntu": [
11+
],
12+
"ubuntu": [
1913

20-
]
21-
},
22-
"license": "Apache 2.0",
23-
"version": "0.7.0",
24-
"providing": {
25-
},
26-
"recipes": {
27-
"python": "Installs python and common python module packages"
28-
},
29-
"replacing": {
30-
},
31-
"name": "python",
32-
"description": "Installs python packages",
33-
"groupings": {
34-
},
35-
"long_description": ""
36-
}
14+
],
15+
"centos": [
16+
17+
],
18+
"redhat": [
19+
20+
],
21+
"fedora": [
22+
23+
]
24+
},
25+
"dependencies": {
26+
},
27+
"recommendations": {
28+
},
29+
"suggestions": {
30+
},
31+
"conflicting": {
32+
},
33+
"providing": {
34+
},
35+
"replacing": {
36+
},
37+
"attributes": {
38+
},
39+
"groupings": {
40+
},
41+
"recipes": {
42+
"python": "Installs python, pip, and virtualenv"
43+
},
44+
"version": "0.99.0"
45+
}

metadata.rb

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,10 +2,10 @@
22
maintainer_email "[email protected]"
33
license "Apache 2.0"
44
description "Installs python packages"
5-
version "0.7"
5+
version "0.99"
66

7-
recipe "python", "Installs python and common python module packages"
7+
recipe "python", "Installs python, pip, and virtualenv"
88

9-
%w{ debian ubuntu }.each do |os|
9+
%w{ debian ubuntu centos redhat fedora }.each do |os|
1010
supports os
1111
end

providers/pip.rb

Lines changed: 146 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,146 @@
1+
#
2+
# Author:: Seth Chisamore <[email protected]>
3+
# Cookbook Name:: python
4+
# Provider:: pip
5+
#
6+
# Copyright:: 2011, Opscode, Inc <[email protected]>
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+
21+
require 'chef/mixin/shell_out'
22+
require 'chef/mixin/language'
23+
include Chef::Mixin::ShellOut
24+
25+
# the logic in all action methods mirror that of
26+
# the Chef::Provider::Package which will make
27+
# refactoring into core chef easy
28+
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+
38+
if install_version
39+
Chef::Log.info("Installing #{@new_resource} version #{install_version}")
40+
status = install_package(@new_resource.package_name, install_version)
41+
if status
42+
@new_resource.updated_by_last_action(true)
43+
end
44+
end
45+
end
46+
47+
action :upgrade do
48+
if @current_resource.version != candidate_version
49+
orig_version = @current_resource.version || "uninstalled"
50+
Chef::Log.info("Upgrading #{@new_resource} version from #{orig_version} to #{candidate_version}")
51+
status = upgrade_package(@new_resource.package_name, candidate_version)
52+
if status
53+
@new_resource.updated_by_last_action(true)
54+
end
55+
end
56+
end
57+
58+
action :remove do
59+
if removing_package?
60+
Chef::Log.info("Removing #{@new_resource}")
61+
remove_package(@current_resource.package_name, @new_resource.version)
62+
@new_resource.updated_by_last_action(true)
63+
else
64+
end
65+
end
66+
67+
def removing_package?
68+
if @current_resource.version.nil?
69+
false # nothing to remove
70+
elsif @new_resource.version.nil?
71+
true # remove any version of a package
72+
elsif @new_resource.version == @current_resource.version
73+
true # remove the version we have
74+
else
75+
false # we don't have the version we want to remove
76+
end
77+
end
78+
79+
def expand_options(options)
80+
options ? " #{options}" : ""
81+
end
82+
83+
# these methods are the required overrides of
84+
# a provider that extends from Chef::Provider::Package
85+
# so refactoring into core Chef should be easy
86+
87+
def load_current_resource
88+
@current_resource = Chef::Resource::PythonPip.new(@new_resource.name)
89+
@current_resource.package_name(@new_resource.package_name)
90+
@current_resource.version(nil)
91+
92+
unless current_installed_version.nil?
93+
@current_resource.version(current_installed_version)
94+
end
95+
96+
@current_resource
97+
end
98+
99+
def current_installed_version
100+
@current_installed_version ||= begin
101+
delimeter = /==/
102+
103+
version_check_cmd = "pip freeze#{expand_virtualenv(can_haz_virtualenv(@new_resource))} | grep -i #{@new_resource.package_name}"
104+
# incase you upgrade pip with pip!
105+
if @new_resource.package_name.eql?('pip')
106+
delimeter = /\s/
107+
version_check_cmd = "pip --version"
108+
end
109+
p = shell_out!(version_check_cmd)
110+
p.stdout.split(delimeter)[1].strip
111+
rescue Chef::Exceptions::ShellCommandFailed
112+
end
113+
end
114+
115+
def candidate_version
116+
@candidate_version ||= begin
117+
# `pip search` doesn't return versions yet
118+
# `pip list` may be coming soon:
119+
# https://bitbucket.org/ianb/pip/issue/197/option-to-show-what-version-would-be
120+
@new_resource.version||'latest'
121+
end
122+
end
123+
124+
def install_package(name,version)
125+
v = "==#{version}" unless version.eql?('latest')
126+
shell_out!("pip install#{expand_options(@new_resource.options)}#{expand_virtualenv(can_haz_virtualenv(@new_resource))} #{name}#{v}")
127+
end
128+
129+
def upgrade_package(name, version)
130+
v = "==#{version}" unless version.eql?('latest')
131+
shell_out!("pip install --upgrade#{expand_options(@new_resource.options)}#{expand_virtualenv(can_haz_virtualenv(@new_resource))} #{@new_resource.name}#{v}")
132+
end
133+
134+
def remove_package(name, version)
135+
shell_out!("pip uninstall -y#{expand_options(@new_resource.options)}#{expand_virtualenv(can_haz_virtualenv(@new_resource))} #{@new_resource.name}")
136+
end
137+
138+
def expand_virtualenv(virtualenv)
139+
virtualenv && " --environment=#{virtualenv}"
140+
end
141+
142+
# TODO remove when provider is moved into Chef core
143+
# this allows PythonPip to work with Chef::Resource::Package
144+
def can_haz_virtualenv(nr)
145+
nr.respond_to?("virtualenv") ? nr.virtualenv : nil
146+
end

0 commit comments

Comments
 (0)