Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Commited WiP files for publication #833

Closed
wants to merge 11 commits into from
44 changes: 43 additions & 1 deletion askbot/deployment/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
from askbot.utils import console
from askbot.utils.functions import generate_random_key
from askbot.deployment.template_loader import DeploymentTemplate
import askbot.deployment.deployables as deployable
import shutil

DATABASE_ENGINE_CHOICES = ('1', '2', '3', '4')
Expand Down Expand Up @@ -236,7 +237,7 @@ def __call__(self): # this is the main part of the original askbot_setup()
database_engine = database_engine_codes[options.database_engine]
options_dict['database_engine'] = database_engine

self.deploy_askbot(options_dict)
self.deploy_askbot_new(options_dict)

if database_engine == 'postgresql_psycopg2':
try:
Expand Down Expand Up @@ -390,6 +391,47 @@ def deploy_askbot(self, options):
self.verbosity
)

def deploy_askbot_new(self, options):
create_new_project = True
if os.path.exists(options['dir_name']) and \
path_utils.has_existing_django_project(options['dir_name']) and \
options.force is False:
create_new_project = False

options['staticfiles_app'] = "'django.contrib.staticfiles',"
options['auth_context_processor'] = 'django.contrib.auth.context_processors.auth'

project = deployable.ProjectRoot(options['dir_name'])
site = deployable.AskbotSite(project.name)

if create_new_project is True:
project.src_dir = os.path.join(self.SOURCE_DIR, 'setup_templates')
project.contents.update({
path_utils.LOG_DIR_NAME: {options['logfile_name']: deployable.EmptyFile}
})
project.context = {'settings_path': f'{site.name}.settings'}
project.deploy()

site.src_dir = os.path.join(self.SOURCE_DIR, 'setup_templates')
site.dst_dir = options['dir_name']
site.context.update(options)
site.deploy()

help_file = path_utils.get_path_to_help_file()

if create_new_project:
print_message(
messages.HOW_TO_DEPLOY_NEW % {'help_file': help_file},
self.verbosity
)
else:
print_message(
messages.HOW_TO_ADD_ASKBOT_TO_DJANGO % {'help_file': help_file},
self.verbosity
)



# set to askbot_setup_orig to return to original installer
askbot_setup = AskbotSetup()

Expand Down
15 changes: 15 additions & 0 deletions askbot/deployment/deployables/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
"""
The main purpose of this code is to do a one-shot deployment of Askbot. It is
built on the premise that the chosen deployment is viable and possible. If an
error occurs, it is not this code's task to remedy the issue. If an error
occurs the deployment is considered as failed. Ideally, all the work this code
did up to the error is undone. Yet, this code has no means to undo anything.
"""

from .base import AskbotDeploymentError
from .objects import RenderedFile, CopiedFile, EmptyFile, Directory, LinkedDir
from .components import AskbotApp, AskbotSite, ProjectRoot


__all__ = ['RenderedFile', 'CopiedFile', 'EmptyFile', 'Directory', 'LinkedDir',
'AskbotApp', 'AskbotSite', 'ProjectRoot', 'AskbotDeploymentError']
20 changes: 20 additions & 0 deletions askbot/deployment/deployables/base.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
class AskbotDeploymentError(Exception):
"""Use this when something goes wrong while deploying Askbot"""


class ObjectWithOutput(object):
def __init__(self, verbosity=1, force=False):
self._verbosity = verbosity
self._force = force

@property
def verbosity(self):
return self._verbosity

@verbosity.setter
def verbosity(self, value):
self._verbosity = value

def print(self, message, verbosity=1):
if verbosity <= self.verbosity:
print(message)
114 changes: 114 additions & 0 deletions askbot/deployment/deployables/components.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,114 @@

from askbot.deployment.deployables.objects import *
from askbot.deployment.deployables.base import ObjectWithOutput

class DeployableComponent(ObjectWithOutput):
"""These constitute sensible deployment chunks of Askbot. For instance,
one would never deploy just a settings.py, because Django projects need
additional files as well."""
default_name = 'unset'
contents = dict()

def __init__(self, name=None, contents=None):
super(DeployableComponent, self).__init__(verbosity=2)
name = name if name is not None else self.__class__.default_name
contents = contents if contents is not None else self.__class__.contents

self.name = name
self.contents = contents
self._src_dir = None
self._dst_dir = None
self.context = dict()
self.skip_silently = list()
self.forced_overwrite = list()

def _grow_deployment_tree(self, component):
todo = list()
for name, deployable in component.items():
if isinstance(deployable,dict):
branch = self._grow_deployment_tree(deployable)
todo.append(
Directory(
name,
None,
*branch
))
else:
todo.append(deployable(name))
return todo

def _root_deployment_tree(self, tree):
root = Directory(self.name, None, *tree)
root.src_path = self.src_dir
root.dst_path = self.dst_dir
root.context = self.context
root.forced_overwrite = self.forced_overwrite
root.skip_silently = self.skip_silently
root.verbosity = self.verbosity
return root

@property
def src_dir(self):
return self._src_dir

@src_dir.setter
def src_dir(self, value):
self._src_dir = value

@property
def dst_dir(self):
return self._dst_dir

@dst_dir.setter
def dst_dir(self, value):
self._dst_dir = value

def deploy(self):
"""Recursively deploy all DeployItems we know about. This method is
meant to be overwritten by subclasses to provide more fine grained
configurations to individual branches and/or nodes."""
tree = self._grow_deployment_tree(self.contents)
root = self._root_deployment_tree(tree)
root.deploy()

class AskbotSite(DeployableComponent):
default_name = 'askbot_site'
contents = {
'settings.py': RenderedFile,
'__init__.py': CopiedFile,
'celery_app.py': CopiedFile,
'urls.py': CopiedFile,
'django.wsgi': CopiedFile,
}

class AskbotApp(DeployableComponent):
default_name = 'askbot_app'
contents = {}

class ProjectRoot(DeployableComponent):
contents = {
'manage.py': RenderedFile,
'cron': {
'send_email_alerts.sh': CopiedFile,
},
'doc': LinkedDir,
'upfiles': {},
}

def __init__(self, install_path):
dirname, basename = os.path.split(install_path)
if len(basename) == 0:
dirname, basename = os.path.split(dirname)
super(ProjectRoot, self).__init__(basename)
self.dst_dir = dirname

def deploy(self):
tree = self._grow_deployment_tree(self.contents)
root = self._root_deployment_tree(tree)
# doc has no template in setup_templates. we point src_dir to the
# correct directory after applying all defaults in _root_deployment_tree()
doc = [ node for node in root.content
if isinstance(node,LinkedDir)
and node.name == 'doc' ][0]
doc.src_path = os.path.dirname(doc.src_path)
root.deploy()
Loading