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
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")
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
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