Skip to content
This repository was archived by the owner on Jan 23, 2026. It is now read-only.
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import logging
import sys
from functools import partial
from typing import Literal, Optional

Expand All @@ -9,8 +10,14 @@

def _opt_log_level_callback(ctx, param, value):
traceback.install()
# there is no way to determine if the command is invoked for jmp run or something else at this
# point based on ctx and params, so we just look at sys.argv
if len(sys.argv) > 1 and sys.argv[1] == "run":
# on a exporter run we don't want to use RichHandler for logs, just plain logs for the system journal
basicConfig = partial(logging.basicConfig)
else:
basicConfig = partial(logging.basicConfig, handlers=[RichHandler()])

basicConfig = partial(logging.basicConfig, handlers=[RichHandler()])
if value:
basicConfig(level=value.upper())
else:
Expand Down
30 changes: 5 additions & 25 deletions packages/jumpstarter/jumpstarter/exporter/exporter.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,11 +7,9 @@
import grpc
from anyio import (
AsyncContextManagerMixin,
CancelScope,
connect_unix,
create_memory_object_stream,
create_task_group,
move_on_after,
sleep,
)
from anyio.abc import TaskGroup
Expand Down Expand Up @@ -61,30 +59,12 @@ def stop(self, wait_for_lease_exit=False):
async def __asynccontextmanager__(self) -> AsyncGenerator[Self]:
try:
yield self
# no need to unregister, it will be done by the lease
# this context manager is kept because it's likely to be used on the hooks
# mechanism, otherwise remove it later now it's a no-op
# TODO(mangelajo): remove this if not necessary anymore once hooks are implemented
finally:
try:
if self.registered:
logger.info("Unregistering exporter with controller")
try:
with move_on_after(10): # 10 second timeout
channel = await self.channel_factory()
try:
controller = jumpstarter_pb2_grpc.ControllerServiceStub(channel)
await controller.Unregister(
jumpstarter_pb2.UnregisterRequest(
reason="Exporter shutdown",
)
)
logger.info("Controller unregistration completed successfully")
finally:
with CancelScope(shield=True):
await channel.close()
except Exception as e:
logger.error("Error during controller unregistration: %s", e, exc_info=True)

except Exception as e:
logger.error("Error during exporter cleanup: %s", e, exc_info=True)
# Don't re-raise to avoid masking the original exception
logger.info("Exporter is exiting")

async def __handle(self, path, endpoint, token, tls_config, grpc_options):
try:
Expand Down