You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
341 lines
9.8 KiB
341 lines
9.8 KiB
import os
|
|
import sys
|
|
from functools import wraps
|
|
from getpass import getpass, getuser
|
|
from glob import glob
|
|
from contextlib import contextmanager
|
|
|
|
from fabric.api import env, cd, prefix, sudo as _sudo, run as _run, hide, local, put
|
|
from fabric.contrib.files import exists, upload_template
|
|
from fabric.colors import yellow, green, blue, red
|
|
|
|
###########
|
|
# Config #
|
|
###########
|
|
|
|
config = {
|
|
'server_name' : 'go.skillbox.ru',
|
|
'hosts' : ['lms.skillbox.ru'],
|
|
'key_path' : '~/.ssh/hev7.pub',
|
|
'user' : 'root',
|
|
'password' : 'nu5Xefise',
|
|
'project_name' : 'skillbox',
|
|
'db_password' : 'super3360',
|
|
'manage_py_path' : '',
|
|
'settings_path' : 'skillbox',
|
|
'repository_type' : 'git',
|
|
'repository_url' : 'git@gitlab.com:skillbox/go.skillbox.ru.git',
|
|
'aws_key' : '',
|
|
'aws_secret' : ''
|
|
}
|
|
|
|
env.server_name = config['server_name']
|
|
env.key_filename = config['key_path']
|
|
env.hosts = config['hosts']
|
|
env.user = config['user']
|
|
env.project_name = config['project_name']
|
|
env.db_name = env.project_name.lower()
|
|
env.db_password = config['db_password']
|
|
env.project_path = '/var/www/%s' % env.project_name
|
|
#env.application_path = '/var/www/%s/%s' % (env.project_name, config['manage_py_path'])
|
|
env.application_path = '/var/www/%s' % env.project_name
|
|
env.virtualenv_path = '%s/env/bin/activate' % env.project_path
|
|
env.repository_type = config['repository_type']
|
|
env.repository_url = config['repository_url']
|
|
env.manage = "%s/env/bin/python %s/manage.py" % (env.project_path, env.application_path)
|
|
env.settings_path = env.application_path if not len(config['settings_path']) else '%s/%s' % (env.application_path, config['settings_path'])
|
|
env.aws_key = config['aws_key']
|
|
env.aws_secret = config['aws_secret']
|
|
|
|
templates = {
|
|
'django_settings' : {
|
|
'local_path' : 'conf/live_settings.py',
|
|
'remote_path' : '%s/local_settings.py' % env.settings_path
|
|
},
|
|
'uwsgi' : {
|
|
'local_path' : 'conf/uwsgi_prod.ini',
|
|
'remote_path' : '%s/uwsgi_prod.ini' %env.project_path
|
|
},
|
|
'nginx' : {
|
|
'local_path' : 'conf/nginx.conf',
|
|
'remote_path' : '/etc/nginx/sites-enabled/%s.conf' % env.project_name,
|
|
'reload_command' : '/etc/init.d/nginx restart'
|
|
},
|
|
"supervisor": {
|
|
"local_path": "conf/supervisor.conf",
|
|
"remote_path": "/etc/supervisor/conf.d/%s.conf" % env.project_name,
|
|
"reload_command": "supervisorctl reload",
|
|
}
|
|
}
|
|
|
|
def _print(output):
|
|
print
|
|
print '%s' % output
|
|
print
|
|
|
|
def print_command(command):
|
|
_print(blue("$ ", bold=True) +
|
|
yellow(command, bold=True) +
|
|
red(" ->", bold=True))
|
|
|
|
def run(command, show=True):
|
|
"""
|
|
Run a shell comand on the remote server.
|
|
"""
|
|
if show:
|
|
print_command(command)
|
|
with hide("running"):
|
|
return _run(command)
|
|
|
|
def sudo(command, show=True):
|
|
"""
|
|
Run a command as sudo.
|
|
"""
|
|
if show:
|
|
print_command(command)
|
|
with hide("running"):
|
|
return _sudo(command)
|
|
|
|
def psql(sql, show=True):
|
|
"""
|
|
Executes a psql command
|
|
"""
|
|
out = run('sudo -u postgres psql -c "%s"' % sql)
|
|
if show:
|
|
print_command(sql)
|
|
return out
|
|
|
|
def pip(modules):
|
|
"""
|
|
Install the Python modules passed as arguments with pip
|
|
"""
|
|
with virtualenv():
|
|
run('pip install %s' % modules)
|
|
|
|
def log_call(func):
|
|
@wraps(func)
|
|
def logged(*args, **kawrgs):
|
|
header = "-" * len(func.__name__)
|
|
_print(green("\n".join([header, func.__name__, header]), bold=True))
|
|
return func(*args, **kawrgs)
|
|
return logged
|
|
|
|
@contextmanager
|
|
def virtualenv():
|
|
"""
|
|
Run commands within the project's virtualenv.
|
|
"""
|
|
with cd('%s/env/bin/' % env.project_path):
|
|
with prefix("source %s/env/bin/activate" % env.project_path):
|
|
yield
|
|
|
|
|
|
@contextmanager
|
|
def project():
|
|
"""
|
|
Run commands within the project's directory.
|
|
"""
|
|
with virtualenv():
|
|
with cd(env.application_path):
|
|
yield
|
|
|
|
def manage(command):
|
|
"""
|
|
Run a Django management command.
|
|
"""
|
|
return run("%s %s" % (env.manage, command))
|
|
|
|
@log_call
|
|
def generate_ssh_key():
|
|
"""
|
|
Generates a key pair and displays the public key
|
|
"""
|
|
run('ssh-keygen -t rsa')
|
|
run('cat ~/.ssh/id_rsa.pub')
|
|
|
|
@log_call
|
|
def install_aptitude():
|
|
sudo('apt-get install aptitude -y')
|
|
|
|
@log_call
|
|
def upgrade():
|
|
"""
|
|
Updates the repository definitions and upgrades the server
|
|
"""
|
|
sudo('aptitude update -y')
|
|
sudo('aptitude upgrade -y')
|
|
|
|
def upload_template_and_reload(name):
|
|
template_settings = templates[name]
|
|
local_path = template_settings['local_path']
|
|
remote_path = template_settings['remote_path']
|
|
reload_command = template_settings.get('reload_command')
|
|
owner = template_settings.get("owner")
|
|
mode = template_settings.get("mode")
|
|
|
|
print '%s to %s' % (local_path, remote_path)
|
|
|
|
upload_template(local_path, remote_path, env, use_sudo=False, backup=False)
|
|
|
|
if owner:
|
|
sudo("chown %s %s" % (owner, remote_path))
|
|
if mode:
|
|
sudo("chmod %s %s" % (mode, remote_path))
|
|
|
|
if reload_command:
|
|
sudo(reload_command)
|
|
|
|
|
|
@log_call
|
|
def install_base():
|
|
"""
|
|
Installs the base software required to deploy an application
|
|
"""
|
|
install_aptitude()
|
|
sudo(
|
|
"aptitude install gcc make git-core nginx postgresql memcached python-dev\
|
|
python-setuptools supervisor postgresql-server-dev-all libxml2-dev\
|
|
libxslt-dev -y"# redis-server rabbitmq-server -y"
|
|
)
|
|
|
|
#run('wget http://www.ijg.org/files/jpegsrc.v8d.tar.gz')
|
|
#run('tar xvzf jpegsrc.v8d.tar.gz')
|
|
#with cd('jpeg-8d'):
|
|
# run('./configure')
|
|
# run('make')
|
|
# sudo('make install')
|
|
|
|
#run('wget http://download.savannah.gnu.org/releases/freetype/freetype-2.4.10.tar.gz')
|
|
#run('tar xvzf freetype-2.4.10.tar.gz')
|
|
#with cd('freetype-2.4.10'):
|
|
# run('./configure')
|
|
# run('make')
|
|
# sudo('make install')
|
|
|
|
#run('wget http://zlib.net/zlib-1.2.8.tar.gz')
|
|
#run('tar xvzf zlib-1.2.8.tar.gz')
|
|
#with cd('zlib-1.2.8'):
|
|
# run('./configure')
|
|
# run('make')
|
|
# sudo('make install')
|
|
|
|
sudo('easy_install pip')
|
|
sudo('pip install virtualenv mercurial uwsgi')
|
|
|
|
run('echo -e "Host github.com\n\tStrictHostKeyChecking no\n" >> ~/.ssh/config')
|
|
run('echo -e "Host bitbucket.org\n\tStrictHostKeyChecking no\n" >> ~/.ssh/config')
|
|
|
|
#sudo('rabbitmqctl add_user %s %s' % (env.project_name, env.db_name))
|
|
#sudo('rabbitmqctl add_vhost %s' % env.project_name)
|
|
#sudo(
|
|
# 'rabbitmqctl set_permissions -p %s %s ".*" ".*" ".*"' %
|
|
# (env.project_name, env.project_name)
|
|
#)
|
|
|
|
@log_call
|
|
def _create_database(name, password):
|
|
psql("CREATE USER %s WITH ENCRYPTED PASSWORD '%s';" % (name, password))
|
|
psql("ALTER USER %s CREATEDB;" % name)
|
|
psql("CREATE DATABASE %s WITH OWNER %s ENCODING='UTF8';" % (env.project_name, env.project_name))
|
|
|
|
@log_call
|
|
def create_database():
|
|
"""
|
|
Creates a database and a database user with the project name and the specified password
|
|
"""
|
|
_create_database(env.db_name, env.db_password)
|
|
|
|
@log_call
|
|
def fetch():
|
|
with cd(env.project_path):
|
|
run(
|
|
'%s pull %s' % (
|
|
env.repository_type,
|
|
'-u' if env.repository_type == 'hg' else ''
|
|
)
|
|
)
|
|
|
|
with virtualenv():
|
|
#manage('migrate --run-syncdb --noinput')
|
|
#manage('migrate')
|
|
#manage("migrate --noinput")
|
|
manage("collectstatic -v 0 --noinput")
|
|
#upload_template_and_reload('django_settings')
|
|
#upload_template_and_reload('gunicorn')
|
|
upload_template_and_reload('uwsgi')
|
|
upload_template_and_reload('nginx')
|
|
upload_template_and_reload('supervisor')
|
|
|
|
@log_call
|
|
def create():
|
|
"""
|
|
Stages the application on the server
|
|
"""
|
|
sudo('supervisorctl stop all')
|
|
sudo('rm -r -f %s' % env.project_path)
|
|
with cd('/var'):
|
|
run('mkdir -p www')
|
|
with cd('/var/www'):
|
|
run('%s clone %s %s' %(env.repository_type, env.repository_url, env.project_path))
|
|
sudo('ln -s /var/www/media %s' % env.project_path)
|
|
|
|
with cd(env.project_path):
|
|
run("virtualenv -p python3 env --distribute")
|
|
with virtualenv():
|
|
run('pip install -r %s/requirements.txt' % env.project_path)
|
|
|
|
sudo('chown -R www-data /var/www/')
|
|
#pip('python-memcached')
|
|
|
|
#upload_template_and_reload('django_settings')
|
|
#upload_template_and_reload('gunicorn')
|
|
upload_template_and_reload('uwsgi')
|
|
upload_template_and_reload('nginx')
|
|
upload_template_and_reload('supervisor')
|
|
|
|
with virtualenv():
|
|
#manage('migrate --run-syncdb --noinput')
|
|
#manage('migrate --list')
|
|
#manage("migrate --noinput")
|
|
manage("collectstatic -v 0 --noinput")
|
|
|
|
#if exists('%sgunicorn.pid'):
|
|
# sudo("kill -HUP 'cat %sgunicorn.pid'" % env.project_path)
|
|
#else:
|
|
# sudo("supervisorctl start %s:gunicorn" % env.project_name)
|
|
|
|
@log_call
|
|
def install_all():
|
|
install_aptitude()
|
|
upgrade()
|
|
install_base()
|
|
create_database()
|
|
create()
|
|
|
|
@log_call
|
|
def create_superuser():
|
|
with virtualenv():
|
|
manage('createsuperuser')
|
|
|
|
def send_key():
|
|
put('~/.ssh/id_rsa', '~/.ssh/id_rsa')
|
|
put('~/.ssh/id_rsa.pub', '~/.ssh/id_rsa.pub')
|
|
run('chmod 600 ~/.ssh/id_rsa')
|
|
run('chmod 600 ~/.ssh/id_rsa.pub')
|
|
|
|
"""
|
|
def vagrant():
|
|
# change from the default user to 'vagrant'
|
|
env.user = 'vagrant'
|
|
env.password = 'vagrant'
|
|
env.project_path = '/vagrant'
|
|
env.application_path = '/vagrant'
|
|
env.virtualenv_path = '%s/env/bin/activate' % env.project_path
|
|
env.manage = "%s/env/bin/python %s/manage.py" % (env.project_path, env.application_path)
|
|
# connect to the port-forwarded ssh
|
|
env.hosts = ['127.0.0.1:2222']
|
|
|
|
# use vagrant ssh key
|
|
result = local('vagrant ssh-config | grep IdentityFile', capture=True)
|
|
env.key_filename = result.split()[1][1:-1]
|
|
"""
|
|
|