]> git.kaiwu.me - haproxy.git/commitdiff
MINOR: cli: implement wait be-unknown
authorAmaury Denoyelle <adenoyelle@haproxy.com>
Wed, 30 Sep 2026 13:39:56 +0000 (15:39 +0200)
committerAmaury Denoyelle <adenoyelle@haproxy.com>
Wed, 14 Oct 2026 09:33:41 +0000 (11:33 +0200)
Similar to srv-unknown, a new CLI wait condition "be-unknown" is added
to check if a name can be used for a new backend instance to create. A
failure is returned if a proxy already exists with this name, but it can
wait if this is a backend instance targeted for background deletion.

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

index 607ee027043357aae253ea46a72dad3bea421005..b9826cbd088e6a2c87eb6a26c30ed5707d6fd30b 100644 (file)
@@ -4761,6 +4761,12 @@ wait { -h | <delay> } [<condition> [<args>...]]
     not met. If everything is OK before the delay, a success is returned and
     the operation is terminated.
 
+  - be-unknown <proxy> : this will wait for the specified backend name to be
+    available for a new instance to be created. This will fail if a proxy with
+    this name already exists, unless if this is a backend flagged for
+    background deletion, in which case a success will be returned if the
+    deletion is completed before the delay.
+
   - srv-removable <proxy>/<server> : this will wait for the specified server to
     be removable by the "del server" command, i.e. be in maintenance and no
     longer have any connection on it (neither active or idle). Some conditions
index 42bc6ce09725d180589038d637501af4aeecf7e5..331e3ede7eef70979d6a84b13dbb0054697ab643 100644 (file)
@@ -104,6 +104,7 @@ enum cli_wait_cond {
        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
+       CLI_WAIT_COND_BE_UNKNWN, // wait for backend name to be available
 };
 
 struct cli_wait_ctx {
index 128643b4a044afdb0663e7b1376228dc53239793..463d5193b2c9913a93f4d99d3abf7c875e353cca 100644 (file)
--- a/src/cli.c
+++ b/src/cli.c
@@ -2473,6 +2473,9 @@ static int cli_parse_wait(char **args, char *payload, struct appctx *appctx, voi
        else if (strcmp(args[2], "be-removable") == 0) {
                ctx->cond = CLI_WAIT_COND_BE_UNUSED;
        }
+       else if (strcmp(args[2], "be-unknown") == 0) {
+               ctx->cond = CLI_WAIT_COND_BE_UNKNWN;
+       }
        else if (*args[2]) {
                /* show the command's help either upon request (-h) or error */
                err = "Usage: wait {-h|<duration>} [condition [args...]]\n"
@@ -2485,6 +2488,7 @@ static int cli_parse_wait(char **args, char *payload, struct appctx *appctx, voi
                        "    - 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"
+                       "    - be-unknown <px> : wait for this backend name to become available.\n"
                        "";
 
                if (strcmp(args[2], "-h") == 0)
@@ -2516,6 +2520,7 @@ static int cli_parse_wait(char **args, char *payload, struct appctx *appctx, voi
        }
 
        case CLI_WAIT_COND_BE_UNUSED:
+       case CLI_WAIT_COND_BE_UNKNWN:
                if (!*args[3])
                        return cli_err(appctx, "Missing backend name.\n");
                ctx->args[0] = strdup(args[3]);
@@ -2593,6 +2598,33 @@ static int cli_io_handler_wait(struct appctx *appctx)
                        return 1;
                }
        }
+       else if (ctx->cond == CLI_WAIT_COND_BE_UNKNWN) {
+               struct proxy *px;
+
+               if (proxy_find_by_name(ctx->args[0], PR_CAP_DEF, 0)) {
+                       ctx->error = CLI_WAIT_ERR_FAIL;
+                       ctx->msg = "Name already used by a default instance.\n";
+                       return 1;
+               }
+
+               px = proxy_find_by_name(ctx->args[0], PR_CAP_NONE, 0);
+               if (!px) {
+                       /* immediate success */
+                       ctx->error = CLI_WAIT_ERR_DONE;
+                       return 1;
+               }
+               else if (px->cap & PR_CAP_FE) {
+                       ctx->error = CLI_WAIT_ERR_FAIL;
+                       ctx->msg = "Name already used by a frontend/listen instance.\n";
+                       return 1;
+               }
+               else if (!(px->flags & PR_FL_TO_PURGE)) {
+                       /* unrecoverable failure */
+                       ctx->error = CLI_WAIT_ERR_FAIL;
+                       ctx->msg = "Backend not scheduled for purge.\n";
+                       return 1;
+               }
+       }
 
        /* and here we recalculate the new wait time or abort */
        left  = tick_remain(now_ms, ctx->deadline);