]> git.ipfire.org Git - thirdparty/haproxy.git/commitdiff
MINOR: proxy: prevent deletion of backend referenced by config elements
authorAmaury Denoyelle <adenoyelle@haproxy.com>
Tue, 6 Jan 2026 15:53:03 +0000 (16:53 +0100)
committerAmaury Denoyelle <adenoyelle@haproxy.com>
Mon, 2 Mar 2026 13:08:30 +0000 (14:08 +0100)
Define a new proxy flag PR_FL_NON_PURGEABLE. This is used to mark every
proxy instance explicitely referenced in the config. Such instances
cannot be deleted at runtime.

Static use_backend/default_backend rules are handled in
proxy_finalize(). Also, sample expression proxy references are protected
via smp_resolve_args().

Note that this last case also incidentally protects any proxies
referenced via a CLI "set var" expression. This should not be the case
as in this case variable value is instantly resolved so the proxy
reference is not needed anymore. This also affects dynamic servers.

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

index ec9e1164d6614b1279832a40f283e8e0a7f8ad67..f83afbe03832ae7f8756b5d085d794bd2468f28d 100644 (file)
@@ -2130,10 +2130,12 @@ del backend <name>
   This operation is only possible for TCP or HTTP proxies. To succeed, the
   backend instance must have been first unpublished.
 
-  There is also additional restrictions which prevent backend removal.
-  Currently, this is the case when deprecated dispatch or option transparent
-  are used. Also, a backend cannot be removed if there is a stick-table
-  declared in it.
+  There is additional restrictions which prevent backend removal. First, a
+  backend cannot be removed if it is explicitely referenced by config elements,
+  for example via a use_backend rule or in sample expressions. Some proxies
+  options are also incompatible with runtime deletion. Currently, this is the
+  case when deprecated dispatch or option transparent are used. Also, a backend
+  cannot be removed if there is a stick-table declared in it.
 
   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 b865ba2bd86ca393ef64e6cb5dbb7f146a486601..833c55147564f6322c9438568c5bde98cc7a9110 100644 (file)
@@ -248,6 +248,7 @@ enum PR_SRV_STATE_FILE {
 #define PR_FL_CHECKED            0x00000040  /* The proxy configuration was fully checked (including postparsing checks) */
 #define PR_FL_BE_UNPUBLISHED     0x00000080  /* The proxy cannot be targetted by content switching rules */
 #define PR_FL_DELETED            0x00000100  /* Proxy has been deleted and must be manipulated with care */
+#define PR_FL_NON_PURGEABLE      0x00000200  /* Proxy referenced by config elements which prevent its runtime removal. */
 
 struct stream;
 
index 7dde6288787637f9b1e26919cdaf632d78f2c9cc..1e5a168b2c4038243bf252bc5d265c55e55fe90b 100644 (file)
@@ -1982,6 +1982,8 @@ int proxy_finalize(struct proxy *px, int *err_code)
                                 */
                                px->options |= PR_O_HTTP_UPG;
                        }
+
+                       target->flags |= PR_FL_NON_PURGEABLE;
                }
        }
 
@@ -2058,6 +2060,8 @@ int proxy_finalize(struct proxy *px, int *err_code)
                                 */
                                px->options |= PR_O_HTTP_UPG;
                        }
+
+                       target->flags |= PR_FL_NON_PURGEABLE;
                }
                *err_code |= warnif_tcp_http_cond(px, rule->cond);
        }
@@ -5014,6 +5018,11 @@ int be_check_for_deletion(const char *bename, struct proxy **pb, const char **pm
                goto out;
        }
 
+       if (be->cap & PR_CAP_FE) {
+               msg = "Cannot delete a listen section.";
+               goto out;
+       }
+
        if (be->options & (PR_O_DISPATCH|PR_O_TRANSP)) {
                msg = "Deletion of backend with deprecated dispatch/transparent options is not supported.";
                goto out;
@@ -5024,8 +5033,8 @@ int be_check_for_deletion(const char *bename, struct proxy **pb, const char **pm
                goto out;
        }
 
-       if (be->cap & PR_CAP_FE) {
-               msg = "Cannot delete a listen section.";
+       if (be->flags & PR_FL_NON_PURGEABLE) {
+               msg = "This proxy cannot be removed at runtime due to other configuration elements pointing to it.";
                goto out;
        }
 
index 18f7f1c26f54bed3e37ddeba17e19d34b0335d42..7e3d195dcb26e7f0a52a8561c9b38e69eb48b629 100644 (file)
@@ -1512,6 +1512,7 @@ int smp_resolve_args(struct proxy *p, char **err)
                                break;
                        }
 
+                       /* TODO CLI set-var should not prevent server deletion as var value is instantly resolved. */
                        srv->flags |= SRV_F_NON_PURGEABLE;
 
                        chunk_destroy(&arg->data.str);
@@ -1541,6 +1542,9 @@ int smp_resolve_args(struct proxy *p, char **err)
                                break;
                        }
 
+                       /* TODO CLI set-var should not prevent proxy deletion as var value is instantly resolved. */
+                       px->flags |= PR_FL_NON_PURGEABLE;
+
                        chunk_destroy(&arg->data.str);
                        arg->unresolved = 0;
                        arg->data.prx = px;
@@ -1568,6 +1572,9 @@ int smp_resolve_args(struct proxy *p, char **err)
                                break;
                        }
 
+                       /* TODO CLI set-var should not prevent proxy deletion as var value is instantly resolved. */
+                       px->flags |= PR_FL_NON_PURGEABLE;
+
                        chunk_destroy(&arg->data.str);
                        arg->unresolved = 0;
                        arg->data.prx = px;