Skip to content

Instantly share code, notes, and snippets.

@myles
Created June 27, 2017 13:21
Show Gist options
  • Save myles/9d0fe956779a669cfdfef67fc4125573 to your computer and use it in GitHub Desktop.
Save myles/9d0fe956779a669cfdfef67fc4125573 to your computer and use it in GitHub Desktop.
Trellis Fabric File for Transferring Production to Staging
import datetime
import yaml
from ansible_vault.api import Vault
from fabric.api import env, execute, get, local, put, run, task
env.user = 'root'
env.now = datetime.datetime.now().strftime('%Y-%m-%dT%H-%M-%S')
env.roledefs = {
'staging': {
'hosts': ['staging.example.com']
},
'production': {
'hosts': ['production.example.com']
}
}
env.sites = [
'example.com',
'example.org',
'example.ca',
'example.net'
]
with open('./.vault_pass') as fobj:
vault = Vault(password=fobj.read().strip())
with open('./group_vars/production/vault.yml') as fobj:
env.roledefs['production']['vault'] = vault.load(fobj.read())
with open('./group_vars/production/wordpress_sites.yml') as fobj:
env.roledefs['production']['wp_sites'] = \
yaml.load(fobj.read())['wordpress_sites']
with open('./group_vars/staging/vault.yml') as fobj:
env.roledefs['staging']['vault'] = vault.load(fobj.read())
with open('./group_vars/staging/wordpress_sites.yml') as fobj:
env.roledefs['staging']['wp_sites'] = \
yaml.load(fobj.read())['wordpress_sites']
def mysql_dump(db_name, export_name):
run(('mysqldump {db_name} '
'| gzip > /tmp/{export_name}.sql.gz').format(
db_name=db_name,
export_name=export_name))
get('/tmp/{0}.sql.gz'.format(export_name),
'/tmp/{0}.sql.gz'.format(export_name))
def mysql_load(db_name, export_name):
put('/tmp/{0}.sql.gz'.format(export_name),
'/tmp/{0}.sql.gz'.format(export_name))
run(('gunzip < /tmp/{export_name}.sql.gz | mysql -u root '
'-D {db_name}').format(
db_name=db_name,
export_name=export_name,
now=env.now))
def get_database():
role = env.effective_roles[0]
for site in env.sites:
db_name = '{site}_{role}'.format(site=site.replace('.', '_'),
role=role)
export_name = '{site}-{now}'.format(site=site.replace('.', '_'),
now=env.now)
mysql_dump(db_name, export_name)
def put_database():
role = env.effective_roles[0]
for site in env.sites:
db_name = '{site}_{role}'.format(site=site.replace('.', '_'),
role=role)
export_name = '{site}-{now}'.format(site=site.replace('.', '_'),
now=env.now)
mysql_load(db_name, export_name)
def get_uploads():
for site in env.sites:
export_name = '{site}-{now}'.format(site=site.replace('.', '_'),
now=env.now)
run(('tar -czvf /tmp/uploads-{export_name}.tgz '
'/srv/www/{site}/shared/uploads').format(site=site,
export_name=export_name))
get('/tmp/uploads-{0}.tgz'.format(export_name),
'/tmp/uploads-{0}.tgz'.format(export_name))
def put_uploads():
for site in env.sites:
export_name = '{site}-{now}'.format(site=site.replace('.', '_'),
now=env.now)
put('/tmp/uploads-{0}.tgz'.format(export_name),
'/tmp/uploads-{0}.tgz'.format(export_name))
run(('tar -xzvf /tmp/uploads-{export_name}.tgz -C /').format(
export_name=export_name))
@task
def transfer(source='production', target='staging'):
"""Transfer database and uploads between stages."""
get_database.roles = (source,)
get_uploads.roles = (source,)
execute(get_database)
execute(get_uploads)
put_database.roles = (target,)
put_uploads.roles = (target,)
execute(put_database)
execute(put_uploads)
@task
def deploy(stage='staging'):
"""Deploy changes to a stage."""
for site in env.sites:
local('./bin/deploy.sh {0} {1}'.format(stage, site))
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment