Conversation
… services Twelve config modules each carry their own copy of the code that writes a service's transport_url and its [oslo_messaging_rabbit] keys, across fourteen call sites in total. Adding a key means fourteen edits, and missing one is silent: the service keeps working until the broker stops accepting the shape it still asks for. SetMqClientConfig() takes the config by reference, the way the three SetWorkerQueue() copies already did, and keeps the unconditional keys and the HA-gated keys as separate blocks so a later change can add to either one without restructuring. Role gating stays with the caller. Which roles run a given service is a property of that service's deployment, not of the message queue, and the nine UpdateMqConn() copies disagree about it three different ways. withRpcTimeout exists for neutron's VPN agent, the one call site that has never carried rpc_response_timeout. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Signed-off-by: Seki Xu <seki.xu@bigstack.co>
…d writer These three carried byte-identical SetWorkerQueue() copies, comment included, and their signature is the one the shared writer adopted, so the call sites change in name only. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Signed-off-by: Seki Xu <seki.xu@bigstack.co>
… shared writer The role guards are left exactly as they were -- nova, octavia and cyborg admit compute nodes, the other five are control-only -- because that difference is real and belongs to each service. ironic writes twice, to its own config and to the inspector's, so it makes two calls. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Signed-off-by: Seki Xu <seki.xu@bigstack.co>
…d writer neutron is the only module with two asymmetric call sites: the control node's own config gets the full key set, while the compute node's VPN agent config has never been given rpc_response_timeout. That asymmetry is preserved as-is -- this change is meant to alter no generated config. The unconditional RabbitMqServers() call at the top of the function is gone with it. It built a string that a node which is neither control nor compute then discarded. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Signed-off-by: Seki Xu <seki.xu@bigstack.co>
…call sites The acceptance evidence for this refactor -- generated configs identical before and after -- can only come off a real cluster: hex_config's dry run returns at the top of every module's Commit() and produces no config at all, and a module-scoped commit corrupts cluster-wide globals. Both of the cheap routes are closed, so the evidence is expensive and taken rarely. These tests hold the line offline in between. They assert the exact key set and values for each shape the fourteen call sites produce, including the absence of the HA section on a single-node cluster and neutron's missing rpc_response_timeout, so that a later edit to the writer cannot quietly drop a key for one service. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Signed-off-by: Seki Xu <seki.xu@bigstack.co>
SekiXu
marked this pull request as draft
September 16, 2026 05:37
SekiXu
marked this pull request as ready for review
September 16, 2026 06:21
Eandalf-Bigstack
left a comment
Collaborator
There was a problem hiding this comment.
LGTM, we would be merging this PR after v3.1.20, into v3.2.0 instead.
7 tasks
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Closes #1426.
Prerequisite refactor for the AMQP TLS work in #1167. Twelve
config_*.cppmodules each carried theirown copy of the code that writes a service's
transport_urland its[oslo_messaging_rabbit]keys —fourteen call sites once neutron's two and ironic's two are counted. Adding
ssl = true/ssl_ca_filefor TLS would mean fourteen edits, and missing one is silent: that service keeps workinguntil the broker stops accepting the connection shape it still asks for.
This changes no generated config. It is a behaviour-preserving refactor so that the TLS change
later lands in one place, with the HA-gate decision made once.
What changed
SetMqClientConfig()incore/cube_sdk_library/src/cluster.{hpp,cpp}— one writer, taking the configby reference the way the three
SetWorkerQueue()copies already did. Its body keeps the unconditionalkeys and the HA-gated keys as separate blocks, which is where #1167's ssl parameters go without
restructuring again.
SetWorkerQueue()copies, comment included, andtheir signature is the one the shared writer adopted — so those three functions are deleted and the
call sites changed in name only.
UpdateMqConn()wrapper; only the body becomes a call. ironic writes twice, to its own config and tothe inspector's, so it makes two calls.
compute node's VPN agent config has never carried
rpc_response_timeout— confirmed withgit log -Sback to the initial commit, never present. That asymmetry is preserved explicitly viawithRpcTimeout = false, because the acceptance criterion is byte-identical output. Theunconditional
RabbitMqServers()call at the top of the function is gone with it: it built a stringthat a node which is neither control nor compute then discarded.
Role gating deliberately stays with the caller. Which roles run a given service is a property of
that service's deployment, not of the message queue, and the nine
UpdateMqConn()copies disagreeabout it three different ways (
IsControlonly ×5,IsControl || IsCompute×3, neutron's two-stage).Folding that into the helper would have produced one function with a role flag, which is harder to
change, not easier.
config_barbican.cppis untouched — it writeskafka://…:9095, and theRabbitMqServersoccurrenceat
config_barbican.cpp:228is comment text, not a call. The comment already there is more completethan anything this PR would add.
Why
cluster.cpprather than a newcore/rabbitmq/rabbitmq_util.{h,cpp}The
mysql_utilprecedent would need a new set of.mklink settings, and it would split the twothings #1167 has to touch — scheme and port live in
RabbitMqServers()incluster.cpp, the sslparameters would live in the new file. That is the opposite of what this issue is buying.
Evidence
Taken against this branch's final commit
762ed5c4, on a 1cc dev node withcubesys.ha = false.Both sides were built in the x86 jail container from the same
25bbcebdbase — stock, and with thefive patches — so the only variable is this change:
strings | grep -c SetMqClientConfig25bbcebd6d158ff0…762ed5c480bfdf9d…Each binary then committed the same settings file, and the generated tree was snapshotted:
On the fourteen AMQP client configs the patched binary produced,
/etc/neutron/vpn_agent.inicarriestransport_urlbut norpc_response_timeout, while the other thirteen carry both — the asymmetrydescribed above, reproduced on a real node rather than argued from the diff.
Offline unit tests (new):
core/cube_sdk_library/src/tests/test_mq_config_01.cpp, six casespinning the exact key set and values for each shape the fourteen call sites produce — including the
absence of the HA section on a single-node cluster, and neutron's missing
rpc_response_timeout.Verified non-vacuous by a negative control: changing the expected
rpc_response_timeoutto9999turns two assertions red and fails the target; reverting restores green. Note that
make alldoes notbuild that directory — the existing
utils/testsis not built either. They run undermake test.These tests exist because the real-node evidence is expensive and taken rarely:
hex_config's dry runreturns at the top of every module's
Commit()and produces no config at all, and a module-scopedcommit rewrites cluster-wide settings. Both cheap routes are closed.
Three traps are worth recording for anyone reproducing the comparison, since each one produces a
confident-looking wrong answer:
hex_config commit /etc/settings.txtdoes nothing. Current and new are then the same file, thedigest matches, and every module reports
commit(x)— a skip, not a pass. The settings file passedin has to differ from
/etc/settings.txt.developdrift, which shows up as a diff that has nothing to do with this change.
/var/log/hex_config.logdoes not mean the commit did not run.rsyslog'simjournalrate limit (20000 messages / 600s) was tripped by another service mid-run and dropped 12098
messages, silently blanking the whole window.
journalctl -t hex_confighad all 1594 lines,including every module's
commit(o).Not verified here: the refactored writer on an HA node
The HA branch is where all four
[oslo_messaging_rabbit]keys live, so the non-HA run above saysnothing about them. Two things narrow that gap; one remains open.
Offline cases 2 and 4 pin the HA key set for the new writer. Those expectations were then checked
against a live
cubesys.ha = truecluster: across all fourteen config files the six keys and theirexact values match what the pre-refactor code produces today — including
vpn_agent.inicarrying thefour HA keys but no
rpc_response_timeout. The test expectations are therefore grounded in productionoutput, not derived from the diff they are meant to check.
What remains open is that the refactored binary has not itself run on an HA node. Whether each of the
fourteen call sites passes the right arguments is read from the diff, not executed. That needs a
cluster installed from a build containing this change — QA's environment, not a hot-patch. The ticket
carries the rows for it.
Scope
No port change, no scheme change, no ssl parameters — those are #1167's implementation issue. Only
*.cpp/*.hppand one testsMakefilechange, so nothing enters the rootfs and no ISO rebuild isrequired.
🤖 Generated with Claude Code