]> git.kaiwu.me - haproxy.git/commitdiff
MINOR: cli: implement wait srv-unknown
authorAmaury Denoyelle <adenoyelle@haproxy.com>
Mon, 21 Sep 2026 12:04:20 +0000 (14:04 +0200)
committerAmaury Denoyelle <adenoyelle@haproxy.com>
Wed, 14 Oct 2026 09:33:40 +0000 (11:33 +0200)
Define a new CLI wait condition named "srv-unknown".

This will report if the server name is currently not used by an instance
in a specific backend. An error is immediately reported if a matching
instance is found, unless it is flagged for background deletion.

Typically, this is useful after CLI "purge server" to detect the
deletion completion and before creating a new instance via "add server".

doc/management.txt
include/haproxy/cli-t.h
src/cli.c

index 7d41abd68021ad3e43690f7e6fdb4807348619bf..fc3270bb0aef9cb3c149d5b086a38c7de1078ff6 100644 (file)
@@ -4756,6 +4756,12 @@ wait { -h | <delay> } [<condition> [<args>...]]
     everything is OK before the delay, a success is returned and the operation
     is terminated.
 
+  - srv-unknown <proxy>/<server> : this will wait for the specified server name
+    to be available for a new instance to be created. This will fail if the
+    server already exists, unless if it is flagged for background deletion, in
+    which case a success will be returned if the deletion is completed before
+    the delay.
+
   The default unit for the delay is milliseconds, though other units are
   accepted if suffixed with the usual timer units (us, ms, s, m, h, d). When
   used with the 'socat' utility, do not forget to extend socat's close timeout
index ddbcd02ccb3ef1da09f39928b661c8845f6fa0b5..42bc6ce09725d180589038d637501af4aeecf7e5 100644 (file)
@@ -102,6 +102,7 @@ enum cli_wait_err {
 enum cli_wait_cond {
        CLI_WAIT_COND_NONE,      // no condition to wait on
        CLI_WAIT_COND_SRV_UNUSED,// wait for server to become unused
+       CLI_WAIT_COND_SRV_UNKNWN,// wait for server name to be available
        CLI_WAIT_COND_BE_UNUSED, // wait for backend to become unused
 };
 
index a2fe4c35b8a49a676a8d6784767f42670511271e..f61c7d50672090e7f96aed410b902b2c284415f0 100644 (file)
--- a/src/cli.c
+++ b/src/cli.c
@@ -2467,6 +2467,9 @@ static int cli_parse_wait(char **args, char *payload, struct appctx *appctx, voi
        if (strcmp(args[2], "srv-removable") == 0) {
                ctx->cond = CLI_WAIT_COND_SRV_UNUSED;
        }
+       else if (strcmp(args[2], "srv-unknown") == 0) {
+               ctx->cond = CLI_WAIT_COND_SRV_UNKNWN;
+       }
        else if (strcmp(args[2], "be-removable") == 0) {
                ctx->cond = CLI_WAIT_COND_BE_UNUSED;
        }
@@ -2480,6 +2483,7 @@ static int cli_parse_wait(char **args, char *payload, struct appctx *appctx, voi
                        "    duration. Supported conditions are:\n"
                        "    - <none> : by default, just sleep for the specified duration.\n"
                        "    - srv-removable <px>/<sv> : wait for this server to become removable.\n"
+                       "    - srv-unknown <px>/<sv> : wait for this server name to be available.\n"
                        "    - be-removable <px> : wait for this backend to become removable.\n"
                        "";
 
@@ -2490,7 +2494,8 @@ static int cli_parse_wait(char **args, char *payload, struct appctx *appctx, voi
        }
 
        switch (ctx->cond) {
-       case CLI_WAIT_COND_SRV_UNUSED: {
+       case CLI_WAIT_COND_SRV_UNUSED:
+       case CLI_WAIT_COND_SRV_UNKNWN: {
                const char *bename, *svname;
 
                if (!*args[3])
@@ -2570,6 +2575,24 @@ static int cli_io_handler_wait(struct appctx *appctx)
                }
                /* let's check the timer */
        }
+       else if (ctx->cond == CLI_WAIT_COND_SRV_UNKNWN) {
+               struct proxy *px;
+               struct server *srv;
+
+               px = proxy_be_by_name(ctx->args[0]);
+               srv = px ? server_find(px, ctx->args[1]) : NULL;
+               if (!px || !srv) {
+                       /* immediate success */
+                       ctx->error = CLI_WAIT_ERR_DONE;
+                       return 1;
+               }
+               else if (!(srv->flags & SRV_F_TO_PURGE)) {
+                       /* unrecoverable failure */
+                       ctx->error = CLI_WAIT_ERR_FAIL;
+                       ctx->msg = "Server not scheduled for purge.\n";
+                       return 1;
+               }
+       }
 
        /* and here we recalculate the new wait time or abort */
        left  = tick_remain(now_ms, ctx->deadline);