Update service table schema

This commit is contained in:
Duc Trung Le
2023-03-08 17:24:36 +01:00
committed by Duc Trung LE
parent d251b705e8
commit 95781880c5
4 changed files with 87 additions and 4 deletions

View File

@@ -14,6 +14,20 @@ depends_on = None
import sqlalchemy as sa import sqlalchemy as sa
from alembic import op from alembic import op
from jupyterhub.orm import JSONDict, JSONList
COL_DATA = [
{'name': 'url', 'type': sa.Unicode(length=2047)},
{'name': 'oauth_client_allowed_scopes', 'type': JSONDict()},
{'name': 'info', 'type': JSONDict()},
{'name': 'display', 'type': sa.Boolean},
{'name': 'oauth_no_confirm', 'type': sa.Boolean},
{'name': 'command', 'type': JSONList()},
{'name': 'cwd', 'type': sa.Unicode(length=2047)},
{'name': 'environment', 'type': JSONDict()},
{'name': 'user', 'type': sa.Unicode(255)},
]
def upgrade(): def upgrade():
engine = op.get_bind().engine engine = op.get_bind().engine
@@ -24,7 +38,14 @@ def upgrade():
sa.Column('from_config', sa.Boolean, nullable=True, default=True), sa.Column('from_config', sa.Boolean, nullable=True, default=True),
) )
op.execute('UPDATE services SET from_config = true') op.execute('UPDATE services SET from_config = true')
for item in COL_DATA:
op.add_column(
'services',
sa.Column(item['name'], item['type'], nullable=True),
)
def downgrade(): def downgrade():
op.drop_column('services', sa.Column('from_config')) op.drop_column('services', sa.Column('from_config'))
for item in COL_DATA:
op.drop_column('services', sa.Column(item['name']))

View File

@@ -80,7 +80,7 @@ class ServiceAPIHandler(APIHandler):
raise web.HTTPError(400, "Invalid service data") raise web.HTTPError(400, "Invalid service data")
data['name'] = service_name data['name'] = service_name
new_service = self.add_service(data) new_service = await self.add_service(data)
self.write(json.dumps(self.service_model(new_service))) self.write(json.dumps(self.service_model(new_service)))
self.set_status(201) self.set_status(201)

View File

@@ -3238,6 +3238,48 @@ class JupyterHub(Application):
if self._check_services_health_callback is not None: if self._check_services_health_callback is not None:
self._check_services_health_callback.stop() self._check_services_health_callback.stop()
async def _start_service(self, service_name, service, ssl_context):
for service_name, service in self._service_map.items():
msg = f'{service_name} at {service.url}' if service.url else service_name
if service.managed:
self.log.info("Starting managed service %s", msg)
try:
await service.start()
except Exception as e:
self.log.critical(
"Failed to start service %s", service_name, exc_info=True
)
self.exit(1)
else:
self.log.info("Adding external service %s", msg)
if service.url:
tries = 10 if service.managed else 1
for i in range(tries):
try:
await Server.from_orm(service.orm.server).wait_up(
http=True, timeout=1, ssl_context=ssl_context
)
except AnyTimeoutError:
if service.managed:
status = await service.spawner.poll()
if status is not None:
self.log.error(
"Service %s exited with status %s",
service_name,
status,
)
break
else:
break
else:
self.log.error(
"Cannot connect to %s service %s at %s. Is it running?",
service.kind,
service_name,
service.url,
)
async def start(self): async def start(self):
"""Start the whole thing""" """Start the whole thing"""
self.io_loop = loop = IOLoop.current() self.io_loop = loop = IOLoop.current()
@@ -3326,9 +3368,9 @@ class JupyterHub(Application):
service_status = await self._start_service( service_status = await self._start_service(
service_name, service, ssl_context service_name, service, ssl_context
) )
if not service_status: # if not service_status:
# Stop the application if a service failed to start. # # Stop the application if a service failed to start.
self.exit(1) # self.exit(1)
await self.proxy.check_routes(self.users, self._service_map) await self.proxy.check_routes(self.users, self._service_map)

View File

@@ -394,6 +394,26 @@ class Service(Base):
'Role', secondary='service_role_map', back_populates='services' 'Role', secondary='service_role_map', back_populates='services'
) )
url = Column(Unicode(2047), nullable=True)
oauth_client_allowed_scopes = Column(
JSONList, nullable=True, default=[]
) # List of string
info = Column(JSONDict, nullable=True, default={}) # Dict
display = Column(Boolean, default=True, nullable=True)
oauth_no_confirm = Column(Boolean, default=False, nullable=True)
command = Column(JSONList, nullable=True, default=[]) # List of string
cwd = Column(Unicode, nullable=True)
environment = Column(JSONDict, nullable=True, default={}) # Dict
user = Column(Unicode, nullable=True)
api_tokens = relationship( api_tokens = relationship(
"APIToken", back_populates="service", cascade="all, delete-orphan" "APIToken", back_populates="service", cascade="all, delete-orphan"
) )