diff --git a/fabfile.py b/fabfile.py index c455b76..8f75eef 100644 --- a/fabfile.py +++ b/fabfile.py @@ -1,130 +1,227 @@ +# coding: utf-8 -from fabric.operations import put -from fabric.api import run, sudo, env +import os + +from fabric import colors +from fabric.decorators import task +from fabric.api import env, run, sudo, local from fabric.contrib.files import exists -from fabric.decorators import with_settings -from fabric.context_managers import prefix, cd, settings +from fabric.context_managers import prefix, cd, settings, shell_env + + +### Start of config + +APP_USER = APP_NAME = VENV_NAME = 'colab' +REPO_URL = 'To be defined' -env.user = 'colab' # key depends on env -env.use_shell = False environments = { 'dev': { 'hosts': ['127.0.0.1'], 'key_filename': '~/.vagrant.d/insecure_private_key', 'port': 2222, + 'is_vagrant': True, + 'superuser': 'vagrant', }, - 'live': { - 'hosts': ['10.1.2.153'], - 'key_filename': '~/.ssh/id_rsa', - 'port': 22, + 'qa': { + 'hosts': [], + 'port': 22, + 'is_vagrant': False, + 'superuser': 'root', }, - 'demo': { - 'hosts': ['colab-demo.tracy.com.br'], - 'key_filename': '~/.ssh/id_rsa', + 'prod': { + 'hosts': [], 'port': 22, + 'is_vagrant': False, + 'superuser': 'root', }, } +DEFAULT_ENVIRONMENT = 'dev' +### End of config +env.user = APP_USER +env.use_shell = False + +PROJECT_PATH = os.path.join(os.path.dirname(__file__)) +REPO_PATH = '/home/{}/{}'.format(APP_USER, APP_NAME) SOURCE_VENV = 'source /usr/local/bin/virtualenvwrapper.sh' -WORKON_COLAB = '{} && workon colab'.format(SOURCE_VENV) +WORKON_ENV = '{} && workon {}'.format(SOURCE_VENV, VENV_NAME) +MANAGE_PATH = os.path.join(REPO_PATH, 'src') +SETTINGS_PATH = os.path.join(MANAGE_PATH, APP_NAME) +@task def environment(name): + """Set the environment where the tasks will be executed""" env.update(environments[name]) env.environment = name -environment('dev') +environment(DEFAULT_ENVIRONMENT) + + +def aptget_install(pkg): + sudo('DEBIAN_FRONTEND=noninteractive apt-get install -y -q {}'.format(pkg)) + + +def install_requirements(): + with cd(REPO_PATH), prefix(WORKON_ENV): + run('pip install -U distribute') + if not env.is_vagrant: + run('pip install -r requirements.txt') + return + + if exists('requirements-{}.txt'.format(env.environment)): + run('pip install -r requirements-{}.txt'.format(env.environment)) + else: + run('pip install -r requirements.txt') def mkvirtualenv(): - if not exists('~/.virtualenvs/colab'): + if not exists('~/.virtualenvs/' + VENV_NAME): with prefix(SOURCE_VENV): - run('mkvirtualenv colab') + run('mkvirtualenv ' + VENV_NAME) return True -def install(local_settings=None): - env_created = mkvirtualenv() +def manage(command): + django_settings = env.get('django_settings') + env_vars = {} + if django_settings: + env_vars.update({'DJANGO_SETTINGS_MODULE': django_settings}) + + with shell_env(**env_vars): + with cd(MANAGE_PATH), prefix(WORKON_ENV): + run('python manage.py {}'.format(command)) + + +def syncdb(): + manage('syncdb') + + +def migrate(): + manage('migrate') + + +def collectstatic(): + sudo('mkdir -p /usr/share/nginx/{}'.format(APP_NAME)) + sudo('chown {} /usr/share/nginx/{}'.format(env.user, APP_NAME)) + manage('collectstatic --noinput') + + +def create_local_settings(): + with cd(SETTINGS_PATH), settings(user=env.superuser): + env_local_settings = 'local_settings-{}.py'.format(env.environment) + + if not exists('local_settings.py') and exists(env_local_settings): + run('ln -s {} {}'.format(env_local_settings, 'local_settings.py')) + run('chown {} local_settings.py'.format(env.user)) + - if not exists('~/colab'): - run('git clone https://github.com/TracyWebTech/colab ~/colab') +def update_code(): + if env.is_vagrant: + if not exists(REPO_PATH): + run('ln -s /vagrant/ {}'.format(REPO_PATH)) + return - if local_settings: - put(local_settings, '~/colab/src/colab/local_settings.py') + if not exists(REPO_PATH): + run('git clone {} {}'.format(REPO_URL, REPO_PATH)) + else: + with cd(REPO_PATH): + run('git pull') - if not exists('~/apache-solr-3.6.2/'): - run('wget http://archive.apache.org/dist/lucene/solr/3.6.2/apache-solr-3.6.2.tgz') - run('tar xzf apache-solr-3.6.2.tgz') - run('rm apache-solr-3.6.2.tgz') - with cd('~/apache-solr-3.6.2/example/solr/conf/'): - if not exists('stopwords_en.txt'): - run('cp stopwords.txt stopwords_en.txt') +@task +def bootstrap(): + """Bootstrap machine to run fabric tasks""" - if env_created: - update_requirements() + with settings(user=env.superuser): - sudo('supervisorctl reload', shell=False) + if not exists('/usr/bin/git'): + aptget_install('git') + if env.is_vagrant: + groups = 'sudo,vagrant' + local('chmod -fR g+w {}'.format(PROJECT_PATH)) + else: + groups = 'sudo' -def update_requirements(): - with cd('~/colab'), prefix(WORKON_COLAB): - run('pip install -U -r requirements.txt') + sudo('useradd {} -G {} -m -s /bin/bash'.format(APP_USER, groups), + quiet=True) + ssh_dir = '/home/{0}/.ssh/'.format(APP_USER) + if not exists(ssh_dir): + sudo('mkdir -p {0}'.format(ssh_dir)) + sudo('chmod 700 {0}'.format(ssh_dir)) + sudo('cp ~{}/.ssh/authorized_keys /home/{}/.ssh/'.format( + env.superuser, + APP_USER + )) + sudo('chown -fR {0}:{0} {1}'.format(APP_USER, ssh_dir)) + sudoers_file = os.path.join('/etc/sudoers.d/', APP_USER) + tmp_file = os.path.join('/tmp', APP_USER) + if not exists(sudoers_file): + sudo('echo "{} ALL=NOPASSWD: ALL" > {}'.format(APP_USER, tmp_file)) + sudo('chown root:root {}'.format(tmp_file)) + sudo('chmod 440 {}'.format(tmp_file)) + sudo('mv {} {}'.format(tmp_file, sudoers_file)) -def deploy(update=False): - with cd('~/colab/src/'), prefix(WORKON_COLAB): - run('git pull') +@task +def provision(): + """Run puppet""" - if update: - update_requirements() + update_code() - with cd('~/colab/src/'), prefix(WORKON_COLAB): - run('python manage.py syncdb') - run('python manage.py migrate') - run('python manage.py collectstatic --noinput') - run('python manage.py build_solr_schema -f ~/apache-solr-3.6.2/example/solr/conf/schema.xml') + puppet_path = os.path.join(REPO_PATH, 'puppet/') + modules_path = os.path.join(puppet_path, 'modules') + puppet_modules = '{}:/etc/puppet/modules'.format(modules_path) - sudo('supervisorctl restart all') + with cd(puppet_path): + run('sudo python bootstrap.py') + if env.is_vagrant: + cmd = os.path.join(puppet_path, 'manifests', 'site.pp') + else: + cmd = '-e "include {}"'.format(APP_NAME) -def rebuild_index(age=None, batch=None): - with cd('~/colab/src/'), prefix(WORKON_COLAB): - age_arg = '' - if age: - age_arg = '--age={}'.format(age) + if not exists('/usr/bin/puppet'): + print(colors.red('Please install `puppet` before continue.')) + return - batch_arg = '' - if batch: - batch_arg = '--batch-size={}'.format(batch) + sudo('puppet apply --modulepath={} {}'.format(puppet_modules, cmd)) - run('python manage.py rebuild_index {} {}'.format(age_arg, batch_arg)) +@task +def ssh_keygen(): + """Create SSH credentials""" + if not exists('~/.ssh/id_rsa'): + run("ssh-keygen -f ~/.ssh/id_rsa -N '' -b 1024 -q") + key = run('cat ~/.ssh/id_rsa.pub') -@with_settings(user='vagrant') -def build_solr_schema(): - with cd('/vagrant/src/'), prefix(WORKON_COLAB): - run('python manage.py build_solr_schema -f /tmp/schema.xml') + print('Public key:') + print(colors.yellow(key)) + print('') + print('Add the key above to your github repository deploy keys') - with settings(user='colab'): - run('cp /tmp/schema.xml ~/apache-solr-3.6.2/example/solr/conf/schema.xml') - sudo('supervisorctl restart solr') +@task +def deploy(noprovision=False): + """Deploy and run the new code (master branch)""" + if noprovision is False: + provision() + else: + update_code() -@with_settings(user='vagrant') -def runserver(update_requirements=False): - env_created = mkvirtualenv() + mkvirtualenv() - with cd('/vagrant/src/'), prefix(WORKON_COLAB): + sudo('supervisorctl stop all') - # If explicitly called or if it's a new environment - if update_requirements or env_created: - run('pip install -r /vagrant/requirements.txt') + install_requirements() + create_local_settings() + collectstatic() + syncdb() + migrate() - run('python manage.py syncdb') - run('python manage.py migrate') - run('python manage.py runserver 0.0.0.0:7000') + sudo('supervisorctl start all') -- libgit2 0.21.2