@@ -6,12 +6,12 @@ use futures::{
66use serde:: Deserialize ;
77use snafu:: prelude:: * ;
88use std:: {
9- collections:: HashMap ,
9+ collections:: { BTreeSet , HashMap } ,
1010 fmt, mem, ops,
1111 process:: Stdio ,
1212 sync:: {
1313 atomic:: { AtomicU64 , Ordering } ,
14- Arc ,
14+ Arc , LazyLock , Mutex ,
1515 } ,
1616 time:: Duration ,
1717} ;
@@ -2532,11 +2532,23 @@ pub enum CommanderError {
25322532 WorkerOperationFailed { source : SerializedError2 } ,
25332533}
25342534
2535+ pub static TRACKED_CONTAINERS : LazyLock < Mutex < BTreeSet < Arc < str > > > > =
2536+ LazyLock :: new ( Default :: default) ;
2537+
25352538#[ derive( Debug ) ]
25362539pub struct TerminateContainer ( Option < ( String , Command ) > ) ;
25372540
25382541impl TerminateContainer {
25392542 pub fn new ( name : String , command : Command ) -> Self {
2543+ let was_inserted = TRACKED_CONTAINERS
2544+ . lock ( )
2545+ . unwrap_or_else ( |e| e. into_inner ( ) )
2546+ . insert ( name. clone ( ) . into ( ) ) ;
2547+
2548+ if !was_inserted {
2549+ error ! ( %name, "This container was already tracked; duplicates are bad logic" ) ;
2550+ }
2551+
25402552 Self ( Some ( ( name, command) ) )
25412553 }
25422554
@@ -2548,6 +2560,7 @@ impl TerminateContainer {
25482560 use terminate_container_error:: * ;
25492561
25502562 if let Some ( ( name, mut kill_child) ) = self . 0 . take ( ) {
2563+ Self :: stop_tracking ( & name) ;
25512564 let o = kill_child
25522565 . output ( )
25532566 . await
@@ -2558,6 +2571,16 @@ impl TerminateContainer {
25582571 Ok ( ( ) )
25592572 }
25602573
2574+ fn stop_tracking ( name : & str ) {
2575+ let was_tracked = TRACKED_CONTAINERS
2576+ . lock ( )
2577+ . unwrap_or_else ( |e| e. into_inner ( ) )
2578+ . remove ( name) ;
2579+ if !was_tracked {
2580+ error ! ( %name, "Container was not in the tracking set" ) ;
2581+ }
2582+ }
2583+
25612584 fn report_failure ( name : String , s : std:: process:: Output ) {
25622585 // We generally don't care if the command itself succeeds or
25632586 // not; the container may already be dead! However, let's log
@@ -2570,6 +2593,9 @@ impl TerminateContainer {
25702593 let stdout = String :: from_utf8_lossy ( & s. stdout ) ;
25712594 let stderr = String :: from_utf8_lossy ( & s. stderr ) ;
25722595
2596+ let stdout = stdout. trim ( ) ;
2597+ let stderr = stderr. trim ( ) ;
2598+
25732599 error ! ( ?code, %stdout, %stderr, %name, "Killing the container failed" ) ;
25742600 }
25752601 }
@@ -2578,6 +2604,7 @@ impl TerminateContainer {
25782604impl Drop for TerminateContainer {
25792605 fn drop ( & mut self ) {
25802606 if let Some ( ( name, mut kill_child) ) = self . 0 . take ( ) {
2607+ Self :: stop_tracking ( & name) ;
25812608 match kill_child. as_std_mut ( ) . output ( ) {
25822609 Ok ( o) => Self :: report_failure ( name, o) ,
25832610 Err ( e) => error ! ( "Unable to kill container {name} while dropping: {e}" ) ,
0 commit comments