Add openSUSE MicroOS support - #13449
Conversation
|
[APPROVALNOTIFIER] This PR is APPROVED This pull-request has been approved by: yankay The full list of commands accepted by this bot can be found here. The pull request process is described here DetailsNeeds approval from an approver in each of these files:
Approvers can indicate their approval by writing |
There was a problem hiding this comment.
🟡 Changes recommended
The implementation and docs currently claim/assume MicroOS transactional package behavior, but the code path still relies on standard zypper-backed package operations (and even skips a documented zypper dependency), which risks breaking bootstrap on MicroOS.
Once you've addressed the issues Copilot identified, you can request another Copilot review.
Pull request overview
Adds initial openSUSE MicroOS awareness across Kubespray (docs, CI, and distro gating) with the intent to support containerd-based clusters on MicroOS.
Changes:
- Adds openSUSE MicroOS to supported distribution lists and enforces
container_manager=containerdon MicroOS. - Introduces a new KubeVirt CI testcase (
opensuse-microos-calico) plus an image-builder entry for an openSUSE MicroOS qcow2. - Updates bootstrap and documentation with MicroOS notes and a post-package reboot hook.
File summaries
| File | Description |
|---|---|
| tests/files/opensuse-microos-calico.yml | Adds a MicroOS Calico CI scenario config and increases package timeout. |
| test-infra/image-builder/roles/kubevirt-images/defaults/main.yml | Adds a MicroOS KubeVirt image definition (filename/url/checksum). |
| roles/kubernetes/preinstall/tasks/0040-verify-settings.yml | Asserts MicroOS only supports containerd as container manager. |
| roles/kubernetes/preinstall/defaults/main.yml | Adds openSUSE MicroOS to supported OS distribution list. |
| roles/container-engine/runc/tasks/main.yml | Skips uninstalling distro-managed runc on MicroOS. |
| roles/container-engine/containerd/defaults/main.yml | Adds openSUSE MicroOS to containerd supported distributions. |
| roles/bootstrap_os/tasks/opensuse.yml | Adjusts gathered facts filter; skips python-xml install on MicroOS. |
| roles/bootstrap_os/tasks/opensuse-microos.yml | Adds MicroOS task entrypoint (imports openSUSE bootstrap). |
| roles/bootstrap_os/tasks/main.yml | Adds a MicroOS reboot after system package changes. |
| README.md | Documents MicroOS as supported for openSUSE (containerd-only) with a docs link. |
| docs/operating_systems/opensuse.md | Adds MicroOS-specific guidance and constraints (containerd-only, reboots). |
| docs/developers/ci.md | Adds “opensuse” row to CI coverage tables (generated from testcase filenames). |
| .gitlab-ci/kubevirt.yml | Adds opensuse-microos-calico to the PR extended KubeVirt matrix. |
| .github/ISSUE_TEMPLATE/bug-report.yaml | Adds MicroOS to the OS dropdown list. |
| .github/advanced-issue-labeler.yml | Adds MicroOS key mapping for auto-labeling issues. |
Review details
- Files reviewed: 15/15 changed files
- Comments generated: 6
- Review effort level: Lite
💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.
| - name: Reboot openSUSE MicroOS after transactional package changes | ||
| ansible.builtin.reboot: {} | ||
| when: | ||
| - ansible_facts['distribution'] == "openSUSE MicroOS" | ||
| - pkgs_task_result is defined | ||
| - pkgs_task_result is changed | ||
| tags: |
| # Required for zypper module | ||
| - name: Install python-xml | ||
| shell: zypper refresh && zypper --non-interactive install python-xml | ||
| changed_when: false | ||
| become: true | ||
| when: ansible_facts['distribution'] != "openSUSE MicroOS" |
| flatcar4081 | :white_check_mark: | :x: | :x: | :x: | :x: | :x: | :x: | | ||
| openeuler24 | :white_check_mark: | :x: | :x: | :x: | :x: | :x: | :x: | | ||
| opensuse | :white_check_mark: | :x: | :x: | :x: | :x: | :x: | :x: | | ||
| rockylinux10 | :white_check_mark: | :white_check_mark: | :x: | :x: | :x: | :x: | :x: | |
| flatcar4081 | :x: | :x: | :x: | :x: | :x: | :x: | :x: | | ||
| openeuler24 | :x: | :x: | :x: | :x: | :x: | :x: | :x: | | ||
| opensuse | :x: | :x: | :x: | :x: | :x: | :x: | :x: | | ||
| rockylinux10 | :x: | :x: | :x: | :x: | :x: | :x: | :x: | |
| flatcar4081 | :x: | :x: | :x: | :x: | :x: | :x: | :x: | | ||
| openeuler24 | :x: | :x: | :x: | :x: | :x: | :x: | :x: | | ||
| opensuse | :x: | :x: | :x: | :x: | :x: | :x: | :x: | | ||
| rockylinux10 | :x: | :x: | :x: | :x: | :x: | :x: | :x: | |
| MicroOS uses a read-only root filesystem and transactional package updates. | ||
| During bootstrap, Kubespray installs required system packages into a new | ||
| snapshot and reboots the node when the package transaction changes the system. | ||
| Ensure nodes can reboot and become reachable through SSH before starting the | ||
| deployment. |
There was a problem hiding this comment.
🔵 Needs a closer look
It introduces a new OS with reboot/bootstrapping and CI image implications that warrant final human validation across real MicroOS environments.
Review details
- Files reviewed: 15/15 changed files
- Comments generated: 0 new
- Review effort level: Lite
There was a problem hiding this comment.
🟡 Changes recommended
Core MicroOS enablement appears incomplete because no transactional/snapshot-aware package installation mechanism is implemented despite MicroOS’s read-only/transactional model and the docs/PR claims.
Once you've addressed the issues Copilot identified, you can request another Copilot review.
Review details
Suppressed comments (1)
docs/operating_systems/opensuse.md:28
- The documentation states that Kubespray installs system packages into a new snapshot and reboots when the package transaction changes the system, but there is no
transactional-update(or other snapshot-aware package install) implementation present in the roles; current package management is via the genericpackagemodule. Either the transactional install mechanism needs to be added, or this section should be adjusted to avoid describing behavior that doesn’t exist.
MicroOS uses a read-only root filesystem and transactional package updates.
During bootstrap, Kubespray installs required system packages into a new
snapshot and reboots the node when the package transaction changes the system.
Ensure nodes can reboot and become reachable through SSH before starting the
deployment.
- Files reviewed: 16/16 changed files
- Comments generated: 3
- Review effort level: Lite
| - name: Normalize openSUSE MicroOS OS family | ||
| set_fact: | ||
| ansible_facts: "{{ ansible_facts | combine({'os_family': 'Suse'}) }}" | ||
| ansible_os_family: Suse | ||
| when: ansible_facts['distribution'] == "openSUSE MicroOS" |
| - name: Reboot openSUSE MicroOS after transactional package changes | ||
| ansible.builtin.reboot: {} | ||
| when: | ||
| - ansible_facts['distribution'] == "openSUSE MicroOS" | ||
| - pkgs_task_result is defined | ||
| - pkgs_task_result is changed | ||
| tags: | ||
| - system-packages | ||
|
|
| opensuse-microos: | ||
| filename: openSUSE-MicroOS.x86_64-16.0.0-ContainerHost-OpenStack-Cloud-Build99.19.qcow2 | ||
| url: https://download.opensuse.org/repositories/devel:/microos:/images/openSUSE_Tumbleweed/openSUSE-MicroOS.x86_64-16.0.0-ContainerHost-OpenStack-Cloud-Build99.19.qcow2 | ||
| checksum: sha256:7192d8a34ac7821a0d2ea0818eb4dd4dff62e0e07b35c6f582e52fc71fd027cf | ||
| converted: true | ||
| tag: "latest" |
There was a problem hiding this comment.
🟡 Changes recommended
The current MicroOS handling in the runc role can still attempt to write a downloaded runc binary into bin_dir, which is likely incompatible with MicroOS’s transactional/read-only filesystem model described in this PR.
Once you've addressed the issues Copilot identified, you can request another Copilot review.
Review details
- Files reviewed: 17/17 changed files
- Comments generated: 1
- Review effort level: Lite
| - ansible_facts['distribution'] != "Flatcar" | ||
| - ansible_facts['distribution'] != "openSUSE MicroOS" | ||
| block: | ||
| - name: Runc | Remove package | ||
| package: |
There was a problem hiding this comment.
🟡 Changes recommended
OS-family fact normalization is inconsistent (updates only one of ansible_os_family vs ansible_facts['os_family'] in different places), which can lead to divergent conditional behavior.
Once you've addressed the issues Copilot identified, you can request another Copilot review.
Review details
- Files reviewed: 17/17 changed files
- Comments generated: 2
- Review effort level: Lite
| - name: Normalize ansible_facts for openSUSE MicroOS | ||
| set_fact: | ||
| ansible_facts: "{{ ansible_facts | combine({'os_family': 'Suse'}) }}" | ||
| when: ansible_facts['distribution'] == "openSUSE MicroOS" | ||
| tags: | ||
| - facts | ||
|
|
| - name: Normalize openSUSE MicroOS legacy OS family fact | ||
| set_fact: | ||
| ansible_os_family: Suse | ||
| when: ansible_facts['distribution'] == "openSUSE MicroOS" | ||
|
|
There was a problem hiding this comment.
🟡 Changes recommended
The current implementation documents transactional updates for MicroOS but still relies on direct zypper/package operations (and skips the “required for zypper” dependency), which is likely to break or behave incorrectly on a transactional/read-only OS.
Once you've addressed the issues Copilot identified, you can request another Copilot review.
Review details
Suppressed comments (1)
roles/bootstrap_os/tasks/opensuse.yml:56
- This task is annotated as “Required for zypper module”, but it is skipped on MicroOS. Since the play still uses zypper/package operations later (system_packages role), MicroOS needs an alternative way to ensure the required Python XML bindings are present (or to avoid the zypper backend entirely via transactional-update). Otherwise package management can break early in the run.
# Required for zypper module
- name: Install python-xml
shell: zypper refresh && zypper --non-interactive install python-xml
changed_when: false
become: true
when: ansible_facts['distribution'] != "openSUSE MicroOS"
- Files reviewed: 17/17 changed files
- Comments generated: 1
- Review effort level: Lite
| - name: Normalize openSUSE MicroOS legacy OS family fact | ||
| set_fact: | ||
| ansible_os_family: Suse | ||
| when: ansible_facts['distribution'] == "openSUSE MicroOS" |
Signed-off-by: Kay Yan <kay.yan@daocloud.io>
Signed-off-by: Kay Yan <kay.yan@daocloud.io>
Signed-off-by: Kay Yan <kay.yan@daocloud.io>
Signed-off-by: Kay Yan <kay.yan@daocloud.io>
Signed-off-by: Kay Yan <kay.yan@daocloud.io>
Signed-off-by: Kay Yan <kay.yan@daocloud.io>
2ac9294 to
7204948
Compare
There was a problem hiding this comment.
🔵 Needs a closer look
MicroOS’ read-only root/transactional model can break existing binary-install paths (e.g., runc/kubelet copies into bin_dir), and the PR needs coordinated handling/documentation to ensure deployments don’t fail.
Review details
Suppressed comments (2)
roles/system_packages/tasks/main.yml:11
- For MicroOS this task only sets
ansible_os_family, but many roles gate behavior onansible_facts['os_family']. Sinceroles/kubernetes/preinstall/tasks/0020-set_facts.ymlnormalizes both, do the same here to avoid inconsistent OS-family detection whensystem_packagesruns outside the preinstall role (or before it).
- name: Normalize openSUSE MicroOS legacy OS family fact
set_fact:
ansible_os_family: Suse
when: ansible_facts['distribution'] == "openSUSE MicroOS"
roles/container-engine/runc/tasks/main.yml:19
- This change prevents uninstalling the distro-provided
runcon MicroOS, but the role still downloads and copies aruncbinary later in the file to{{ runc_bin_dir }}(defaults to{{ bin_dir }}), which is typically under the read-only root on MicroOS. That can still break MicroOS runs unless you either (a) skip the download/copy steps on MicroOS and rely on the packagedrunc, or (b) setbin_dir/runc_bin_dirto a writable location for MicroOS and ensure PATH/systemd units use it.
when:
- not is_ostree
- ansible_facts['distribution'] != "Flatcar Container Linux by Kinvolk"
- ansible_facts['distribution'] != "Flatcar"
- ansible_facts['distribution'] != "openSUSE MicroOS"
- Files reviewed: 17/17 changed files
- Comments generated: 1
- Review effort level: Lite
| MicroOS uses a read-only root filesystem and transactional package updates. | ||
| Packages installed into a new snapshot become available only after a reboot. | ||
| When the bootstrap package transaction changes the system, Kubespray reboots | ||
| one node at a time and waits for it to become reachable before continuing. |
What type of PR is this?
/kind feature
What this PR does / why we need it:
Adds openSUSE MicroOS support for containerd clusters, including transactional
package installation, reboot handling, documentation, and a two-node Calico CI
scenario. Docker and CRI-O are not supported on MicroOS.
Which issue(s) this PR fixes:
Fixes #13446
Special notes for your reviewer:
Validated locally with KVM-backed KubeVirt using single-node and two-node
clusters, including idempotency and unsupported-runtime checks.
This PR was written in part with the assistance of generative AI.
Does this PR introduce a user-facing change?: