@@ -78,7 +78,7 @@ async fn main() -> anyhow::Result<()> {
78
78
79
79
// Create the external shutdown signal (used to shut down Ground
80
80
// Control on UNIX signals).
81
- let ( shutdown_sender, shutdown_receiver) = mpsc:: unbounded_channel ( ) ;
81
+ let ( shutdown_sender, mut shutdown_receiver) = mpsc:: unbounded_channel ( ) ;
82
82
83
83
let sigint_shutdown_sender = shutdown_sender. clone ( ) ;
84
84
tokio:: spawn ( async move {
@@ -98,6 +98,25 @@ async fn main() -> anyhow::Result<()> {
98
98
let _ = sigterm_shutdown_sender. send ( ( ) ) ;
99
99
} ) ;
100
100
101
- // Run the Ground Control specification.
102
- groundcontrol:: run ( config, shutdown_receiver) . await
101
+ // Run the Ground Control specification, *unless* we are in
102
+ // break-glass mode, in which case we freeze startup and just wait
103
+ // for the shutdown signal. (this gives the admin a chance to SSH
104
+ // into a machine that is in a startup-crash loop, perhaps due to an
105
+ // issue on an attached, persistent storage volume)
106
+ if std:: env:: var_os ( "BREAK_GLASS" ) . is_none ( ) {
107
+ groundcontrol:: run ( config, shutdown_receiver) . await
108
+ } else {
109
+ tracing:: info!( "BREAK GLASS MODE: no processes will be started" ) ;
110
+
111
+ shutdown_receiver
112
+ . recv ( )
113
+ . await
114
+ . expect ( "All shutdown senders closed without sending a shutdown signal." ) ;
115
+
116
+ tracing:: info!(
117
+ "Shutdown signal triggered (make sure to clear the `BREAK_GLASS` environment variable)"
118
+ ) ;
119
+
120
+ Ok ( ( ) )
121
+ }
103
122
}
0 commit comments