Skip to content

Instantly share code, notes, and snippets.

@godber
Forked from dansimau/.gitignore
Created April 4, 2013 13:13
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save godber/5310249 to your computer and use it in GitHub Desktop.
Save godber/5310249 to your computer and use it in GitHub Desktop.
*~
*.pyc
.vagrant
venv
from flask import Flask
app = Flask(__name__)
app.config.from_pyfile('%s/config/default.cfg' % app.root_path)
app.config.from_envvar('FLASK_CONFIG')
from fabric.decorators import task
import app
import db
import puppet
import virtualenv
@task
def build():
"""Execute build tasks for all components."""
virtualenv.build()
db.build()

Quick start

After installing Vagrant, create and boot the VM:

vagrant up

SSH to the VM:

vagrant ssh

Run your app:

fab app.run

Notes

After initial boot, you should freeze the newly-installed pip packages at their versions:

pip freeze > requirements.txt

Run fab db.build to init alembic in this directory.

from fabric.decorators import task
from fabric.context_managers import settings
from utils import do
@task
def run():
"""Start app in debug mode (for development)."""
do('export FLASK_CONFIG=$PWD/app/config/dev.cfg && venv/bin/python ./run.py')
remote_path = ''
branches = {
'staging': {
'hosts': ''
},
'uat': {
'hosts': ''
},
'production': {
'hosts': ''
},
}
from fabric.decorators import task
from fabric.context_managers import settings, hide
from fabric.colors import cyan
from utils import do
config_file_path = 'db/alembic.ini'
@task
def build():
"""Initialise and migrate database to latest version."""
print(cyan('\nUpdating database...'))
with settings(hide('warnings'), warn_only=True):
do('venv/bin/alembic -c %s init db/postgresql' % config_file_path)
SECRET_KEY = ''
DEBUG = True
class fabric {
package { 'Fabric':
provider => 'pip',
ensure => 'present',
}
}
class git {
package { 'git':
ensure => 'installed',
}
}
class postgresql {
# postgresql-dev required for Python's psycopg2
package { [ 'postgresql', 'postgresql-server-dev-all' ]:
ensure => 'installed',
}
service { 'postgresql':
ensure => running,
require => Package[postgresql],
}
}
class python {
include python::modules
package { 'python':
ensure => installed,
}
}
class vagrant {
line { 'line-venv-activate':
ensure => present,
file => '/home/vagrant/.bashrc',
line => 'cd /vagrant && . venv/bin/activate',
}
}
define line($file, $line, $ensure = 'present') {
case $ensure {
default : { err ( "unknown ensure value ${ensure}" ) }
present: {
exec { "/bin/echo '${line}' >> '${file}'":
unless => "/bin/grep -qFx '${line}' '${file}'"
}
}
absent: {
exec { "/bin/grep -vFx '${line}' '${file}' | /usr/bin/tee '${file}' >/dev/null 2>&1":
onlyif => "/bin/grep -qFx '${line}' '${file}'"
}
}
uncomment: {
exec { "/bin/sed -i -e'/${line}/s/#\\+//' '${file}'":
onlyif => "/bin/grep '${line}' '${file}' | /bin/grep '^#' | /usr/bin/wc -l"
}
}
comment: {
exec { "/bin/sed -i -e'/${line}/s/\\(.\\+\\)$/#\\1/' '${file}'":
onlyif => "/usr/bin/test `/bin/grep '${line}' '${file}' | /bin/grep -v '^#' | /usr/bin/wc -l` -ne 0"
}
}
}
}
class python::modules {
package { [ 'python-virtualenv', 'python-dev', ]:
ensure => 'installed',
}
}
from fabric.api import env
from fabric.decorators import task
from fabric.colors import cyan
from utils import do
@task
def check():
"""Syntax check on Puppet config."""
print(cyan('\nChecking puppet syntax...'))
do('find puppet -type f -name \'*.pp\' |xargs puppet parser validate')
@task
def apply():
"""Apply Puppet manifest."""
print(cyan('\nApplying puppet manifest...'))
do('sudo puppet apply --modulepath=puppet/modules/ puppet/manifests/standalone.pp' % env)
alembic
Flask
Flask-SQLAlchemy
Flask-Assets
psycopg2
#!/usr/bin/env python
from app import app
app.run(host='0.0.0.0')
#
# Standalone manifest - for dev Vagrant box.
#
import 'lib/*.pp'
include fabric
include git
include postgresql
include python
include vagrant
from fabric.api import require, env, local, run as fab_run
from fabric.utils import abort
import config
def do(*args, **kwargs):
"""
Runs command locally or remotely depending on whether a remote host has
been specified.
"""
if env.host_string:
with settings(cd(config.remote_path)):
return fab_run(*args, **kwargs)
else:
return local(*args, **kwargs)
def require_host():
"""
Forces a remote host to be set, automatically detecting it from the current
git branch if possible.
"""
if not env.host_string:
# Detect current branch from git, based on config
branch = local('git symbolic-ref -q HEAD', capture=True).split('/')[2]
# Ensure the current branch matches up to a known branch
if branch in config.branches:
env.branch = branch
require('branch')
# Manually set host_string variable
env.host_string = env.branches[branch]['hosts']
require('host_string')
# -*- mode: ruby -*-
# vi: set ft=ruby :
Vagrant::Config.run do |config|
# All Vagrant configuration is done here. The most common configuration
# options are documented and commented below. For a complete reference,
# please see the online documentation at vagrantup.com.
# Every Vagrant virtual environment requires a box to build off of.
config.vm.box = "precise64"
# The url from where the 'config.vm.box' box will be fetched if it
# doesn't already exist on the user's system.
config.vm.box_url = "http://files.vagrantup.com/precise64.box"
# Boot with a GUI so you can see the screen. (Default is headless)
# config.vm.boot_mode = :gui
# Assign this VM to a host-only network IP, allowing you to access it
# via the IP. Host-only networks can talk to the host machine as well as
# any other machines on the same network, but cannot be accessed (through this
# network interface) by any external networks.
config.vm.network :hostonly, "172.16.1.2"
# Assign this VM to a bridged network, allowing you to connect directly to a
# network using the host's network device. This makes the VM appear as another
# physical device on your network.
# config.vm.network :bridged
# Forward a port from the guest to the host, which allows for outside
# computers to access the VM, whereas host only networking does not.
config.vm.forward_port 5000, 5000
# Share an additional folder to the guest VM. The first argument is
# an identifier, the second is the path on the guest to mount the
# folder, and the third is the path on the host to the actual folder.
config.vm.share_folder("v-root", "/vagrant", ".", :nfs => true)
# Update apt
config.vm.provision :shell, :inline => "aptitude -q2 update"
# Enable provisioning with Puppet stand alone. Puppet manifests
# are contained in a directory path relative to this Vagrantfile.
# You will need to create the manifests directory and a manifest in
# the file base.pp in the manifests_path directory.
config.vm.provision :puppet do |puppet|
puppet.manifests_path = "puppet/manifests"
puppet.module_path = "puppet/modules"
puppet.manifest_file = "standalone.pp"
end
# Application provision
config.vm.provision :shell, :inline => "cd /vagrant && stdbuf -o0 fab build; exit 0"
end
from fabric.decorators import task
from fabric.context_managers import settings, hide
from fabric.colors import cyan, red
from fabric.utils import abort
from utils import do
@task
def build():
"""Build or update the virtualenv."""
with settings(hide('stdout')):
print(cyan('\nUpdating venv, installing packages...'))
do('[ -e venv ] || virtualenv venv --no-site-packages')
# annoyingly, pip prints errors to stdout (instead of stderr), so we
# have to check the return code and output only if there's an error.
with settings(warn_only=True):
pip = do('venv/bin/pip install -r requirements.txt', capture=True)
if pip.failed:
print(red(pip))
abort("pip exited with return code %i" % pip.return_code)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment