Skip to content

Post-2.4.0 follow-ups: ArtifactHub license, configurable helper images, Minikube guide fixes - #22

Draft
dmytro-landiak wants to merge 5 commits into
mainfrom
fix/post-2.4.0-followups
Draft

dmytro-landiak wants to merge 5 commits into
mainfrom
fix/post-2.4.0-followups

Conversation

@dmytro-landiak

@dmytro-landiak dmytro-landiak commented Aug 28, 2026

Copy link
Copy Markdown
Contributor

Follow-ups found while auditing the TBMQ 2.4.0 chart release (chart 2.1.0 / app 2.4.0) against the published ArtifactHub package and the Minikube guide.

Opened as a draft because it carries a chart version bump — see Two decisions below. Merging this does not publish anything; packaging and the push to helm.thingsboard.io are separate steps.

What the audit confirmed was already correct

No action needed on these, recording them so the release is traceable:

  • Chart 2.1.0 / app 2.4.0 is live on both ArtifactHub and helm.thingsboard.io/tbmq, and the published tarball matches main (only Helm's key re-serialization differs; parsed YAML is identical).
  • All five image tags exist on Docker Hub, published 2026-08-27.
  • The 2.1.0 changelog's central claim holds. Cross-checked all 42 env keys the chart sets against TBMQ 2.4.0's thingsboard-mqtt-broker.yml (469 vars) and tbmq-integration-executor.yml (93 vars): every one is still supported, and neither config has a single required-without-default ${VAR}, so no new mandatory setting exists.
  • The Jedis removal in refactor(tbmq): drop dead Jedis cluster topology-refresh keys from Redis ConfigMap #20 was right: REDIS_JEDIS_CLUSTER_TOPOLOGY_REFRESH_* is absent from 2.4.0 while REDIS_LETTUCE_* remains. The IE is Kafka-only, matching the chart's envFrom wiring.
  • kafka.strimzi.io/v1 is served by Strimzi 0.50.0, and the shipped minikube-values.yaml / minikube-pe-values.yaml match the guide's inline YAML exactly.

Changes

1. ArtifactHub showed no license (fix)

Chart.yaml used a bare licenses: Apache-2.0 key, which is not an ArtifactHub annotation. The API returned license: null for 2.1.0. Switched to the supported artifacthub.io/license.

2. Helper images were hardcoded and stale (feat)

Three image references were hardcoded in templates — thingsboard/toolbox:1.13.0 (broker validate-db init container) and busybox:1.36 (wait-for-postgres on the install Pod and pre-upgrade Job). Not being wired to values, they could not be repointed at a private registry or air-gapped mirror.

Now exposed as helperImages.toolbox / helperImages.busybox using the same repository/tag shape as tbmq.image, and bumped: toolbox 1.13.0 → 1.29.0 (was 16 releases behind), busybox 1.36 → 1.37.0 (the 1.36 tag is no longer rebuilt, so it carries unpatched base CVEs).

Both bumps were checked rather than assumed: toolbox 1.29.0 has the same layout as 1.13.0 (bash, psql, and script-runner.sh / psql-validator.sh under WORKDIR /scripts) with byte-identical script contents.

3. Minikube guide: wrong install-Pod delete policy (docs)

The guide said hook-succeeded,hook-failed. The template sets hook-succeeded,before-hook-creation — a failed install Pod is retained for inspection, not deleted. This inverted the debugging advice: readers were told to race kubectl logs -f during install, when in the case that actually matters the Pod is still there afterwards.

4. Minikube guide: no way to verify MQTT actually works (docs)

The guide ended at logging into the UI, which only exercises the HTTP port. Added a Smoke-test MQTT section that publishes and subscribes through the broker.

It uses the credential TBMQ creates at install — tbmq_websockets_username ("TBMQ WebSockets MQTT Credentials"), defined in common/data BrokerConstants so it exists in CE and PE alike, with no password. That needs no setup and matches what TBMQ's own "Getting started" guides use.

The section also explains the genuinely confusing case: MQTT_BASIC is the only auth provider enabled by default (X.509, JWT, SCRAM, HTTP off), so a client sending no username at all is rejected with CONNECTION_REFUSED_NOT_AUTHORIZED. Creating your own credential over the REST API is kept as an optional subsection for when you want a password or narrower topic rules.

An earlier revision of this branch got this wrong — it claimed the credential list starts empty and made readers create a credential before they could test anything. Corrected in fd32970.

Verification

Full Minikube guide run on a clean cluster (k8s v1.32.0): PGO 6.0.1 → PostgreSQL 17.9, Strimzi 0.50.0 → 3-node KRaft Kafka 4.0.0, Valkey 0.9.3. Steps 1–4 all worked verbatim on the unmodified chart first.

Then the release was wiped, the broker PVC deleted, the database dropped and recreated, and the modified chart installed from scratch:

  • tbmq-cluster-2.1.1 / app 2.4.0, both pods Ready, PVC Bound 1Gi
  • broker init container ran thingsboard/toolbox:1.29.0, exit 0 — its retry logic behaved correctly, failing the first schema probe against the empty DB and succeeding once the install Pod populated it
  • events confirm the busybox swap: busybox:1.36 on the old install, busybox:1.37.0 on the new one
  • tb_schema_settings2004000 | CE, 20 tables
  • anonymous client rejected as documented; -u tbmq_websockets_username with no password round-tripped tbmq/demo/hello hello from minikube at QoS 1
  • 0 ERROR lines in the broker log
  • helm lint clean on CE, PE, minikube-CE and minikube-PE; helm package produces a valid 2.1.1 tarball
  • image overrides confirmed: --set helperImages.toolbox.repository=registry.internal/mirror/toolbox renders correctly on all four paths, including the pre-upgrade Job under --is-upgrade

Step 5 (CE → PE migration) — also verified

Run against a QA license server with a real PE license. This exercises the pre-upgrade Job, which is one of the two places the new busybox image is used:

  • pre-upgrade Job tbmq-upgrade-2 ran with init container busybox:1.37.0, main container thingsboard/tbmq-pe-node:2.4.0PE, UPGRADE_TB=true, FROM_VERSION=ce — completed 1/1
  • Job log: Upgrading TBMQ from version CE to PE ...Upgrade finished successfully!Loading system data for PE...
  • tb_schema_settings2004000 | PE
  • both StatefulSets rolled to tbmq-pe-node:2.4.0PE / tbmq-pe-integration-executor:2.4.0PE
  • license client activated: Executed activateInstance method, Initialized ThingsBoard License Client with instanceId [...], plan data returned
  • per-Pod license cache written to /data/tbmq-instance-license-tbmq-tbmq-node-0.data, exactly the path the chart documents
  • 0 ERROR lines in the PE broker log; pre-existing MQTT credentials survived the migration
  • NOTES.txt correctly reported Edition: PE (Professional)

Two decisions for the reviewer

  1. Chart version. Bumped to 2.1.1 in a separate commit, because 2.1.0 is published and immutable so fixes 1 and 2 cannot reach ArtifactHub without a new version. Drop that commit if these should instead batch into 2.2.0.
  2. Metrics heads-up. Per ArtifactHub semantics artifacthub.io/changes now describes 2.1.1, which means the TBMQ 2.4.0 Prometheus metrics-rename warning no longer appears on the latest package page (it remains on 2.1.0's). It is also not in tbmq/README.md, whose newest upgrade section is still chart 1.x → 2.0.0. Worth carrying that entry forward, and/or adding a 2.3.0 → 2.4.0 upgrade section to the README.

Known gaps left out of scope

  • No .github/ CI — nothing runs helm lint on PRs.
  • No values.schema.json (has_values_schema: false on ArtifactHub), no provenance signing (signed: false), no artifacthub.io/links, no kubeVersion.
  • ArtifactHub's scanner ran for 2.1.0 (security_report_created_at is set) but produced an empty summary despite scanner_disabled: false — worth a look.

The chart declared its license with a bare `licenses: Apache-2.0` key, which is
not an Artifact Hub annotation, so Artifact Hub never picked it up — the package
page showed no license at all (the API returned `license: null` for 2.1.0).

Use the supported `artifacthub.io/license` annotation instead. The value must be
a valid SPDX identifier, which Apache-2.0 is.
The chart hardcoded three image references in its templates:
`thingsboard/toolbox:1.13.0` for the broker's `validate-db` init container, and
`busybox:1.36` for the `wait-for-postgres` init container on both the install Pod
and the pre-upgrade Job. Because they were not wired to values, there was no way
to repoint them at a private registry or an air-gapped mirror — the chart always
tried to pull them from Docker Hub.

Expose them as `helperImages.toolbox` and `helperImages.busybox`, each with the
same `repository` / `tag` shape already used by `tbmq.image`, and resolve them
through two new template helpers.

Also bump both to current releases: toolbox 1.13.0 -> 1.29.0 (1.13.0 was 16
releases behind) and busybox 1.36 -> 1.37.0 (the 1.36 tag is no longer rebuilt,
so it carries unpatched base-image CVEs). Both are drop-in replacements:
toolbox 1.29.0 has the same layout as 1.13.0 (bash, psql, and the
script-runner.sh / psql-validator.sh scripts under WORKDIR /scripts) and the
script contents are unchanged, and busybox only needs a shell and `nc`. Both
were verified running as init containers against a live PostgreSQL 17 cluster.
…ke test

Two fixes to the Minikube guide.

The note on the install Pod claimed the delete policy is
`hook-succeeded,hook-failed`, so Helm would remove the Pod "as soon as it
succeeds (or fails)". The template actually sets
`hook-succeeded,before-hook-creation`: a succeeded Pod is removed immediately,
but a FAILED Pod is deliberately retained and only cleaned up just before the
next hook run. That inverted the debugging advice — the guide told readers to
race `kubectl logs -f` during install, when in the case that actually matters
(a failed install) the Pod is still sitting there to inspect afterwards.

Second, the guide stopped at logging into the UI, which only exercises the
broker's HTTP port. TBMQ 2.4.0 enables the MQTT_BASIC authentication provider
with an empty credential list (X.509, JWT, SCRAM and HTTP are disabled by
default), so a freshly deployed broker refuses every MQTT client with
CONNECTION_REFUSED_NOT_AUTHORIZED. Anyone following the guide and then pointing
an MQTT client at the broker hit that with no explanation.

Add a "Smoke-test MQTT" section that says so upfront, shows the exact client
error and broker log lines, creates an MQTT_BASIC credential over the REST API,
and round-trips a message with mosquitto_sub / mosquitto_pub. Token extraction
uses sed so the guide adds no jq or python dependency.
2.1.0 is already published and immutable, so the license-annotation fix and the
new `helperImages` values only reach Artifact Hub under a new chart version.

Replace the `artifacthub.io/changes` entries with the ones describing 2.1.1, per
Artifact Hub semantics (the annotation lists what changed in *this* version;
2.1.0's entries stay visible on the 2.1.0 package page).

Note: this drops the TBMQ 2.4.0 Prometheus metrics-rename heads-up from the
latest version's changelog. If that warning should stay visible on the newest
package page, carry the entry forward here.
The MQTT smoke test added in the previous commit was wrong on its central
premise. It claimed TBMQ 2.4.0 enables MQTT_BASIC with an empty credential list,
so every client is refused until you create credentials.

TBMQ actually creates a system credential at install time —
`WS_SYSTEM_MQTT_CLIENT_CREDENTIALS_USERNAME` / "TBMQ WebSockets MQTT
Credentials", username `tbmq_websockets_username`, with no password. It is
defined in common/data BrokerConstants, so it exists in CE and PE alike, and
TBMQ's own "Getting started" guides publish and subscribe with it directly.
Verified against a live broker: a client passing `-u tbmq_websockets_username`
and no password authenticates and round-trips a message.

What is true is narrower: MQTT_BASIC is the only provider enabled by default, so
a client sending no username at all is rejected with
CONNECTION_REFUSED_NOT_AUTHORIZED. That is worth documenting, because it is the
confusing case — but it is not a reason to make readers create a credential
before they can test anything.

Rewrite the section to use the built-in credential (no setup, no REST call),
keep the rejection message as an explained aside, and demote creating your own
credential to an optional subsection for when you want a password or narrower
topic rules. Also add upstream's caveat about passing `-P` if the credential has
been changed, and correct the matching artifacthub.io/changes entry.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant