[PATCH 05/13] qemu: install under the controller data path
Daniel Gomez <[email protected]> Fri, 12 Jun 2026 14:36:43 +0200
| Newsgroups | dev.linux.lists.kdevops |
|---|---|
| Message-ID | <[email protected]> |
From: Daniel Gomez <[email protected]> Build QEMU out of tree and install it under a qemu-destdir/ prefix in the controller data path, which the invoking user owns, so the install needs no root and the binary stays out of confined system locations. The fetched tree, the out-of-tree build directory and the destdir now all sit side by side under KDEVOPS_CONTROLLER_DATA_PATH. The libvirt backend is the exception: its QEMU runs under libvirtd's AppArmor and SELinux confinement, which only permits binaries under /usr/local, so libvirt keeps the /usr/local prefix and the sudo install. QEMU_INSTALL_DIR and QEMU_INSTALL_NEEDS_SUDO capture this per-backend, and the install task becomes conditional on the latter. The role default for qemu_install_needs_sudo is a plain false rather than a self-reference, because a false bool is omitted from extra_vars and a self-referential default would recurse; the libvirt backend emits true and overrides it. QEMU_BIN_PATH derives from QEMU_INSTALL_DIR so the configure prefix and the path the qemu role verifies and qsu execs share one source of truth. Generated-by: Claude AI Signed-off-by: Daniel Gomez <[email protected]> --- kconfigs/Kconfig.qemu | 49 ++++++++++++++++++++++++++-------- playbooks/roles/qemu/defaults/main.yml | 9 ++++--- playbooks/roles/qemu/tasks/main.yml | 27 ++++++++++++++----- 3 files changed, 64 insertions(+), 21 deletions(-) diff --git a/kconfigs/Kconfig.qemu b/kconfigs/Kconfig.qemu index b19ef8c0..549b322b 100644 --- a/kconfigs/Kconfig.qemu +++ b/kconfigs/Kconfig.qemu @@ -58,11 +58,12 @@ config QEMU_GIT config QEMU_GIT_DATA_PATH string "The destination directory where to fetch the QEMU git tree" output yaml - default "{{local_dev_path}}/qemu" + default "{{ kdevops_controller_data_path }}/qemu" help This is the target location of where to fetch the above git tree. - Note that {{local_dev_path}} corresponds to the location set by the - configuration option CONFIG_NEEDS_LOCAL_DEVELOPMENT_PATH. + Defaults to a qemu/ directory under KDEVOPS_CONTROLLER_DATA_PATH, + the controller-side data path, alongside the out-of-tree build + directory (qemu-build/) and the install destdir (qemu-destdir/). config QEMU_GIT_VERSION string "The version of QEMU to build" @@ -89,18 +90,44 @@ config QEMU_TARGET QEMU --target-list value derived from the target architecture. Consumed by the qemu role to configure the build. +config QEMU_INSTALL_DIR + string + output yaml + default "/usr/local" if LIBVIRT + default "{{ kdevops_controller_data_path }}/qemu-destdir" + help + The install prefix passed to QEMU's configure (--prefix). The + libvirt backend installs into /usr/local so the system QEMU under + libvirtd's AppArmor/SELinux confinement can execute it. Every other + backend installs into a qemu-destdir/ under the controller data + path, which the invoking user owns, so the install needs no sudo + and the binary stays out of confined system locations. + +config QEMU_INSTALL_NEEDS_SUDO + bool + output yaml + default y if LIBVIRT + default n + help + Whether installing the built QEMU needs root. The /usr/local prefix + used by the libvirt backend does; the per-user qemu-destdir prefix + used by the other backends does not. + endif # QEMU config QEMU_BIN_PATH string output yaml + default "{{ qemu_install_dir }}/bin/qemu-system-x86_64" if QEMU && TARGET_ARCH_X86_64 + default "{{ qemu_install_dir }}/bin/qemu-system-aarch64" if QEMU && TARGET_ARCH_ARM64 + default "{{ qemu_install_dir }}/bin/qemu-system-ppc64" if QEMU && TARGET_ARCH_PPC64LE default QEMU_BIN_PATH_LIBVIRT if LIBVIRT - default "/usr/local/bin/qemu-system-aarch64" if TARGET_ARCH_ARM64 - default "/usr/local/bin/qemu-system-ppc64" if TARGET_ARCH_PPC64LE - default "/usr/local/bin/qemu-system-x86_64" + default "/usr/bin/qemu-system-x86_64" help - Absolute path to the QEMU system emulator binary. The libvirt - backend resolves this from QEMU_BIN_PATH_LIBVIRT. Every other - backend uses the binary installed by the qemu role under its - install prefix. This single source of truth feeds gen_nodes for - the libvirt domain emulator and qsu for the systemd unit ExecStart. + Absolute path to the QEMU system emulator binary. When QEMU=y this + derives from QEMU_INSTALL_DIR so the install prefix and the consumed + binary path share one source of truth; both Jinja2 references + resolve at Ansible-use time, so the qemu role and qsu render a + fully-expanded path. The plain-libvirt case with no QEMU build + resolves it from QEMU_BIN_PATH_LIBVIRT for the gen_nodes domain + emulator. diff --git a/playbooks/roles/qemu/defaults/main.yml b/playbooks/roles/qemu/defaults/main.yml index 806d5375..31671d78 100644 --- a/playbooks/roles/qemu/defaults/main.yml +++ b/playbooks/roles/qemu/defaults/main.yml @@ -1,11 +1,14 @@ # SPDX-License-Identifier: copyleft-next-0.3.1 --- +qemu_install_dir: "{{ qemu_install_dir | default('/usr/local') }}" +qemu_install_needs_sudo: false + # Forces to build and install even if the binary is already present qemu_force_install_if_present: false -qemu_bin_path: "{{ qemu_bin_path | default('/usr/local/bin/qemu-system-x86_64') }}" -qemu_data: "{{ qemu_git_data_path | default(local_dev_path + '/qemu') }}" +qemu_bin_path: "{{ qemu_bin_path | default(qemu_install_dir + '/bin/qemu-system-x86_64') }}" +qemu_data: "{{ qemu_git_data_path | default(kdevops_controller_data_path + '/qemu') }}" qemu_git: "{{ qemu_git | default('https://github.com/qemu/qemu.git') }}" qemu_version: "{{ qemu_git_version | default('v7.2.0-rc4') }}" -qemu_build_dir: "{{ qemu_data }}/build" +qemu_build_dir: "{{ kdevops_controller_data_path }}/qemu-build" qemu_target: "{{ qemu_target | default('x86_64-softmmu') }}" diff --git a/playbooks/roles/qemu/tasks/main.yml b/playbooks/roles/qemu/tasks/main.yml index 005d8637..015c4d15 100644 --- a/playbooks/roles/qemu/tasks/main.yml +++ b/playbooks/roles/qemu/tasks/main.yml @@ -36,9 +36,9 @@ - qemu_force_install_if_present|bool or not qemu_present.stat.exists tags: vars -- name: Ensure the local development path exists +- name: Ensure the controller data path exists ansible.builtin.file: - path: "{{ local_dev_path }}" + path: "{{ kdevops_controller_data_path }}" state: directory mode: "0755" tags: ["qemu", "build-deps"] @@ -63,6 +63,15 @@ when: - qemu_build_now|bool +- name: Create the out-of-tree build directory + ansible.builtin.file: + path: "{{ qemu_build_dir }}" + state: directory + mode: "0755" + tags: ["qemu", "build-deps"] + when: + - qemu_build_now|bool + - name: Pre-fetch QEMU subprojects so configure can disable downloads ansible.builtin.command: "meson subprojects download" changed_when: true @@ -73,11 +82,15 @@ - qemu_build_now|bool - name: Run configure for QEMU - ansible.builtin.command: "./configure --target-list={{ qemu_target }} --disable-download" + ansible.builtin.command: >- + {{ qemu_data }}/configure + --target-list={{ qemu_target }} + --prefix={{ qemu_install_dir }} + --disable-download changed_when: true tags: ["qemu", "configure"] args: - chdir: "{{ qemu_data }}" + chdir: "{{ qemu_build_dir }}" when: - qemu_build_now|bool @@ -91,19 +104,19 @@ - name: Build QEMU community.general.make: - chdir: "{{ qemu_data }}" + chdir: "{{ qemu_build_dir }}" jobs: "{{ qemu_nproc.stdout }}" tags: ["qemu", "build"] when: - qemu_build_now|bool - name: Install QEMU - become: true + become: "{{ qemu_install_needs_sudo | bool }}" become_method: ansible.builtin.sudo ansible.builtin.command: "{{ make }} install" changed_when: true args: - chdir: "{{ qemu_data }}" + chdir: "{{ qemu_build_dir }}" tags: ["qemu", "install"] when: - qemu_build_now|bool -- 2.54.0