]> git.ipfire.org Git - thirdparty/haproxy.git/commitdiff
MINOR: proxy: parse mode on dynamic backend creation
authorAmaury Denoyelle <adenoyelle@haproxy.com>
Mon, 12 Jan 2026 14:25:52 +0000 (15:25 +0100)
committerAmaury Denoyelle <adenoyelle@haproxy.com>
Fri, 6 Feb 2026 16:27:50 +0000 (17:27 +0100)
Add an optional "mode" argument to "add backend" CLI command. This
argument allows to specify if the backend is in TCP or HTTP mode.

By default, it is mandatory, unless the inherited default proxy already
explicitely specifies the mode. To differentiate if TCP mode is implicit
or explicit, a new proxy flag PR_FL_DEF_EXPLICIT_MODE is defined. It is
set for every defaults instances which explicitely defined their mode.

doc/management.txt
include/haproxy/proxy-t.h
src/cfgparse-listen.c
src/proxy.c

index b07f287baa7909614b32ad0a779271a92197b5cb..43eed45076a60387588aeda29d8e4b6b6a75e38b 100644 (file)
@@ -1725,14 +1725,17 @@ add acl [@<ver>] <acl> <pattern>
   This command cannot be used if the reference <acl> is a name also used with
   a map. In this case, the "add map" command must be used instead.
 
-add backend <name> from <defproxy> [ EXPERIMENTAL ]
+add backend <name> from <defproxy> [mode <mode>] [ EXPERIMENTAL ]
   Instantiate a new backend proxy with the name <name>.
 
   Only TCP or HTTP proxies can be created. All of the settings are inherited
-  from <defproxy> default proxy instance. Servers can be added via the command
-  "add server". The backend is initialized in the unpublished state. Once
-  considered ready for traffic, use "publish backend" to expose the newly
-  created instance.
+  from <defproxy> default proxy instance. By default, it is mandatory to
+  specify the backend mode via the argument of the same name, unless <defproxy>
+  already defines it explicitely.
+
+  Servers can be added via the command "add server". The backend is initialized
+  in the unpublished state. Once considered ready for traffic, use "publish
+  backend" to expose the newly created instance.
 
   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
index 4f4b6c45d083483bbd139cb64cbbdeb4cd177eb3..20c359126e894986599571897db4365dea20c10c 100644 (file)
@@ -242,7 +242,7 @@ enum PR_SRV_STATE_FILE {
 /* Proxy flags */
 #define PR_FL_DISABLED           0x01  /* The proxy was disabled in the configuration (not at runtime) */
 #define PR_FL_STOPPED            0x02  /* The proxy was stopped */
-/* 0x04 unused */
+#define PR_FL_DEF_EXPLICIT_MODE  0x04  /* Proxy mode is explicitely defined - only used for defaults instance */
 #define PR_FL_EXPLICIT_REF       0x08  /* The default proxy is explicitly referenced by another proxy */
 #define PR_FL_IMPLICIT_REF       0x10  /* The default proxy is implicitly referenced by another proxy */
 #define PR_FL_PAUSED             0x20  /* The proxy was paused at run time (reversible) */
index 3c27a638e620f3f781be71e87482390ca9f06008..9a680ef09bfd2ab43720572a83c53ebec1483067 100644 (file)
@@ -657,6 +657,8 @@ int cfg_parse_listen(const char *file, int linenum, char **args, int kwm)
                }
 
                curproxy->mode = mode;
+               if (curproxy->cap & PR_CAP_DEF)
+                       curproxy->flags |= PR_FL_DEF_EXPLICIT_MODE;
        }
        else if (strcmp(args[0], "id") == 0) {
                struct proxy *conflict;
index 3d9f9440ba3291c6760b6bacfcf1665cd2adc939..43651b51570b18c94a3c309d2115d969e1b7594e 100644 (file)
@@ -4789,6 +4789,7 @@ static int cli_parse_add_backend(char **args, char *payload, struct appctx *appc
        struct proxy *px, *defpx;
        const char *be_name, *def_name, *err;
        char *msg = NULL;
+       enum pr_mode mode = 0;
 
        usermsgs_clr("CLI");
 
@@ -4813,11 +4814,39 @@ static int cli_parse_add_backend(char **args, char *payload, struct appctx *appc
                return 1;
        }
 
+       /* Parse optional arguments */
+       args += 2;
+       while (*args[1]) {
+               /* "mode" */
+               if (*args[2] && !mode && strcmp(args[1], "mode") == 0) {
+                       mode = str_to_proxy_mode(args[2]);
+                       if (mode == PR_MODES) {
+                               cli_err(appctx, "Unknown proxy mode.\n");
+                               return 1;
+                       }
+                       if (mode != PR_MODE_TCP && mode != PR_MODE_HTTP) {
+                               cli_err(appctx, "Dynamic backends are compatible with only TCP or HTTP mode.\n");
+                               return 1;
+                       }
+               }
+               /* unknown, malformed or duplicate argument */
+               else {
+                       cli_err(appctx, "Usage: add backend <name> from <defproxy> [mode <px_mode>].\n");
+                       return 1;
+               }
+
+               args += 2;
+       }
+
        defpx = proxy_find_by_name(def_name, PR_CAP_DEF, 0);
        if (!defpx) {
                cli_dynerr(appctx, memprintf(&msg, "Cannot find default proxy '%s'.\n", def_name));
                return 1;
        }
+       if (!(defpx->flags & PR_FL_DEF_EXPLICIT_MODE) && !mode) {
+               cli_dynerr(appctx, memprintf(&msg, "Mode is required as '%s' default proxy does not explicitely defines it.\n", def_name));
+               return 1;
+       }
 
        thread_isolate();