@@ -6,12 +6,12 @@ use futures::{
6
6
use serde:: Deserialize ;
7
7
use snafu:: prelude:: * ;
8
8
use std:: {
9
- collections:: HashMap ,
9
+ collections:: { BTreeSet , HashMap } ,
10
10
fmt, mem, ops,
11
11
process:: Stdio ,
12
12
sync:: {
13
13
atomic:: { AtomicU64 , Ordering } ,
14
- Arc ,
14
+ Arc , LazyLock , Mutex ,
15
15
} ,
16
16
time:: Duration ,
17
17
} ;
@@ -2532,11 +2532,23 @@ pub enum CommanderError {
2532
2532
WorkerOperationFailed { source : SerializedError2 } ,
2533
2533
}
2534
2534
2535
+ pub static TRACKED_CONTAINERS : LazyLock < Mutex < BTreeSet < Arc < str > > > > =
2536
+ LazyLock :: new ( Default :: default) ;
2537
+
2535
2538
#[ derive( Debug ) ]
2536
2539
pub struct TerminateContainer ( Option < ( String , Command ) > ) ;
2537
2540
2538
2541
impl TerminateContainer {
2539
2542
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
+
2540
2552
Self ( Some ( ( name, command) ) )
2541
2553
}
2542
2554
@@ -2548,6 +2560,7 @@ impl TerminateContainer {
2548
2560
use terminate_container_error:: * ;
2549
2561
2550
2562
if let Some ( ( name, mut kill_child) ) = self . 0 . take ( ) {
2563
+ Self :: stop_tracking ( & name) ;
2551
2564
let o = kill_child
2552
2565
. output ( )
2553
2566
. await
@@ -2558,6 +2571,16 @@ impl TerminateContainer {
2558
2571
Ok ( ( ) )
2559
2572
}
2560
2573
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
+
2561
2584
fn report_failure ( name : String , s : std:: process:: Output ) {
2562
2585
// We generally don't care if the command itself succeeds or
2563
2586
// not; the container may already be dead! However, let's log
@@ -2570,6 +2593,9 @@ impl TerminateContainer {
2570
2593
let stdout = String :: from_utf8_lossy ( & s. stdout ) ;
2571
2594
let stderr = String :: from_utf8_lossy ( & s. stderr ) ;
2572
2595
2596
+ let stdout = stdout. trim ( ) ;
2597
+ let stderr = stderr. trim ( ) ;
2598
+
2573
2599
error ! ( ?code, %stdout, %stderr, %name, "Killing the container failed" ) ;
2574
2600
}
2575
2601
}
@@ -2578,6 +2604,7 @@ impl TerminateContainer {
2578
2604
impl Drop for TerminateContainer {
2579
2605
fn drop ( & mut self ) {
2580
2606
if let Some ( ( name, mut kill_child) ) = self . 0 . take ( ) {
2607
+ Self :: stop_tracking ( & name) ;
2581
2608
match kill_child. as_std_mut ( ) . output ( ) {
2582
2609
Ok ( o) => Self :: report_failure ( name, o) ,
2583
2610
Err ( e) => error ! ( "Unable to kill container {name} while dropping: {e}" ) ,
0 commit comments