A gpus entry can now reference a held GPUDevice by name or ask for a
device of a class for as long as the VM runs, next to the existing raw
resource name. References are rendered only as the device-reference
label and one JSON list in the devices annotation on the VMI template.
The GPU webhook resolves them when the VMI is created, and the label is
what selects the VMI and its virt-launcher pod for it.
The schema cannot say "exactly one of", so name becomes optional and
the template refuses an entry that sets none or several of the three,
a list mixing raw names with references, a device listed twice, and a
deviceTemplate without a class or with a count below one. A zero
deviceTemplate counts as unset, since a typed client sends one on
every entry. The dashboard offers the tenant's devices and the GPU
catalog through the gpudevice and gpuclass option sources.
Assisted-by: LLM
Signed-off-by: Aleksei Sviridkin <f@lex.la>
Keying the network-data on instanceProfile reached every VM that never
set the field, because the profile defaults to ubuntu whatever image
the disk holds. The sysconfig, NetworkManager and eni renderers turn
each match stanza into an interface literally named after the netplan
ID, so a non-netplan guest left on the default profile would lose the
DHCP it gets today. A VM with neither cloudInit nor sshKeys would also
gain a cloud-init disk on upgrade, and KubeVirt's NoCloud instance-id
is new to that guest, so its next boot would regenerate host keys as a
first boot.
The configuration also shadows a static NIC set up through netplan:
netplan emits one networkd file per ID, networkd applies only the first
file in lexical order that matches a link, and 10-netplan-cozy-en sorts
before the file for enp2s0. The external-VLAN recipe claimed otherwise.
An explicit netplanDhcp value, off by default, leaves every existing
VM rendering exactly as before and lets the documentation say when not
to turn it on.
Assisted-by: LLM
Signed-off-by: Mattia Eleuteri <mattia@hidora.io>
A netplan guest configures only the interface cloud-init's fallback
configuration covers, and keeps none of the search domains DHCP offers
it, so two things the platform already puts on the wire never reach it.
virt-launcher runs a DHCP server on every bridge-bound interface,
secondary ones included, yet a VM joined to a VPC subnet leaves that
interface inert for want of a client asking. The same server advertises
the launcher pod's search domains as option 119, which systemd-networkd
discards because UseDomains= defaults to no, and a cluster domain under
.local then falls through to the mDNS exclusion in resolved and answers
REFUSED.
The virtual-machine chart carried a network-data template for the first
of those, gated on systemDisk.image. Splitting that chart into vm-disk
and vm-instance removed the template along with the field it read, and
neither came back.
Matching en* and eth* rather than naming interfaces by index keeps the
configuration correct whatever the guest enumerates its NICs as, which
is where the previous template was fragile.
Assisted-by: LLM
Signed-off-by: Mattia Eleuteri <mattia@hidora.io>
The memory guard refused only zero and negative amounts, while KubeVirt
admission refuses a non-zero amount below 1M. A value such as 500m or
1Ki rendered cleanly and then failed when the VirtualMachine was
applied, two hops away from the value that caused it. The render now
refuses it with the reason.
This is breaking: a memory above zero and below 1M rendered before and
no longer does. Such a VM could not be admitted by KubeVirt either.
Assisted-by: LLM
Signed-off-by: Aleksei Sviridkin <f@lex.la>
The cpu and sockets descriptions named millicore and fractional values
as refused, while the guard also refuses other unit suffixes, zero,
negative, past-uint32 and quoted leading-zero values. An operator
reading the schema got a narrower rule than the render enforces. The
error message gains the negative case for the same reason.
Assisted-by: LLM
Signed-off-by: Aleksei Sviridkin <f@lex.la>
The resource guard quoted the decoded value in its error. An unquoted
YAML number has lost its spelling by the time the chart sees it, and a
large one formats in exponent form, so an operator who wrote 4294967296
was told about 4.294967296e+09. The spelling cannot be recovered after
decode, so a number is printed in plain digits and marked as read, while
a string still appears exactly as written.
Assisted-by: LLM
Signed-off-by: Aleksei Sviridkin <f@lex.la>
resources.cpu and resources.sockets are typed as quantities, but they
land in domain.cpu.cores and domain.cpu.sockets, which KubeVirt
declares as uint32. The chart cast them with int64, which turns 500m,
1.5 or 1e1 into 0 without an error, and KubeVirt boots a zero core
count as one core. The user asked for half a core and got a one-core
VM with nothing reporting it.
The raw spelling is now decoded as YAML, the way an integer field
reads it, and the render stops unless the result is a positive whole
number that fits in uint32. A leading zero is refused, because YAML
reads 010 as octal 8. The check keys on presence rather than
truthiness, so an unquoted 0 is refused instead of being read as
unset.
Memory gets the same presence check. A quoted "0" was truthy and
rendered requests.memory: "0", while an unquoted 0 was falsy and
dropped, so one quantity took two paths. A zero or negative amount
now stops the render in both spellings.
BREAKING CHANGE: values that used to render now either fail or
render differently. A cpu or sockets that does not decode to a plain
whole number within uint32 (a millicore, suffixed such as 1k,
fractional, zero, negative or leading-zero value), and a zero or
negative memory, fail the next upgrade of the release until the
value is fixed. This includes cpu or sockets set on its own beside an
instanceType, which used to be ignored whatever it held. A spelling
that the int64 cast truncated to 0 but that YAML decodes to a whole
number, such as the exponent 1e1 or the trailing dot 2., used to boot
one core and now sizes the VM with the count it spells, so such a VM
changes size on upgrade.
Assisted-by: LLM
Signed-off-by: Aleksei Sviridkin <f@lex.la>
## What this PR does
Guards the Kube-OVN `IP` lookup behind API discovery. The `vm-instance`
chart now renders on clusters using another CNI instead of trying to
query a CRD that is not installed.
The Helm regression suite mocks the IP object through
`kubernetesProvider` and pins both sides: with `kubeovn.io/v1/IP`
advertised the annotations carry the mocked MAC and IP, without it they
are absent even though the object exists, which is the branch the guard
adds. helm-unittest's fake lookup never errors on an unserved kind, so
only the second case distinguishes the guard; it fails on main and
passes here.
Open PRs #3991, #3978, #3931, and #3900 touch the same template. Their
current hunks do not alter this lookup; #3900 adds secondary-interface
annotations immediately after it, so it is the only nearby merge hunk to
watch.
### Screenshots
Not applicable; there is no UI change.
### Downstream repositories
- [x] No downstream repository is affected by this change
- [ ] [cozystack/website](https://github.com/cozystack/website) -
follow-up:
- [ ]
[cozystack/terraform-provider-cozystack](https://github.com/cozystack/terraform-provider-cozystack)
- follow-up:
- [ ]
[cozystack/ansible-cozystack](https://github.com/cozystack/ansible-cozystack)
- follow-up:
- [ ] [cozystack/ccp](https://github.com/cozystack/ccp) - follow-up:
- [ ] [cozystack/talm](https://github.com/cozystack/talm) - follow-up:
- [ ] [cozystack/cozyhr](https://github.com/cozystack/cozyhr) -
follow-up:
- [ ] [cozystack/cozy-proxy](https://github.com/cozystack/cozy-proxy) -
follow-up:
- [ ]
[cozystack/cozystack-telemetry-server](https://github.com/cozystack/cozystack-telemetry-server)
- follow-up:
- [ ]
[cozystack/external-apps-example](https://github.com/cozystack/external-apps-example)
- follow-up:
- [ ] [cozystack/examples](https://github.com/cozystack/examples) -
follow-up:
### Release note
```release-note
fix(virtual-machine): render VM instances on clusters where the Kube-OVN IP API is not installed.
```
<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit
* **Bug Fixes**
* VM instances now render correctly in environments without the Kube-OVN
IP capability.
* OVN IP lookups and MAC/IP annotations are only generated when the
required Kube-OVN API is available.
* MAC/IP annotations are omitted when the capability is unavailable,
even if an IP object exists.
* **Tests**
* Added coverage for both supported and unsupported Kube-OVN IP
discovery scenarios.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
KubeVirt refuses a VirtualMachine that carries an instancetype matcher and
explicit domain sizing at once. validateCPU in pkg/instancetype/apply
conflicts on domain.cpu.cores and domain.cpu.sockets when they are
non-zero, and validateMemory conflicts on
domain.resources.requests.memory whenever the key is present. The chart
rendered both, because the matcher keyed off instanceType while the
domain sizing keyed off resources, and neither side looked at the other.
values.yaml ships instanceType "u1.medium", so clearing that field in the
dashboard only falls back to the default. A user who then fills in cpu,
sockets and memory gets a VM the webhook rejects, with an error naming
fields the form gives them no way to clear.
Resources that size the VM completely now replace the matcher, the same
way the kubernetes-nodes chart sizes its worker VMs. Beside an instance
type, sizing that is only partial stops the render, because there is then
no safe reading: dropping the matcher would size the VM from fields the
user never finished, and keeping it either loses to the webhook or
silently discards what was typed. With no instance type in play there is
nothing to conflict with, so that half is left as it renders today.
Completeness is decided from what domainResources emitted, not from which
keys the user set, and the two readings come apart. resources.cpu on its
own emits nothing, so it conflicts with nothing and goes on rendering a
plain instancetype-sized VM. cpu and sockets pass through int64, which
yields 0 for a quantity the schema accepts, so a cpu of 500m beside a
whole sockets and a memory would read as complete from the values, drop
the matcher, and hand KubeVirt a cores of 0 the user never asked for. And
a resources block nulled outright leaves .Values.resources nil, where a
raw field read is a render-time nil pointer and the emitted object is
merely empty.
The existence check and the update hook read the same effective value.
Keying the lookup on the raw one would fail a resource-sized render over
an instance type it never references, which is the same confusing error
this fixes. Reading .Values in the hook would see the leftover
instanceType, skip the removal patch, and leave
spec.instancetype.revisionName on a VM Helm had just given explicit
domain resources.
Assisted-by: LLM
Signed-off-by: Aleksei Sviridkin <f@lex.la>
Hidora's customers are leaving VMware now, and a tenant has to be able to
import their own machines without a platform administrator. The chart
approach could not express that: a tenant can neither create the Secret
holding vCenter credentials nor name the VDDK image, so both had to come
from somewhere they cannot reach.
Two CRDs in a new `forklift.cozystack.io` group, split by lifecycle. A
VMImportSource is a long-lived connection -- type, endpoint, credentials,
readiness -- and a VMImportTask is the one-shot operation that names
machines and produces VMDisks and VMInstances. The outputs carry no owner
reference back to the task, so deleting a finished import leaves the
machines alone. Konveyor Forklift does the transfer underneath; the
controller renders its objects, mirrors its verdicts, and hands each
finished volume into a VMDisk without copying it.
What a live vCenter migration forced out, and no amount of source reading
would have:
- A guest copied verbatim keeps the drivers it had under VMware and no
virtio, so on a virtio disk it does not fail the import -- it succeeds
and then does not boot. Imported disks go on SATA.
- VDDK connects straight to the ESXi host at the address vCenter
advertises, which is routinely unreachable, and on the first cluster
collided with the Service CIDR. `spec.hosts` redirects per host.
- Firmware must be carried across or a UEFI guest imports as BIOS and
never boots (stacked on #3002).
- Deleting a task mid-transfer orphaned its DataVolume; a finalizer now
removes the engine's volumes and leaves the outputs.
The console gains a Migration section: connections are editable, and the
VM field is a picker built from a machine list the controller publishes,
since the aggregated API cannot reach the inventory and should not hold a
source's credentials to try. Two general mechanisms fall out of that --
an option source may take an argument, and one named in a CRD annotation
may reference a sibling field.
Design: cozystack/community#62. Docs: cozystack/website#673.
Signed-off-by: Andrei Kvapil <kvapss@gmail.com>
Helm's `lookup` propagates the discovery error when the requested API
group is not served, so the vm-instance chart could not render at all on
clusters without the Kube-OVN CRDs. Gate the IP lookup behind
`.Capabilities.APIVersions.Has "kubeovn.io/v1/IP"`.
The regression suite mocks the IP object through kubernetesProvider and
pins both sides: with the API advertised the annotations carry the mocked
MAC and IP, without it they are absent even though the object exists.
helm-unittest's fake lookup never errors on an unserved kind, so only the
second case distinguishes the guard; it fails on main and passes here.
Assisted-By: GPT-5 <noreply@openai.com>
Signed-off-by: Loïc Fontaine <lfinmauritius@users.noreply.github.com>
The vm-disk pvc-resize, cozystack-api, seaweedfs and vm-instance update
hooks (whose alpine/k8s image this PR refreshes) ran as root with no
securityContext. Add a pod-level runAsNonRoot + runAsUser 65534 +
seccompProfile RuntimeDefault and a container-level
allowPrivilegeEscalation: false + capabilities drop ALL, mirroring the
dashboard adopt hook. kubectl needs no root, so this is behavior-neutral.
Each hook is lookup-gated; pin the securityContext in a per-chart
helm-unittest that mocks the gating object (DaemonSet / PVC / Service) via
kubernetesProvider so the guard renders without a cluster. vm-disk and
vm-instance had no Makefile test target, so add 'test: helm unittest .' to
both so CI runs the new suites.
Scope note: other kubectl hooks on clastix/kubectl (mariadb, keycloak,
kubernetes, tenant) are untouched here — they are not part of this
alpine/k8s refresh and belong to a separate hardening pass.
Also fix the vm-disk resize hook's backoffLimit: it was nested under the
pod spec (silently ignored, leaving the Job at the default 6 retries)
instead of Job.spec. Move it to Job.spec and pin it in the test.
Assisted-By: Claude <noreply@anthropic.com>
Signed-off-by: Aleksei Sviridkin <f@lex.la>
Six further references to the alpine/k8s tools image were still pinned at
1.33.4 across the installer, the cozystack-api post-upgrade hook, the vm-disk
and vm-instance resize hooks, the vertical-pod-autoscaler CRD-install override,
and the e2e cilium leak healer. Move them all to 1.36.2 so the whole repo runs
a single current tools-image version (the two digest-pinned refs get the
matching multi-arch digest sha256:44ef4942...). Same stale-stdlib remediation
as the seaweedfs bump in this PR.
Assisted-By: Claude <noreply@anthropic.com>
Signed-off-by: Aleksei Sviridkin <f@lex.la>
Regenerate values.schema.json and embedded openAPISchema in the -rd
ApplicationDefinitions so the x-cozystack-options dynamic-source
directives declared in each app values.yaml are carried into the
generated artifacts. Brings the -rd schemas in sync with the
hand-edited values.schema.json files (CI runs make generate +
git diff --exit-code).
Co-Authored-By: Claude <noreply@anthropic.com>
Signed-off-by: Andrei Kvapil <andrei.kvapil@aenix.io>
The instanceProfile field is now driven by an x-cozystack-options dynamic
dropdown (source: instanceprofile), so the Makefile generate step no longer
needs to post-inject a static enum into values.schema.json via yq. Remove
that injection along with the already-commented-out instanceType enum
injection so the dynamic dropdown is not fought by a stale static enum.
Co-Authored-By: Claude <noreply@anthropic.com>
Signed-off-by: Andrei Kvapil <andrei.kvapil@aenix.io>
Move the dynamic-dropdown x-cozystack-options vendor extensions from the
generated values.schema.json into the values.yaml source for vm-instance,
kubernetes, vm-disk and bucket so they survive schema regeneration. The new
cozyvalues-gen @x-<keyword> directive emits these extensions from the source
annotations. Annotations on typedef @field entries (Disk, Network, GPU,
NodeGroup) are declared once and cover every place the typedef is reused.
Co-Authored-By: Claude <noreply@anthropic.com>
Signed-off-by: Andrei Kvapil <andrei.kvapil@aenix.io>
Mark fields that reference cluster resources with the x-cozystack-options
vendor keyword so the dashboard renders them as dynamic dropdowns:
GPU, instanceType, instanceProfile, network (vm-instance), GPU/
instanceType (kubernetes nodeGroups), image (vm-disk), storagePool
(bucket), storageClass (all apps) and disks[].name (vm-instance). Drop
the stale static instanceProfile enum.
Co-Authored-By: Claude <noreply@anthropic.com>
Signed-off-by: Andrei Kvapil <andrei.kvapil@aenix.io>
Address review feedback from lexfrei: dropping the centos.7/centos.7.desktop/
centos.stream8{,.desktop,.dpdk} VirtualMachineClusterPreference objects hard-fails
the vm-instance Helm render (vm.yaml fails when a referenced preference is absent)
and makes the dynamic CRD enum reject the stored value for every existing VM on
those profiles on upgrade. Re-add them as deprecated aliases in
extra-instancetypes.yaml, mirroring the gn1.* GPU instancetype treatment, and
extend the vm-instance enum generation to union preference names from
extra-instancetypes.yaml so the retained profiles stay in values.schema.json and
the RD schema.
Assisted-By: Claude <noreply@anthropic.com>
Signed-off-by: Myasnikov Daniil <myasnikovdaniil2001@gmail.com>
Building from unpinned common-instancetypes HEAD on every `make update` silently
churns the catalog. Worse, the v1.3.0 upstream removal dropped the gn1.* (GPU
NVIDIA) instancetypes that existing GPU VMs and tenant Kubernetes GPU workers
still reference — vm-instance/templates/vm.yaml hard-fails the render when a
referenced instancetype is absent.
Pin the source to a commit SHA (not a tag: the multi-arch preferredArchitecture
fields exist only on main past v1.6.0, so a tag would regress them) and
re-append the gn1.* objects from a Cozystack-local extra-instancetypes.yaml the
regen copies into templates/. The EOL centos.7*/centos.stream8* preferences
stay dropped (release-noted). Regenerate the vm-instance and kubernetes README
instancetype/preference tables to match the shipped catalog.
Assisted-By: Claude <noreply@anthropic.com>
Signed-off-by: Myasnikov Daniil <myasnikovdaniil2001@gmail.com>
When a disk entry has no bus set (the schema default), the previous
template rendered `disk:` with no value — YAML parses that as
`disk: null` and KubeVirt's virtualmachines-mutator webhook denies the
request with: "spec.template.spec.domain.devices.disks.disk in body
must be of type object: null".
Restructure the disk loop so the disk/cdrom value is always a valid
object: `disk: {}` when bus is empty, `disk: {bus: <x>}` when set.
Mirrors how `cloudinitdisk` already does it in the same template.
Signed-off-by: Myasnikov Daniil <myasnikovdaniil2001@gmail.com>
(cherry picked from commit 0f3d2fa3a6)
(cherry picked from commit e2c6b7b60b)
`make update` stripped `persistent: true` from upstream's
`preferredTPM: { persistent: true }`, leaving the parent key with a null value.
KubeVirt v1.6's CRD tolerated it; v1.8 (the operator version we bumped to in
6af0bf71) enforces structural schema and rejects null:
VirtualMachineClusterPreference "windows.11" is invalid:
spec.devices.preferredTPM: Invalid value: "null": spec.devices.preferredTPM
in body must be of type object: "null"
Stop stripping the line and regenerate the templates from upstream
common-instancetypes. Persistent TPM state falls back to the cluster default
StorageClass with RWO access mode when `vmStateStorageClass` is unset on the
KubeVirt CR, per pkg/storage/backend-storage/backend-storage.go.
Drive-by from the regen:
- Removed (upstream EOL): centos.7*, centos.stream8*
- Added: debian, oraclelinux, legacy, linux*, fedora.s390x, rhel.{9,10}.s390x,
windows.{xp,7,7.virtio,2k3,2k8,2k8.virtio,2k12,2k12.virtio}, plus new
cx1.*1gi and d1 instancetype variants.
Also regenerates packages/apps/vm-instance instanceProfile enum
(values.schema.json / README.md) from the refreshed preferences.yaml.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Signed-off-by: Myasnikov Daniil <myasnikovdaniil2001@gmail.com>
- Add `externalAllowICMP` value (default true) propagated as
`networking.cozystack.io/allowICMP` annotation on the rendered Service
when `externalMethod: PortList`. The cozy-proxy companion (released as
part of cozystack/cozy-proxy#11 + #12) drops ICMP by default in
port-filter mode, which breaks ping and PMTU discovery; defaulting the
chart to "true" preserves user expectations while still allowing
operators to opt out by setting `externalAllowICMP: false`.
- Remove the v1.3.1.md changelog entry. Project convention is to add
changelogs in a dedicated "docs: add changelog for vX.Y.Z" commit at
release time, not as part of feature/fix PRs.
Signed-off-by: mattia-eleuteri <mattia@hidora.io>
Render `networking.cozystack.io/wholeIP: "false"` on the Service when
`externalMethod: PortList` is configured (was always `"true"` before).
Combined with cozy-proxy v0.3.0+ which adds per-port filtering for
"false"-annotated services, this makes `externalMethod: PortList`
behave as documented: only ports listed in `externalPorts` are
reachable from the LoadBalancer IP.
Backward-compatible: existing services with `externalMethod: WholeIP`
continue to set `wholeIP: "true"` and behave identically. cozy-proxy
versions older than v0.3.0 ignore Services with `wholeIP: "false"`,
which means PortList Services on older cozy-proxy will lose their
egress IP preservation — but that path was already non-functional
ingress-wise, so this is not a regression for users actually relying
on PortList.
Signed-off-by: mattia-eleuteri <mattia@hidora.io>
Add service.kubernetes.io/service-proxy-name label to LoadBalancer
services when external: true. This prevents Cilium from adding the
service to its BPF service map, fixing two issues:
1. Inter-tenant connectivity via public LB IPs: Cilium's kube-proxy
replacement DNATs traffic to LB IPs before policy evaluation,
causing the CiliumClusterwideNetworkPolicy to block legitimate
cross-tenant traffic through public IPs.
2. WholeIP broken on Cilium 1.19+ (#2327): wildcard service drop
entries block all ports not declared in the Service spec before
traffic reaches cozy-proxy's nftables rules.
With this label, Cilium completely ignores the Service. Routing is
handled by kube-ovn (via the wholeIP annotation) and MetalLB
continues to advertise the IP via L2 unaffected.
Tested on Cilium 1.18.6 and 1.19.1: inter-tenant via LB IP works,
pod IP isolation preserved, external access unaffected.
Signed-off-by: mattia-eleuteri <mattia@hidora.io>
After migration 36 copies subnets to networks, both fields are populated.
The fail guard would break Helm reconciliation. Instead, networks simply
takes priority via the existing default fallback.
Also handle missing VMInstance CRD gracefully in migration 36.
Assisted-By: Claude AI
Signed-off-by: Kirill Ilin <stitch14@yandex.ru>
Add fail validation when both 'networks' and 'subnets' are set to
prevent silent data loss during migration. Compute $networks variable
once at template top level to eliminate DRY violation. Regenerate CRD
via make generate instead of manual editing.
Assisted-By: Claude AI
Signed-off-by: Kirill Ilin <stitch14@yandex.ru>
Rename the misleading 'subnets' field to 'networks' in VMInstance to
better reflect that it attaches the VM to VPC network attachments, not
creates subnets. The old 'subnets' field is kept as deprecated with
fallback logic for backward compatibility.
Add an API-backed dropdown (listInput) for networks[].name that lists
available NetworkAttachmentDefinitions in the namespace, and hide the
deprecated subnets field from the dashboard UI.
Assisted-By: Claude AI
Signed-off-by: Kirill Ilin <stitch14@yandex.ru>
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>
Port three features from virtual-machine to vm-instance:
- Add cpuModel field to specify CPU model without instanceType
- Allow switching between instancetype and custom resources via update hook
- Migrate from running boolean to runStrategy enum
Co-Authored-By: Claude <noreply@anthropic.com>
Signed-off-by: Andrei Kvapil <kvapss@gmail.com>
Move common-envs.mk and package.mk from scripts/ to hack/ directory.
Update all Makefile includes to use new paths. Remove unused
issue-flux-certificates.sh script.
Co-Authored-By: Claude <noreply@anthropic.com>
Signed-off-by: Andrei Kvapil <kvapss@gmail.com>
Replace Helm lookup functions with FluxCD valuesFrom mechanism for
reading cluster and namespace configuration.
Changes:
- Create Secret cozystack-values in each namespace with values.yaml key
containing _cluster and _namespace configuration as nested YAML
- Configure HelmReleases to read from this Secret via valuesFrom
(valuesKey defaults to values.yaml, so it can be omitted)
- Update cozy-lib helpers to access config via .Values._cluster
- Add default values for required _cluster keys to ensure all fields exist
- Update Go code (cozystack-api and helm reconciler) to use new format
This eliminates the need for Helm lookup functions while maintaining
the same configuration interface for charts.
Co-Authored-By: Claude <noreply@anthropic.com>
Signed-off-by: Andrei Kvapil <kvapss@gmail.com>
## What this PR does
When VMs are created without a public IP, no service is created for them
and they have no in-cluster DNS name. This PR fixes this and resolves
#1731.
### Release note
```release-note
[vm] Always expose VMs with at least a ClusterIP service.
```
<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit
* **Improvements**
* Service templates now conditionally enable external-specific
annotations and settings when external mode is enabled.
* External LoadBalancer deployments support richer port configuration
(including whole-IP fallback), while internal services retain a single
default port (65535).
* External traffic policy and node port allocation are applied only in
external mode to preserve internal behavior.
<sub>✏️ Tip: You can customize this high-level summary in your review
settings.</sub>
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
## What this PR does
When VMs are created without a public IP, no service is created for them
and they have no in-cluster DNS name. This PR fixes this and resolves
#1731.
### Release note
```release-note
[vm] Always expose VMs with at least a ClusterIP service.
```
Signed-off-by: Timofei Larkin <lllamnyp@gmail.com>
This patch extends the resource-selecting function of the webhook to
also apply selectors to ingresses and services, like has been already
done for secrets. The Cozystack resource definitions have been upgraded
to contain two more fields: `ingresses` and `services` and populated
with counterparts of the legacy selectors from the dashboard roles.
```release-note
[controller, api] Enable marking ingresses and services as user-facing
and implement selectors for existing CozystackResourceDefinitions.
```
Signed-off-by: Timofei Larkin <lllamnyp@gmail.com>
[cozystack-controller] Introduce new dashboard-controller
[dashboard] Introduce new dashboard based on openapi-ui
Co-authored-by: kklinch0 <kklinch0@gmail.com>
Signed-off-by: kklinch0 <kklinch0@gmail.com>
Signed-off-by: Andrei Kvapil <kvapss@gmail.com>
Signed-off-by: Andrei Kvapil <kvapss@gmail.com>
<!-- Thank you for making a contribution! Here are some tips for you:
- Start the PR title with the [label] of Cozystack component:
- For system components: [platform], [system], [linstor], [cilium],
[kube-ovn], [dashboard], [cluster-api], etc.
- For managed apps: [apps], [tenant], [kubernetes], [postgres],
[virtual-machine] etc.
- For development and maintenance: [tests], [ci], [docs], [maintenance].
- If it's a work in progress, consider creating this PR as a draft.
- Don't hesistate to ask for opinion and review in the community chats,
even if it's still a draft.
- Add the label `backport` if it's a bugfix that needs to be backported
to a previous version.
-->
## What this PR does
Fix regression introduced by
https://github.com/cozystack/cozystack/pull/1169, now we have correct
singular names for virtualmachines which are conflictiing with KubeVirt
ones.
Solution: explicitly specify apiversion
### Release note
<!-- Write a release note:
- Explain what has changed internally and for users.
- Start with the same [label] as in the PR title
- Follow the guidelines at
https://github.com/kubernetes/community/blob/master/contributors/guide/release-notes.md.
-->
```release-note
[virtual-machine] Fix vm update hook
```
<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit
* **Bug Fixes**
* Improved reliability of VM update hooks by targeting the correct API
resource, preventing occasional patch failures when updating
instancetype and preference.
* Ensures VM updates apply consistently across environments without
changing existing behavior.
* **Chores**
* Aligned resource references with fully qualified API names to enhance
compatibility with current cluster configurations.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
Signed-off-by: Andrei Kvapil <kvapss@gmail.com>
<!-- Thank you for making a contribution! Here are some tips for you:
- Start the PR title with the [label] of Cozystack component:
- For system components: [platform], [system], [linstor], [cilium],
[kube-ovn], [dashboard], [cluster-api], etc.
- For managed apps: [apps], [tenant], [kubernetes], [postgres],
[virtual-machine] etc.
- For development and maintenance: [tests], [ci], [docs], [maintenance].
- If it's a work in progress, consider creating this PR as a draft.
- Don't hesistate to ask for opinion and review in the community chats,
even if it's still a draft.
- Add the label `backport` if it's a bugfix that needs to be backported
to a previous version.
-->
## What this PR does
This PR removes bitnami images from all charts. Bitnami has deprecated
their free images, see details here:
- https://github.com/bitnami/charts/issues/35164
Also dashboard has moved helper images to `bitnamilegacy`, we will fully
replace it by our new dashboard soon:
- https://github.com/cozystack/cozystack/pull/1269
### Release note
<!-- Write a release note:
- Explain what has changed internally and for users.
- Start with the same [label] as in the PR title
- Follow the guidelines at
https://github.com/kubernetes/community/blob/master/contributors/guide/release-notes.md.
-->
```release-note
Get rid of bitnami images
```
<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit
* New Features
* Added configurable image overrides for Kubeapps components (frontend,
auth proxy, Redis, kubectl).
* Introduced image settings for Velero’s kubectl helper.
* Added image configuration for Vertical Pod Autoscaler components.
* Added a configurable resize hook image for SeaweedFS volumes.
* Chores
* Standardized kubectl-related images to alpine/k8s:1.33.4 across
multiple operational hooks (VM update, PVC resize, etcd maintenance,
SeaweedFS pre-upgrade), with no behavioral changes.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->