This repository was archived by the owner on May 2, 2021. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 1
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
George Silva
committed
Jan 15, 2015
1 parent
09a1680
commit e2a955f
Showing
19 changed files
with
973 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -52,3 +52,5 @@ docs/_build/ | |
|
||
# PyBuilder | ||
target/ | ||
|
||
.idea/ |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,4 @@ | ||
include LICENSE | ||
include README.md | ||
recursive-include fabfile/templates * | ||
recursive-include docs * |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,7 @@ | ||
from .configuration import * | ||
from .database import * | ||
from .dependencies import * | ||
from .django import * | ||
from .system import * | ||
from .virtualenv import * | ||
from .webserver import * |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,184 @@ | ||
import ConfigParser | ||
import os | ||
from fabric.state import env | ||
import pprint | ||
|
||
@task | ||
def load_fabconfig(configuration_file=None): | ||
|
||
if configuration_file: | ||
configuration = ConfigParser.RawConfigParser() | ||
configuration.read(configuration_file) | ||
|
||
_load_main_configuration(configuration) | ||
_load_deploy_configuration(configuration) | ||
_load_os_configuration(configuration) | ||
_load_databases_configuration(configuration) | ||
_load_packages_configuration(configuration) | ||
_load_django_configuration(configuration) | ||
|
||
print "Configuration Done!" | ||
pprint.pprint(env, indent=2) | ||
|
||
def _load_main_configuration(configuration): | ||
|
||
# /opt/apps | ||
env.app_folder_prefix = configuration.get("main", "app_folder_prefix") | ||
|
||
# mapport | ||
env.virtualenv_name = configuration.get("main", "virtualenv_name") | ||
|
||
# /opt/apps/.virtualenvs | ||
env.virtualenvs_path = os.path.join(env.app_folder_prefix, configuration.get("main", "virtualenvs_path")) | ||
|
||
# /opt/apps/.virtualenvs/mapport | ||
env.virtualenv_path = os.path.join(env.virtualenvs_path, env.virtualenv_name) | ||
|
||
# /opt/apps/mapport | ||
env.app_path = os.path.join(env.app_folder_prefix, env.virtualenv_name) | ||
|
||
# /opt/apps/mapport/mapport | ||
env.app_root = os.path.join(env.app_path, env.repository_name) | ||
env.django_settings_path = os.path.join(env.app_root, env.virtualenv_name) | ||
|
||
def _load_git_configuration(configuration): | ||
|
||
# http://github.com/enplan/mapport.git | ||
env.git_url = configuration.get("git", "git_url") | ||
|
||
# mapport | ||
env.repository_name = configuration.get("git", "repository_name") | ||
|
||
if configuration.has_option("git", "source_root"): | ||
# /opt/apps/mapport/mapport/src | ||
env.source_root = os.path.join(env.app_root, configuration.get("git", "source_root")) | ||
env.django_settings_path = os.path.join(env.source_root, env.virtualenv_name) | ||
|
||
|
||
if configuration.has_option("git", "deploy_branch"): | ||
# ci-george, for example | ||
env.deploy_branch = configuration.get("git", "deploy_branch") | ||
|
||
|
||
def _load_packages_configuration(configuration): | ||
|
||
env.postgresql_version = configuration.get("packages", "postgresql_version") | ||
|
||
env.postgis_version = configuration.get("packages", "postgis_version") | ||
|
||
if configuration.has_section("packages") and configuration.has_option("packages", "extra_packages"): | ||
env.extra_packages = configuration.get("packages", "extra_packages") | ||
|
||
def _load_os_configuration(configuration): | ||
|
||
"""Loads all OS configurations""" | ||
|
||
# trusty | ||
env.distro = configuration.get("os", "distro") | ||
|
||
def _load_deploy_configuration(configuration): | ||
|
||
"""Load deploy related configurations""" | ||
|
||
first_task = env.tasks[0] | ||
|
||
if configuration.has_section("deploy") and first_task != "vagrant": | ||
|
||
if configuration.has_option("deploy", "fabric_user"): | ||
env.user = configuration.get("deploy", "fabric_user") | ||
|
||
if configuration.has_option("deploy", "fabric_sudo_user"): | ||
env.sudo_user = configuration.get("deploy", "fabric_sudo_user") | ||
|
||
if configuration.has_option("deploy", "fabric_sudo_password"): | ||
env.password = configuration.get("deploy", "fabric_sudo_password") | ||
|
||
if configuration.has_option("deploy", "fabric_parallel"): | ||
env.parallel = configuration.getboolean("deploy", "fabric_parallel") | ||
|
||
if configuration.has_option("deploy", "fabric_hosts"): | ||
env.hosts = configuration.get("deploy", "fabric_hosts") | ||
|
||
env.deploy_templates_path = configuration.get("deploy", "deploy_templates_path") | ||
|
||
env.postgresql_user_password = configuration.get("deploy", "postgresql_user_password") | ||
env.postgresql_role_password = configuration.get("deploy", "postgresql_role_password") | ||
|
||
env.app_user = configuration.get("deploy", "app_user") | ||
env.app_group = configuration.get("deploy", "app_group") | ||
env.no_workers = configuration.get("deploy", "no_workers") | ||
|
||
|
||
def _load_databases_configuration(configuration): | ||
|
||
"""Load all databases defined in the configuration file to environment in fabric. | ||
The configuration variable must be the result of ConfigParse.read method object.""" | ||
|
||
env.databases = {} | ||
|
||
for section in configuration.sections(): | ||
|
||
if section.startswith("database-"): | ||
|
||
try: | ||
alias = section.split("-")[1] | ||
except: | ||
raise ValueError("Malformed database configuration. {0} should have the prefix database- followed by the name of the django alias.") | ||
|
||
try: | ||
database_engine = configuration.get(section, "engine") | ||
database_name = configuration.get(section, "name") | ||
database_host = configuration.get(section, "host") | ||
database_port = configuration.get(section, "port") | ||
database_user = configuration.get(section, "user") | ||
database_password = configuration.get(section, "password") | ||
database_options = None | ||
if configuration.has_option(section, "managed"): | ||
database_managed = configuration.getboolean(section, "managed") | ||
else: | ||
database_managed = True | ||
|
||
if configuration.has_option(section, "options"): | ||
database_options = configuration.get(section, "options") | ||
|
||
except ConfigParser.NoOptionError: | ||
raise ValueError("Missing option in the database configuration for PostgreSQL.") | ||
|
||
env.databases[alias] = {"ENGINE": database_engine, | ||
"NAME": database_name, | ||
"USER": database_user, | ||
"PASSWORD": database_password, | ||
"HOST": database_host, | ||
"PORT": database_port, | ||
"MANAGED": database_managed} | ||
|
||
if database_options: | ||
env.databases[alias]["OPTIONS"] = database_options | ||
|
||
def _load_django_configuration(configuration): | ||
|
||
env.django = {} | ||
|
||
env.django["debug"] = configuration.getboolean("django", "debug") | ||
|
||
env.django["template_debug"] = configuration.getboolean("django", "template_debug") | ||
if configuration.has_option("django", "allowed_hosts"): | ||
env.django["allowed_hosts"] = configuration.get("django", "allowed_hosts") | ||
else: | ||
env.django["allowed_hosts"] = None | ||
|
||
if configuration.has_option("django", "media_root"): | ||
env.django["media_root"] = configuration.get("django", "media_root") | ||
else: | ||
env.django["media_root"] = os.path.join(env.source_root, "{0}_website".format(env.virtualenv_name), "media") | ||
|
||
if configuration.has_option("django", "static_root"): | ||
env.django["static_root"] = configuration.get("django", "static_root") | ||
else: | ||
env.django["static_root"] = os.path.join(env.source_root, "{0}_website".format(env.virtualenv_name), "static") | ||
|
||
env.django["django_admin_enabled"] = configuration.getboolean("django", "django_admin_enabled") | ||
|
||
if env.django["django_admin_enabled"]: | ||
|
||
env.django["django_contrib_path"] = os.path.join(env.virtualenv_path, "lib/python2.7/site-packages/django/contrib") |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,110 @@ | ||
"""All tasks related to database manipulation""" | ||
from fabric.context_managers import settings | ||
from fabric.decorators import task | ||
from fabric.operations import run, sudo | ||
from fabric.state import env | ||
from fabtools import user as system_user | ||
from fabtools.postgres import database_exists as postgresql_exists, user_exists | ||
from fabtools.postgres import create_database as create_postgres | ||
from fabtools.postgres import _run_as_pg | ||
from fabtools.mysql import database_exists as mysql_exists | ||
from fabtools.mysql import create_database as create_mysql | ||
|
||
@task | ||
def configure_database_access(): | ||
|
||
configure_postgres_user() | ||
configure_postgres_role() | ||
|
||
@task | ||
def configure_postgres_user(): | ||
|
||
if system_user.exists("postgres"): | ||
system_user.modify("postgres", password=env.postgresql_user_password) | ||
|
||
@task | ||
def configure_postgres_role(): | ||
|
||
if user_exists("postgres"): | ||
_run_as_pg("psql -U postgres -c \"ALTER USER postgres WITH password '{0}'\"".format(env.postgresql_role_password)) | ||
|
||
|
||
@task | ||
def create_databases(): | ||
|
||
databases = env.get("databases", None) | ||
|
||
if not databases: | ||
raise ValueError("We have no databases configuration.") | ||
|
||
database_creator = DatabaseCreator() | ||
database_creator.create_databases(databases) | ||
|
||
|
||
class DatabaseCreator(object): | ||
|
||
DATABASE_ENGINE_MAPPING = {"django.contrib.gis.db.backends.postgis": "_create_database_postgis", | ||
"django.db.backends.postgresql_psycopg2": "_create_database_postgresql", | ||
"django.db.backends.sqlite3": "_create_database_sqlite3", | ||
"django.db.backends.mysql": "_create_database_mysql", | ||
"django.db.backends.oracle": "_create_database_oracle"} | ||
|
||
POSTGIS_EXTENSION_COMMAND = 'psql -U postgres -d {0} -c "CREATE EXTENSION postgis; CREATE EXTENSION postgis_topology;"' | ||
DROP_DATABASE_COMMAND = 'psql -U postgres -c "DROP DATABASE IF EXISTS {0};"' | ||
|
||
def __init__(self): | ||
|
||
pass | ||
|
||
def create_databases(self, databases): | ||
|
||
"""Given a env.databases setting, creates all necessary databases""" | ||
|
||
for database_alias in databases: | ||
|
||
database = databases[database_alias] | ||
|
||
if not database["MANAGED"]: | ||
continue | ||
|
||
if not database["ENGINE"] in self.DATABASE_ENGINE_MAPPING: | ||
raise ValueError("Database engine not supported.") | ||
|
||
method = getattr(self, self.DATABASE_ENGINE_MAPPING[database["ENGINE"]]) | ||
method(database) | ||
|
||
def _create_database_postgresql(self, database_settings): | ||
|
||
if not postgresql_exists(database_settings["NAME"]): | ||
result = create_postgres(name=database_settings["NAME"], | ||
owner=database_settings["USER"]) | ||
|
||
return result | ||
|
||
def _create_database_postgis(self, database_settings): | ||
|
||
self._create_database_postgresql(database_settings) | ||
|
||
major_postgis_version = int(env.get("postgis_version").split(".")[0]) | ||
|
||
if major_postgis_version < 2: | ||
raise ValueError("PostGIS versions minor then 2 are not supported.") | ||
|
||
with settings(warn_only=True): | ||
result = _run_as_pg(self.POSTGIS_EXTENSION_COMMAND.format(database_settings["NAME"])) | ||
|
||
if result.failed: | ||
_run_as_pg(self.DROP_DATABASE_COMMAND.format(database_settings["NAME"])) | ||
|
||
def _create_database_sqlite3(self, database_settings): | ||
print "Database not created using fabric. It will be created using migrations." | ||
|
||
def _create_database_mysql(self, database_settings): | ||
|
||
if not mysql_exists(database_settings["NAME"]): | ||
create_mysql(name=database_settings["NAME"], | ||
owner=database_settings["USER"], | ||
owner_host=database_settings["HOST"]) | ||
|
||
def _create_database_oracle(self, database_settings): | ||
print "Oracle database creation not implemented yet." |
Oops, something went wrong.