MINOR: cli: implement wait on be-removable

Implement be-removable argument to CLI wait. This is implemented via
be_check_for_deletion() invokation, also used by "del backend" handler.

The objective is to test whether a backend instance can be removed. If
this is not the case, the command may returns immediately if the target
proxy is incompatible with dynamic removal or if a user action is
required. Else, the command will wait until the temporary restriction is
lifted.
This commit is contained in:
Amaury Denoyelle 2026-02-18 14:00:08 +01:00
parent 5ddfbd4b03
commit 98c8c5e16e
3 changed files with 31 additions and 4 deletions

View File

@ -2129,7 +2129,8 @@ del backend <name>
This operation is only possible for TCP or HTTP proxies. To succeed, the
backend instance must have been first unpublished. Also, all of its servers
must first be removed (via "del server" CLI).
must first be removed (via "del server" CLI). Finally, no stream must still
be attached to the backend instance.
There is additional restrictions which prevent backend removal. First, a
backend cannot be removed if it is explicitely referenced by config elements,
@ -2139,6 +2140,10 @@ del backend <name>
cannot be removed if there is a stick-table declared in it. Finally, it is
impossible for now to remove a backend if QUIC servers were present in it.
It can be useful to use "wait be-removable" prior to this command to check
for the aformentioned requisites. This also provides a methode to wait for
the final closure of the streams attached to the target backend.
This command is restricted and can only be issued on sockets configured for
level "admin". Moreover, this feature is still considered in development so it
also requires experimental mode (see "experimental-mode on").
@ -4545,6 +4550,13 @@ wait { -h | <delay> } [<condition> [<args>...]]
specified condition to be satisfied, to unrecoverably fail, or to remain
unsatisfied for the whole <delay> duration. The supported conditions are:
- be-removable <proxy> : this will wait for the specified proxy backend to be
removable by the "del backend" command. Some conditions will never be
accepted (e.g. backend not yet unpublished or with servers in it) and will
cause the report of a specific error message indicating what condition is
not met. If everything is OK before the delay, a success is returned and
the operation is terminated.
- 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

View File

@ -100,6 +100,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_BE_UNUSED, // wait for backend to become unused
};
struct cli_wait_ctx {

View File

@ -2120,6 +2120,14 @@ static int cli_parse_wait(char **args, char *payload, struct appctx *appctx, voi
ctx->args[1] = ist0(sv_name);
ctx->cond = CLI_WAIT_COND_SRV_UNUSED;
}
else if (strcmp(args[2], "be-removable") == 0) {
if (!*args[3])
return cli_err(appctx, "Missing backend name.\n");
ctx->args[0] = strdup(args[3]);
if (!ctx->args[0])
return cli_err(appctx, "Out of memory trying to clone the backend name.\n");
ctx->cond = CLI_WAIT_COND_BE_UNUSED;
}
else if (*args[2]) {
/* show the command's help either upon request (-h) or error */
err = "Usage: wait {-h|<duration>} [condition [args...]]\n"
@ -2165,9 +2173,15 @@ static int cli_io_handler_wait(struct appctx *appctx)
/* here we should evaluate our waiting conditions, if any */
if (ctx->cond == CLI_WAIT_COND_SRV_UNUSED) {
/* check if the server in args[0]/args[1] can be released now */
ret = srv_check_for_deletion(ctx->args[0], ctx->args[1], NULL, NULL, &ctx->msg);
if (ctx->cond == CLI_WAIT_COND_SRV_UNUSED ||
ctx->cond == CLI_WAIT_COND_BE_UNUSED) {
if (ctx->cond == CLI_WAIT_COND_SRV_UNUSED) {
/* check if the server in args[0]/args[1] can be released now */
ret = srv_check_for_deletion(ctx->args[0], ctx->args[1], NULL, NULL, &ctx->msg);
}
else {
ret = be_check_for_deletion(ctx->args[0], NULL, &ctx->msg);
}
if (ret < 0) {
/* unrecoverable failure */