def conditional_s3_get(key, filename, sha=None): """Download a file from S3 to the local machine. Don't re-download if the sha matches (uses sha256). """ sha_matches = False if exists(filename) and sha: sha_matches = sha_for_file(filename).startswith(sha) if not exists(filename) or not sha_matches: env.s3_key.key = key env.s3_key.get_contents_to_filename(filename)
def conditional_symlink_current_release(deployed=False): """Swap the 'current' symlink to point to the new release if it doesn't point there already. Requires the env keys: pretty_release - set by make_pretty_release(), a commit identifier release_path - root target directory on the remote server """ current_version = None if exists(utils.absolute_release_path()): with settings(cd(utils.absolute_release_path()), warn_only=True): current_version = run('git describe') if (not exists(utils.absolute_release_path()) or deployed or current_version != env.pretty_release): _symlink_current_release(env.release_path)
def install_requirements(deployed=False): """Install the pip packages listed in the project's requirements files, private packages, as well as manual installation scripts. Installation scripts defined by env.package_installation_scripts will be provided the path to the virtualenv if one exists as the first argument. Requires the env keys: release_path -- remote path of the deployed app virtualenv -- path to this app's virtualenv (required to grab the correct Python executable) """ require('release_path') require('virtualenv') with settings(cd(env.release_path), warn_only=True): virtualenv_exists = exists('%(virtualenv)s' % env) if (deployed or not virtualenv_exists or confirm( yellow("Reinstall Python dependencies?"), default=True)): _install_pip_requirements() for package in _read_private_requirements(): _install_private_package(*package) _install_manual_packages() return True return False
def maintenancemode(): """If using the maintenancemode app (https://github.com/jezdez/django-maintenancemode), this command will toggle it on and off. It finds the `MAINTENANCE_MODE` variable in your `settings.py` on the remote server, toggles its value and restarts the web server. Requires the env keys: toggle - set by enable() or disable(), indicates whether we should turn maintenance mode on or off. settings - relative path from the project root to the settings.py file current_release_path - path to the current release on the remote server """ require('toggle', provided_by=[enable, disable]) require('settings') require('current_release_path') settings_file = os.path.join(utils.absolute_release_path(), env.settings) if exists(settings_file): sed(settings_file, '(MAINTENANCE_MODE = )(False|True)', '\\1%(toggle)s' % env) restart_webserver() else: warn('Settings file %s could not be found' % settings_file)
def install_requirements(deployed=False): """Install the pip packages listed in the project's requirements files, private packages, as well as manual installation scripts. Installation scripts defined by env.package_installation_scripts will be provided the path to the virtualenv if one exists as the first argument. Requires the env keys: release_path -- remote path of the deployed app virtualenv -- path to this app's virtualenv (required to grab the correct Python executable) """ require('release_path') require('virtualenv') with settings(cd(env.release_path), warn_only=True): virtualenv_exists = exists('%(virtualenv)s' % env) if (deployed or not virtualenv_exists or confirm(yellow("Reinstall Python dependencies?"), default=True)): _install_pip_requirements() for package in _read_private_requirements(): _install_private_package(*package) _install_manual_packages() return True return False
def bootstrap_release_folders(): """Create the target deploy directories if they don't exist and clone a fresh copy of the project's repository into each of the release directories. """ require('path') require('deploy_group') conditional_mkdir(os.path.join(env.path, env.releases_root), env.deploy_group, 'g+w', use_sudo=True) with cd(os.path.join(env.path, env.releases_root)): first_exists = exists(env.release_paths[0]) if not first_exists: run('git clone %s %s' % (env.scm, env.release_paths[0]), forward_agent=True) with cd(os.path.join(env.path, env.releases_root)): if not exists(env.release_paths[1]): run('cp -R %s %s' % (env.release_paths[0], env.release_paths[1])) chmod(os.path.join(env.path, env.releases_root), 'g+w', use_sudo=True)
def conditional_install_crontab(base_path, crontab, user): """If the project specifies a crontab, install it for the specified user on the remote server. """ if crontab: crontab_path = os.path.join(base_path, crontab) if crontab and exists(crontab_path): sudo('crontab -u %s %s' % (user, crontab_path))
def _package_installed(package): with settings(warn_only=True): virtualenv_exists = exists('%(virtualenv)s' % env) if virtualenv_exists: installed = run('%s/bin/python -c "import %s"' % (env.virtualenv, package)) else: installed = run('python -c "import %s"' % package) return installed.return_code == 0
def alternative_release_path(): """Determine the release directory that is not currently in use. For example if the 'current' symlink points to the 'a' release directory, this method returns 'b'. Requires the env keys: release_paths - a tuple of length 2 with the release directory names (defaults to 'a' and 'b') """ if exists(utils.absolute_release_path()): current_release_path = run('readlink %s' % utils.absolute_release_path()) if os.path.basename(current_release_path) == env.release_paths[0]: alternative = env.release_paths[1] else: alternative = env.release_paths[0] return alternative else: return env.release_paths[0]