@@ -349,8 +349,33 @@ Configuration
349349 ./cloud-sql-proxy wait --max 10s
350350`
351351
352+ var shutdownHelp = `
353+ Shutting Down the Proxy
354+
355+ The shutdown command signals a running Proxy process to gracefully shut
356+ down. This is useful for scripting and for Kubernetes environments.
357+
358+ The shutdown command requires that the Proxy be started in another process
359+ with the admin server enabled. For example:
360+
361+ ./cloud-sql-proxy <INSTANCE_CONNECTION_NAME> --quitquitquit
362+
363+ Invoke the shutdown command like this:
364+
365+ # signals another Proxy process to shut down
366+ ./cloud-sql-proxy shutdown
367+
368+ Configuration
369+
370+ If the running Proxy is configured with a non-default admin port, the
371+ shutdown command must also be told to use the same custom value:
372+
373+ ./cloud-sql-proxy shutdown --admin-port 9192
374+ `
375+
352376const (
353377 waitMaxFlag = "max"
378+ adminPortFlag = "admin-port"
354379 httpAddressFlag = "http-address"
355380 httpPortFlag = "http-port"
356381)
@@ -384,6 +409,29 @@ func runWaitCmd(c *cobra.Command, _ []string) error {
384409 }
385410}
386411
412+ func runShutdownCmd (c * cobra.Command , _ []string ) error {
413+ p , _ := c .Flags ().GetString (adminPortFlag )
414+ addr := fmt .Sprintf ("http://127.0.0.1:%v/quitquitquit" , p )
415+ c .SilenceUsage = true
416+
417+ req , err := http .NewRequestWithContext (c .Context (), "POST" , addr , nil )
418+ if err != nil {
419+ return fmt .Errorf ("failed to create shutdown request: %w" , err )
420+ }
421+
422+ resp , err := http .DefaultClient .Do (req )
423+ if err != nil {
424+ return fmt .Errorf ("failed to send shutdown request: %w" , err )
425+ }
426+ defer resp .Body .Close ()
427+
428+ if resp .StatusCode != http .StatusOK {
429+ return fmt .Errorf ("shutdown request failed: status code %v, %v" , resp .StatusCode , resp .Status )
430+ }
431+
432+ return nil
433+ }
434+
387435const envPrefix = "CSQL_PROXY"
388436
389437// NewCommand returns a Command object representing an invocation of the proxy.
@@ -419,6 +467,20 @@ func NewCommand(opts ...Option) *Command {
419467 )
420468 rootCmd .AddCommand (waitCmd )
421469
470+ var shutdownCmd = & cobra.Command {
471+ Use : "shutdown" ,
472+ Short : "Signal a running Proxy process to shut down" ,
473+ Long : shutdownHelp ,
474+ RunE : runShutdownCmd ,
475+ }
476+ shutdownFlags := shutdownCmd .Flags ()
477+ shutdownFlags .String (
478+ adminPortFlag ,
479+ "9091" ,
480+ "port for the admin server" ,
481+ )
482+ rootCmd .AddCommand (shutdownCmd )
483+
422484 rootCmd .Args = func (_ * cobra.Command , args []string ) error {
423485 // Load the configuration file before running the command. This should
424486 // ensure that the configuration is loaded in the correct order:
@@ -490,7 +552,7 @@ the Proxy will then pick-up automatically.`)
490552 "Enable pprof on the localhost admin server" )
491553 localFlags .BoolVar (& c .conf .QuitQuitQuit , "quitquitquit" , false ,
492554 "Enable quitquitquit endpoint on the localhost admin server" )
493- localFlags .StringVar (& c .conf .AdminPort , "admin-port" , "9091" ,
555+ localFlags .StringVar (& c .conf .AdminPort , adminPortFlag , "9091" ,
494556 "Port for localhost-only admin server" )
495557 localFlags .BoolVar (& c .conf .HealthCheck , "health-check" , false ,
496558 "Enables health check endpoints /startup, /liveness, and /readiness on localhost." )
0 commit comments