Initial import of codebase

This commit is contained in:
2013-05-05 18:24:00 +01:00
commit 51337beeb0
42 changed files with 1121 additions and 0 deletions

2
.gitignore vendored Normal file
View File

@@ -0,0 +1,2 @@
.idea
*.db3

13
Vagrantfile vendored Normal file
View File

@@ -0,0 +1,13 @@
Vagrant::Config.run do |config|
config.vm.box = "precise64"
config.vm.box_url = "http://files.vagrantup.com/precise64.box"
config.vm.host_name = "limetime.local"
config.vm.forward_port 80, 8080
config.vm.provision :shell, :inline => "apt-get update --fix-missing"
config.vm.provision :puppet do |puppet|
puppet.manifests_path = "puppet/manifests"
puppet.manifest_file = "vagrant.pp"
puppet.options = ['--templatedir', '/vagrant/puppet/templates']
end
end

1
app/limetime/__init__.py Normal file
View File

@@ -0,0 +1 @@
__version__ = '0.1'

View File

131
app/limetime/conf/base.py Normal file
View File

@@ -0,0 +1,131 @@
# Django settings for limetime project.
DEBUG = True
TEMPLATE_DEBUG = DEBUG
ADMINS = (
# ('Your Name', 'your_email@example.com'),
)
MANAGERS = ADMINS
# Hosts/domain names that are valid for this site; required if DEBUG is False
# See https://docs.djangoproject.com/en/1.5/ref/settings/#allowed-hosts
ALLOWED_HOSTS = []
# Local time zone for this installation. Choices can be found here:
# http://en.wikipedia.org/wiki/List_of_tz_zones_by_name
# although not all choices may be available on all operating systems.
# In a Windows environment this must be set to your system time zone.
TIME_ZONE = 'UTC'
# Language code for this installation. All choices can be found here:
# http://www.i18nguy.com/unicode/language-identifiers.html
LANGUAGE_CODE = 'en-us'
SITE_ID = 1
# If you set this to False, Django will make some optimizations so as not
# to load the internationalization machinery.
USE_I18N = True
# If you set this to False, Django will not format dates, numbers and
# calendars according to the current locale.
USE_L10N = True
# If you set this to False, Django will not use timezone-aware datetimes.
USE_TZ = True
# Absolute filesystem path to the directory that will hold user-uploaded files.
# Example: "/var/www/example.com/media/"
MEDIA_ROOT = ''
# URL that handles the media served from MEDIA_ROOT. Make sure to use a
# trailing slash.
# Examples: "http://example.com/media/", "http://media.example.com/"
MEDIA_URL = ''
# Absolute path to the directory static files should be collected to.
# Don't put anything in this directory yourself; store your static files
# in apps' "static/" subdirectories and in STATICFILES_DIRS.
# Example: "/var/www/example.com/static/"
STATIC_ROOT = ''
# URL prefix for static files.
# Example: "http://example.com/static/", "http://static.example.com/"
STATIC_URL = '/static/'
# Additional locations of static files
STATICFILES_DIRS = (
# Put strings here, like "/home/html/static" or "C:/www/django/static".
# Always use forward slashes, even on Windows.
# Don't forget to use absolute paths, not relative paths.
)
# List of finder classes that know how to find static files in
# various locations.
STATICFILES_FINDERS = (
'django.contrib.staticfiles.finders.FileSystemFinder',
'django.contrib.staticfiles.finders.AppDirectoriesFinder',
)
# Make this unique, and don't share it with anybody.
SECRET_KEY = '$+y3w%y3286wetd#tqhvqch$^ed)x=#s$we1c2)d1&lf9quktl'
# List of callables that know how to import templates from various sources.
TEMPLATE_LOADERS = (
'django.template.loaders.filesystem.Loader',
'django.template.loaders.app_directories.Loader',
)
MIDDLEWARE_CLASSES = (
'django.middleware.common.CommonMiddleware',
'django.contrib.sessions.middleware.SessionMiddleware',
'django.middleware.csrf.CsrfViewMiddleware',
'django.contrib.auth.middleware.AuthenticationMiddleware',
'django.contrib.messages.middleware.MessageMiddleware',
)
ROOT_URLCONF = 'limetime.urls'
# Python dotted path to the WSGI application used by Django's runserver.
WSGI_APPLICATION = 'limetime.wsgi.application'
import os
TEMPLATE_DIRS = (os.path.join(os.path.dirname(__file__), '../templates').replace('\\','/'),)
INSTALLED_APPS = (
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.sites',
'django.contrib.messages',
'django.contrib.staticfiles',
'django.contrib.admin',
'gunicorn',
'timer',
)
LOGGING = {
'version': 1,
'disable_existing_loggers': False,
'filters': {
'require_debug_false': {
'()': 'django.utils.log.RequireDebugFalse'
}
},
'handlers': {
'mail_admins': {
'level': 'ERROR',
'filters': ['require_debug_false'],
'class': 'django.utils.log.AdminEmailHandler'
}
},
'loggers': {
'django.request': {
'handlers': ['mail_admins'],
'level': 'ERROR',
'propagate': True,
},
}
}

View File

@@ -0,0 +1,6 @@
import os
import dj_database_url
from .base import *
default_db_url = 'sqlite:///%s' % os.path.join(os.path.dirname(__file__), '..', '..', '..', 'limetime.db3')
DATABASES = {'default': dj_database_url.config(default=default_db_url)}

10
app/limetime/urls.py Normal file
View File

@@ -0,0 +1,10 @@
from django.conf.urls import patterns, include, url
# Uncomment the next two lines to enable the admin:
from django.contrib import admin
admin.autodiscover()
urlpatterns = patterns('',
url(r'^', include('timer.urls')),
url(r'^admin/', include(admin.site.urls)),
)

32
app/limetime/wsgi.py Normal file
View File

@@ -0,0 +1,32 @@
"""
WSGI config for limetime project.
This module contains the WSGI application used by Django's development server
and any production WSGI deployments. It should expose a module-level variable
named ``application``. Django's ``runserver`` and ``runfcgi`` commands discover
this application via the ``WSGI_APPLICATION`` setting.
Usually you will have the standard Django WSGI application here, but it also
might make sense to replace the whole Django WSGI application with a custom one
that later delegates to the Django one. For example, you could introduce WSGI
middleware here, or combine a Django application with an application of another
framework.
"""
import os
# We defer to a DJANGO_SETTINGS_MODULE already in the environment. This breaks
# if running multiple sites in the same mod_wsgi process. To fix this, use
# mod_wsgi daemon mode with each site in its own daemon process, or use
# os.environ["DJANGO_SETTINGS_MODULE"] = "limetime.settings"
os.environ.setdefault("DJANGO_SETTINGS_MODULE", "limetime.settings")
# This application object is used by any WSGI server configured to use this
# file. This includes Django's development server, if the WSGI_APPLICATION
# setting points here.
from django.core.wsgi import get_wsgi_application
application = get_wsgi_application()
# Apply WSGI middleware here.
# from helloworld.wsgi import HelloWorldApplication
# application = HelloWorldApplication(application)

10
app/manage.py Executable file
View File

@@ -0,0 +1,10 @@
#!/usr/bin/env python
import os
import sys
if __name__ == "__main__":
os.environ.setdefault("DJANGO_SETTINGS_MODULE", "limetime.conf.development")
from django.core.management import execute_from_command_line
execute_from_command_line(sys.argv)

1
app/timer/__init__.py Normal file
View File

@@ -0,0 +1 @@
__version__ = '0.1'

8
app/timer/admin.py Normal file
View File

@@ -0,0 +1,8 @@
from django.contrib import admin
from timer.models import Timer
class TimerAdmin(admin.ModelAdmin):
readonly_fields = ['location']
admin.site.register(Timer, admin.ModelAdmin)

View File

View File

@@ -0,0 +1,23 @@
from django.core.management.base import BaseCommand, CommandError
from django.db import transaction
from timer.models import Alliance, Corporation
from eveapi import EVEAPIConnection
class Command(BaseCommand):
args = ''
help = 'Updates alliances from the EVE API'
def handle(self, *args, **options):
api = EVEAPIConnection()
alliance_list = api.eve.AllianceList().alliances
print 'Updating %d alliances... ' % len(alliance_list)
with transaction.commit_on_success():
for alliance in alliance_list:
allobj, created = Alliance.objects.get_or_create(pk=alliance.allianceID)
allobj.name = alliance.name
allobj.save()
corp_ids = [x.corporationID for x in alliance.memberCorporations]
Corporation.objects.exclude(pk__in=corp_ids).update(alliance=None)
Corporation.objects.filter(pk__in=corp_ids).update(alliance=allobj)
print 'Done'

View File

@@ -0,0 +1,44 @@
from __future__ import division
import sqlite3
from django.core.management.base import BaseCommand, CommandError
from django.db import transaction
from timer.models import Region, Constellation, System, Planet, Moon
class Command(BaseCommand):
args = '<map csv>'
help = 'Imports the EVE Map from a sqlite dump of the SDE table mapDenormalized'
def handle(self, *args, **options):
# Connect to the sqlite3 DB
db = sqlite3.connect(args[0])
cur = db.cursor()
objs = []
# eveUnits
print "Importing mapDenormalize..."
cur.execute("""SELECT itemID, typeID, groupID, solarSystemID, constellationID, regionID, orbitID, x, y, z, itemName FROM mapDenormalize WHERE typeID in (3, 4, 5, 14) OR groupID = 7""")
for row in cur.fetchall():
id, type, group, solarid, constellationid, regionid, orbitid, x, y, z, name = row
if int(type) == 3:
objs.append(Region(pk=id, name=name, x=0, y=0, z=0))
elif int(type) == 4:
objs.append(Constellation(pk=id, name=name, region_id=regionid, x=0, y=0, z=0))
elif int(type) == 5:
objs.append(System(pk=id, name=name, constellation_id=constellationid, x=0, y=0, z=0))
elif int(group) == 7:
objs.append(Planet(pk=id, name=name, system_id=solarid, x=x, y=y, z=z))
elif int(type) == 14:
objs.append(Moon(pk=id, name=name, planet_id=orbitid, x=x, y=y, z=z))
print "Done"
# Dump to DB
print 'Processing %d objects for commiting...' % len(objs)
with transaction.commit_on_success():
for i, x in enumerate(objs, start=1):
if i % 1000 == 0: print "%d/%d (%d%%)" % (i, len(objs), round(i/len(objs) * 100))
x.save()
print 'Commited'

View File

@@ -0,0 +1,24 @@
from django.core.management.base import BaseCommand
from django.db import transaction
from timer.models import Station, System
from eveapi import EVEAPIConnection
class Command(BaseCommand):
args = ''
help = 'Updates conquerable stations from the EVE API'
def handle(self, *args, **options):
api = EVEAPIConnection()
station_list = api.eve.ConquerableStationList().outposts
print 'Updating %d stations... ' % len(station_list)
with transaction.commit_on_success():
for station in station_list:
try:
obj = Station.objects.get(pk=station.stationID)
except Station.DoesNotExist:
obj = Station(pk=station.stationID)
obj.system, created = System.objects.get_or_create(pk=station.solarSystemID)
obj.name = station.stationName
obj.save()
print 'Done'

View File

@@ -0,0 +1,4 @@
from .locations import *
from .owners import *
from .timer import *
from .utils import *

View File

@@ -0,0 +1,88 @@
from django.db import models
from .utils import InheritanceQuerySet
from .owners import Corporation
class LocationManager(models.Manager):
def all_subclassed(self):
return InheritanceQuerySet(model=self.model).select_subclasses()
class Location(models.Model):
id = models.BigIntegerField('Location ID', primary_key=True)
name = models.CharField('Location Name', max_length=200)
x = models.BigIntegerField('X Location', null=True)
y = models.BigIntegerField('Y Location', null=True)
z = models.BigIntegerField('Z Location', null=True)
def __unicode__(self):
return "%(name)s (%(id)d)" % self.__dict__
class Meta:
app_label = 'timer'
class Region(Location):
@property
def systems(self):
return System.objects.filter(constellation__in=self.constellations.all())
@property
def planets(self):
return Planet.objects.filter(system__constellation__in=self.constellations.all())
@property
def moons(self):
return Moon.objects.filter(planet__system__constellation__in=self.constellations.all())
class Meta:
app_label = 'timer'
class Constellation(Location):
region = models.ForeignKey(Region, related_name='constellations')
@property
def planets(self):
return Planet.objects.filter(system__in=self.systems.all())
@property
def moons(self):
return Moon.objects.filter(planet__system__in=self.systems.all())
class Meta:
app_label = 'timer'
class System(Location):
constellation = models.ForeignKey(Constellation, related_name='systems')
owner = models.ForeignKey(Corporation, related_name='systems', null=True)
@property
def moons(self):
return Moon.objects.filter(planet__in=self.planets.all())
class Meta:
app_label = 'timer'
class Planet(Location):
system = models.ForeignKey(System, related_name='planets')
class Meta:
app_label = 'timer'
class Moon(Location):
planet = models.ForeignKey(Planet, related_name='moons')
class Meta:
app_label = 'timer'
class Station(Location):
system = models.ForeignKey(System, related_name='stations')
class Meta:
app_label = 'timer'

View File

@@ -0,0 +1,24 @@
from django.db import models
class Owner(models.Model):
id = models.BigIntegerField('Owner ID', primary_key=True)
name = models.CharField('Owner Name', max_length=200)
class Meta:
app_label = 'timer'
def __unicode__(self):
return self.name
class Alliance(Owner):
class Meta:
app_label = 'timer'
class Corporation(Owner):
"""Represents a EVE Corporation """
alliance = models.ForeignKey(Alliance, related_name='corporations', null=True)
class Meta:
app_label = 'timer'

35
app/timer/models/timer.py Normal file
View File

@@ -0,0 +1,35 @@
from django.db import models
from django.utils.timezone import now
class Timer(models.Model):
STATE_ACTIVE = 1
STATE_EXPIRED = 2
STATE_CHOICES = (
(STATE_ACTIVE, 'Active'),
(STATE_EXPIRED, 'Expired'),
)
TYPE_SHEILD_REENFORCEMENT = 1
TYPE_ARMOR_REENFORCEMENT = 2
TYPE_CHOICES = (
(TYPE_SHEILD_REENFORCEMENT, 'Sheild Reenforcement'),
(TYPE_ARMOR_REENFORCEMENT, 'Armor Reenforcement'),
)
location = models.ForeignKey('timer.Location', related_name='timers')
expiration = models.DateTimeField('Timer Expiration')
reenforcement_type = models.PositiveIntegerField('Timer Type', choices=TYPE_CHOICES)
@property
def state(self):
if self.expiration <= now():
return self.STATE_EXPIRED
return self.STATE_ACTIVE
class Meta:
app_label = 'timer'
ordering = ['-expiration']

29
app/timer/models/utils.py Normal file
View File

@@ -0,0 +1,29 @@
from django.db.models.fields.related import SingleRelatedObjectDescriptor
from django.db.models.query import QuerySet
class InheritanceQuerySet(QuerySet):
def select_subclasses(self, *subclasses):
if not subclasses:
subclasses = [o for o in dir(self.model)
if isinstance(getattr(self.model, o), SingleRelatedObjectDescriptor)\
and issubclass(getattr(self.model,o).related.model, self.model)]
new_qs = self.select_related(*subclasses)
new_qs.subclasses = subclasses
return new_qs
def _clone(self, klass=None, setup=False, **kwargs):
try:
kwargs.update({'subclasses': self.subclasses})
except AttributeError:
pass
return super(InheritanceQuerySet, self)._clone(klass, setup, **kwargs)
def iterator(self):
iter = super(InheritanceQuerySet, self).iterator()
if getattr(self, 'subclasses', False):
for obj in iter:
obj = [getattr(obj, s) for s in self.subclasses if getattr(obj, s)] or [obj]
yield obj[0]
else:
for obj in iter:
yield obj

View File

@@ -0,0 +1,3 @@
{% for timer in timer_list %}
{{ timer.location.name }} - {{ timer.expiration_datetime }}
{% endfor %}

16
app/timer/tests.py Normal file
View File

@@ -0,0 +1,16 @@
"""
This file demonstrates writing tests using the unittest module. These will pass
when you run "manage.py test".
Replace this with more appropriate tests for your application.
"""
from django.test import TestCase
class SimpleTest(TestCase):
def test_basic_addition(self):
"""
Tests that 1 + 1 always equals 2.
"""
self.assertEqual(1 + 1, 2)

6
app/timer/urls.py Normal file
View File

@@ -0,0 +1,6 @@
from django.conf.urls import patterns, url
from timer.views import TimerListView
urlpatterns = patterns('',
url(r'^$', TimerListView.as_view(), name='timer-list'),
)

14
app/timer/views.py Normal file
View File

@@ -0,0 +1,14 @@
from django.views.generic import ListView
from django.utils.timezone import now
from timer.models import Timer
class TimerListView(ListView):
model = Timer
def get_queryset(self):
qs = super(TimerListView, self).get_queryset()
if 'active' in self.kwargs:
qs = qs.filter(expiry_datetime__gt=now())
return qs

View File

@@ -0,0 +1,30 @@
user nginx;
worker_processes 1;
error_log /var/log/nginx/error.log warn;
pid /var/run/nginx.pid;
events {
worker_connections 1024;
}
http {
include /etc/nginx/mime.types;
default_type application/octet-stream;
log_format main '$remote_addr - $remote_user [$time_local] "$request" '
'$status $body_bytes_sent "$http_referer" '
'"$http_user_agent" "$http_x_forwarded_for"';
access_log /var/log/nginx/access.log main;
sendfile on;
#tcp_nopush on;
keepalive_timeout 65;
#gzip on;
include /etc/nginx/conf.d/*.conf;
include /etc/nginx/sites-enabled/*.conf;
}

View File

@@ -0,0 +1 @@
deb http://nginx.org/packages/ubuntu/ lucid nginx

View File

@@ -0,0 +1 @@
deb http://ppa.launchpad.net/rwky/redis/ubuntu lucid main

View File

@@ -0,0 +1,186 @@
#!/usr/bin/env bash
### BEGIN INIT INFO
# Provides: uwsgi
# Required-Start: $all
# Required-Stop: $all
# Default-Start: 2 3 4 5
# Default-Stop: 0 1 6
# Short-Description: starts the uwsgi app server
# Description: starts uwsgi app server using start-stop-daemon
### END INIT INFO
#set -e
PATH=/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin
DAEMON=/usr/local/bin/uwsgi
RUN=/var/run/uwsgi
ENABLED_CONFIGS_DIR=/etc/uwsgi/sites-enabled
AVAILABLE_CONFIGS_DIR=/etc/uwsgi/sites-available
OWNER=www-data
NAME=uwsgi
DESC=uwsgi
OP=$1
[[ -x $DAEMON ]] || exit 0
[[ -d $RUN ]] || mkdir $RUN && chown www-data $RUN
DAEMON_OPTS=""
# Include uwsgi defaults if available
if [[ -f /etc/default/uwsgi ]]; then
. /etc/default/uwsgi
fi
do_pid_check()
{
local PIDFILE=$1
[[ -f $PIDFILE ]] || return 0
local PID=$(cat $PIDFILE)
for p in $(pgrep uwsgi); do
[[ $p == $PID ]] && return 1
done
return 0
}
do_start()
{
local PIDFILE=$RUN/uwsgi.pid
local START_OPTS=" \
--emperor $ENABLED_CONFIGS_DIR \
--pidfile $PIDFILE \
--daemonize /var/log/uwsgi/uwsgi-emperor.log \
"
if do_pid_check $PIDFILE; then
sudo -u $OWNER -i uwsgi $DAEMON_OPTS $START_OPTS
else
echo "Already running!"
fi
}
send_sig()
{
local PIDFILE=$RUN/uwsgi.pid
set +e
[[ -f $PIDFILE ]] && kill $1 $(cat $PIDFILE) > /dev/null 2>&1
set -e
}
wait_and_clean_pidfile()
{
local PIDFILE=$RUN/uwsgi.pid
until do_pid_check $PIDFILE; do
echo -n "";
done
rm -f $PIDFILE
}
do_stop()
{
send_sig -3
wait_and_clean_pidfile
}
do_reload()
{
send_sig -1
}
do_force_reload()
{
send_sig -15
}
get_status()
{
send_sig -10
}
enable_configs()
{
local configs
if [[ $# -eq 0 || ${1,,} = 'all' ]]; then
configs=$(diff $AVAILABLE_CONFIGS_DIR $ENABLED_CONFIGS_DIR \
| grep $AVAILABLE_CONFIGS_DIR \
| sed -re 's#.+: (.+)$#\1#')
else
configs=$@
fi
for c in $configs; do
echo -n "Enabling $c..."
[[ -f $ENABLED_CONFIGS_DIR/$c ]] && echo "Skipped" && continue
[[ -f $AVAILABLE_CONFIGS_DIR/$c ]] && \
ln -s $AVAILABLE_CONFIGS_DIR/$c $ENABLED_CONFIGS_DIR && \
echo "Done" && \
continue
echo "Error"
done
}
disable_configs()
{
local configs
if [[ $# -eq 0 || ${1,,} = 'all' ]]; then
configs=$(find $ENABLED_CONFIGS_DIR -type l -exec basename {} \;)
else
configs=$@
fi
for c in $configs; do
local config_path="$ENABLED_CONFIGS_DIR/$c"
echo -n "Disabling $c..."
[[ ! -L $config_path ]] && echo "Skipped" && continue
[[ -f $config_path ]] && rm $config_path && echo "Done" && continue
echo "Error"
done
}
case "$OP" in
start)
echo "Starting $DESC: "
do_start
echo "$NAME."
;;
stop)
echo -n "Stopping $DESC: "
do_stop
echo "$NAME."
;;
reload)
echo -n "Reloading $DESC: "
do_reload
echo "$NAME."
;;
force-reload)
echo -n "Force-reloading $DESC: "
do_force_reload
echo "$NAME."
;;
restart)
echo "Restarting $DESC: "
do_stop
sleep 1
do_start
echo "$NAME."
;;
status)
get_status
;;
enable)
shift
enable_configs $@
;;
disable)
shift
disable_configs $@
;;
*)
N=/etc/init.d/$NAME
echo "Usage: $N {start|stop|restart|reload|force-reload|status"
"|enable|disable}">&2
exit 1
;;
esac
exit 0

View File

@@ -0,0 +1,34 @@
stage {'repo': before => Stage['pre']}
class apt {
exec {'apt-get-update':
path => '/usr/local/bin:/usr/bin:/bin',
command => 'apt-get update',
}
}
class {'apt': stage => 'repo' }
define apt::repo ($source, $key) {
file {"/etc/apt/sources.list.d/${name}.list":
source => "${source}",
owner => root,
group => root,
mode => 0644,
notify => Exec['apt-get-update'],
}
apt::key{"${name}-key":
key => "${key}",
}
}
define apt::key($key) {
exec {"${name}-exec":
command => "/usr/bin/env bash -c 'apt-key adv --recv-key --keyserver keyserver.ubuntu.com ${key}'",
}
}
Apt::Repo <| |> -> Exec['apt-get-update']
Apt::Key <| |> -> Exec['apt-get-update']

View File

@@ -0,0 +1,6 @@
class django::uwsgi {
include nginx
include uwsgi
}

View File

View File

@@ -0,0 +1,34 @@
# Get mysql up and running
class mysql {
package { "mysql-server":
ensure => installed,
}
case $operatingsystem {
ubuntu: {
package { "libmysqld-dev":
ensure => installed,
}
}
}
service { "mysql":
ensure => running,
enable => true,
require => Package['mysql-server'],
}
}
define mysql::database($user, $password) {
exec { "create-${name}-db":
unless => "/usr/bin/mysql -uroot ${name}",
command => "/usr/bin/mysql -uroot -e \"create database ${name};\"",
require => Service["mysql"],
}
exec { "grant-${name}-db":
unless => "/usr/bin/mysql -u${user} -p${password} ${name}",
command => "/usr/bin/mysql -uroot -e \"grant all on ${name}.* to ${user}@localhost identified by '$password';\"",
require => [Service["mysql"], Exec["create-${name}-db"]]
}
}

View File

@@ -0,0 +1,75 @@
class nginx {
include nginx::apt
package {'nginx':
ensure => latest,
require => Apt::Repo['nginx'],
}
service {'nginx':
ensure => running,
enable => true,
require => Package['nginx'],
}
file{['/etc/nginx/sites-available', '/etc/nginx/sites-enabled']:
ensure => directory,
}
# Remove the default config
file {['/etc/nginx/sites-enabled/default', '/etc/nginx/conf.d/default.conf']:
ensure => absent,
require => Package['nginx'],
notify => Service['nginx'],
}
file {'/etc/nginx/nginx.conf':
owner => root,
group => root,
mode => 0644,
ensure => present,
source => '/vagrant/puppet/files/nginx/nginx.conf',
require => Package['nginx'],
notify => Service['nginx'],
}
}
class nginx::apt {
apt::repo {'nginx':
source => '/vagrant/puppet/files/nginx/nginx.list',
key => 'ABF5BD827BD9BF62',
}
}
class {'nginx::apt': stage => 'repo' }
# Setup a gunicorn instance in nginx
define nginx::gunicorn($ensure, $host, $port, $root, $static='') {
case $ensure {
enabled: {
file{"/etc/nginx/sites-available/${name}.conf":
content => template('nginx/gunicorn.erb'),
ensure => present,
notify => Service['nginx'],
require => [Package['nginx'], File['/etc/nginx/sites-available']],
}
file{"/etc/nginx/sites-enabled/${name}.conf":
ensure => link,
target => "/etc/nginx/sites-available/${name}.conf",
notify => Service['nginx'],
require => [File["/etc/nginx/sites-available/${name}.conf"], File['/etc/nginx/sites-enabled']],
}
}
absent: {
file{"/etc/nginx/sites-available/${name}.conf":
ensure => absent,
notify => Service['nginx'],
}
file{"/etc/nginx/sites-enabled/${name}.conf":
ensure => absent,
notify => Service['nginx'],
}
}
}
}

View File

@@ -0,0 +1,47 @@
stage { 'pre': before => Stage['main'] }
class python {
package {
"build-essential": ensure => latest;
"python": ensure => latest;
"python-dev": ensure => latest;
"python-setuptools": ensure => installed;
"git-core": ensure => installed;
"mercurial": ensure => installed;
"libevent-dev": ensure => installed;
"libgeos-dev": ensure => installed;
}
exec {'pip-package':
command => 'easy_install pip',
path => '/usr/local/bin:/usr/bin:/bin',
require => Package['python-setuptools'],
subscribe => Package['python-setuptools'],
}
package {['virtualenv', 'virtualenvwrapper', 'gunicorn', 'gevent']:
ensure => latest,
provider => pip,
require => Exec['pip-package'],
}
}
class { 'python': stage => 'pre' }
define python::venv($path, $requirements) {
file {"$requirements":
ensure => present,
}
exec{"${name}-venv":
path => '/usr/local/bin:/usr/bin:/bin',
command => "virtualenv --system-site-packages ${path}",
creates => "${path}",
require => Package['virtualenv'],
}
exec {"${name}-requirements":
command => "/usr/bin/env bash -c 'source ${path}/bin/activate; pip install -i http://f.pypi.python.org/simple -r ${requirements}'",
require => Exec["${name}-venv"],
subscribe => File["$requirements"],
}
}

View File

@@ -0,0 +1,25 @@
class redis {
include redis::apt
package {'redis-server':
ensure => latest,
require => Apt::Repo['redis'],
}
service { 'redis-server':
ensure => running,
enable => true,
hasrestart => true,
require => Package['redis-server'],
}
}
class redis::apt {
apt::repo {'redis':
source => '/vagrant/puppet/files/redis/redis.list',
key => '5862E31D',
}
}
class {'redis::apt': stage => 'repo' }

View File

@@ -0,0 +1,30 @@
class supervisor {
package{'supervisor':
ensure => latest,
}
service{'supervisor':
ensure => running,
hasrestart => false,
require => Package['supervisor'],
}
}
define supervisor::program(
$command = $title,
$directory = "/tmp/",
$user = "nobody",
$autostart = true,
$autorestart = true,
$redirect_stderr = true)
{
file {"/etc/supervisor/conf.d/$title.conf":
ensure => present,
owner => "root",
group => "root",
content => template('supervisor/program.erb'),
notify => Service['supervisor'],
require => Package['supervisor'],
}
}

View File

@@ -0,0 +1,59 @@
import "classes/*.pp"
include apt
include python
include nginx
include mysql
include supervisor
$database = "mysql://limetime:randompassword1234@localhost/limetime"
mysql::database{'limetime':
user => 'limetime',
password => 'randompassword1234'
}
python::venv {'limetime':
path => "/usr/local/${name}-venv",
requirements => '/vagrant/requirements.txt',
}
file{'/usr/local/bin/limetime-init.sh':
content => "#!/bin/bash\n. /usr/local/main-venv/bin/activate\nDATABASE_URL=$database /usr/bin/env python manage.py run_gunicorn -c gunicorn_config --preload",
ensure => present,
mode => 755,
}
supervisor::program {'limetime':
command => '/usr/local/bin/limetime-init.sh',
directory => '/vagrant/app/',
user => 'vagrant',
require => [File['/usr/local/bin/limetime-init.sh'], Python::Venv['limetime'], Mysql::Database['limetime']],
}
nginx::gunicorn { 'limetime':
ensure => enabled,
host => '_',
port => 3322,
root => '/vagrant/root/',
static => '/vagrant/static/',
}
exec{'limetime-collectstatic':
command => "/usr/bin/env bash -c 'source /usr/local/main-venv/bin/activate; cd /vagrant/app;DATABASE_URL=$database /usr/bin/env python ./manage.py collectstatic --noinput'",
path => '/usr/local/bin:/usr/bin:/bin',
require => Python::Venv['limetime'],
}
exec{'limetime-syncdb':
command => "/usr/bin/env bash -c 'source /usr/local/main-venv/bin/activate; cd /vagrant/app;DATABASE_URL=$database /usr/bin/env python ./manage.py syncdb --all --noinput'",
path => '/usr/local/bin:/usr/bin:/bin',
require => [Python::Venv['limetime'], Mysql::Database['limetime']],
}
exec{'limetime-migrationfake':
command => "/usr/bin/env bash -c 'source /usr/local/main-venv/bin/activate; cd /vagrant/app;DATABASE_URL=$database /usr/bin/env python ./manage.py migrate --fake --noinput'",
path => '/usr/local/bin:/usr/bin:/bin',
require => Exec['limetime-syncdb'],
}

View File

@@ -0,0 +1,23 @@
server {
listen 80;
server_name <%= @host %>;
server_name_in_redirect off;
<% if @static %>
location /static {
alias <%= @static %>;
}
<% end %>
location / {
proxy_pass_header Server;
proxy_set_header Host $http_host;
proxy_redirect off;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Scheme $scheme;
proxy_connect_timeout 10;
proxy_read_timeout 3600;
proxy_pass http://127.0.0.1:<%= @port %>/;
proxy_buffering off;
}
}

View File

@@ -0,0 +1,35 @@
CONFIG = {
<% if mode == 'django' -%>
'mode': 'django',
<% else -%>
'mode': 'wsgi',
<% end -%>
<% if virtualenv -%>
'environment': {
<% if environment -%>
'ENVIRONMENT': '<%= environment %>',
<% end -%>
'PYTHONPATH': '<%= virtualenv %>'
},
<% end -%>
'working_dir': '<%= dir %>',
'user': 'www-data',
'group': 'www-data',
<% 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',
<% else -%>
'--bind=<%= bind %>',
<% end -%>
'--workers=<%= @processorcount.to_i*2 %>',
'--timeout=30',
'app:app',
),
}

View File

@@ -0,0 +1,7 @@
[program:<%= @title %>]
command=<%= @command %>
directory=<%= @directory %>
user=<%= @user %>
autostart=<%= @autostart %>
autorestart=<%= @autorestart %>
redirect_stderr=<%= @redirect_stderr %>

4
requirements.txt Normal file
View File

@@ -0,0 +1,4 @@
django>=1.5,<1.6
eveapi
dj_database_url
gunicorn