helm: make the Postgres role and bootstrap database configurable for validators - #6803
Conversation
0c7b8d7 to
8922982
Compare
|
Thanks @SLoeuillet this seems sensible to me. Can you please add a release notes entry in release_notes_upcoming.rst please? |
|
/cluster_test |
|
Deploy cluster test triggered for Commit 8922982c3fc846f1de44ca301cc5ed80fa47f146 in , please contact a Contributor to approve it in CircleCI: https://app.circleci.com/pipelines/github/DACH-NY/canton-network-internal/79923 |
8922982 to
f62c546
Compare
Requested by @isegall-da on canton-network#6803. Signed-off-by: Stephane Loeuillet <stephane.loeuillet@kaiko.com>
|
Thanks @isegall-da — release notes entry added in I rebased onto One consequence: the head commit moved from |
|
Deploy cluster test triggered for Commit f62c54648dae06d3835dc8abafa5ba8a79fade81 in , please contact a Contributor to approve it in CircleCI: https://app.circleci.com/pipelines/github/DACH-NY/canton-network-internal/79972 |
There was a problem hiding this comment.
Thank you @SLoeuillet !
I think I would feel slightly better if we could add 1-2 helm tests (perhaps for validator + participant?) that cover the new value, to guard against regressions.
More on the nit side: we could also cover splitwell.yaml, for symmetry... (Really we should think about some larger refactoring that avoids all this code duplication, but doesn't have to be in this PR.)
Also please rebase to latest main again to fix your merge conflict and consume the fix for the reason your deployment test failed... sorry for the trouble.
martinflorian-da
left a comment
There was a problem hiding this comment.
Argh apologies for missing that earlier, we should also fix the sequencer:
> rg "\-\-dbname=cantonnet" cluster/helm/
cluster/helm/splice-splitwell-app/templates/splitwell.yaml
128: until errmsg=$(psql -h {{ .Values.persistence.host }} -p {{ .Values.persistence.port }} --username=cnadmin --dbname=cantonnet -c 'create database {{ .Values.persistence.databaseName }}' 2>&1); do
cluster/helm/splice-global-domain/templates/sequencer.yaml
266: until psql -h "$DB_HOST" -p "$DB_PORT" --username="$DB_USER" --dbname=cantonnet -tAc 'SELECT 1' >/dev/null 2>&1; do
270: if [ "$(psql -h "$DB_HOST" -p "$DB_PORT" --username="$DB_USER" --dbname=cantonnet -tAc "SELECT 1 FROM pg_database WHERE datname = '${DB_NAME}'")" = "1" ]; then
274: psql -v ON_ERROR_STOP=1 -h "$DB_HOST" -p "$DB_PORT" --username="$DB_USER" --dbname=cantonnet -c "CREATE DATABASE \"${DB_NAME}\"";
And even bigger miss: for participant/domain/mediator/sequencer persistence.user is not actually used for anything but the init container atm? You want to be overriding POSTGRES_USER somewhere: https://github.com/digital-asset/canton/blob/72c82f382942e3bda7d6418f72f95b1524f57ca8/docker/canton/images/canton-base/storage.conf#L9
Given that both @isegall-da and myself missed these things on the first pass makes me want to ask you for some e2e confirmation on a cluster that this is working as expected, with dbname overridden... Did you try these changes out?
Requested by @isegall-da on canton-network#6803. Signed-off-by: Stephane Loeuillet <stephane.loeuillet@kaiko.com>
f62c546 to
2b12d7b
Compare
|
Thanks — all three addressed, and good catch on the sequencer. 1. The missed call sites. Your
2. Tests. Added a One wrinkle worth mentioning: the obvious negative assertion ( 3. Rebased onto Test suites for every touched chart, compared against On the wider refactoring you mentioned to remove the duplication across these init containers — happy to take that on in a follow-up PR if you think it's worth doing; it seemed too broad to fold in here. |
|
@SLoeuillet I don't think you have addressed my concerns that the Canton nodes will not learn about the new database user to use.
Did you give some thought on how you could end-to-end test these changes? Deploy at least a validator with a custom DB config, ideally using both compose and Helm? |
2b12d7b to
0c1efc9
Compare
Requested by @isegall-da on canton-network#6803. Signed-off-by: Stephane Loeuillet <stephane.loeuillet@kaiko.com>
|
You're right, and I apologise — I answered only the first half of your review and claimed it was complete. The Now fixed. For the participant, domain, mediator and sequencer, Two things that made the fix straightforward, and which I think strengthen the case for the PR:
I also checked the Splice apps while I was there: The env var is emitted only when Tests: the value reaching the node's env, and nothing emitted when unset, on On end-to-end: agreed it is warranted, and given two of you missed this on the first pass I would rather not self-certify. Before I burn a cluster deployment on it — would you rather see it validated through compose (which already has Rebased onto current |
Requested by @isegall-da on canton-network#6803. Signed-off-by: Stephane Loeuillet <stephane.loeuillet@kaiko.com>
0c1efc9 to
391f753
Compare
@SLoeuillet Ah compose doesn't matter much here, does it? Apologies for even bringing that one up. So I think we want to test with a Helm deployment here. Do you have a reasonable way to do that manually / locally? A confirmation for a validator (app + participant) would be sufficient for me. I guess you don't even have to connect to a synchronizer - if init passes until the "connect to synchronizer" step then we should be safe. Alternatively I'm also open to you making an additional Pulumi commit that makes some validator deployment and perhaps the sv-runbook use the new fields. We use this to trigger a scratchnet cluster test on the PR, then we revert your commit (so it can be hacky). Either that or just a new PR stacked on this one. Longer-term we want to cover your changes here in our regular cluster tests. That seems like we should better move it to a follow-up PR though. |
|
Tested with a Helm deployment on a local Setup — a plain Both charts installed with Participant —
Validator app — reaches and completes its DB work: with Negative control, which I think is the part that actually proves it: installing the unpatched and its rendered env contains no Two incidental notes from doing this, neither related to the change:
Happy to also do the Pulumi/scratchnet commit you offered if you would still like the change exercised in your own cluster tests — say the word and I will stack it, or leave it for the follow-up PR you mentioned. |
|
Thank you @SLoeuillet ! I think you have convinced me that the changes work for validators. The Helm test coverage there is also quite good. After thinking about your PR some more though I still don't feel comfortable about merging the changes for SVs without having additional testing. Among other things, an SV deployment also consists of more moving parts - so harder to judge if we're not still missing something. Adding relevant (or at least: easy to repurpose) cluster testing is actually planned soon as part of a security hardening story. So how about this, assuming that you are mostly interested in the validator use case anyway:
If you prefer not to cut up your PR we could also just delay merging by a few weeks, but I'd actually prefer having your changes for validators in earlier. |
…validators
The pg-init and wait containers, the Postgres exporter sidecar, and the participant's
Canton node all connected with a hardcoded cnadmin role and cantonnet bootstrap
database. They now read persistence.user and persistence.bootstrapDatabaseName,
defaulting to those same values so rendered output is byte-identical unless set.
This matters for operators moving off splice-postgres, which is unsupported after
2026-11-12: a managed Postgres offering may not let you create a cnadmin superuser or a
cantonnet database at all, so the migration path upstream points at is blocked by names
the charts assume.
The participant needed more than the init container: canton-base's storage.conf reads
`user = ${?CANTON_PARTICIPANT_POSTGRES_USER}` and the chart never set it, so the node
kept connecting as cnadmin even when persistence.user was configured — a half-applied
configuration that looks correct. The image already supports the variable, and the
compose deployment already passes it; only Helm was missing it. splice-validator was
never affected: it writes `user` straight into its HOCON storage block.
Scope is deliberately limited to validator and participant. The SV charts (sv-node,
scan, global-domain, domain) and splitwell are left for a follow-up, once the cluster
test coverage for SV deployments discussed in canton-network#6803 exists.
Tested on a kind cluster against a Postgres initialised with a different role and
bootstrap database, so cnadmin and cantonnet do not exist: both charts come up, the
databases are owned by the configured role, and the unpatched charts fail on
`password authentication failed for user "cnadmin"`.
Signed-off-by: Stephane Loeuillet <stephane.loeuillet@kaiko.com>
391f753 to
2fbac1b
Compare
|
That works for me — validators are exactly the use case I care about, so getting them in early is the better trade. Done: the PR is now validator + participant only, rebased onto current Kept: Dropped, and reverted to The title, description and release-notes entry are all rescoped, and the entry now says explicitly that the SV charts still use the hardcoded values, so the note does not overclaim. The SV work is preserved on a branch and nothing is lost. I am happy to open the follow-up PR whenever you prefer — either now so it is queued behind this one, or once the security-hardening testing lands and it can be reviewed against real coverage. Your call; if it is easier for you to recover the parts yourself at that point, that is fine too. |
…validators
The pg-init and wait containers, the Postgres exporter sidecar, and the participant's
Canton node all connected with a hardcoded cnadmin role and cantonnet bootstrap
database. They now read persistence.user and persistence.bootstrapDatabaseName,
defaulting to those same values so rendered output is byte-identical unless set.
This matters for operators moving off splice-postgres, which is unsupported after
2026-11-12: a managed Postgres offering may not let you create a cnadmin superuser or a
cantonnet database at all, so the migration path upstream points at is blocked by names
the charts assume.
The participant needed more than the init container: canton-base's storage.conf reads
`user = ${?CANTON_PARTICIPANT_POSTGRES_USER}` and the chart never set it, so the node
kept connecting as cnadmin even when persistence.user was configured — a half-applied
configuration that looks correct. The image already supports the variable, and the
compose deployment already passes it; only Helm was missing it. splice-validator was
never affected: it writes `user` straight into its HOCON storage block.
Scope is deliberately limited to validator and participant. The SV charts (sv-node,
scan, global-domain, domain) and splitwell are left for a follow-up, once the cluster
test coverage for SV deployments discussed in canton-network#6803 exists.
Tested on a kind cluster against a Postgres initialised with a different role and
bootstrap database, so cnadmin and cantonnet do not exist: both charts come up, the
databases are owned by the configured role, and the unpatched charts fail on
`password authentication failed for user "cnadmin"`.
Signed-off-by: Stephane Loeuillet <stephane.loeuillet@kaiko.com>
2fbac1b to
034b2ed
Compare
martinflorian-da
left a comment
There was a problem hiding this comment.
Perfect, thank you!
|
@SLoeuillet We had a bug on main, please rebase (hopefully the last time on this PR...) |
…validators
The pg-init and wait containers, the Postgres exporter sidecar, and the participant's
Canton node all connected with a hardcoded cnadmin role and cantonnet bootstrap
database. They now read persistence.user and persistence.bootstrapDatabaseName,
defaulting to those same values so rendered output is byte-identical unless set.
This matters for operators moving off splice-postgres, which is unsupported after
2026-11-12: a managed Postgres offering may not let you create a cnadmin superuser or a
cantonnet database at all, so the migration path upstream points at is blocked by names
the charts assume.
The participant needed more than the init container: canton-base's storage.conf reads
`user = ${?CANTON_PARTICIPANT_POSTGRES_USER}` and the chart never set it, so the node
kept connecting as cnadmin even when persistence.user was configured — a half-applied
configuration that looks correct. The image already supports the variable, and the
compose deployment already passes it; only Helm was missing it. splice-validator was
never affected: it writes `user` straight into its HOCON storage block.
Scope is deliberately limited to validator and participant. The SV charts (sv-node,
scan, global-domain, domain) and splitwell are left for a follow-up, once the cluster
test coverage for SV deployments discussed in canton-network#6803 exists.
Tested on a kind cluster against a Postgres initialised with a different role and
bootstrap database, so cnadmin and cantonnet do not exist: both charts come up, the
databases are owned by the configured role, and the unpatched charts fail on
`password authentication failed for user "cnadmin"`.
Signed-off-by: Stephane Loeuillet <stephane.loeuillet@kaiko.com>
Head branch was pushed to by a user without write access
034b2ed to
3cda0ee
Compare
|
Rebased onto Note the force-push will have re-armed |
|
Thanks for merging, and for the review — the Opened the follow-up as #7069 with the SV charts plus splitwell, so the work is queued rather than lost. No urgency from my side: it is there for whenever the SV cluster coverage lands, and I have said as much in the description. Happy to rebase it whenever you need. |
Fixes #6802. Scope reduced to validator and participant per the discussion below — the SV charts and splitwell move to a follow-up.
Why
splice-postgresis unsupported after 2026-11-12, so every operator on it has to move to a self-provisioned or managed Postgres. The charts assumed that migration target would offer acnadminsuperuser and acantonnetdatabase, which a managed offering may not permit creating at all — so the names blocked the very migration path upstream points at.persistence.userandpersistence.bootstrapDatabaseNameare now read wherever those values were hardcoded, defaulting tocnadminandcantonnetso rendered output is byte-identical unless you set them.The part that was not just the init container
The participant needed more than the pg-init fix.
canton-base'sstorage.confreadsuser = ${?CANTON_PARTICIPANT_POSTGRES_USER}, and the chart never set it — so the node kept connecting ascnadmineven withpersistence.userconfigured. That is a half-applied configuration: the init container uses the new role, the application does not, and nothing complains. Worse than not offering the value, since it looks configurable.The image already supports the variable and the compose deployment already passes it (
CANTON_PARTICIPANT_POSTGRES_USER=${SPLICE_DB_USER}); Helm was the only deployment path missing it.splice-validatorwas never affected — it writesuserstraight into its HOCON storage block.Testing
Helm deployment on a
kindcluster, against a Postgres initialised withPOSTGRES_USER=appuser/POSTGRES_DB=bootstrapdb, socnadminandcantonnetdo not exist:1/1 Running—participant_test owner=appuser,CANTON_PARTICIPANT_POSTGRES_USER=appuser, 18 Flyway migrations,Canton started, and Postgres reportsappuser -> participant_test (32 conn)validator_test owner=appuser, schemavalidator owner=appuser— then stops at the ledger-API wiring, which was deliberately not configuredFATAL: password authentication failed for user "cnadmin"atInit:0/1, with no user env var rendered at allChart unit tests cover the defaults, an override, and that neither default survives in the rendered command; each was checked to fail without the change rather than assumed.
Not in this PR
splice-sv-node,splice-scan,splice-global-domain(sequencer + mediator),splice-domainandsplice-splitwell-appcarry the same hardcoding and the same fix, but SV deployments have more moving parts and the cluster test coverage for them is not there yet. That work is preserved and will follow once it is.