def test_reserve_app_port(self): port = utils.get_next_application_port() assert port != None utils.reserve_application_port(port) ports_key = schema.PORTS_KEY ports = json.loads(self.db.get(ports_key)) assert port in ports # cleanup utils.release_application_port(port) ports = self.db.get(ports_key) if ports: ports = json.loads(ports) assert port not in ports
def deploy_app(app_name=None, package=None, build_ve=True, force_rebuild_ve=False): """ Deploys application :keyword app_name: Name of application to deploy :keyword package: Package to deploy (as tar.gz) :keyword build_ve: Builds virtualenv for app :keyword force_rebuild_ve: Forces a rebuild of the virtualenv (destroys existing) """ log = config.get_logger("deploy_app") log.info("Deploying package {0}".format(package)) errors = {} output = {} tmp_deploy_dir = tempfile.mkdtemp() # extract try: tf = tarfile.open(package, mode="r:gz") tf.extractall(tmp_deploy_dir) # look for manifest manifest = os.path.join(tmp_deploy_dir, "manifest.json") if os.path.exists(manifest): mdata = json.loads(open(manifest, "r").read()) if not app_name: if "application" in mdata: app_name = mdata["application"] if not app_name: errors["deploy"] = "Unspecified application name or missing in manifest" else: ## attempt to stop before deploy # stop_application(app_name) # get app config app_config = utils.get_application_config(app_name) if app_config: try: app_config = json.loads(app_config) except: app_config = {} else: app_config = {} # create a uuid if non existent if "uuid" not in app_config: app_uuid = str(uuid.uuid4()) log.warn("UUID not found for {0}. Assigning {1}".format(app_name, app_uuid)) app_config["uuid"] = app_uuid if "version" in mdata: version = mdata["version"] log.info("Deploying version {0}".format(version)) else: version = None app_config["version"] = version if "packages" in mdata: pkgs = mdata["packages"] else: pkgs = None app_config["packages"] = pkgs if os.path.exists(os.path.join(tmp_deploy_dir, "requirements.txt")): reqs = os.path.join(tmp_deploy_dir, "requirements.txt") else: reqs = None if "runtime" in mdata: runtime = mdata["runtime"] else: runtime = None app_config["runtime"] = runtime if "repo_type" in mdata: repo_type = mdata["repo_type"] else: repo_type = None app_config["repo_type"] = repo_type if "repo_url" in mdata: repo_url = mdata["repo_url"].lower() else: repo_url = None app_config["repo_url"] = repo_url if "repo_revision" in mdata: repo_revision = mdata["repo_revision"] else: repo_revision = None app_config["repo_revision"] = repo_revision log.debug(mdata) ## get app port # port_reserved = False # if 'port' in app_config: # port = app_config['port'] # port_reserved = True # else: # port = utils.get_next_application_port() # app_config['port'] = port # get instances if "instances" in app_config: instances = app_config["instances"] if settings.NODE_NAME in instances: instances = instances[settings.NODE_NAME] else: instances = [] else: instances = [] if not instances: new_port = utils.get_next_application_port() instances.append(new_port) utils.reserve_application_port(new_port) log.debug("Reserved port {0} for {1}".format(new_port, app_name)) app_config["instances"] = {} app_config["instances"][settings.NODE_NAME] = instances # install app app_dir = os.path.join(settings.APPLICATION_BASE_DIR, app_name) if not os.path.exists(app_dir): os.makedirs(app_dir) else: # remove existing and re-create shutil.rmtree(app_dir) os.makedirs(app_dir) install_app_data = {} if repo_type and repo_url: log.info("Cloning {0} from {1} using {2}".format(app_name, repo_url, repo_type)) install_app_data["repo_url"] = repo_url if repo_type == "git": install_app_data["repo_init"] = "Cloning with git" p = Popen(["git", "clone", repo_url], stdout=PIPE, stderr=PIPE, cwd=app_dir) os.waitpid(p.pid, 0) elif repo_type == "hg": install_app_data["repo_init"] = "Cloning with mercurial" p = Popen(["hg", "clone", repo_url], stdout=PIPE, stderr=PIPE, cwd=app_dir) os.waitpid(p.pid, 0) else: log.error("Unknown repo type: {0}".format(repo_type)) p = None if p: p_out, p_err = p.stdout, p.stderr install_app_data["repo_out"] = p_out.read() install_app_data["repo_err"] = p_out.read() # checkout revision if needed if repo_revision: log.info("{0}: checking out revision {1}".format(app_name, repo_revision)) if repo_type == "git": p = Popen(["git", "checkout", repo_revision], stdout=PIPE, stderr=PIPE, cwd=app_dir) elif repo_type == "hg": p = Popen(["hg", "checkout", repo_revision], stdout=PIPE, stderr=PIPE, cwd=app_dir) else: log.error("{0}: Unknown repo type: {0}".format(app_name, repo_type)) p = None if p: os.waitpid(p.pid, 0) else: log.debug("{0}: installing application".format(app_name)) app_dir_target = os.path.join(app_dir, app_name) shutil.copytree(tmp_deploy_dir, app_dir_target) output["install_app"] = install_app_data # install ve if build_ve: output["install_virtualenv"] = install_virtualenv( application=app_name, packages=pkgs, requirements=reqs, runtime=runtime, force=force_rebuild_ve ) # update app config utils.update_application_config(app_name, app_config) # configure supervisor output["configure_supervisor"] = configure_supervisor(application=app_name) output["configure_webserver"] = configure_webserver(application=app_name) # restart app restart_application(app_name) else: log.error("Missing package manifest") errors["deploy"] = "missing package manifest" except Exception, e: traceback.print_exc() log.error("Deploy: {0}".format(traceback.format_exc())) errors["deploy"] = str(e)