Skip to content
40 changes: 40 additions & 0 deletions doc/configuration.txt
Original file line number Diff line number Diff line change
Expand Up @@ -1817,6 +1817,7 @@ The following keywords are supported in the "global" section :
- presetenv
- prealloc-fd
- resetenv
- server-rename
- set-dumpable
- set-var
- setenv
Expand Down Expand Up @@ -3209,6 +3210,14 @@ server-state-file <file>
configuration. See also "server-state-base" and "show servers state",
"load-server-state-from-file" and "server-state-file-name"

server-rename
Enable runtime renaming of servers via the CLI for all backends globally.
When set, it allows the name of any server to be changed at runtime using
the CLI command "set server <backend>/<server> name <newname>" without
requiring "option server-rename" in each backend individually. This option
supports the "no" prefix to disable it. See also: 'option server-rename'
for per-backend control.

set-dumpable [ on | off | libs ]
This option helps choose the core dump behavior in case of process crash.
Available options are:
Expand Down Expand Up @@ -6187,6 +6196,7 @@ option pgsql-check X - X X
option prefer-last-server (*) X - X X
option redispatch (*) X - X X
option redis-check X - X X
option server-rename - - X X
option smtpchk X - X X
option socket-stats (*) X X X -
option splice-auto (*) X X X X
Expand Down Expand Up @@ -6274,6 +6284,36 @@ use-server - - X X


4.2. Alphabetically sorted keywords reference

option server-rename
Enable runtime renaming of servers via the CLI.

May be used in the following contexts: tcp, http

May be used in sections : defaults | frontend | listen | backend
no | no | no | yes

When this option is enabled in a backend, it allows the name of any server in that backend to be changed at runtime using the CLI command:
set server <backend>/<server> name <newname>

Restrictions:
- The new name must be unique among all servers in the backend.
- The change is effective immediately for all runtime operations, stats, and logs.
- The new name is not persisted to the configuration file and will be lost on reload.
- Renaming is only available if 'option server-rename' is set in the backend
or 'server-rename' is set in the global section.
- Some features that rely on static server names (such as certain stick-tables or external monitoring) may not recognize the new name until restart.

Example:
backend myapp
option server-rename
server s1 10.0.0.1:80
server s2 10.0.0.2:80

To rename server 's1' to 'blue':
echo "set server myapp/s1 name blue" | socat /var/run/haproxy.sock -

See also: 'server-rename' in the global section, 'set server <b>/<s> name' in the management guide (doc/management.txt).
---------------------------------------------

This section provides a description of each keyword and its usage.
Expand Down
30 changes: 30 additions & 0 deletions doc/management.txt
Original file line number Diff line number Diff line change
Expand Up @@ -2688,6 +2688,36 @@ set server <backend>/<server> ssl [ on | off ] (deprecated)
This command is deprecated, create a new server dynamically with or without
SSL instead, using the "add server" command.

set server <backend>/<server> name <newname>
Change the name of a server at runtime (if 'option server-rename'
is enabled in the backend or 'server-rename' is set in the global section).

The new name must be unique among all servers in the backend. The
change is effective immediately for all runtime operations, stats,
and logs, but is not persisted to the configuration file and will
be lost on reload. Some features that rely on static server names
(such as stick-tables or external monitoring) may not recognize
the new name until restart.

There is no strict requirement that no sessions are active
before renaming. However, if there are active sessions, log entries
for those sessions may use either the old or new name, depending on
when the rename occurs relative to logging. This may result in split
or inconsistent logs for in-flight requests. If strict log consistency
is required, it is the user's responsibility to ensure all sessions
have finished before renaming (e.g., by draining or maintenance mode
and waiting for all connections to close).

For most use cases, a clear naming scheme (such as srv1 → srv1-old,
srv1-new, or srv1*) allows correlating log entries before and after
the rename, even if some overlap occurs. Users should choose a naming
convention that fits their operational and troubleshooting needs.

Example:
set server myapp/s1 name blue

See also: 'option server-rename' in doc/configuration.txt.

set severity-output [ none | number | string ]
Change the severity output format of the stats socket connected to for the
duration of the current session.
Expand Down
2 changes: 2 additions & 0 deletions include/haproxy/event_hdl-t.h
Original file line number Diff line number Diff line change
Expand Up @@ -279,6 +279,8 @@ struct event_hdl_sub {
#define EVENT_HDL_SUB_SERVER_CHECK EVENT_HDL_SUB_TYPE(1,7)
/* server inet addr (addr:svc_port tuple) change event */
#define EVENT_HDL_SUB_SERVER_INETADDR EVENT_HDL_SUB_TYPE(1,8)
/* server name change event */
#define EVENT_HDL_SUB_SERVER_NAME EVENT_HDL_SUB_TYPE(1,9)

/* PAT_REF family, only published in pat ref subscription list
* (not published in global subscription list for performance reasons)
Expand Down
1 change: 1 addition & 0 deletions include/haproxy/global-t.h
Original file line number Diff line number Diff line change
Expand Up @@ -80,6 +80,7 @@
#define GTUNE_DISABLE_ACTIVE_CLOSE (1<<22)
#define GTUNE_QUICK_EXIT (1<<23)
#define GTUNE_COLLECT_LIBS (1<<24)
#define GTUNE_SRV_RENAME (1<<25)
/* (1<<25) unused */
#define GTUNE_USE_FAST_FWD (1<<26)
#define GTUNE_LISTENER_MQ_FAIR (1<<27)
Expand Down
4 changes: 3 additions & 1 deletion include/haproxy/proxy-t.h
Original file line number Diff line number Diff line change
Expand Up @@ -188,7 +188,9 @@ enum PR_SRV_STATE_FILE {
#define PR_O3_HASHAFNTY_MAXQUEUE 0x00000200 /* preserve hash affinity until maxqueue is reached */
#define PR_O3_HASHAFNTY_MASK 0x00000300 /* mask for hash-preserve-affinity */

/* unused: 0x00000400 to 0x80000000 */
#define PR_O3_SRV_RENAME 0x00000400 /* allow runtime server renaming */

/* unused: 0x00000800 to 0x80000000 */
/* end of proxy->options3 */

/* Cookie settings for pr->ck_opts */
Expand Down
19 changes: 19 additions & 0 deletions include/haproxy/server-t.h
Original file line number Diff line number Diff line change
Expand Up @@ -566,6 +566,7 @@ struct event_hdl_cb_data_server {
* EVENT_HDL_SUB_SERVER_ADMIN
* EVENT_HDL_SUB_SERVER_CHECK
* EVENT_HDL_SUB_SERVER_INETADDR
* EVENT_HDL_SUB_SERVER_NAME
*/
struct {
/* safe data can be safely used from both
Expand Down Expand Up @@ -769,6 +770,24 @@ struct event_hdl_cb_data_server_inetaddr {
/* no unsafe data */
};

/* data provided to EVENT_HDL_SUB_SERVER_NAME handlers through
* event_hdl facility
*
* Note that this may be casted to regular event_hdl_cb_data_server if
* you don't care about name related optional info
*/
struct event_hdl_cb_data_server_name {
/* provided by:
* EVENT_HDL_SUB_SERVER_NAME
*/
struct event_hdl_cb_data_server server; /* must be at the beginning */
struct {
char old_name[64];
char new_name[64];
} safe;
/* no unsafe data */
};

/* Storage structure to load server-state lines from a flat file into
* an ebtree, for faster processing
*/
Expand Down
186 changes: 186 additions & 0 deletions reg-tests/server/cli_set_server_name.vtc
Original file line number Diff line number Diff line change
@@ -0,0 +1,186 @@
varnishtest "Set server name via CLI"

feature ignore_unknown_macro

#REGTEST_TYPE=devel

# Do nothing. Is there only to create s1_* macros
server s1 {
rxreq
txresp
} -start

haproxy h1 -conf {
global
.if feature(THREAD)
thread-groups 1
.endif

defaults
mode http
timeout connect "${HAPROXY_TEST_TIMEOUT-5s}"
timeout client "${HAPROXY_TEST_TIMEOUT-5s}"
timeout server "${HAPROXY_TEST_TIMEOUT-5s}"

frontend fe
bind "fd@${feS}"
default_backend test

backend test
option server-rename
balance random
server s1 ${s1_addr}:${s1_port}
server s2 ${s1_addr}:${s1_port}

backend norename
balance random
server s1 ${s1_addr}:${s1_port}

backend useserver
option server-rename
balance random
server s1 ${s1_addr}:${s1_port}
server s2 ${s1_addr}:${s1_port}
use-server s1 if { always_true }

backend tracked
option server-rename
balance random
server s1 ${s1_addr}:${s1_port}
server s2 ${s1_addr}:${s1_port} track tracked/s1
} -start

haproxy h1 -cli {
# ---- error cases ----

# missing new name argument
send "set server test/s1 name"
expect ~ "set server <b>/<s> name requires a new name."

# backend without 'option server-rename'
send "set server norename/s1 name newname"
expect ~ "Backend does not allow server renaming"

# server not in maintenance mode
send "set server test/s1 name newname"
expect ~ "Server must be in maintenance mode"

# put s1 in maintenance for subsequent tests
send "disable server test/s1"
expect ~ ".*"

# name containing '/' is rejected
send "set server test/s1 name bad/name"
expect ~ "Server name must not contain spaces, control characters, or '/'."

# duplicate name — s2 already exists
send "set server test/s1 name s2"
expect ~ "A server with the same name already exists"

# server targeted by a static use-server rule
send "disable server useserver/s1"
expect ~ ".*"
send "set server useserver/s1 name newname"
expect ~ "referenced by a 'use-server' rule"

# server tracked by another server
send "disable server tracked/s1"
expect ~ ".*"
send "set server tracked/s1 name newname"
expect ~ "tracked by another server"

# renaming to the same name is a no-op (success)
send "set server test/s1 name s1"
expect ~ "Server name updated."

# ---- success case ----

# rename s1 -> blue
send "set server test/s1 name blue"
expect ~ "Server name updated."

# verify the new name appears in show servers state
send "show servers state test"
expect ~ "test 1 blue"

# the old name should no longer resolve
send "set server test/s1 state ready"
expect ~ "No such server."

# new name is usable via enable
send "enable server test/blue"
expect ~ ".*"

# ---- rename back ----

# must go through maintenance again
send "disable server test/blue"
expect ~ ".*"

send "set server test/blue name s1"
expect ~ "Server name updated."

send "show servers state test"
expect ~ "test 1 s1"

# bring back up
send "enable server test/s1"
expect ~ ".*"
}

# verify traffic still works after rename round-trip
client c1 -connect ${h1_feS_sock} {
txreq
rxresp
expect resp.status == 200
} -run

# ---- test global server-rename ----

server s2 {
rxreq
txresp
} -start

haproxy h2 -conf {
global
server-rename
.if feature(THREAD)
thread-groups 1
.endif

defaults
mode http
timeout connect "${HAPROXY_TEST_TIMEOUT-5s}"
timeout client "${HAPROXY_TEST_TIMEOUT-5s}"
timeout server "${HAPROXY_TEST_TIMEOUT-5s}"

frontend fe
bind "fd@${feS}"
default_backend test

backend test
balance random
server s1 ${s2_addr}:${s2_port}
} -start

haproxy h2 -cli {
# global server-rename allows renaming without per-backend option
send "disable server test/s1"
expect ~ ".*"

send "set server test/s1 name green"
expect ~ "Server name updated."

send "show servers state test"
expect ~ "test 1 green"

send "enable server test/green"
expect ~ ".*"
}

client c2 -connect ${h2_feS_sock} {
txreq
rxresp
expect resp.status == 200
} -run
9 changes: 9 additions & 0 deletions src/cfgparse-global.c
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@ int cluster_secret_isset;
static const char *common_kw_list[] = {
"global", "busy-polling", "set-dumpable",
"insecure-fork-wanted", "insecure-setuid-wanted", "nosplice",
"server-rename",
"nogetaddrinfo", "noreuseport", "uid", "gid",
"external-check", "user", "group", "maxconn",
"ssl-server-verify", "maxconnrate", "maxsessrate", "maxsslrate",
Expand Down Expand Up @@ -123,6 +124,14 @@ int cfg_parse_global(const char *file, int linenum, char **args, int kwm)
else
global.tune.options |= GTUNE_INSECURE_FORK;
}
else if (strcmp(args[0], "server-rename") == 0) { /* "no server-rename" or "server-rename" */
if (alertif_too_many_args(0, file, linenum, args, &err_code))
goto out;
if (kwm == KWM_NO)
global.tune.options &= ~GTUNE_SRV_RENAME;
else
global.tune.options |= GTUNE_SRV_RENAME;
}
else if (strcmp(args[0], "insecure-setuid-wanted") == 0) { /* "no insecure-setuid-wanted" or "insecure-setuid-wanted" */
if (alertif_too_many_args(0, file, linenum, args, &err_code))
goto out;
Expand Down
1 change: 1 addition & 0 deletions src/proxy.c
Original file line number Diff line number Diff line change
Expand Up @@ -158,6 +158,7 @@ const struct cfg_opt cfg_opts3[] =
{
{"assume-rfc6587-ntf", PR_O3_ASSUME_RFC6587_NTF, PR_CAP_FE, 0, PR_MODE_SYSLOG },
{"dont-parse-log", PR_O3_DONTPARSELOG, PR_CAP_FE, 0, PR_MODE_SYSLOG },
{"server-rename", PR_O3_SRV_RENAME, PR_CAP_BE, 0, 0 },
{ NULL, 0, 0, 0 }
};

Expand Down
Loading
Loading