예제 #1
0
def _install_backend(
    backend_root,
    name,
    remote_user,
    backend_virtual_env,
    team,
    repo,
    database_uri,
    env_vars,
    install_postgres=True,
    create_postgres_database=True,
    use_sudo=True,
):
    uname = run("uname -v")
    is_ubuntu = "Ubuntu" in uname
    run_cmd = partial(_run_command, sudo=use_sudo)

    if install_postgres:
        if not is_ubuntu and not cmd_avail("psql"):
            raise NotImplementedError("Postgres install on {!r}".format(uname))
        postgres.install0()

    if create_postgres_database:
        parsed_database_uri = urlparse(database_uri)

        created = postgres.setup_users(
            create=({
                "user": parsed_database_uri.username,
                "password": parsed_database_uri.password,
                "dbname": parsed_database_uri.path[1:],
            }, ),
            connection_str=database_uri,
        )
        assert created is not None

    clone_or_update(team=team,
                    repo=repo,
                    use_sudo=use_sudo,
                    to_dir=backend_root,
                    branch="master")
    offregister_python_ubuntu.install_venv0(virtual_env=backend_virtual_env,
                                            python3=True,
                                            packages=("gunicorn", "uwsgi"))
    offregister_python_ubuntu.install_package1(package_directory=backend_root,
                                               virtual_env=backend_virtual_env)

    if not exists("/etc/systemd/system"):
        raise NotImplementedError("Non SystemD platforms")

    if run("id {remote_user}".format(remote_user=remote_user),
           warn_only=True,
           quiet=True).failed:
        sudo('adduser {remote_user} --disabled-password --quiet --gecos ""'.
             format(remote_user=remote_user))
    (uid, user), (gid, group) = get_user_group_tuples(remote_user)

    uwsgi_service = "/etc/systemd/system/{name}-uwsgi.service".format(
        name=name)
    upload_template(
        circus_dir("uwsgi.service"),
        uwsgi_service,
        context={
            "USER": user,
            "GROUP": group,
            "{}_BACK".format(name.upper()): "{}/{}".format(backend_root, name),
            "UID": uid,
            "GID": gid,
            "VENV": backend_virtual_env,
            "BACKEND_ROOT": backend_root,
            "SERVICE_USER": "******",
            "NAME": name,
            "ENV": env_vars,
        },
        use_sudo=True,
        backup=False,
        mode=0o644,
    )
    grp = sudo("id -gn", quiet=True)
    sudo("chown {grp}:{grp} {uwsgi_service}".format(
        grp=grp, uwsgi_service=uwsgi_service))
    restart_systemd("{name}-uwsgi".format(name=name))

    return backend_virtual_env, database_uri
예제 #2
0
def install0(*args, **kwargs):
    kwargs.setdefault("virtual_env", "/opt/venvs/mlflow")

    if not kwargs.get("skip_virtualenv", False):
        venv0_kwargs = {
            "virtual_env": kwargs["virtual_env"],
            "python3": True,
            "pip_version": "19.2.3",
            "use_sudo": True,
            "remote_user": "******",
            "PACKAGES": ["mlflow[extras]"],
        }
        venv0_kwargs.update(kwargs)
        python_mod.install_venv0(**venv0_kwargs)

    circus0_kwargs = {
        "APP_NAME": "mlflow",
        "APP_PORT": 5000,
        "CMD":
        "{virtual_env}/bin/mlflow".format(virtual_env=kwargs["virtual_env"]),
        "CMD_ARGS": "ui",
        "WSGI_FILE": None,
    }
    circus0_kwargs.update(kwargs)
    circus_mod.install_circus0(**circus0_kwargs)

    kwargs.setdefault("skip_nginx_restart", True)
    kwargs.setdefault(
        "conf_remote_filename",
        "/etc/nginx/sites-enabled/{}.conf".format(kwargs["SERVER_NAME"]),
    )
    kwargs.update({
        "nginx_conf":
        "proxy-pass.conf",
        "NAME_OF_BLOCK":
        "mlflow",
        "SERVER_LOCATION":
        "localhost:{port}".format(port=circus0_kwargs["APP_PORT"]),
        "LISTEN_PORT":
        80,
        "LOCATION":
        "/",
    })
    if exists(kwargs["conf_remote_filename"]):
        parsed_remote_conf = get_parsed_remote_conf(
            kwargs["conf_remote_filename"])

        parsed_api_block = loads(
            api_proxy_block(
                location=kwargs["LOCATION"],
                proxy_pass="******".format(kwargs["SERVER_LOCATION"]),
            ))
        sio = StringIO()
        sio.write(
            dumps(
                merge_into(kwargs["SERVER_NAME"], parsed_remote_conf,
                           parsed_api_block)))
        sio.seek(0)

        put(sio, kwargs["conf_remote_filename"], use_sudo=True)
    else:
        nginx_static.setup_conf0(**kwargs)

        # with shell_env(VIRTUAL_ENV=kwargs['virtual_env'], PATH="{}/bin:$PATH".format(kwargs['virtual_env'])):sudo('mlflow initdb')

    restart_systemd("circusd")
예제 #3
0
def _setup_circus(
    home,
    name,
    remote_user,
    circus_virtual_env,
    backend_virtual_env,
    database_uri,
    env_vars,
    backend_root,
    backend_logs_root,
    port,
):
    sudo("mkdir -p {circus_virtual_env}".format(
        circus_virtual_env=circus_virtual_env))
    group_user = run("""printf '%s:%s' "$USER" $(id -gn)""",
                     shell_escape=False,
                     quiet=True)
    sudo("chown -R {group_user} {circus_virtual_env}".format(
        group_user=group_user, circus_virtual_env=circus_virtual_env))
    uname = run("uname -v", quiet=True)
    is_ubuntu = "Ubuntu" in uname
    if is_ubuntu:
        offregister_python_ubuntu.install_venv0(
            python3=True,
            virtual_env=circus_virtual_env,
        )
    else:
        run('python3 -m venv "{virtual_env}"'.format(
            virtual_env=circus_virtual_env))
    with shell_env(VIRTUAL_ENV=circus_virtual_env,
                   PATH="{}/bin:$PATH".format(circus_virtual_env)):
        run("pip install circus")
    conf_dir = "/etc/circus/conf.d"  # '/'.join((backend_root, 'config'))
    sudo("mkdir -p {conf_dir} {backend_logs_root}".format(
        conf_dir=conf_dir, backend_logs_root=backend_logs_root))
    py_ver = run("{virtual_env}/bin/python --version".format(
        virtual_env=backend_virtual_env)).partition(" ")[2][:3]
    sudo("touch {backend_logs_root}/gunicorn.{{stderr,stdout}}.log".format(
        backend_logs_root=backend_logs_root))
    upload_template(
        circus_dir("circus.ini"),
        "{conf_dir}/".format(conf_dir=conf_dir),
        context={
            "HOME": backend_logs_root,
            "BACKEND_LOGS_ROOT": backend_logs_root,
            "BACKEND_ROOT": backend_root,
            "NAME": name,
            "USER": remote_user,
            "VENV": backend_virtual_env,
            "PYTHON_VERSION": py_ver,
            "PORT": port,
            "ENV": env_vars,
        },
        backup=False,
        mode=0o644,
        use_sudo=True,
    )
    circusd_context = {
        "CIRCUS_VENV": circus_virtual_env,
        "CONF_DIR": conf_dir,
        "BACKEND_ROOT": backend_root,
        "NAME": name,
        "ENV": env_vars,
    }
    if uname.startswith("Darwin"):
        upload_template(
            circus_dir("circusd.launchd.xml"),
            "{home}/Library/LaunchAgents/io.readthedocs.circus.plist".format(
                home=home),
            context=circusd_context,
            backup=False,
            mode=0o644,
        )
    elif exists("/etc/systemd/system"):
        remote_service_name = "/etc/systemd/system/circusd.service"
        upload_template(
            circus_dir(remote_service_name[remote_service_name.rfind("/") +
                                           1:]),
            remote_service_name,
            context=circusd_context,
            use_sudo=True,
            backup=False,
            mode=0o644,
        )
        sudo("chown {grp}:{grp} {remote_service_name}"
             "".format(grp=sudo("id -gn", quiet=True),
                       remote_service_name=remote_service_name))
    else:
        upload_template(
            circus_dir("circusd.conf"),
            "/etc/init/",
            context=circusd_context,
            use_sudo=True,
            backup=False,
            mode=0o644,
        )
    return circus_virtual_env, database_uri
예제 #4
0
def setup_circus(
    circus_virtual_env,
    env,
    home,
    log_dir,
    name,
    port,
    remote_user,
    app_virtual_env,
    working_dir,
    wsgi_file,
    uname,
    cmd_args=None,
    cmd="gunicorn",
    shell="/bin/bash",
):
    conf_dir = "/etc/circus/conf.d"
    remote_circus_ini = "{conf_dir}/circus.ini".format(conf_dir=conf_dir)

    assert (cmd_args is not None
            or wsgi_file is not None), "cmd_args or wsgi_file must be defined"

    circus_ini_context = {
        "CMD":
        cmd,
        "CMD_ARGS": ("-w 3 -t 60 -b 127.0.0.1:{port:d} {wsgi_file}".format(
            port=port, wsgi_file=wsgi_file) if cmd_args is None else cmd_args),
        "ENV":
        "" if env is None else "\n".join(
            ("{} = {}".format(k, v) for k, v in iteritems(env))),
        "HOME":
        home,
        "LOG_DIR":
        log_dir,
        "NAME":
        name,
        "SHELL":
        shell,
        "USER":
        remote_user,
        "VENV":
        app_virtual_env,
        "WORKING_DIR":
        working_dir,
    }

    paths = "{circus_virtual_env} {log_dir} {working_dir}".format(
        circus_virtual_env=circus_virtual_env,
        log_dir=log_dir,
        working_dir=working_dir)
    sudo("mkdir -p {paths} {conf_dir}".format(paths=paths, conf_dir=conf_dir))
    group_user = run(
        """printf '%s:%s' "{user}" $(id -gn)""".format(user=remote_user),
        shell_escape=False,
        quiet=True,
    )
    sudo("chown -R {group_user} {paths}".format(group_user=group_user,
                                                paths=paths))

    venvs = (venv for venv in (circus_virtual_env, app_virtual_env)
             if not exists("{}/bin".format(circus_virtual_env)))
    for virtual_env in venvs:
        if "Ubuntu" in uname:
            install_venv0(python3=True, virtual_env=virtual_env)
        else:
            run('python3 -m venv "{virtual_env}"'.format(
                virtual_env=virtual_env))

    py_ver = run("{virtual_env}/bin/python --version".format(
        virtual_env=app_virtual_env)).partition(" ")[2][:3]
    circus_ini_context["PYTHON_VERSION"] = py_ver

    with open(configs_dir("circus.ini"), "rt") as f:
        circus_ini_content = f.read()

    circus_ini_content = circus_ini_content.format(
        **circus_ini_context)  # Code is here because I like to error early

    if not exists(remote_circus_ini):
        with shell_env(
                VIRTUAL_ENV=circus_virtual_env,
                PATH="{}/bin:$PATH".format(circus_virtual_env),
        ):
            run("pip install circus")

        sio = StringIO()
        sio.write("[circus]\n"
                  "check_delay = 5\n"
                  "endpoint = tcp://127.0.0.1:5555\n"
                  "pubsub_endpoint = tcp://127.0.0.1:5556\n"
                  "statsd = true\n\n")
        sio.seek(0)

        put(sio, remote_path=remote_circus_ini, use_sudo=True)

        circusd_context = {
            "CONF_DIR": conf_dir,
            "CIRCUS_VENV": circus_virtual_env
        }
        if uname.startswith("Darwin"):
            upload_template(
                configs_dir("circusd.launchd.xml"),
                "{home}/Library/LaunchAgents/io.readthedocs.circus.plist".
                format(home=home),
                context=circusd_context,
            )
        elif exists("/etc/systemd/system"):
            upload_template(
                configs_dir("circusd.service"),
                "/etc/systemd/system/",
                context=circusd_context,
                use_sudo=True,
            )
        else:
            upload_template(
                configs_dir("circusd.conf"),
                "/etc/init/",
                context=circusd_context,
                use_sudo=True,
            )

    sio0 = StringIO()
    get(remote_circus_ini, sio0, use_sudo=True)
    sio0.seek(0)

    config0 = ConfigParser()
    config0.readfp(sio0)

    sio1 = StringIO()
    sio1.write(circus_ini_content)
    sio1.seek(0)

    config1 = ConfigParser()
    config1.readfp(sio1)

    for section in config1.sections():
        if config0.has_section(section):
            config0.remove_section(section)
        config0.add_section(section)
        for item, val in config1.items(section):
            config0.set(section, item, val)

    sio2 = StringIO()
    config0.write(sio2)
    sio2.seek(0)

    put(local_path=sio2, remote_path=remote_circus_ini, use_sudo=True)

    return circus_virtual_env