Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Release #31

Open
wants to merge 22 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
33 changes: 33 additions & 0 deletions conf/nginx/awesome
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
server {
listen 80;

root /srv/awesome/www;
access_log /srv/awesome/log/access_log;
error_log /srv/awesome/log/error_log;

# server_name awesome.liaoxuefeng.com;

client_max_body_size 1m;

gzip on;
gzip_min_length 1024;
gzip_buffers 4 8k;
gzip_types text/css application/x-javascript application/json;

sendfile on;

location /favicon.ico {
root /srv/awesome/www;
}

location ~ ^\/static\/.*$ {
root /srv/awesome/www;
}

location / {
proxy_pass http://127.0.0.1:9000;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header Host $host;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
}
}
11 changes: 11 additions & 0 deletions conf/supervisor/awesome.conf
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
[program:awesome]

command = /usr/bin/gunicorn --bind 127.0.0.1:9000 --workers 1 --worker-class gevent wsgiapp:application
directory = /srv/awesome/www
user = www-data
startsecs = 3

redirect_stderr = true
stdout_logfile_maxbytes = 50MB
stdout_logfile_backups = 10
stdout_logfile = /srv/awesome/log/app.log
169 changes: 169 additions & 0 deletions fabfile.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,169 @@
#!/usr/bin/env python
# -*- coding: utf-8 -*-

__author__ = 'Michael Liao'

'''
Deployment toolkit.
'''

import os, re

from datetime import datetime
from fabric.api import *

env.user = 'michael'
env.sudo_user = 'root'
env.hosts = ['192.168.0.3']

db_user = 'www-data'
db_password = 'www-data'

_TAR_FILE = 'dist-awesome.tar.gz'

_REMOTE_TMP_TAR = '/tmp/%s' % _TAR_FILE

_REMOTE_BASE_DIR = '/srv/awesome'

def _current_path():
return os.path.abspath('.')

def _now():
return datetime.now().strftime('%y-%m-%d_%H.%M.%S')

def backup():
'''
Dump entire database on server and backup to local.
'''
dt = _now()
f = 'backup-awesome-%s.sql' % dt
with cd('/tmp'):
run('mysqldump --user=%s --password=%s --skip-opt --add-drop-table --default-character-set=utf8 --quick awesome > %s' % (db_user, db_password, f))
run('tar -czvf %s.tar.gz %s' % (f, f))
get('%s.tar.gz' % f, '%s/backup/' % _current_path())
run('rm -f %s' % f)
run('rm -f %s.tar.gz' % f)

def build():
'''
Build dist package.
'''
includes = ['static', 'templates', 'transwarp', 'favicon.ico', '*.py']
excludes = ['test', '.*', '*.pyc', '*.pyo']
local('rm -f dist/%s' % _TAR_FILE)
with lcd(os.path.join(_current_path(), 'www')):
cmd = ['tar', '--dereference', '-czvf', '../dist/%s' % _TAR_FILE]
cmd.extend(['--exclude=\'%s\'' % ex for ex in excludes])
cmd.extend(includes)
local(' '.join(cmd))

def deploy():
newdir = 'www-%s' % _now()
run('rm -f %s' % _REMOTE_TMP_TAR)
put('dist/%s' % _TAR_FILE, _REMOTE_TMP_TAR)
with cd(_REMOTE_BASE_DIR):
sudo('mkdir %s' % newdir)
with cd('%s/%s' % (_REMOTE_BASE_DIR, newdir)):
sudo('tar -xzvf %s' % _REMOTE_TMP_TAR)
with cd(_REMOTE_BASE_DIR):
sudo('rm -f www')
sudo('ln -s %s www' % newdir)
sudo('chown www-data:www-data www')
sudo('chown -R www-data:www-data %s' % newdir)
with settings(warn_only=True):
sudo('supervisorctl stop awesome')
sudo('supervisorctl start awesome')
sudo('/etc/init.d/nginx reload')

RE_FILES = re.compile('\r?\n')

def rollback():
'''
rollback to previous version
'''
with cd(_REMOTE_BASE_DIR):
r = run('ls -p -1')
files = [s[:-1] for s in RE_FILES.split(r) if s.startswith('www-') and s.endswith('/')]
files.sort(cmp=lambda s1, s2: 1 if s1 < s2 else -1)
r = run('ls -l www')
ss = r.split(' -> ')
if len(ss) != 2:
print ('ERROR: \'www\' is not a symbol link.')
return
current = ss[1]
print ('Found current symbol link points to: %s\n' % current)
try:
index = files.index(current)
except ValueError, e:
print ('ERROR: symbol link is invalid.')
return
if len(files) == index + 1:
print ('ERROR: already the oldest version.')
old = files[index + 1]
print ('==================================================')
for f in files:
if f == current:
print (' Current ---> %s' % current)
elif f == old:
print (' Rollback to ---> %s' % old)
else:
print (' %s' % f)
print ('==================================================')
print ('')
yn = raw_input ('continue? y/N ')
if yn != 'y' and yn != 'Y':
print ('Rollback cancelled.')
return
print ('Start rollback...')
sudo('rm -f www')
sudo('ln -s %s www' % old)
sudo('chown www-data:www-data www')
with settings(warn_only=True):
sudo('supervisorctl stop awesome')
sudo('supervisorctl start awesome')
sudo('/etc/init.d/nginx reload')
print ('ROLLBACKED OK.')

def restore2local():
'''
Restore db to local
'''
backup_dir = os.path.join(_current_path(), 'backup')
fs = os.listdir(backup_dir)
files = [f for f in fs if f.startswith('backup-') and f.endswith('.sql.tar.gz')]
files.sort(cmp=lambda s1, s2: 1 if s1 < s2 else -1)
if len(files)==0:
print 'No backup files found.'
return
print ('Found %s backup files:' % len(files))
print ('==================================================')
n = 0
for f in files:
print ('%s: %s' % (n, f))
n = n + 1
print ('==================================================')
print ('')
try:
num = int(raw_input ('Restore file: '))
except ValueError:
print ('Invalid file number.')
return
restore_file = files[num]
yn = raw_input('Restore file %s: %s? y/N ' % (num, restore_file))
if yn != 'y' and yn != 'Y':
print ('Restore cancelled.')
return
print ('Start restore to local database...')
p = raw_input('Input mysql root password: ')
sqls = [
'drop database if exists awesome;',
'create database awesome;',
'grant select, insert, update, delete on awesome.* to \'%s\'@\'localhost\' identified by \'%s\';' % (db_user, db_password)
]
for sql in sqls:
local(r'mysql -uroot -p%s -e "%s"' % (p, sql))
with lcd(backup_dir):
local('tar zxvf %s' % restore_file)
local(r'mysql -uroot -p%s awesome < backup/%s' % (p, restore_file[:-7]))
with lcd(backup_dir):
local('rm -f %s' % restore_file[:-7])
Loading