Exemplo n.º 1
0
 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
Exemplo n.º 2
0
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)