예제 #1
0
    def setUp(self):
        super(CannulaTestCase, self).setUp()
        self.base_dir = conf.CANNULA_BASE
        if not os.path.isdir(self.base_dir):
            os.makedirs(self.base_dir)
        logging.info("Running Setup")
        self.dummy_project = os.path.join(self.base_dir, 'dummy')

        # TODO: Override any thing else?

        try:

            from cannula.api import api
            self.api = api

            # create an admin user
            self.api.users.create('abby',
                                  password="******",
                                  email='*****@*****.**',
                                  first_name="Abby",
                                  last_name="Admin",
                                  is_admin=True)
            self.api.users.create('jim',
                                  password="******",
                                  email='*****@*****.**',
                                  first_name="Jim",
                                  last_name="User",
                                  is_admin=False)
            # Copy the test git project to base_dir
            shutil.copytree(os.path.join(DATA_DIR, 'dummy'),
                            self.dummy_project)
            from cannula.git import Git
            self.dummy = Git(self.dummy_project)
            self.dummy.init()
            self.dummy.add_all()
            self.dummy.commit('initial commit')

            # Write out base supervisor and proxy configs
            self.api.proc.write_main_conf(commit=True)
            self.api.proxy.write_main_conf(commit=True)
            self.api.proc.startup()
        except:
            logging.exception('Setup Failed')
            shutil.rmtree(self.base_dir)
            self.fail("Problem setting up testcase")
예제 #2
0
 def git_repo(self):
     return Git(self.conf_base)
예제 #3
0
 def deploy(self, project, user, oldrev='old', newrev='new'):
     user = api.users.get(user)
     project = api.projects.get(project)
     if not os.path.isfile(project.appconfig):
         raise ApiError("Project missing app.yaml file!")
     
     # Attempt to get an exclusive lock on the project
     # file. A way to ensure only one process can deploy
     # at any single time. This is hard because deployment is
     # triggered by a git push (which is just an ssh connection)
     with DeployLock(project, user):
         with open(project.appconfig) as f:
             
             # Store the configuration for this project in git repo
             # so that we can roll back to previous states
             conf_dir = Git(project.conf_dir)
             
             if not os.path.isdir(project.conf_dir):
                 os.makedirs(project.conf_dir)
                 conf_dir.init()
                 # Add an initial commit, just to make a rollback point.
                 open(project.deployconfig, 'a')
                 conf_dir.add_all()
                 conf_dir.commit("Initial Commit")
             
             # Copy the project app.yaml to the conf_dir
             shutil.copy(project.appconfig, project.deployconfig)
             
             # read in the application configuration
             app = yaml.load(f.read())
             
             # setup any runtime specific things here
             try:
                 runtime = import_object(app.get('runtime'))
             except ImportError:
                 raise ApiError("Unsupported runtime!")
             # runtime bootstrap, setup project environment here
             runtime.bootstrap(project, app)    
                 
         
             # Simple counter to make unique names for each handler
             # and keep them in order
             handler_position = 0
             sections = []
             for handler in app.get('handlers', []):
                 if handler.get('worker'):
                     # Setup worker
                     name = '%s_%d' % (project.name, handler_position)
                     # defaults are special, they reference another
                     # section in the app.yaml
                     defaults = handler.pop('defaults', None)
                     if defaults:
                         handler_defaults = app.get(defaults, {})
                         handler.update(handler_defaults)
                     handle = Handler(name, project, **handler)
                     # write out bash start up scripts
                     handle.write_startup_script()
                     # add handler to vhost_sections
                     sections.append(handle)
                     handler_position += 1
                 else:
                     # Just pass the dictionary to the proxy vhosts
                     sections.append(handler)
             
             # Write out the proxy file to serve this app
             ctx = {
                 'sections': sections,
                 'domain': app.get('domain', 'localhost'),
                 'runtime': app.get('runtime', 'python'),
                 'port': app.get('port', 80),
                 'project_conf_dir': project.conf_dir,
                 'conf_dir': os.path.join(conf.CANNULA_BASE, 'config'),
                 'project': project,
             }
             api.proxy.write_vhost_conf(project, ctx)
             api.proc.write_project_conf(project, ctx)
             
             # Check if any files changed and check if still valid
             conf_dir.add_all()
             _, changed = conf_dir.status()
             logging.debug(changed)
             if re.search('vhost.conf', changed):
                 # Vhost file is either new or changed which will require 
                 # our proxy server to reload its configuration files.
                 try:
                     api.proxy.restart()
                 except:
                     logging.exception("Error restarting proxy")
                     conf_dir.reset()
                     raise ApiError("Deployment failed")
             if re.search('supervisor.conf', changed):
                 try:
                     api.proc.reread()
                 except:
                     logging.exception("Error reading supervisor configs")
                     conf_dir.reset()
                     raise ApiError("Deployment failed")
             
             # Add the project
             api.proc.reread(stderr=True)
             api.proc.add_project(project.name)
                 
             # Restart the project
             try:
                 api.proc.restart(project.name, stderr=True)
             except:
                 logging.exception("Error restarting project")
                 conf_dir.reset()
                 raise ApiError("Deployment failed")
             # Current revision of conf directory
             conf_oldrev = conf_dir.head()
             if changed:
                 # Commit config changes
                 conf_dir.commit("Configuration: %s" % datetime.datetime.now().ctime())
             
             # new revision of conf directory
             conf_newrev = conf_dir.head()
             if oldrev is None:
                 oldrev = "Initial Commit"
             self._create(project, user, oldrev, newrev, conf_oldrev, conf_newrev)