......@@ -156,6 +156,17 @@ CAUTION: This command may wipe the modifications made in the working directories
TIP: The formatters used are _pretty_ and _junit_.
* _Deploy_ the Drupal installation to a Web Server
$ fab deploy:dev
TIP: 'dev' is the environment to deploy the Drupal installation, see the default_vars.py file.
* _Deploy_ the Drupal installation to Aegir
$ fab --set=build_number=1,migrate=true,remove_platform_without_sites=true deploy:dev
TIP: 'migrate' and 'remove_platform_without_sites' are optionals parameters but 'build_number' is not, you should pass it always with a different value.
== Other common tasks
......
......@@ -17,100 +17,19 @@
#
from __future__ import unicode_literals
from fabric.api import task, roles, env, local, run
from fabric.colors import red, green
from fabric.api import task, env, local, run
from fabric.colors import green
from fabric.utils import abort
import helpers as h
import os, glob
import os
import glob
@task
@roles('local')
def to_aegir(environement, build='0', role='local', migrate_sites=False, delete_old_platforms=False):
"""Deploy the artifact to the aegir server.
$ fab deploy.to_aegir
:param environement: the environnement (dev, stage, production)
:param build: the number of the build in Jenkins
:param role: the role to run the task in fabric
:param migrate_sites: if aegir should migrate the sites to the new platform
:param delete_old_platforms: if aegir should remove old platforms
"""
aegir_server = env.aegir_server
aegir_user = env.aegir_user
aegir_path = env.aegir_path
aegir_dest_server = env.aegir_dest_server
build_dir = '{}/build'.format(env.workspace)
if environement == 'dev' and aegir_server and aegir_user and aegir_path and aegir_dest_server:
os.chdir(build_dir)
for artifact in glob.glob("*.tar.gz"):
# Get platform name
platform_name = '{}-{}-{}'.format(environement, artifact.split('.')[0], build)
# Remove old platforms
if h.fab_exists(role, env.site_root):
h.fab_run(role, 'rm -rf {}'.format(env.site_root))
# Untar new platform
with h.fab_cd(role, '{}/src'.format(env.workspace)):
h.fab_run(role, 'tar -xvzf {}/build/{}'.format(env.workspace, artifact))
# Rsync new platform
with h.fab_cd(role, env.workspace):
print green('Rsync {} to aegir'.format(platform_name))
h.fab_run(role, 'rsync -a src/drupal/ {}@{}:{}/platforms/{}'.format(aegir_user, aegir_server,
aegir_path, platform_name))
# Declare platform in aegir
print green('Declaring {} in aegir'.format(platform_name))
h.fab_run(
role,
"""
ssh {}@{} "drush --root='{}/platforms/{}' provision-save '@platform_{}' --context_type='platform' --web_server=@{}"
""".format(aegir_user, aegir_server, aegir_path, platform_name, platform_name, aegir_dest_server)
)
h.fab_run(
role,
"""
ssh {}@{} "drush @hostmaster hosting-import platform_{}"
""".format(aegir_user, aegir_server, platform_name)
)
h.fab_run(
role,
"""
ssh {}@{} "drush @hostmaster hosting-dispatch"
""".format(aegir_user, aegir_server)
)
if migrate_sites == 'true':
print green("Migrating all websites currently on {} to {}".format(environement, platform_name))
h.fab_run(
role,
"""
ssh {}@{} "./migrateS.drush {} {}"
""".format(aegir_user, aegir_server, environement, platform_name))
# Remove old platforms
h.fab_run(role, 'rm -rf {}'.format(env.site_root))
h.fab_run(role, 'rm -rf {}/build/{}'.format(env.workspace, artifact))
# Delete old platforms in aegir
if delete_old_platforms == 'true':
print green("Deleting old platforms on {}".format(environement))
h.fab_run(
role,
"""
ssh {}@{} "./deleteP.drush {} {}"
""".format(aegir_user, aegir_server, environement, platform_name))
else:
print red('There are not enought information to deploy the platformt')
def set_hosts(environment):
def _set_hosts(environment):
"""
Set the hosts Fabric environment variable with the target environment.
This is the host that will be used to run SSH commands on.
:param environment This is the host that will be used to run SSH commands on.
"""
if environment not in env.aliases:
abort('Environment {} could not be found in the aliases definition.'.format(environment))
......@@ -119,45 +38,135 @@ def set_hosts(environment):
env.hosts = ['{}@{}'.format(target.get('user'), target.get('host'))]
def is_aegir_deployment(target):
"""Check if the target environment is an Aegir server."""
return False if 'aegir' not in target or target.get('aegir') is False else True
def _is_aegir_deployment(target):
"""
Check if the target environment is an Aegir server.
"""
return False if 'aegir' not in target or target.get('aegir') is False else True
def _aegir_platform_name(target, environment):
"""Build the platform needed by Aegir, from the placeholder in configuration file.
"""
if 'aegir_platform' not in target:
abort('Aegir needs a unique platform name to function properly. Check your aegir_platform key in your aliases.')
aegir_platform = target.get('aegir_platform')
return aegir_platform.format(name=env.project_name, env=environment, build=env.build_number)
"""
Build the platform needed by Aegir, from the placeholder in configuration file.
"""
if 'aegir_platform' not in target:
abort('Aegir needs a unique platform name to function properly. Check your aegir_platform key in your aliases.')
aegir_platform = target.get('aegir_platform')
return aegir_platform.format(name=env.project_name, env=environment, build=env.build_number)
def _target_dir(environment):
"""
Return the target directory to deploy the site.
:param environment
"""
target = env.aliases.get(environment)
if _is_aegir_deployment(target):
return target.get('root') + _aegir_platform_name(target, environment)
return target.get('root')
def _set_site_offline(target, environment):
"""
Helper function to set the site in maintenance.
:param environment
"""
run('drush --yes --root={} vset site_offline 1'.format(target.get('root')))
print(green('The is in maintenance mode on the target environment {}.'.format(environment)))
def _set_site_online(target, environment):
"""
Helper function to set the site online.
:param environment
"""
run('drush --yes --root={} vset site_offline 0'.format(target.get('root')))
print(green('The site is online on the target environment {}.'.format(environment)))
def _update_site_database(target, environment):
"""
Helper function to update site database.
:param environment
"""
run('drush --yes --root={} updatedb'.format(target.get('root')))
print(green('The target environment {} is up-to-date.'.format(environment)))
def _clear_site_cache(target, environment):
"""
Helper function to clear site cache.
:param environment
"""
def target_dir(environment):
target = env.aliases.get(environment)
return target.get('root') + _aegir_platform_name(target, environment) if is_aegir_deployment(target) else target.get('root')
run('drush --yes --root={} cache-clear all'.format(target.get('root')))
print(green('The cache have been cleared on the target environment {}.'.format(environment)))
def get_archive_from_dir(directory):
"""List tarball archives in a directory.
"""
files = glob.glob1(directory, '*.tar.gz')
if len(files) == 0:
abort('No tarball found in {}'.format(directory))
if len(files) > 1:
abort('More than one tarball has been found in {}. Can not decide which one to deploy.'.format(directory))
return files[0]
def _get_archive_from_dir(directory):
"""
List tarball archives in a directory.
:param directory The directory used to untar the artefact.
"""
files = glob.glob1(directory, '*.tar.gz')
if len(files) == 0:
abort('No tarball found in {}'.format(directory))
if len(files) > 1:
abort('More than one tarball has been found in {}. Can not decide which one to deploy.'.format(directory))
return files[0]
def _rsync_platform(target, target_directory):
"""
Helper function to rsync platform to server.
"""
local('rsync -a src/drupal/ {}@{}:{}'.format(target.get('user'), target.get('host'), target_directory))
def _aegir_provision_platform(platform, aegir_path, aegir_destsrv):
"""
Provision the platform on Aegir
:param platform The platform name
:param aegir_path The path to the home of aegir, usually in /var/aegir
:param aegir_destsrv The destination webserver for the platform.
"""
run('drush --root="{}/platforms/{}" provision-save "@platform_{}" --context_type="platform" --web_server=@{}'
.format(aegir_path, platform, platform, aegir_destsrv))
run('drush @hostmaster hosting-import platform_{}'.format(platform))
run('drush @hostmaster hosting-dispatch')
def _aegir_migrate_sites(target, environment, platform):
"""
Helper funtion to migrage sites in aegir after a deployment.
:param environment
:param platform The patern name of the platform in wich the sites will be migrated on
"""
aegir_path = target.get('aegir_path')
run('{}/migrate-sites {} {}'.format(aegir_path, environment, platform))
def _aegir_remove_platform_without_sites(target, environment, platform):
"""
Helper funtion to remove platforms without sites in aegir after a deployment.
:param environment
:param platform The patern name of the platform in wich the sites will be migrated on
"""
aegir_path = target.get('aegir_path')
run('{}/remove-platform-wihout-sites {} {}'.format(aegir_path, environment, platform))
@task
def provision(environment, role='local'):
"""Provision a Jenkins deployment.
"""
Provision a Jenkins deployment.
This task loads the target environment and extract the archive to deploy.
:param environment The environment to deploy the site DEV, STAGE, PROD
:param role Tha fabric role to run the task.
"""
set_hosts(environment)
_set_hosts(environment)
artefact = get_archive_from_dir(env.builddir)
artefact = _get_archive_from_dir(env.builddir)
with h.fab_cd(role, '{}/src'.format(env.workspace)):
......@@ -174,129 +183,47 @@ def provision(environment, role='local'):
if not os.path.isfile('{}/src/drupal/cron.php'.format(env.workspace)):
abort('The archive to deploy does not seem to contain a valid Drupal installation.')
print green('The platform {} is now ready to be deployed to the target environment {}.'.format(artefact, environment))
print(green('The platform {} is now ready to be deployed to the target environment {}.'.format(artefact,
environment)))
@task
def push(environment, role='local'):
"""Push the platform to the target environment.
:param environment: The target environment. It must match a valid Drush alias.
def push(environment):
"""
Push the platform to the target environment.
:param environment: The target environment. It must match a valid Drush alias.
"""
target = env.aliases.get(environment)
target_directory = target_dir(environment)
target_directory = _target_dir(environment)
local('rsync -a src/drupal/ {}@{}:{}'.format(target.get('user'), target.get('host'), target_directory))
if is_aegir_deployment(target):
if _is_aegir_deployment(target):
# Push platform to Aegir Server
_rsync_platform(target, target_directory)
platform = _aegir_platform_name(target, environment)
_aegir_provision_platform(platform, target.get('aegir_path'), target.get('aegir_destsrv'))
else:
# Push platform to Web Server
_set_site_offline(target, environment)
_rsync_platform(target, target_directory)
def _aegir_provision_platform(platform, aegir_path, aegir_destsrv):
# Provision the platform on Aegir
run('drush --root="{}/platforms/{}" provision-save "@platform_{}" --context_type="platform" --web_server=@{}'.format(aegir_path, platform, platform, aegir_destsrv))
run('drush @hostmaster hosting-import platform_{}'.format(platform))
run('drush @hostmaster hosting-dispatch')
def _aegir_migrate_sites(environment, platform):
run('{}/migrate-sites {} {}'.format(environment, platform))
@task
@roles('local')
def migrate(environment, role='local'):
"""Migrate the Drupal database on the target environment.
:param environment: The target environment. It must match a valid Drush alias.
def migrate(environment):
"""
Migrate the Drupal database on the target environment.
:param environment: The target environment. It must match a valid Drush alias.
"""
target = env.aliases.get(environment)
if is_aegir_deployment(target) and env.migrate == "true":
if _is_aegir_deployment(target):
# Deploy to Aegir server.
platform = _aegir_platform_name(target, environment)
_aegir_migrate_sites(environment, platform)
# Run the updatedb script
# with h.fab_cd(role, env.site_root):
# Run the Drupal update script
# h.fab_run(
# role,
# 'drush --yes @{} updatedb'
# .format(environment)
# )
# print green('The target environment {} is up-to-date.'.format(environment))
#
# Clear caches
# h.fab_run(
# role,
# 'drush --yes @{} cache-clear all'
# .format(environment)
# )
# print green('The caches have been cleared on the target environment {}.'.format(environment))
if env.get('migrate', "false") == "true":
_aegir_migrate_sites(target, environment, platform)
@task
@roles('local')
def to_server(environement, role='local'):
"""Deploy the artifact to the aegir server.
$ fab deploy.to_aegir
:param environement: the environnement (dev, stage, production)
:param role: the role to run the task in fabric
"""
build_dir = '{}/build'.format(env.workspace)
os.chdir(build_dir)
for artifact in glob.glob("*.tar.gz"):
# Remove old platforms
if h.fab_exists(role, env.site_root):
h.fab_run(role, 'rm -rf {}'.format(env.site_root))
# Untar new platform
print green('Untar new platform')
with h.fab_cd(role, '{}/src'.format(env.workspace)):
h.fab_run(role, 'tar -xvzf {}/build/{}'.format(env.workspace, artifact))
d.aliases()
with h.fab_cd(role, env.site_root):
# Set the site in maintenance mode
print green('Set the site in maitenance mode')
h.fab_run(
role,
'drush --yes @{} vset site_offline 1'
.format(environement)
)
# rsync
print green('Rsync the site source code')
h.fab_run(
role,
'drush --yes rsync --exclude=sites/all/files --exclude-files --exclude=.htaccess --delete --verbose @self @{}'
.format(environement)
)
# update data base
print green('Update site database')
h.fab_run(
role,
'drush --yes @{} updatedb'
.format(environement)
)
# Set site online
print green('Set the site online')
h.fab_run(
role,
'drush --yes @{} vset site_offline 0'
.format(environement)
)
# clean cache
print green('Clear site cache')
h.fab_run(
role,
'drush --yes @{} cache-clear all'
.format(environement)
)
# Remove old platforms
h.fab_run(role, 'rm -rf {}'.format(env.site_root))
h.fab_run(role, 'rm -rf {}/build/{}'.format(env.workspace, artifact))
print green('Deployment in {} finished'.format(environement))
if env.get('remove_platform_without_sites', "false") == "true":
_aegir_remove_platform_without_sites(target, environment, platform)
else:
# Deploy to a Web Server
_update_site_database(target, environment)
_clear_site_cache(target, environment)
_set_site_online(target, environment)