Commits

theoden  committed 3661b48

eliminating of env.conf.APPS

  • Participants
  • Parent commits 2d9d9cb
  • Branches multiple web-servers

Comments (0)

Files changed (8)

File fab_deploy/project.py

 # coding: utf-8
 from __future__ import with_statement
 from functools import wraps
+import types
 
 from fabric.api import abort, settings, cd, run, env, puts, sudo
 from fabric.contrib import console
 from taskset import TaskSet, task_method
 
 from fab_deploy import utils, pip, system, vcs, db
+from fab_deploy.webserver.apache import Apache
+from fab_deploy.webserver.nginx import Nginx
+from fab_deploy.django import Django
 
 __all__ = ['WebProject']
 
 class WebProject(TaskSet):
 
+    def __init__(self, apps=None):
+        if apps is None:
+            apps = dict(django=Django(Nginx(), Apache(wsgi='django_wsgi.py')))
+        self.apps = apps
+
+    def _expose_to(self, module_obj):
+        for name, task in self._get_fabric_tasks():
+            setattr(module_obj, name, task)
+            yield name
+        apps_module = types.ModuleType('apps')
+        for app_name, app in self.apps.iteritems():
+            module = app.expose_as_module(app_name)
+            setattr(apps_module, app_name, module)
+        module_obj.apps = apps_module
+
     @task_method
     def full_deploy(self):
         """ Prepares server and deploys the project. """
     @task_method
     def install_web_servers(self):
         """ Installs servers for all of the project apps. """
-        for app in env.conf.APPS:
+        for app in self.apps.itervalues():
             app.install_web_servers()
 
     @task_method
         """
         pip.install_r(what, options)
         if restart:
-            for app in env.conf.APPS:
+            for app in self.apps.itervalues():
                 app.restart()
 
     @task_method
         """
         pip.update_r(what, options)
         if restart:
-            for app in env.conf.APPS:
+            for app in self.apps.itervalues():
                 app.restart()
 
     @task_method
         pip.virtualenv_create()
         self._make_clone()
         self.install_r(env.conf.PIP_REQUIREMENTS, restart=False)
-        for app in env.conf.APPS:
+        for app in self.apps.itervalues():
             app.deploy()
 
     @task_method
             message = "Do you wish to undeploy host %s?" % env.hosts[0]
             if not console.confirm(message, default=False):
                 abort("Aborting.")
-        for app in env.conf.APPS:
+        for app in self.apps.itervalues():
             app.remove()
         # remove project sources
         run('rm -rf %s' % env.conf.SRC_DIR)
 
     @task_method
     def update_web_servers(self):
-        for app in env.conf.APPS:
+        for app in self.apps.itervalues():
             app.update_web_servers()
 
     @task_method
         with cd('src/' + env.conf['INSTANCE_NAME']):
             vcs.up(branch)
         before_restart()
-        for app in env.conf.APPS:
+        for app in self.apps.itervalues():
             app.restart()
     
     @task_method
     
         if 'pip_update' in args:
             self.update_r(restart=False)
-        for app in env.conf.APPS:
+        for app in self.apps.itervalues():
             if 'syncdb' in args:
                 app.syncdb()
             if 'migrate' in args:
                 app.migrate()
         # execute 'before_restart' callback
         kwargs.get('before_restart', lambda: None)()
-        for app in env.conf.APPS:
+        for app in self.apps.itervalues():
             if 'norestart' not in args:
                 app.restart()
             if 'notest' not in args:

File fab_deploy/utils.py

 import os
 import posixpath
 import pprint
-import types
 from copy import deepcopy
 from re import match
 from functools import wraps
         if match(p[0], distname) and match(p[1], version) and match(p[2], id):
             return name
 
-class IterableModule(types.ModuleType):
-
-    def __iter__(self):
-        for i in [attr for attr in dir(self) if not attr.startswith('_')]:
-            yield getattr(self, i)
-
-def define_apps(**kwargs):
-    apps_module = IterableModule('apps')
-    for app_name, app in kwargs.items():
-        module = app.expose_as_module(app_name)
-        setattr(apps_module, app_name, module)
-    def dispatch(self, name):
-        if (self != env.conf.APPS): # yep, we need identities here
-            raise AttributeError
-        return object.__getattribute__(self, name)
-    apps_module.__getattribute__ = dispatch
-    return apps_module
-
 @task
 def detect_os():
     if 'conf' in env and 'OS' in env.conf:
         if env.conf.VCS == vcs:
             env.conf.VCS = 'fab_deploy.vcs.' + vcs
 
-def define_host(host_string, defaults=None, host_apps=None):
+def define_host(host_string, defaults=None):
     """
     This decorator populates :attr:`env.hosts`, :attr:`env.conf` and
     calls :func:`update_env() <fab_deploy.utils.update_env>`::
             else:
                 env.conf = deepcopy(defaults)
             env.conf.update(func(*args, **kwargs))
-            env.conf['APPS'] = host_apps
             update_env()
         return inner
     return decorator

File fab_deploy_tests/test_project/fabfile.py

 from fabric.api import env, task
 
-from fab_deploy.utils import define_host, define_apps, update_env
-from fab_deploy.webserver.apache import Apache
-from fab_deploy.webserver.nginx import Nginx
-from fab_deploy.django import Django
+from fab_deploy.utils import define_host, update_env
 from fab_deploy.project import WebProject
 
-apps = define_apps(
-    django=Django(Nginx(config='nginx.config'), Apache(config='apache.config', wsgi='django_wsgi.py'))
-)
 project = WebProject().expose_as_module('project')
 
-@define_host('foo@127.0.0.1:2222', host_apps=apps)
+@define_host('foo@127.0.0.1:2222')
 def foo_site():
     return dict(
         DB_USER = 'root',
         VCS = 'none',
         SERVER_NAME = 'bar.example.com',
         INSTANCE_NAME = 'bar',
-        APPS = apps,
     )
     update_env()
 
-@define_host('foo@127.0.0.1:2222', host_apps=apps)
+@define_host('foo@127.0.0.1:2222')
 def invalid_site():
     return dict(
         DB_USER = 'root',

File fab_deploy_tests/test_project2/fabfile.py

-from fab_deploy.utils import define_host, define_apps
+from fab_deploy.utils import define_host
 from fab_deploy.webserver.apache import Apache
 from fab_deploy.webserver.nginx import Nginx
 from fab_deploy.django import Django
     CONFIG_TEMPLATES_PATHS = ['hosting/staging', 'hosting'],
 )
 
-apps = define_apps(
+apps = dict(
     django=Django(
-        Nginx(config='nginx.config'), 
-        Apache(config='apache.config', wsgi='django_wsgi.py'),
+        Nginx(), 
+        Apache(wsgi='django_wsgi.py'),
         local_config='local_settings.py',
         remote_config='staging_settings.py'
     )
 )
-project = WebProject().expose_as_module('project')
+project = WebProject(apps).expose_as_module('project')
 
-@define_host('foo2@127.0.0.1:2222', LAYOUT_OPTIONS, apps)
+@define_host('foo2@127.0.0.1:2222', LAYOUT_OPTIONS)
 def foo_site():
     return dict(
         VCS = 'git',

File fab_deploy_tests/test_project3/fabfile.py

-from fab_deploy.utils import define_host, define_apps
+from fab_deploy.utils import define_host
 from fab_deploy.webserver.apache import Apache
 from fab_deploy.webserver.nginx import Nginx
 from fab_deploy.django import Django
     SERVER_NAME = 'baz.example.com'
 )
 
-apps = define_apps(
+apps = dict(
     django=Django(
         Nginx(config='nginx.config'), 
         Apache(config='apache.config', wsgi='django_wsgi.py'),
         remote_config='test_project3/config.server.py'
     )
 )
-project = WebProject().expose_as_module('project')
+project = WebProject(apps=apps).expose_as_module('project')
 
-@define_host('baz@127.0.0.1:2222', COMMON, host_apps=apps)
+@define_host('baz@127.0.0.1:2222', COMMON)
 def postgres_site():
     return dict(
         DB_BACKEND = 'postgres',
     )
 
 
-@define_host('baz@127.0.0.1:2222', COMMON, host_apps=apps)
+@define_host('baz@127.0.0.1:2222', COMMON)
 def postgis_site():
     return dict(
         DB_BACKEND = 'postgis',

File fab_deploy_tests/tests/base.py

 from fabric.api import env, run
 from fabric.state import _AttributeDict
 from fabtest import FabTest
-from fab_deploy.utils import update_env, define_apps
-from fab_deploy.webserver.apache import Apache
-from fab_deploy.webserver.nginx import Nginx
-from fab_deploy.django import Django
+from fab_deploy.utils import update_env
+from fab_deploy.project import WebProject
 from fab_deploy_tests.utils import get_package_state, private_key_path
 
 class FabDeployTest(FabTest):
     host = 'foo@127.0.0.1:2222'
     key_filename = [private_key_path()]
+    project = WebProject().expose_as_module('project')
 
     def setup_env(self):
-        # define_apps should save its result to a variable from global namespace
-        # of the project's fabfile. It is needed to make apps' tasks available
-        # to commandline "fab" call. 
-        self.apps_module = define_apps(
-            django=Django(Nginx(), Apache())
-        )
         super(FabDeployTest, self).setup_env()
         env.abort_on_prompts = True
         self.setup_conf()
         env.conf = _AttributeDict(
             DB_USER='root',
             DB_BACKEND='dummy',
-            APPS = self.apps_module,
         )
 
     def assertPackageInstalled(self, name):

File fab_deploy_tests/tests/deploy.py

 from fab_deploy.webserver.apache import Apache
 from .base import FabDeployTest
 from ..utils import setup_ssh, setup_sudo
-from ..test_project.fabfile import foo_site, bar_site, invalid_site, apps, project
-from ..test_project2.fabfile import foo_site as foo_site2, apps as apps2, project as project2
-from ..test_project3.fabfile import postgis_site, postgres_site, apps as apps3, project as project3
+from ..test_project.fabfile import foo_site, bar_site, invalid_site, project
+from ..test_project2.fabfile import foo_site as foo_site2, project as project2
+from ..test_project3.fabfile import postgis_site, postgres_site, project as project3
 
 @contextlib.contextmanager
 def answer_yes():
 class FabDeployProjectTest(FabDeployTest):
     snapshot = 'fabtest-prepared-server'
     project_dir = 'test_project'
-    apps = apps
     project = project
 
     def assertResponse(self, url, response, post_data = None):
             self.assertTrue(get_file_content(path))
 
     def assertCommandAvailable(self, command):
-        result = fab(self.apps.django.command_is_available, command)
+        result = fab(self.project.apps.django.command_is_available, command)
         self.assertTrue(result)
 
     def assertCommandNotAvailable(self, command):
-        result = fab(self.apps.django.command_is_available, command)
+        result = fab(self.project.apps.django.command_is_available, command)
         self.assertFalse(result)
 
     def assertCommandFails(self, command):
         self.assertRaises(FabricAbortException, fab,
-                          self.apps.django.command_is_available, command)
+                          self.project.apps.django.command_is_available, command)
 
     def assertInstanceWorks(self, instance):
         url = 'http://%s.example.com/instance/' % instance
 
         # first site
         fab(foo_site)
-        fab(env.conf.APPS.django.backend.upload_config)
+        fab(self.project.apps.django.backend.upload_config)
 
         foo_port = env.conf.PORTS['apache']
         self.assertPortNotBound(foo_port)
 
         # second site
         fab(bar_site)
-        fab(env.conf.APPS.django.backend.upload_config)
+        fab(self.project.apps.django.backend.upload_config)
 
         bar_port = env.conf.PORTS['apache']
         self.assertNotEqual(foo_port, bar_port)
         self.assertPortBound(bar_port)
 
         # re-configuring doesn't lead to errors
-        fab(env.conf.APPS.django.backend.upload_config)
+        fab(self.project.apps.django.backend.upload_config)
         fab(apacheNoConfig.restart)
         self.assertPortBound(bar_port)
 
 class CustomLayoutDeployTest(FabDeployProjectTest):
     project_dir = 'test_project2'
     project = project2
-    apps = apps2
 
     def setUp(self):
         super(CustomLayoutDeployTest, self).setUp()
 
 class Django14LayoutDeployTest(FabDeployProjectTest):
     project_dir = 'test_project3'
-    apps = apps3
     project = project3
 
     def post_name(self, name):

File fab_deploy_tests/tests/system_tests.py

 
         fab(prepare)
         self.assertPackageInstalled('python')
-        apps = env.conf.APPS
+        apps = self.project.apps
         fab(apps.django.backend.install, confirm=False)
         fab(apps.django.frontend.install)
         self.assertPackageInstalled('nginx')