added improved scripts/setup-web2py-nginx-uwsgi-ubuntu.sh, thanks Niphlod

This commit is contained in:
mdipierro
2012-12-20 09:22:24 -06:00
parent dcf0a7ccc9
commit 95b3ca839a
14 changed files with 60 additions and 53 deletions
+1 -1
View File
@@ -1 +1 @@
Version 2.3.2 (2012-12-20 09:02:23) dev Version 2.3.2 (2012-12-20 09:21:27) dev
+1
View File
@@ -0,0 +1 @@
+2 -2
View File
@@ -3487,7 +3487,7 @@ def _parse_date_rfc822(dt):
# If the year is 2 digits, assume everything in the 90's is the 1990's # If the year is 2 digits, assume everything in the 90's is the 1990's
if m['year'] < 100: if m['year'] < 100:
m['year'] += (1900, 2000)[m['year'] < 90] m['year'] += (1900, 2000)[m['year'] < 90]
stamp = datetime.datetime(*[m[i] for i in stamp = datetime.datetime(*[m[i] for i in
('year', 'month', 'day', 'hour', 'minute', 'second')]) ('year', 'month', 'day', 'hour', 'minute', 'second')])
# Use the timezone information to calculate the difference between # Use the timezone information to calculate the difference between
@@ -3699,7 +3699,7 @@ def convert_to_utf8(http_headers, data):
u'application/xml-external-parsed-entity') u'application/xml-external-parsed-entity')
text_content_types = (u'text/xml', u'text/xml-external-parsed-entity') text_content_types = (u'text/xml', u'text/xml-external-parsed-entity')
if (http_content_type in application_content_types) or \ if (http_content_type in application_content_types) or \
(http_content_type.startswith(u'application/') and (http_content_type.startswith(u'application/') and
http_content_type.endswith(u'+xml')): http_content_type.endswith(u'+xml')):
acceptable_content_type = 1 acceptable_content_type = 1
rfc3023_encoding = http_encoding or xml_encoding or u'utf-8' rfc3023_encoding = http_encoding or xml_encoding or u'utf-8'
+1 -1
View File
@@ -17,7 +17,7 @@ ADAPTERS['postgres'] = HerokuPostgresAdapter
def get_db(name = None, pool_size=10): def get_db(name = None, pool_size=10):
if not name: if not name:
names = [n for n in os.environ.keys() names = [n for n in os.environ.keys()
if n[:18]+n[-4:]=='HEROKU_POSTGRESQL__URL'] if n[:18]+n[-4:]=='HEROKU_POSTGRESQL__URL']
if names: if names:
name = names[0] name = names[0]
+5 -7
View File
@@ -70,7 +70,7 @@ class PaymenTech(object):
################################################################# #################################################################
# Notes for web2py implementations # # Notes for web2py implementations #
################################################################# #################################################################
# A recommended model for handling payments # A recommended model for handling payments
@@ -87,7 +87,7 @@ class PaymenTech(object):
PAYMENTECH_TARGET = <str> PAYMENTECH_TARGET = <str>
PAYMENTECH_HOST = <str> PAYMENTECH_HOST = <str>
PAYMENTECH_API_URL = <str> PAYMENTECH_API_URL = <str>
# The following table would allow passing data with web2py and to # The following table would allow passing data with web2py and to
# update records with the webservice authorization output by using # update records with the webservice authorization output by using
# the DAL # the DAL
@@ -102,10 +102,10 @@ class PaymenTech(object):
# #
# # Send the authorization request to the webservice # # Send the authorization request to the webservice
# result = mypaymentech.charge(myrow.as_dict()) # result = mypaymentech.charge(myrow.as_dict())
# #
# # Update the db record with the webservice response # # Update the db record with the webservice response
# myrow.update_record(**result) # myrow.update_record(**result)
db.define_table("paymentech", db.define_table("paymentech",
Field("account"), Field("account"),
Field("exp", comment="Must be of the mmyyyy form"), Field("exp", comment="Must be of the mmyyyy form"),
@@ -302,7 +302,7 @@ class PaymenTech(object):
tx_ref_num = order_id = None tx_ref_num = order_id = None
conn = httplib.HTTPS(self.host) conn = httplib.HTTPS(self.host)
conn.putrequest('POST', self.api_url) conn.putrequest('POST', self.api_url)
if self.development: if self.development:
content_type = "PTI56" content_type = "PTI56"
else: else:
@@ -340,5 +340,3 @@ class PaymenTech(object):
dom.getElementsByTagName('CustomerRefNum')[0].firstChild.data dom.getElementsByTagName('CustomerRefNum')[0].firstChild.data
return result return result
+4 -4
View File
@@ -6853,7 +6853,7 @@ class DAL(object):
self._adapter = ADAPTERS[self._dbname](**kwargs) self._adapter = ADAPTERS[self._dbname](**kwargs)
types = ADAPTERS[self._dbname].types types = ADAPTERS[self._dbname].types
# copy so multiple DAL() possible # copy so multiple DAL() possible
self._adapter.types = copy.copy(types) self._adapter.types = copy.copy(types)
if bigint_id: if bigint_id:
if 'big-id' in types and 'reference' in types: if 'big-id' in types and 'reference' in types:
self._adapter.types['id'] = types['big-id'] self._adapter.types['id'] = types['big-id']
@@ -7200,7 +7200,7 @@ def index():
fields = list(fields) + list(common_fields) fields = list(fields) + list(common_fields)
table_class = args_get('table_class',Table) table_class = args_get('table_class',Table)
table = table_class(self, tablename, *fields, **args) table = table_class(self, tablename, *fields, **args)
table._actual = True table._actual = True
self[tablename] = table self[tablename] = table
# must follow above line to handle self references # must follow above line to handle self references
@@ -7747,10 +7747,10 @@ class Table(object):
def __call__(self, key=DEFAULT, **kwargs): def __call__(self, key=DEFAULT, **kwargs):
for_update = kwargs.get('_for_update',False) for_update = kwargs.get('_for_update',False)
if '_for_update' in kwargs: del kwargs['_for_update'] if '_for_update' in kwargs: del kwargs['_for_update']
orderby = kwargs.get('_orderby',None) orderby = kwargs.get('_orderby',None)
if '_orderby' in kwargs: del kwargs['_orderby'] if '_orderby' in kwargs: del kwargs['_orderby']
if not key is DEFAULT: if not key is DEFAULT:
if isinstance(key, Query): if isinstance(key, Query):
record = self._db(key).select( record = self._db(key).select(
+2 -2
View File
@@ -520,7 +520,7 @@ class XmlComponent(object):
c = self['_class'] c = self['_class']
classes = (set(c.split()) if c else set()) - set(name.split()) classes = (set(c.split()) if c else set()) - set(name.split())
self['_class'] = ' '.join(classes) if classes else None self['_class'] = ' '.join(classes) if classes else None
return self return self
class XML(XmlComponent): class XML(XmlComponent):
""" """
@@ -1487,7 +1487,7 @@ class A(DIV):
(self['callback'], self['target'] or '', d) (self['callback'], self['target'] or '', d)
self['_href'] = self['_href'] or '#null' self['_href'] = self['_href'] or '#null'
elif self['cid']: elif self['cid']:
pre = self['pre_call'] + ';' if self['pre_call'] else '' pre = self['pre_call'] + ';' if self['pre_call'] else ''
self['_onclick'] = '%sweb2py_component("%s","%s");%sreturn false;' % \ self['_onclick'] = '%sweb2py_component("%s","%s");%sreturn false;' % \
(pre,self['_href'], self['cid'], d) (pre,self['_href'], self['cid'], d)
return DIV.xml(self) return DIV.xml(self)
-1
View File
@@ -154,4 +154,3 @@ def redirect(location='', how=303, client_side=False):
from gluon import current from gluon import current
if client_side and current.request.ajax: if client_side and current.request.ajax:
raise HTTP(200, **{'web2py-component-command': 'window.location.reload(true)'}) raise HTTP(200, **{'web2py-component-command': 'window.location.reload(true)'})
+3 -3
View File
@@ -269,7 +269,7 @@ jQuery.fn.grow_input = function() {
function pe(ul, e) { function pe(ul, e) {
var new_line = ml(ul); var new_line = ml(ul);
rel(ul); rel(ul);
new_line.appendTo(ul); new_line.appendTo(ul);
new_line.find(":text").focus(); new_line.find(":text").focus();
return false; return false;
} }
@@ -761,7 +761,7 @@ def formstyle_bootstrap(form, fields):
# For password fields, which are wrapped in a CAT object. # For password fields, which are wrapped in a CAT object.
if isinstance(controls, CAT) and isinstance(controls[0], INPUT): if isinstance(controls, CAT) and isinstance(controls[0], INPUT):
controls[0].add_class('input-xlarge') controls[0].add_class('input-xlarge')
if isinstance(controls, SELECT): if isinstance(controls, SELECT):
controls.add_class('input-xlarge') controls.add_class('input-xlarge')
@@ -1789,7 +1789,7 @@ class SQLFORM(FORM):
if not ( if not (
'/'.join(str(a) for a in args) == '/'.join(request.args) or '/'.join(str(a) for a in args) == '/'.join(request.args) or
URL.verify(request,user_signature=user_signature, URL.verify(request,user_signature=user_signature,
hash_vars=False) or hash_vars=False) or
(request.args(len(args))=='view' and not logged)): (request.args(len(args))=='view' and not logged)):
session.flash = T('not authorized') session.flash = T('not authorized')
redirect(referrer) redirect(referrer)
+6 -6
View File
@@ -1959,9 +1959,9 @@ class Auth(object):
onaccept = self.settings.login_onaccept onaccept = self.settings.login_onaccept
if log is DEFAULT: if log is DEFAULT:
log = self.messages.login_log log = self.messages.login_log
onfail = self.settings.login_onfail onfail = self.settings.login_onfail
user = None # default user = None # default
# do we use our own login form, or from a central source? # do we use our own login form, or from a central source?
@@ -2117,7 +2117,7 @@ class Auth(object):
session._auth_next = None session._auth_next = None
next = replace_id(next, form) next = replace_id(next, form)
redirect(next, client_side=True) redirect(next, client_side=True)
table_user[username].requires = old_requires table_user[username].requires = old_requires
return form return form
elif user: elif user:
@@ -3016,7 +3016,7 @@ class Auth(object):
if user_id: if user_id:
user = self.table_user()[user_id] user = self.table_user()[user_id]
else: else:
user = self.user user = self.user
return self.settings.create_user_groups % user return self.settings.create_user_groups % user
def has_membership(self, group_id=None, user_id=None, role=None): def has_membership(self, group_id=None, user_id=None, role=None):
@@ -4690,7 +4690,7 @@ class Wiki(object):
rows_page = 25 rows_page = 25
def markmin_render(self, page): def markmin_render(self, page):
html = MARKMIN(page.body, extra=self.extra, html = MARKMIN(page.body, extra=self.extra,
url=True, environment=self.env, url=True, environment=self.env,
autolinks=lambda link: expand_one(link, {})).xml() autolinks=lambda link: expand_one(link, {})).xml()
html += DIV(_class='w2p_wiki_tags', html += DIV(_class='w2p_wiki_tags',
@@ -5053,7 +5053,7 @@ class Wiki(object):
return self.not_authorized() return self.not_authorized()
db = self.auth.db db = self.auth.db
slugs=db(db.wiki_page.id>0).select(db.wiki_page.id,db.wiki_page.slug) slugs=db(db.wiki_page.id>0).select(db.wiki_page.id,db.wiki_page.slug)
options=[OPTION(row.slug,_value=row.id) for row in slugs] options=[OPTION(row.slug,_value=row.id) for row in slugs]
options.insert(0, OPTION('',_value='')) options.insert(0, OPTION('',_value=''))
form = SQLFORM.factory(Field("slug", default=current.request.args(1), form = SQLFORM.factory(Field("slug", default=current.request.args(1),
requires=(IS_SLUG(), requires=(IS_SLUG(),
+1 -1
View File
@@ -171,7 +171,7 @@ class Web2pyCronService(Web2pyService):
opt_mod = self._exe_args_ opt_mod = self._exe_args_
options = __import__(opt_mod, [], [], '') options = __import__(opt_mod, [], [], '')
global_settings.global_settings.web2py_crontype = 'external' global_settings.global_settings.web2py_crontype = 'external'
if options.scheduler: # -K if options.scheduler: # -K
apps = [app.strip() for app in options.scheduler.split( apps = [app.strip() for app in options.scheduler.split(
',') if check_existent_app(options, app.strip())] ',') if check_existent_app(options, app.strip())]
else: else:
-1
View File
@@ -1,4 +1,3 @@
import os import os
import sys import sys
from collections import deque from collections import deque
+31 -20
View File
@@ -1,19 +1,24 @@
#!/bin/bash
echo 'setup-web2py-nginx-uwsgi-ubuntu-precise.sh' echo 'setup-web2py-nginx-uwsgi-ubuntu-precise.sh'
echo 'Requires Ubuntu 12.04 and installs Nginx + uWSGI + Web2py' echo 'Requires Ubuntu > 12.04 and installs Nginx + uWSGI + Web2py'
# Check if user has root privileges
if [[ $EUID -ne 0 ]]; then
echo "You must run the script as root or using sudo"
exit 1
fi
# Get Web2py Admin Password # Get Web2py Admin Password
echo -e "Web2py Admin Password: \c " echo -e "Web2py Admin Password: \c "
read PW read PW
# Upgrade and install needed software # Upgrade and install needed software
apt-get update apt-get update
apt-get -y upgrade apt-get -y upgrade
apt-get -y dist-upgrade
apt-get autoremove apt-get autoremove
apt-get autoclean apt-get autoclean
apt-get -y install nginx-full apt-get -y install nginx-full
apt-get -y install build-essential python-dev libxml2-dev python-pip apt-get -y install build-essential python-dev libxml2-dev python-pip unzip
pip install --upgrade pip pip install --upgrade pip
pip install --upgrade uwsgi PIPPATH=`which pip`
$PIPPATH install --upgrade uwsgi
# Create configuration file /etc/nginx/sites-available/web2py # Create configuration file /etc/nginx/sites-available/web2py
echo 'server { echo 'server {
listen 80; listen 80;
@@ -37,11 +42,16 @@ echo 'server {
} }
} }
server { server {
listen 443; listen 443 default_server ssl;
server_name $hostname; server_name $hostname;
ssl on;
ssl_certificate /etc/nginx/ssl/web2py.crt; ssl_certificate /etc/nginx/ssl/web2py.crt;
ssl_certificate_key /etc/nginx/ssl/web2py.key; ssl_certificate_key /etc/nginx/ssl/web2py.key;
ssl_prefer_server_ciphers on;
ssl_session_cache shared:SSL:10m;
ssl_session_timeout 10m;
ssl_ciphers ECDHE-RSA-AES256-SHA:DHE-RSA-AES256-SHA:DHE-DSS-AES256-SHA:DHE-RSA-AES128-SHA:DHE-DSS-AES128-SHA;
ssl_protocols SSLv3 TLSv1;
keepalive_timeout 70;
location / { location / {
#uwsgi_pass 127.0.0.1:9001; #uwsgi_pass 127.0.0.1:9001;
uwsgi_pass unix:///tmp/web2py.socket; uwsgi_pass unix:///tmp/web2py.socket;
@@ -49,21 +59,24 @@ server {
uwsgi_param UWSGI_SCHEME $scheme; uwsgi_param UWSGI_SCHEME $scheme;
uwsgi_param SERVER_SOFTWARE nginx/$nginx_version; uwsgi_param SERVER_SOFTWARE nginx/$nginx_version;
} }
}' >/etc/nginx/sites-available/web2py }' >/etc/nginx/sites-available/web2py
ln -s /etc/nginx/sites-available/web2py /etc/nginx/sites-enabled/web2py ln -s /etc/nginx/sites-available/web2py /etc/nginx/sites-enabled/web2py
rm /etc/nginx/sites-enabled/default rm /etc/nginx/sites-enabled/default
mkdir /etc/nginx/ssl mkdir /etc/nginx/ssl
cd /etc/nginx/ssl cd /etc/nginx/ssl
openssl genrsa -out web2py.key 1024
openssl req -batch -new -key web2py.key -out web2py.csr openssl genrsa 1024 > web2py.key
openssl x509 -req -days 1780 -in web2py.csr -signkey web2py.key -out web2py.crt chmod 400 web2py.key
openssl req -new -x509 -nodes -sha1 -days 1780 -key web2py.key > web2py.crt
openssl x509 -noout -fingerprint -text < web2py.crt > web2py.info
# Prepare folders for uwsgi # Prepare folders for uwsgi
sudo mkdir /etc/uwsgi sudo mkdir /etc/uwsgi
sudo mkdir /var/log/uwsgi sudo mkdir /var/log/uwsgi
# Create configuration file /etc/uwsgi/web2py.xml # Create configuration file /etc/uwsgi/web2py.xml
echo '<uwsgi> echo '<uwsgi>
<socket>/tmp/web2py.socket</socket> <socket>/tmp/web2py.socket</socket>
@@ -84,11 +97,11 @@ echo '<uwsgi>
<cron>0 0 -1 -1 -1 python /home/www-data/web2py/web2py.py -Q -S welcome -M -R scripts/sessions2trash.py -A -o</cron> <cron>0 0 -1 -1 -1 python /home/www-data/web2py/web2py.py -Q -S welcome -M -R scripts/sessions2trash.py -A -o</cron>
<no-orphans/> <no-orphans/>
</uwsgi>' >/etc/uwsgi/web2py.xml </uwsgi>' >/etc/uwsgi/web2py.xml
#Create a configuration file for uwsgi in emperor-mode #Create a configuration file for uwsgi in emperor-mode
#for Upstart in /etc/init/uwsgi-emperor.conf #for Upstart in /etc/init/uwsgi-emperor.conf
echo '# Emperor uWSGI script echo '# Emperor uWSGI script
description "uWSGI Emperor" description "uWSGI Emperor"
start on runlevel [2345] start on runlevel [2345]
stop on runlevel [06] stop on runlevel [06]
@@ -104,7 +117,6 @@ respawn
exec uwsgi --master --die-on-term --emperor /etc/uwsgi --logto /var/log/uwsgi/uwsgi.log exec uwsgi --master --die-on-term --emperor /etc/uwsgi --logto /var/log/uwsgi/uwsgi.log
' > /etc/init/uwsgi-emperor.conf ' > /etc/init/uwsgi-emperor.conf
# Install Web2py # Install Web2py
apt-get -y install unzip
mkdir /home/www-data mkdir /home/www-data
cd /home/www-data cd /home/www-data
wget http://web2py.com/examples/static/web2py_src.zip wget http://web2py.com/examples/static/web2py_src.zip
@@ -117,11 +129,10 @@ cd /home/www-data/web2py
sudo -u www-data python -c "from gluon.main import save_password; save_password('$PW',443)" sudo -u www-data python -c "from gluon.main import save_password; save_password('$PW',443)"
start uwsgi-emperor start uwsgi-emperor
/etc/init.d/nginx restart /etc/init.d/nginx restart
## you can reload uwsgi with ## you can reload uwsgi with
# restart uwsgi-emperor # restart uwsgi-emperor
## and stop it with ## and stop it with
# stop uwsgi-emperor # stop uwsgi-emperor
## to reload web2py only (without restarting uwsgi) ## to reload web2py only (without restarting uwsgi)
# touch /etc/uwsgi/web2py.xml # touch /etc/uwsgi/web2py.xml
+3 -4
View File
@@ -43,13 +43,13 @@ def sync_main(file, apps):
data = eval(langfile.read()) data = eval(langfile.read())
finally: finally:
langfile.close() langfile.close()
d = sync_language(d, data) d = sync_language(d, data)
path = 'applications/%s/' % apps[-1] path = 'applications/%s/' % apps[-1]
file1 = os.path.join(path, 'languages', '%s.py' % file) file1 = os.path.join(path, 'languages', '%s.py' % file)
f = open(file1, 'w') f = open(file1, 'w')
try: try:
f.write('# coding: utf8\n') f.write('# coding: utf8\n')
@@ -61,7 +61,7 @@ def sync_main(file, apps):
f.write('}\n') f.write('}\n')
finally: finally:
f.close() f.close()
oapps = reversed(apps[:-1]) oapps = reversed(apps[:-1])
for app in oapps: for app in oapps:
path2 = 'applications/%s/' % app path2 = 'applications/%s/' % app
@@ -75,4 +75,3 @@ if __name__ == "__main__":
apps = sys.argv[2:] apps = sys.argv[2:]
sync_main(file, apps) sync_main(file, apps)