summaryrefslogtreecommitdiff
path: root/manifests
diff options
context:
space:
mode:
authorSergey Stankevich <sergey.stankevich@gmail.com>2012-09-09 18:36:30 -0400
committerSergey Stankevich <sergey.stankevich@gmail.com>2012-09-09 18:36:30 -0400
commited137893babebabdfdb5adf44d1a52272093ce8b (patch)
treef611108dc849fe8f4372aac981d7e242d59b957b /manifests
Initial import
Diffstat (limited to 'manifests')
-rw-r--r--manifests/config.pp24
-rw-r--r--manifests/gunicorn.pp65
-rw-r--r--manifests/init.pp50
-rw-r--r--manifests/install.pp31
-rw-r--r--manifests/pip.pp64
-rw-r--r--manifests/requirements.pp68
-rw-r--r--manifests/virtualenv.pp82
7 files changed, 384 insertions, 0 deletions
diff --git a/manifests/config.pp b/manifests/config.pp
new file mode 100644
index 0000000..43da22e
--- /dev/null
+++ b/manifests/config.pp
@@ -0,0 +1,24 @@
+class python::config {
+
+ Class['python::install'] -> Python::Pip <| |>
+ Class['python::install'] -> Python::Requirements <| |>
+ Class['python::install'] -> Python::Virtualenv <| |>
+
+ Python::Virtualenv <| |> -> Python::Pip <| |>
+ Python::Virtualenv <| |> -> Python::Requirements <| |>
+
+ if $python::gunicorn {
+ Class['python::install'] -> Python::Gunicorn <| |>
+
+ Python::Gunicorn <| |> ~> Service['gunicorn']
+
+ service { 'gunicorn':
+ ensure => running,
+ enable => true,
+ hasrestart => true,
+ hasstatus => false,
+ pattern => '/usr/bin/gunicorn',
+ }
+ }
+
+}
diff --git a/manifests/gunicorn.pp b/manifests/gunicorn.pp
new file mode 100644
index 0000000..d328d75
--- /dev/null
+++ b/manifests/gunicorn.pp
@@ -0,0 +1,65 @@
+# == Define: python::gunicorn
+#
+# Manages Gunicorn virtual hosts.
+#
+# === Parameters
+#
+# [*ensure*]
+# present|absent. Default: present
+#
+# [*virtualenv*]
+# Run in virtualenv, specify directory. Default: disabled
+#
+# [*mode*]
+# Gunicorn mode.
+# wsgi|django. Default: wsgi
+#
+# [*dir*]
+# Application directory.
+#
+# [*bind*]
+# Bind on: 'HOST', 'HOST:PORT', 'unix:PATH'.
+# Default: system-wide: unix:/tmp/gunicorn-$name.socket
+# virtualenv: unix:${virtualenv}/${name}.socket
+#
+# [*environment*]
+# Set ENVIRONMENT variable. Default: none
+#
+# === Examples
+#
+# python::gunicorn { 'vhost':
+# ensure => present,
+# virtualenv => '/var/www/project1',
+# mode => 'wsgi',
+# dir => '/var/www/project1/current',
+# bind => 'unix:/tmp/gunicorn.socket',
+# environment => 'prod',
+# }
+#
+# === Authors
+#
+# Sergey Stankevich
+#
+define python::gunicorn (
+ $ensure = present,
+ $virtualenv = false,
+ $mode = 'wsgi',
+ $dir = false,
+ $bind = false,
+ $environment = false
+) {
+
+ # Parameter validation
+ if ! $dir {
+ fail('python::gunicorn: dir parameter must not be empty')
+ }
+
+ file { "/etc/gunicorn.d/${name}":
+ ensure => $ensure,
+ mode => '0644',
+ owner => 'root',
+ group => 'root',
+ content => template('python/gunicorn.erb'),
+ }
+
+}
diff --git a/manifests/init.pp b/manifests/init.pp
new file mode 100644
index 0000000..c7ab10f
--- /dev/null
+++ b/manifests/init.pp
@@ -0,0 +1,50 @@
+# == Class: python
+#
+# Installs and manages python, python-dev, python-virtualenv and Gunicorn.
+#
+# === Parameters
+#
+# [*version*]
+# Python version to install. Default: system default
+#
+# [*dev*]
+# Install python-dev. Default: false
+#
+# [*virtualenv*]
+# Install python-virtualenv. Default: false
+#
+# [*gunicorn*]
+# Install Gunicorn. Default: false
+#
+# === Examples
+#
+# class { 'python':
+# version => 'system',
+# dev => true,
+# virtualenv => true,
+# gunicorn => true,
+# }
+#
+# === Authors
+#
+# Sergey Stankevich
+#
+class python (
+ $version = 'system',
+ $dev = false,
+ $virtualenv = false,
+ $gunicorn = false
+) {
+
+ # Module compatibility check
+ $compatible = [ 'Debian', 'Ubuntu' ]
+ if ! ($::operatingsystem in $compatible) {
+ fail("Module is not compatible with ${::operatingsystem}")
+ }
+
+ Class['python::install'] -> Class['python::config']
+
+ include python::install
+ include python::config
+
+}
diff --git a/manifests/install.pp b/manifests/install.pp
new file mode 100644
index 0000000..dec99b8
--- /dev/null
+++ b/manifests/install.pp
@@ -0,0 +1,31 @@
+class python::install {
+
+ $python = $python::version ? {
+ 'system' => 'python',
+ default => "python${python::version}",
+ }
+
+ package { $python: ensure => present }
+
+ $dev_ensure = $python::dev ? {
+ true => present,
+ default => absent,
+ }
+
+ package { "${python}-dev": ensure => $dev_ensure }
+
+ $venv_ensure = $python::virtualenv ? {
+ true => present,
+ default => absent,
+ }
+
+ package { 'python-virtualenv': ensure => $venv_ensure }
+
+ $gunicorn_ensure = $python::gunicorn ? {
+ true => present,
+ default => absent,
+ }
+
+ package { 'gunicorn': ensure => $gunicorn_ensure }
+
+}
diff --git a/manifests/pip.pp b/manifests/pip.pp
new file mode 100644
index 0000000..9762c10
--- /dev/null
+++ b/manifests/pip.pp
@@ -0,0 +1,64 @@
+# == Define: python::pip
+#
+# Installs and manages packages from pip.
+#
+# === Parameters
+#
+# [*ensure*]
+# present|absent. Default: present
+#
+# [*virtualenv*]
+# virtualenv to run pip in.
+#
+# [*proxy*]
+# Proxy server to use for outbound connections. Default: none
+#
+# === Examples
+#
+# python::pip { 'flask':
+# virtualenv => '/var/www/project1',
+# proxy => 'http://proxy.domain.com:3128',
+# }
+#
+# === Authors
+#
+# Sergey Stankevich
+#
+define python::pip (
+ $virtualenv,
+ $ensure = present,
+ $proxy = false
+) {
+
+ # Parameter validation
+ if ! $virtualenv {
+ fail('python::pip: virtualenv parameter must not be empty')
+ }
+
+ $proxy_flag = $proxy ? {
+ false => '',
+ default => "--proxy=${proxy}",
+ }
+
+ $grep_regex = $name ? {
+ /==/ => "^${name}\$",
+ default => "^${name}==",
+ }
+
+ case $ensure {
+ present: {
+ exec { "pip_install_${name}":
+ command => "${virtualenv}/bin/pip install ${proxy_flag} ${name}",
+ unless => "${virtualenv}/bin/pip freeze | grep -i -e ${grep_regex}",
+ }
+ }
+
+ default: {
+ exec { "pip_uninstall_${name}":
+ command => "echo y | ${virtualenv}/bin/pip uninstall ${proxy_flag} ${name}",
+ onlyif => "${virtualenv}/bin/pip freeze | grep -i -e ${grep_regex}",
+ }
+ }
+ }
+
+}
diff --git a/manifests/requirements.pp b/manifests/requirements.pp
new file mode 100644
index 0000000..e49c86c
--- /dev/null
+++ b/manifests/requirements.pp
@@ -0,0 +1,68 @@
+# == Define: python::requirements
+#
+# Installs and manages Python packages from requirements file.
+#
+# === Parameters
+#
+# [*virtualenv*]
+# virtualenv to run pip in. Default: system-wide
+#
+# [*proxy*]
+# Proxy server to use for outbound connections. Default: none
+#
+# === Examples
+#
+# python::requirements { '/var/www/project1/requirements.txt':
+# virtualenv => '/var/www/project1',
+# proxy => 'http://proxy.domain.com:3128',
+# }
+#
+# === Authors
+#
+# Sergey Stankevich
+#
+define python::requirements (
+ $virtualenv = 'system',
+ $proxy = false
+) {
+
+ $requirements = $name
+
+ $pip_env = $virtualenv ? {
+ 'system' => '`which pip`',
+ default => "${virtualenv}/bin/pip",
+ }
+
+ $proxy_flag = $proxy ? {
+ false => '',
+ default => "--proxy=${proxy}",
+ }
+
+ $req_dir = inline_template('<%= requirements.match(%r!(.+)/.+!)[1] %>')
+ $req_crc = "${req_dir}/requirements.sha1"
+
+ file { $requirements:
+ ensure => present,
+ mode => '0644',
+ owner => 'root',
+ group => 'root',
+ replace => false,
+ content => '# Puppet will install and/or update pip packages listed here',
+ }
+
+ # SHA1 checksum to detect changes
+ exec { "python_requirements_check_${name}":
+ command => "sha1sum ${requirements} > ${req_crc}",
+ unless => "sha1sum -c ${req_crc}",
+ require => File[$requirements],
+ }
+
+ exec { "python_requirements_update_${name}":
+ command => "${pip_env} install ${proxy_flag} -Ur ${requirements}",
+ cwd => $virtualenv,
+ refreshonly => true,
+ timeout => 1800,
+ subscribe => Exec["python_requirements_check_${name}"],
+ }
+
+}
diff --git a/manifests/virtualenv.pp b/manifests/virtualenv.pp
new file mode 100644
index 0000000..a5cf12b
--- /dev/null
+++ b/manifests/virtualenv.pp
@@ -0,0 +1,82 @@
+# == Define: python::virtualenv
+#
+# Creates Python virtualenv.
+#
+# === Parameters
+#
+# [*ensure*]
+# present|absent. Default: present
+#
+# [*version*]
+# Python version to use. Default: system default
+#
+# [*requirements*]
+# Path to pip requirements.txt file. Default: none
+#
+# [*proxy*]
+# Proxy server to use for outbound connections. Default: none
+#
+# === Examples
+#
+# python::virtualenv { '/var/www/project1':
+# ensure => present,
+# version => 'system',
+# requirements => '/var/www/project1/requirements.txt',
+# proxy => 'http://proxy.domain.com:3128',
+# }
+#
+# === Authors
+#
+# Sergey Stankevich
+#
+define python::virtualenv (
+ $ensure = present,
+ $version = 'system',
+ $requirements = false,
+ $proxy = false
+) {
+
+ $venv_dir = $name
+
+ if $ensure == 'present' {
+
+ $python = $version ? {
+ 'system' => 'python',
+ default => "python${version}",
+ }
+
+ $proxy_flag = $proxy ? {
+ false => '',
+ default => "--proxy=${proxy}",
+ }
+
+ exec { "python_virtualenv_${venv_dir}":
+ command => "mkdir -p ${venv_dir} \
+ && export http_proxy=${proxy} \
+ && virtualenv -p `which ${python}` ${venv_dir} \
+ && ${venv_dir}/bin/pip install ${proxy_flag} --upgrade distribute pip",
+ creates => $venv_dir,
+ }
+
+ if $requirements {
+ Exec["python_virtualenv_${venv_dir}"]
+ -> Python::Requirements[$requirements]
+
+ python::requirements { $requirements:
+ virtualenv => $venv_dir,
+ proxy => $proxy,
+ }
+ }
+
+ } elsif $ensure == 'absent' {
+
+ file { $venv_dir:
+ ensure => absent,
+ force => true,
+ recurse => true,
+ purge => true,
+ }
+
+ }
+
+}