]> git.ipfire.org Git - thirdparty/haproxy.git/commitdiff
MINOR: proxy: implement unpublished backend keyword
authorAmaury Denoyelle <adenoyelle@haproxy.com>
Mon, 6 Jul 2026 13:51:41 +0000 (15:51 +0200)
committerAmaury Denoyelle <adenoyelle@haproxy.com>
Mon, 3 Aug 2026 14:52:09 +0000 (16:52 +0200)
Add a new "unpublished" proxy keyword. This allows to start a backend
instance in unpublished state. This can be reverted via "publish
backend" on the CLI.

This keyword is restricted to backend and listen sections.

This patch is a simple feature implementation, however it can be
considered as a must-have when using dynamic backends. As such, it
should be backported up to 3.4.

doc/configuration.txt
reg-tests/stream/test_content_switching.vtc
src/proxy.c

index 111e8e52f06aad45710f4eaa2ed0e7c24de8d39c..bcdd50c254e55305f054eaa31d385b1554319488 100644 (file)
@@ -6041,6 +6041,7 @@ Note: Some dangerous and not recommended directives are intentionnaly not
 acl                                       X (!)      X         X         X
 backlog                                   X          X         X         -
 balance                                   X          -         X         X
+be-unpublished                            -          -         X         X
 bind                                      -          X         X         -
 capture cookie                            -          X         X         -
 capture request header                    -          X         X         -
@@ -6642,6 +6643,26 @@ balance url_param <param> [check_post]
   See also : "cookie", "hash-type".
 
 
+be-unpublished
+  Instructs the backend to start in the unpublished state.
+
+  May be used in the following contexts: tcp, http, log
+
+  May be used in sections :   defaults | frontend | listen | backend
+                                  no   |    no    |   yes  |   yes
+
+  In effect, any use_backend and default_backend rules from another proxy which
+  reference the current proxy are ignored and the next content switching rules
+  are evaluated. This can be bypassed though via a "force-be-switch" rule.
+
+  This state is similar to the disabled one but with some differences. First,
+  an unpublished backend will still be fully initialized, including the server
+  health checks which remain active. Finally, a backend can be publicly exposed
+  via the command "publish backend" on the CLI. See the management manual.
+
+  See also : "force-be-switch"
+
+
 bind [<address>]:<port_range> [, ...] [param*]
 bind /<path> [, ...] [param*]
   Define one or several listening addresses and/or ports in a frontend.
@@ -7879,7 +7900,7 @@ force-be-switch { if | unless } <condition>
   May be used in sections:    defaults | frontend | listen | backend
                                  no    |   yes    |   yes  |   no
 
-  See also : "disabled"
+  See also : "be-unpublished", "disabled"
 
 
 filter <name> [param*]
index ef518690afeef4e7b04bfcfd9609b05a82a43bb0..a071ace88000757bafa2b1bef3608960a6558f65 100644 (file)
@@ -58,6 +58,10 @@ haproxy h1 -conf {
        backend be2
                http-request return status 200 hdr "x-be" %[be_name]
 
+       backend be_unpublished
+               be-unpublished
+               http-request return status 200 hdr "x-be" %[be_name]
+
        backend be_disabled
                disabled
                http-request return status 200 hdr "x-be" %[be_name]
@@ -93,6 +97,12 @@ client c2 -connect ${h1_fe2S_sock} {
        expect resp.status == 200
        expect resp.http.x-be == "be_default"
 
+       # Static rule on unpublished backend -> continue to next rule
+       txreq -hdr "x-target: be_unpublished"
+       rxresp
+       expect resp.status == 200
+       expect resp.http.x-be == "be"
+
        # Static rule on disabled backend -> continue to next rule
        txreq -hdr "x-target: be_disabled"
        rxresp
index 2de25245f2b6522db0e29ce5190209b13140170d..5d81c0918872260cfff1eb8f81464c007b137d64 100644 (file)
@@ -1228,6 +1228,29 @@ static int proxy_parse_tcpka_intvl(char **args, int section, struct proxy *proxy
 }
 #endif
 
+/* Parser for "be-unpublished" proxy keyword. */
+static int proxy_parse_be_unpublished(char **args, int section_type, struct proxy *curpx,
+                                      const struct proxy *defpx, const char *file, int line,
+                                      char **err)
+{
+       if (curpx->cap & PR_CAP_DEF) {
+               memprintf(err, "'%s' not allowed in 'defaults' section.", args[0]);
+               goto err;
+       }
+
+       if (!(curpx->cap & PR_CAP_BE)) {
+               memprintf(err, "'%s' only available in backend or listen section.", args[0]);
+               goto err;
+       }
+
+       curpx->flags |= PR_FL_BE_UNPUBLISHED;
+
+       return 0;
+
+ err:
+       return -1;
+}
+
 static int proxy_parse_force_be_switch(char **args, int section_type, struct proxy *curpx,
                                        const struct proxy *defpx, const char *file, int line,
                                        char **err)
@@ -4344,6 +4367,7 @@ static struct cfg_kw_list cfg_kws = {ILH, {
        { CFG_LISTEN, "clitcpka-intvl", proxy_parse_tcpka_intvl },
        { CFG_LISTEN, "srvtcpka-intvl", proxy_parse_tcpka_intvl },
 #endif
+       { CFG_LISTEN, "be-unpublished", proxy_parse_be_unpublished },
        { CFG_LISTEN, "force-be-switch", proxy_parse_force_be_switch },
        { CFG_LISTEN, "guid", proxy_parse_guid },
        { 0, NULL, NULL },