@@ -172,6 +172,7 @@ async function provisionMysqlDockerService(service: WorkspaceRecipeRuntimeServic
172172 const { stdout } = await dependencies . execute ( "docker" , [ "port" , container , "3306/tcp" ] , { signal, timeout : 10_000 } )
173173 const port = parseLoopbackPort ( stdout )
174174 await dependencies . waitForReady ( "127.0.0.1" , port , 30_000 , signal )
175+ await waitForMysqlDatabase ( container , engine , password , dependencies , 30_000 , signal )
175176 throwIfAborted ( signal )
176177 evidence . readiness = "ready"
177178 evidence . lifecycle = "provisioned"
@@ -186,6 +187,23 @@ async function provisionMysqlDockerService(service: WorkspaceRecipeRuntimeServic
186187 }
187188}
188189
190+ async function waitForMysqlDatabase ( container : string , engine : keyof typeof MYSQL_IMAGES , password : string , dependencies : RuntimeServiceDependencies , timeoutMs : number , signal ?: AbortSignal ) : Promise < void > {
191+ const deadline = Date . now ( ) + timeoutMs
192+ const client = engine === "mariadb" ? "mariadb" : "mysql"
193+ const args = [ "exec" , "--env" , "MYSQL_PWD" , container , client , "--protocol=TCP" , "--host=127.0.0.1" , "--user=runtime" , "--database=runtime" , "--execute=SELECT 1" ]
194+ while ( Date . now ( ) < deadline ) {
195+ throwIfAborted ( signal )
196+ try {
197+ await dependencies . execute ( "docker" , args , { env : { ...process . env , MYSQL_PWD : password } , signal, timeout : 5_000 } )
198+ return
199+ } catch ( error ) {
200+ if ( signal ?. aborted ) throw error
201+ await abortableDelay ( 100 , signal )
202+ }
203+ }
204+ throw new Error ( `MySQL database readiness timed out after ${ timeoutMs } ms` )
205+ }
206+
189207async function ensureDockerImage ( image : string , dependencies : RuntimeServiceDependencies , signal ?: AbortSignal ) : Promise < void > {
190208 try {
191209 await dependencies . execute ( "docker" , [ "image" , "inspect" , image ] , { signal, timeout : 10_000 } )
0 commit comments