@@ -201,6 +201,17 @@ pub async fn list_interrupted_candidates(
201201 Ok ( deserialize_rows ( rows) )
202202}
203203
204+ pub async fn list_active_for_instance (
205+ instance_id : & str ,
206+ app_state : & State ,
207+ ) -> crate :: Result < Vec < InstallJobRecord > > {
208+ Ok ( list_interrupted_candidates ( app_state)
209+ . await ?
210+ . into_iter ( )
211+ . filter ( |job| job. instance_id . as_deref ( ) == Some ( instance_id) )
212+ . collect ( ) )
213+ }
214+
204215pub async fn update_state (
205216 id : Uuid ,
206217 state : & InstallJobState ,
@@ -212,20 +223,30 @@ pub async fn update_state(
212223 let id_value = id. to_string ( ) ;
213224 let modified = now. timestamp ( ) ;
214225
215- sqlx:: query! (
226+ let result = sqlx:: query (
216227 "
217228 UPDATE install_jobs
218- SET instance_id = ?, state = ?, modified = ?
219- WHERE id = ?
229+ SET
230+ instance_id = (SELECT id FROM instances WHERE id = ?),
231+ state = ?,
232+ modified = ?
233+ WHERE id = ? AND status IN ('queued', 'running')
220234 " ,
221- instance_id,
222- json,
223- modified,
224- id_value,
225235 )
236+ . bind ( instance_id)
237+ . bind ( json)
238+ . bind ( modified)
239+ . bind ( id_value)
226240 . execute ( & app_state. pool )
227241 . await ?;
228242
243+ if result. rows_affected ( ) == 0 {
244+ return Err ( crate :: ErrorKind :: InputError ( format ! (
245+ "Install job {id} is no longer active"
246+ ) )
247+ . into ( ) ) ;
248+ }
249+
229250 get_required ( id, app_state) . await
230251}
231252
@@ -319,7 +340,12 @@ pub async fn finish_active(
319340 let result = sqlx:: query (
320341 "
321342 UPDATE install_jobs
322- SET instance_id = ?, status = ?, state = ?, modified = ?, finished = ?
343+ SET
344+ instance_id = (SELECT id FROM instances WHERE id = ?),
345+ status = ?,
346+ state = ?,
347+ modified = ?,
348+ finished = ?
323349 WHERE id = ? AND status IN ('queued', 'running')
324350 " ,
325351 )
@@ -356,19 +382,24 @@ pub async fn complete_success(
356382 let mut transaction = app_state. pool . begin ( ) . await ?;
357383
358384 let job_result = sqlx:: query (
359- "
385+ "
360386 UPDATE install_jobs
361- SET instance_id = ?, status = 'succeeded', state = ?, modified = ?, finished = ?
387+ SET
388+ instance_id = (SELECT id FROM instances WHERE id = ?),
389+ status = 'succeeded',
390+ state = ?,
391+ modified = ?,
392+ finished = ?
362393 WHERE id = ? AND status = 'running'
363394 " ,
364- )
365- . bind ( & instance_id)
366- . bind ( json)
367- . bind ( now)
368- . bind ( now)
369- . bind ( id_value)
370- . execute ( & mut * transaction)
371- . await ?;
395+ )
396+ . bind ( & instance_id)
397+ . bind ( json)
398+ . bind ( now)
399+ . bind ( now)
400+ . bind ( id_value)
401+ . execute ( & mut * transaction)
402+ . await ?;
372403
373404 if job_result. rows_affected ( ) == 0 {
374405 transaction. rollback ( ) . await ?;
0 commit comments