Skip to content

Commit b32c277

Browse files
lexfreikvapsclaude
authored
fix(prepare): enable containerd device_ownership_from_security_context for CDI block imports (#48)
* fix(prepare): enable containerd device_ownership_from_security_context for CDI block imports KubeVirt's CDI importer writes VM disk images into raw block volumes from a non-root pod. containerd only chowns the block device to the pod's SecurityContext when device_ownership_from_security_context is enabled on the CRI plugin, and k3s ships it disabled. Without it the importer fails with 'cannot open /dev/cdi-block-volume: Permission denied', the DataVolume hangs in ImportInProgress, and VMs referencing the disk stay Pending. Add a k3s containerd drop-in (config-v3.toml.d/10-cozystack-cri.toml) to all three prepare playbooks, gated behind cozystack_enable_kubevirt and overridable via cozystack_k3s_containerd_dropin_dir. Co-Authored-By: Claude <noreply@anthropic.com> Signed-off-by: Andrei Kvapil <andrei.kvapil@aenix.io> * test(examples): cover containerd device-ownership drop-in across distros Pin the device_ownership_from_security_context drop-in, its KubeVirt gate, the containerd v3 CRI runtime table, and the k3s restart handler across the Ubuntu/RHEL/SUSE prepare playbooks, so the mechanism cannot silently regress or drift between distros. Assisted-By: Claude <noreply@anthropic.com> Signed-off-by: Aleksei Sviridkin <f@lex.la> * chore(release): keep collection version inheritance, defer bump to upstream The collection version tracks the upstream Cozystack chart release; a bugfix on its own does not force a version bump. Keep galaxy.yml at the inherited version and record the change under an Unreleased CHANGELOG section, to be renamed when upstream bumps. Assisted-By: Claude <noreply@anthropic.com> Signed-off-by: Aleksei Sviridkin <f@lex.la> * docs(readme): unwrap hard-wrapped prose into single lines Reflow the remaining hard-wrapped prose paragraphs so each paragraph is one continuous line, letting the renderer wrap to viewer width. Formatting only; tables, code blocks and YAML are left untouched. Assisted-By: Claude <noreply@anthropic.com> Signed-off-by: Aleksei Sviridkin <f@lex.la> * docs(readme): document native --nonroot-devices flag and live-restart caveat Explain why the collection uses a containerd config drop-in rather than k3s's native --nonroot-devices flag (uniform server+agent coverage without wiring agent args, and it applies to an already-running cluster), and warn that the restart handler bounces k3s when the drop-in is first added or changes on a live re-run. Add a doc-drift guard test pinning both points to the drop-in README section. Assisted-By: Claude <noreply@anthropic.com> Signed-off-by: Aleksei Sviridkin <f@lex.la> * docs(claude): list containerd device-ownership in silent-failure traps Add the containerd device_ownership_from_security_context failure (CDI block import Permission denied -> DataVolume ImportInProgress -> VM Pending) to the project's canonical Critical silent-failure traps list, alongside the multipath/vhost_net/br_netfilter entries, with a guard test pinning it. Assisted-By: Claude <noreply@anthropic.com> Signed-off-by: Aleksei Sviridkin <f@lex.la> * docs(readme): correct the containerd 1.x drop-in guidance The drop-in content (version = 3, io.containerd.cri.v1.runtime) is hardcoded for containerd 2.x; cozystack_k3s_containerd_dropin_dir only relocates the file, it does not rewrite the content. State plainly that containerd 1.x is not handled as-is and operators must write their own v2 drop-in, rather than implying a one-variable override that the code cannot honor. Guard the corrected wording with a test. Assisted-By: Claude <noreply@anthropic.com> Signed-off-by: Aleksei Sviridkin <f@lex.la> * docs(readme): list containerd drop-in dir var and update kubevirt toggle scope Add cozystack_k3s_containerd_dropin_dir to the Example playbook variables table (the canonical override reference, where every other examples/* tunable is listed), and extend the cozystack_enable_kubevirt row to note it now also gates the containerd device-ownership drop-in for CDI block imports — so disabling KubeVirt prep is understood to disable that fix too. Also attribute the k3s version pin to the example inventories rather than the role. Guard both table facts with a test. Assisted-By: Claude <noreply@anthropic.com> Signed-off-by: Aleksei Sviridkin <f@lex.la> * fix(prepare): harden containerd CDI drop-in toggle and k3s restart The drop-in toggle was one-way: cozystack_enable_kubevirt: false only skipped writing 10-cozystack-cri.toml, so a host that ran with KubeVirt enabled kept device_ownership_from_security_context on and the host state no longer matched the toggle. Add a symmetric cleanup task that removes the drop-in when the toggle is off and notifies the restart handler, mirroring the existing DRBD drop-in cleanup pattern. The restart handler used failed_when: false, which masked every failure, not just the intended missing-unit case (only one of k3s/k3s-agent exists on a node, and on a full-pipeline run neither exists yet when prepare runs). A malformed drop-in or a k3s that failed to come back was silently reported as success. Refresh service facts on the same notify topic and restart only units present in ansible_facts.services, so a genuine restart failure fails the play while a missing unit is still skipped. Assisted-By: Claude <noreply@anthropic.com> Signed-off-by: Aleksei Sviridkin <f@lex.la> * docs(prepare): correct containerd 1.x drop-in caveat in comments and changelog The playbook comments and the changelog entry still claimed cozystack_k3s_containerd_dropin_dir could target a containerd 1.x cluster, but the drop-in content is hardcoded for containerd 2.x (config version 3, [plugins.'io.containerd.cri.v1.runtime']). Pointing the variable at a 1.x config-dir does not produce a working config: containerd 1.x needs config version 2 and [plugins.'io.containerd.grpc.v1.cri']. The override only relocates the file (e.g. a non-default k3s data-dir); it does not rewrite the content. The README already states this — align the playbook comments, the changelog, and a stale test message with it. Assisted-By: Claude <noreply@anthropic.com> Signed-off-by: Aleksei Sviridkin <f@lex.la> --------- Signed-off-by: Andrei Kvapil <andrei.kvapil@aenix.io> Signed-off-by: Aleksei Sviridkin <f@lex.la> Co-authored-by: Andrei Kvapil <andrei.kvapil@aenix.io> Co-authored-by: Claude <noreply@anthropic.com>
1 parent 752d40b commit b32c277

7 files changed

Lines changed: 622 additions & 47 deletions

File tree

CHANGELOG.rst

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,34 @@ Unreleased
1919
``isp-full-generic`` platform variant when nodes lack a native load
2020
balancer (cloud VMs, bare metal).
2121

22+
Unreleased
23+
==========
24+
25+
Bugfixes
26+
--------
27+
28+
- Prepare playbooks now enable
29+
``device_ownership_from_security_context`` on the containerd CRI
30+
plugin (k3s drop-in
31+
``config-v3.toml.d/10-cozystack-cri.toml``). KubeVirt's CDI importer
32+
writes disk images into raw block volumes as a non-root pod, which
33+
requires containerd to chown the block device to the pod's
34+
SecurityContext; k3s disables this by default. Without it the
35+
importer failed with ``blockdev: cannot open /dev/cdi-block-volume:
36+
Permission denied``, the ``DataVolume`` hung in ``ImportInProgress``,
37+
and VMs referencing the disk stayed ``Pending``. Gated behind
38+
``cozystack_enable_kubevirt``; drop-in directory overridable via
39+
``cozystack_k3s_containerd_dropin_dir`` (relocates the file only — the
40+
content is hardcoded for containerd 2.x / config version 3 as shipped
41+
by current k3s; a containerd 1.x cluster needs a hand-written
42+
``config.toml.d`` drop-in instead).
43+
Setting ``cozystack_enable_kubevirt`` to ``false`` removes a
44+
previously written drop-in so the host state matches the toggle, and
45+
the restart handler only restarts a k3s unit that is actually present
46+
(a genuine restart failure now fails the play instead of being
47+
silently ignored).
48+
49+
2250
v1.4.0
2351
======
2452

CLAUDE.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -144,3 +144,4 @@ The host only needs the kernel modules and, for KVM, a working `/dev/kvm`.
144144
- **`br_netfilter` missing**: `net.bridge.bridge-nf-call-*` sysctls fail
145145
with "No such file or directory". Load the module before applying the
146146
sysctl.
147+
- **containerd `device_ownership_from_security_context` disabled**: k3s ships it off; without the `config-v3.toml.d/10-cozystack-cri.toml` drop-in, KubeVirt's non-root CDI importer cannot open a raw block volume (`blockdev: cannot open /dev/cdi-block-volume: Permission denied`), the DataVolume hangs in `ImportInProgress`, and VMs that reference the disk stay Pending. Apply when KubeVirt is enabled (gated on `cozystack_enable_kubevirt`).

README.md

Lines changed: 32 additions & 47 deletions
Original file line numberDiff line numberDiff line change
@@ -12,9 +12,7 @@ Supported targets:
1212

1313
Cloud-image users **must** set `cozystack_flush_iptables: true` for multi-master k3s to bootstrap — Ubuntu cloud images ship with `REJECT icmp-host-prohibited` in INPUT that blocks etcd peer port 2380 between nodes. See **Node Prerequisites → Known limitations** below.
1414

15-
Deploys the Cozystack operator and Platform Package using the
16-
`kubernetes.core.helm` module with automatic Helm and helm-diff
17-
installation.
15+
Deploys the Cozystack operator and Platform Package using the `kubernetes.core.helm` module with automatic Helm and helm-diff installation.
1816

1917
## Prerequisites
2018

@@ -30,9 +28,7 @@ ansible-galaxy collection install --requirements-file requirements.yml
3028

3129
- SSH access to the target nodes
3230

33-
The role automatically installs Helm and the
34-
[helm-diff](https://github.com/databus23/helm-diff) plugin
35-
on the control-plane node. No manual Helm installation is needed.
31+
The role automatically installs Helm and the [helm-diff](https://github.com/databus23/helm-diff) plugin on the control-plane node. No manual Helm installation is needed.
3632

3733
### Node Prerequisites
3834

@@ -168,11 +164,25 @@ tun
168164
kvm_intel # or kvm_amd depending on the CPU
169165
```
170166

167+
#### Enabled by default: containerd device ownership for CDI block imports
168+
169+
When KubeVirt is enabled, the prepare playbook drops a containerd CRI config that sets `device_ownership_from_security_context = true`. KubeVirt's CDI (Containerized Data Importer) writes VM disk images into raw **block** volumes from a non-root importer pod; containerd only chowns the block device to the pod's `SecurityContext` UID/GID when this option is on, and k3s ships it disabled. Without it the importer fails with `blockdev: cannot open /dev/cdi-block-volume: Permission denied`, the `DataVolume` is stuck in `ImportInProgress`, and every VM that references the disk stays `Pending` — one of the silent "VMs stuck in Pending" failure modes called out above.
170+
171+
Written as a drop-in that containerd merges on top of k3s's generated `config.toml`:
172+
173+
```text
174+
/var/lib/rancher/k3s/agent/etc/containerd/config-v3.toml.d/10-cozystack-cri.toml
175+
```
176+
177+
`config-v3.toml.d` and the `io.containerd.cri.v1.runtime` plugin table are the containerd 2.x (config version 3) paths shipped by current k3s (the example inventories pin `k3s_version: v1.36.1+k3s1`), and the drop-in content is hardcoded for that — `version = 3` and the v3 table. `cozystack_k3s_containerd_dropin_dir` only relocates the file; it does not rewrite the content. So on a containerd 1.x cluster (older k3s) this drop-in does not apply as-is — write your own under `config.toml.d/` with `version = 2` and the `io.containerd.grpc.v1.cri` table. The drop-in is read at first k3s start in the full pipeline; on a re-run against a running cluster a handler restarts k3s so the change takes effect.
178+
179+
k3s also exposes a native `--nonroot-devices` flag (valid on both server and agent) that sets the same containerd option. This collection uses the config drop-in instead because it applies uniformly to every node in the `cluster` group — including agent/worker nodes, for which the example playbooks do not wire `extra_agent_args` — and because it can be applied to an already-running cluster, which an install-time k3s flag cannot.
180+
181+
The restart handler only fires when the drop-in is first created or its content changes; idempotent re-runs leave k3s untouched. When it does fire, `systemctl restart k3s` (or `k3s-agent`) briefly disrupts the control plane and the node's workloads on that host, so apply such a change in a maintenance window rather than casually mid-day.
182+
171183
#### Known limitations
172184

173-
ZFS support depends on the OS ecosystem and kernel flavor. The prepare
174-
playbooks skip ZFS automation gracefully in these cases and emit an
175-
informational notice:
185+
ZFS support depends on the OS ecosystem and kernel flavor. The prepare playbooks skip ZFS automation gracefully in these cases and emit an informational notice:
176186

177187
| OS / kernel | ZFS automation | Reason |
178188
| --- | --- | --- |
@@ -213,9 +223,7 @@ Enable and start:
213223

214224
#### iptables (cloud providers)
215225

216-
Cloud providers (OCI, AWS, GCP) may ship images with restrictive iptables
217-
INPUT rules that block inter-node Kubernetes traffic (API 6443, kubelet 10250,
218-
etcd 2379-2380) even when security groups allow it.
226+
Cloud providers (OCI, AWS, GCP) may ship images with restrictive iptables INPUT rules that block inter-node Kubernetes traffic (API 6443, kubelet 10250, etcd 2379-2380) even when security groups allow it.
219227

220228
Fix: flush the INPUT chain and set policy to ACCEPT before deploying k3s.
221229

@@ -249,11 +257,7 @@ cluster-cidr: 10.42.0.0/16
249257
service-cidr: 10.43.0.0/16
250258
```
251259
252-
These CIDRs are the k3s defaults. The example prepare playbooks
253-
(e.g., `examples/ubuntu/prepare-ubuntu.yml`) set them via the
254-
`server_config_yaml` variable used by `k3s.orchestration`. The role
255-
variables `cozystack_pod_cidr` and `cozystack_svc_cidr` must match —
256-
they default to the same values.
260+
These CIDRs are the k3s defaults. The example prepare playbooks (e.g., `examples/ubuntu/prepare-ubuntu.yml`) set them via the `server_config_yaml` variable used by `k3s.orchestration`. The role variables `cozystack_pod_cidr` and `cozystack_svc_cidr` must match — they default to the same values.
257261

258262
## Installation
259263

@@ -273,8 +277,7 @@ collections:
273277

274278
## Quick start
275279

276-
1. Create your environment (pick your distro — see `examples/ubuntu/`,
277-
`examples/rhel/`, or `examples/suse/`):
280+
1. Create your environment (pick your distro — see `examples/ubuntu/`, `examples/rhel/`, or `examples/suse/`):
278281

279282
```text
280283
my-env/
@@ -314,9 +317,7 @@ Both stages are handled automatically by the `cozystack` role.
314317

315318
## Role: cozystack.installer.cozystack
316319

317-
Installs Cozystack via the official `cozy-installer` Helm chart using
318-
the `kubernetes.core.helm` module with automatic Helm and helm-diff
319-
installation.
320+
Installs Cozystack via the official `cozy-installer` Helm chart using the `kubernetes.core.helm` module with automatic Helm and helm-diff installation.
320321

321322
Runs on `server[0]` only.
322323

@@ -353,14 +354,13 @@ Runs on `server[0]` only.
353354

354355
### Example playbook variables
355356

356-
These variables are consumed only by the example prepare playbooks in
357-
`examples/*/`, not by the role itself. Set them as inventory host/group
358-
vars to opt out of the corresponding prepare step:
357+
These variables are consumed only by the example prepare playbooks in `examples/*/`, not by the role itself. Set them as inventory host/group vars to opt out of the corresponding prepare step:
359358

360359
| Variable | Default | Description |
361360
| --- | --- | --- |
362361
| `cozystack_enable_zfs` | `true` | Example playbooks: install ZFS userspace and load the module. Set `false` to skip. |
363-
| `cozystack_enable_kubevirt` | `true` | Example playbooks: load KubeVirt kernel modules. Set `false` to skip. |
362+
| `cozystack_enable_kubevirt` | `true` | Example playbooks: load KubeVirt kernel modules **and** install the containerd `device_ownership_from_security_context` drop-in for CDI block imports. Set `false` to skip both. |
363+
| `cozystack_k3s_containerd_dropin_dir` | `/var/lib/rancher/k3s/agent/etc/containerd/config-v3.toml.d` | Example playbooks: directory for the containerd CRI drop-in (gated on `cozystack_enable_kubevirt`). Only relocates the file — the drop-in content is hardcoded for containerd 2.x (config v3); a containerd 1.x cluster needs a hand-written `config.toml.d` drop-in instead. |
364364
| `cozystack_flush_iptables` | `false` | Example playbooks: flush the iptables INPUT chain before k3s installs. Set `true` on Ubuntu/Debian cloud images (OCI/AWS/GCP) where the default INPUT chain ends with `REJECT icmp-host-prohibited` and blocks k3s inter-node ports 2380/6443. |
365365
| `cozystack_zfs_release_rpm_extra` | `{}` | `examples/rhel/` only: merged on top of the built-in `cozystack_zfs_release_rpm_by_major` dict, so you can add (or override) a single EL-major → OpenZFS release RPM entry from inventory without wiping the base dict. Example: `{"10": "https://zfsonlinux.org/epel/zfs-release-X-Y.el10.noarch.rpm"}` once upstream ships one. |
366366
| `cozystack_enable_drbd_dkms` | `true` | `examples/ubuntu/` only: install `drbd-dkms` from the LINBIT PPA on Ubuntu LTS 22.04 / 24.04 hosts so DRBD's kernel module is signed via dkms+shim under Secure Boot. Set `false` on Talos hosts (Talos ships pre-signed DRBD modules in extensions) or where Secure Boot is disabled and the in-cluster compile path is preferred. The toggle stops *future* installs but does NOT undo a prior install — manually `apt purge drbd-dkms` and remove the LINBIT entry from `/etc/apt/sources.list.d/` if you flipped to `false` after a successful run. |
@@ -371,8 +371,7 @@ vars to opt out of the corresponding prepare step:
371371

372372
This collection is designed to work alongside [k3s.orchestration](https://github.com/k3s-io/k3s-ansible). The inventory structure (groups: `cluster`, `server`, `agent`) is fully compatible.
373373

374-
Example full pipeline (`site.yml`) — see `examples/ubuntu/`, `examples/rhel/`,
375-
or `examples/suse/`:
374+
Example full pipeline (`site.yml`) — see `examples/ubuntu/`, `examples/rhel/`, or `examples/suse/`:
376375

377376
```yaml
378377
- name: Prepare nodes
@@ -393,12 +392,9 @@ On cloud providers with NAT (OCI, AWS, GCP), nodes have internal IPs different f
393392

394393
### Multi-master setup (kube-ovn RAFT)
395394

396-
Kube-ovn requires `MASTER_NODES` — a comma-separated list of all
397-
control-plane node IPs for OVN RAFT consensus. By default, the role
398-
auto-detects these IPs from the `server` inventory group host keys.
395+
Kube-ovn requires `MASTER_NODES` — a comma-separated list of all control-plane node IPs for OVN RAFT consensus. By default, the role auto-detects these IPs from the `server` inventory group host keys.
399396

400-
This works when host keys are internal IPs (the recommended inventory
401-
pattern):
397+
This works when host keys are internal IPs (the recommended inventory pattern):
402398

403399
```yaml
404400
server:
@@ -409,30 +405,19 @@ server:
409405
ansible_host: 203.0.113.11
410406
```
411407

412-
If your inventory uses hostnames or non-IP host keys, set
413-
`cozystack_master_nodes` explicitly:
408+
If your inventory uses hostnames or non-IP host keys, set `cozystack_master_nodes` explicitly:
414409

415410
```yaml
416411
cozystack_master_nodes: "10.0.0.10,10.0.0.11,10.0.0.12"
417412
```
418413

419414
### Automatic Helm installation
420415

421-
The role installs Helm and the
422-
[helm-diff](https://github.com/databus23/helm-diff) plugin on the
423-
target node automatically. The `helm-diff` plugin enables true
424-
idempotency — repeated runs report no changes when the release is
425-
already up to date.
416+
The role installs Helm and the [helm-diff](https://github.com/databus23/helm-diff) plugin on the target node automatically. The `helm-diff` plugin enables true idempotency — repeated runs report no changes when the release is already up to date.
426417

427418
### Customizing variables
428419

429-
The example prepare playbooks define internal variables (like
430-
`cozystack_k3s_server_args`) in the play `vars` section. User-facing
431-
variables such as `cozystack_k3s_extra_args` and
432-
`cozystack_flush_iptables` should be set **in the inventory**, not in
433-
the playbook. Ansible play `vars` take precedence over inventory
434-
variables, so defining them in both places causes the inventory values
435-
to be silently ignored.
420+
The example prepare playbooks define internal variables (like `cozystack_k3s_server_args`) in the play `vars` section. User-facing variables such as `cozystack_k3s_extra_args` and `cozystack_flush_iptables` should be set **in the inventory**, not in the playbook. Ansible play `vars` take precedence over inventory variables, so defining them in both places causes the inventory values to be silently ignored.
436421

437422
### Idempotency
438423

examples/rhel/prepare-rhel.yml

Lines changed: 75 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -122,6 +122,29 @@
122122
state: restarted
123123
failed_when: false # tolerated: same reason as the enable task below
124124

125+
# Refresh service facts on the same notify topic so the restart
126+
# handler below sees the current unit set. Defined first, so it runs
127+
# first (handlers fire in definition order, not notify order).
128+
- name: Refresh service facts before k3s restart
129+
ansible.builtin.service_facts:
130+
listen: Restart k3s to apply containerd config
131+
132+
- name: Restart k3s to apply containerd config
133+
ansible.builtin.systemd:
134+
name: "{{ item }}"
135+
state: restarted
136+
loop:
137+
- k3s
138+
- k3s-agent
139+
# Restart only the unit that exists on this node: a server runs
140+
# k3s, an agent runs k3s-agent, and on a full-pipeline run neither
141+
# exists yet when prepare runs (the drop-in is read at first k3s
142+
# start instead). service_facts keys systemd units with the
143+
# .service suffix. A unit that IS present but fails to restart
144+
# still fails the play — a malformed drop-in or a k3s that will not
145+
# come back is surfaced, not masked by failed_when: false.
146+
when: (item ~ '.service') in ansible_facts.services
147+
125148
tasks:
126149
- name: Create k3s_cluster group for k3s.orchestration
127150
ansible.builtin.group_by:
@@ -188,6 +211,58 @@
188211
| map(attribute='item')
189212
| list }}
190213
214+
# CDI (Containerized Data Importer) streams VM disk images into raw
215+
# block volumes from a NON-root importer pod. containerd only chowns
216+
# the block device to the pod's SecurityContext UID/GID when
217+
# device_ownership_from_security_context is enabled on the CRI
218+
# plugin, and k3s ships it disabled. Without it the importer dies
219+
# with "blockdev: cannot open /dev/cdi-block-volume: Permission
220+
# denied", the DataVolume hangs in ImportInProgress, and every VM
221+
# that references the disk stays Pending.
222+
#
223+
# The drop-in is merged by containerd on top of k3s's generated
224+
# config.toml via the config-v3.toml.d import glob — read at first
225+
# k3s start (full pipeline) or applied by the handler on re-runs
226+
# against a running cluster. config-v3.toml.d and
227+
# io.containerd.cri.v1.runtime are the containerd 2.x (config
228+
# version 3) paths shipped by current k3s, and the content is
229+
# hardcoded for that schema. cozystack_k3s_containerd_dropin_dir
230+
# only relocates the file (e.g. a non-default k3s data-dir); it does
231+
# not rewrite the content, so a containerd 1.x cluster needs a
232+
# hand-written config.toml.d drop-in (version = 2,
233+
# io.containerd.grpc.v1.cri) instead.
234+
- name: Ensure k3s containerd config drop-in directory exists
235+
ansible.builtin.file:
236+
path: "{{ cozystack_k3s_containerd_dropin_dir | default('/var/lib/rancher/k3s/agent/etc/containerd/config-v3.toml.d') }}"
237+
state: directory
238+
mode: "0755"
239+
when: cozystack_enable_kubevirt | default(true) | bool
240+
241+
- name: Enable device_ownership_from_security_context for CDI block imports
242+
ansible.builtin.copy:
243+
dest: "{{ cozystack_k3s_containerd_dropin_dir | default('/var/lib/rancher/k3s/agent/etc/containerd/config-v3.toml.d') }}/10-cozystack-cri.toml"
244+
mode: "0644"
245+
content: |
246+
version = 3
247+
248+
[plugins.'io.containerd.cri.v1.runtime']
249+
device_ownership_from_security_context = true
250+
when: cozystack_enable_kubevirt | default(true) | bool
251+
notify: Restart k3s to apply containerd config
252+
253+
# Reverse the drop-in when KubeVirt is turned off: a host that
254+
# carried 10-cozystack-cri.toml from an earlier enabled run would
255+
# otherwise keep device_ownership_from_security_context on, so the
256+
# host state no longer matches the toggle. Removal notifies the
257+
# restart handler so a running cluster drops the setting too. (No-op
258+
# when the file was never written — file: absent reports unchanged.)
259+
- name: Remove containerd CDI drop-in when KubeVirt is disabled
260+
ansible.builtin.file:
261+
path: "{{ cozystack_k3s_containerd_dropin_dir | default('/var/lib/rancher/k3s/agent/etc/containerd/config-v3.toml.d') }}/10-cozystack-cri.toml"
262+
state: absent
263+
when: not (cozystack_enable_kubevirt | default(true) | bool)
264+
notify: Restart k3s to apply containerd config
265+
191266
- name: Ensure multipath drop-in directory exists
192267
ansible.builtin.file:
193268
path: /etc/multipath/conf.d

0 commit comments

Comments
 (0)