Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
30 commits
Select commit Hold shift + click to select a range
5e99874
docs: add release notes for v1.9.3 (#2604)
Isteb4k Jul 7, 2026
e132f73
Changelog v1.9.3 (#2573)
deckhouse-BOaTswain Jul 7, 2026
1144772
fix(vm): reduce virt-launcher log volume (#2561)
eofff Jul 8, 2026
14583ba
fix(vm): start VM after restore for all run policies (#2577)
danilrwx Jul 8, 2026
888698f
chore(ci): silence dmt mount-points and webhook-annotation checks (#2…
nevermarine Jul 8, 2026
f4fcd9e
chore(ci): add sds-elastic e2e tests (#2608)
nevermarine Jul 8, 2026
7600bd0
test(test): add iperf migration continuity checks to release e2e (#2617)
hayer969 Jul 9, 2026
4694576
fix(vm): read ansible-inventory host vars from the vars. annotation p…
fl64 Jul 9, 2026
2ae8bae
fix(vm): fix VM stuck until the child KVVMI in Failed phase is delet…
yaroslavborbat Jul 9, 2026
531e7d6
feat(vmpool): add VirtualMachinePool for group VM management (#2572)
fl64 Jul 9, 2026
54f6d8a
feat(vmpool): enable VirtualMachinePool in EE/SE+ without a feature g…
fl64 Jul 9, 2026
a7d61a8
feat(network): bind live migration to a dedicated SystemNetwork (#2222)
loktev-d Jul 9, 2026
dbb09fc
chore(ci): use ru registry for release checks (#2476)
universal-itengineer Jul 9, 2026
4ff8078
fix(vmclass): make sizing policy validation messages actionable and c…
fl64 Jul 9, 2026
53555c3
docs: add VM launcher update notes to release notes (#2613)
prismagod Jul 9, 2026
855f8db
Chore/remove cdi (#2394)
Isteb4k Jul 9, 2026
247fddb
test(e2e): bump VI-derived disk size to 450Mi (#2627)
Isteb4k Jul 9, 2026
1994cce
feat(vm): switch VM network datapath to eBPF bpfbridge binding (#2212)
LopatinDmitr Jul 9, 2026
65c4ebb
feat(audit): add audit events (#2611)
Suselz Jul 10, 2026
5d1718f
chore(ci): fix dlv debug tasks for all controller components (#2631)
danilrwx Jul 10, 2026
0447deb
fix(images, disks): self-heal uploader ingress tls secret to unblock …
fl64 Jul 10, 2026
8dfbd20
feat(network): add metrics for conntrack sync (#2542)
loktev-d Jul 10, 2026
121e8de
fix(vm): dynamic domain wait timeout (#2616)
danilrwx Jul 10, 2026
df1a317
chore(api): integrate crd-enricher into CRD codegen (#2622)
prismagod Jul 10, 2026
f9568db
fix(vm): move disks to preset bus when enableParavirtualization flips…
universal-itengineer Jul 10, 2026
4ebef2f
fix(observability): correct audit server default TLS paths and prefix…
danilrwx Jul 10, 2026
155bf11
docs: add localized disable confirmation messages (#2639)
prismagod Jul 10, 2026
dae46dc
feat(vm): add VNC screenshot subresource
fl64 Jul 10, 2026
0faf073
fix(vm): register VirtualMachineVNCScreenshot in internal scheme
fl64 Jul 12, 2026
cf84b97
feat(vm): add Screenshot method to virtualization kubeclient
fl64 Jul 12, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
The table of contents is too big for display.
Diff view
Diff view
  •  
  •  
  •  
82 changes: 66 additions & 16 deletions .dmtlint.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -13,25 +13,15 @@ linters-settings:
- "spec.versions[0].schema.openAPIV3Schema.properties.spec.properties.contentType"
rbac:
exclude-rules:
# We exclude RBAC rules for virt-operator and cdi-operator because they create ClusterRoles and ClusterRoleBindings with wildcards.
# If we remove wildcard, virt-operator and cdi-operator will be unable to create them, as they do not have wildcard permissions themselves.
# We exclude RBAC rules for virt-operator because it creates ClusterRoles and ClusterRoleBindings with wildcards.
# If we remove wildcard, virt-operator will be unable to create them, as it does not have wildcard permissions itself.
wildcards:
- kind: ClusterRole
name: d8:virtualization:kubevirt-operator
- kind: ClusterRole
name: d8:containerized-data-importer:cdi-operator

# We exclude RBAC rules for CDI and Kubevirt resources because they are used by upstream deployments.
# We exclude RBAC rules for Kubevirt resources because they are used by upstream deployments.
# Changing these rules will require patching upstream code.
placement:
- kind: ClusterRoleBinding
name: d8:containerized-data-importer:cdi-operator
- kind: ServiceAccount
name: cdi-operator
- kind: Role
name: cdi-operator
- kind: RoleBinding
name: cdi-operator
- kind: ServiceAccount
name: kubevirt-operator
- kind: Role
Expand All @@ -40,10 +30,7 @@ linters-settings:
name: kubevirt-operator
- kind: RoleBinding
name: virt-operator
- kind: ClusterRole
name: d8:containerized-data-importer:cdi-operator
binding-subject:
- cdi-sa
- kubevirt-internal-virtualization-controller
- kubevirt-internal-virtualization-handler
module:
Expand All @@ -54,6 +41,7 @@ linters-settings:
- test/performance/ssh
- test/e2e/legacy/testdata/sshkeys
- images/dvcr-artifact/staging
- images/pvc-artifact/staging
container:
exclude-rules:
readiness-probe:
Expand All @@ -64,3 +52,65 @@ linters-settings:
- kind: Deployment
name: dvcr
container: dvcr-garbage-collection
no-cyrillic:
exclude-rules:
files:
- templates/security-events.yaml # Ru information for docs
templates:
exclude-rules:
# These mount-points.yaml directories pre-create mount points for containerd strict mode.
# They are consumed by pods that are NOT rendered from this module's Helm templates:
# virt-launcher (created per-VM by KubeVirt at runtime), dvcr importer/uploader (created on
# demand by the controllers), and the virt-* components deployed by virt-operator.
# The mount-points linter only inspects Helm pod controllers, so it cannot see these
# mountPaths and reports false positives.
mount-points:
- /auth
- /certs
- /data
- /dev/bus/usb
- /dvcr-auth
- /dvcr-src-auth
- /etc/docker/registry
- /etc/libvirt
- /etc/podinfo
- /etc/ssl/docker
- /etc/virt-api/certificates
- /etc/virt-controller/certificates
- /etc/virt-controller/exportca
- /etc/virt-handler/clientcertificates
- /etc/virt-handler/servercertificates
- /etc/virt-operator/certificates
- /etc/virtualization-api-proxy/certificates
- /etc/virtualization-api/certificates
- /etc/virtualization-audit/certificates
- /init/usr/bin
- /kubeconfig.local
- /opt
- /path
- /pods
- /profile-data
- /proxycerts
- /run/cilium
- /run/kubevirt
- /run/kubevirt-libvirt-runtimes
- /run/kubevirt-private
- /scratch
- /shared
- /tmp/k8s-webhook-server/serving-certs
- /usr/lib/modules
- /var/cache/libvirt
- /var/lib/kubelet/device-plugins
- /var/lib/kubelet/plugins
- /var/lib/kubelet/plugins_registry
- /var/lib/kubelet/pods
- /var/lib/kubevirt
- /var/lib/kubevirt-node-labeller
- /var/lib/libvirt
- /var/lib/libvirt/qemu
- /var/lib/libvirt/qemu/nvram
- /var/lib/libvirt/swtpm
- /var/lib/registry
- /var/lib/swtpm-localca
- /var/log/libvirt
- /var/run/cdi
2 changes: 1 addition & 1 deletion .github/CODEOWNERS
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
/tests/ @hardcoretime @danilrwx

/images/ @universal-itengineer @nevermarine
/images/cdi-artifact/ @Isteb4k @yaroslavborbat @diafour
/images/pvc-artifact/ @Isteb4k @yaroslavborbat @diafour
/images/virt-artifact/ @Isteb4k @yaroslavborbat @diafour
/images/dvcr-artifact/ @Isteb4k @yaroslavborbat @diafour
/images/vm-route-forge/ @yaroslavborbat @diafour
Expand Down
1 change: 1 addition & 0 deletions .github/actions/milestone-changelog/action.yml
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@ runs:
vdsnapshot
vmsnapshot
vmrestore
vmpool
disks
vd
images
Expand Down
18 changes: 15 additions & 3 deletions .github/scripts/bash/e2e/cleanup-nightly-resources.sh
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,10 @@ source "${SCRIPT_DIR}/common.sh"
LABEL_SELECTOR="${LABEL_SELECTOR:-test=nightly-e2e}"
KEEP_HOURS="${KEEP_HOURS:-47}"
FRIDAY_KEEP_HOURS="${FRIDAY_KEEP_HOURS:-71}"
# sds-elastic (Ceph) nested clusters are heavy, so they are torn down sooner (~1 day)
# and are not granted the Friday extension. Matched by storage type in the resource name.
ELASTIC_KEEP_HOURS="${ELASTIC_KEEP_HOURS:-23}"
ELASTIC_NAME_PATTERN="${ELASTIC_NAME_PATTERN:-sds-elastic}"

current_date_seconds="$(date -u +%s)"

Expand All @@ -35,20 +39,28 @@ collect_items_json() {

should_keep() {
local created_at="$1"
local name="$2"
local resource_created_at_seconds
local age_seconds
local weekday_of_day
local keep_hours="${KEEP_HOURS}"
local friday_keep_hours="${FRIDAY_KEEP_HOURS}"

if [[ "${name}" == *"${ELASTIC_NAME_PATTERN}"* ]]; then
keep_hours="${ELASTIC_KEEP_HOURS}"
friday_keep_hours="${ELASTIC_KEEP_HOURS}"
fi

resource_created_at_seconds="$(date -d "${created_at}" -u +%s)"
age_seconds="$(( current_date_seconds - resource_created_at_seconds ))"
weekday_of_day="$(date -d "${created_at}" -u +%u)"

if [ "${age_seconds}" -lt "$(( KEEP_HOURS * 3600 ))" ]; then
if [ "${age_seconds}" -lt "$(( keep_hours * 3600 ))" ]; then
echo "keep"
return 0
fi

if [ "${weekday_of_day}" -eq 5 ] && [ "${age_seconds}" -lt "$(( FRIDAY_KEEP_HOURS * 3600 ))" ]; then
if [ "${weekday_of_day}" -eq 5 ] && [ "${age_seconds}" -lt "$(( friday_keep_hours * 3600 ))" ]; then
echo "keep"
return 0
fi
Expand All @@ -69,7 +81,7 @@ cleanup_kind() {
created_at="$(echo "${item}" | jq -r '.created_at')"
[ -z "${name}" ] && continue

decision="$(should_keep "${created_at}")"
decision="$(should_keep "${created_at}" "${name}")"
if [ "${decision}" = "keep" ]; then
printf "%-63s %22s\n" "[INFO] Keep ${kind}/${name}:" "created_at ${created_at}"
continue
Expand Down
134 changes: 134 additions & 0 deletions .github/scripts/bash/e2e/configure-sds-elastic.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,134 @@
#!/usr/bin/env bash

# Copyright 2026 Flant JSC
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

set -Eeuo pipefail

SCRIPT_DIR="$(cd -- "$(dirname -- "${BASH_SOURCE[0]}")" && pwd)"
# shellcheck source=.github/scripts/bash/e2e/wait-sds-elastic.sh
source "${SCRIPT_DIR}/wait-sds-elastic.sh"

ELASTIC_CLUSTER_NAME=elastic
ELASTIC_STORAGE_CLASS=nested-ceph-rbd
# StorageClassMigration needs a second RBD storage class as a migration target.
ELASTIC_STORAGE_CLASSES=(nested-ceph-rbd nested-ceph-rbd-r3)

# sds-elastic (Ceph via Rook) is Experimental, so enable it and its dependencies
# (sds-node-configurator, csi-ceph). On the stage profile the modules are absent in
# the stage registry, so pull them from the deckhouse-prod ModuleSource created by
# enable-sdn.sh; otherwise use the default deckhouse source.
apply_module_configs() {
local source_field=" source: deckhouse"

if [ -n "${MODULE_SOURCE_REGISTRY_CFG:-}" ]; then
source_field=" source: deckhouse-prod"
fi

kubectl apply -f - <<EOF
---
apiVersion: deckhouse.io/v1alpha1
kind: ModuleConfig
metadata:
name: sds-node-configurator
spec:
enabled: true
version: 1
${source_field}
---
apiVersion: deckhouse.io/v1alpha1
kind: ModuleConfig
metadata:
name: csi-ceph
spec:
enabled: true
version: 1
${source_field}
settings:
cephfsEnabled: false
---
apiVersion: deckhouse.io/v1alpha1
kind: ModuleConfig
metadata:
name: sds-elastic
spec:
enabled: true
version: 1
${source_field}
settings:
dataNodes:
nodeSelector:
node-role.deckhouse.io/worker: ""
EOF
}

echo "[INFO] Allow experimental modules (sds-elastic is Experimental)"
kubectl patch mc deckhouse --type=merge \
-p '{"spec":{"settings":{"allowExperimentalModules":true}}}'

d8_queue

if [ -n "${MODULE_SOURCE_REGISTRY_CFG:-}" ]; then
echo "[INFO] Apply sds-elastic ModuleConfigs with deckhouse-prod source (stage profile)"
else
echo "[INFO] Apply sds-elastic ModuleConfigs with deckhouse source"
fi
apply_module_configs

echo "[INFO] Wait for sds-node-configurator to be ready"
kubectl wait --for=jsonpath='{.status.phase}'=Ready modules sds-node-configurator --timeout=300s

echo "[INFO] Wait for csi-ceph to be ready"
kubectl wait --for=jsonpath='{.status.phase}'=Ready modules csi-ceph --timeout=600s

echo "[INFO] Wait for sds-elastic to be ready"
kubectl wait --for=jsonpath='{.status.phase}'=Ready modules sds-elastic --timeout=600s

echo "[INFO] Wait for raw block devices to be discovered"
elastic_blockdevices_ready

echo "[INFO] Label consumable block devices as OSDs (app=elastic-osd)"
for bd in $(kubectl get blockdevices.storage.deckhouse.io -o json | jq -r '.items[] | select(.status.consumable == true) | .metadata.name'); do
echo "[INFO] Label blockdevice ${bd} app=elastic-osd"
kubectl label blockdevice "${bd}" app=elastic-osd --overwrite
done

echo "[INFO] Create ElasticCluster (host networking)"
kubectl apply -f ./elastic-cluster.yaml

echo "[INFO] Wait for ElasticCluster to be ready"
elastic_cluster_ready "${ELASTIC_CLUSTER_NAME}"

echo "[INFO] Create ElasticStorageClasses (RBD: replica-2 default + replica-3 migration target)"
kubectl apply -f ./elastic-storage-class.yaml

for sc in "${ELASTIC_STORAGE_CLASSES[@]}"; do
echo "[INFO] Wait for StorageClass ${sc} to appear"
for i in $(seq 1 30); do
if kubectl get storageclass "${sc}" >/dev/null 2>&1; then
echo "[SUCCESS] StorageClass ${sc} is present"
break
fi
echo "[INFO] Wait 10s for StorageClass ${sc} (attempt ${i}/30)"
sleep 10
done
done

echo "[INFO] Set default cluster storage class to ${ELASTIC_STORAGE_CLASS}"
kubectl patch mc global --type='json' \
-p='[{"op": "replace", "path": "/spec/settings/defaultClusterStorageClass", "value": "'"${ELASTIC_STORAGE_CLASS}"'"}]'

echo "[INFO] Show existing storageclasses and volumesnapshotclasses"
kubectl get storageclass
kubectl get volumesnapshotclass || echo "[WARNING] No volumesnapshotclasses found"
6 changes: 3 additions & 3 deletions .github/scripts/bash/e2e/power-off-nested-vms.sh
Original file line number Diff line number Diff line change
Expand Up @@ -20,9 +20,9 @@ SCRIPT_DIR="$(cd -- "$(dirname -- "${BASH_SOURCE[0]}")" && pwd)"
# shellcheck source=.github/scripts/bash/e2e/common.sh
source "${SCRIPT_DIR}/common.sh"

# Constants (nested cluster: 1 master + 3 workers x2)
REQUIRED_MEM_GI=86
REQUIRED_CPU=26
# Constants ((nested cluster: 1 master + 3 workers) x3: replicated + nfs + sds-elastic)
REQUIRED_MEM_GI=129
REQUIRED_CPU=39
MIN_MEM_GI_PER_NODE=12
MIN_CPU_PER_NODE=4
MIN_NODES_FOR_PLACEMENT=3
Expand Down
13 changes: 13 additions & 0 deletions .github/scripts/bash/e2e/render-dvp-static-values.sh
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,19 @@ envsubst_variables="$(grep -oE '\$\{[A-Z0-9_]+\}' values.yaml.tmpl | sort -u | t
envsubst "${envsubst_variables}" \
< values.yaml.tmpl > values.yaml

# The template defines one additional worker disk. When ADDITIONAL_DISK_COUNT > 1
# (e.g. sds-elastic runs several Ceph OSDs per node), append the extra disks, each
# of ADDITIONAL_DISK_SIZE, to every worker node group.
additional_disk_count="${ADDITIONAL_DISK_COUNT:-1}"
if (( additional_disk_count > 1 )); then
for (( d = 2; d <= additional_disk_count; d++ )); do
# ADDITIONAL_DISK_SIZE is exported by the workflow step env and read by yq's env().
yq eval --inplace \
'(.instances.additionalNodes[] | select(.name == "worker") | .cfg.additionalDisks) += [{"size": env(ADDITIONAL_DISK_SIZE)}]' \
values.yaml
done
fi

mkdir -p tmp
touch tmp/discovered-values.yaml

Expand Down
Loading
Loading