Compare commits

...
Sign in to create a new pull request.

74 commits

Author SHA1 Message Date
Andrei Kvapil
dc404f48fe
ci(pull-requests): replace GH_PAT with cozystack-ci GitHub App token (#2383)
## Summary
- Replace `GH_PAT` (cozystack-bot PAT) with `cozystack-ci` GitHub App
token in `pull-requests.yaml`
- This was missed in #2351 and broke the `resolve_assets` / `e2e` jobs
for release PRs (draft releases not visible with invalid token)

## Test plan
- [ ] Re-run the release PR pipeline for `release-1.1.6` and verify
`resolve_assets` job passes

<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->

## Summary by CodeRabbit

* **Chores**
* Updated continuous integration authentication mechanism to use GitHub
App tokens instead of personal access tokens.

<!-- end of auto-generated comment: release notes by coderabbit.ai -->

Signed-off-by: Andrei Kvapil <kvapss@gmail.com>
2026-04-13 10:08:55 +02:00
Andrei Kvapil
63af323142
Release v1.0.7 (#2276)
This PR prepares the release `v1.0.7`.
2026-03-30 13:33:17 +02:00
cozystack-bot
a19de3f4f2 Prepare release v1.0.7
Signed-off-by: cozystack-bot <217169706+cozystack-bot@users.noreply.github.com>
2026-03-30 01:36:34 +00:00
Kirill Ilin
f70d03d2c2
[Backport release-1.0] [linstor] Fix swapped VMPodScrape job labels (#2288)
# Description
Backport of #2264 to `release-1.0`.
2026-03-27 17:51:57 +05:00
Kirill Ilin
58df2d6fbf
[Backport release-1.0] [piraeus-operator] Fix LINSTOR satellite alert labels and scrape flapping false positives (#2287)
# Description
Backport of #2265 to `release-1.0`.
2026-03-27 17:51:36 +05:00
Kirill Ilin
bf29c700dd
[Backport release-1.0] [dashboard] Fix EndpointSlice column definitions for Pod serving table (#2282)
# Description
Backport of #2266 to `release-1.0`.
2026-03-27 17:51:17 +05:00
Kirill Ilin
d0ad701c87
[Backport release-1.0] [system] Fix tenant RBAC for endpointslices read access (#2284)
# Description
Backport of #2257 to `release-1.0`.
2026-03-27 17:51:07 +05:00
sasha-sup
ee148f3e26 [linstor] Fix swapped VMPodScrape job labels
Signed-off-by: sasha-sup <alexsup4ik@gmail.com>
(cherry picked from commit bad59103f4)
2026-03-27 12:50:59 +00:00
sasha-sup
0ac077fde5 [piraeus-operator] Split LINSTOR controller availability and metrics alerts
Signed-off-by: sasha-sup <alexsup4ik@gmail.com>
(cherry picked from commit a052a650b0)
2026-03-27 12:50:55 +00:00
sasha-sup
125dd4997e [piraeus-operator] Add hold time to LINSTOR controller offline alert
Signed-off-by: sasha-sup <alexsup4ik@gmail.com>
(cherry picked from commit 4a92d7753c)
2026-03-27 12:50:55 +00:00
sasha-sup
683547013e [piraeus-operator] Fix LINSTOR satellite alert labels and scrape flapping false positives
Signed-off-by: sasha-sup <alexsup4ik@gmail.com>
(cherry picked from commit a562d9cb80)
2026-03-27 12:50:55 +00:00
Kirill Ilin
4f3d613219 fix(rbac): add endpointslices read access for tenant roles
Dashboard requests EndpointSlices from discovery.k8s.io API group
to display "Pod serving" section on Service details page. Without
this permission, tenant users see a 403 error.

Assisted-By: Claude AI
Signed-off-by: Kirill Ilin <stitch14@yandex.ru>
(cherry picked from commit ab92b67c3f)
2026-03-27 12:49:00 +00:00
Kirill Ilin
f37dda8f79 fix(dashboard): add EndpointSlice column definitions for Pod serving table
The service details page showed "Raw:" and "Invalid Date" in the Pod
serving table because the EnrichedTable referenced customizationId
"factory-kube-service-details-endpointslice" which had no corresponding
CustomColumnsOverride. Add column definitions for Pod, Addresses, Ready,
and Node fields.

Assisted-By: Claude AI
Signed-off-by: Kirill Ilin <stitch14@yandex.ru>
(cherry picked from commit 37f1b3b59c)
2026-03-27 12:48:55 +00:00
Kirill Ilin
f54ec49ce5
[Backport release-1.0] [dashboard] Fix broken backup menu links missing cluster context (#2270)
# Description
Backport of #2232 to `release-1.0`.
2026-03-26 18:56:13 +05:00
Kirill Ilin
f4d4e82c49
[Backport release-1.0] [platform] Add missing apps to tenant admin RBAC (#2271)
# Description
Backport of #2268 to `release-1.0`.
2026-03-26 18:55:29 +05:00
Kirill Ilin
8295eaaeac fix(platform): add missing apps to tenant admin RBAC
The cozy:tenant:admin:base ClusterRole was missing several application
resources from apps.cozystack.io, preventing tenant admins from creating
them (the "Add" button was inactive in the dashboard).

Add the following resources: foundationdbs, harbors, mongodbs, openbaos,
opensearches, qdrants, vpns.

Assisted-By: Claude AI
Signed-off-by: Kirill Ilin <stitch14@yandex.ru>
(cherry picked from commit 8e01eb5f7e)
2026-03-26 13:05:16 +00:00
Kirill Ilin
6ef4d5d97e [dashboard] Add missing baseFactoriesMapping for backup resources
Backup resources (plans, backupjobs, backups) are not
ApplicationDefinitions, so ensureNavigation() never adds their
baseFactoriesMapping entries. Without these mappings the OpenUI
frontend cannot resolve the {cluster} context for backup pages,
producing broken sidebar links with an empty cluster segment
(e.g. /openapi-ui//tenant-root/...).

Add the three missing entries to the static Navigation resource.

Assisted-By: Claude AI
Signed-off-by: Kirill Ilin <stitch14@yandex.ru>
(cherry picked from commit 398ca5844a)
2026-03-26 12:49:30 +00:00
Andrei Kvapil
fa97b3b8e6
Release v1.0.6 (#2250)
This PR prepares the release `v1.0.6`.
2026-03-20 15:47:15 +01:00
cozystack-bot
e0b669b0e0 Prepare release v1.0.6
Signed-off-by: cozystack-bot <217169706+cozystack-bot@users.noreply.github.com>
2026-03-20 01:36:04 +00:00
Andrei Kvapil
a41e120b83
Release v1.0.6 (#2237)
This PR prepares the release `v1.0.6`.
2026-03-19 07:59:45 +01:00
cozystack-bot
e61e14b300 Prepare release v1.0.6
Signed-off-by: cozystack-bot <217169706+cozystack-bot@users.noreply.github.com>
2026-03-19 01:36:21 +00:00
Andrei Kvapil
f793ebd0a3
[Backport release-1.0] [dashboard] Add secret-hash annotation to KeycloakClient for secret sync (#2240)
# Description
Backport of #2231 to `release-1.0`.
2026-03-18 12:53:25 +01:00
Kirill Ilin
e7b1256d14 [dashboard] Add secret-hash annotation to KeycloakClient for secret sync
Add secret-hash annotation to the dashboard KeycloakClient CRD resource
so that when the Kubernetes Secret value changes, the operator detects
the CRD update and reconciles the client secret in Keycloak.

Without this annotation, if the dashboard-client Secret is recreated
with a new value (e.g. after upgrade), the KeycloakClient spec remains
unchanged, the operator skips reconciliation, and Keycloak retains the
stale secret — causing authentication failures for the dashboard.

Assisted-By: Claude AI
Signed-off-by: Kirill Ilin <stitch14@yandex.ru>
(cherry picked from commit bb5ee3ea4a)
2026-03-18 10:23:41 +00:00
Andrei Kvapil
4de45cb6ac
[Backport release-1.0] [etcd] Add protective limits to defrag CronJob (#2235)
# Description
Backport of #2233 to `release-1.0`.
2026-03-17 17:40:55 +01:00
Kirill Ilin
9e80439d4e fix(etcd): add protective limits to defrag CronJob
Without concurrencyPolicy and job limits, the defrag CronJob can
accumulate hundreds of running/failed pods during cluster upgrades
when etcd is temporarily unavailable. This was observed after
upgrading to v1.1.2 where defrag jobs piled up across tenants.

Assisted-By: Claude AI
Signed-off-by: Kirill Ilin <stitch14@yandex.ru>
(cherry picked from commit ed8ba3beec)
2026-03-17 16:36:29 +00:00
Andrei Kvapil
593adcd9cf
[Backport release-1.0] [kubernetes] Fix CiliumNetworkPolicy endpointSelector for multi-node RWX volumes (#2228)
# Description
Backport of #2227 to `release-1.0`.
2026-03-17 09:31:15 +01:00
mattia-eleuteri
1dfa6c4317 [kubernetes] Fix CiliumNetworkPolicy endpointSelector for multi-node RWX volumes
When an NFS-backed RWX volume is published to multiple VMs, the
CiliumNetworkPolicy egress rule only allowed traffic from the first VM.
The endpointSelector.matchLabels was set once on creation and never
broadened, causing NFS mounts to hang on all nodes except the first.

Switch from matchLabels to matchExpressions (operator: In) so the
selector can list multiple VM names. Rebuild the selector whenever
ownerReferences are added or removed.

Signed-off-by: mattia-eleuteri <mattia@hidora.io>
(cherry picked from commit cc5ec0b7a3)
2026-03-16 16:22:05 +00:00
Andrei Kvapil
28c9ad9253
Release v1.0.5 (#2219)
This PR prepares the release `v1.0.5`.
2026-03-13 18:30:05 +01:00
cozystack-bot
8c49cf373d Prepare release v1.0.5
Signed-off-by: cozystack-bot <217169706+cozystack-bot@users.noreply.github.com>
2026-03-13 15:34:14 +00:00
Andrei Kvapil
c0ea9daca5
[Backport release-1.0] fix(api): skip OpenAPI post-processor for non-apps group versions (#2216)
# Description
Backport of #2212 to `release-1.0`.
2026-03-13 16:24:16 +01:00
Andrei Kvapil
f0134cf6ae Revert "fix(operator): requeue packages when dependencies are not ready"
This reverts commit f906a0d8ad.

Signed-off-by: Andrei Kvapil <kvapss@gmail.com>
(cherry picked from commit 2b60c010dd)
2026-03-13 15:23:34 +00:00
Andrei Kvapil
5e897ef207 fix(operator): requeue packages when dependencies are not ready
When dependencies are not ready the reconciler returned without
requeueing, relying solely on watch events to re-trigger. If a watch
event was missed (controller restart, race condition, dependency already
ready before watch setup), the package would stay stuck in
DependenciesNotReady forever.

Add RequeueAfter: 30s so dependencies are periodically rechecked.

Co-Authored-By: Claude <noreply@anthropic.com>
Signed-off-by: Andrei Kvapil <kvapss@gmail.com>
(cherry picked from commit f906a0d8ad)
2026-03-13 15:23:34 +00:00
Andrei Kvapil
c10fdc36b8 fix(api): skip OpenAPI post-processor for non-apps group versions
The OpenAPI PostProcessSpec callback is invoked for every group-version
(apps, core, version, etc.), but the Application schema cloning logic
only applies to apps.cozystack.io. When called for other GVs the base
Application schemas are absent, causing a spurious error log on every
API server start.

Return early instead of erroring when the base schemas are not found.

Co-Authored-By: Claude <noreply@anthropic.com>
Signed-off-by: Andrei Kvapil <kvapss@gmail.com>
(cherry picked from commit ee83aaa82e)
2026-03-13 15:23:34 +00:00
Andrei Kvapil
92bf13a9fc
Release v1.0.4 (#2186)
This PR prepares the release `v1.0.4`.
2026-03-10 22:58:56 +01:00
cozystack-bot
c055fcbb48 Prepare release v1.0.4
Signed-off-by: cozystack-bot <217169706+cozystack-bot@users.noreply.github.com>
2026-03-10 20:34:42 +00:00
Andrei Kvapil
81f2546f44
[Backport release-1.0] fix(dashboard): exclude hidden MarketplacePanel resources from sidebar menu (#2204)
# Description
Backport of #2177 to `release-1.0`.
2026-03-10 17:50:23 +01:00
Andrei Kvapil
3251991014
[Backport release-1.0] fix(dashboard): preserve disabled/hidden state on MarketplacePanel reconciliation (#2202)
# Description
Backport of #2176 to `release-1.0`.
2026-03-10 17:49:56 +01:00
IvanHunters
1f0df5fbcd fix(dashboard): exclude hidden MarketplacePanel resources from sidebar menu
The sidebar was generated independently from MarketplacePanels, always
showing all resources regardless of their hidden state. Fetch
MarketplacePanels during sidebar reconciliation and skip resources
where hidden=true, so hiding a resource from the marketplace also
removes it from the sidebar navigation.

Signed-off-by: IvanHunters <xorokhotnikov@gmail.com>
(cherry picked from commit 318079bf66)
2026-03-10 16:49:44 +00:00
IvanHunters
d412bd54f2 fix(dashboard): preserve disabled/hidden state on MarketplacePanel reconciliation
The controller was hardcoding disabled=false and hidden=false on every
reconciliation, overwriting any user changes made through the dashboard
UI. Move spec building inside the CreateOrUpdate mutate function to read
and preserve current disabled/hidden values from the existing resource.

Signed-off-by: IvanHunters <xorokhotnikov@gmail.com>
(cherry picked from commit e69efd80c4)
2026-03-10 16:48:33 +00:00
Andrei Kvapil
ca0282d3c7
[Backport release-1.0] fix(dashboard): fix External IPs factory EnrichedTable rendering (#2192)
# Description
Backport of #2175 to `release-1.0`.
2026-03-10 15:19:33 +01:00
Andrei Kvapil
4389b60571
[Backport release-1.0] [platform] Fix VM MAC address not preserved during migration (#2191)
# Description
Backport of #2169 to `release-1.0`.
2026-03-10 15:19:23 +01:00
IvanHunters
1eaf32812d fix(dashboard): fix External IPs factory EnrichedTable rendering
The external-ips factory used incorrect EnrichedTable properties causing
empty rows in the dashboard. Replace `clusterNamePartOfUrl` with
`cluster` and change `pathToItems` from array to dot-path string format
to match the convention used by all other working EnrichedTable instances.

Signed-off-by: IvanHunters <xorokhotnikov@gmail.com>
(cherry picked from commit 49601b166d)
2026-03-10 14:19:13 +00:00
Kirill Ilin
2658bfabda fix(migration): preserve VM MAC address during virtual-machine to vm-instance migration
Kube-OVN reads MAC address exclusively from the pod annotation
ovn.kubernetes.io/mac_address, not from the IP resource spec.macAddress.
Without pod-level annotations, migrated VMs receive a new random MAC,
breaking OS-level network config that matches by MAC (e.g. netplan).

Add a Helm lookup for the Kube-OVN IP resource in the vm-instance chart
template. When the IP resource exists, its macAddress and ipAddress are
automatically injected as pod annotations. This removes the need for
fragile Flux postRenderers on the HelmRelease — the chart itself handles
MAC/IP preservation based on actual cluster state.

Remove the postRenderers approach from migration 29 since the chart now
handles this natively.

Co-Authored-By: Claude <noreply@anthropic.com>
Signed-off-by: Kirill Ilin <stitch14@yandex.ru>
(cherry picked from commit 9a4f49238c)
2026-03-10 14:18:35 +00:00
Andrei Kvapil
448b4d9c80
[Backport release-1.0] fix(etcd-operator): replace deprecated kube-rbac-proxy image (#2183)
# Description
Backport of #2181 to `release-1.0`.
2026-03-10 12:39:09 +01:00
Andrei Kvapil
80a62bd3ee fix(etcd-operator): replace deprecated kube-rbac-proxy image
The gcr.io/kubebuilder/kube-rbac-proxy image is no longer available
since GCR was deprecated. Replace it with quay.io/brancz/kube-rbac-proxy
from the original upstream author.

Co-Authored-By: Claude <noreply@anthropic.com>
Signed-off-by: Andrei Kvapil <kvapss@gmail.com>
(cherry picked from commit 4946383cf1)
2026-03-10 11:37:08 +00:00
Andrei Kvapil
ca330b2aca
[Backport release-1.0] fix(keycloak): use management port health endpoints for probes (#2178)
# Description
Backport of #2162 to `release-1.0`.
2026-03-10 08:17:23 +01:00
mattia-eleuteri
352be923ae fix(keycloak): add startupProbe, remove initialDelaySeconds
Use a startupProbe to defer liveness/readiness checks until Keycloak
has fully started, instead of relying on initialDelaySeconds. This is
more robust for applications with variable startup times.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Signed-off-by: mattia-eleuteri <mattia@hidora.io>
(cherry picked from commit d18ed79382)
2026-03-10 07:15:32 +00:00
mattia-eleuteri
5356a5260a fix(keycloak): use management port health endpoints for probes
Keycloak 26.x exposes dedicated health endpoints on the management
port (9000) via /health/live and /health/ready. The previous probes
used GET / on port 8080 which redirects to the configured KC_HOSTNAME
(HTTPS), causing kubelet to fail the probe with "Probe terminated
redirects" and eventually kill the pod in a crashloop.

Changes:
- Add KC_HEALTH_ENABLED=true to activate health endpoints
- Expose management port 9000 in container ports
- Switch liveness probe to /health/live on port 9000
- Switch readiness probe to /health/ready on port 9000
- Increase failure thresholds for more tolerance during startup

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Signed-off-by: mattia-eleuteri <mattia@hidora.io>
(cherry picked from commit 0873691913)
2026-03-10 07:15:32 +00:00
IvanHunters
64b4be5c78
Release v1.0.3 (#2159)
This PR prepares the release `v1.0.3`.
2026-03-06 12:21:14 +03:00
cozystack-bot
c79545ba04 Prepare release v1.0.3
Signed-off-by: cozystack-bot <217169706+cozystack-bot@users.noreply.github.com>
2026-03-06 01:37:07 +00:00
Andrei Kvapil
eda0e8ee50
[Backport release-1.0] Fixed packages name conversion in migration script (#2148)
# Description
Backport of #2144 to `release-1.0`.
2026-03-05 17:25:11 +01:00
Myasnikov Daniil
f68fc0c921 Fixed packages name conversion in migration script
Signed-off-by: Myasnikov Daniil <myasnikovdaniil2001@gmail.com>
(cherry picked from commit 780af33ee1)
2026-03-03 23:22:55 +00:00
Andrei Kvapil
48ce08f584
Release v1.0.2 (#2140)
This PR prepares the release `v1.0.2`.
2026-03-02 21:48:54 +01:00
cozystack-bot
2675ff326a Prepare release v1.0.2
Signed-off-by: cozystack-bot <217169706+cozystack-bot@users.noreply.github.com>
2026-03-02 18:38:46 +00:00
Andrei Kvapil
51a5073175
[Backport release-1.0] [dashboard] fix: restore stock-instance sidebars for namespace-level pages (#2138)
# Description
Backport of #2136 to `release-1.0`.
2026-03-02 19:29:25 +01:00
Kirill Ilin
05d1c02eff fix(dashboard): restore stock-instance sidebars for namespace-level pages
PR #2106 removed stock-instance-* sidebar resources to fix broken URLs
on the main page before namespace selection. However, these sidebars are
required for rendering namespace-level pages (api-table, api-form, etc.)
such as the Backup Plans page.

Without stock-instance-api-table, the frontend cannot find the sidebar
for namespace-scoped api-table pages and renders an empty page instead.

The original bug (broken URLs with empty namespace placeholder) is already
fixed by CUSTOMIZATION_SIDEBAR_FALLBACK_ID="" in web.yaml, so re-adding
stock-instance-* sidebars does not reintroduce it.

Co-Authored-By: Claude <noreply@anthropic.com>
Signed-off-by: Kirill Ilin <stitch14@yandex.ru>
(cherry picked from commit 45b61f812d)
2026-03-02 18:28:56 +00:00
Andrei Kvapil
f06817d4e8
[Backport release-1.0] [dashboard] fix: allow clearing instanceType and preserve secret copy newlines (#2137)
# Description
Backport of #2135 to `release-1.0`.
2026-03-02 19:28:55 +01:00
Kirill Ilin
0fefaa246f fix(dashboard): preserve newlines when copying secrets with CMD+C
Add onCopy handler to SecretBase64Plain inputs to intercept native browser
copy events and explicitly write the full decoded text (including newlines)
to the clipboard. Without this, input[type=text] strips newlines on copy.

Upstream PR: https://github.com/PRO-Robotech/openapi-k8s-toolkit/pull/339

Co-Authored-By: Claude <noreply@anthropic.com>
Signed-off-by: Kirill Ilin <stitch14@yandex.ru>
(cherry picked from commit 99ee0e34bf)
2026-03-02 18:27:55 +00:00
Kirill Ilin
7cea11e57b feat(dashboard): set allowEmpty on instanceType and update openapi-ui toolkit
Update openapi-k8s-toolkit commit to d6b9e4ad (release/1.4.0) which
includes the FormListInput layout refactor, making formlistinput-value-binding.diff
obsolete.

Set allowEmpty: true on the VMInstance instanceType field so users can
explicitly clear the selection and override the default instance type.

Co-Authored-By: Claude <noreply@anthropic.com>
Signed-off-by: Kirill Ilin <stitch14@yandex.ru>
(cherry picked from commit 6e8ce65e49)
2026-03-02 18:27:55 +00:00
Kirill Ilin
31ae2bb826 feat(dashboard): allow clearing instanceType field in VMInstance form
Update openapi-k8s-toolkit to release/1.4.0 (d6b9e4ad). The previous
value-binding layout refactor is already included upstream, so drop the
formlistinput-value-binding.diff patch.

Add formlistinput-allow-empty.diff patch which introduces two props to
the listInput component:
- allowEmpty: when set, auto-persists the field so BFF sends an empty
  value instead of falling back to the schema default
- persistType: controls the type of empty value ('str' | 'number' | 'arr'
  | 'obj'), allowing the feature to work correctly for any field type

Set allowEmpty: true on the VMInstance instanceType field so users can
explicitly clear the selection and override the default instance type.

Co-Authored-By: Claude <noreply@anthropic.com>
Signed-off-by: Kirill Ilin <stitch14@yandex.ru>
(cherry picked from commit a3ccb4f87d)
2026-03-02 18:27:55 +00:00
Andrei Kvapil
c976378f2f
[Backport release-1.0] [system] Fix Keycloak proxy configuration for v26.x (#2134)
# Description
Backport of #2125 to `release-1.0`.
2026-03-02 18:56:45 +01:00
Kirill Ilin
edc32eec51 fix(keycloak): replace deprecated KC_PROXY with KC_PROXY_HEADERS
KC_PROXY=edge was deprecated and removed in Keycloak 26.x, causing
"Non-secure context detected" warnings and broken cookie handling
behind reverse proxy. Replace with KC_PROXY_HEADERS=xforwarded and
KC_HTTP_ENABLED=true.

Co-Authored-By: Claude <noreply@anthropic.com>
Signed-off-by: Kirill Ilin <stitch14@yandex.ru>
(cherry picked from commit 14228aa0d7)
2026-03-02 17:30:05 +00:00
Andrei Kvapil
e51f05d850
[Backport release-1.0] [platform] Fixed run-migrations script (#2132)
# Description
Backport of #2126 to `release-1.0`.
2026-03-02 17:54:10 +01:00
Myasnikov Daniil
dac1a375e2 [platform] Fixed run-migrations script
Signed-off-by: Myasnikov Daniil <myasnikovdaniil2001@gmail.com>
(cherry picked from commit 79c57874bb)
2026-03-02 16:53:58 +00:00
Andrei Kvapil
2a956eb0f9
[Backport release-1.0] fix(migration): suspend cozy-proxy if it conflicts with installer release (#2130)
# Description
Backport of #2128 to `release-1.0`.
2026-03-02 16:34:02 +01:00
Andrei Kvapil
6fbe026927 fix(migration): suspend cozy-proxy if it conflicts with installer release
In v0.41.x, cozy-proxy HelmRelease was configured with
releaseName: cozystack, which collides with the installer helm release.
If not suspended before upgrade, the cozy-proxy HR reconciles and
overwrites the installer release, deleting cozystack-operator.

Add a check in the migration script that detects this conflict and
suspends the cozy-proxy HelmRelease before proceeding.

Co-Authored-By: Claude <noreply@anthropic.com>
Signed-off-by: Andrei Kvapil <kvapss@gmail.com>
(cherry picked from commit 14a9017932)
2026-03-02 15:31:21 +00:00
Andrei Kvapil
4c3a6987c5
Release v1.0.1 (#2117)
This PR prepares the release `v1.0.1`.
2026-02-28 15:16:04 +01:00
cozystack-bot
30c5696541 Prepare release v1.0.1
Signed-off-by: cozystack-bot <217169706+cozystack-bot@users.noreply.github.com>
2026-02-28 11:00:44 +00:00
Andrei Kvapil
42780f26d2
[Backport release-1.0] fix(dashboard): add FlowSchema to exempt BFF from API throttling (#2124)
# Description
Backport of #2121 to `release-1.0`.
2026-02-28 11:56:50 +01:00
Andrei Kvapil
e9e2121153 fix(dashboard): add FlowSchema to exempt BFF from API throttling
The dashboard BFF service account (incloud-web-web) falls under the
default "service-accounts" FlowSchema which maps to the "workload-low"
priority level. Under load, this causes API Priority and Fairness to
return 429 (Too Many Requests) responses to the BFF, resulting in 500
errors for dashboard users.

Add a FlowSchema that maps the BFF service account to the "exempt"
priority level to prevent APF throttling of dashboard API requests.

Co-Authored-By: Claude <noreply@anthropic.com>
Signed-off-by: Andrei Kvapil <kvapss@gmail.com>
(cherry picked from commit 161b5be8c2)
2026-02-28 10:55:27 +00:00
Andrei Kvapil
3033e718dd
[Backport release-1.0] fix(installer): add keep annotation to Namespace and update migration script (#2123)
# Description
Backport of #2122 to `release-1.0`.
2026-02-28 11:53:44 +01:00
Andrei Kvapil
aa8a7eae47 fix(installer): add keep annotation to Namespace and update migration script
Add helm.sh/resource-policy=keep annotation to the cozy-system Namespace
in the installer helm chart. This prevents Helm from deleting the
namespace when the HelmRelease is removed, which would otherwise destroy
all other HelmReleases within it.

Update the migration script to annotate the cozy-system namespace and
cozystack-version ConfigMap with helm.sh/resource-policy=keep before
generating the Package resource.

Co-Authored-By: Claude <noreply@anthropic.com>
Signed-off-by: Andrei Kvapil <kvapss@gmail.com>
(cherry picked from commit c83e41ea14)
2026-02-28 10:53:06 +00:00
Andrei Kvapil
5a14dc6f54
[Backport release-1.0] [platform] Prevent version cm from deletion (#2114)
# Description
Backport of #2112 to `release-1.0`.
2026-02-27 13:05:06 +01:00
Myasnikov Daniil
2b59d4fc97 [platform] Prevent version cm from deletion
Signed-off-by: Myasnikov Daniil <myasnikovdaniil2001@gmail.com>
(cherry picked from commit c05dd5e7b1)
2026-02-27 12:03:48 +00:00
52 changed files with 411 additions and 143 deletions

View file

@ -85,6 +85,14 @@ jobs:
disk_id: ${{ steps.fetch_assets.outputs.disk_id }}
steps:
- name: Generate GitHub App token
id: app-token
uses: actions/create-github-app-token@v1
with:
app-id: ${{ secrets.COZYSTACK_CI_APP_ID }}
private-key: ${{ secrets.COZYSTACK_CI_PRIVATE_KEY }}
owner: cozystack
- name: Checkout code
if: contains(github.event.pull_request.labels.*.name, 'release')
uses: actions/checkout@v4
@ -111,7 +119,7 @@ jobs:
id: fetch_assets
uses: actions/github-script@v7
with:
github-token: ${{ secrets.GH_PAT }}
github-token: ${{ steps.app-token.outputs.token }}
script: |
const tag = '${{ steps.get_tag.outputs.tag }}';
const releases = await github.rest.repos.listReleases({
@ -144,6 +152,15 @@ jobs:
if: ${{ always() && (needs.build.result == 'success' || needs.resolve_assets.result == 'success') }}
steps:
- name: Generate GitHub App token
if: contains(github.event.pull_request.labels.*.name, 'release')
id: app-token
uses: actions/create-github-app-token@v1
with:
app-id: ${{ secrets.COZYSTACK_CI_APP_ID }}
private-key: ${{ secrets.COZYSTACK_CI_PRIVATE_KEY }}
owner: cozystack
# ▸ Checkout and prepare the codebase
- name: Checkout code
uses: actions/checkout@v4
@ -173,11 +190,11 @@ jobs:
if: contains(github.event.pull_request.labels.*.name, 'release')
run: |
mkdir -p _out/assets
curl -sSL -H "Authorization: token ${GH_PAT}" -H "Accept: application/octet-stream" \
curl -sSL -H "Authorization: token ${APP_TOKEN}" -H "Accept: application/octet-stream" \
-o _out/assets/nocloud-amd64.raw.xz \
"https://api.github.com/repos/${GITHUB_REPOSITORY}/releases/assets/${{ needs.resolve_assets.outputs.disk_id }}"
env:
GH_PAT: ${{ secrets.GH_PAT }}
APP_TOKEN: ${{ steps.app-token.outputs.token }}
- name: Set sandbox ID
run: echo "SANDBOX_NAME=cozy-e2e-sandbox-$(echo "${GITHUB_REPOSITORY}:${GITHUB_WORKFLOW}:${GITHUB_REF}" | sha256sum | cut -c1-10)" >> $GITHUB_ENV

View file

@ -32,6 +32,54 @@ if ! kubectl get namespace "$NAMESPACE" &> /dev/null; then
exit 1
fi
# Step 0: Annotate critical resources to prevent Helm from deleting them
echo "Step 0: Protect critical resources from Helm deletion"
echo ""
echo "The following resources will be annotated with helm.sh/resource-policy=keep"
echo "to prevent Helm from deleting them when the installer release is removed:"
echo " - Namespace: $NAMESPACE"
echo " - ConfigMap: $NAMESPACE/cozystack-version"
echo ""
read -p "Do you want to annotate these resources? (y/N) " -n 1 -r
echo ""
if [[ $REPLY =~ ^[Yy]$ ]]; then
echo "Annotating namespace $NAMESPACE..."
kubectl annotate namespace "$NAMESPACE" helm.sh/resource-policy=keep --overwrite
echo "Annotating ConfigMap cozystack-version..."
kubectl annotate configmap -n "$NAMESPACE" cozystack-version helm.sh/resource-policy=keep --overwrite 2>/dev/null || echo " ConfigMap cozystack-version not found, skipping."
echo ""
echo "Resources annotated successfully."
else
echo "WARNING: Skipping annotation. If you remove the Helm installer release,"
echo "the namespace and its contents may be deleted!"
fi
echo ""
# Step 1: Check for cozy-proxy HelmRelease with conflicting releaseName
# In v0.41.x, cozy-proxy was incorrectly configured with releaseName "cozystack",
# which conflicts with the installer helm release name. If not suspended, cozy-proxy
# HelmRelease will overwrite the installer release and delete cozystack-operator.
COZY_PROXY_RELEASE_NAME=$(kubectl get hr -n "$NAMESPACE" cozy-proxy -o jsonpath='{.spec.releaseName}' 2>/dev/null || true)
if [ "$COZY_PROXY_RELEASE_NAME" = "cozystack" ]; then
echo "WARNING: HelmRelease cozy-proxy has releaseName 'cozystack', which conflicts"
echo "with the installer release. It must be suspended before proceeding, otherwise"
echo "it will overwrite the installer and delete cozystack-operator."
echo ""
read -p "Suspend HelmRelease cozy-proxy? (y/N) " -n 1 -r
echo ""
if [[ $REPLY =~ ^[Yy]$ ]]; then
kubectl -n "$NAMESPACE" patch hr cozy-proxy --type=merge --field-manager=flux-client-side-apply -p '{"spec":{"suspend":true}}'
echo "HelmRelease cozy-proxy suspended."
else
echo "ERROR: Cannot proceed with conflicting cozy-proxy HelmRelease active."
echo "Please suspend it manually:"
echo " kubectl -n $NAMESPACE patch hr cozy-proxy --type=merge -p '{\"spec\":{\"suspend\":true}}'"
exit 1
fi
echo ""
fi
# Read ConfigMap cozystack
echo "Reading ConfigMap cozystack..."
COZYSTACK_CM=$(kubectl get configmap -n "$NAMESPACE" cozystack -o json 2>/dev/null || echo "{}")
@ -107,13 +155,13 @@ fi
if [ -z "$BUNDLE_DISABLE" ]; then
DISABLED_PACKAGES="[]"
else
DISABLED_PACKAGES=$(echo "$BUNDLE_DISABLE" | sed 's/,/\n/g' | awk 'BEGIN{print}{print " - "$0}')
DISABLED_PACKAGES=$(echo "$BUNDLE_DISABLE" | sed 's/,/\n/g' | awk 'BEGIN{print}{print " - cozystack."$0}')
fi
if [ -z "$BUNDLE_ENABLE" ]; then
ENABLED_PACKAGES="[]"
else
ENABLED_PACKAGES=$(echo "$BUNDLE_ENABLE" | sed 's/,/\n/g' | awk 'BEGIN{print}{print " - "$0}')
ENABLED_PACKAGES=$(echo "$BUNDLE_ENABLE" | sed 's/,/\n/g' | awk 'BEGIN{print}{print " - cozystack."$0}')
fi
if [ -z "$EXPOSE_SERVICES" ]; then
@ -127,7 +175,7 @@ BUNDLE_NAME=$(echo "$BUNDLE_NAME" | sed 's/paas/isp/')
# Extract branding if available
BRANDING=$(echo "$BRANDING_CM" | jq -r '.data // {} | to_entries[] | "\(.key): \"\(.value)\""')
if [ -z "$BRANDING" ]; then
if [ -z "$BRANDING" ]; then
BRANDING="{}"
else
BRANDING=$(echo "$BRANDING" | awk 'BEGIN{print}{print " " $0}')

View file

@ -195,6 +195,7 @@ func applyListInputOverrides(schema map[string]any, kind string, openAPIProps ma
"valueUri": "/api/clusters/{cluster}/k8s/apis/instancetype.kubevirt.io/v1beta1/virtualmachineclusterinstancetypes",
"keysToValue": []any{"metadata", "name"},
"keysToLabel": []any{"metadata", "name"},
"allowEmpty": true,
},
}
if prop, _ := openAPIProps["instanceType"].(map[string]any); prop != nil {

View file

@ -202,6 +202,10 @@ func TestApplyListInputOverrides_VMInstance(t *testing.T) {
t.Errorf("expected valueUri %s, got %v", expectedURI, customProps["valueUri"])
}
if customProps["allowEmpty"] != true {
t.Errorf("expected allowEmpty true, got %v", customProps["allowEmpty"])
}
// Check disks[].name is a listInput
disks, ok := specProps["disks"].(map[string]any)
if !ok {

View file

@ -307,6 +307,10 @@ func (m *Manager) buildExpectedResourceSet(crds []cozyv1alpha1.ApplicationDefini
"stock-project-builtin-table",
"stock-project-crd-form",
"stock-project-crd-table",
"stock-instance-api-form",
"stock-instance-api-table",
"stock-instance-builtin-form",
"stock-instance-builtin-table",
}
for _, sidebarID := range stockSidebars {
expected["Sidebar"][sidebarID] = true

View file

@ -68,31 +68,46 @@ func (m *Manager) ensureMarketplacePanel(ctx context.Context, crd *cozyv1alpha1.
tags[i] = t
}
specMap := map[string]any{
"description": d.Description,
"name": displayName,
"type": "nonCrd",
"apiGroup": "apps.cozystack.io",
"apiVersion": "v1alpha1",
"plural": app.Plural, // e.g., "buckets"
"disabled": false,
"hidden": false,
"tags": tags,
"icon": d.Icon,
}
specBytes, err := json.Marshal(specMap)
if err != nil {
return reconcile.Result{}, err
}
_, err = controllerutil.CreateOrUpdate(ctx, m.Client, mp, func() error {
_, err := controllerutil.CreateOrUpdate(ctx, m.Client, mp, func() error {
if err := controllerutil.SetOwnerReference(crd, mp, m.Scheme); err != nil {
return err
}
// Add dashboard labels to dynamic resources
m.addDashboardLabels(mp, crd, ResourceTypeDynamic)
// Preserve user-set disabled/hidden values from existing resource
disabled := false
hidden := false
if mp.Spec.Raw != nil {
var existing map[string]any
if err := json.Unmarshal(mp.Spec.Raw, &existing); err == nil {
if v, ok := existing["disabled"].(bool); ok {
disabled = v
}
if v, ok := existing["hidden"].(bool); ok {
hidden = v
}
}
}
specMap := map[string]any{
"description": d.Description,
"name": displayName,
"type": "nonCrd",
"apiGroup": "apps.cozystack.io",
"apiVersion": "v1alpha1",
"plural": app.Plural, // e.g., "buckets"
"disabled": disabled,
"hidden": hidden,
"tags": tags,
"icon": d.Icon,
}
specBytes, err := json.Marshal(specMap)
if err != nil {
return err
}
// Only update spec if it's different to avoid unnecessary updates
newSpec := dashv1alpha1.ArbitrarySpec{
JSON: apiextv1.JSON{Raw: specBytes},

View file

@ -38,6 +38,23 @@ func (m *Manager) ensureSidebar(ctx context.Context, crd *cozyv1alpha1.Applicati
}
all = crdList.Items
// 1b) Fetch all MarketplacePanels to determine which resources are hidden
hiddenResources := map[string]bool{}
var mpList dashv1alpha1.MarketplacePanelList
if err := m.List(ctx, &mpList, &client.ListOptions{}); err == nil {
for i := range mpList.Items {
mp := &mpList.Items[i]
if mp.Spec.Raw != nil {
var spec map[string]any
if err := json.Unmarshal(mp.Spec.Raw, &spec); err == nil {
if hidden, ok := spec["hidden"].(bool); ok && hidden {
hiddenResources[mp.Name] = true
}
}
}
}
}
// 2) Build category -> []item map (only for CRDs with spec.dashboard != nil)
type item struct {
Key string
@ -63,6 +80,11 @@ func (m *Manager) ensureSidebar(ctx context.Context, crd *cozyv1alpha1.Applicati
plural := pickPlural(kind, def)
lowerKind := strings.ToLower(kind)
// Skip resources hidden via MarketplacePanel
if hiddenResources[def.Name] {
continue
}
// Check if this resource is a module
if def.Spec.Dashboard.Module {
// Special case: info should have its own keysAndTags, not be in modules
@ -243,6 +265,11 @@ func (m *Manager) ensureSidebar(ctx context.Context, crd *cozyv1alpha1.Applicati
"stock-project-builtin-table",
"stock-project-crd-form",
"stock-project-crd-table",
// stock-instance sidebars (namespace-level pages after namespace is selected)
"stock-instance-api-form",
"stock-instance-api-table",
"stock-instance-builtin-form",
"stock-instance-builtin-table",
}
// Add details sidebars for all CRDs with dashboard config

View file

@ -154,6 +154,14 @@ func CreateAllCustomColumnsOverrides() []*dashboardv1alpha1.CustomColumnsOverrid
createStringColumn("Version", ".status.version"),
}),
// Factory service details endpointslice (Pod serving table)
createCustomColumnsOverride("factory-kube-service-details-endpointslice", []any{
createStringColumn("Pod", ".targetRef.name"),
createArrayColumn("Addresses", ".addresses"),
createBoolColumn("Ready", ".conditions.ready"),
createStringColumn("Node", ".nodeName"),
}),
// Factory service details port mapping
createCustomColumnsOverride("factory-kube-service-details-port-mapping", []any{
createStringColumn("Name", ".name"),
@ -1936,12 +1944,12 @@ func CreateAllFactories() []*dashboardv1alpha1.Factory {
map[string]any{
"type": "EnrichedTable",
"data": map[string]any{
"id": "external-ips-table",
"fetchUrl": "/api/clusters/{2}/k8s/api/v1/namespaces/{3}/services",
"clusterNamePartOfUrl": "{2}",
"baseprefix": "/openapi-ui",
"customizationId": "factory-details-v1.services",
"pathToItems": []any{"items"},
"id": "external-ips-table",
"fetchUrl": "/api/clusters/{2}/k8s/api/v1/namespaces/{3}/services",
"cluster": "{2}",
"baseprefix": "/openapi-ui",
"customizationId": "factory-details-v1.services",
"pathToItems": ".items",
"fieldSelector": map[string]any{
"spec.type": "LoadBalancer",
},
@ -1997,6 +2005,10 @@ func CreateAllNavigations() []*dashboardv1alpha1.Navigation {
// Namespaced API resources
"base-factory-namespaced-api-networking.k8s.io-v1-ingresses": "kube-ingress-details",
"base-factory-namespaced-api-cozystack.io-v1alpha1-workloadmonitors": "workloadmonitor-details",
// Backup resources (not ApplicationDefinitions, so ensureNavigation doesn't cover them)
"base-factory-namespaced-api-backups.cozystack.io-v1alpha1-plans": "plan-details",
"base-factory-namespaced-api-backups.cozystack.io-v1alpha1-backupjobs": "backupjob-details",
"base-factory-namespaced-api-backups.cozystack.io-v1alpha1-backups": "backup-details",
}
return []*dashboardv1alpha1.Navigation{

View file

@ -1 +1 @@
ghcr.io/cozystack/cozystack/nginx-cache:0.0.0@sha256:cb25e40cb665b8bbeee8cb1ec39da4c9a7452ef3f2f371912bbc0d1b1e2d40a8
ghcr.io/cozystack/cozystack/nginx-cache:0.0.0@sha256:2f987017ff95d3c782e16ef0d99928831f520daf154d08a2fa38c2d68363e036

View file

@ -1 +1 @@
ghcr.io/cozystack/cozystack/cluster-autoscaler:0.0.0@sha256:3753b735b0315bee90de54cb25cfebc63bd2cc90ad11ca4fdc0e70439abd5096
ghcr.io/cozystack/cozystack/cluster-autoscaler:0.0.0@sha256:e9d0aa7e651b03a6713b380101a61832818a91b5f989da9754f58693898c4056

View file

@ -1 +1 @@
ghcr.io/cozystack/cozystack/kubevirt-csi-driver:0.0.0@sha256:434aa3b8e2a3cbf6681426b174e1c4fde23bafd12a6cccd046b5cb1749092ec4
ghcr.io/cozystack/cozystack/kubevirt-csi-driver:0.0.0@sha256:fb47bd5e6acfb9957fb7987a27c22e55ab37232fd37cd98528815365e941ffef

View file

@ -317,11 +317,7 @@ func (w *WrappedControllerService) ControllerPublishVolume(ctx context.Context,
"ownerReferences": []interface{}{vmiOwnerRef},
},
"spec": map[string]interface{}{
"endpointSelector": map[string]interface{}{
"matchLabels": map[string]interface{}{
"kubevirt.io/vm": vmName,
},
},
"endpointSelector": buildEndpointSelector([]string{vmName}),
"egress": []interface{}{
map[string]interface{}{
"toEndpoints": []interface{}{
@ -441,6 +437,13 @@ func (w *WrappedControllerService) addCNPOwnerReference(ctx context.Context, nam
if err := unstructured.SetNestedSlice(existing.Object, ownerRefs, "metadata", "ownerReferences"); err != nil {
return status.Errorf(codes.Internal, "failed to set ownerReferences: %v", err)
}
// Rebuild endpointSelector to include all VMs
selector := buildEndpointSelector(vmNamesFromOwnerRefs(ownerRefs))
if err := unstructured.SetNestedField(existing.Object, selector, "spec", "endpointSelector"); err != nil {
return status.Errorf(codes.Internal, "failed to set endpointSelector: %v", err)
}
if _, err := w.dynamicClient.Resource(ciliumNetworkPolicyGVR).Namespace(namespace).Update(ctx, existing, metav1.UpdateOptions{}); err != nil {
return err
}
@ -486,6 +489,13 @@ func (w *WrappedControllerService) removeCNPOwnerReference(ctx context.Context,
if err := unstructured.SetNestedSlice(existing.Object, remaining, "metadata", "ownerReferences"); err != nil {
return status.Errorf(codes.Internal, "failed to set ownerReferences: %v", err)
}
// Rebuild endpointSelector from remaining VMs
selector := buildEndpointSelector(vmNamesFromOwnerRefs(remaining))
if err := unstructured.SetNestedField(existing.Object, selector, "spec", "endpointSelector"); err != nil {
return status.Errorf(codes.Internal, "failed to set endpointSelector: %v", err)
}
if _, err := w.dynamicClient.Resource(ciliumNetworkPolicyGVR).Namespace(namespace).Update(ctx, existing, metav1.UpdateOptions{}); err != nil {
return err
}
@ -494,6 +504,37 @@ func (w *WrappedControllerService) removeCNPOwnerReference(ctx context.Context,
})
}
// buildEndpointSelector returns an endpointSelector using matchExpressions
// so that multiple VMs can be listed in a single selector.
func buildEndpointSelector(vmNames []string) map[string]interface{} {
values := make([]interface{}, len(vmNames))
for i, name := range vmNames {
values[i] = name
}
return map[string]interface{}{
"matchExpressions": []interface{}{
map[string]interface{}{
"key": "kubevirt.io/vm",
"operator": "In",
"values": values,
},
},
}
}
// vmNamesFromOwnerRefs extracts VM names from ownerReferences.
func vmNamesFromOwnerRefs(ownerRefs []interface{}) []string {
var names []string
for _, ref := range ownerRefs {
if refMap, ok := ref.(map[string]interface{}); ok {
if name, ok := refMap["name"].(string); ok {
names = append(names, name)
}
}
}
return names
}
func hasRWXAccessMode(pvc *corev1.PersistentVolumeClaim) bool {
for _, mode := range pvc.Spec.AccessModes {
if mode == corev1.ReadWriteMany {

View file

@ -1 +1 @@
ghcr.io/cozystack/cozystack/ubuntu-container-disk:v1.35@sha256:39f626c802dd84f95720ffb54fcd80dfb8a58ac280498870d0a1aa30d4252f94
ghcr.io/cozystack/cozystack/ubuntu-container-disk:v1.35@sha256:c4ae418b2a2c139794cd9630c3b2c2171870cc7748ac200344d2c4ed4283cf0b

View file

@ -34,6 +34,12 @@ spec:
metadata:
annotations:
kubevirt.io/allow-pod-bridge-network-live-migration: "true"
{{- $ovnIPName := printf "%s.%s" (include "virtual-machine.fullname" .) .Release.Namespace }}
{{- $ovnIP := lookup "kubeovn.io/v1" "IP" "" $ovnIPName }}
{{- if $ovnIP }}
ovn.kubernetes.io/mac_address: {{ $ovnIP.spec.macAddress | quote }}
ovn.kubernetes.io/ip_address: {{ $ovnIP.spec.ipAddress | quote }}
{{- end }}
labels:
{{- include "virtual-machine.labels" . | nindent 8 }}
spec:

View file

@ -10,6 +10,8 @@ metadata:
labels:
cozystack.io/system: "true"
pod-security.kubernetes.io/enforce: privileged
annotations:
helm.sh/resource-policy: keep
---
apiVersion: v1
kind: ServiceAccount

View file

@ -1,9 +1,9 @@
cozystackOperator:
# Deployment variant: talos, generic, hosted
variant: talos
image: ghcr.io/cozystack/cozystack/cozystack-operator:v1.0.0@sha256:9e5229764b6077809a1c16566881a524c33e8986e36597e6833f8857a7e6a335
image: ghcr.io/cozystack/cozystack/cozystack-operator:v1.0.7@sha256:0c39e3762658ee6d41b22dd252b43d9e32e150c24dcfaf0c7d697247beb7cd74
platformSourceUrl: 'oci://ghcr.io/cozystack/cozystack/cozystack-packages'
platformSourceRef: 'digest=sha256:ef3e4ba7d21572a61794d8be594805f063aa04f4a8c3753351fc89c7804d337e'
platformSourceRef: 'digest=sha256:340733d7c6a5581a9cfba6abee875c2cd8685db9be50f4e3e7585fdffb8fa9f6'
# Generic variant configuration (only used when cozystackOperator.variant=generic)
cozystack:
# Kubernetes API server host (IP only, no protocol/port)

View file

@ -24,7 +24,7 @@ if [ "$CURRENT_VERSION" -ge "$TARGET_VERSION" ]; then
fi
# Run migrations sequentially from current version to target version
for i in $(seq $((CURRENT_VERSION + 1)) $TARGET_VERSION); do
for i in $(seq $CURRENT_VERSION $((TARGET_VERSION - 1))); do
if [ -f "/migrations/$i" ]; then
echo "Running migration $i"
chmod +x /migrations/$i

View file

@ -6,6 +6,8 @@ kind: ConfigMap
metadata:
name: cozystack-version
namespace: {{ .Release.Namespace }}
annotations:
helm.sh/resource-policy: keep
data:
version: {{ .Values.migrations.targetVersion | quote }}
{{- end }}

View file

@ -5,7 +5,7 @@ sourceRef:
path: /
migrations:
enabled: false
image: ghcr.io/cozystack/cozystack/platform-migrations:v1.0.0@sha256:68dabdebc38ac439228ae07031cc70e0fa184a24bd4e5b3b22c17466b2a55201
image: ghcr.io/cozystack/cozystack/platform-migrations:v1.0.7@sha256:d43c6f26c65edd448f586a29969ff76718338f1f1f78b24d3ad54c6c8977c748
targetVersion: 34
# Bundle deployment configuration
bundles:

View file

@ -1,2 +1,2 @@
e2e:
image: ghcr.io/cozystack/cozystack/e2e-sandbox:v1.0.0@sha256:0eae9f519669667d60b160ebb93c127843c470ad9ca3447fceaa54604503a7ba
image: ghcr.io/cozystack/cozystack/e2e-sandbox:v1.0.7@sha256:7964a3e4b11053887be201d62f94138c3a7836c861036c26fb833aa1fcb934e1

View file

@ -1 +1 @@
ghcr.io/cozystack/cozystack/matchbox:v1.0.0@sha256:c48eb7b23f01a8ff58d409fdb51c88e771f819cb914eee03da89471e62302f33
ghcr.io/cozystack/cozystack/matchbox:v1.0.7@sha256:b79fbfb5bceb9d70db355b7418ee81b3480d7c5734e885336b8b036678575928

View file

@ -4,9 +4,14 @@ metadata:
name: {{ .Release.Name }}-defrag
spec:
schedule: "0 * * * *"
concurrencyPolicy: Forbid
startingDeadlineSeconds: 300
successfulJobsHistoryLimit: 3
failedJobsHistoryLimit: 1
jobTemplate:
spec:
activeDeadlineSeconds: 1800
backoffLimit: 2
template:
spec:
containers:

View file

@ -1 +1 @@
ghcr.io/cozystack/cozystack/objectstorage-sidecar:v1.0.0@sha256:2a3595cd88b30af55b2000d3ca204899beecef0012b0e0402754c3914aad1f7f
ghcr.io/cozystack/cozystack/objectstorage-sidecar:v1.0.7@sha256:8644a157dec5b4af93e80f863966259382613f55290ebd212e4fe4dab6d8312b

View file

@ -1,5 +1,5 @@
backupController:
image: "ghcr.io/cozystack/cozystack/backup-controller:v1.0.0@sha256:e1a6c8ac7ba64442812464b59c53e782e373a339c18b379c2692921b44c6edb5"
image: "ghcr.io/cozystack/cozystack/backup-controller:v1.0.7@sha256:71a4634d7ee35ea598a20027b57ffa9cea32cb22ed3b9d3ef6384cdb7d2ef170"
replicas: 2
debug: false
metrics:

View file

@ -1,5 +1,5 @@
backupStrategyController:
image: "ghcr.io/cozystack/cozystack/backupstrategy-controller:v1.0.0@sha256:29735d945c69c6bbaab21068bf4ea30f6b63f4c71a7a8d95590f370abcb4b328"
image: "ghcr.io/cozystack/cozystack/backupstrategy-controller:v1.0.7@sha256:4171330e5b646a965e929b1ff343a5bdc1f9e46cb51e0bc04a722b78cd07bdd6"
replicas: 2
debug: false
metrics:

View file

@ -1 +1 @@
ghcr.io/cozystack/cozystack/s3manager:v0.5.0@sha256:279008f87460d709e99ed25ee8a1e4568a290bb9afa0e3dd3a06d524163a132b
ghcr.io/cozystack/cozystack/s3manager:v0.5.0@sha256:dceafaf119191af1fc69fb6d900cf1250bf33e953ff8df39ae12194d8c4b8696

View file

@ -1,3 +1,3 @@
cozystackAPI:
image: ghcr.io/cozystack/cozystack/cozystack-api:v1.0.0@sha256:bd70ecb944bde9a0d6b88114aea89bdbbe2d07e33f03175cfd885de013e88294
image: ghcr.io/cozystack/cozystack/cozystack-api:v1.0.7@sha256:0538b26363f8e4b200c7dae10253186ef16ee7d473915047bd4c67b2b34ac3cb
replicas: 2

View file

@ -21,6 +21,9 @@ rules:
- apiGroups: [""]
resources: ["pods", "services", "persistentvolumes", "endpoints", "events", "resourcequotas"]
verbs: ["get", "list", "watch"]
- apiGroups: ["discovery.k8s.io"]
resources: ["endpointslices"]
verbs: ["get", "list", "watch"]
- apiGroups: ["networking.k8s.io"]
resources: ["ingresses"]
verbs: ["get", "list", "watch"]
@ -94,6 +97,14 @@ rules:
- get
- list
- watch
- apiGroups:
- discovery.k8s.io
resources:
- endpointslices
verbs:
- get
- list
- watch
- apiGroups:
- networking.k8s.io
resources:
@ -194,12 +205,18 @@ rules:
- buckets
- clickhouses
- foos
- foundationdbs
- harbors
- httpcaches
- kafkas
- kuberneteses
- mariadbs
- mongodbs
- natses
- openbaos
- opensearches
- postgreses
- qdrants
- rabbitmqs
- redises
- seaweedfses
@ -207,6 +224,7 @@ rules:
- virtualmachines
- vmdisks
- vminstances
- vpns
- infos
- virtualprivateclouds
verbs:

View file

@ -1,4 +1,4 @@
cozystackController:
image: ghcr.io/cozystack/cozystack/cozystack-controller:v1.0.0@sha256:da01085026a4a01514ae435c7bfb48cca2cf00eb17feb2ed7ae88711f82693e0
image: ghcr.io/cozystack/cozystack/cozystack-controller:v1.0.7@sha256:c4f1c2562b7b6ade4e0fe0915c80b7a418874a0fadb01342dfbf30f7f4e8af1b
debug: false
disableTelemetry: false

View file

@ -6,7 +6,7 @@ FROM node:${NODE_VERSION}-alpine AS openapi-k8s-toolkit-builder
RUN apk add git
WORKDIR /src
# release/1.4.0
ARG COMMIT=c67029cc7b7495c65ee0406033576e773a73bb01
ARG COMMIT=d6b9e4ad0d1eb9d3730f7f0c664792c8dda3214d
RUN wget -O- https://github.com/PRO-Robotech/openapi-k8s-toolkit/archive/${COMMIT}.tar.gz | tar -xzvf- --strip-components=1
COPY openapi-k8s-toolkit/patches /patches

View file

@ -0,0 +1,37 @@
diff --git a/src/localTypes/formExtensions.ts b/src/localTypes/formExtensions.ts
--- a/src/localTypes/formExtensions.ts
+++ b/src/localTypes/formExtensions.ts
@@ -59,2 +59,4 @@
relatedValuePath?: string
+ allowEmpty?: boolean
+ persistType?: 'str' | 'number' | 'arr' | 'obj'
}
diff --git a/src/components/molecules/BlackholeForm/molecules/FormListInput/FormListInput.tsx b/src/components/molecules/BlackholeForm/molecules/FormListInput/FormListInput.tsx
--- a/src/components/molecules/BlackholeForm/molecules/FormListInput/FormListInput.tsx
+++ b/src/components/molecules/BlackholeForm/molecules/FormListInput/FormListInput.tsx
@@ -149,3 +149,10 @@
}, [relatedPath, form, arrName, fixedName, relatedFieldValue, onValuesChangeCallBack, isTouchedPeristed])
+ // When allowEmpty is set, auto-persist the field so the BFF preserves empty values
+ useEffect(() => {
+ if (customProps.allowEmpty) {
+ persistedControls.onPersistMark(persistName || name, customProps.persistType ?? 'str')
+ }
+ }, [customProps.allowEmpty, customProps.persistType, persistedControls, persistName, name])
+
const uri = prepareTemplate({
@@ -267,5 +274,14 @@
validateTrigger="onBlur"
hasFeedback={designNewLayout ? { icons: feedbackIcons } : true}
style={{ flex: 1 }}
+ normalize={(value: unknown) => {
+ if (customProps.allowEmpty && (value === undefined || value === null)) {
+ if (customProps.persistType === 'number') return 0
+ if (customProps.persistType === 'arr') return []
+ if (customProps.persistType === 'obj') return {}
+ return ''
+ }
+ return value
+ }}
>
<Select

View file

@ -1,49 +0,0 @@
diff --git a/src/components/molecules/BlackholeForm/molecules/FormListInput/FormListInput.tsx b/src/components/molecules/BlackholeForm/molecules/FormListInput/FormListInput.tsx
index d5e5230..9038dbb 100644
--- a/src/components/molecules/BlackholeForm/molecules/FormListInput/FormListInput.tsx
+++ b/src/components/molecules/BlackholeForm/molecules/FormListInput/FormListInput.tsx
@@ -259,14 +259,15 @@ export const FormListInput: FC<TFormListInputProps> = ({
<PersistedCheckbox formName={persistName || name} persistedControls={persistedControls} type="arr" />
</Flex>
</Flex>
- <ResetedFormItem
- key={arrKey !== undefined ? arrKey : Array.isArray(name) ? name.slice(-1)[0] : name}
- name={arrName || fixedName}
- rules={[getRequiredRule(forceNonRequired === false && !!required?.includes(getStringByName(name)), name)]}
- validateTrigger="onBlur"
- hasFeedback={designNewLayout ? { icons: feedbackIcons } : true}
- >
- <Flex gap={8} align="center">
+ <Flex gap={8} align="center">
+ <ResetedFormItem
+ key={arrKey !== undefined ? arrKey : Array.isArray(name) ? name.slice(-1)[0] : name}
+ name={arrName || fixedName}
+ rules={[getRequiredRule(forceNonRequired === false && !!required?.includes(getStringByName(name)), name)]}
+ validateTrigger="onBlur"
+ hasFeedback={designNewLayout ? { icons: feedbackIcons } : true}
+ style={{ flex: 1 }}
+ >
<Select
mode={customProps.mode}
placeholder="Select"
@@ -277,13 +278,13 @@ export const FormListInput: FC<TFormListInputProps> = ({
showSearch
style={{ width: '100%' }}
/>
- {relatedValueTooltip && (
- <Tooltip title={relatedValueTooltip}>
- <QuestionCircleOutlined />
- </Tooltip>
- )}
- </Flex>
- </ResetedFormItem>
+ </ResetedFormItem>
+ {relatedValueTooltip && (
+ <Tooltip title={relatedValueTooltip}>
+ <QuestionCircleOutlined />
+ </Tooltip>
+ )}
+ </Flex>
</HiddenContainer>
)
}

View file

@ -0,0 +1,29 @@
diff --git a/src/components/organisms/DynamicComponents/molecules/SecretBase64Plain/SecretBase64Plain.tsx b/src/components/organisms/DynamicComponents/molecules/SecretBase64Plain/SecretBase64Plain.tsx
--- a/src/components/organisms/DynamicComponents/molecules/SecretBase64Plain/SecretBase64Plain.tsx
+++ b/src/components/organisms/DynamicComponents/molecules/SecretBase64Plain/SecretBase64Plain.tsx
@@ -145,6 +145,12 @@
<Styled.DisabledInput
$hidden={effectiveHidden}
onClick={e => handleInputClick(e, effectiveHidden, value)}
+ onCopy={e => {
+ if (!effectiveHidden) {
+ e.preventDefault()
+ e.clipboardData?.setData('text/plain', value)
+ }
+ }}
value={shownValue}
readOnly
/>
@@ -161,6 +167,12 @@
<Styled.DisabledInput
$hidden={effectiveHidden}
onClick={e => handleInputClick(e, effectiveHidden, value)}
+ onCopy={e => {
+ if (!effectiveHidden) {
+ e.preventDefault()
+ e.clipboardData?.setData('text/plain', value)
+ }
+ }}
value={shownValue}
readOnly
/>

View file

@ -1,6 +1,6 @@
{{- $brandingConfig := .Values._cluster.branding | default dict }}
{{- $tenantText := "v1.0.0" }}
{{- $tenantText := "v1.0.7" }}
{{- $footerText := "Cozystack" }}
{{- $titleText := "Cozystack Dashboard" }}
{{- $logoText := "" }}

View file

@ -0,0 +1,20 @@
apiVersion: flowcontrol.apiserver.k8s.io/v1
kind: FlowSchema
metadata:
name: cozy-dashboard-exempt
spec:
matchingPrecedence: 2
priorityLevelConfiguration:
name: exempt
rules:
- subjects:
- kind: ServiceAccount
serviceAccount:
name: incloud-web-web
namespace: {{ .Release.Namespace }}
resourceRules:
- verbs: ["*"]
apiGroups: ["*"]
resources: ["*"]
namespaces: ["*"]
clusterScope: true

View file

@ -49,6 +49,8 @@ apiVersion: v1.edp.epam.com/v1
kind: KeycloakClient
metadata:
name: dashboard-client
annotations:
secret-hash: {{ $dashboardClient | sha256sum }}
spec:
serviceAccount:
enabled: true

View file

@ -1,6 +1,6 @@
openapiUI:
image: ghcr.io/cozystack/cozystack/openapi-ui:v1.0.0@sha256:73a8bd4283a46a99d22536eece9c2059fa2fb1c17b43ddefe6716e8960e4731e
image: ghcr.io/cozystack/cozystack/openapi-ui:v1.0.7@sha256:983155b6ac76a753cbf4a7264659f810a6f91e6da3bdf21d24a1985c3d2462bd
openapiUIK8sBff:
image: ghcr.io/cozystack/cozystack/openapi-ui-k8s-bff:v1.0.0@sha256:c938fee904acd948800d4dc5e121c4c5cd64cb4a3160fb8d2f9dbff0e5168740
image: ghcr.io/cozystack/cozystack/openapi-ui-k8s-bff:v1.0.7@sha256:7dd82ebe1d0c1925bbc440bc65a86852f3dd2bc0f6f12856904df847f15913d3
tokenProxy:
image: ghcr.io/cozystack/cozystack/token-proxy:v1.0.0@sha256:2e280991e07853ea48f97b0a42946afffa10d03d6a83d41099ed83e6ffc94fdc
image: ghcr.io/cozystack/cozystack/token-proxy:v1.0.7@sha256:2e280991e07853ea48f97b0a42946afffa10d03d6a83d41099ed83e6ffc94fdc

View file

@ -38,8 +38,8 @@
| kubeRbacProxy.args[2] | string | `"--logtostderr=true"` | |
| kubeRbacProxy.args[3] | string | `"--v=0"` | |
| kubeRbacProxy.image.pullPolicy | string | `"IfNotPresent"` | Image pull policy |
| kubeRbacProxy.image.repository | string | `"gcr.io/kubebuilder/kube-rbac-proxy"` | Image repository |
| kubeRbacProxy.image.tag | string | `"v0.16.0"` | Version of image |
| kubeRbacProxy.image.repository | string | `"quay.io/brancz/kube-rbac-proxy"` | Image repository |
| kubeRbacProxy.image.tag | string | `"v0.18.1"` | Version of image |
| kubeRbacProxy.livenessProbe | object | `{}` | https://kubernetes.io/docs/tasks/configure-pod-container/configure-liveness-readiness-startup-probes/ |
| kubeRbacProxy.readinessProbe | object | `{}` | https://kubernetes.io/docs/tasks/configure-pod-container/configure-liveness-readiness-startup-probes/ |
| kubeRbacProxy.resources | object | `{"limits":{"cpu":"250m","memory":"128Mi"},"requests":{"cpu":"100m","memory":"64Mi"}}` | ref: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/ |

View file

@ -98,13 +98,13 @@ kubeRbacProxy:
image:
# -- Image repository
repository: gcr.io/kubebuilder/kube-rbac-proxy
repository: quay.io/brancz/kube-rbac-proxy
# -- Image pull policy
pullPolicy: IfNotPresent
# -- Version of image
tag: v0.16.0
tag: v0.18.1
args:
- --secure-listen-address=0.0.0.0:8443

View file

@ -1 +1 @@
ghcr.io/cozystack/cozystack/grafana-dashboards:v1.0.0@sha256:7a3c9af59f8d74d5a23750bbc845c7de64610dbd4d4f84011e10be037b3ce2a0
ghcr.io/cozystack/cozystack/grafana-dashboards:v1.0.7@sha256:7a3c9af59f8d74d5a23750bbc845c7de64610dbd4d4f84011e10be037b3ce2a0

View file

@ -3,7 +3,7 @@ kamaji:
deploy: false
image:
pullPolicy: IfNotPresent
tag: v1.0.0@sha256:50db517ebe7698083dd32223a96c987b6ed0c88d3a093969beb571e4a96d18e4
tag: v1.0.7@sha256:d87bd84c1f79bdef08757b830b47500c57f43017ef2d47c75199136722efa65b
repository: ghcr.io/cozystack/cozystack/kamaji
resources:
limits:
@ -13,4 +13,4 @@ kamaji:
cpu: 100m
memory: 100Mi
extraArgs:
- --migrate-image=ghcr.io/cozystack/cozystack/kamaji:v1.0.0@sha256:50db517ebe7698083dd32223a96c987b6ed0c88d3a093969beb571e4a96d18e4
- --migrate-image=ghcr.io/cozystack/cozystack/kamaji:v1.0.7@sha256:d87bd84c1f79bdef08757b830b47500c57f43017ef2d47c75199136722efa65b

View file

@ -76,14 +76,18 @@ spec:
{{- end }}
- name: KC_METRICS_ENABLED
value: "true"
- name: KC_HEALTH_ENABLED
value: "true"
- name: KC_LOG_LEVEL
value: "info"
- name: KC_CACHE
value: "ispn"
- name: KC_CACHE_STACK
value: "kubernetes"
- name: KC_PROXY
value: "edge"
- name: KC_PROXY_HEADERS
value: "xforwarded"
- name: KC_HTTP_ENABLED
value: "true"
- name: KEYCLOAK_ADMIN
value: admin
- name: KEYCLOAK_ADMIN_PASSWORD
@ -128,16 +132,27 @@ spec:
- name: http
containerPort: 8080
protocol: TCP
- name: management
containerPort: 9000
protocol: TCP
startupProbe:
httpGet:
path: /health/ready
port: management
failureThreshold: 30
periodSeconds: 10
livenessProbe:
httpGet:
path: /
port: http
initialDelaySeconds: 120
path: /health/live
port: management
periodSeconds: 15
timeoutSeconds: 5
failureThreshold: 5
readinessProbe:
httpGet:
path: /realms/master
port: http
initialDelaySeconds: 60
timeoutSeconds: 1
path: /health/ready
port: management
periodSeconds: 10
timeoutSeconds: 5
failureThreshold: 3
terminationGracePeriodSeconds: 60

View file

@ -1,4 +1,4 @@
portSecurity: true
routes: ""
image: ghcr.io/cozystack/cozystack/kubeovn-plunger:v1.0.0@sha256:b6045fdb4f324b9b1cb44a218c40422aafbbc600b085c819ff58809bb6e97220
image: ghcr.io/cozystack/cozystack/kubeovn-plunger:v1.0.7@sha256:8bbd58457e604677d51da87b790e045eb4e78e51838bb11d25fee01bdad9cf21
ovnCentralName: ovn-central

View file

@ -1,3 +1,3 @@
portSecurity: true
routes: ""
image: ghcr.io/cozystack/cozystack/kubeovn-webhook:v1.0.0@sha256:e18f9fd679e38f65362a8d0042f25468272f6d081136ad47027168d8e7e07a4a
image: ghcr.io/cozystack/cozystack/kubeovn-webhook:v1.0.7@sha256:e18f9fd679e38f65362a8d0042f25468272f6d081136ad47027168d8e7e07a4a

View file

@ -1,3 +1,3 @@
storageClass: replicated
csiDriver:
image: ghcr.io/cozystack/cozystack/kubevirt-csi-driver:0.0.0@sha256:434aa3b8e2a3cbf6681426b174e1c4fde23bafd12a6cccd046b5cb1749092ec4
image: ghcr.io/cozystack/cozystack/kubevirt-csi-driver:0.0.0@sha256:fb47bd5e6acfb9957fb7987a27c22e55ab37232fd37cd98528815365e941ffef

View file

@ -1,5 +1,5 @@
lineageControllerWebhook:
image: ghcr.io/cozystack/cozystack/lineage-controller-webhook:v1.0.0@sha256:af765c2829db4f513084522a384710acc321bd4a332eaf7fe814fecacea1022f
image: ghcr.io/cozystack/cozystack/lineage-controller-webhook:v1.0.7@sha256:88d08240b5abcccb9df4274f965f689dc58e579f30399728d82d7be5d3d6e83c
debug: false
localK8sAPIEndpoint:
enabled: true

View file

@ -11,7 +11,7 @@ spec:
relabelConfigs:
- action: labeldrop
regex: (endpoint|namespace|pod|container)
- replacement: linstor-controller
- replacement: linstor-satellite
targetLabel: job
- sourceLabels: [__meta_kubernetes_pod_node_name]
targetLabel: node
@ -34,7 +34,7 @@ spec:
relabelConfigs:
- action: labeldrop
regex: (endpoint|namespace|pod|container)
- replacement: linstor-satellite
- replacement: linstor-controller
targetLabel: job
- sourceLabels: [__meta_kubernetes_pod_node_name]
targetLabel: controller_node

View file

@ -1,7 +1,7 @@
piraeusServer:
image:
repository: ghcr.io/cozystack/cozystack/piraeus-server
tag: 1.32.3@sha256:aa97f39d90c0726b587f0a376504f13d1f308adeb42db7d98cec9ac7de237361
tag: 1.32.3@sha256:64c91357affc6317d9544fc35b3ff8b2fcb065ad8fc5ed26f7a2fa8ac991a1c1
# Talos-specific workarounds (disable for generic Linux like Ubuntu/Debian)
talos:
enabled: true
@ -13,4 +13,4 @@ linstor:
linstorCSI:
image:
repository: ghcr.io/cozystack/cozystack/linstor-csi
tag: v1.10.5@sha256:c87b6f6dadaa6e3a3643d3279e81742830147f6c38f99e9232d9780abbcac897
tag: v1.10.5@sha256:c3c41b154cde941612e27f19b537b49b104d8d42bc638a384cd0d1836e98c79c

View file

@ -1,3 +1,3 @@
objectstorage:
controller:
image: "ghcr.io/cozystack/cozystack/objectstorage-controller:v1.0.0@sha256:e40e94f3014cfd04cce4230597315a1acfcca2daa8051b987614d0c05da6d928"
image: "ghcr.io/cozystack/cozystack/objectstorage-controller:v1.0.7@sha256:d873325577d005b549557d22f331f9b7be94727479af296de99672367c7ee963"

View file

@ -7,19 +7,31 @@ spec:
groups:
- name: linstor.rules
rules:
- alert: linstorControllerOffline
- alert: linstorControllerUnavailable
annotations:
description: |
LINSTOR Controller is not reachable.
expr: up{job="linstor-controller"} == 0
LINSTOR Controller deployment has no available replicas.
expr: kube_deployment_status_replicas_available{namespace="cozy-linstor",deployment="linstor-controller"} < 1
for: 3m
labels:
severity: critical
- alert: linstorControllerMetricsScrapeFailing
annotations:
description: |
LINSTOR Controller metrics endpoint is not being scraped successfully.
expr: up{job="linstor-controller"} == 0
for: 10m
labels:
severity: warning
- alert: linstorSatelliteErrorRate
annotations:
description: |
LINSTOR Satellite "{{ $labels.name }}" reports {{ $value }} errors in the last 15 minutes.
Use "linstor error-reports list --nodes {{ $labels.name }} --since 15minutes" to see them.
expr: increase(linstor_error_reports_count{module="SATELLITE"}[15m]) > 0
LINSTOR Satellite "{{ $labels.hostname }}" reports {{ $value }} errors in the last 15 minutes.
Use "linstor error-reports list --nodes {{ $labels.hostname }}" to inspect the reports.
expr: |
increase(linstor_error_reports_count{module="SATELLITE"}[15m]) > 0
and on(instance, job)
min_over_time(up{job="linstor-controller"}[15m]) == 1
labels:
severity: warning
- alert: linstorControllerErrorRate
@ -33,7 +45,7 @@ spec:
- alert: linstorSatelliteNotOnline
annotations:
description: |
LINSTOR Satellite "{{ $labels.name }}" is not ONLINE.
LINSTOR Satellite "{{ $labels.hostname }}" is not ONLINE.
Check that the Satellite is running and reachable from the LINSTOR Controller.
expr: linstor_node_state{nodetype="SATELLITE"} != 2
labels:

View file

@ -177,7 +177,7 @@ seaweedfs:
bucketClassName: "seaweedfs"
region: ""
sidecar:
image: "ghcr.io/cozystack/cozystack/objectstorage-sidecar:v1.0.0@sha256:2a3595cd88b30af55b2000d3ca204899beecef0012b0e0402754c3914aad1f7f"
image: "ghcr.io/cozystack/cozystack/objectstorage-sidecar:v1.0.7@sha256:8644a157dec5b4af93e80f863966259382613f55290ebd212e4fe4dab6d8312b"
certificates:
commonName: "SeaweedFS CA"
ipAddresses: []

View file

@ -224,8 +224,8 @@ func buildPostProcessV3(kindSchemas map[string]string) func(*spec3.OpenAPI) (*sp
base, ok1 := doc.Components.Schemas[baseRef]
list, ok2 := doc.Components.Schemas[baseListRef]
stat, ok3 := doc.Components.Schemas[baseStatusRef]
if !(ok1 && ok2 && ok3) && len(kindSchemas) > 0 {
return doc, fmt.Errorf("base Application* schemas not found")
if !(ok1 && ok2 && ok3) {
return doc, nil // not the apps GV — nothing to patch
}
// Clone base schemas for each kind
@ -339,8 +339,8 @@ func buildPostProcessV2(kindSchemas map[string]string) func(*spec.Swagger) (*spe
base, ok1 := defs[baseRef]
list, ok2 := defs[baseListRef]
stat, ok3 := defs[baseStatusRef]
if !(ok1 && ok2 && ok3) && len(kindSchemas) > 0 {
return sw, fmt.Errorf("base Application* schemas not found")
if !(ok1 && ok2 && ok3) {
return sw, nil // not the apps GV — nothing to patch
}
for kind, raw := range kindSchemas {