def wrapper(config_dir, *args, **kwargs): assert "config" not in kwargs ssl_keyfile = kwargs["ssl_keyfile"] ssl_certfile = kwargs["ssl_certfile"] if ssl_certfile or ssl_keyfile: ssl_context = trio.ssl.create_default_context( trio.ssl.Purpose.SERVER_CLIENT) if ssl_certfile: ssl_context.load_cert_chain(ssl_certfile, ssl_keyfile) else: ssl_context.load_default_certs() kwargs["ssl_context"] = ssl_context configure_logging(kwargs["log_level"], kwargs["log_format"], kwargs["log_file"], kwargs["log_filter"]) config_dir = Path( config_dir) if config_dir else get_default_config_dir(os.environ) config = load_config(config_dir, debug="DEBUG" in os.environ) if config.sentry_url: configure_sentry_logging(config.sentry_url) kwargs["config"] = config return fn(**kwargs)
def bootstrap_organization(device, addr, config_dir, force, password): """ Configure the organization and register it first user&device. """ config_dir = Path(config_dir) if config_dir else get_default_config_dir(os.environ) debug = "DEBUG" in os.environ configure_logging(log_level="DEBUG" if debug else "WARNING") with cli_exception_handler(debug): trio_run(_bootstrap_organization, debug, device, addr, config_dir, force, password)
def wrapper(config_dir, *args, **kwargs): assert "config" not in kwargs configure_logging(kwargs["log_level"], kwargs["log_format"], kwargs["log_file"], kwargs["log_filter"]) config_dir = Path( config_dir) if config_dir else get_default_config_dir(os.environ) config = load_config(config_dir, debug="DEBUG" in os.environ) if config.telemetry_enabled and config.sentry_url: configure_sentry_logging(config.sentry_url) kwargs["config"] = config return fn(**kwargs)
def wrapper(**kwargs): # `click.open_file` considers "-" to be stdout if kwargs["log_file"] in (None, "-"): @contextmanager def open_log_file(): yield sys.stderr else: open_log_file = partial(click.open_file, kwargs["log_file"], "w") with open_log_file() as fd: configure_logging(log_level=kwargs["log_level"], log_format=kwargs["log_format"], log_stream=fd) return fn(**kwargs)
async def main(): # Config configure_logging(LOG_LEVEL) config_dir = get_default_config_dir(os.environ) config = load_config(config_dir) devices = list_available_devices(config_dir) key_file = next(key_file for _, device_id, _, key_file in devices if device_id == DEVICE_ID) device = load_device_with_password(key_file, PASSWORD) # Log in async with logged_core_factory(config, device) as core: # Get workspace user_manifest = core.user_fs.get_user_manifest() workspace_entry = user_manifest.workspaces[0] workspace = core.user_fs.get_workspace(workspace_entry.id) # await make_workspace_dir_inconsistent(device, workspace, "/bar") await make_workspace_dir_simple_versions(device, workspace, "/foo")
def status_organization(name, addr, administration_token): debug = "DEBUG" in os.environ configure_logging(log_level="DEBUG" if debug else "WARNING") with cli_exception_handler(debug): trio_run(_status_organization, name, addr, administration_token)
def run_cmd( host, port, db, db_drop_deleted_data, db_min_connections, db_max_connections, blockstore, administration_token, ssl_keyfile, ssl_certfile, log_level, log_format, log_file, log_filter, sentry_url, debug, dev, ): configure_logging(log_level, log_format, log_file, log_filter) if sentry_url: configure_sentry_logging(sentry_url) with cli_exception_handler(debug): config = BackendConfig( administration_token=administration_token, db_url=db, db_drop_deleted_data=db_drop_deleted_data, db_min_connections=db_min_connections, db_max_connections=db_max_connections, blockstore_config=blockstore, debug=debug, ) if ssl_certfile or ssl_keyfile: ssl_context = ssl.create_default_context(ssl.Purpose.CLIENT_AUTH) if ssl_certfile: ssl_context.load_cert_chain(ssl_certfile, ssl_keyfile) else: ssl_context.load_default_certs() else: ssl_context = None async def _run_backend(): async with backend_app_factory(config=config) as backend: async def _serve_client(stream): if ssl_context: stream = trio.SSLStream(stream, ssl_context, server_side=True) try: await backend.handle_client(stream) except Exception: # If we are here, something unexpected happened... logger.exception("Unexpected crash") await stream.aclose() await trio.serve_tcp(_serve_client, port, host=host) click.echo( f"Starting Parsec Backend on {host}:{port} (db={config.db_type}, " f"blockstore={config.blockstore_config.type})" ) try: trio_run(_run_backend, use_asyncio=True) except KeyboardInterrupt: click.echo("bye ;-)")
def create_organization(name, addr, administration_token, expiration_date): debug = "DEBUG" in os.environ configure_logging(log_level="DEBUG" if debug else "WARNING") with cli_exception_handler(debug): trio_run(_create_organization, debug, name, addr, administration_token, expiration_date)
def run_cmd( host, port, db, db_min_connections, db_max_connections, db_first_tries_number, db_first_tries_sleep, blockstore, administration_token, spontaneous_organization_bootstrap, organization_bootstrap_webhook, backend_addr, email_host, email_port, email_host_user, email_host_password, email_use_ssl, email_use_tls, email_sender, forward_proto_enforce_https, ssl_keyfile, ssl_certfile, log_level, log_format, log_file, log_filter, sentry_url, debug, dev, ): # Start a local backend configure_logging(log_level, log_format, log_file, log_filter) if sentry_url: configure_sentry_logging(sentry_url) with cli_exception_handler(debug): if ssl_certfile or ssl_keyfile: ssl_context = ssl.create_default_context(ssl.Purpose.CLIENT_AUTH) if ssl_certfile: ssl_context.load_cert_chain(ssl_certfile, ssl_keyfile) else: ssl_context.load_default_certs() else: ssl_context = None if email_host == "MOCKED": tmpdir = tempfile.mkdtemp(prefix="tmp-email-folder-") if email_sender: email_config = MockedEmailConfig(sender=email_sender, tmpdir=tmpdir) else: email_config = MockedEmailConfig(sender=DEFAULT_EMAIL_SENDER, tmpdir=tmpdir) else: if not email_sender: raise ValueError( "--email-sender is required when --email-host is provided") email_config = SmtpEmailConfig( host=email_host, port=email_port, host_user=email_host_user, host_password=email_host_password, use_ssl=email_use_ssl, use_tls=email_use_tls, sender=email_sender, ) config = BackendConfig( administration_token=administration_token, db_url=db, db_min_connections=db_min_connections, db_max_connections=db_max_connections, db_first_tries_number=db_first_tries_number, db_first_tries_sleep=db_first_tries_sleep, spontaneous_organization_bootstrap= spontaneous_organization_bootstrap, organization_bootstrap_webhook_url=organization_bootstrap_webhook, blockstore_config=blockstore, email_config=email_config, ssl_context=True if ssl_context else False, forward_proto_enforce_https=forward_proto_enforce_https, backend_addr=backend_addr, debug=debug, ) async def _run_backend(): async with backend_app_factory(config=config) as backend: async def _serve_client(stream): if ssl_context: stream = trio.SSLStream(stream, ssl_context, server_side=True) try: await backend.handle_client(stream) except Exception: # If we are here, something unexpected happened... logger.exception("Unexpected crash") await stream.aclose() await trio.serve_tcp(_serve_client, port, host=host) click.echo(f"Starting Parsec Backend on {host}:{port}" f" (db={config.db_type}" f" blockstore={config.blockstore_config.type}" f" backend_addr={config.backend_addr}" f" email_config={str(email_config)})") try: trio_run(_run_backend, use_asyncio=True) except KeyboardInterrupt: click.echo("bye ;-)")
async def initialize_test_organization( config_dir: Path, backend_address: BackendAddr, password: str, administration_token: str, force: bool, ) -> Tuple[LocalDevice, LocalDevice, LocalDevice]: configure_logging("WARNING") organization_id = OrganizationID("Org") # Create organization async with apiv1_backend_administration_cmds_factory( backend_address, administration_token ) as administration_cmds: rep = await administration_cmds.organization_create(organization_id) assert rep["status"] == "ok" bootstrap_token = rep["bootstrap_token"] organization_bootstrap_addr = BackendOrganizationBootstrapAddr.build( backend_address, organization_id, bootstrap_token ) # Bootstrap organization and Alice user async with apiv1_backend_anonymous_cmds_factory(organization_bootstrap_addr) as anonymous_cmds: alice_device = await bootstrap_organization( cmds=anonymous_cmds, human_handle=HumanHandle(label="Alice", email="*****@*****.**"), device_label="laptop", ) save_device_with_password(config_dir, alice_device, password, force=force) # Create a workspace for Alice config = load_config(config_dir, debug="DEBUG" in os.environ) async with logged_core_factory(config, alice_device) as core: alice_ws_id = await core.user_fs.workspace_create("alice_workspace") await core.user_fs.sync() # Register a new device for Alice other_alice_device = None async with backend_authenticated_cmds_factory( addr=alice_device.organization_addr, device_id=alice_device.device_id, signing_key=alice_device.signing_key, ) as alice_cmds: rep = await alice_cmds.invite_new(type=InvitationType.DEVICE) assert rep["status"] == "ok" invitation_addr = BackendInvitationAddr.build( backend_addr=alice_device.organization_addr, organization_id=alice_device.organization_id, invitation_type=InvitationType.DEVICE, token=rep["token"], ) async with backend_invited_cmds_factory(addr=invitation_addr) as invited_cmds: async def invite_task(): initial_ctx = DeviceGreetInitialCtx(cmds=alice_cmds, token=invitation_addr.token) in_progress_ctx = await initial_ctx.do_wait_peer() in_progress_ctx = await in_progress_ctx.do_wait_peer_trust() in_progress_ctx = await in_progress_ctx.do_signify_trust() in_progress_ctx = await in_progress_ctx.do_get_claim_requests() await in_progress_ctx.do_create_new_device( author=alice_device, device_label=in_progress_ctx.requested_device_label ) async def claim_task(): nonlocal other_alice_device initial_ctx = await claimer_retrieve_info(cmds=invited_cmds) in_progress_ctx = await initial_ctx.do_wait_peer() in_progress_ctx = await in_progress_ctx.do_signify_trust() in_progress_ctx = await in_progress_ctx.do_wait_peer_trust() other_alice_device = await in_progress_ctx.do_claim_device( requested_device_label="pc" ) async with trio.open_service_nursery() as nursery: nursery.start_soon(invite_task) nursery.start_soon(claim_task) save_device_with_password(config_dir, other_alice_device, password, force=force) # Invite Bob in bob_device = None rep = await alice_cmds.invite_new(type=InvitationType.USER, claimer_email="*****@*****.**") assert rep["status"] == "ok" invitation_addr = BackendInvitationAddr.build( backend_addr=alice_device.organization_addr, organization_id=alice_device.organization_id, invitation_type=InvitationType.USER, token=rep["token"], ) async with backend_invited_cmds_factory(addr=invitation_addr) as invited_cmds: async def invite_task(): initial_ctx = UserGreetInitialCtx(cmds=alice_cmds, token=invitation_addr.token) in_progress_ctx = await initial_ctx.do_wait_peer() in_progress_ctx = await in_progress_ctx.do_wait_peer_trust() in_progress_ctx = await in_progress_ctx.do_signify_trust() in_progress_ctx = await in_progress_ctx.do_get_claim_requests() await in_progress_ctx.do_create_new_user( author=alice_device, human_handle=in_progress_ctx.requested_human_handle, device_label=in_progress_ctx.requested_device_label, profile=UserProfile.STANDARD, ) async def claim_task(): nonlocal bob_device initial_ctx = await claimer_retrieve_info(cmds=invited_cmds) in_progress_ctx = await initial_ctx.do_wait_peer() in_progress_ctx = await in_progress_ctx.do_signify_trust() in_progress_ctx = await in_progress_ctx.do_wait_peer_trust() bob_device = await in_progress_ctx.do_claim_user( requested_human_handle=HumanHandle(label="Bob", email="*****@*****.**"), requested_device_label="laptop", ) async with trio.open_service_nursery() as nursery: nursery.start_soon(invite_task) nursery.start_soon(claim_task) save_device_with_password(config_dir, bob_device, password, force=force) # Create bob workspace and share with Alice async with logged_core_factory(config, bob_device) as core: bob_ws_id = await core.user_fs.workspace_create("bob_workspace") await core.user_fs.workspace_share(bob_ws_id, alice_device.user_id, WorkspaceRole.MANAGER) # Share Alice workspace with bob async with logged_core_factory(config, alice_device) as core: await core.user_fs.workspace_share(alice_ws_id, bob_device.user_id, WorkspaceRole.MANAGER) # Synchronize every device for device in (alice_device, other_alice_device, bob_device): async with logged_core_factory(config, device) as core: await core.user_fs.process_last_messages() await core.user_fs.sync() return (alice_device, other_alice_device, bob_device)
async def amain( backend_address="ws://*****:*****@laptop", bob_device_id="bob@laptop", other_device_name="pc", alice_workspace="alicews", bob_workspace="bobws", password="******", administrator_token=DEFAULT_ADMINISTRATOR_TOKEN, force=False, ): configure_logging("WARNING") config_dir = get_default_config_dir(os.environ) organization_id = OrganizationID(organization_id) backend_address = BackendAddr(backend_address) alice_device_id = DeviceID(alice_device_id) bob_device_id = DeviceID(bob_device_id) alice_slugid = f"{organization_id}:{alice_device_id}" bob_slugid = f"{organization_id}:{bob_device_id}" # Create organization async with backend_administrator_cmds_factory(backend_address, administrator_token) as cmds: bootstrap_token = await cmds.organization_create(organization_id) organization_bootstrap_addr = BackendOrganizationBootstrapAddr.build( backend_address, organization_id, bootstrap_token ) # Bootstrap organization and Alice user async with backend_anonymous_cmds_factory(organization_bootstrap_addr) as cmds: root_signing_key = SigningKey.generate() root_verify_key = root_signing_key.verify_key organization_addr = organization_bootstrap_addr.generate_organization_addr(root_verify_key) alice_device = generate_new_device(alice_device_id, organization_addr) save_device_with_password(config_dir, alice_device, password, force=force) now = pendulum.now() certified_user = certify_user( None, root_signing_key, alice_device.user_id, alice_device.public_key, now ) certified_device = certify_device( None, root_signing_key, alice_device_id, alice_device.verify_key, now ) await cmds.organization_bootstrap( organization_bootstrap_addr.organization_id, organization_bootstrap_addr.bootstrap_token, root_verify_key, certified_user, certified_device, ) # Create a workspace for Alice config = load_config(config_dir, debug="DEBUG" in os.environ) async with logged_core_factory(config, alice_device) as core: await core.fs.workspace_create(f"/{alice_workspace}") # Register a new device for Alice token = generate_invitation_token() other_alice_device_id = DeviceID("@".join((alice_device.user_id, other_device_name))) other_alice_slugid = f"{organization_id}:{other_alice_device_id}" async def invite_task(): async with backend_cmds_factory( alice_device.organization_addr, alice_device.device_id, alice_device.signing_key ) as cmds: await invite_and_create_device(alice_device, cmds, other_device_name, token) async def claim_task(): async with backend_anonymous_cmds_factory(alice_device.organization_addr) as cmds: other_alice_device = await retry(claim_device, cmds, other_alice_device_id, token) save_device_with_password(config_dir, other_alice_device, password, force=force) async with trio.open_nursery() as nursery: nursery.start_soon(invite_task) nursery.start_soon(claim_task) # Invite Bob in token = generate_invitation_token() async def invite_task(): async with backend_cmds_factory( alice_device.organization_addr, alice_device.device_id, alice_device.signing_key ) as cmds: await invite_and_create_user( alice_device, cmds, bob_device_id.user_id, token, is_admin=True ) async def claim_task(): async with backend_anonymous_cmds_factory(alice_device.organization_addr) as cmds: bob_device = await retry(claim_user, cmds, bob_device_id, token) save_device_with_password(config_dir, bob_device, password, force=force) async with trio.open_nursery() as nursery: nursery.start_soon(invite_task) nursery.start_soon(claim_task) # Create bob workspace and share with Alice bob_device = load_device_with_password( config.config_dir, organization_id, bob_device_id, password ) async with logged_core_factory(config, bob_device) as core: await core.fs.workspace_create(f"/{bob_workspace}") await core.fs.share(f"/{bob_workspace}", alice_device_id.user_id) # Share Alice workspace with bob async with logged_core_factory(config, alice_device) as core: await core.fs.share(f"/{alice_workspace}", bob_device_id.user_id) # Print out click.echo( f""" Mount alice and bob drives using: $ parsec core run -P {password} -D {alice_slugid} $ parsec core run -P {password} -D {other_alice_slugid} $ parsec core run -P {password} -D {bob_slugid} """ )
async def initialize_test_organization( config_dir: Path, backend_address: BackendAddr, password: str, administration_token: str, additional_users_number: int, additional_devices_number: int, ) -> Tuple[LocalDevice, LocalDevice, LocalDevice]: configure_logging(log_level="WARNING") organization_id = OrganizationID("Org") # Create organization async with apiv1_backend_administration_cmds_factory( backend_address, administration_token) as administration_cmds: rep = await administration_cmds.organization_create(organization_id) assert rep["status"] == "ok", rep bootstrap_token = rep["bootstrap_token"] organization_bootstrap_addr = BackendOrganizationBootstrapAddr.build( backend_address, organization_id, bootstrap_token) # Bootstrap organization and Alice user and create device "laptop" for Alice async with apiv1_backend_anonymous_cmds_factory( organization_bootstrap_addr) as anonymous_cmds: alice_device = await bootstrap_organization( cmds=anonymous_cmds, human_handle=HumanHandle(label="Alice", email="*****@*****.**"), device_label="laptop", ) save_device_with_password(config_dir=config_dir, device=alice_device, password=password) config = load_config(config_dir, debug="DEBUG" in os.environ) # Create context manager, alice_core will be needed for the rest of the script async with logged_core_factory(config, alice_device) as alice_core: async with backend_authenticated_cmds_factory( addr=alice_device.organization_addr, device_id=alice_device.device_id, signing_key=alice_device.signing_key, ) as alice_cmds: # Create new device "pc" for Alice other_alice_device = await _register_new_device( cmds=alice_cmds, author=alice_device, device_label="pc") save_device_with_password(config_dir=config_dir, device=other_alice_device, password=password) # Invite Bob in organization bob_device = await _register_new_user( cmds=alice_cmds, author=alice_device, device_label="laptop", human_handle=HumanHandle(email="*****@*****.**", label="Bob"), profile=UserProfile.STANDARD, ) save_device_with_password(config_dir=config_dir, device=bob_device, password=password) # Invite Toto in organization toto_device = await _register_new_user( cmds=alice_cmds, author=alice_device, device_label="laptop", human_handle=HumanHandle(email="*****@*****.**", label="Toto"), profile=UserProfile.OUTSIDER, ) save_device_with_password(config_dir=config_dir, device=toto_device, password=password) # Create Alice workspace alice_ws_id = await alice_core.user_fs.workspace_create( "alice_workspace") # Create context manager async with logged_core_factory(config, bob_device) as bob_core: # Create Bob workspace bob_ws_id = await bob_core.user_fs.workspace_create( "bob_workspace") # Bob share workspace with Alice await bob_core.user_fs.workspace_share(bob_ws_id, alice_device.user_id, WorkspaceRole.MANAGER) # Alice share workspace with Bob await alice_core.user_fs.workspace_share( alice_ws_id, bob_device.user_id, WorkspaceRole.MANAGER) # Add additional random users await _add_random_users( cmds=alice_cmds, author=alice_device, alice_core=alice_core, bob_core=bob_core, alice_ws_id=alice_ws_id, bob_ws_id=bob_ws_id, additional_users_number=additional_users_number, ) # Add additional random device for alice await _add_random_device( cmds=alice_cmds, device=alice_device, additional_devices_number=additional_devices_number, ) # Synchronize every device for device in (alice_device, other_alice_device, bob_device): async with logged_core_factory(config, device) as core: await core.user_fs.process_last_messages() await core.user_fs.sync() return (alice_device, other_alice_device, bob_device)
async def initialize_test_organization( backend_address, organization_id, alice_device_id, bob_device_id, other_device_name, alice_workspace, bob_workspace, password, administration_token, force, ): configure_logging("WARNING") config_dir = get_default_config_dir(os.environ) alice_slugid = f"{organization_id}:{alice_device_id}" bob_slugid = f"{organization_id}:{bob_device_id}" # Create organization async with backend_administration_cmds_factory( backend_address, administration_token) as cmds: rep = await cmds.organization_create(organization_id) assert rep["status"] == "ok" bootstrap_token = rep["bootstrap_token"] organization_bootstrap_addr = BackendOrganizationBootstrapAddr.build( backend_address, organization_id, bootstrap_token) # Bootstrap organization and Alice user async with backend_anonymous_cmds_factory( organization_bootstrap_addr) as cmds: root_signing_key = SigningKey.generate() root_verify_key = root_signing_key.verify_key organization_addr = organization_bootstrap_addr.generate_organization_addr( root_verify_key) alice_device = generate_new_device(alice_device_id, organization_addr, True) save_device_with_password(config_dir, alice_device, password, force=force) now = pendulum.now() user_certificate = UserCertificateContent( author=None, timestamp=now, user_id=alice_device.user_id, public_key=alice_device.public_key, is_admin=True, ).dump_and_sign(author_signkey=root_signing_key) device_certificate = DeviceCertificateContent( author=None, timestamp=now, device_id=alice_device.device_id, verify_key=alice_device.verify_key, ).dump_and_sign(author_signkey=root_signing_key) rep = await cmds.organization_bootstrap( organization_bootstrap_addr.organization_id, organization_bootstrap_addr.token, root_verify_key, user_certificate, device_certificate, ) assert rep["status"] == "ok" # Create a workspace for Alice config = load_config(config_dir, debug="DEBUG" in os.environ) async with logged_core_factory(config, alice_device) as core: alice_ws_id = await core.user_fs.workspace_create(f"{alice_workspace}") await core.user_fs.sync() # Register a new device for Alice token = generate_invitation_token() other_alice_device_id = DeviceID( f"{alice_device.user_id}@{other_device_name}") other_alice_slugid = f"{organization_id}:{other_alice_device_id}" async def invite_task(): await invite_and_create_device(alice_device, other_device_name, token) other_alice_device = None async def claim_task(): nonlocal other_alice_device other_alice_device = await retry_claim(claim_device, alice_device.organization_addr, other_alice_device_id, token) save_device_with_password(config_dir, other_alice_device, password, force=force) async with trio.open_service_nursery() as nursery: nursery.start_soon(invite_task) nursery.start_soon(claim_task) # Invite Bob in token = generate_invitation_token() bob_device = None async def invite_task(): await invite_and_create_user(alice_device, bob_device_id.user_id, token, is_admin=False) async def claim_task(): nonlocal bob_device bob_device = await retry_claim(claim_user, alice_device.organization_addr, bob_device_id, token) save_device_with_password(config_dir, bob_device, password, force=force) async with trio.open_service_nursery() as nursery: nursery.start_soon(invite_task) nursery.start_soon(claim_task) # Create bob workspace and share with Alice async with logged_core_factory(config, bob_device) as core: bob_ws_id = await core.user_fs.workspace_create(f"{bob_workspace}") await core.user_fs.workspace_share(bob_ws_id, alice_device_id.user_id, WorkspaceRole.MANAGER) # Share Alice workspace with bob async with logged_core_factory(config, alice_device) as core: await core.user_fs.workspace_share(alice_ws_id, bob_device_id.user_id, WorkspaceRole.MANAGER) # Synchronize every device for device in (alice_device, other_alice_device, bob_device): async with logged_core_factory(config, device) as core: await core.user_fs.process_last_messages() await core.user_fs.sync() return alice_slugid, other_alice_slugid, bob_slugid
def run_cmd( host, port, db, blockstore, ssl_keyfile, ssl_certfile, log_level, log_format, log_file, log_filter, ): configure_logging(log_level, log_format, log_file, log_filter) debug = "DEBUG" in os.environ with cli_exception_handler(debug): try: config = config_factory(blockstore_type=blockstore, db_url=db, debug=debug, environ=os.environ) except ValueError as exc: raise ValueError(f"Invalid configuration: {exc}") if config.sentry_url: configure_sentry_logging(config.sentry_url) backend = BackendApp(config) if ssl_certfile or ssl_keyfile: ssl_context = trio.ssl.create_default_context( trio.ssl.Purpose.SERVER_AUTH) if ssl_certfile: ssl_context.load_cert_chain(ssl_certfile, ssl_keyfile) else: ssl_context.load_default_certs() else: ssl_context = None async def _serve_client(stream): if ssl_context: stream = trio.ssl.SSLStream(stream, ssl_context, server_side=True) try: await backend.handle_client(stream) except Exception as exc: # If we are here, something unexpected happened... logger.error("Unexpected crash", exc_info=exc) await stream.aclose() async def _run_backend(): async with trio.open_nursery() as nursery: await backend.init(nursery) try: await trio.serve_tcp(_serve_client, port, host=host) finally: await backend.teardown() print( f"Starting Parsec Backend on {host}:{port} (db={config.db_type}, " f"blockstore={config.blockstore_config.type})") try: trio_asyncio.run(_run_backend) except KeyboardInterrupt: print("bye ;-)")
def run_cmd( host, port, db, db_min_connections, db_max_connections, maximum_database_connection_attempts, pause_before_retry_database_connection, blockstore, administration_token, spontaneous_organization_bootstrap, organization_bootstrap_webhook, backend_addr, email_host, email_port, email_host_user, email_host_password, email_use_ssl, email_use_tls, email_sender, forward_proto_enforce_https, ssl_keyfile, ssl_certfile, log_level, log_format, log_file, sentry_url, debug, dev, ): # Start a local backend configure_logging(log_level=log_level, log_format=log_format, log_file=log_file) if sentry_url: configure_sentry_logging(sentry_url) with cli_exception_handler(debug): if ssl_certfile or ssl_keyfile: ssl_context = ssl.create_default_context(ssl.Purpose.CLIENT_AUTH) if ssl_certfile: ssl_context.load_cert_chain(ssl_certfile, ssl_keyfile) else: ssl_context.load_default_certs() else: ssl_context = None if email_host == "MOCKED": tmpdir = tempfile.mkdtemp(prefix="tmp-email-folder-") if email_sender: email_config = MockedEmailConfig(sender=email_sender, tmpdir=tmpdir) else: email_config = MockedEmailConfig(sender=DEFAULT_EMAIL_SENDER, tmpdir=tmpdir) else: if not email_sender: raise ValueError( "--email-sender is required when --email-host is provided") email_config = SmtpEmailConfig( host=email_host, port=email_port, host_user=email_host_user, host_password=email_host_password, use_ssl=email_use_ssl, use_tls=email_use_tls, sender=email_sender, ) app_config = BackendConfig( administration_token=administration_token, db_url=db, db_min_connections=db_min_connections, db_max_connections=db_max_connections, spontaneous_organization_bootstrap= spontaneous_organization_bootstrap, organization_bootstrap_webhook_url=organization_bootstrap_webhook, blockstore_config=blockstore, email_config=email_config, ssl_context=True if ssl_context else False, forward_proto_enforce_https=forward_proto_enforce_https, backend_addr=backend_addr, debug=debug, ) click.echo(f"Starting Parsec Backend on {host}:{port}" f" (db={app_config.db_type}" f" blockstore={app_config.blockstore_config.type}" f" backend_addr={app_config.backend_addr}" f" email_config={str(email_config)})") try: retry_policy = RetryPolicy(maximum_database_connection_attempts, pause_before_retry_database_connection) trio_run(_run_backend, host, port, ssl_context, retry_policy, app_config, use_asyncio=True) except KeyboardInterrupt: click.echo("bye ;-)")