From a19a9aa2a76e0f054389e1e75d7758c1b40e4e26 Mon Sep 17 00:00:00 2001 From: Matthias Erll Date: Tue, 25 Nov 2025 18:41:07 +0100 Subject: [PATCH 1/4] chore: upgrade Gitea to 1.25.2 --- charts/gitea/Chart.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/charts/gitea/Chart.yaml b/charts/gitea/Chart.yaml index 681d4028c3..b4d8fda4fc 100644 --- a/charts/gitea/Chart.yaml +++ b/charts/gitea/Chart.yaml @@ -11,7 +11,7 @@ annotations: - kind: changed description: update alpine/helm docker tag to v3.19.0 (#954) apiVersion: v2 -appVersion: 1.24.7 +appVersion: 1.25.2 dependencies: - condition: postgresql.enabled name: postgresql From 4a15bbce671c96af240ffeda1fec50598e41b4fc Mon Sep 17 00:00:00 2001 From: Matthias Erll Date: Thu, 27 Nov 2025 14:25:28 +0100 Subject: [PATCH 2/4] fix: added post-install password validity reset --- src/common/k8s.test.ts | 40 +++++++++++++++++++ src/common/k8s.ts | 22 ++++++++++ .../runtime-upgrades/runtime-upgrades.ts | 9 ++++- src/common/runtime-upgrades/v4.13.0.ts | 15 ++++++- 4 files changed, 84 insertions(+), 2 deletions(-) diff --git a/src/common/k8s.test.ts b/src/common/k8s.test.ts index 2680d0d260..9dc4149ec6 100644 --- a/src/common/k8s.test.ts +++ b/src/common/k8s.test.ts @@ -7,6 +7,7 @@ import { KubeConfig, PatchStrategy, setHeaderOptions, + V1Deployment, V1Pod, V1PodList, V1ResourceRequirements, @@ -169,6 +170,45 @@ describe('StatefulSet tests', () => { jest.clearAllMocks() }) + describe('getPodsOfDeployment', () => { + it('should return pods matching the Deployment label selector', async () => { + const mockDeployment = { + spec: { + selector: { + matchLabels: { app: 'my-app' }, + }, + }, + } + + const mockPodList: V1PodList = { + items: [{ metadata: { name: 'pod-1' } }, { metadata: { name: 'pod-2' } }], + } as V1PodList + + mockAppsApi.readNamespacedDeployment.mockResolvedValue(mockDeployment as any) + mockCoreApi.listNamespacedPod.mockResolvedValue(mockPodList as any) + + const pods = await k8s.getPodsOfDeployment(mockAppsApi, mockCoreApi, 'my-deploy', 'my-namespace') + expect(mockAppsApi.readNamespacedDeployment).toHaveBeenCalledWith({ + name: 'my-deploy', + namespace: 'my-namespace', + }) + expect(mockCoreApi.listNamespacedPod).toHaveBeenCalledWith({ + labelSelector: 'app=my-app', + namespace: 'my-namespace', + }) + expect(pods).toEqual(mockPodList) + }) + + it('should throw an error if matchLabels is missing', async () => { + const mockDeployment: V1Deployment = {} as V1Deployment + mockAppsApi.readNamespacedDeployment.mockResolvedValue(mockDeployment as any) + + await expect(k8s.getPodsOfDeployment(mockAppsApi, mockCoreApi, 'my-deploy', 'my-namespace')).rejects.toThrow( + 'Deployment my-deploy does not have matchLabels', + ) + }) + }) + describe('getPodsOfStatefulSet', () => { it('should return pods matching the StatefulSet label selector', async () => { const mockStatefulSet = { diff --git a/src/common/k8s.ts b/src/common/k8s.ts index ff0d7907a2..21508619b3 100644 --- a/src/common/k8s.ts +++ b/src/common/k8s.ts @@ -532,6 +532,28 @@ export async function createUpdateConfigMap( } } +export async function getPodsOfDeployment( + appsApi: AppsV1Api, + coreApi: CoreV1Api, + deploymentName: string, + namespace: string, +) { + const deployment = await appsApi.readNamespacedDeployment({ name: deploymentName, namespace }) + + if (!deployment.spec?.selector?.matchLabels) { + throw new Error(`Deployment ${deploymentName} does not have matchLabels`) + } + + const labelSelector = Object.entries(deployment.spec.selector.matchLabels) + .map(([key, value]) => `${key}=${value}`) + .join(',') + + return await coreApi.listNamespacedPod({ + namespace, + labelSelector, + }) +} + export async function getPodsOfStatefulSet( appsApi: AppsV1Api, statefulSetName: string, diff --git a/src/common/runtime-upgrades/runtime-upgrades.ts b/src/common/runtime-upgrades/runtime-upgrades.ts index 539ffb1e74..5cc5a16ac2 100644 --- a/src/common/runtime-upgrades/runtime-upgrades.ts +++ b/src/common/runtime-upgrades/runtime-upgrades.ts @@ -6,7 +6,7 @@ import { updateDbCollation } from './cloudnative-pg' import { removeOldMinioResources } from './remove-old-minio-resources' import { detectAndRestartOutdatedIstioSidecars } from './restart-istio-sidecars' import { upgradeKnativeServing } from './upgrade-knative-serving-cr' -import { detachApplicationFromApplicationSet, pruneArgoCDImageUpdater } from './v4.13.0' +import { detachApplicationFromApplicationSet, pruneArgoCDImageUpdater, resetGiteaPasswordValidity } from './v4.13.0' import { removeHttpBinApplication } from './remove-httpbin-application' export interface RuntimeUpgradeContext { @@ -150,5 +150,12 @@ export const runtimeUpgrades: RuntimeUpgrades = [ post: async () => { await removeHttpBinApplication() }, + applications: { + 'gitea-gitea': { + post: async (context: RuntimeUpgradeContext) => { + await resetGiteaPasswordValidity(context) + }, + }, + }, }, ] diff --git a/src/common/runtime-upgrades/v4.13.0.ts b/src/common/runtime-upgrades/v4.13.0.ts index 46f1d6fcbd..a4a9fc3b43 100644 --- a/src/common/runtime-upgrades/v4.13.0.ts +++ b/src/common/runtime-upgrades/v4.13.0.ts @@ -1,6 +1,6 @@ import { ApiException } from '@kubernetes/client-node' import { ARGOCD_APP_PARAMS, ObjectMetadataCollection } from '../constants' -import { getArgoCdApp, k8s, setArgoCdAppSync } from '../k8s' +import { exec, getArgoCdApp, getK8sSecret, getPodsOfDeployment, k8s, setArgoCdAppSync } from '../k8s' import { RuntimeUpgradeContext } from './runtime-upgrades' async function scaleDeployment(context: RuntimeUpgradeContext, namespace: string, name: string, replicas: number) { @@ -135,3 +135,16 @@ export async function detachApplicationFromApplicationSet(context: RuntimeUpgrad await setArgoCdAppSync('argocd-argocd', true, customApi) d.log('Cleanup complete: ApplicationSets removed, Applications retained.') } + +export async function resetGiteaPasswordValidity(context: RuntimeUpgradeContext) { + context.debug.info('Resetting status of Gitea admin credentials') + const giteaPods = await getPodsOfDeployment(k8s.app(), k8s.core(), 'gitea', 'gitea') + const [firstPod] = giteaPods.items + // In case Gitea pods happened to be restarting in the meantime, it will likely fix the issue by itself + if (firstPod) { + const giteaCredentialsSecret = await getK8sSecret('gitea-credentials', 'apl-operator') + const userName = giteaCredentialsSecret?.GITEA_USERNAME ?? 'otomi-admin' + const resetCmd = ['gitea', 'admin', 'user', 'must-change-password', '--unset', userName as string] + await exec(firstPod.metadata!.namespace as string, firstPod.metadata!.name as string, 'gitea', resetCmd) + } +} From 8081fe2a38fbbeb992f349f38275a28784ed3cf3 Mon Sep 17 00:00:00 2001 From: Matthias Erll Date: Thu, 27 Nov 2025 17:31:26 +0100 Subject: [PATCH 3/4] feat: log output --- src/common/runtime-upgrades/v4.13.0.ts | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/src/common/runtime-upgrades/v4.13.0.ts b/src/common/runtime-upgrades/v4.13.0.ts index a4a9fc3b43..b528212b1c 100644 --- a/src/common/runtime-upgrades/v4.13.0.ts +++ b/src/common/runtime-upgrades/v4.13.0.ts @@ -145,6 +145,12 @@ export async function resetGiteaPasswordValidity(context: RuntimeUpgradeContext) const giteaCredentialsSecret = await getK8sSecret('gitea-credentials', 'apl-operator') const userName = giteaCredentialsSecret?.GITEA_USERNAME ?? 'otomi-admin' const resetCmd = ['gitea', 'admin', 'user', 'must-change-password', '--unset', userName as string] - await exec(firstPod.metadata!.namespace as string, firstPod.metadata!.name as string, 'gitea', resetCmd) + const { stdout, stderr } = await exec( + firstPod.metadata!.namespace as string, + firstPod.metadata!.name as string, + 'gitea', + resetCmd, + ) + context.debug.info(stderr, stdout) } } From 23f102e16d1da1ab9aef8ae0e15e56dc13b8f5f8 Mon Sep 17 00:00:00 2001 From: Matthias Erll Date: Mon, 1 Dec 2025 16:06:47 +0100 Subject: [PATCH 4/4] chore: move upgrade to following release --- src/common/runtime-upgrades/runtime-upgrades.ts | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/common/runtime-upgrades/runtime-upgrades.ts b/src/common/runtime-upgrades/runtime-upgrades.ts index 5cc5a16ac2..85bf2885c8 100644 --- a/src/common/runtime-upgrades/runtime-upgrades.ts +++ b/src/common/runtime-upgrades/runtime-upgrades.ts @@ -150,6 +150,9 @@ export const runtimeUpgrades: RuntimeUpgrades = [ post: async () => { await removeHttpBinApplication() }, + }, + { + version: '4.14.0', applications: { 'gitea-gitea': { post: async (context: RuntimeUpgradeContext) => {