Permalink
Browse files

Initial commit

  • Loading branch information...
0 parents commit 866ec86aeda04ab4133beeeecedd54871667097a @flashingpumpkin flashingpumpkin committed Oct 26, 2011
1 AUTHORS
@@ -0,0 +1 @@
+Alen Mujezinovic
22 LICENSE
@@ -0,0 +1,22 @@
+Copyright (c) 2009 Caffeinehit Ltd
+
+Permission is hereby granted, free of charge, to any person
+obtaining a copy of this software and associated documentation
+files (the "Software"), to deal in the Software without
+restriction, including without limitation the rights to use,
+copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the
+Software is furnished to do so, subject to the following
+conditions:
+
+The above copyright notice and this permission notice shall be
+included in all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+OTHER DEALINGS IN THE SOFTWARE.
4 MANIFEST.in
@@ -0,0 +1,4 @@
+include AUTHORS
+include LICENSE
+include README.rst
+
7 README.md
@@ -0,0 +1,7 @@
+# fabric-provision
+
+`fabric-provision` is a tiny wrapper around
+[Chef Solo](http://wiki.opscode.com/display/chef/Chef+Solo). Use it for easy
+provisioning right out of your ``fabfile.py``.
+
+Have a look at the [documentation](http://fabric-provision.readthedocs.org).
9 README.rst
@@ -0,0 +1,9 @@
+fabric-provision
+================
+
+``fabric-provision`` is a tiny wrapper around `Chef
+Solo <http://wiki.opscode.com/display/chef/Chef+Solo>`_. Use it for easy
+provisioning right out of your ``fabfile.py``.
+
+Have a look at the
+`documentation <http://fabric-provision.readthedocs.org>`_.
9 Vagrantfile
@@ -0,0 +1,9 @@
+Vagrant::Config.run do |config|
+ # Every Vagrant virtual environment requires a box to build off of.
+ config.vm.box = "base"
+
+ config.vm.boot_mode = :gui
+
+ config.vm.forward_port "ssh", 22, 2222
+
+end
1 cookbooks/README
@@ -0,0 +1 @@
+Place your cookbooks here
162 cookbooks/python/README.md
@@ -0,0 +1,162 @@
+Description
+===========
+
+Installs and configures Python. Also includes LWRPs for managing python packages with `pip` and `virtualenv` isolated Python environments.
+
+Requirements
+============
+
+Platform
+--------
+
+* Debian, Ubuntu
+* CentOS, Red Hat, Fedora
+
+Cookbooks
+---------
+
+* build-essential
+
+Attributes
+==========
+
+* `node["python"]["install_method"]` = method to install python with, default `package`.
+
+The file also contains the following attribute types:
+
+* platform specific locations and settings.
+* source installation settings
+
+Resource/Provider
+=================
+
+This cookbook includes LWRPs for managing:
+
+* pip packages
+* virtualenv isolated Python environments
+
+`python_pip`
+------------
+
+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.
+
+# Actions
+
+- :install: Install a pip package - if version is provided, install that specific version
+- :upgrade: Upgrade a pip package - if version is provided, upgrade to that specific version
+- :remove: Remove a pip package
+- :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`
+
+# Attribute Parameters
+
+- package_name: name attribute. The name of the pip package to install
+- version: the version of the package to install/upgrade. If no version is given latest is assumed.
+- virtualenv: virtualenv environment to install pip package into
+- options: Add additional options to the underlying pip package command
+
+# Example
+
+ # install latest gunicorn into system path
+ python_pip "gunicorn" do
+ action :install
+ end
+
+ # target a virtualenv
+ python_pip "gunicorn" do
+ virtualenv "/home/ubunut/my_ve"
+ action :install
+ end
+
+ # install Django 1.1.4
+ python_pip "django" do
+ version "1.1.4"
+ action :install
+ end
+
+ # use this provider with the core package resource
+ package "django" do
+ provider Chef::Provider::PythonPip
+ action :install
+ end
+
+`python_virtualenv`
+-------------------
+
+[`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.
+
+# Actions
+
+- :create: creates a new virtualenv
+- :delete: deletes an existing virtualenv
+
+# Attribute Parameters
+
+- path: name attribute. The path where the virtualenv will be created
+- interpreter: The Python interpreter to use. default is `python2.6`
+- owner: The owner for the virtualenv
+- group: The group owner of the file (string or id)
+
+# Example
+
+ # create a 2.6 virtualenv owned by ubuntu user
+ python_virtualenv "/home/ubuntu/my_cool_ve" do
+ owner "ubuntu"
+ group "ubuntu"
+ action :create
+ end
+
+ # create a Python 2.4 virtualenv
+ python_virtualenv "/home/ubuntu/my_old_ve" do
+ interpreter "python2.4"
+ owner "ubuntu"
+ group "ubuntu"
+ action :create
+ end
+
+Usage
+=====
+
+default
+-------
+
+Include default recipe in a run list, to get `python`, `pip` and `virtualenv`. Installs python by package or source depending on the platform.
+
+package
+-------
+
+Installs Python from packages.
+
+source
+------
+
+Installs Python from source.
+
+pip
+---
+
+Installs `pip` from source.
+
+virtualenv
+----------
+
+Installs virtualenv using the `python_pip` resource.
+
+
+License and Author
+==================
+
+Author:: Seth Chisamore (<schisamo@opscode.com>)
+
+Copyright:: 2011, Opscode, Inc
+
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
28 cookbooks/python/attributes/default.rb
@@ -0,0 +1,28 @@
+#
+# Author:: Seth Chisamore (<schisamo@opscode.com>)
+# Cookbook Name:: python
+# Attribute:: default
+#
+# Copyright 2011, Opscode, Inc.
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+
+default['python']['install_method'] = 'package'
+
+default['python']['url'] = 'http://www.python.org/ftp/python'
+default['python']['version'] = '2.7.1'
+default['python']['checksum'] = '80e387bcf57eae8ce26726753584fd63e060ec11682d1145af921e85fd612292'
+default['python']['prefix_dir'] = '/usr/local'
+
+default['python']['configure_options'] = %W{--prefix=#{python['prefix_dir']}}
17 cookbooks/python/metadata.rb
@@ -0,0 +1,17 @@
+maintainer "Opscode, Inc."
+maintainer_email "cookbooks@opscode.com"
+license "Apache 2.0"
+description "Installs Python, pip and virtualenv. Includes LWRPs for managing Python packages with `pip` and `virtualenv` isolated Python environments."
+version "1.0.2"
+
+depends "build-essential"
+
+recipe "python", "Installs python, pip, and virtualenv"
+recipe "python::package", "Installs python using packages."
+recipe "python::source", "Installs python from source."
+recipe "python::pip", "Installs pip from source."
+recipe "python::virtualenv", "Installs virtualenv using the python_pip resource."
+
+%w{ debian ubuntu centos redhat fedora }.each do |os|
+ supports os
+end
146 cookbooks/python/providers/pip.rb
@@ -0,0 +1,146 @@
+#
+# Author:: Seth Chisamore <schisamo@opscode.com>
+# Cookbook Name:: python
+# Provider:: pip
+#
+# Copyright:: 2011, Opscode, Inc <legal@opscode.com>
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+
+require 'chef/mixin/shell_out'
+require 'chef/mixin/language'
+include Chef::Mixin::ShellOut
+
+# the logic in all action methods mirror that of
+# the Chef::Provider::Package which will make
+# refactoring into core chef easy
+
+action :install do
+ # If we specified a version, and it's not the current version, move to the specified version
+ if @new_resource.version != nil && @new_resource.version != @current_resource.version
+ install_version = @new_resource.version
+ # If it's not installed at all, install it
+ elsif @current_resource.version == nil
+ install_version = candidate_version
+ end
+
+ if install_version
+ Chef::Log.info("Installing #{@new_resource} version #{install_version}")
+ status = install_package(@new_resource.package_name, install_version)
+ if status
+ @new_resource.updated_by_last_action(true)
+ end
+ end
+end
+
+action :upgrade do
+ if @current_resource.version != candidate_version
+ orig_version = @current_resource.version || "uninstalled"
+ Chef::Log.info("Upgrading #{@new_resource} version from #{orig_version} to #{candidate_version}")
+ status = upgrade_package(@new_resource.package_name, candidate_version)
+ if status
+ @new_resource.updated_by_last_action(true)
+ end
+ end
+end
+
+action :remove do
+ if removing_package?
+ Chef::Log.info("Removing #{@new_resource}")
+ remove_package(@current_resource.package_name, @new_resource.version)
+ @new_resource.updated_by_last_action(true)
+ else
+ end
+end
+
+def removing_package?
+ if @current_resource.version.nil?
+ false # nothing to remove
+ elsif @new_resource.version.nil?
+ true # remove any version of a package
+ elsif @new_resource.version == @current_resource.version
+ true # remove the version we have
+ else
+ false # we don't have the version we want to remove
+ end
+end
+
+def expand_options(options)
+ options ? " #{options}" : ""
+end
+
+# these methods are the required overrides of
+# a provider that extends from Chef::Provider::Package
+# so refactoring into core Chef should be easy
+
+def load_current_resource
+ @current_resource = Chef::Resource::PythonPip.new(@new_resource.name)
+ @current_resource.package_name(@new_resource.package_name)
+ @current_resource.version(nil)
+
+ unless current_installed_version.nil?
+ @current_resource.version(current_installed_version)
+ end
+
+ @current_resource
+end
+
+def current_installed_version
+ @current_installed_version ||= begin
+ delimeter = /==/
+
+ version_check_cmd = "pip freeze#{expand_virtualenv(can_haz_virtualenv(@new_resource))} | grep -i #{@new_resource.package_name}=="
+ # incase you upgrade pip with pip!
+ if @new_resource.package_name.eql?('pip')
+ delimeter = /\s/
+ version_check_cmd = "pip --version"
+ end
+ p = shell_out!(version_check_cmd)
+ p.stdout.split(delimeter)[1].strip
+ rescue Chef::Exceptions::ShellCommandFailed
+ end
+end
+
+def candidate_version
+ @candidate_version ||= begin
+ # `pip search` doesn't return versions yet
+ # `pip list` may be coming soon:
+ # https://bitbucket.org/ianb/pip/issue/197/option-to-show-what-version-would-be
+ @new_resource.version||'latest'
+ end
+end
+
+def install_package(name,version)
+ v = "==#{version}" unless version.eql?('latest')
+ shell_out!("pip install#{expand_options(@new_resource.options)}#{expand_virtualenv(can_haz_virtualenv(@new_resource))} #{name}#{v}")
+end
+
+def upgrade_package(name, version)
+ v = "==#{version}" unless version.eql?('latest')
+ shell_out!("pip install --upgrade#{expand_options(@new_resource.options)}#{expand_virtualenv(can_haz_virtualenv(@new_resource))} #{@new_resource.name}#{v}")
+end
+
+def remove_package(name, version)
+ shell_out!("pip uninstall -y#{expand_options(@new_resource.options)}#{expand_virtualenv(can_haz_virtualenv(@new_resource))} #{@new_resource.name}")
+end
+
+def expand_virtualenv(virtualenv)
+ virtualenv && " --environment=#{virtualenv}"
+end
+
+# TODO remove when provider is moved into Chef core
+# this allows PythonPip to work with Chef::Resource::Package
+def can_haz_virtualenv(nr)
+ nr.respond_to?("virtualenv") ? nr.virtualenv : nil
+end
60 cookbooks/python/providers/virtualenv.rb
@@ -0,0 +1,60 @@
+#
+# Author:: Seth Chisamore <schisamo@opscode.com>
+# Cookbook Name:: python
+# Provider:: virtualenv
+#
+# Copyright:: 2011, Opscode, Inc <legal@opscode.com>
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+
+require 'chef/mixin/shell_out'
+require 'chef/mixin/language'
+include Chef::Mixin::ShellOut
+
+action :create do
+ unless exists?
+ Chef::Log.info("Creating virtualenv #{@new_resource} at #{@new_resource.path}")
+ execute "virtualenv --python=#{@new_resource.interpreter} #{@new_resource.path}" do
+ user new_resource.owner if new_resource.owner
+ group new_resource.group if new_resource.group
+ end
+ new_resource.updated_by_last_action(true)
+ end
+end
+
+action :delete do
+ if exists?
+ Chef::Log.info("Deleting virtualenv #{@new_resource} at #{@new_resource.path}")
+ FileUtils.rm_rf(@new_resource.path)
+ new_resource.updated_by_last_action(true)
+ end
+end
+
+def load_current_resource
+ @current_resource = Chef::Resource::PythonVirtualenv.new(@new_resource.name)
+ @current_resource.path(@new_resource.path)
+
+ if exists?
+ cstats = ::File.stat(@current_resource.path)
+ @current_resource.owner(cstats.uid)
+ @current_resource.group(cstats.gid)
+ end
+ @current_resource
+end
+
+private
+def exists?
+ ::File.exist?(@current_resource.path) && ::File.directory?(@current_resource.path) \
+ && ::File.exists?("#{@current_resource.path}/bin/activate")
+end
23 cookbooks/python/recipes/default.rb
@@ -0,0 +1,23 @@
+#
+# Author:: Seth Chisamore <schisamo@opscode.com>
+# Cookbook Name:: python
+# Recipe:: default
+#
+# Copyright 2011, Opscode, Inc.
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+
+include_recipe "python::#{node['python']['install_method']}"
+include_recipe "python::pip"
+include_recipe "python::virtualenv"
36 cookbooks/python/recipes/package.rb
@@ -0,0 +1,36 @@
+#
+# Author:: Seth Chisamore <schisamo@opscode.com>
+# Cookbook Name:: python
+# Recipe:: package
+#
+# Copyright 2011, Opscode, Inc.
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+
+python_pkgs = value_for_platform(
+ ["debian","ubuntu"] => {
+ "default" => ["python","python-dev"]
+ },
+ ["centos","redhat","fedora"] => {
+ "default" => ["python26","python26-devel"]
+ },
+ "default" => ["python","python-dev"]
+)
+
+python_pkgs.each do |pkg|
+ package pkg do
+ action :install
+ end
+end
+
38 cookbooks/python/recipes/pip.rb
@@ -0,0 +1,38 @@
+#
+# Author:: Seth Chisamore <schisamo@opscode.com>
+# Cookbook Name:: python
+# Recipe:: pip
+#
+# Copyright 2011, Opscode, Inc.
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+
+# Ubuntu's python-setuptools, python-pip and python-virtualenv packages
+# are broken...this feels like Rubygems!
+# http://stackoverflow.com/questions/4324558/whats-the-proper-way-to-install-pip-virtualenv-and-distribute-for-python
+# https://bitbucket.org/ianb/pip/issue/104/pip-uninstall-on-ubuntu-linux
+remote_file "#{Chef::Config[:file_cache_path]}/distribute_setup.py" do
+ source "http://python-distribute.org/distribute_setup.py"
+ mode "0644"
+ not_if "which pip"
+end
+
+bash "install-pip" do
+ cwd Chef::Config[:file_cache_path]
+ code <<-EOF
+ python distribute_setup.py
+ easy_install pip
+ EOF
+ not_if "which pip"
+end
52 cookbooks/python/recipes/source.rb
@@ -0,0 +1,52 @@
+#
+# Author:: Seth Chisamore <schisamo@opscode.com>
+# Cookbook Name:: python
+# Recipe:: source
+#
+# Copyright 2011, Opscode, Inc.
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+
+configure_options = node['python']['configure_options'].join(" ")
+
+packages = value_for_platform(
+ ["centos","redhat","fedora"] =>
+ {"default" => ["openssl-devel","bzip2-devel","zlib-devel","expat-devel","db4-devel","sqlite-devel","ncurses-devel","readline-devel"]},
+ "default" =>
+ ["libssl-dev","libbz2-dev","zlib1g-dev","libexpat1-dev","libdb4.8-dev","libsqlite3-dev","libncursesw5-dev","libncurses5-dev","libreadline-dev"]
+ )
+
+packages.each do |dev_pkg|
+ package dev_pkg
+end
+
+version = node['python']['version']
+install_path = "#{node['python']['prefix_dir']}/lib/python#{version.split(/(^\d+\.\d+)/)}"
+
+remote_file "#{Chef::Config[:file_cache_path]}/Python-#{version}.tar.bz2" do
+ source "#{node['python']['url']}/#{version}/Python-#{version}.tar.bz2"
+ checksum node['python']['checksum']
+ mode "0644"
+ not_if { ::File.exists?(install_path) }
+end
+
+bash "build-and-install-python" do
+ cwd Chef::Config[:file_cache_path]
+ code <<-EOF
+ tar -jxvf Python-#{version}.tar.bz2
+ (cd Python-#{version} && ./configure #{configure_options})
+ (cd Python-#{version} && make && make install)
+ EOF
+ not_if { ::File.exists?(install_path) }
+end
25 cookbooks/python/recipes/virtualenv.rb
@@ -0,0 +1,25 @@
+#
+# Author:: Seth Chisamore <schisamo@opscode.com>
+# Cookbook Name:: python
+# Recipe:: virtualenv
+#
+# Copyright 2011, Opscode, Inc.
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+
+include_recipe "python::pip"
+
+python_pip "virtualenv" do
+ action :install
+end
26 cookbooks/python/resources/pip.rb
@@ -0,0 +1,26 @@
+#
+# Author:: Seth Chisamore <schisamo@opscode.com>
+# Cookbook Name:: python
+# Resource:: pip
+#
+# Copyright:: 2011, Opscode, Inc <legal@opscode.com>
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+
+actions :install, :upgrade, :remove, :purge
+
+attribute :package_name, :kind_of => String, :name_attribute => true
+attribute :version, :default => nil
+attribute :virtualenv, :kind_of => String
+attribute :options, :kind_of => String
26 cookbooks/python/resources/virtualenv.rb
@@ -0,0 +1,26 @@
+#
+# Author:: Seth Chisamore <schisamo@opscode.com>
+# Cookbook Name:: python
+# Resource:: virtualenv
+#
+# Copyright:: 2011, Opscode, Inc <legal@opscode.com>
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+
+actions :create, :delete
+
+attribute :path, :kind_of => String, :name_attribute => true
+attribute :interpreter, :default => 'python2.6'
+attribute :owner, :regex => Chef::Config[:user_valid_regex]
+attribute :group, :regex => Chef::Config[:group_valid_regex]
130 docs/Makefile
@@ -0,0 +1,130 @@
+# Makefile for Sphinx documentation
+#
+
+# You can set these variables from the command line.
+SPHINXOPTS =
+SPHINXBUILD = sphinx-build
+PAPER =
+BUILDDIR = _build
+
+# Internal variables.
+PAPEROPT_a4 = -D latex_paper_size=a4
+PAPEROPT_letter = -D latex_paper_size=letter
+ALLSPHINXOPTS = -d $(BUILDDIR)/doctrees $(PAPEROPT_$(PAPER)) $(SPHINXOPTS) .
+
+.PHONY: help clean html dirhtml singlehtml pickle json htmlhelp qthelp devhelp epub latex latexpdf text man changes linkcheck doctest
+
+help:
+ @echo "Please use \`make <target>' where <target> is one of"
+ @echo " html to make standalone HTML files"
+ @echo " dirhtml to make HTML files named index.html in directories"
+ @echo " singlehtml to make a single large HTML file"
+ @echo " pickle to make pickle files"
+ @echo " json to make JSON files"
+ @echo " htmlhelp to make HTML files and a HTML help project"
+ @echo " qthelp to make HTML files and a qthelp project"
+ @echo " devhelp to make HTML files and a Devhelp project"
+ @echo " epub to make an epub"
+ @echo " latex to make LaTeX files, you can set PAPER=a4 or PAPER=letter"
+ @echo " latexpdf to make LaTeX files and run them through pdflatex"
+ @echo " text to make text files"
+ @echo " man to make manual pages"
+ @echo " changes to make an overview of all changed/added/deprecated items"
+ @echo " linkcheck to check all external links for integrity"
+ @echo " doctest to run all doctests embedded in the documentation (if enabled)"
+
+clean:
+ -rm -rf $(BUILDDIR)/*
+
+html:
+ $(SPHINXBUILD) -b html $(ALLSPHINXOPTS) $(BUILDDIR)/html
+ @echo
+ @echo "Build finished. The HTML pages are in $(BUILDDIR)/html."
+
+dirhtml:
+ $(SPHINXBUILD) -b dirhtml $(ALLSPHINXOPTS) $(BUILDDIR)/dirhtml
+ @echo
+ @echo "Build finished. The HTML pages are in $(BUILDDIR)/dirhtml."
+
+singlehtml:
+ $(SPHINXBUILD) -b singlehtml $(ALLSPHINXOPTS) $(BUILDDIR)/singlehtml
+ @echo
+ @echo "Build finished. The HTML page is in $(BUILDDIR)/singlehtml."
+
+pickle:
+ $(SPHINXBUILD) -b pickle $(ALLSPHINXOPTS) $(BUILDDIR)/pickle
+ @echo
+ @echo "Build finished; now you can process the pickle files."
+
+json:
+ $(SPHINXBUILD) -b json $(ALLSPHINXOPTS) $(BUILDDIR)/json
+ @echo
+ @echo "Build finished; now you can process the JSON files."
+
+htmlhelp:
+ $(SPHINXBUILD) -b htmlhelp $(ALLSPHINXOPTS) $(BUILDDIR)/htmlhelp
+ @echo
+ @echo "Build finished; now you can run HTML Help Workshop with the" \
+ ".hhp project file in $(BUILDDIR)/htmlhelp."
+
+qthelp:
+ $(SPHINXBUILD) -b qthelp $(ALLSPHINXOPTS) $(BUILDDIR)/qthelp
+ @echo
+ @echo "Build finished; now you can run "qcollectiongenerator" with the" \
+ ".qhcp project file in $(BUILDDIR)/qthelp, like this:"
+ @echo "# qcollectiongenerator $(BUILDDIR)/qthelp/fabric-chef.qhcp"
+ @echo "To view the help file:"
+ @echo "# assistant -collectionFile $(BUILDDIR)/qthelp/fabric-chef.qhc"
+
+devhelp:
+ $(SPHINXBUILD) -b devhelp $(ALLSPHINXOPTS) $(BUILDDIR)/devhelp
+ @echo
+ @echo "Build finished."
+ @echo "To view the help file:"
+ @echo "# mkdir -p $$HOME/.local/share/devhelp/fabric-chef"
+ @echo "# ln -s $(BUILDDIR)/devhelp $$HOME/.local/share/devhelp/fabric-chef"
+ @echo "# devhelp"
+
+epub:
+ $(SPHINXBUILD) -b epub $(ALLSPHINXOPTS) $(BUILDDIR)/epub
+ @echo
+ @echo "Build finished. The epub file is in $(BUILDDIR)/epub."
+
+latex:
+ $(SPHINXBUILD) -b latex $(ALLSPHINXOPTS) $(BUILDDIR)/latex
+ @echo
+ @echo "Build finished; the LaTeX files are in $(BUILDDIR)/latex."
+ @echo "Run \`make' in that directory to run these through (pdf)latex" \
+ "(use \`make latexpdf' here to do that automatically)."
+
+latexpdf:
+ $(SPHINXBUILD) -b latex $(ALLSPHINXOPTS) $(BUILDDIR)/latex
+ @echo "Running LaTeX files through pdflatex..."
+ make -C $(BUILDDIR)/latex all-pdf
+ @echo "pdflatex finished; the PDF files are in $(BUILDDIR)/latex."
+
+text:
+ $(SPHINXBUILD) -b text $(ALLSPHINXOPTS) $(BUILDDIR)/text
+ @echo
+ @echo "Build finished. The text files are in $(BUILDDIR)/text."
+
+man:
+ $(SPHINXBUILD) -b man $(ALLSPHINXOPTS) $(BUILDDIR)/man
+ @echo
+ @echo "Build finished. The manual pages are in $(BUILDDIR)/man."
+
+changes:
+ $(SPHINXBUILD) -b changes $(ALLSPHINXOPTS) $(BUILDDIR)/changes
+ @echo
+ @echo "The overview file is in $(BUILDDIR)/changes."
+
+linkcheck:
+ $(SPHINXBUILD) -b linkcheck $(ALLSPHINXOPTS) $(BUILDDIR)/linkcheck
+ @echo
+ @echo "Link check complete; look for any errors in the above output " \
+ "or in $(BUILDDIR)/linkcheck/output.txt."
+
+doctest:
+ $(SPHINXBUILD) -b doctest $(ALLSPHINXOPTS) $(BUILDDIR)/doctest
+ @echo "Testing of doctests in the sources finished, look at the " \
+ "results in $(BUILDDIR)/doctest/output.txt."
216 docs/conf.py
@@ -0,0 +1,216 @@
+# -*- coding: utf-8 -*-
+#
+# fabric-chef documentation build configuration file, created by
+# sphinx-quickstart on Wed Oct 26 17:29:47 2011.
+#
+# This file is execfile()d with the current directory set to its containing dir.
+#
+# Note that not all possible configuration values are present in this
+# autogenerated file.
+#
+# All configuration values have a default; values that are commented out
+# serve to show the default.
+
+import sys, os
+
+# If extensions (or modules to document with autodoc) are in another directory,
+# add these directories to sys.path here. If the directory is relative to the
+# documentation root, use os.path.abspath to make it absolute, like shown here.
+#sys.path.insert(0, os.path.abspath('.'))
+
+# -- General configuration -----------------------------------------------------
+
+# If your documentation needs a minimal Sphinx version, state it here.
+#needs_sphinx = '1.0'
+
+# Add any Sphinx extension module names here, as strings. They can be extensions
+# coming with Sphinx (named 'sphinx.ext.*') or your custom ones.
+extensions = ['sphinx.ext.autodoc']
+
+# Add any paths that contain templates here, relative to this directory.
+templates_path = ['_templates']
+
+# The suffix of source filenames.
+source_suffix = '.rst'
+
+# The encoding of source files.
+#source_encoding = 'utf-8-sig'
+
+# The master toctree document.
+master_doc = 'index'
+
+# General information about the project.
+project = u'fabric-chef'
+copyright = u'2011, Alen Mujezinovic'
+
+# The version info for the project you're documenting, acts as replacement for
+# |version| and |release|, also used in various other places throughout the
+# built documents.
+#
+# The short X.Y version.
+version = '0.0.1'
+# The full version, including alpha/beta/rc tags.
+release = '0.0.1'
+
+# The language for content autogenerated by Sphinx. Refer to documentation
+# for a list of supported languages.
+#language = None
+
+# There are two options for replacing |today|: either, you set today to some
+# non-false value, then it is used:
+#today = ''
+# Else, today_fmt is used as the format for a strftime call.
+#today_fmt = '%B %d, %Y'
+
+# List of patterns, relative to source directory, that match files and
+# directories to ignore when looking for source files.
+exclude_patterns = ['_build']
+
+# The reST default role (used for this markup: `text`) to use for all documents.
+#default_role = None
+
+# If true, '()' will be appended to :func: etc. cross-reference text.
+#add_function_parentheses = True
+
+# If true, the current module name will be prepended to all description
+# unit titles (such as .. function::).
+#add_module_names = True
+
+# If true, sectionauthor and moduleauthor directives will be shown in the
+# output. They are ignored by default.
+#show_authors = False
+
+# The name of the Pygments (syntax highlighting) style to use.
+pygments_style = 'sphinx'
+
+# A list of ignored prefixes for module index sorting.
+#modindex_common_prefix = []
+
+
+# -- Options for HTML output ---------------------------------------------------
+
+# The theme to use for HTML and HTML Help pages. See the documentation for
+# a list of builtin themes.
+html_theme = 'default'
+
+# Theme options are theme-specific and customize the look and feel of a theme
+# further. For a list of options available for each theme, see the
+# documentation.
+#html_theme_options = {}
+
+# Add any paths that contain custom themes here, relative to this directory.
+#html_theme_path = []
+
+# The name for this set of Sphinx documents. If None, it defaults to
+# "<project> v<release> documentation".
+#html_title = None
+
+# A shorter title for the navigation bar. Default is the same as html_title.
+#html_short_title = None
+
+# The name of an image file (relative to this directory) to place at the top
+# of the sidebar.
+#html_logo = None
+
+# The name of an image file (within the static path) to use as favicon of the
+# docs. This file should be a Windows icon file (.ico) being 16x16 or 32x32
+# pixels large.
+#html_favicon = None
+
+# Add any paths that contain custom static files (such as style sheets) here,
+# relative to this directory. They are copied after the builtin static files,
+# so a file named "default.css" will overwrite the builtin "default.css".
+html_static_path = ['_static']
+
+# If not '', a 'Last updated on:' timestamp is inserted at every page bottom,
+# using the given strftime format.
+#html_last_updated_fmt = '%b %d, %Y'
+
+# If true, SmartyPants will be used to convert quotes and dashes to
+# typographically correct entities.
+#html_use_smartypants = True
+
+# Custom sidebar templates, maps document names to template names.
+#html_sidebars = {}
+
+# Additional templates that should be rendered to pages, maps page names to
+# template names.
+#html_additional_pages = {}
+
+# If false, no module index is generated.
+#html_domain_indices = True
+
+# If false, no index is generated.
+#html_use_index = True
+
+# If true, the index is split into individual pages for each letter.
+#html_split_index = False
+
+# If true, links to the reST sources are added to the pages.
+#html_show_sourcelink = True
+
+# If true, "Created using Sphinx" is shown in the HTML footer. Default is True.
+#html_show_sphinx = True
+
+# If true, "(C) Copyright ..." is shown in the HTML footer. Default is True.
+#html_show_copyright = True
+
+# If true, an OpenSearch description file will be output, and all pages will
+# contain a <link> tag referring to it. The value of this option must be the
+# base URL from which the finished HTML is served.
+#html_use_opensearch = ''
+
+# This is the file name suffix for HTML files (e.g. ".xhtml").
+#html_file_suffix = None
+
+# Output file base name for HTML help builder.
+htmlhelp_basename = 'fabric-chefdoc'
+
+
+# -- Options for LaTeX output --------------------------------------------------
+
+# The paper size ('letter' or 'a4').
+#latex_paper_size = 'letter'
+
+# The font size ('10pt', '11pt' or '12pt').
+#latex_font_size = '10pt'
+
+# Grouping the document tree into LaTeX files. List of tuples
+# (source start file, target name, title, author, documentclass [howto/manual]).
+latex_documents = [
+ ('index', 'fabric-chef.tex', u'fabric-chef Documentation',
+ u'Alen Mujezinovic', 'manual'),
+]
+
+# The name of an image file (relative to this directory) to place at the top of
+# the title page.
+#latex_logo = None
+
+# For "manual" documents, if this is true, then toplevel headings are parts,
+# not chapters.
+#latex_use_parts = False
+
+# If true, show page references after internal links.
+#latex_show_pagerefs = False
+
+# If true, show URL addresses after external links.
+#latex_show_urls = False
+
+# Additional stuff for the LaTeX preamble.
+#latex_preamble = ''
+
+# Documents to append as an appendix to all manuals.
+#latex_appendices = []
+
+# If false, no module index is generated.
+#latex_domain_indices = True
+
+
+# -- Options for manual page output --------------------------------------------
+
+# One entry per manual page. List of tuples
+# (source start file, name, description, authors, manual section).
+man_pages = [
+ ('index', 'fabric-chef', u'fabric-chef Documentation',
+ [u'Alen Mujezinovic'], 1)
+]
88 docs/index.rst
@@ -0,0 +1,88 @@
+.. include:: ../README.rst
+
+Installation
+------------
+
+::
+
+ pip install fabric-provision
+
+Usage
+-----
+- Create a ``fabfile.py``
+
+::
+
+ from fabric.api import *
+ from provision import chef, provision
+
+ env.hosts = ['vagrant@localhost:2222']
+
+ chef.add_recipe('python')
+
+- Assuming you have a `Vagrant <http://vagrantup.com/>`_ machine running locally,
+ you can provision it instantly:
+
+::
+
+ $ fab provision
+
+What it does
+------------
+
+- ``apt-get update``
+- ``apt-get upgrade``
+- Install a current version of `Chef <http://www.opscode.com/chef/>`_
+- Run your configured recipes
+
+API
+---
+
+.. currentmodule:: provision.chef
+
+.. function:: add_recipe(recipe)
+
+ Adds a recipe to run when provisioning. Alternatively you can just
+ override ``provision.chef.recipes``.
+
+Settings
+--------
+
+.. currentmodule:: provision.chef
+
+.. attribute:: path
+
+ :default: ``'/var/chef'``
+
+ Remote path to store cookbooks and cached files.
+
+.. attribute:: cookbooks
+
+ :default: ``'cookbooks/'``
+
+ The local path to your recipes, relative to you ``fabfile.py``.
+
+.. attribute:: log_level
+
+ :default: ``'info'``
+
+ Chef's log level.
+
+.. attribute:: gems
+
+ :default: ``'1.8.10'``
+
+ Which version of ``gem`` to install.
+
+
+.. attribute:: recipes
+
+ :default: ``[]``
+
+ The list of recipes to run.
+
+.. attribute:: json
+
+ :default: ``{}``
+
+ Additional JSON information you'd like to transfer to the server.
7 fabfile.py
@@ -0,0 +1,7 @@
+from fabric.api import *
+from provision import chef, provision
+
+env.hosts = ['vagrant@localhost:2222']
+
+chef.add_recipe('python')
+chef.path = '/tmp'
91 provision/__init__.py
@@ -0,0 +1,91 @@
+from fabric.api import *
+from fabric.contrib.files import append
+from fabric.operations import *
+from fabric.state import _AttributeDict
+import json
+import os
+import sys
+import tempfile
+
+__version__ = '0.0.1'
+
+DEFAULTS = dict(
+ path='/var/chef',
+ cookbooks='cookbooks',
+ log_level='info',
+ gems='1.8.10',
+ recipes=[],
+ json={},
+)
+
+SOLO_RB = """
+log_level :%(log_level)s
+log_location STDOUT
+file_cache_path "%(path)s"
+cookbook_path [ "%(path)s/cookbooks" ]
+Chef::Log::Formatter.show_time = true
+"""
+
+CHEF_DEPENDENCIES = """
+libopenid-ruby
+liberubis-ruby
+libjson-ruby
+libextlib-ruby
+libstomp-ruby
+libohai-ruby
+libopenssl-ruby
+"""
+
+class ChefDict(_AttributeDict):
+ def add_recipe(self, recipe):
+ self.recipes.append(recipe)
+
+ def _get_json(self):
+ json = self['json'].copy()
+ json['recipes'] = self['recipes']
+ return json
+ json = property(fget=_get_json)
+
+chef = ChefDict(DEFAULTS)
+
+def apt():
+ sudo('apt-get update')
+ sudo('apt-get -y upgrade')
+ sudo('apt-get install -y ruby ruby-dev wget %s' % ' '.join(CHEF_DEPENDENCIES.split('\n')))
+
+def gems():
+ gems = '%s/rubygems-%s.tgz' % (chef.path, chef.gems)
+ gemsurl = 'http://production.cf.rubygems.org/rubygems/rubygems-%s.tgz' % (chef.gems)
+ sudo('if [ ! -f %s ]; then wget -O %s %s; fi' % (gems, gems, gemsurl))
+
+ with cd(chef.path):
+ sudo('tar -xf %s' % gems)
+ with cd(os.path.split(os.path.splitext(gems)[0])[1]):
+ sudo('ruby setup.rb install --no-format-executable --no-rdoc --no-ri')
+
+ sudo('if [ ! `which chef-solo` ]; then gem install chef --no-rdoc --no-ri -n /usr/local/bin; fi')
+
+def upload():
+ sudo('mkdir -p %s' % chef.path)
+ tmpfolder = tempfile.mkdtemp()
+ local('mkdir %s/cookbooks && cp -r %s/* %s/cookbooks/' % (tmpfolder, os.path.normpath(chef.cookbooks), tmpfolder))
+ local('cd %s && tar -f cookbooks.tgz -cz ./cookbooks' % tmpfolder)
+ put('%s/cookbooks.tgz' % tmpfolder, chef.path, use_sudo=True)
+ sudo('if [ -d %s/cookbooks ]; then rm -rf %s/cookbooks; fi' % (chef.path, chef.path))
+ sudo('if [ -f %s/node.json ]; then rm %s/node.json; fi' % (chef.path, chef.path))
+ sudo('if [ -f %s/solo.rb ]; then rm %s/solo.rb; fi' % (chef.path, chef.path))
+ with cd(chef.path):
+ sudo('tar -xf cookbooks.tgz')
+ append('%s/node.json' % chef.path, json.dumps(chef.json), use_sudo=True)
+ append('%s/solo.rb' % chef.path, SOLO_RB % chef, use_sudo=True)
+
+@task(default=True)
+def provision():
+ apt()
+ gems()
+ upload()
+ with cd(chef.path):
+ sudo('chef-solo -c solo.rb -j node.json')
+
+
+
18 setup.py
@@ -0,0 +1,18 @@
+#!/usr/bin/env python
+import provision
+from setuptools import setup, find_packages
+
+METADATA = dict(
+ name='fabric-provision',
+ version=provision.__version__,
+ author='Alen Mujezinovic',
+ author_email='alen@caffeinehit.com',
+ description='Server provisioning with Chef',
+ long_description=open('README.rst').read(),
+ url='http://github.com/caffeinehit/fabric-provisionn',
+ keywords='server provisioning fabric chef',
+ install_requires=['fabric'],
+ packages=find_packages(),
+)
+
+setup(**METADATA)

0 comments on commit 866ec86

Please sign in to comment.