11#!/usr/bin/env python
22"""Utilities for running singlestoredb-dev-image."""
3+ from __future__ import annotations
4+
35import atexit
46import os
57import platform
68import secrets
9+ import time
710import urllib .parse
811from types import TracebackType
912from typing import Any
1417
1518import docker
1619
17- from . import connect
18- from .connection import Connection
20+ from .. import connect
21+ from .. connection import Connection
1922
2023try :
2124 import pymongo
@@ -132,20 +135,38 @@ def __init__(
132135 for k , v in self .global_vars .items ():
133136 env ['SINGLESTORE_SET_GLOBAL_' + k .upper ()] = str (v )
134137
138+ self ._saved_server_urls : Dict [str , Optional [str ]] = {}
139+
135140 docker_client = docker .from_env ()
141+ self .container = docker_client .containers .run (image , ** kwargs )
142+ atexit .register (self .stop )
136143
137- self .container = docker_client .containers .run (
138- image ,
139- environmen = env ,
140- ports = ports ,
141- detach = True ,
142- ** kwargs ,
143- )
144+ if not self ._wait_on_ready ():
145+ raise RuntimeError ('server did not come up properly' )
144146
145- atexit .register (self .stop )
147+ self ._set_server_urls ()
148+
149+ def _set_server_urls (self ) -> None :
150+ self ._saved_server_urls ['DATABASE_URL' ] = os .environ .get ('DATABASE_URL' )
151+ os .environ ['DATABASE_URL' ] = self .connection_url
152+
153+ def _restore_server_urls (self ) -> None :
154+ for k , v in self ._saved_server_urls .items ():
155+ if v is None :
156+ del os .environ [k ]
157+ else :
158+ os .environ [k ] = v
159+
160+ def _wait_on_ready (self ) -> bool :
161+ for i in range (20 ):
162+ for line in self .logs ():
163+ if 'INFO: ' in line :
164+ return True
165+ time .sleep (3 )
166+ return False
146167
147168 def logs (self ) -> List [str ]:
148- return self .container .logs ().encode ('utf8' ).split ('\n ' )
169+ return self .container .logs ().decode ('utf8' ).split ('\n ' )
149170
150171 @property
151172 def connection_url (self ) -> str :
@@ -176,7 +197,7 @@ def kai_url(self) -> Optional[str]:
176197 return f'mongodb://root:{ root_password } @' + \
177198 f'localhost:{ self .kai_port } /?authMechanism=PLAIN&loadBalanced=true'
178199
179- def connect_kai (self ) -> pymongo .MongoClient :
200+ def connect_kai (self ) -> ' pymongo.MongoClient' :
180201 if not self .kai_enabled :
181202 raise RuntimeError ('kai is not enabled' )
182203 if not has_pymongo :
@@ -192,8 +213,8 @@ def connect_studio(self) -> None:
192213 import webbrowser
193214 webbrowser .open (self .studio_url )
194215
195- def __enter__ (self ) -> None :
196- pass
216+ def __enter__ (self ) -> SingleStoreDB :
217+ return self
197218
198219 def __exit__ (
199220 self ,
@@ -206,5 +227,42 @@ def __exit__(
206227
207228 def stop (self ) -> None :
208229 if self .container is not None :
230+ self ._restore_server_urls ()
209231 self .container .stop ()
210232 self .container = None
233+
234+
235+ def start (
236+ name : Optional [str ] = None ,
237+ root_password : Optional [str ] = None ,
238+ license : Optional [str ] = None ,
239+ enable_kai : bool = False ,
240+ server_port : int = 3306 ,
241+ studio_port : int = 8080 ,
242+ data_api_port : int = 9000 ,
243+ kai_port : int = 27017 ,
244+ hostname : Optional [str ] = None ,
245+ data_dir : Optional [str ] = None ,
246+ logs_dir : Optional [str ] = None ,
247+ server_dir : Optional [str ] = None ,
248+ global_vars : Optional [Dict [str , Any ]] = None ,
249+ init_sql : Optional [str ] = None ,
250+ image : str = 'ghcr.io/singlestore-labs/singlestoredb-dev:latest' ,
251+ ) -> SingleStoreDB :
252+ return SingleStoreDB (
253+ name = name ,
254+ root_password = root_password ,
255+ license = license ,
256+ enable_kai = enable_kai ,
257+ server_port = server_port ,
258+ studio_port = studio_port ,
259+ data_api_port = data_api_port ,
260+ kai_port = kai_port ,
261+ hostname = hostname ,
262+ data_dir = data_dir ,
263+ logs_dir = logs_dir ,
264+ server_dir = server_dir ,
265+ global_vars = global_vars ,
266+ init_sql = init_sql ,
267+ image = image ,
268+ )
0 commit comments