summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Modulefile2
-rw-r--r--lib/facter/pip_version.rb19
-rw-r--r--lib/facter/python_version.rb28
-rw-r--r--lib/facter/virtualenv_version.rb19
-rw-r--r--manifests/config.pp16
-rw-r--r--manifests/gunicorn.pp4
-rw-r--r--manifests/init.pp20
-rw-r--r--manifests/install.pp42
-rw-r--r--manifests/pip.pp30
-rw-r--r--manifests/requirements.pp14
-rw-r--r--manifests/virtualenv.pp39
-rw-r--r--templates/gunicorn.erb32
12 files changed, 207 insertions, 58 deletions
diff --git a/Modulefile b/Modulefile
index 171490c..4f2424b 100644
--- a/Modulefile
+++ b/Modulefile
@@ -1,5 +1,5 @@
name 'stankevich-python'
-version '1.3.0'
+version '1.6.0'
author 'Sergey Stankevich'
license 'Apache License, Version 2.0'
diff --git a/lib/facter/pip_version.rb b/lib/facter/pip_version.rb
new file mode 100644
index 0000000..131d1f9
--- /dev/null
+++ b/lib/facter/pip_version.rb
@@ -0,0 +1,19 @@
+# Make pip version available as a fact
+# Works with pip loaded and without, pip installed using pip and package installed
+require 'puppet'
+pkg = Puppet::Type.type(:package).new(:name => "python-pip")
+Facter.add("pip_version") do
+ has_weight 100
+ setcode do
+ /^pip (\d+\.\d+\.?\d*).*$/.match(Facter::Util::Resolution.exec('pip --version'))[1]
+ end
+end
+
+Facter.add("pip_version") do
+ has_weight 50
+ setcode do
+ if pkg.retrieve[pkg.property(:ensure)] != 'purged'
+ /^.*(\d+\.\d+\.\d+).*$/.match(pkg.retrieve[pkg.property(:ensure)])[1]
+ end
+ end
+end
diff --git a/lib/facter/python_version.rb b/lib/facter/python_version.rb
new file mode 100644
index 0000000..a2bdb26
--- /dev/null
+++ b/lib/facter/python_version.rb
@@ -0,0 +1,28 @@
+# Make python versions available as facts
+# In lists default python and system python versions
+require 'puppet'
+pkg = Puppet::Type.type(:package).new(:name => "python")
+
+Facter.add("system_python_version") do
+ setcode do
+ if pkg.retrieve[pkg.property(:ensure)] != 'purged'
+ /^(\d+\.\d+\.\d+).*$/.match(pkg.retrieve[pkg.property(:ensure)])[1]
+ end
+ end
+end
+
+Facter.add("python_version") do
+ has_weight 100
+ setcode do
+ /^.*(\d+\.\d+\.\d+)$/.match(Facter::Util::Resolution.exec('python -V'))[1]
+ end
+end
+
+Facter.add("python_version") do
+ has_weight 50
+ setcode do
+ if pkg.retrieve[pkg.property(:ensure)] != 'purged'
+ /^.*(\d+\.\d+\.\d+).*$/.match(pkg.retrieve[pkg.property(:ensure)])[1]
+ end
+ end
+end
diff --git a/lib/facter/virtualenv_version.rb b/lib/facter/virtualenv_version.rb
new file mode 100644
index 0000000..c923b09
--- /dev/null
+++ b/lib/facter/virtualenv_version.rb
@@ -0,0 +1,19 @@
+# Make virtualenv version available as a fact
+# Works with virualenv loaded and without, pip installed and package installed
+require 'puppet'
+pkg = Puppet::Type.type(:package).new(:name => "virtualenv")
+Facter.add("virtualenv_version") do
+ has_weight 100
+ setcode do
+ Facter::Util::Resolution.exec('virtualenv --version')
+ end
+end
+
+Facter.add("virtualenv_version") do
+ has_weight 50
+ setcode do
+ if pkg.retrieve[pkg.property(:ensure)] != 'purged'
+ /^.*(\d+\.\d+\.\d+).*$/.match(pkg.retrieve[pkg.property(:ensure)])[1]
+ end
+ end
+end
diff --git a/manifests/config.pp b/manifests/config.pp
index fdd808f..c7196f2 100644
--- a/manifests/config.pp
+++ b/manifests/config.pp
@@ -1,3 +1,18 @@
+# == Define: python::config
+#
+# Optionally installs the gunicorn service
+#
+# === Examples
+#
+# include python::config
+#
+# === Authors
+#
+# Sergey Stankevich
+# Ashley Penney
+# Fotis Gimian
+#
+
class python::config {
Class['python::install'] -> Python::Pip <| |>
@@ -21,4 +36,5 @@ class python::config {
}
}
}
+
}
diff --git a/manifests/gunicorn.pp b/manifests/gunicorn.pp
index 13f4872..159afa3 100644
--- a/manifests/gunicorn.pp
+++ b/manifests/gunicorn.pp
@@ -37,6 +37,8 @@
# dir => '/var/www/project1/current',
# bind => 'unix:/tmp/gunicorn.socket',
# environment => 'prod',
+# owner => 'www-data',
+# group => 'www-data',
# template => 'python/gunicorn.erb',
# }
#
@@ -53,6 +55,8 @@ define python::gunicorn (
$dir = false,
$bind = false,
$environment = false,
+ $owner = 'www-data',
+ $group = 'www-data',
$template = 'python/gunicorn.erb',
) {
diff --git a/manifests/init.pp b/manifests/init.pp
index 74244e1..4797b11 100644
--- a/manifests/init.pp
+++ b/manifests/init.pp
@@ -14,7 +14,8 @@
# Install python-dev. Default: false
#
# [*virtualenv*]
-# Install python-virtualenv. Default: false
+# Install python-virtualenv. Default: false, also accepts 'pip' which will
+# install latest virtualenv from pip rather than package manager
#
# [*gunicorn*]
# Install Gunicorn. Default: false
@@ -37,17 +38,18 @@
# Sergey Stankevich
#
class python (
- $version = 'system',
- $pip = false,
- $dev = false,
- $virtualenv = false,
- $gunicorn = false,
- $manage_gunicorn = true
+ $version = 'system',
+ $pip = false,
+ $dev = false,
+ $virtualenv = false,
+ $gunicorn = false,
+ $manage_gunicorn = true,
+ $provider = undef
) {
# Module compatibility check
- $compatible = [ 'Debian', 'Ubuntu', 'CentOS', 'RedHat', 'Scientific' ]
- if ! ($::operatingsystem in $compatible) {
+ $compatible = [ 'Debian', 'RedHat']
+ if ! ($::osfamily in $compatible) {
fail("Module is not compatible with ${::operatingsystem}")
}
diff --git a/manifests/install.pp b/manifests/install.pp
index caead49..c4914f7 100644
--- a/manifests/install.pp
+++ b/manifests/install.pp
@@ -1,3 +1,18 @@
+# == Define: python::install
+#
+# Installs core python packages
+#
+# === Examples
+#
+# include python::install
+#
+# === Authors
+#
+# Sergey Stankevich
+# Ashley Penney
+# Fotis Gimian
+#
+
class python::install {
$python = $python::version ? {
@@ -5,13 +20,11 @@ class python::install {
default => "python${python::version}",
}
- $pythondev = $::operatingsystem ? {
- /(?i:RedHat|CentOS|Fedora|Scientific)/ => "${python}-devel",
- /(?i:Debian|Ubuntu)/ => "${python}-dev"
+ $pythondev = $::osfamily ? {
+ RedHat => "${python}-devel",
+ Debian => "${python}-dev"
}
- package { $python: ensure => present }
-
$dev_ensure = $python::dev ? {
true => present,
default => absent,
@@ -22,15 +35,26 @@ class python::install {
default => absent,
}
- package { $pythondev: ensure => $dev_ensure }
- package { 'python-pip': ensure => $pip_ensure }
-
$venv_ensure = $python::virtualenv ? {
true => present,
default => absent,
}
- package { 'python-virtualenv': ensure => $venv_ensure }
+ # Install latest from pip if pip is the provider
+ case $python::provider {
+ pip: {
+ package { 'virtualenv': ensure => latest, provider => pip }
+ package { 'pip': ensure => latest, provider => pip }
+ package { $pythondev: ensure => latest }
+ package { "python==${python::version}": ensure => latest, provider => pip }
+ }
+ default: {
+ package { 'python-virtualenv': ensure => $venv_ensure }
+ package { 'python-pip': ensure => $pip_ensure }
+ package { $pythondev: ensure => $dev_ensure }
+ package { $python: ensure => present }
+ }
+ }
if $python::manage_gunicorn {
$gunicorn_ensure = $python::gunicorn ? {
diff --git a/manifests/pip.pp b/manifests/pip.pp
index 7b51439..fb73ae7 100644
--- a/manifests/pip.pp
+++ b/manifests/pip.pp
@@ -57,7 +57,7 @@ define python::pip (
$cwd = $virtualenv ? {
'system' => '/',
- default => "${virtualenv}",
+ default => $virtualenv,
}
$pip_env = $virtualenv ? {
@@ -85,19 +85,36 @@ define python::pip (
default => "${url}#egg=${egg_name}",
}
+ # Python 2.6 and older does not support setuptools/distribute > 0.8 which
+ # is required for pip wheel support, pip therefor requires --no-use-wheel flag
+ # if the # pip version is more recent than 1.4.1 but using an old python or
+ # setuputils/distribute version
+ # To check for this we test for wheel parameter using help and then using
+ # version, this makes sure we only use wheels if they are supported
+
case $ensure {
present: {
exec { "pip_install_${name}":
- command => "$pip_env --log ${cwd}/pip.log install $install_args ${proxy_flag} ${source}",
- unless => "$pip_env freeze | grep -i -e ${grep_regex}",
+ command => "${pip_env} wheel --help > /dev/null 2>&1 && { ${pip_env} wheel --version > /dev/null 2>&1 || wheel_support_flag='--no-use-wheel'; } ; ${pip_env} --log ${cwd}/pip.log install ${install_args} \$wheel_support_flag ${proxy_flag} ${source}",
+ unless => "${pip_env} freeze | grep -i -e ${grep_regex}",
+ user => $owner,
+ environment => $environment,
+ path => ['/usr/local/bin','/usr/bin','/bin', '/usr/sbin'],
+ }
+ }
+
+ latest: {
+ exec { "pip_install_${name}":
+ command => "${pip_env} wheel --help > /dev/null 2>&1 && { ${pip_env} wheel --version > /dev/null 2>&1 || wheel_support_flag='--no-use-wheel'; } ; ${pip_env} --log ${cwd}/pip.log install --upgrade \$wheel_support_flag ${proxy_flag} ${source}",
user => $owner,
environment => $environment,
+ path => ['/usr/local/bin','/usr/bin','/bin', '/usr/sbin'],
}
}
latest: {
exec { "pip_install_${name}":
- command => "$pip_env --log ${cwd}/pip.log install -U $install_args ${proxy_flag} ${source}",
+ command => "${pip_env} wheel --help > /dev/null 2>&1 && { ${pip_env} wheel --version > /dev/null 2>&1 || wheel_support_flag='--no-use-wheel'; } ; ${pip_env} --log ${cwd}/pip.log install -U ${install_args} \$wheel_support_flag ${proxy_flag} ${source}",
user => $owner,
environment => $environment,
}
@@ -105,10 +122,11 @@ define python::pip (
default: {
exec { "pip_uninstall_${name}":
- command => "echo y | $pip_env uninstall $uninstall_args ${proxy_flag} ${name}",
- onlyif => "$pip_env freeze | grep -i -e ${grep_regex}",
+ command => "echo y | ${pip_env} uninstall ${uninstall_args} ${proxy_flag} ${name}",
+ onlyif => "${pip_env} freeze | grep -i -e ${grep_regex}",
user => $owner,
environment => $environment,
+ path => ['/usr/local/bin','/usr/bin','/bin', '/usr/sbin'],
}
}
}
diff --git a/manifests/requirements.pp b/manifests/requirements.pp
index 60c5b6c..5fa6eb9 100644
--- a/manifests/requirements.pp
+++ b/manifests/requirements.pp
@@ -27,6 +27,11 @@
# [*environment*]
# Additional environment variables required to install the packages. Default: none
#
+# [*forceupdate*]
+# Run a pip install requirements even if we don't receive an event from the
+# requirements file - Useful for when the requirements file is written as part of a
+# resource other than file (E.g vcsrepo)
+#
# === Examples
#
# python::requirements { '/var/www/project1/requirements.txt':
@@ -47,7 +52,8 @@ define python::requirements (
$group = 'root',
$proxy = false,
$src = false,
- $environment = []
+ $environment = [],
+ $forceupdate = false,
) {
if $virtualenv == 'system' and ($owner != 'root' or $group != 'root') {
@@ -56,7 +62,7 @@ define python::requirements (
$cwd = $virtualenv ? {
'system' => '/',
- default => "${virtualenv}",
+ default => $virtualenv,
}
$pip_env = $virtualenv ? {
@@ -90,8 +96,8 @@ define python::requirements (
exec { "python_requirements${name}":
provider => shell,
- command => "${pip_env} --log-file ${cwd}/pip.log install ${proxy_flag} ${src_flag} -r ${requirements}",
- refreshonly => true,
+ command => "${pip_env} --log ${cwd}/pip.log install ${proxy_flag} ${src_flag} -r ${requirements}",
+ refreshonly => !$forceupdate,
timeout => 1800,
user => $owner,
subscribe => File[$requirements],
diff --git a/manifests/virtualenv.pp b/manifests/virtualenv.pp
index 8486183..7f7fbb4 100644
--- a/manifests/virtualenv.pp
+++ b/manifests/virtualenv.pp
@@ -15,6 +15,8 @@
#
# [*systempkgs*]
# Copy system site-packages into virtualenv. Default: don't
+# If virtualenv version < 1.7 this flag has no effect since
+# the system packages were not supported
#
# [*distribute*]
# Include distribute in the virtualenv. Default: true
@@ -72,7 +74,7 @@ define python::virtualenv (
$group = 'root',
$proxy = false,
$environment = [],
- $path = [ '/bin', '/usr/bin', '/usr/sbin' ],
+ $path = [ '/bin', '/usr/bin', '/usr/sbin','/usr/local/bin' ],
$cwd = undef,
$timeout = 1800
) {
@@ -96,9 +98,16 @@ define python::virtualenv (
default => "&& export http_proxy=${proxy}",
}
- $system_pkgs_flag = $systempkgs ? {
- false => '',
- default => '--system-site-packages',
+ # Virtualenv versions prior to 1.7 do not support the
+ # --system-site-packages flag, default off for prior versions
+ # Prior to version 1.7 the default was equal to --system-site-packages
+ # and the flag --no-site-packages had to be passed to do the opposite
+ if (( versioncmp($::virtualenv_version,'1.7') > 0 ) and ( $systempkgs == true )) {
+ $system_pkgs_flag = '--system-site-packages'
+ } elsif (( versioncmp($::virtualenv_version,'1.7') < 0 ) and ( $systempkgs == false )) {
+ $system_pkgs_flag = '--no-site-packages'
+ } else {
+ $system_pkgs_flag = ''
}
$distribute_pkg = $distribute ? {
@@ -110,18 +119,25 @@ define python::virtualenv (
default => "-i ${index}",
}
+ # Python 2.6 and older does not support setuptools/distribute > 0.8 which
+ # is required for pip wheel support, pip therefor requires --no-use-wheel flag
+ # if the # pip version is more recent than 1.4.1 but using an old python or
+ # setuputils/distribute version
+ # To check for this we test for wheel parameter using help and then using
+ # version, this makes sure we only use wheels if they are supported
+
exec { "python_virtualenv_${venv_dir}":
- command => "mkdir -p ${venv_dir} ${proxy_command} && virtualenv ${system_pkgs_flag} -p ${python} ${venv_dir} && ${venv_dir}/bin/pip --log-file ${venv_dir}/pip.log install ${pypi_index} ${proxy_flag} --upgrade pip ${distribute_pkg}",
- user => $owner,
- creates => "${venv_dir}/bin/activate",
- path => $path,
- cwd => "/tmp",
+ command => "mkdir -p ${venv_dir} ${proxy_command} && virtualenv ${system_pkgs_flag} -p ${python} ${venv_dir} && ${venv_dir}/bin/pip wheel --help > /dev/null 2>&1 && { ${venv_dir}/bin/pip wheel --version > /dev/null 2>&1 || wheel_support_flag='--no-use-wheel'; } ; ${venv_dir}/bin/pip --log ${venv_dir}/pip.log install ${pypi_index} ${proxy_flag} \$wheel_support_flag --upgrade pip ${distribute_pkg}",
+ user => $owner,
+ path => $path,
+ cwd => $venv_dir,
environment => $environment,
+ unless => "grep '^[\\t ]*VIRTUAL_ENV=[\\\\'\\\"]*${venv_dir}[\\\"\\\\'][\\t ]*$' ${venv_dir}/bin/activate", #Unless activate exists and VIRTUAL_ENV is correct we re-create the virtualenv
}
if $requirements {
exec { "python_requirements_initial_install_${requirements}_${venv_dir}":
- command => "${venv_dir}/bin/pip --log-file ${venv_dir}/pip.log install ${pypi_index} ${proxy_flag} -r ${requirements}",
+ command => "${venv_dir}/bin/pip wheel --help > /dev/null 2>&1 && { ${venv_dir}/bin/pip wheel --version > /dev/null 2>&1 || wheel_support_flag='--no-use-wheel'; } ; ${venv_dir}/bin/pip --log ${venv_dir}/pip.log install ${pypi_index} ${proxy_flag} \$wheel_support_flag -r ${requirements}",
refreshonly => true,
timeout => $timeout,
user => $owner,
@@ -139,7 +155,6 @@ define python::virtualenv (
require => Exec["python_virtualenv_${venv_dir}"],
}
}
-
} elsif $ensure == 'absent' {
file { $venv_dir:
@@ -148,7 +163,5 @@ define python::virtualenv (
recurse => true,
purge => true,
}
-
}
-
}
diff --git a/templates/gunicorn.erb b/templates/gunicorn.erb
index 1a96531..10f81fa 100644
--- a/templates/gunicorn.erb
+++ b/templates/gunicorn.erb
@@ -1,36 +1,36 @@
CONFIG = {
-<% if mode == 'django' -%>
+<% if @mode == 'django' -%>
'mode': 'django',
<% else -%>
'mode': 'wsgi',
<% end -%>
-<% if virtualenv -%>
+<% if @virtualenv -%>
'environment': {
-<% if environment -%>
- 'ENVIRONMENT': '<%= environment %>',
+<% if @environment -%>
+ 'ENVIRONMENT': '<%= @environment %>',
<% end -%>
- 'PYTHONPATH': '<%= virtualenv %>'
+ 'PYTHONPATH': '<%= @virtualenv %>'
},
<% end -%>
- 'working_dir': '<%= dir %>',
- 'user': 'www-data',
- 'group': 'www-data',
-<% if virtualenv -%>
- 'python': '<%= virtualenv %>/bin/python',
+ 'working_dir': '<%= @dir %>',
+ 'user': '<%= @owner %>',
+ 'group': '<%= @group %>',
+<% if @virtualenv -%>
+ 'python': '<%= @virtualenv %>/bin/python',
<% else -%>
'python': '/usr/bin/python',
<% end -%>
'args': (
-<% if !virtualenv and !bind -%>
- '--bind=unix:/tmp/gunicorn-<%= name %>.socket',
-<% elsif virtualenv and !bind -%>
- '--bind=unix:<%= virtualenv %>/<%= name %>.socket',
+<% if !@virtualenv and !@bind -%>
+ '--bind=unix:/tmp/gunicorn-<%= @name %>.socket',
+<% elsif @virtualenv and !@bind -%>
+ '--bind=unix:<%= @virtualenv %>/<%= @name %>.socket',
<% else -%>
- '--bind=<%= bind %>',
+ '--bind=<%= @bind %>',
<% end -%>
'--workers=<%= @processorcount.to_i*2 %>',
'--timeout=30',
-<% if mode != 'django' -%>
+<% if @mode != 'django' -%>
'app:app',
<% end -%>
),