Source code for schrodinger.job.server

"""
Interact with a Job Server.
"""
import json
import os
from typing import NamedTuple
from typing import Union

from schrodinger.utils import subprocess


[docs]def ensure_localhost_server_running(): """ Makes sure there is a localhost jobserver running to do devtests. This server is configured in the default location. """ proc = subprocess.run( [jsc(os.environ["SCHRODINGER"]), "local-server-start"], stderr=subprocess.STDOUT, stdout=subprocess.PIPE) if proc.returncode != 0: raise RuntimeError( f"localhost job server failed to start with error {proc.stdout}")
[docs]def jsc(schrodinger): return f"{schrodinger}/jsc"
[docs]class ServerInfo(NamedTuple): """ ServerInfo is a serialization of a jobs protobuf ServerInfoResponse. See "jobs.proto" for more up-to-date details on each of these fields. It is created manually instead of generated by protoc because this is currently a niche data structure only used for generating a cert. It's not worth the time to incorporate the generation into our build steps or to wrap from c++ using SWIG because the raw data must come serialized from jsc anyway - see "get_server_info" for details. """ # webServerSecret is a deprecated field not relevant to most users. webServerSecret: str # hasLicenseChecking indicates whether the server has license checking. hasLicenseChecking: bool # hasServerAuth indicates whether the server has LDAP Authentication enabled. hasServerAuth: bool # hasSocketAuth indicates whether the server has Unix socket authentication enabled. hasSocketAuth: bool # authSocketPath is the path to the unix socket on the job server, if hasSocketAuth is True. authSocketPath: str # versionString is the version string for the job server, of the form "55000 revision={git_hash}" versionString: str # APIVersion is the API version of the jobserver. APIVersion: str # hostname is the hostname of the jobserver as specified on its TLS certificate. # It must be DNS-resolvable from a client machine in order to make a connection. hostname: str # databaseType is the database system used by the job server (either "sqlite" or "postgres") databaseType: str # schrodingerInstallation is a path to ANY schrodinger installation known by the job server. schrodingerInstallation: str
[docs] @classmethod def from_dict(cls, data: dict) -> "ServerInfo": """ Convert a dict to a ServerInfo. """ return ServerInfo(**{field: data[field] for field in cls._fields})
[docs] def has_authenticator(self) -> bool: return self.hasServerAuth or self.hasSocketAuth
[docs]def get_server_info(schrodinger: str, address: str) -> ServerInfo: """ Subprocess '$SCHRODINGER/jsc server-info' to get server information. This must be collected from jsc (the Go gRPC JobServerClient cli) because the c++ gRPC client doesn't support TLS connections to jobserver until we already have a cert. """ server_info_command = [jsc(schrodinger), "server-info", "--json", address] proc = subprocess.run(server_info_command, stdout=subprocess.PIPE, stderr=subprocess.STDOUT) if proc.returncode: raise RuntimeError( f"Could not get server info from job server: {address}.\n" f"Ran command: '{server_info_command}' with output: '{proc.stdout!r}'" f"with exit code: '{proc.returncode}.'") info = decode_to_server_info(proc.stdout) return info
[docs]def decode_to_server_info(data: Union[str, bytes]) -> ServerInfo: info_json = json.loads(data) server_info = ServerInfo.from_dict(info_json) return server_info