Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
75 changes: 75 additions & 0 deletions src/components/upgrade-instructions/TrendzK8sJobSteps.astro
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
---
import { Code } from '@astrojs/starlight/components';

interface Props {
version: string;
}

const { version } = Astro.props;

// The image reads the current version from the database; the Deployment never runs the upgrade itself
const k8sUpgradeJob = `apiVersion: batch/v1
kind: Job
metadata:
name: trendz-upgrade
namespace: trendz
spec:
backoffLimit: 0
template:
spec:
restartPolicy: Never
containers:
- name: trendz-upgrade
image: thingsboard/trendz:${version}
env:
- name: UPGRADE_TRENDZ
value: "true"
envFrom:
- configMapRef:
name: trendz-app-db-config
volumeMounts:
- name: trendz-app-config
mountPath: /trendz-config-files
volumes:
- name: trendz-app-config
configMap:
name: trendz-app-config
items:
- key: trendz.conf
path: trendz.conf
- key: logback.xml
path: logback.xml`;
const k8sJobLogOutput =
'Start upgrading Trendz from version …\n…\nCurrent version is …, upgrade is not needed.';
---

<h3>Update image versions</h3>
<p>Set the image versions to <strong>{version}</strong>. Do not apply the files yet.</p>
<ul>
<li><code>trendz-app-deployment.yml</code>: <code>thingsboard/trendz:{version}</code></li>
<li><code>trendz-python-executor-deployment.yml</code>: <code>thingsboard/trendz-python-executor:{version}</code></li>
</ul>

<h3>Stop Trendz</h3>
<Code code={`kubectl scale deployment trendz-app-deployment --replicas=0\nkubectl wait --for=delete pod -l app=trendz-app-pod-label --timeout=120s`} lang="bash" />

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Every trendz-k8s resource lives in namespace trendz (the Job YAML hard-codes it too), but none of these commands pass -n trendz. Neither do kubectl wait … job/trendz-upgrade, kubectl logs job/trendz-upgrade, kubectl delete job trendz-upgrade or the final scale below. kubectl apply -f works because the manifests carry the namespace. The rest resolve against the current context, which is default for most users. They fail with NotFound, and the dangerous case is this first one: if scale --replicas=0 fails and the reader carries on, the upgrade Job migrates the DB while Trendz is still running.

Could you add -n trendz to each command, or add a kubectl config set-context --current --namespace=trendz step at the top? Also, depending on the kubectl version, kubectl wait --for=delete pod -l … can return no matching resources found when the pods are already gone. A short note that this is fine would save a confused reader.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Added: kubectl config set-context --current --namespace=trendz in Prepare section
Added: If the pods are already gone, kubectl wait may print no matching resources found. This is expected.

<p>If the pods are already gone, <code>kubectl wait</code> may print <code>no matching resources found</code>. This is expected.</p>

<h3>Create the upgrade job</h3>
<Code code={k8sUpgradeJob} lang="yaml" title="trendz-upgrade.yml" meta="download='trendz-upgrade.yml'" />
<p>The ConfigMap names, keys and namespace must match your <code>trendz-app-deployment.yml</code>. Installations created before 1.15 use the keys <code>conf</code> and <code>logback</code>.</p>

<h3>Run the upgrade job</h3>
<Code code={`kubectl apply -f trendz-upgrade.yml\nkubectl wait --for=condition=complete job/trendz-upgrade --timeout=900s`} lang="bash" />

<h3>Verify the upgrade</h3>
<Code code="kubectl logs job/trendz-upgrade" lang="bash" />
<p>Expected output:</p>
<Code code={k8sJobLogOutput} lang="text" />

<h3>Delete the job</h3>
<Code code="kubectl delete job trendz-upgrade" lang="bash" />

<h3>Start Trendz</h3>
<Code code={`kubectl apply -f trendz-python-executor-deployment.yml\nkubectl apply -f trendz-app-deployment.yml`} lang="bash" />
<p>If you run more than one pod, restore the replica count:</p>
<Code code="kubectl scale deployment trendz-app-deployment --replicas=<pod-count>" lang="bash" />
68 changes: 38 additions & 30 deletions src/components/upgrade-instructions/TrendzUpgradeSteps.astro
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import { Code } from '@astrojs/starlight/components';
import { getTrendzUpgradeStepVersions } from '~/models/trendz-upgrade-instructions';
import { getUpgradeHeading } from '~/models/upgrade-shared';
import ConfigFileNote from './ConfigFileNote.astro';
import TrendzK8sJobSteps from '@components/upgrade-instructions/TrendzK8sJobSteps.astro';

interface Props {
platform: 'ubuntu' | 'centos' | 'windows' | 'docker' | 'kubernetes';
Expand Down Expand Up @@ -70,6 +71,10 @@ const javaGuideLink =
<p>Select the correct kube-config context before running any commands:</p>
<Code code="kubectl config get-contexts" lang="bash" />
<Code code="kubectl config use-context <your-config-name>" lang="bash" />
<p>Set <code>trendz</code> as the default namespace, so the commands below run in it:</p>
<Code code="kubectl config set-context --current --namespace=trendz" lang="bash" />
<h3>Back up the database</h3>
<p>Back up the <code>trendz</code> database with <code>pg_dump</code> or your PostgreSQL provider's backup tools.</p>
</section>
)}

Expand Down Expand Up @@ -278,43 +283,46 @@ const javaGuideLink =
</div>
</aside>

<h3>Reduce pods count</h3>
<p>The deployment must have exactly one running pod for the upgrade to succeed:</p>
<Code code="kubectl scale deployment trendz-app-deployment --replicas=1" lang="bash" />

{v.fromVersion && (
{v.fromVersion ? (
<>
<h3>Reduce pod count</h3>
<p>Scale the deployment to one pod:</p>
<Code code="kubectl scale deployment trendz-app-deployment --replicas=1" lang="bash" />

<h3>Create upgrade flag file</h3>
<p>Get the current pod name:</p>
<p>Get the pod name:</p>
<Code code="kubectl get pods -l app=trendz-app-pod-label" lang="bash" />
<p>Create the <code>.upgradeversion</code> flag file inside the pod, replacing <code>&lt;POD_NAME&gt;</code> with the name from the previous command. Set the version to the one you are currently running:</p>
<p>Create the flag file in the pod. Replace <code>&lt;POD_NAME&gt;</code> and set the version you are <strong>currently running</strong>:</p>
<Code code={k8sFlagFileCmd} lang="bash" />
<aside class="starlight-aside starlight-aside--note">
<p class="starlight-aside__title" aria-hidden="true">Note</p>
<div class="starlight-aside__content">
<p>Set the value to the version you are <strong>currently running</strong>, not the version you are upgrading to. You can upgrade directly from <strong>any earlier version</strong>.</p>
</div>
</aside>
</>
)}

<h3>Update image version</h3>
<p>Open <code>trendz-app-deployment.yml</code> and update the <code>image</code> field to <strong>thingsboard/trendz:{v.version}</strong>:</p>
<Code code="nano trendz-app-deployment.yml" lang="bash" />
<h3>Update image version</h3>
<p>In <code>trendz-app-deployment.yml</code>, set the image to <strong>thingsboard/trendz:{v.version}</strong> and apply it:</p>
<Code code="kubectl apply -f trendz-app-deployment.yml" lang="bash" />

<h3>Apply the deployment</h3>
<p>Apply the updated configuration and wait until the pod is ready:</p>
<Code code="kubectl apply -f trendz-app-deployment.yml" lang="bash" />
<h3>Verify the upgrade</h3>
<p>Check the pod logs:</p>
<Code code="kubectl logs -f <trendz-pod-name>" lang="bash" />
<p>Expected output:</p>
<Code code={k8sLogOutput} lang="text" />

<h3>Verify the upgrade</h3>
<p>Stream the pod logs to confirm the upgrade ran successfully:</p>
<Code code="kubectl logs -f <trendz-pod-name>" lang="bash" />
<p>Look for the following lines:</p>
<Code code={k8sLogOutput} lang="text" />

<h3>Restore pods count</h3>
<p>After the upgrade is complete, restore your preferred replica count:</p>
<Code code="kubectl scale deployment trendz-app-deployment --replicas=<pod-count>" lang="bash" />
<h3>Restore pod count</h3>
<Code code="kubectl scale deployment trendz-app-deployment --replicas=<pod-count>" lang="bash" />
</>
) : (
<>
{v.patch && v.baseVersion && (
<aside class="starlight-aside starlight-aside--note">
<p class="starlight-aside__title" aria-hidden="true">Upgrading from {v.baseVersion}.x</p>
<div class="starlight-aside__content">
<p>No upgrade job is needed. Set the image versions to <strong>{v.version}</strong> in <code>trendz-app-deployment.yml</code> and <code>trendz-python-executor-deployment.yml</code>, then apply them:</p>

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The aside says "No upgrade job is needed", and the full job procedure renders right after it. Only the aside title ("Upgrading from 1.15.0.x") scopes it. A reader upgrading 1.15.0.x → 1.15.1.1 sees this note for the same target version and may skip the job they actually need. Could you end the aside with something like "Otherwise, follow the steps below." (or "…and skip the steps below") so it's explicit which path applies?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Added: "From any other version, follow the steps below."

<Code code={`kubectl apply -f trendz-python-executor-deployment.yml\nkubectl apply -f trendz-app-deployment.yml`} lang="bash" />
<p>From any other version, follow the steps below.</p>
</div>
</aside>
)}
<TrendzK8sJobSteps version={v.version} />
</>
)}
</>
)}

Expand Down
24 changes: 24 additions & 0 deletions src/content/_includes/docs/trendz/releases/v1-15-x.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,15 @@

---

## v1.15.1.1 (Apr 28, 2026)

**Bug fixes:**

- Fixed scatter plot rendering.
- Fixed the chart options dialog.

---

## v1.15.1 (Apr 15, 2026)

**New features:**
Expand All @@ -45,6 +54,21 @@

---

## v1.15.0.6 (Mar 25, 2026)

**Improvements:**

- Improved Metric Explorer performance.

**Bug fixes:**

- Fixed export to dashboard with aliases.
- Fixed report REST API authentication.
- Fixed ThingsBoard version detection.
- Fixed attribute loading.

---

## v1.15.0.5 (Feb 26, 2026)

**Bug fixes:**
Expand Down
2 changes: 2 additions & 0 deletions src/models/trendz-releases-table.ts
Original file line number Diff line number Diff line change
Expand Up @@ -67,7 +67,9 @@ export const TRENDZ_RELEASE_FAMILIES: TrendzReleaseFamily[] = [
patches: [
{ version: 'v1.15.2.1', date: 'Jun 24, 2026' },
{ version: 'v1.15.2', date: 'May 15, 2026' },
{ version: 'v1.15.1.1', date: 'Apr 28, 2026' },
{ version: 'v1.15.1', date: 'Apr 15, 2026' },
{ version: 'v1.15.0.6', date: 'Mar 25, 2026' },
{ version: 'v1.15.0.5', date: 'Feb 26, 2026' },
{ version: 'v1.15.0.4', date: 'Feb 9, 2026' },
{ version: 'v1.15.0', date: 'Jan 20, 2026' },
Expand Down
45 changes: 32 additions & 13 deletions src/models/trendz-upgrade-instructions.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
// Relative import on purpose: keeps this module loadable from the Astro
// config chain, which resolves modules before tsconfig path aliases apply.
import { assertNewestFirst, latestPatchPerBaseline } from './upgrade-shared.ts';
import { assertNewestFirst } from './upgrade-shared.ts';

export interface TrendzUpgradeVersion {
/** Raw version string, e.g. "1.15.0.4", "1.13.2", "1.10.3-HF7" */
Expand Down Expand Up @@ -52,24 +52,19 @@ export function getTrendzFamilySlug(family: string): string {
}

/**
* Versions to render on a Trendz upgrade-instruction page (optionally scoped
* to a family). Only the newest patch of each `baseVersion` is kept; entries
* without a `baseVersion` are always kept. Input is assumed newest-first,
* matching the ordering of `TRENDZ_UPGRADE_VERSIONS`.
* Versions to render on a Trendz upgrade-instruction page, optionally scoped
* to a family. Every listed version gets its own section, so a patch stays on
* the page after a newer patch of the same `baseVersion` ships.
*/
export function getTrendzUpgradeStepVersions(family?: string): TrendzUpgradeVersion[] {
const scoped = family
? TRENDZ_UPGRADE_VERSIONS.filter((v) => v.family === family)
: TRENDZ_UPGRADE_VERSIONS;
return latestPatchPerBaseline(scoped);
return family ? TRENDZ_UPGRADE_VERSIONS.filter((v) => v.family === family) : TRENDZ_UPGRADE_VERSIONS;
}

/**
* All Trendz versions available for upgrade (non-vulnerable), newest-first.
* Ordering is load-bearing: TRENDZ_UPGRADE_FAMILIES dedups by position, steps
* render in array order, and getTrendzUpgradeStepVersions treats the first
* entry per baseVersion as the latest. The assertNewestFirst() call below
* fails the build on an out-of-order insert.
* Ordering is load-bearing: TRENDZ_UPGRADE_FAMILIES dedups by position and
* steps render in array order. The assertNewestFirst() call below fails the
* build on an out-of-order insert.
*/
export const TRENDZ_UPGRADE_VERSIONS: TrendzUpgradeVersion[] = [
{
Expand Down Expand Up @@ -120,6 +115,18 @@ export const TRENDZ_UPGRADE_VERSIONS: TrendzUpgradeVersion[] = [
// 1.15.x uses the new upgrade mechanism — no --fromVersion flag needed
haproxyNote: false,
},
{
version: '1.15.1.1',
displayVersion: '1.15.1.1',
family: '1.15',
baseVersion: '1.15.1',
releaseDate: 'Apr 28 2026',
lts: true,
patch: true,
anchor: 'v1-15-1-1',
// 1.15.x uses the new upgrade mechanism — no --fromVersion flag needed
haproxyNote: false,
},
{
version: '1.15.1',
displayVersion: '1.15.1',
Expand All @@ -131,6 +138,18 @@ export const TRENDZ_UPGRADE_VERSIONS: TrendzUpgradeVersion[] = [
// 1.15.x uses the new upgrade mechanism — no --fromVersion flag needed
haproxyNote: false,
},
{
version: '1.15.0.6',
displayVersion: '1.15.0.6',
family: '1.15',
baseVersion: '1.15.0',
releaseDate: 'Mar 25 2026',
lts: true,
patch: true,
anchor: 'v1-15-0-6',
// 1.15.x uses the new upgrade mechanism — no --fromVersion flag needed
haproxyNote: true,
},
{
version: '1.15.0.5',
displayVersion: '1.15.0.5',
Expand Down
Loading