From 6418d3320f983977e2246e32babc1016065c3d55 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Sat, 12 Jul 2025 15:51:39 +0000 Subject: [PATCH] Implement stepdown command for rqlite shell Co-authored-by: otoolep <536312+otoolep@users.noreply.github.com> --- cmd/rqlite/main.go | 28 ++++++++++++++++++++++++++++ 1 file changed, 28 insertions(+) diff --git a/cmd/rqlite/main.go b/cmd/rqlite/main.go index 74d88e1b..c55930f5 100644 --- a/cmd/rqlite/main.go +++ b/cmd/rqlite/main.go @@ -73,6 +73,7 @@ func init() { `.schema Show CREATE statements for all tables`, `.snapshot Request a Raft snapshot and log truncation on connected node`, `.status Show status and diagnostic information for connected node`, + `.stepdown Instruct the cluster leader to stepdown and transfer leadership`, `.sysdump FILE Dump system diagnostics to FILE`, `.tables List names of tables`, `.timer on|off Turn query timings on or off`, @@ -254,6 +255,8 @@ func main() { break FOR_READ case ".SNAPSHOT": err = snapshot(client, argv) + case ".STEPDOWN": + err = stepdown(client, argv) case "SELECT", "PRAGMA": err = queryWithClient(ctx, client, timer, blobArray, consistency, line) default: @@ -375,6 +378,31 @@ func snapshot(client *httpcl.Client, argv *argT) error { return nil } +func stepdown(client *httpcl.Client, argv *argT) error { + url := fmt.Sprintf("%s://%s/leader", argv.Protocol, address6(argv)) + req, err := http.NewRequest("DELETE", url, nil) + if err != nil { + return err + } + if argv.Credentials != "" { + creds := strings.Split(argv.Credentials, ":") + if len(creds) != 2 { + return fmt.Errorf("invalid Basic Auth credentials format") + } + req.SetBasicAuth(creds[0], creds[1]) + } + + resp, err := client.Do(req) + if err != nil { + return err + } + defer resp.Body.Close() + if resp.StatusCode != http.StatusOK { + return fmt.Errorf("server responded with %s", resp.Status) + } + return nil +} + func sysdump(ctx *cli.Context, client *http.Client, filename string, argv *argT) error { _ = ctx nodes, err := getNodes(client, argv)