feat(controller-peers-env-fallback): refuse an env-supplied peers list without the controller's own name (task 2.4)
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
This commit is contained in:
parent
64d3429cd8
commit
9018980b08
3 changed files with 79 additions and 1 deletions
|
|
@ -495,6 +495,36 @@ int main(int argc, char* argv[])
|
|||
return 1;
|
||||
}
|
||||
|
||||
/* Req 1.6: a list taken from the environment must name this
|
||||
* controller, or a stray variable would silently join it to a
|
||||
* cluster it is not part of. Refuse before the cert pre-flight and
|
||||
* any network activity. An explicit --peers keeps its existing
|
||||
* handling (the later refusal in cluster_open_listener()). */
|
||||
if (peers_from_env &&
|
||||
xce_peers_find_identity(&myconf.peers_cfg, arguments.myname) < 0) {
|
||||
char names[512];
|
||||
size_t used = 0;
|
||||
names[0] = '\0';
|
||||
for (int i = 0; i < myconf.peers_cfg.candidates_count; i++) {
|
||||
const xce_candidate_t* c = &myconf.peers_cfg.candidates[i];
|
||||
int n = snprintf(names + used, sizeof(names) - used, "%s%s",
|
||||
i > 0 ? ", " : "",
|
||||
c->name[0] != '\0' ? c->name : c->hostname);
|
||||
if (n < 0 || (size_t)n >= sizeof(names) - used) {
|
||||
names[used] = '\0'; /* drop the partial last name */
|
||||
break;
|
||||
}
|
||||
used += (size_t)n;
|
||||
}
|
||||
fprintf(stderr,
|
||||
"xce_controller: XCE_CONTROLLER_PEERS (%s) has no "
|
||||
"candidate named '%s'; pass --myname <one of: %s> or "
|
||||
"unset XCE_CONTROLLER_PEERS to run standalone\n",
|
||||
peers_str, arguments.myname, names);
|
||||
mylog_fini();
|
||||
return 1;
|
||||
}
|
||||
|
||||
strncpy(myconf.peers_cfg.identity, arguments.myname,
|
||||
sizeof(myconf.peers_cfg.identity) - 1);
|
||||
INFO("HA mode: %d controller candidates, identity=%s%s",
|
||||
|
|
|
|||
|
|
@ -456,6 +456,54 @@ case_controller_help_names_variable() {
|
|||
add_case case_controller_help_names_variable \
|
||||
"controller: --help documents XCE_CONTROLLER_PEERS and the opt-out (1.5, 1.7)"
|
||||
|
||||
# ── Task 2.4 (Req 1.6): an XCE_CONTROLLER_PEERS list that has no candidate for
|
||||
# the controller's own name is refused on stderr before the certificate
|
||||
# pre-flight. Without the check these runs still exit non-zero at the
|
||||
# pre-flight, so the cases assert on the message, not just the exit status.
|
||||
OWN_NAME_RE="has no candidate named"
|
||||
|
||||
case_controller_env_own_name_missing() {
|
||||
local d; d="$(new_scratch controller-own-missing)"
|
||||
run_controller "$d" "XCE_CONTROLLER_PEERS=$ENV3" -- --myname zz
|
||||
assert_rc nonzero || return 1
|
||||
assert_grep "$d/stderr" "XCE_CONTROLLER_PEERS \\($ENV3\\) $OWN_NAME_RE 'zz'" "stderr" || return 1
|
||||
assert_grep "$d/stderr" -- '--myname <one of: a, b, c>' "stderr" || return 1
|
||||
assert_grep "$d/stderr" 'unset XCE_CONTROLLER_PEERS' "stderr" || return 1
|
||||
assert_no_grep "$d/stderr" 'cert|key' "stderr (must stop before the certificate pre-flight)" || return 1
|
||||
}
|
||||
add_case case_controller_env_own_name_missing \
|
||||
"controller: env list without the own name is refused on stderr (1.6)"
|
||||
|
||||
case_controller_env_own_name_unnamed() {
|
||||
local d; d="$(new_scratch controller-own-unnamed)"
|
||||
run_controller "$d" "XCE_CONTROLLER_PEERS=localhost:1" -- --myname zz
|
||||
assert_rc nonzero || return 1
|
||||
assert_grep "$d/stderr" "$OWN_NAME_RE 'zz'" "stderr" || return 1
|
||||
assert_grep "$d/stderr" -- '--myname <one of: localhost>' "stderr (unnamed candidate listed by hostname)" || return 1
|
||||
}
|
||||
add_case case_controller_env_own_name_unnamed \
|
||||
"controller: unnamed env candidates are listed by hostname in the 1.6 message"
|
||||
|
||||
case_controller_env_own_name_present() {
|
||||
local d; d="$(new_scratch controller-own-present)"
|
||||
run_controller "$d" "XCE_CONTROLLER_PEERS=$ENV3" -- --myname b
|
||||
_assert_stopped_early "$d" || return 1
|
||||
assert_grep "$d/controller.log" 'HA mode: 3 controller candidates, identity=b' || return 1
|
||||
assert_no_grep "$d/stderr" "$OWN_NAME_RE" "stderr" || return 1
|
||||
}
|
||||
add_case case_controller_env_own_name_present \
|
||||
"controller: env list containing the own name is accepted (1.6)"
|
||||
|
||||
case_controller_flag_own_name_unchecked() {
|
||||
local d; d="$(new_scratch controller-own-flag)"
|
||||
run_controller "$d" -u XCE_CONTROLLER_PEERS -- --myname zz --peers "$ENV3"
|
||||
_assert_stopped_early "$d" || return 1
|
||||
assert_grep "$d/controller.log" 'HA mode: 3 controller candidates, identity=zz' || return 1
|
||||
assert_no_grep "$d/stderr" "$OWN_NAME_RE" "stderr" || return 1
|
||||
}
|
||||
add_case case_controller_flag_own_name_unchecked \
|
||||
"controller: explicit --peers without the own name is not checked at startup (1.6)"
|
||||
|
||||
|
||||
# ════════════════════════════════════════════════════════════════════════════
|
||||
# main
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue