Compare commits

...

105 Commits
v0.7.1 ... main

Author SHA1 Message Date
ArtiomDivak 85a8640c15
Restructure qmctl (#839)
* Added QMCTL class

This MR I added QMCTL class wich will be responsiable to run all the
command function and return the result. Also added all the imports
needed to all the file

Signed-off-by: Artiom Divak <adivak@redhat.com>

* Adding ArgumentParserWithDefaults and SubcommandInitializer

ArgumentParserWithDefaults class automatically adds default values to the help text of arguments
SubcommandInitializer is a generic class to initialize subparsers for command-line applications

Signed-off-by: Artiom Divak <adivak@redhat.com>

* Added the core of QMCTL

This commits adds the main function the init of the subcommand and the
handle function for the subcommand with other vital function.

Signed-off-by: Artiom Divak <adivak@redhat.com>

---------

Signed-off-by: Artiom Divak <adivak@redhat.com>
Co-authored-by: Douglas Landgraf <dougsland@redhat.com>
2025-07-10 16:31:01 -04:00
Daniel J Walsh 0bea8fa121
Merge pull request #863 from containers/specipc
qm.spec: add validation for file context entries
2025-07-10 07:52:20 -04:00
Yariv Rachmani 6dd6ec4fa4
Merge pull request #862 from aesteve-rh/krun-support
qm.if: allow process setcurrent for qm_t
2025-07-09 10:30:25 +03:00
Douglas Schilling Landgraf 19c6d30934 qm.spec: add validation for file context entries
RHEL < 10 and Fedora < 40 use file context entries in /var/run.

Signed-off-by: Douglas Schilling Landgraf <dougsland@redhat.com>
2025-07-08 14:59:29 -04:00
Albert Esteve d3e4209241 qm.if: allow process setcurrent for qm_t
Update SELinux rules to support krun
runtime to work properly inside QM
container.

Update check_libkrun.sh test accordinly.

Fixes: https://github.com/containers/qm/issues/846
Signed-off-by: Albert Esteve <aesteve@redhat.com>
2025-07-08 15:33:34 +02:00
Ian Mullins c4f1ed9cf0
Improve logging in setup script (#841)
Improve error handling and logging output.
Add more details where qm.service fails to start.

Signed-off-by: Ian Mullins <imullins@redhat.com>
2025-06-30 16:28:37 -04:00
Michael Engel 7d9bc52e5c
Move readmes to readthedoc (#856)
* Moved README content to readthedoc pages

Signed-off-by: Michael Engel <mengel@redhat.com>

* Removed non-existing and unused js reference from mkdocs.yml

Signed-off-by: Michael Engel <mengel@redhat.com>

---------

Signed-off-by: Michael Engel <mengel@redhat.com>
2025-06-30 16:28:20 -04:00
Michael Engel 5c4aa9546d
Merge pull request #853 from containers/doc-ipc
doc: IPC documentation
2025-06-30 12:29:28 +02:00
Douglas Landgraf dcd89dddbe
bump release 0.7.6 (#855)
Signed-off-by: Douglas Schilling Landgraf <dougsland@redhat.com>
2025-06-27 19:18:57 -04:00
Douglas Schilling Landgraf 72e7f5adc8 doc: IPC documentation
Explain communication between ASIL to QM and QM to QM.

Signed-off-by: Douglas Schilling Landgraf <dougsland@redhat.com>
2025-06-27 18:30:29 -04:00
Daniel J Walsh 648f6416ca
Merge pull request #850 from rhatdan/selinux
Add filetrans rule for ipc_var_run_t directory named ipc
2025-06-25 12:56:12 -04:00
Daniel J Walsh 3923c628f1
Add filetrans rule for ipc_var_run_t directory named ipc
Signed-off-by: Daniel J Walsh <dwalsh@redhat.com>
2025-06-24 09:35:36 -04:00
Daniel J Walsh f5c47e2bee
Merge pull request #845 from pengshanyu/libkrun-test-c9s
add QM libkrun test against c9s
2025-06-20 10:39:23 -04:00
pengshanyu 1758aab6a3 add comment
Signed-off-by: pengshanyu <yupengshan@hotmail.com>
2025-06-18 15:29:15 +08:00
pengshanyu 5e98e5826f update tag
Signed-off-by: pengshanyu <yupengshan@hotmail.com>
2025-06-17 15:56:45 +08:00
pengshanyu fb6116c5cf add libkrun c9s test
Signed-off-by: pengshanyu <yupengshan@hotmail.com>
2025-06-17 14:25:16 +08:00
Douglas Landgraf 2e70fe16d3
bump release 0.7.5 (#844)
Signed-off-by: Douglas Schilling Landgraf <dougsland@redhat.com>
2025-06-16 16:51:38 -04:00
Daniel J Walsh 9f2b3fa700
Fix file label specification (#842)
As of latest fedora and RHEL 10 the specifications should be on
/run
not on /var/run.

Signed-off-by: Daniel J Walsh <dwalsh@redhat.com>
2025-06-16 16:21:08 -04:00
ArtiomDivak daec692be0
Qmctl tests (#831)
Closes: https://issues.redhat.com/browse/VROOM-28614

Signed-off-by: Artiom Divak <adivak@redhat.com>
2025-06-04 08:40:28 -03:00
Ian Mullins 647e56c900
Improve subpackage CI/CD rpm build process and error handling (#836)
Add explicit RPM existence checks after builds in subsystem Makefiles to ensure successful subpackage
creation.

Signed-off-by: Ian Mullins <imullins@redhat.com>
2025-06-02 08:12:22 -03:00
pengshanyu 3ab116d733
improve deny_set_scheduler (#833)
Signed-off-by: pengshanyu <yupengshan@hotmail.com>
2025-05-21 08:44:27 -04:00
pengshanyu f4314581b1
improve deny_set_scheduler (#832)
Signed-off-by: pengshanyu <yupengshan@hotmail.com>
2025-05-20 08:49:05 -04:00
Douglas Landgraf 4fbfebc24b
manpage: man page for qmctl (#829)
Signed-off-by: Douglas Schilling Landgraf <dougsland@redhat.com>
2025-05-19 09:10:18 -04:00
Laura Marsh b4b399c927
Adding README updates (#825)
* Adding README updates

Signed-off-by: Laura Marsh <lmarsh@redhat.com>

* fixed typo qm_selinx > qm_selinux

Signed-off-by: Laura Marsh <lmarsh@redhat.com>

---------

Signed-off-by: Laura Marsh <lmarsh@redhat.com>
2025-05-12 17:08:55 -04:00
Douglas Landgraf 10c87d916d
sched_setscheduler to allow other, batch idle (#824)
The current seccomp changes completely disallow
calling sched_setscheduler, but we can safely
allow calling it with policy==SCHED_OTHER/BATCH/IDLE,
as really the only problem is the various real-time classes.

The profile argument is the second (id 1) and the values for
the classes are OTHER=0, BATCH==3, IDLE==5

Resolves: #702
See-Also: https://github.com/containers/qm/pull/818

Signed-off-by: Douglas Schilling Landgraf <dougsland@redhat.com>
2025-05-12 10:57:09 -04:00
Alexander Larsson 2ca6668b12
Merge pull request #797 from engelmi/tighten-bluechi-agent-policy
Restrict access to the mounted socket to bluechi-agent
2025-05-07 11:38:18 +02:00
Michael Engel 4b3d2dfc61
Restrict access to the mounted socket to bluechi-agent
Signed-off-by: Michael Engel <mengel@redhat.com>
2025-05-02 14:53:28 +02:00
Ian Mullins 0f170e8967
Docs: Custom subpackage creation (#821)
Develop documentation on how to create custom subpackages.
Move subpackage section from the main developers guide to experimental.

Signed-off-by: Ian Mullins <imullins@redhat.com>
2025-05-01 14:49:23 -04:00
michalskrivanek 45f3e6e569
a-i-b.sh moved from sample-images to a-i-b (#820)
update where to get the script from

Signed-off-by: Michal Skrivanek <michal.skrivanek@redhat.com>
2025-05-01 14:47:04 -04:00
Ian Mullins 4eba902d46
Fixes for broken subpackages (#822)
- Fix subpackages currently failing to build
- Also address subpackage naming consistency

Signed-off-by: Ian Mullins <imullins@redhat.com>
2025-05-01 14:45:27 -04:00
Ilia Markelov 8b53cea2ae
ttyUSB0 test manual (#819)
Signed-off-by: Ilia Markelov <imarkelo@redhat.com>
2025-04-25 07:49:00 -04:00
ArtiomDivak 018318c844
Add copy feature for qmctl (#809)
Closes https://github.com/containers/qm/issues/803
Signed-off-by: Artiom Divak <adivak@redhat.com>
2025-04-23 19:06:11 -04:00
ArtiomDivak 735a8dc733
Add exicin for qmctl command (#816)
execin wil execute command inside a container in QM

Signed-off-by: Artiom Divak <adivak@redhat.com>
2025-04-21 15:52:06 -04:00
Douglas Landgraf a55521851e
subpackage: ros2 improvements (#814)
* subpackage ros2: add sleep infinity

Keep the container running

Signed-off-by: Douglas Schilling Landgraf <dougsland@redhat.com>

* subpackage ros2: use official fedora robotics img

quay.io/fedora-sig-robotics/ros2:jazzy-cs9

Signed-off-by: Douglas Schilling Landgraf <dougsland@redhat.com>

* subpackage: ROS2 update documentation

Signed-off-by: Douglas Schilling Landgraf <dougsland@redhat.com>

* update docs and makefile with new name

Signed-off-by: Douglas Schilling Landgraf <dougsland@redhat.com>

* Update docs/devel/experimental/SUBPACKAGES.md

Signed-off-by: Douglas Schilling Landgraf <dougsland@redhat.com>

---------

Signed-off-by: Douglas Schilling Landgraf <dougsland@redhat.com>
2025-04-17 10:22:47 -04:00
Albert Esteve bdaec559e3
qm.container: drop sys_boot capability (#811)
A better solution would be to rely on namespaces,
but in the meantime, this helps clearing a
safety concern from assessors.

Signed-off-by: Albert Esteve <aesteve@redhat.com>
2025-04-16 11:43:39 -04:00
Ilia Markelov 8b91f7b631
Added tty7 setup manual, fix for topics ordering (#808)
Signed-off-by: Ilia Markelov <imarkelo@redhat.com>
2025-04-15 10:49:27 -04:00
Ian Mullins 5095f24b49
Revise readthedocs content (#781)
- Minimize RTD content to serve as an appropriate starting point to improve structure.
- Introduce mkdocs-check.yml workflow

Signed-off-by: Ian Mullins <imullins@redhat.com>
2025-04-14 17:05:26 -04:00
Ilia Markelov 279289e581
Added documentation for input subpackage test (#801)
Signed-off-by: Ilia Markelov <imarkelo@redhat.com>
2025-04-14 09:04:11 -04:00
Ilia Markelov 974f65b506
Fix for video subsystem containerfile (#795)
Signed-off-by: Ilia Markelov <imarkelo@redhat.com>
2025-04-10 09:03:38 -04:00
Ilia Markelov 893417b4b6
Fix sub-package Video manual according to containerfile fix (#796)
Signed-off-by: Ilia Markelov <imarkelo@redhat.com>
2025-04-10 08:55:11 -04:00
Ian Mullins a30be64c2c
Fix setup script for older installations of Fedora (#798)
--use-host-config is only applicable to dnf5

Signed-off-by: Ian Mullins <imullins@redhat.com>
2025-04-10 08:47:33 -04:00
Yariv Rachmani 7ca5b38338
Merge pull request #785 from containers/qmtool
qmctl - QM control tool
2025-04-09 05:34:50 +03:00
Douglas Schilling Landgraf 5c1e4202d5 update description in README
Signed-off-by: Douglas Schilling Landgraf <dougsland@redhat.com>
2025-04-08 14:45:56 -04:00
Douglas Schilling Landgraf 13c8a2c88d README: fix markdown warnings
Signed-off-by: Douglas Schilling Landgraf <dougsland@redhat.com>
2025-04-08 12:10:57 -04:00
Douglas Schilling Landgraf 8ee206668c qmctl - QM control tool
Initial commit

Signed-off-by: Douglas Schilling Landgraf <dougsland@redhat.com>
2025-04-08 12:10:28 -04:00
Sandro Bonazzola d96a3f587c
Removing myself from `CODEOWNERS` (#793)
I'm not really owning any code in this repository.

Signed-off-by: Sandro Bonazzola <sbonazzo@redhat.com>
2025-04-08 09:52:05 -04:00
Yariv Rachmani 69ac992063
Merge pull request #790 from containers/winmanager
subpackages: adjust path and remove qm_rootfs
2025-04-07 21:17:43 +03:00
Douglas Landgraf 80f8746fa7
add systemct daemon-reload in to the docs (#791)
podman restart qm was not enough to bring sound
container up.

Signed-off-by: Douglas Schilling Landgraf <dougsland@redhat.com>
2025-04-07 09:55:45 -04:00
Douglas Landgraf f50555cfd7
subpackages: remove dup entry in windowmanager (#792)
Signed-off-by: Douglas Schilling Landgraf <dougsland@redhat.com>
2025-04-07 09:53:31 -04:00
Yariv Rachmani a6e289ffe0
Merge pull request #789 from containers/ros2
subpackage: fix path for ros2
2025-04-07 14:45:52 +03:00
Douglas Schilling Landgraf 122677c853 subpackages: adjust path and remove qm_rootfs
Signed-off-by: Douglas Schilling Landgraf <dougsland@redhat.com>
2025-04-06 16:25:00 -04:00
Douglas Schilling Landgraf 738632738f subpackage: fix path for ros2
- Remove old reference for qm_rootfs
- adjust ros2 for subpackage

Signed-off-by: Douglas Schilling Landgraf <dougsland@redhat.com>
2025-04-06 16:08:58 -04:00
Yariv Rachmani d02de8f746
Merge pull request #787 from ArtiomDivak/issue-771-2
Added AddDevice=/dev/snd
2025-04-06 17:36:49 +03:00
Artiom Divak 49637001c6 Added AddDevice=/dev/snd
This MR is a corection for https://github.com/containers/qm/pull/783

related
closes https://github.com/containers/qm/issues/771
Signed-off-by: Artiom Divak <adivak@redhat.com>
2025-04-06 15:27:35 +03:00
Yariv Rachmani 1fa5ddfb83
Merge pull request #786 from containers/subvideo
subpackage: adjust spec for subpackage video
2025-04-06 09:25:12 +03:00
Douglas Schilling Landgraf eb9016d8b0 subpackage: adjust spec for subpackage video
- adjust spec for subpackage video
- add AddDevice=-/dev/video into the container file

Signed-off-by: Douglas Schilling Landgraf <dougsland@redhat.com>
2025-04-05 16:41:36 -04:00
ArtiomDivak 1280331fbc
Container systemd-audio is not running in QM (#783)
This MR will fix the problem of systemd-audio container not runnig after
qm is up

Closes https://github.com/containers/qm/issues/771
Signed-off-by: Artiom Divak <adivak@redhat.com>
2025-04-03 09:39:02 -04:00
Yariv Rachmani 56f0b0f968
Merge pull request #764 from ArtiomDivak/document-cinf-change
Document change config in qm
2025-04-02 23:48:26 +03:00
Yariv Rachmani e8eb967ccc
Merge pull request #762 from containers/prepare_refactor
Refactoring prepare.sh
2025-04-02 23:47:51 +03:00
Pavol Brilla c91df0bc1e Suggestions added
Signed-off-by: Pavol Brilla <pbrilla@redhat.com>
2025-04-02 16:58:04 +02:00
Pavol Brilla 81d79a4ec7 Fixing last failing test (agent-flood)
agent-flood to use proper image in quadlet
returning -e to shebang of disk test
modules test added debug info message

Signed-off-by: Pavol Brilla <pbrilla@redhat.com>
2025-04-02 12:45:25 +02:00
Pavol Brilla c5da37a8c5
Merge branch 'main' into prepare_refactor 2025-04-02 10:47:46 +02:00
Artiom Divak 9db5cde521 Document change config in qm
Dodument change configuration in QM with drop-in

Signed-off-by: Artiom Divak <adivak@redhat.com>
2025-04-02 10:07:25 +03:00
Yariv Rachmani 3a95050279
Merge pull request #740 from pengshanyu/improve-disk
improve the name of var partition
2025-04-01 22:08:58 +03:00
Pavol Brilla f6cb3efadc Refactoring prepare.sh
- prepare_images:
  - removing all temporary registry location and all related items
- run_container_in_qm:
  - change calling of run_ctr_in_qm
  - if image of tools-ffi:latest is downloaded it will run directly
- clean-up:
  - as we are not doing 'podman commit' image is kept clean
  - removing image clean-up, it should speed up overall times of tests
  - clean-up is in trap (cleaning after test not before test)

Signed-off-by: Pavol Brilla <pbrilla@redhat.com>
2025-04-01 16:11:27 +02:00
pengshanyu 8f990c7f24 remove L75-79
Signed-off-by: pengshanyu <yupengshan@hotmail.com>
2025-04-01 21:54:36 +08:00
pengshanyu 5ba1055155
Merge branch 'containers:main' into improve-disk 2025-04-01 21:47:52 +08:00
Yariv Rachmani 5301363274
Adding fix for create kvm script (#779)
* Adding fix for create kvm script

Fix readme
Fix kvm container in quay
Fix kvm spec file

Signed-off-by: Yariv Rachmani <yrachman@redhat.com>

* Rebase with latest docs changes

I assume that docs/docs/index.md is not relevant

Signed-off-by: Yariv Rachmani <yrachman@redhat.com>

---------

Signed-off-by: Yariv Rachmani <yrachman@redhat.com>
2025-04-01 08:53:02 -04:00
nsednev b7d0eda13d
Added network README.md for network options using quadlets. (#776)
Signed-off-by: nsednev <nsednev@redhat.com>
2025-04-01 08:49:51 -04:00
Yariv Rachmani 27cfd18e54
Merge pull request #777 from iamianmullins/cpu_management
docs/devel: cpu management
2025-03-31 19:55:50 +03:00
Ian Mullins e7b369c43c docs/devel: cpu management
Signed-off-by: Ian Mullins <imullins@redhat.com>
2025-03-31 11:19:38 +01:00
Douglas Landgraf 949029be51
subpackages - move it to devel/docs (#778)
* docs: remove subpackages from main README

Signed-off-by: Douglas Schilling Landgraf <dougsland@redhat.com>

* docs/devel: mention about experimantal subpackages

Signed-off-by: Douglas Schilling Landgraf <dougsland@redhat.com>

* Update docs/devel/experimental/SUBPACKAGES.md

Co-authored-by: sourcery-ai[bot] <58596630+sourcery-ai[bot]@users.noreply.github.com>
Signed-off-by: Douglas Schilling Landgraf <dougsland@redhat.com>

---------

Signed-off-by: Douglas Schilling Landgraf <dougsland@redhat.com>
Co-authored-by: sourcery-ai[bot] <58596630+sourcery-ai[bot]@users.noreply.github.com>
2025-03-28 11:28:19 -04:00
Ian Mullins e6c664db85
devel/README.md: Fix building CentOS and QM Manually documentation (#773)
Minor changes to setup and build command. The command provided currently fails.

Signed-off-by: Ian Mullins <imullins@redhat.com>
2025-03-26 13:33:39 -04:00
Lokesh Mandvekar 10585de109
CODEOWNERS: remove lsm5 (#775)
I am not actively involved in the project.

Signed-off-by: Lokesh Mandvekar <lsm5@fedoraproject.org>
2025-03-25 16:15:22 +05:30
Douglas Landgraf d2c835982b
docs/devel: Show how to create tag/release (#772)
Signed-off-by: Douglas Schilling Landgraf <dougsland@redhat.com>
2025-03-20 11:43:00 -04:00
Douglas Landgraf 6f3bf2add4
README.md: add restorecon command for subpkgs (#768)
Signed-off-by: Douglas Schilling Landgraf <dougsland@redhat.com>
2025-03-19 12:56:32 -04:00
Douglas Landgraf a0ddb2dd81
README.md: update docs regarding subpackages (#767)
* README.md: update docs regarding subpackages

Remove old steps.

Signed-off-by: Douglas Schilling Landgraf <dougsland@redhat.com>

* README.md: fix markdown for command

Signed-off-by: Douglas Schilling Landgraf <dougsland@redhat.com>

---------

Signed-off-by: Douglas Schilling Landgraf <dougsland@redhat.com>
2025-03-19 11:47:08 -04:00
Yariv Rachmani 8ec51ba47e
Merge pull request #754 from engelmi/improve-qm-and-bluechi-test
Use bluechi-is-online to determine if nodes are connected or not
2025-03-19 12:58:23 +02:00
Michael Engel 9d814fc6e7
Added journalctl to agent in QM
Signed-off-by: Michael Engel <mengel@redhat.com>
2025-03-19 09:00:55 +01:00
Michael Engel eb7b9229ea
Add wait time to BlueChi check
Signed-off-by: Michael Engel <mengel@redhat.com>
2025-03-19 09:00:55 +01:00
Michael Engel 20542d7279
Removed redundant bluechi-controller e2e test
Signed-off-by: Michael Engel <mengel@redhat.com>
2025-03-19 09:00:55 +01:00
Michael Engel 9b2f82970e
Use bluechi-is-online to determine if nodes are connected or not
Signed-off-by: Michael Engel <mengel@redhat.com>
2025-03-19 09:00:55 +01:00
Douglas Landgraf 74a169bc9c
bump version for release (#760)
Signed-off-by: Douglas Landgraf <dlandgra@redhat.com>
2025-03-18 16:34:31 -04:00
Ian Mullins f2f13569c0
Initial setup of readthedocs documentation (#757)
Using the existing README file as a placeholder

Signed-off-by: Ian Mullins <imullins@redhat.com>
2025-03-18 11:42:24 -04:00
Yariv Rachmani 7a423be4d4
Added yaml prefix subpackages build (#746)
* Removing img_temp subpackage

Obsolted by #727

Signed-off-by: Yariv Rachmani <yrachman@redhat.com>

* Added yaml prefix

It seems that github actions for subpackage build is not working
Apdating require qm version more loose

Signed-off-by: Yariv Rachmani <yrachman@redhat.com>

* Update docs/devel/README.md

Nothing to add

Signed-off-by: Yariv Rachmani <yrachman@redhat.com>
Co-authored-by: sourcery-ai[bot] <58596630+sourcery-ai[bot]@users.noreply.github.com>

---------

Signed-off-by: Yariv Rachmani <yrachman@redhat.com>
Co-authored-by: sourcery-ai[bot] <58596630+sourcery-ai[bot]@users.noreply.github.com>
2025-03-18 11:11:27 -04:00
Yariv Rachmani 22e22781e4
Merge pull request #751 from containers/cpuweight-idle
Change CPUWeight default to "idle"
2025-03-17 19:22:06 +02:00
Alexander Larsson 3a27c8b4ed Change CPUWeight default to "idle"
This default means that the QM partition only gets CPU if nothing is
wants to run on the rest of the system. Essentially it gets SCHED_IDLE
behaviour.

Signed-off-by: Alexander Larsson <alexl@redhat.com>
2025-03-17 15:39:20 +01:00
Daniel J Walsh 157a7843f0
Merge pull request #750 from nsednev/nsednev-sound
Update NETWORK.md missing documentation.
2025-03-17 09:23:51 -04:00
Daniel J Walsh 2229e960c4
Merge pull request #749 from telemaco/ffi-vfs-safety-fixes
Improve safety in qm virtual filesystems
2025-03-17 09:22:30 -04:00
nsednev b581ff71cc Update NETWORK.md missing documentation.
Signed-off-by: nsednev <nsednev@redhat.com>
2025-03-17 14:53:17 +02:00
Roberto Majadas cb6bb2cdf3 Improve safety in qm virtual filesystems
- Removed `Unmask=ALL` from the qm.container file to enhance safety for
qm virtual filesystems.
- Set `netns="host"` as the default configuration in the
`containers.conf`.

A bit background on this. To guarantee FFI we can't have all the
sensitive pseudo-filesystems like /proc/sys and /sys fully available
inside QM. However, unfortunately currently this is needed for podman to
set up the network bridge when doing --network=private. It fails setting
some network sysctl options. For now we hack-fix this by making
non-private network default, because FFI is more important than podman
features.

However, we think long term this is fixable by granting setting some
sysctls by default in the qm container and possibly granting specific
access to safe sysctls. we did some initial work on this and got part of
the way there, but we don't have a full solution yet.

Signed-off-by: Roberto Majadas <rmajadas@redhat.com>
2025-03-17 11:14:52 +01:00
Yariv Rachmani 11aef5ccaa
Merge pull request #748 from containers/qm-cpuweight
Fix suport for CPUWeight

Remove QM.slice, run the qm service under -.slice, 
to verify QM service weights cgroups calculated based to the whole root cgroups
2025-03-17 11:26:38 +02:00
Alexander Larsson 558cc12c15 Remove references to QM.slice from docs/demos
Signed-off-by: Alexander Larsson <alexl@redhat.com>
2025-03-17 10:00:18 +01:00
Alexander Larsson 7be55d6ffa Fix suport for CPUWeight
In the current setup, qm.service is part of the QM.slice. This means
that the CPUWeight of qm.service is only applied against the other
groups of QM.slice, i.e. none. This means CPUWeight does nothing.

Here change the parent of qm.service to be -.service (the root
cgroup), which means that the weight of it will be compared to the
other toplevel slices, which normally is user.slice and system.slice.

So, with the current default CPUWeight in qm.container of 50, and the
default weight of 100, this means that qm.service now will get half
the cpu of the processes in system.slice, which is the intent.

I tried this by running "openssl speed --seconds 99999" both inside qm
and outside it one a one-cpu VM, and before both processes always got
50% cpu, but now they are split up according to CPUWeight in the
qm.container.

Signed-off-by: Alexander Larsson <alexl@redhat.com>
2025-03-14 17:47:12 +01:00
pengshanyu 6558b5b63a improve the name of var partition
Signed-off-by: pengshanyu <yupengshan@hotmail.com>

improve oom.conf;improve variable names

improve PodmanArgs
2025-03-06 14:11:15 +08:00
Yariv Rachmani 59bc58b38e
Merge pull request #745 from Yarboa/packit_release
Updating release build for c10s
2025-03-06 00:12:05 +02:00
Yariv Rachmani 21c9895b25 Updating release build for c10s
Signed-off-by: Yariv Rachmani <yrachman@redhat.com>
2025-03-05 22:55:17 +02:00
Douglas Landgraf d4a5732ebd
bump to v0.7.3 (#744)w
Signed-off-by: Douglas Landgraf <dlandgra@redhat.com>
2025-03-05 15:32:07 -05:00
Yariv Rachmani c74db387c2
Merge pull request #743 from containers/fix-network-subnet
containers.conf: Set a different default ip subnet for qm containers
2025-03-05 21:13:53 +02:00
Alexander Larsson 38374ff2c7 containers.conf: Set a different default ip subnet for qm containers
Otherwise both host and qm containers have the same range and things get
confused.

Signed-off-by: Alexander Larsson <alexl@redhat.com>
2025-03-05 16:52:23 +01:00
Yariv Rachmani 6e15f6cba5
Merge pull request #742 from containers/fix-qm-selinux-mmap-dev-zero
Selinux: Allow qm_t to mmap qm_file_t char devices
2025-03-04 12:26:57 +02:00
Alexander Larsson 05cfa40e7e Selinux: Allow qm_t to mmap qm_file_t char devices
This allows qm apps to mmap /dev/zero which is a common operation, and
should be safe.

Fixes: https://github.com/containers/qm/issues/741
Signed-off-by: Alexander Larsson <alexl@redhat.com>
2025-03-04 09:12:17 +01:00
Douglas Landgraf c95f521942
update VERSION to 0.7.2 (#738)
Signed-off-by: Douglas Schilling Landgraf <dougsland@redhat.com>
2025-02-28 16:27:52 -05:00
Douglas Landgraf 950f07d91b
spec: in case host don't have ip_tables proceed (#737)
Resolves: https://github.com/containers/qm/issues/736

Signed-off-by: Douglas Schilling Landgraf <dougsland@redhat.com>
2025-02-28 14:53:19 -05:00
Yariv Rachmani a09ba109d9
Fix merge errors (#735)
resolve #677

There is misssing target for epel-10
There is missing dependency bluechi-selinux exist in epel and not c10s

Signed-off-by: Yariv Rachmani <yrachman@redhat.com>
2025-02-27 16:23:20 -05:00
108 changed files with 3254 additions and 1334 deletions

2
.github/CODEOWNERS vendored
View File

@ -2,4 +2,4 @@
# https://docs.github.com/en/repositories/managing-your-repositorys-settings-and-features/customizing-your-repository/about-code-owners
# Default to all maintainers if nothing more specific matches
* @rhatdan @lsm5 @dougsland @yarboa @sandrobonazzola @nsednev @aesteve-rh @pengshanyu @kleinffm
* @rhatdan @dougsland @yarboa @nsednev @aesteve-rh @pengshanyu @kleinffm

View File

@ -1,29 +0,0 @@
name: Build Subpackages
on:
pull_request
jobs:
build-subpackages:
runs-on: ubuntu-latest
steps:
- name: Checkout repository
uses: actions/checkout@v4
- name: Install dependencies
run: sudo apt-get update && sudo apt-get install -y make
- name: Run make for each subsystem
run: |
for dir in subsystems/*; do
if [ -d "$dir" ]; then
subsystem=$(basename "$dir")
echo "Running make for $subsystem..."
make TARGETS=$subsystem subpackages
if [ $? -ne 0 ]; then
echo "❌ Make failed for $subsystem" >&2
exit 1
fi
fi
done

42
.github/workflows/check-subpackages.yml vendored Normal file
View File

@ -0,0 +1,42 @@
name: Build Subpackages
on:
pull_request
jobs:
build-subpackages:
runs-on: ubuntu-latest
container:
image: fedora:latest # Use Fedora as the container image
steps:
- name: Checkout repository
uses: actions/checkout@v4
- name: Install dependencies
run: sudo dnf install -y git make rpmdevtools rpmbuild
- name: Run make for each subsystem
run: |
subsystem_build_failures=()
for dir in subsystems/*; do
if [ -d "$dir" ]; then
subsystem=$(basename "$dir")
echo "Running make for $subsystem..."
make TARGETS=$subsystem subpackages
if [ $? -ne 0 ]; then
subsystem_build_failures+=("$subsystem")
echo "❌ Make failed for $subsystem" >&2
fi
fi
done
if (( ${#subsystem_build_failures[@]} == 0 )); then
echo "✅ All subsystems built successfully"; \
exit 0;
else
echo "❌ The following subsystems failed to build: ";
echo -e "\t${subsystem_build_failures[@]}" | tr ' ' ', ';
exit 1;
fi

30
.github/workflows/mkdocs-check.yml vendored Normal file
View File

@ -0,0 +1,30 @@
name: MkDocs Build Check
on:
pull_request:
paths:
- 'docs/**'
- '**.md'
jobs:
mkdocs-build:
runs-on: ubuntu-latest
steps:
- name: Checkout repository
uses: actions/checkout@v3
- name: Set up Python
uses: actions/setup-python@v4
with:
python-version: '3.x'
- name: Install MkDocs and dependencies
run: |
pip install \
mkdocs \
mkdocs-material \
pymdown-extensions
- name: Build MkDocs site
run: mkdocs build -f docs/mkdocs.yml --strict

1
.gitignore vendored
View File

@ -6,3 +6,4 @@ qm.pp.bz2
qm_file_contexts
*.8
tests/e2e/ContainerFile.template
__pycache__/

View File

@ -45,6 +45,9 @@ jobs:
- epel-9-aarch64
- epel-9-ppc64le
- epel-9-x86_64
- epel-10-aarch64
- epel-10-ppc64le
- epel-10-x86_64
- job: tests
trigger: pull_request
@ -135,12 +138,14 @@ jobs:
dist_git_branches:
- fedora-all
- epel-9
- epel-10
- job: koji_build
trigger: commit
dist_git_branches:
- fedora-all
- epel-9
- epel-10
- job: bodhi_update
trigger: commit
@ -148,3 +153,4 @@ jobs:
# rawhide updates are created automatically
- fedora-branched
- epel-9
- epel-10

20
.readthedocs.yaml Normal file
View File

@ -0,0 +1,20 @@
# .readthedocs.yaml
# Read the Docs configuration file
# See https://docs.readthedocs.io/en/stable/config-file/v2.html for details
# Required
version: 2
# Set the version of Python and other tools you might need
build:
os: ubuntu-22.04
tools:
python: "3.11"
mkdocs:
configuration: docs/mkdocs.yml
# Optionally declare the Python requirements required to build your docs
python:
install:
- requirements: docs/requirements.txt

653
README.md
View File

@ -1,74 +1,58 @@
# Topics
1. [QM is a containerized environment for running Functional Safety QM (Quality Management) software](#qm-is-a-containerized-environment-for-running-functional-safety-qm-quality-management-software)
2. [SELinux Policy](#selinux-policy)
3. [BlueChi](#bluechi)
4. [RPM Building Dependencies](#rpm-building-dependencies)
5. [How the OOM Score Adjustment is Used in QM](#how-the-oom-score-adjustment-is-used-in-qm)
- [Why Use oom score adj in QM?](#why-use-oomscoreadj-in-qm)
- [OOM Score Adjustment in QM](#oom-score-adjustment-in-qm)
- [Nested Containers](#nested-containers)
- [QM Process](#qm-process)
- [ASIL Applications](#asil-applications)
- [Highlights](#highlights)
- [ASCII Diagram](#ascii-diagram)
6. [QM Sub-Packages](#qm-sub-packages)
- [Key Features of QM Sub-Packages](#key-features-of-qm-sub-packages)
- [Building QM Sub-Packages](#building-qm-sub-packages)
- [Installing QM Sub-Packages](#installing-qm-sub-packages)
- [Removing QM Sub-Packages](#removing-qm-sub-packages)
- [Creating Your Own Drop-In QM Sub-Package](#creating-your-own-drop-in-qm-sub-package)
- [QM Sub-Package ROS2](#qm-sub-package-ros2)
- [QM Sub-Package KVM](#qm-sub-package-kvm)
- [QM Sub-Package Sound](#qm-sub-package-sound)
- [QM Sub-Package Video](#qm-sub-package-video)
7. [Examples](#examples)
8. [Development](#development)
9. [Network Settings](https://github.com/containers/qm/blob/main/docs/tutorials/NETWORK.md)
10. [Realtime](#realtime)
11. [Talks and Videos](#talks-and-videos)
- [Paving the Way for Uninterrupted Car Operations - DevConf Boston 2024](https://www.youtube.com/watch?v=jTrLqpw7E6Q)
- [Security - Sample Risk Analysis according to ISO26262](https://www.youtube.com/watch?v=jTrLqpw7E6Q&t=1268s)
- [ASIL and QM - Simulation and Service Monitoring using bluechi and podman](https://www.youtube.com/watch?v=jTrLqpw7E6Q&t=1680s)
- [Containers in a Car - DevConf.CZ 2023](https://www.youtube.com/watch?v=FPxka5uDA_4)
12. [RPM Mirrors](#rpm-mirrors)
- [Topics](#topics)
- [QM is a containerized environment for running functional safety Quality Management software](#qm-is-a-containerized-environment-for-running-functional-safety-quality-management-software)
- [QM SELinux policy](#qm-selinux-policy)
- [BlueChi](#bluechi)
- [RPM building dependencies](#rpm-building-dependencies)
- [How OOM score adjustment is used in QM](#how-oom-score-adjustment-is-used-in-qm)
- [Priority process of OOM killer in the QM context](#priority-process-of-oom-killer-in-the-qm-context)
- [Contributing to the QM project](#contributing-to-the-qm-project)
- [Realtime](#realtime)
- [Talks and videos](#talks-and-videos)
- [RPM mirrors](#rpm-mirrors)
- [Configuring QM](#configuring-qm)
- [Modifying the `MemoryHigh` variable](#modifying-the-memoryhigh-variable)
## QM is a containerized environment for running Functional Safety QM (Quality Management) software
## QM is a containerized environment for running functional safety Quality Management software
The main purpose of this package is allow users to setup an environment which
prevents applications and container tools from interfering with other processes
on the system. For example ASIL (Automotive Safety Integrity Level) environments.
The main purpose of the Quality Management (QM) environment is to allow users to configure
an environment that prevents applications and container tools from interfering with
other processes on the system, such as in Automotive Safety Integrity Level (ASIL)
processes and applications. AutoSD is not a certified safety product. In the context of
AutoSD, QM is not for use in production environments but for research and learning purposes only.
The QM environment uses containerization tools like cgroups, namespaces, and
security isolation to prevent accidental interference by processes in the qm.
The QM environment uses containerization tools, such as cgroups, namespaces, and
security isolation, to prevent accidental interference by processes in the QM.
The QM will run its own version of systemd and Podman to isolate not only the
applications and containers launched by systemd and Podman but systemd and
The QM runs its own version of systemd and Podman to isolate not only the
applications and containers launched by systemd and Podman, but also systemd and
Podman commands themselves.
This package requires the Podman package to establish the containerized
environment and uses quadlet to set it up.
environment and uses Quadlet to set it up. Refer to the [docs directory](docs/quadlet-examples/)
for example Quadlet files.
Software install into the qm environment under /usr/lib/qm/rootfs will
be automatically isolated from the host. But if developers want to further
isolate these processes from other processes in the QM they can use container
tools like Podman to further isolate.
Software installed in the QM environment under `/usr/lib/qm/rootfs` is
automatically isolated from the host. To further isolate these processes
from other processes in the QM, developers can use container tools, such as Podman.
## SELinux Policy
## QM SELinux policy
This policy is used to isolate Quality Management parts of the operating system
from the other Domain-Specific Functional Safety Levels (ASIL).
The QM SELinux policy isolates QM parts of the operating system
from the other domain-specific functional safety levels, such as ASIL.
The main purpose of this policy is to prevent applications and container tools
with interfering with other processes on the system. The QM needs to support
further isolate containers run within the qm from the qm_t process and from
each other.
The main purpose of this policy is to prevent applications and container
tools from interfering with other processes on the system. The QM must
isolate containers from `qm_t` processes as well as from other containers.
For now all of the control processes in the qm other then containers will run
with the same qm_t type.
For now, all of the control processes in the QM other than containers run
with the same `qm_t` type. For more information, refer to `man qm_selinux`.
Still would like to discuss about a specific selinux prevision?
Please open an [QM issue](https://github.com/containers/qm/issues) with the output of selinux error from a recent operation related to QM. The output of the following commands are appreciated for understanding the root cause.
For support with a specific SELinux issue, open a [QM issue](https://github.com/containers/qm/issues)
and include the SELinux error output from a recent QM-related operation.
The following commands yield output that can help determine the root cause of the issue:
```console
ausearch -m avc -ts recent | audit2why
@ -76,444 +60,66 @@ journalctl -t setroubleshoot
sealert -a /var/log/audit/audit.log
```
## Bluechi
## BlueChi
- [BlueChi](https://github.com/containers/qm/pull/57)
The package configures the bluechi agent within the QM.
The package configures the bluechi-agent within the QM.
BlueChi is a systemd service controller intended for multi-node environments with
a predefined number of nodes and with a focus on highly regulated ecosystems such
as those requiring functional safety. Potential use cases can be found in domains
such as transportation, where services need to be controlled across different
edge devices and where traditional orchestration tools are not compliant with
BlueChi is a systemd service controller intended for use in highly regulated
ecosystems that feature multi-node environments with a predefined number of nodes.
Potential use cases can be found in industries that require functional safety,
such as the transportation industry in which services must be controlled across different
edge devices and where traditional orchestration tools do not comply with
regulatory requirements.
Systems with QM installed will have two systemd's running on them. The QM bluechi-agent
is based on the hosts /etc/bluechi/agent.conf file. By default any changes to the
systems agent.conf file are reflected into the QM /etc/bluechi/agent.conf. You can
further customize the QM bluechi agent by adding content to the
/usr/lib/qm/rootfs/etc/bluechi/agent.conf.d/ directory.
Systems with QM installed have two systemd processes running on them. The QM
bluechi-agent is based on the hosts `/etc/bluechi/agent.conf` file. By default, any
changes to the system's `agent.conf` file are reflected in the QM `/etc/bluechi/agent.conf` file.
You can further customize the QM bluechi-agent by adding content to the
`/usr/lib/qm/rootfs/etc/bluechi/agent.conf.d/` directory.
```console
# dnf install -y python3-dnf-plugins-core
# dnf config-manager --set-enabled crb
```
## QM Sub-packages
The qm project is designed to provide a flexible and modular environment for managing
Quality Management (QM) software in containerized environments. One of the key features
of the qm package is its support for sub-package(s), such as the qm-dropin sub-packages.
These sub-packages are not enabled by default and are optional. However, allow users
to easily extend or customize their QM environment by adding specific configurations,
tools, or scripts to the containerized QM ecosystem by simple installing or uninstalling
a RPM package into the system.
## Key Features of QM Sub-Packages
### Modularity
- No configuration change, no typo or distribution rebuild/update.
- Just dnf install/remove from the tradicional rpm schema.
### Customizability
- Users can easily add specific configurations to enhance or modify the behavior of their QM containers.
### Maintainability
- Sub-packages ensure that the base qm package remains untouched, allowing easy updates without breaking custom configurations.
### Simplicity
- Like qm-dropin provide a clear directory structure and templates to guide users in customizing their QM environment.
## Building QM sub-packages
Choose one of the following sub-packages and build using make.
```bash
git clone git@github.com:containers/qm.git && cd qm
make| grep subpackage
kvm_subpackage - Creates a local RPM package, useful for development
ros2_rolling_subpackage - Creates a local RPM package, useful for development
sound_subpackage - Creates a local RPM package, useful for development
video_subpackage - Creates a local RPM package, useful for development
tty7_subpackage - Creates a local RPM package, useful for development
input_subpackage - Creates a local RPM package, useful for development
ttyUSB0_subpackage - Creates a local RPM package, useful for development
img_tempdir_subpackage - Creates a local RPM package, useful for development
windowmanager_subpackage - Creates a local RPM package, useful for development
douglas@fedora:~/qm-multiplespecs/qm$
make TARGETS=input subpackages
ls rpmbuild/RPMS/noarch/
qm-0.6.7-1.fc40.noarch.rpm qm_mount_bind_input-0.6.7-1.fc40.noarch.rpm
```
## Installing QM sub-packages
```bash
$ sudo dnf install ./rpmbuild/RPMS/noarch/qm_mount_bind_input-0.6.7-1.fc40.noarch.rpm
<SNIP>
Complete!
```
If QM is already running, restart or reload your QM container environment to apply the new configurations.
```bash
sudo podman restart qm
```
## Removing QM sub-packages
```bash
sudo rpm -e qm_mount_bind_input
```
## QM sub-package Video
The video sub-package exposes `/dev/video0` (or many video devices required) to the container. This feature is useful for demonstrating how to share a camera from the host system into a container using Podman drop-in. To showcase this functionality, we provide the following demo:
### Building the video sub-package, installing, and restarting QM
```bash
make TARGETS=video subpackages
sudo podman restart qm
sudo dnf install ./rpmbuild/RPMS/noarch/qm_mount_bind_video-0.6.7-1.fc40.noarch.rpm
```
This simulates a rear camera when the user shifts into reverse gear.
In this simulation, we created a systemd service that, every time it is started, captures a snapshot from the webcam, simulating the action of a rear camera. (Feel free to start and restart the service multiple times!)
```bash
host> sudo podman exec -it qm bash
bash-5.2# systemctl daemon-reload
bash-5.2# systemctl start rear-camera
# ls -la /tmp/screenshot.jpg
-rw-r--r--. 1 root root 516687 Oct 13 04:05 /tmp/screenshot.jpg
bash-5.2#
```
### Copy the screenshot to the host and view it
```bash
host> sudo podman cp qm:/tmp/screenshot.jpg .
```
Great job! Now imagine all the possibilities this opens up!
## QM sub-package Sound
### Step 1: Install the QM Mount Bind Sound Package
To set up sound cards in a QM environment using Podman, follow the steps below:
Run the following commands to install the `qm_mount_bind_sound` package and restart QM (if previously in use):
```bash
# Build and install the RPM for QM sound
git clone https://github.com/containers/qm.git && cd qm
make TARGETS=sound subpackages
sudo dnf install -y rpmbuild/RPMS/noarch/qm_mount_bind_sound-0.6.7-1.fc40.noarch.rpm
# Restart QM container (if already running)
sudo podman restart qm
### Step 2: Identify Sound Cards
After installing the drop-in and restarting QM, you need to identify which sound card in the Linux system will be used in QM. If you're familiar with your sound card setup feel free to skip this step.
To list the sound cards available on your system (in our case, we will pick the number 1):
```bash
cat /proc/asound/cards
```
**Example Output**:
```bash
0 [NVidia ]: HDA-Intel - HDA NVidia
HDA NVidia at 0x9e000000 irq 17
1 [sofhdadsp ]: sof-hda-dsp - sof-hda-dsp
LENOVO-20Y5000QUS-ThinkPadX1ExtremeGen4i
2 [USB ]: USB-Audio - USB Audio Device
Generic USB Audio at usb-0000:00:14.0-5, full speed
```
### Detecting Channels and Sample Rates
To list the supported number of channels and samples use `pactl` command:
```bash
pactl list sinks | grep -i 48000 | uniq
Sample Specification: s24-32le 2ch 48000Hz
```
### Verify Sample Rate Support
To show the supported sample rates for a specific sound card codec, you can also inspect the codec details:
```bash
cat /proc/asound/card1/codec#0 | grep -i rates
```
This will output the supported sample rates for the codec associated with `card1`.
### Differentiating Between Cards
Accessing Card 1 (sof-hda-dsp)
```bash
cat /proc/asound/cards | grep -A 1 '^ 1 '
```
Accessing Card 2 (USB Audio Device)
```bash
cat /proc/asound/cards | grep -A 1 '^ 2 '
```
### Step 3: Testing audio inside QM
Inside QM, run the following command:
```bash
podman exec -it qm bash
bash-# podman ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
76dacaa9a89e quay.io/qm-images/audio:latest sleep infinity 7 hours ago Up 7 hours systemd-audio
bash-# podman exec -it systemd-audio bash
Execute the audio test within the nested container, and the sound will be output through the physical speakers of your computer—or, in this case, the car's multimedia soundbox.
bash-# speaker-test -D hw:1,0 -c 2 -r 48000
```
Params:
```bash
hw:1,0: sound card 1, device 0
-c 2: two channels (stereo)
-r 48000: sample rate of 48 kHz
```
## Creating your own drop-in QM sub-package
We recommend using the existing drop-in files as a guide and adapting them to your specific needs. However, here are the step-by-step instructions:
1) Create a drop-in file in the directory: `etc/qm/containers/containers.conf.d`
2) Add it as a sub-package to `rpm/qm.spec`
3) Test it by running: `make clean && VERSION=YOURVERSIONHERE make rpm`
4) Additionally, test it with and without enabling the sub-package using (by default it should be disabled but there are cases where it will be enabled by default if QM community decide):
Example changing the spec and triggering the build via make (feel free to automate via sed, awk etc):
```bash
# Define the feature flag: 1 to enable, 0 to disable
# By default it's disabled: 0
%define enable_qm_dropin_img_tempdir 1
make clean && VERSION=YOURVERSIONHERE make rpm
```
## QM sub-package ROS2
The QM sub-package ROS2 (a.k.a "The Robot Operating System" or middleware for robots) is widely used by open-source projects, enterprises, companies, edge env and government agencies, including NASA, to advance robotics and autonomous systems. Enabled by Quadlet in QM, ROS2 on top of QM provides a secure environment where robots can operate and communicate safely, benefiting from QM's "Freedom from Interference" frequently tested layer. This ensures robots can function without external interference, enhancing their reliability and security.
The types of robots compatible with this environment are extensive, ranging from medical devices and aerial drones to aqua drones and space rockets. ROS2 within QM supports high availability, meaning these robotic systems can maintain continuous operations, crucial for mission-critical and industrial applications. This versatility makes it ideal for environments that demand robust communication and operational safety, from healthcare and aerospace to underwater exploration and autonomous land vehicles.
How to test this env?
```bash
git clone https://github.com/containers/qm.git && cd qm
make TARGETS=ros2_rolling subpackages
sudo dnf install rpmbuild/RPMS/noarch/qm_ros2_rolling-0.6.7-1.fc40.noarch.rpm -y
sudo podman restart qm # if you have qm already running
Testing using talked and listener examples
$host> sudo podman exec -it qm bash
QM> ros2 run demo_nodes_cpp talker &
QM> ros2 run demo_nodes_cpp listener
```
## QM sub-package KVM
The QM sub-package KVM includes drop-in configuration that enables the integration of Kernel-based Virtual Machine (KVM) management into the QM (Quality Management) container environment. This configuration allows users to easily configure and manage KVM virtual machines within the QM system, streamlining virtualization tasks in containerized setups.
Below example step by step:
Step 1: clone QM repo, install libvirt packages, prepare some files inside QM and start the libvirt daemon.
```bash
git clone https://github.com/containers/qm.git && cd qm
make TARGETS=kvm subpackages
sudo dnf install rpmbuild/RPMS/noarch/qm_mount_bind_kvm-0.6.7-1.fc40.noarch.rpm
sudo podman restart qm # if you have qm already running
sudo dnf --installroot /usr/lib/qm/rootfs/ install virt-install libvirt-daemon libvirt-daemon-qemu libvirt-daemon-kvm -y
# Copy default network settings to /root dir inside QM (/usr/lib/qm/rootfs/root)
$host> sudo cp /usr/share/libvirt/networks/default.xml /usr/lib/qm/rootfs/root
Step 2: Preparing cloudinit files inside QM (/usr/lib/qm/rootfs/root)
# Cloud-init files
------------------------------
$host> cd /usr/lib/qm/rootfs/root/
$host> cat meta-data
instance-id: fedora-cloud
local-hostname: fedora-vm
# We are setting to user fedora the default password as fedora
$host> cd /usr/lib/qm/rootfs/root/
$host> cat user-data
#cloud-config
password: fedora
chpasswd: { expire: False }
ssh_pwauth: True
# Download the Fedora Cloud image for tests and save it /usr/lib/qm/rootfs/var/lib/libvirt/images/
$ wget -O /usr/lib/qm/rootfs/root/Fedora-Cloud-Base-Generic.qcow2 https://download.fedoraproject.org/pub/fedora/linux/releases/40/Cloud/x86_64/images/Fedora-Cloud-Base-Generic.x86_64-40-1.14.qcow2
# Generate the cloud-init.iso and move it to /usr/lib/qm/rootfs/var/lib/libvirt/images/
$host> cloud-localds cloud-init.iso user-data meta-data
$host> mv cloud-init.iso /usr/lib/qm/rootfs/var/lib/libvirt/images/
# Change permission to qemu:qemu
$host> chown qemu:qemu /usr/lib/qm/rootfs/var/lib/libvirt/*
Step 3: Starting libvirtd and checking if it's active inside QM
##################################################################
# Keep in mind for the next steps:
# Depending on the distro you are running SELinux might complain
# about libvirtd running on QM / udev errors
##################################################################
# Going inside QM
$ sudo podman exec -it qm bash
# Starting libvirtd
bash-5.2# systemctl start libvirt
# Check if it's running:
bash-5.2# systemctl is-active libvirtd
active
```
Step 4: Creating a script inside QM and running the VM
```bash
$host> cd /usr/lib/qm/rootfs/root/
$host> vi run
##### START SCRIPT ############
# Set .cache to /tmp
export XDG_CACHE_HOME=/tmp/.cache
# Remove previous instance
virsh destroy fedora-cloud-vm 2> /dev/null
virsh undefine fedora-cloud-vm 2> /dev/null
# Network
virsh net-define ./default.xml 2> /dev/null
virsh net-start default 2> /dev/null
virsh net-autostart default 2> /dev/null
# Install
virt-install \
--name fedora-cloud-vm \
--memory 20048 \
--vcpus 4 \
--disk path=/var/lib/libvirt/images/Fedora-Cloud-Base-Generic.qcow2,format=qcow2 \
--disk path=/var/lib/libvirt/images/cloud-init.iso,device=cdrom \
--os-variant fedora-unknown \
--network network=default \
--import \
--graphics none \
--console pty,target_type=serial \
--noautoconsole
##### END SCRIPT ############
```
Step 5: Running the script
```bash
qm$ sudo podman exec -it qm bash
bash-5.2# cd /root
bash-5.2# ./run
Domain 'fedora-cloud-vm' destroyed
Domain 'fedora-cloud-vm' has been undefined
Network default marked as autostarted
Starting install...
Creating domain... | 0 B 00:00:00
Domain creation completed.
bash-5.2# virsh list
Id Name State
---------------------------------
4 fedora-cloud-vm running
bash-5.2# virsh console fedora-cloud-vm
fedora-vm login: fedora
Password:
Last login: Tue Oct 8 06:01:18 on ttyS0
[fedora@fedora-vm ~]$
```
## RPM building dependencies
In order to build qm package on CentOS Stream 9 you'll need Code Ready Builder
repository enabled in order to provide `golang-github-cpuguy83-md2man` package.
To build QM packages on CentOS Stream 9, enable the Code Ready Builder
repository for access to the `golang-github-cpuguy83-md2man` package.
## How the OOM Score Adjustment is used in QM
## How OOM score adjustment is used in QM
The om_score_adj refers to the "Out of Memory score adjustment" in Linux operating systems. This parameter is used by the Out of Memory (OOM) killer to decide which processes to terminate when the system is critically low on memory.
The Linux host kernel controls ASIL and QM processes. The Out-of-Memory (OOM) Killer is part of the Linux
kernel's memory management subsystem. OOM Killer terminates processes to release RAM in memory-constrained conditions.
The `oom_score_adj` parameter refers to the Out-of-Memory score adjustment in Linux operating systems.
The OOM Killer uses the `oom_score_adj` parameter to decide which processes to terminate when the system is
critically low on memory.
### Why use oomscoreadj in QM?
By fine-tuning which processes are more likely to be terminated during low-memory situations,
critical processes can be protected, which enhances the overall stability of the system.
By fine-tuning which processes are more likely to be terminated during low memory situations, critical processes can be protected, thereby enhancing the overall stability of the system. For instance only, ASIL (Automotive Safety Integrity Level) applications, which are critical for ensuring functional safety in automotive systems, will be preserved in case of low resources.
- For example, ASIL applications are essential to maintaining functional safety in automotive systems.
You can set their OOM score adjustment value from *-1* to *-1000*. To prioritize their operation
even in low-memory situations, setting the value to *-1000* makes the process immune to the OOM killer
and ensures that ASIL applications are the last to be terminated.
### OOM Score Adjustment in QM
#### Nested Containers
- All nested containers created inside QM will have their OOM score adjustment set to *750*.
```console
$ cat /usr/share/qm/containers.conf | grep oom_score_adj
oom_score_adj = 750
```
#### QM Process
- The QM process has a default OOM score adjustment value set to *500*, configured via the *qm.container* file.
- The QM process has a default OOM score adjustment value set to *500*, configured via the `qm.container` file.
```console
cat /usr/share/containers/systemd/qm.container | grep OOMScoreAdjust
# OOMScoreAdjust=500
```
### ASIL Applications
- All nested containers created inside the QM have a default OOM score adjustment of *750*.
If we consider the example of ASIL (Automotive Safety Integrity Level) applications, which are essential for maintaining functional safety in automotive systems, their OOM score adjustment values can range from -1 to -1000. Setting the value to -1000 makes the process immune to the OOM killer. This ensures that ASIL applications are the last to be terminated by the OOM killer, thus prioritizing their operation even in low memory situations.
```console
$ cat /usr/share/qm/containers.conf | grep oom_score_adj
oom_score_adj = 750
```
#### Highlights
- Nested Containers inside QM: OOM score adjustment set to 750. (/usr/share/qm/containers.conf)
- QM Process: OOM score adjustment value set to 500, configured via the qm.container file.
- ASIL Applications: Can explore a range from -1 to -1000, with -1000 making the process immune to the OOM killer.
#### ASCII Diagram
### Priority process of OOM killer in the QM context
```txt
+-------------------------------------------------------------+
@ -572,7 +178,7 @@ If we consider the example of ASIL (Automotive Safety Integrity Level) applicati
| |
| Compared to other processes with the default adjustment |
| value of 0, nested containers are still more likely to be |
| terminated first, ensuring the system and ASIL Apps are |
| terminated first, ensuring the system and ASIL apps are |
| kept as safe as possible. |
| |
+-------------------------------------------------------------+
@ -582,17 +188,13 @@ If we consider the example of ASIL (Automotive Safety Integrity Level) applicati
------------------------------------ Kernel space -----------------------------------------------
```
## Examples
## Contributing to the QM project
Looking for quadlet examples files? See our [docs dir](docs/quadlet-examples/).
## Development
If your looking for contribute to the project use our [development README guide](docs/devel/README.md) as start point.
For information about how to contribute to the QM project, see the [Developers documentation README](docs/devel/README.md).
## Realtime
To enable real-time removal of sched_* blockage via seccomp, use the following schema.
To enable real-time removal of sched_* blockage via seccomp, use the following schema:
```bash
cat << EOF >> /etc/containers/systemd/qm.container.d/rt.conf
@ -601,14 +203,101 @@ SeccompProfile=""
> EOF
```
## Talks and Videos
## Talks and videos
Let's spread the knowledge regarding QM, if you have any interesting video regarding any
technology related to QM please with us.
Let's spread the knowledge regarding QM. If you have interesting content pertaining to
QM-related technology, please share it with us.
## RPM Mirrors
## RPM mirrors
Looking for a specific version of QM?
Search in the mirrors list below.
Looking for a specific version of QM? Search the [CentOS Automotive SIG Stream Mirror](https://mirror.stream.centos.org/SIGs/9-stream/automotive/aarch64/packages-main/Packages/q/). The packages in CentOS Automotive SIG Stream Mirror are for experimentation only.
[CentOS Automotive SIG - qm package - noarch](https://mirror.stream.centos.org/SIGs/9-stream/automotive/aarch64/packages-main/Packages/q/)
## Configuring QM
To run QM on an immutable OSTree-based OS, we use systemd units with Podman Quadlet.
For more information on how `podman-systemd.unit` works, refer to the manual:
`man podman-systemd.unit`
The default QM configuration drop-in file is located in `/usr/share/containers/systemd/qm.container`.
Modifying the original service file is not an option. Instead, create drop-in files to
modify the default configuration.
**NOTE:** The configuration is built in alphabetical order of the drop-in files.
### Modifying the `MemoryHigh` variable
To override the default settings, create a new drop-in `.conf` file in the
`/etc/containers/systemd/qm.container.d/` directory. This method ensures that QM memory
usage is controlled without modifying the base system configuration.
1. Check the current memory limit:
```bash
systemctl show -P MemoryHigh qm
infinity
```
The command output `infinity` indicates that `MemoryHigh` is unlimited. You can
see this setting in `/usr/share/containers/systemd/qm.container`.
1. Create a directory for the new drop-in file:
```bash
mkdir -p /etc/containers/systemd/qm.container.d/
```
1. Create a new drop-in file:
```bash
vim /etc/containers/systemd/qm.container.d/100-MemoryMax.conf
```
In this example, the new drop-in file is named `100-MemoryMax.conf`. You can choose a different name,
but be aware that the configuration is built in alphabetical order of the drop-in files.
1. Edit the file to add the following content:
```bash
[Service]
MemoryHigh=2G
```
`MemoryHigh` is specified in gigabytes. 2G means 2 gigabytes.
1. Preview the updated systemd configuration:
```bash
/usr/lib/systemd/system-generators/podman-system-generator {--user} --dryrun
```
1. Reload systemd and restart `qm.service` to apply the configuration changes:
```bash
systemctl daemon-reload
systemctl restart qm.service
```
1. Verify the value of `MemoryHigh`:
```bash
systemctl show -P MemoryHigh qm
2147483648
```
Memory values are displayed in bytes; 2147483648 bytes = 2G, which confirms that `MemoryHigh` is set to 2G.

View File

@ -1 +1 @@
0.7.1
0.7.6

View File

@ -6,6 +6,10 @@ cgroup_conf=[
"memory.oom.group=1",
]
# Temporary default to host network until we fix private network bridge setup
# when the qm container doesn't unmask all the virtual filesystems.
netns="host"
# The om_score_adj refers to the "Out of Memory score adjustment" in Linux
# operating systems. This parameter is used by the Out of Memory (OOM)
# killer to decide which processes to terminate when the system is
@ -18,3 +22,8 @@ cgroup_conf=[
# OOMScoreAdjust=500
#
oom_score_adj = 750
[network]
# The default is 10.88.0.0, but we need qm containers to have a
# different ip address range or routing becomes confused
default_subnet="10.89.0.0/16"

View File

@ -37,11 +37,69 @@ function add_syscall_deny_list() {
local syscall_name="$1"
local seccomp_file_path="$2"
local temp_file
temp_file=$(mktemp)
jq --tab \
--arg syscall "$syscall_name" \
'.syscalls += [{"names": [$syscall], "action": "SCMP_ACT_ERRNO", "args": [], "errnoRet": 1, "errno": "EPERM"}]' \
"${seccomp_file_path}" > "$temp_file" && mv "$temp_file" "${seccomp_file_path}"
if [[ "$syscall_name" == "sched_setscheduler" ]]; then
jq --tab \
'.syscalls += [
{
"names": ["sched_setscheduler"],
"action": "SCMP_ACT_ALLOW",
"args": [
{
"index": 1,
"value": 0,
"valueTwo": 0,
"op": "SCMP_CMP_EQ"
}
],
"comment": "",
"includes": {},
"excludes": {}
},
{
"names": ["sched_setscheduler"],
"action": "SCMP_ACT_ALLOW",
"args": [
{
"index": 1,
"value": 3,
"valueTwo": 0,
"op": "SCMP_CMP_EQ"
}
],
"comment": "",
"includes": {},
"excludes": {}
},
{
"names": ["sched_setscheduler"],
"action": "SCMP_ACT_ALLOW",
"args": [
{
"index": 1,
"value": 5,
"valueTwo": 0,
"op": "SCMP_CMP_EQ"
}
],
"comment": "",
"includes": {},
"excludes": {}
}
]' "$seccomp_file_path" > "$temp_file" && mv "$temp_file" "$seccomp_file_path"
else
jq --tab \
--arg syscall "$syscall_name" \
'.syscalls += [{
"names": [$syscall],
"action": "SCMP_ACT_ERRNO",
"args": [],
"errnoRet": 1,
"errno": "EPERM"
}]' "$seccomp_file_path" > "$temp_file" && mv "$temp_file" "$seccomp_file_path"
fi
rm "$temp_file" &> /dev/null
}

View File

@ -105,20 +105,15 @@ status() {
}
cpuweight() {
exec_color "sudo systemctl set-property --runtime QM.slice CPUWeight=50"
exec_color "sudo systemctl set-property --runtime qm.service CPUWeight=50"
echo "Value stored in QM.slice/cpu.weight:"
sudo cat /sys/fs/cgroup/QM.slice/cpu.weight
echo "Value stored in qm.service/cpu.weight:"
sudo cat /sys/fs/cgroup/qm.service/cpu.weight
echo "Value stored in QM.slice/qm.service/cpu.weight:"
sudo cat /sys/fs/cgroup/QM.slice/qm.service/cpu.weight
exec_color "sudo systemctl set-property --runtime QM.slice CPUWeight=10"
exec_color "sudo systemctl set-property --runtime qm.service CPUWeight=10"
echo "Value stored in QM.slice/cpu.weight:"
sudo cat /sys/fs/cgroup/QM.slice/cpu.weight
echo "Value stored in QM.slice/qm.service/cpu.weight:"
sudo cat /sys/fs/cgroup/QM.slice/qm.service/cpu.weight
echo "Value stored in qm.service/cpu.weight:"
sudo cat /sys/fs/cgroup/qm.service/cpu.weight
echo -e "\n\n[Press enter to continue]"
read -r
}

View File

@ -0,0 +1,109 @@
# Developers documentation
## Building QM rpm manually with changes
Building QM locally with changes for tests is a recommended practice,
especially for testing new features before submitting a pull request.
**1.** Prerequisite
```bash
dnf install -y rpm-build golang-github-cpuguy83-md2man selinux-policy-devel
```
**2.** Clone the repo
```bash
git clone https://github.com/containers/qm.git && cd qm
```
**3.** Build the RPM
Select a QM version that is a higher number from the current one.
For example, if today's QM version is 0.6.2, set it to 1.0 so that
the RPM created is identifiable as yours.
```bash
make clean && VERSION=1.0 make rpm
```
The rpm is created at the `${RPM_TOPDIR}/RPMS` folder, by default
`${PWD}/rpmbuild/RPMS`.
You can export **RPM_TOPDIR** to change the path where the rpm will be placed.
For example:
```bash
VERSION=1.0 RPM_TOPDIR=/USER/rpmbuild make rpm
```
## Building CentOS AutoSD and QM manually
During development, it is common to conduct integration tests to ensure your
changes work well with other components within the overall solution.
In our case, it's best to test against the CentOS Automotive Stream
Distribution (AutoSD) image.
Once you have the new [RPM](#building-qm-rpm-manually-with-changes), follow these steps:
**1.** Make sure the new rpm is located in **/USER/rpmbuild/RPMS/**
Example
```bash
ls /root/rpmbuild/RPMS/noarch/qm-1.0-1.noarch.rpm
/root/rpmbuild/RPMS/noarch/qm-1.0-1.noarch.rpm
```
**2.** Download additional packages required by the image
```bash
sudo dnf download --destdir /root/rpmbuild/RPMS/noarch/ selinux-policy selinux-policy-any
```
**3.** Create a local repository with the new package
```bash
dnf install createrepo_c -y
cd /root/rpmbuild/RPMS/noarch/
createrepo .
```
**4.** Clone the CentOS Automotive distro for the build
Ensure you meet the requirements for the CentOS Automotive Stream by
referring to [this link](https://sigs.centos.org/automotive/building/).
The following commands will execute:
- Install the podman package
- Clone the sample-images repository and required submodules (automotive-image-builder)
- Cleanups before a fresh build
- Finally creates a new qcow2 image (BASED ON distro name, mode (ostree or regular) and uses the qemu-qm-container sample image)
NOTE:
- The path for the new QM rpm file (/root/rpmbuild/RPMS/noarch)
- extra_rpms - useful for debug.
- ssh enabled
The command below utilises automotive-image-builder to produce a `qm-minimal` qcow2 image for cs9,
other example images such as `simple-qm-container` and the `simple-qm`
image can be found in the images directory of the sample-images repository.
```bash
dnf install podman -y && dnf clean all
git clone https://gitlab.com/CentOS/automotive/sample-images.git
git submodule update --init
cd sample-images/
rm -rf _build #Optional, only relevant after initial build
rm -rf *.qcow2 #Optional, only relevant after initial build
./automotive-image-builder/automotive-image-builder build --distro cs9 --mode package --define 'ssh_permit_root_login=true' --define 'ssh_permit_password_auth=true' --define 'extra_repos=[{"id":"local","baseurl":"file:///root/rpmbuild/RPMS/noarch"}]' --define 'extra_rpms=["qm-1.0", "vim-enhanced", "openssh-server", "openssh-clients", "python3", "polkit", "rsync", "strace", "dnf", "gdb"]' --target qemu --export qcow2 images/qm-minimal.mpp.yml cs9-qemu-qm-container.x86_64.qcow2
```
If you would like more information on building automotive images with automotive-image-builder, please see the
[Automotive SIG pages for AutoSD](https://sigs.centos.org/automotive/getting-started/about-automotive-image-builder/)
Run the virtual machine, default user: root, pass: password.
To change default values, use the [defaults.ipp.yml](https://gitlab.com/CentOS/automotive/src/automotive-image-builder/-/blob/main/include/defaults.ipp.yml) file.
```bash
./automotive-image-builder/automotive-image-runner --nographics ./cs9-qemu-qm-container.x86_64.qcow2
```

View File

@ -0,0 +1,21 @@
# Maintainer documentation
## Creating a new release
Initially, make sure to [bump **qm.te** and **VERSION** files in the git repo](https://github.com/containers/qm/pull/760) to the next release, i.e: *v0.7.5*.
After that, follow the steps below using GitHub UI.
**Create a new Release**
![Click on Releases](./pics/creatingreleases/00-Click-on-Releases.jpeg)
**Draft a new release**
![Draft a new release](./pics/creatingreleases/01-Draft-a-new-release.png)
**Create a new tag**
![Create a tag](./pics/creatingreleases/02-Create-a-tag.jpeg)
**Generate release notes**
![Generate release notes](./pics/creatingreleases/03-Generate-release-notes.jpeg)
**Publish Release**
![Click on publish release](./pics/creatingreleases/04-click-on-publish-release.jpeg)

View File

@ -1,359 +0,0 @@
# Developers documentation
## Table of contents
- [Building QM rpm manually with changes](#building-qm-rpm-manually-with-changes)
- [Building CentOS AutoSD and QM manually](#building-centos-autosd-and-qm-manually)
- [Useful Commands](#useful-commands)
- [Installing software inside QM partition](#installing-software-inside-qm-partition)
- [Removing software inside QM partition](#removing-software-inside-qm-partition)
- [Copying files to QM partition](#copying-files-to-qm-partition)
- [Listing QM service](#listing-qm-service)
- [List QM container via podman](#list-qm-container-via-podman)
- [Extend QM quadlet managed by podman](#extend-qm-quadlet-managed-by-podman)
- [Connecting to QM container via podman](#connecting-to-qm-container-via-podman)
- [SSH guest CentOS Automotive Stream Distro](#ssh-guest-centos-automotive-stream-distro)
- [Check if HOST and Container are using different network namespace](#check-if-host-and-container-are-using-different-network-namespace)
- [Debugging with podman in QM using --root](#debugging-with-podman-in-qm)
- [Creating your own drop-in QM sub-package](#creating-your-own-dropin-qm-subpackage)
- [Let automation create/publish PR sub-packages](#let-automation-create-publish-pr-subpackages)
- [Install PR copr sub-packages on local machine](#install-pr-copr-sub-packages-on-local-machine)
- [Debugging with quadlet](#debugging-with-quadlet)
## Building QM rpm manually with changes
Building QM locally with changes for tests is a recommended practice,
especially for testing new features before submitting a pull request.
**1.** Prerequisite
```bash
dnf install -y rpm-build golang-github-cpuguy83-md2man selinux-policy-devel
```
**2.** Clone the repo
```bash
git clone https://github.com/containers/qm.git
```
**3.** Build the RPM
Select a QM version that is a higher number from the current one.
For example, if today's QM version is 0.6.2, set it to 1.0 so that
the RPM created is identifiable as yours.
```bash
make clean && VERSION=1.0 make rpm
```
The rpm is created at the `${RPM_TOPDIR}/RPMS` folder, by default
`${PWD}/rpmbuild/RPMS`.
You can export **RPM_TOPDIR** to change the path where the rpm will be placed.
For example:
```bash
VERSION=1.0 RPM_TOPDIR=/USER/rpmbuild make rpm
```
## Building CentOS AutoSD and QM manually
During development, it is common to conduct integration tests to ensure your
changes work well with other components within the overall solution.
In our case, it's best to test against the CentOS Automotive Stream
Distribution (AutoSD) image.
Once you have the new [RPM](#building-qm-rpm-manually-with-changes), follow these steps:
**1.** Make sure the new rpm is located in **/USER/rpmbuild/RPMS/**
Example
```bash
ls /root/rpmbuild/RPMS/noarch/qm-1.0-1.noarch.rpm
/root/rpmbuild/RPMS/noarch/qm-1.0-1.noarch.rpm
```
**2.** Create a local repository with the new package
```bash
dnf install createrepo_c -y
cd /root/rpmbuild/RPMS/
createrepo .
```
**4.** Clone the CentOS Automotive distro for the build
Ensure you meet the requirements for the CentOS Automotive Stream by
referring to [this link](https://sigs.centos.org/automotive/building/).
The following commands will execute:
- Cleanups before a fresh build
- Remove old qcow2 images used (regular and ostree)
- Finally creates a new image (BASED ON target name, ostree or regular)
NOTE:
- The path for the new QM rpm file (/root/rpmbuild/RPMS/noarch)
- extra_rpms - useful for debug (do not use spaces between packages or will break)
- ssh enabled
```bash
dnf install podman -y && dnf clean all
git clone https://gitlab.com/CentOS/automotive/sample-images.git
git submodule update --init
cd sample-images/
rm -rf _build
rm -f cs9-qemu-qmcontainer-regular.x86_64.qcow2
rm -f cs9-qemu-qmcontainer-ostree.x86_64.qcow2
./build --distro cs9 --target qemu --define 'extra_repos=[{\"id\":\"local\",\"baseurl\":\"file:///root/rpmbuild/RPMS/noarch\"}]' --define 'extra_rpms=[\"qm-1.0\",\"vim-enhanced\",\"strace\",\"dnf\",\"gdb\",\"polkit\",\"rsync\",\"python3\",\"openssh-server\",\"openssh-clients\"]' --define 'ssh_permit_root_login=true' --define 'ssh_permit_password_auth=true' cs9-qemu-qmcontainer-regular.x86_64.qcow2
```
Run the virtual machine, default user: root, pass: password.
To change default values, use the [defaults.ipp.yml](https://gitlab.com/CentOS/automotive/src/automotive-image-builder/-/blob/main/include/defaults.ipp.yml) file.
```bash
./runvm --nographics ./cs9-qemu-qm-minimal-regular.x86_64.qcow2
```
## Useful Commands
### Installing software inside QM partition
```bash
dnf --installroot /usr/lib/qm/rootfs/ install vim -y
```
### Removing software inside QM partition
```bash
dnf --installroot /usr/lib/qm/rootfs/ remove vim -y
```
### Copying files to QM partition
Please note: This process is only applicable for regular images.
OSTree images are read-only, and any files must be included during the build process.
Once this is understood, proceed by executing the following command on the host after
the QM package has been installed.
```bash
#host> cp file_to_be_copied /usr/lib/qm/rootfs/root
#host> podman exec -it qm bash
bash-5.1> ls /root
file_to_be_copied
```
### Listing QM service
```bash
[root@localhost ~]# systemctl status qm -l
● qm.service
Loaded: loaded (/usr/share/containers/systemd/qm.container; generated)
Active: active (running) since Sun 2024-04-28 22:12:28 UTC; 12s
ago
Main PID: 354 (conmon)
Tasks: 7 (limit: 7772)
Memory: 82.1M (swap max: 0B)
CPU: 945ms
CGroup: /QM.slice/qm.service
├─libpod-payload-a83253ae278d7394cb38e975535590d71de90a41157b547040
4abd6311fd8cca
│ ├─init.scope
│ │ └─356 /sbin/init
│ └─system.slice
│ ├─bluechi-agent.service
│ │ └─396 /usr/libexec/bluechi-agent
│ ├─dbus-broker.service
│ │ ├─399 /usr/bin/dbus-broker-launch --scope system
--audit
│ │ └─401 dbus-broker --log 4 --controller 9 --machin
e-id a83253ae278d7394cb38e975535590d7 --max-bytes 536870912 --max-fds 4096 --max
-matches 16384 --audit
```
### List QM container via podman
```console
# podman ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
a83253ae278d /sbin/init 38 seconds ago Up 38 seconds qm
```
### Extend QM quadlet managed by podman
QM quadlet file is shipped through rpm, refer the following file.
qm.container which is installed to /usr/share/containers/systemd/qm.container
Please refer `man quadlet` for the supported value and how to.
In case a change needed in quadlet file, do not update systemd/qm.container file
As per `man quadlet` do the following:
```console
if ! test -e /etc/containers/systemd/qm.container.d ; then
mkdir -p /etc/containers/systemd/qm.container.d
fi
cat > "/etc/containers/systemd/qm.container.d/expose-dev.conf" <<EOF
[Container]
# Expose host device /dev/net/tun
AddDevice=-/dev/net/tun
# In case parameter override needed, add empty value before the required key
Unmask=
Unmask=ALL
EOF
```
To verify the result use the following command:
```console
/usr/lib/systemd/system-generators/podman-system-generator --dryrun
```
Once the result is satisfied, apply the following
```console
systemctl daemon-reload
systemctl restart qm
systemctl is-active qm
active
```
### Connecting to QM container via podman
```console
# podman exec -it qm bash
bash-5.1#
```
### SSH guest CentOS Automotive Stream Distro
Make sure the CentOS Automotive Stream Distro Virtual Machine/Container is running with SSHD enabled
and permits ssh connection from root user.
Add **PermitRootLogin yes** into **sshd_config**
```bash
host> vi /etc/ssh/sshd_config
```
Restart systemctl restart sshd
```bash
host> systemctl restart sshd
```
Find the port the ssh is listening in the VM
```bash
host> netstat -na |more # Locate the port (2222 or 2223, etc)
```
Example connecting from the terminal to the Virtual Machine:
```bash
connect-to-VM-via-SSH> ssh root@127.0.0.1 \
-p 2222 \
-oStrictHostKeyChecking=no \
-oUserKnownHostsFile=/dev/null
```
### Check if HOST and Container are using different network namespace
#### HOST
```console
[root@localhost ~]# ls -l /proc/self/ns/net
lrwxrwxrwx. 1 root root 0 May 1 04:33 /proc/self/ns/net -> 'net:[4026531840]'
```
#### QM
```console
bash-5.1# ls -l /proc/self/ns/net
lrwxrwxrwx. 1 root root 0 May 1 04:33 /proc/self/ns/net -> 'net:[4026532287]'
```
### Debugging with podman in QM
```console
bash-5.1# podman --root /usr/share/containers/storage pull alpine
Error: creating runtime static files directory "/usr/share/containers/storage/libpod":
mkdir /usr/share/containers/storage: read-only file system
```
### Creating your own dropin QM subpackage
We recommend using the existing drop-in files as a guide and adapting them to your specific needs. However, here are the step-by-step instructions:
1) Create a drop-in file in the directory: `etc/qm/containers/containers.conf.d`
2) Add it as a sub-package to `rpm/qm.spec`
3) Test it by running: `make clean && VERSION=YOURVERSIONHERE make rpm`
4) Additionally, test it with and without enabling the sub-package using (by default it should be disabled but there are cases where it will be enabled by default if QM community decide):
Example changing the spec and triggering the build via make (feel free to automate via sed, awk etc):
```bash
# Define the feature flag: 1 to enable, 0 to disable
# By default it's disabled: 0
%define enable_qm_dropin_img_tempdir 1
$ make clean && VERSION=YOURVERSIONHERE make rpm
```
### Let automation create publish PR subpackages
subpuckges could be created by Packit and uploaded
by Copr to packit/containers-qm-<PR_ID> repo.
Default macros for each subpackage deactivated by default.
To enable PR repo apply the follwoing
1. Enable subpackage spec macro definition in .packit.sh
Add the following line at the end of file,
```bash
# Update build additional rpms in spec
sed -i 's/\(<spec_file_macro_name> \).*/\11/' ${SPEC_FILE}
```
Check rpms created in PT Actions under PR Checks > Packit-as-a-Service
In case new tests need the sub-package, it will be innstalled immediatly
on Packit-as-a-Service test phase.
### Install PR copr sub-packages on local machine
1. Enbale repo in your machine
This part is done automatically by TestingFarm guest provisioning.
In case of manual installation,
```bash
dnf copr enable packit/containers-qm-<PR_ID> <distro><arch>
```
1. Install rpm in qm
This part is done automatically by TestingFarm guest provisioning.
In case of manual installation,
```bash
podman cp /etc/yum.repos.d/_copr:copr.fedorainfracloud.org:packit:containers-qm-<PR_ID>.repo qm:/etc/yum.repos.d/
dnf install --releasever=<VERSION_ID> --installroot /usr/lib/qm/rootfs/ <package>
```
### Debugging with quadlet
Imagine a situation where you have a Quadlet container inside QM that isn't starting, and you're unsure why. The best approach is to log into the QM, run the ```quadlet --dryrun``` command, and analyze what's happening. Here's how you can troubleshoot the issue step by step.
```bash
$ sudo podman exec -it qm bash
bash-5.1# cd /etc/containers/systemd/
bash-5.1# ls
ros2-rolling.container
bash-5.1# /usr/libexec/podman/quadlet --dryrun
quadlet-generator[1068]: Loading source unit file /etc/containers/systemd/ros2-rolling.container
quadlet-generator[1068]: converting "ros2-rolling.container": unsupported key 'Command' in group 'Container' in /etc/containers/systemd/ros2-rolling.container
bash-5.1#
```
As you can see above, the error occurs because the Quadlet is attempting to use an unsupported key from the Service section in the Container group. Removing the unsupported key ```Command``` from ```ros2-rolling.container``` and then reloading or restarting the service should resolve the issue.

Binary file not shown.

After

Width:  |  Height:  |  Size: 513 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 943 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 374 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 405 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 500 KiB

View File

@ -0,0 +1,419 @@
# Subpackages
Subpackages are **experimental approach** to deliver in a single point (RPM) dropin files
and additional requirements.
The qm project is designed to provide a flexible and modular environment for managing
Quality Management (QM) software in containerized environments. One of the key features
of the qm package is its support for sub-package(s), such as the qm-dropin sub-packages.
These sub-packages are not enabled by default and are optional. However, allow users
to easily extend or customize their QM environment by adding specific configurations,
tools, or scripts to the containerized QM ecosystem by simple installing or uninstalling
a RPM package into the system.
The key features of QM Sub-Packages are
- **Modularity**
- No configuration change, no typo or distribution rebuild/update.
- Just dnf install/remove from the traditional rpm schema.
- **Customizability**
- Users can easily add specific configurations to enhance or modify the behavior of their QM containers.
- **Maintainability**
- Sub-packages ensure that the base qm package remains untouched, allowing easy updates without breaking custom configurations.
- **Simplicity**
- Like qm-dropin provide a clear directory structure and templates to guide users in customizing their QM environment.
!!! note
The following sections describe the currently available QM subpackages.
## Building QM sub-packages
Choose one of the following sub-packages and build using make.
```bash
git clone git@github.com:containers/qm.git && cd qm
Example of subpackages: input, kvm, sound, tty7, ttyUSB0, video, windowmanager
make TARGETS=input subpackages
ls rpmbuild/RPMS/noarch/
qm-0.6.7-1.fc40.noarch.rpm qm_mount_bind_input-0.6.7-1.fc40.noarch.rpm
```
## Installing QM sub-packages
```bash
$ sudo dnf install ./rpmbuild/RPMS/noarch/qm_mount_bind_input-0.6.7-1.fc40.noarch.rpm
<SNIP>
Complete!
```
If QM is already running, restart or reload your QM container environment to apply the new configurations.
```bash
sudo systemctl daemon-reload
sudo podman restart qm
```
## Removing QM sub-packages
```bash
sudo rpm -e qm_mount_bind_input
```
## Creating your own drop-in QM sub-package
We recommend using the existing drop-in files as a guide and adapting them to your specific needs. However, here are the step-by-step instructions:
1) Add a drop-in file to: `etc/containers/systemd/qm.container.d/qm_dropin_<subpackage>.conf>`
2) Add your package as a sub-package to: `rpm/<subpackage_directory>/<subpackage>.spec`
3) Add the makefile for the sub-package and any files required by the sub-package to: `subsystems/<subpackage_directory>`
4) Test the sub-package build by running: `make clean && make TARGETS=<subpackage> subpackages`
5) Install your sub-package using: `dnf install -y rpmbuild/RPMS/noarch/<subpackage>*.noarch.rpm`
6) Restart podman container using: `sudo podman restart qm`
7) Additionally, test it with and without enabling the sub-package using (by default it should be disabled but there are cases where it will be enabled by default if QM community decide):
Example changing the spec and triggering the build via make (feel free to automate via sed, awk etc):
```bash
# Use make file to run specific subpackage
make TARGETS=windowmanager subpackages
```
## QM sub-package Input
The `input` sub-package exposes `/dev/input/*` devices (such as keyboards, mice, touchpads, etc.) from the host system to the QM container.
Follow the steps below to verify that the input sub-package properly mounts and exposes input devices inside the QM container.
### Step 1: Verify input devices are NOT visible inside QM
```bash
host> sudo podman exec -it qm ls /dev/input
ls: cannot access '/dev/input': No such file or directory
```
### Step 2: Build and install the input sub-package
```bash
host> make TARGETS=input subpackages
host> sudo dnf install ./rpmbuild/RPMS/noarch/qm_mount_bind_input-0.7.4-1.fc41.noarch.rpm
```
### Step 3: Confirm input devices exist on the host
```bash
host> ls /dev/input
by-id event0 event2 event4 js0 mouse0 mouse2
by-path event1 event3 event5 mice mouse1
```
### Step 4: Restart QM to apply the mount bind configuration
```bash
host> sudo systemctl daemon-reload
host> sudo podman restart qm
```
### Step 5: Re-check input devices inside QM
```bash
host> sudo podman exec -it qm ls /dev/input
event0 event2 event4 js0 mouse0 mouse2
event1 event3 event5 mice mouse1
```
## QM sub-package tty7
The tty7 sub-package exposes `/dev/tty7` to the container. `/dev/tty7` is typically the virtual terminal associated with the graphical user interface (GUI) on Linux systems.
Follow the steps below to verify that the input sub-package properly mounts and exposes input devices inside the QM container.
### Step 1: Verify tty7 is NOT visible inside QM
```bash
host> sudo podman exec -it qm ls -l /dev/tty7
ls: cannot access '/dev/tty7': No such file or directory
```
### Step 2: Build and install the tty7 sub-package
```bash
host> make TARGETS=tty7 subpackages
host> sudo dnf install ./rpmbuild/RPMS/noarch/qm-mount-bind-tty7-0.7.4-1.fc41.noarch.rpm
```
### Step 3: Restart QM to apply the mount bind configuration
```bash
host> sudo systemctl daemon-reload
host> sudo podman restart qm
```
### Step 4: Re-check tty7 inside QM
```bash
host> sudo podman exec -it qm ls -l /dev/tty7
crw--w----. 1 root tty 4, 7 Apr 15 13:34 /dev/tty7
```
## QM sub-package ttyUSB0
The ttyUSB0 sub-package exposes /dev/ttyUSB0 to the QM container. This device node is commonly used for USB-to-serial adapters, which are widely used to connect embedded systems, IoT devices, or other serial-based equipment.
### Step 1: Verify ttyUSB0 is NOT visible inside QM
```bash
host> sudo podman exec -it qm ls -l /dev/ttyUSB0
ls: cannot access '/dev/ttyUSB0': No such file or directory
```
### Step 2: Build and install the ttyUSB0 sub-package
```bash
host> make TARGETS=ttyUSB0 subpackages
host> sudo dnf install ./rpmbuild/RPMS/noarch/qm-mount-bind-ttyUSB0-0.7.4-1.fc41.noarch.rpm
```
### Step 3: Restart QM to apply the configuration
```bash
host> sudo systemctl daemon-reload
host> sudo podman restart qm
```
### Step 4: Re-check ttyUSB0 inside QM
```bash
host> sudo podman exec -it qm ls -l /dev/ttyUSB0
crw-rw-rw-. 1 root root 4, 64 Apr 24 08:50 /dev/ttyUSB0
```
### Additional Notes
- Make sure the USB-to-serial device is connected to the host machine before restarting QM.
- You can fake ttyUSB0 connection on host machine for testing reasons with:
```bash
sudo mknod /dev/ttyUSB0 c 4 64
sudo chmod 666 /dev/ttyUSB0
```
## QM sub-package Video
The video sub-package exposes `/dev/video0` (or many video devices required) to the container. This feature is useful for demonstrating how to share a camera from the host system into a container using Podman drop-in. To showcase this functionality, we provide the following demo:
### Building the video sub-package, installing, and restarting QM
```bash
make TARGETS=video subpackages
sudo dnf install ./rpmbuild/RPMS/noarch/qm-mount-bind-video-0.6.7-1.fc40.noarch.rpm
sudo systemctl daemon-reload
sudo podman restart qm
```
This simulates a rear camera when the user shifts into reverse gear.
In this simulation, we created a systemd service that, every time it is started, captures a snapshot from the webcam, simulating the action of a rear camera. (Feel free to start and restart the service multiple times!)
```bash
host> sudo podman exec -it qm bash
bash-5.2# systemctl daemon-reload
bash-5.2# systemctl start rear-camera
# ls -la /var/tmp/screenshot.jpg
-rw-r--r--. 1 root root 516687 Oct 13 04:05 /var/tmp/screenshot.jpg
bash-5.2#
```
### Copy the screenshot to the host and view it
```bash
host> sudo podman cp qm:/var/tmp/screenshot.jpg .
```
Great job! Now imagine all the possibilities this opens up!
## QM sub-package Sound
### Step 1: Install the QM Mount Bind Sound Package
To set up sound cards in a QM environment using Podman, follow the steps below:
Run the following commands to install the `qm_mount_bind_sound` package and restart QM (if previously in use):
```bash
# Build and install the RPM for QM sound
git clone https://github.com/containers/qm.git && cd qm
make TARGETS=sound subpackages
sudo dnf install -y rpmbuild/RPMS/noarch/qm_mount_bind_sound-0.6.7-1.fc40.noarch.rpm
# Restart QM container (if already running)
sudo systemctl daemon-reload
sudo podman restart qm
```
### Step 2: Identify Sound Cards
After installing the drop-in and restarting QM, you need to identify which sound card in the Linux system will be used in QM. If you're familiar with your sound card setup feel free to skip this step.
To list the sound cards available on your system (in our case, we will pick the number 1):
```bash
cat /proc/asound/cards
```
**Example Output**:
```bash
0 [NVidia ]: HDA-Intel - HDA NVidia
HDA NVidia at 0x9e000000 irq 17
1 [sofhdadsp ]: sof-hda-dsp - sof-hda-dsp
LENOVO-20Y5000QUS-ThinkPadX1ExtremeGen4i
2 [USB ]: USB-Audio - USB Audio Device
Generic USB Audio at usb-0000:00:14.0-5, full speed
```
### Detecting Channels and Sample Rates
To list the supported number of channels and samples use `pactl` command:
```bash
pactl list sinks | grep -i 48000 | uniq
Sample Specification: s24-32le 2ch 48000Hz
```
### Verify Sample Rate Support
To show the supported sample rates for a specific sound card codec, you can also inspect the codec details:
```bash
cat /proc/asound/card1/codec#0 | grep -i rates
```
This will output the supported sample rates for the codec associated with `card1`.
### Differentiating Between Cards
Accessing Card 1 (sof-hda-dsp)
```bash
cat /proc/asound/cards | grep -A 1 '^ 1 '
```
Accessing Card 2 (USB Audio Device)
```bash
cat /proc/asound/cards | grep -A 1 '^ 2 '
```
### Step 3: Testing audio inside QM
Inside QM, run the following command:
```bash
podman exec -it qm bash
bash-# podman ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
76dacaa9a89e quay.io/qm-images/audio:latest sleep infinity 7 hours ago Up 7 hours systemd-audio
bash-# podman exec -it systemd-audio bash
Execute the audio test within the nested container, and the sound will be output through the physical speakers of your computer—or, in this case, the car's multimedia soundbox.
bash-# speaker-test -D hw:1,0 -c 2 -r 48000
```
Params:
```bash
hw:1,0: sound card 1, device 0
-c 2: two channels (stereo)
-r 48000: sample rate of 48 kHz
```
## QM sub-package ROS2
The QM sub-package ROS2 (a.k.a "The Robot Operating System" or middleware for robots) is widely used by open-source projects, enterprises, companies, edge env and government agencies, including NASA, to advance robotics and autonomous systems. Enabled by Quadlet in QM, ROS2 on top of QM provides a secure environment where robots can operate and communicate safely, benefiting from QM's "Freedom from Interference" frequently tested layer. This ensures robots can function without external interference, enhancing their reliability and security.
The types of robots compatible with this environment are extensive, ranging from medical devices and aerial drones to aqua drones and space rockets. ROS2 within QM supports high availability, meaning these robotic systems can maintain continuous operations, crucial for mission-critical and industrial applications. This versatility makes it ideal for environments that demand robust communication and operational safety, from healthcare and aerospace to underwater exploration and autonomous land vehicles.
How to test this env?
```bash
git clone https://github.com/containers/qm.git && cd qm
make TARGETS=ros2_rolling subpackages
sudo dnf install rpmbuild/RPMS/noarch/qm_ros2_rolling-0.6.7-1.fc40.noarch.rpm -y
sudo systemctl daemon-reload
sudo podman restart qm # if you have qm already running
Testing using talker and listener examples
$host> sudo podman exec -it qm bash
QM> . /opt/ros/jazzy/setup.bash # always replace jazz with the image ROS distro
QM> ros2 run demo_nodes_cpp talker &
QM> ros2 run demo_nodes_cpp listener
```
## QM sub-package KVM
The QM sub-package KVM includes drop-in configuration that enables the integration of Kernel-based Virtual Machine (KVM) management into the QM (Quality Management) container environment.
This configuration allows users to pull containerized kvm from [qm-images-repo](https://quay.io/repository/qm-images/kvm) and run it inside QM
There is also kvm.container which is installed as a service.
Below example step by step:
Step 1: clone QM repo, create rpm.
```bash
git clone https://github.com/containers/qm.git && cd qm
make TARGETS=kvm subpackages
```
Step 2: copy rpm to running machine
```bash
scp -oStrictHostKeyChecking=no -oUserKnownHostsFile=/dev/null -P 2222 rpmbuild/RPMS/noarch/qm-kvm-0.7.4-1.fc41.noarch.rpm root@127.0.0.1:/root/
```
Step 3: ssh machine install and verify
```bash
sudo dnf install ./qm-kvm-0.7.4-1.fc41.noarch.rpm
sudo systemctl restart qm # if you have qm already running
```
Step 4: verify, configuration exist
```bash
ls -ltr /etc/containers/systemd/qm.container.d/
total 12
-rw-r--r--. 1 root root 34 Jan 1 1970 publish-port.conf
-rw-r--r--. 1 root root 139 Jul 21 2023 qm_dropin_mount_bind_kvm.conf
ls -ltr /etc/qm/containers/systemd/
total 12
-rw-r--r--. 1 root root 91 Jan 1 1970 nginx.container
-rw-r--r--. 1 root root 188 Jul 21 2023 kvm.container
[root@localhost ~]# podman exec qm systemctl is-active kvm
active
[root@localhost ~]# podman exec -it qm sh
sh-5.1# ssh fedora@localhost -p 2226
[fedora@ibm-p8-kvm-03-guest-02 ~]$ grep ^NAME /etc/os-release
NAME="Fedora Linux"
```
### AutoSD install
Some notes related to installing qm on ostree AutoSD image
1. Check /var/qm size is larger then 1.5G
2. Installing in ostree images with dnf command, requires running rpm-ostree usroverlay
In case using aib schema to build your image, verify adding the following to build command
```bash
--define 'extra_rpms=["audit","dnf","python3-gobject"] qm_varpart_relative_size=0.5'
```

View File

@ -0,0 +1,17 @@
## Installing QM
The first step to getting started with QM is installation.
Fedora or CentOS:
On Fedora and CentOS-Stream systems (with EPEL repository enabled), QM can be directly installed via:
```bash
dnf install qm
```
## RPM Mirrors
Looking for a specific version of QM?
Search in the mirrors list below.
[CentOS Automotive SIG - qm package - noarch](https://mirror.stream.centos.org/SIGs/9-stream/automotive/aarch64/packages-main/Packages/q/)

View File

@ -1,4 +1,6 @@
# An example of Android container running on top of kvm using quadlet and Wayland
# Virtualization: Android container with Quadlet
This is an example of an Android container running on top of kvm using quadlet and Wayland:
```console
$ cat ~/.config/containers/systemd/android.container

View File

@ -1,20 +1,22 @@
# Network Modes in Podman
# Using network modes with QM
## Basics: Network Modes in Podman
When running a container with Podman, you can specify the network mode using the `--network` flag. Two common options are `host` and `private`.
## Network=host
### Network=host
If you set `--network=host`, the container will use the host's network stack. This means the container will share the same network namespace as the host, and will be able to access the host's network interfaces, IP addresses, and ports.
In this mode, the container is not isolated from the host's network, and can potentially access sensitive network resources. This can be useful for certain use cases, such as running a container that needs to access a specific network interface or port on the host.
## Network=private (default)
### Network=private (default)
By default, Podman uses the `private` network mode. This means that the container will have its own isolated network namespace, and will not be able to access the host's network interfaces, IP addresses, or ports.
In this mode, the container is isolated from the host's network, and can only communicate with other containers on the same network. This provides a higher level of security, as the container is not able to access sensitive network resources on the host.
## Security Implications
### Security Implications
The reason `private` is the default network mode is due to security concerns. By isolating the container's network namespace, Podman prevents the container from accessing sensitive network resources on the host, such as:
@ -27,7 +29,7 @@ This helps to prevent potential security vulnerabilities, such as:
* Container escape: a container accessing sensitive resources on the host
* Lateral movement: a container accessing other containers on the host
## Example
### Example
To illustrate the difference, consider the following example:
@ -36,9 +38,47 @@ To illustrate the difference, consider the following example:
podman run -it --network=host fedora /bin/bash
# Run a container with network=private (default)
podman run -it fedora /bin/bash
podman run -it --network=private fedora /bin/bash
```
In the first example, the container will share the host's network namespace, while in the second example, the container will have its own isolated network namespace.
For more information, see the [Podman Networking Tutorial](https://github.com/containers/podman/blob/main/docs/tutorials/basic_networking.md).
For network modes configuration example using quadlets, see [Quadlet Network Example](https://github.com/containers/qm/blob/main/docs/quadlet-examples/network/README.md).
## Quadlet example running host and private networks
Here is an example of running a network-test container using quadlets for both --network=host and --network=private. You should place this file either in /usr/share/containers/systemd/ or /etc/containers/systemd/
```console
/usr/share/containers/systemd/
/etc/containers/systemd/
```
For rootless users:
```console
$HOME/.config/containers/systemd/
```
Host Network
```console
# network-test.container
[Container]
ContainerName=network-test
Image=localhost/local-audio-image
Network=host
```
Private Network
```console
# network-test.container
[Container]
ContainerName=network-test
Image=localhost/local-audio-image
Network=private
```

View File

@ -1,11 +1,7 @@
# Title: How to change the variables in qm containers.conf
## Description
# Changing variables in qm containers.conf
The `container.conf` file needs to be modified to allow pulling images larger than 1G from the repository on OStree images.
Input:
## Update container image_copy_tmp_dir if the image is an OStree
1. Create /var/qm/tmp.dir or differently named directory on host.

11
docs/docs/index.md Normal file
View File

@ -0,0 +1,11 @@
# QM
## QM is a containerized environment for running Functional Safety QM (Quality Management) software
The qm package sets up an isolated runtime environment for non-critical processes, managed through container tools and systemd. It is designed to ensure that these processes do not interfere with the host system, making it ideal for scenarios such as ASIL (Automotive Safety Integrity Level) separation.
QM runs as an exploded container—a persistent, containerized root filesystem mounted under /var/lib/qm/rootfs. It operates with its own instance of systemd, effectively creating a nested user space within its dedicated disk partition. This setup allows the system to isolate and control resource usage via cgroups, namespaces, and security constraints.
System-level tooling like Podman and systemd inside QM are fully independent from the host, so even container commands themselves are sandboxed. The environment is provisioned using Podman and configured with quadlet units, which streamline setup and lifecycle management.
Software installed inside the QM root is automatically isolated from the host. Developers can further segment workloads by using container tools inside QM to manage additional levels of containment for processes requiring extra isolation.

72
docs/docs/ipc.md Normal file
View File

@ -0,0 +1,72 @@
# Setting up IPC
In systems where **Automotive Safety Integrity Level (ASIL)** and **Quality Management (QM)**
components coexist, strict separation is enforced to maintain safety and security boundaries via
**SELinux (Security-Enhanced Linux)**, which labels processes and files with security contexts
to control their interactions.
**IPC (Inter-Process Communication)** between ASIL and QM components must be tightly controlled.
To comply with SELinux policies and avoid permission denials, any socket-based communication
between ASIL and QM domains should be established in the dedicated directory such as /run/ipc
with ipc_var_run_t file context. It serves as a secure bridge for cross-domain communication
while maintaining SELinux isolation.
On the other hand, **IPC between QM services** (e.g., two services or containers within the same QM domain)
can occur as well. Since these components share the same SELinux type and context, they are allowed to
communicate using standard Unix domain sockets located in /run. This approach simplifies internal QM
communication without compromising the system's overall security posture. Such communication can be
orchestrated also using container orchestration patterns like **.pod (Podman pod definitions)** or
**.kube (Kubernetes pod manifests)**, which group related services in shared namespaces to support efficient
IPC within the same trust boundary.
## Example QM to QM app
## /etc/qm/containers/systemd/ipc_client.container
```console
[Unit]
Description=Demo client service container
Requires=ipc_server.socket
After=ipc_server.socket
[Container]
Image=quay.io/username/ipc-demo/ipc_client:latest
Network=none
Volume=/run/:/run/
SecurityLabelLevel=s0:c1,c2
[Service]
Restart=always
[Install]
WantedBy=multi-user.target
```
## /etc/qm/containers/systemd/ipc_server.container
```console
[Unit]
Description=Demo server service container
Requires=ipc_server.socket
After=ipc_server.socket
[Container]
Image=quay.io/username/ipc-demo/ipc_server:latest
Network=none
Volume=/run/:/run/
SecurityLabelLevel=s0:c1,c2
[Service]
Restart=always
Type=notify
[Install]
WantedBy=multi-user.target
```
## /etc/qm/systemd/system/ipc_server.socket
```console
[Unit]
Description=IPC Server Socket
[Socket]
ListenStream=%t/ipc_server.socket
SELinuxContextFromNet=yes
[Install]
WantedBy=sockets.target
```

6
docs/docs/resources.md Normal file
View File

@ -0,0 +1,6 @@
# Additional Resources
- [Paving the Way for Uninterrupted Car Operations - DevConf Boston 2024](https://www.youtube.com/watch?v=jTrLqpw7E6Q)
- [Security - Sample Risk Analysis according to ISO26262](https://www.youtube.com/watch?v=jTrLqpw7E6Q&t=1268s)
- [ASIL and QM - Simulation and Service Monitoring using bluechi and podman](https://www.youtube.com/watch?v=jTrLqpw7E6Q&t=1680s)
- [Containers in a Car - DevConf.CZ 2023](https://www.youtube.com/watch?v=FPxka5uDA_4)

262
docs/docs/usage.md Normal file
View File

@ -0,0 +1,262 @@
# Using QM
This section describes how to interact with QM.
## Installing software inside QM partition
```bash
dnf --installroot /usr/lib/qm/rootfs/ install vim -y
```
## Removing software inside QM partition
```bash
dnf --installroot /usr/lib/qm/rootfs/ remove vim -y
```
## Copying files to QM partition
Please note: This process is only applicable for regular images.
OSTree images are read-only, and any files must be included during the build process.
Once this is understood, proceed by executing the following command on the host after
the QM package has been installed.
```bash
#host> cp file_to_be_copied /usr/lib/qm/rootfs/root
#host> podman exec -it qm bash
bash-5.1> ls /root
file_to_be_copied
```
## Listing QM service
```bash
[root@localhost ~]# systemctl status qm -l
● qm.service
Loaded: loaded (/usr/share/containers/systemd/qm.container; generated)
Active: active (running) since Sun 2024-04-28 22:12:28 UTC; 12s
ago
Main PID: 354 (conmon)
Tasks: 7 (limit: 7772)
Memory: 82.1M (swap max: 0B)
CPU: 945ms
CGroup: /qm.service
├─libpod-payload-a83253ae278d7394cb38e975535590d71de90a41157b547040
4abd6311fd8cca
│ ├─init.scope
│ │ └─356 /sbin/init
│ └─system.slice
│ ├─bluechi-agent.service
│ │ └─396 /usr/libexec/bluechi-agent
│ ├─dbus-broker.service
│ │ ├─399 /usr/bin/dbus-broker-launch --scope system
--audit
│ │ └─401 dbus-broker --log 4 --controller 9 --machin
e-id a83253ae278d7394cb38e975535590d7 --max-bytes 536870912 --max-fds 4096 --max
-matches 16384 --audit
```
## List QM container via podman
```console
# podman ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
a83253ae278d /sbin/init 38 seconds ago Up 38 seconds qm
```
## Extend QM quadlet managed by podman
QM quadlet file is shipped through rpm, refer the following file.
qm.container which is installed to /usr/share/containers/systemd/qm.container
Please refer `man quadlet` for the supported value and how to.
In case a change needed in quadlet file, do not update systemd/qm.container file
As per `man quadlet` do the following:
```console
if ! test -e /etc/containers/systemd/qm.container.d ; then
mkdir -p /etc/containers/systemd/qm.container.d
fi
cat > "/etc/containers/systemd/qm.container.d/expose-dev.conf" <<EOF
[Container]
# Expose host device /dev/net/tun
AddDevice=-/dev/net/tun
# In case parameter override needed, add empty value before the required key
Unmask=
Unmask=ALL
EOF
```
To verify the result use the following command:
```console
/usr/lib/systemd/system-generators/podman-system-generator --dryrun
```
Once the result is satisfied, apply the following
```console
systemctl daemon-reload
systemctl restart qm
systemctl is-active qm
active
```
## Managing CPU usage
Using the steps below, it's possible to manage CPU usage of the `qm.service` by modifying service attributes and utilizing drop-in files.
### Setting the CPUWeight attribute
Modifying the `CPUWeight` attribute affects the priority of the `qm.service`. A higher value prioritizes the service, while a lower value deprioritizes it.
Inspect the current CPUWeight value:
```bash
systemctl show -p CPUWeight qm.service
```
Set the CPUWeight value:
```bash
systemctl set-property qm.service CPUWeight=500
```
### Limiting CPUQuota
It's also possible to limit the percentage of the CPU allocated to the `qm.service` by defining `CPUQuota`. The percentage specifies how much CPU time the unit shall get at maximum, relative to the total CPU time available on one CPU.
Inspect the current `CPUQuota` value via the `CPUQuotaPerSecUSec` property:
```bash
systemctl show -p CPUQuotaPerSecUSec qm.service
```
Set the `CPUQuota` value of `qm.service` on the host using:
```bash
systemctl set-property qm.service CPUQuota=50%
```
Verify the `CPUQuota` drop in file has been created using the command below.
```bash
systemctl show qm.service | grep "DropInPath"
```
Expected output:
```bash
DropInPaths=/usr/lib/systemd/system/service.d/10-timeout-abort.conf /etc/systemd/system.control/qm.service.d/50-CPUQuota.conf
```
To test maxing out CPU usage and then inspect using the `top` command, follow these steps:
- Set the `CPUQuota` value of `qm.service` on the host using:
```bash
systemctl set-property qm.service CPUQuota=50%
```
- Execute this command to stress the CPU for 30 seconds:
```bash
podman exec qm timeout 30 dd if=/dev/zero of=/dev/null
```
- Observe the limited CPU consumption from the `qm.service`, as shown in the output of the command below:
```bash
top | head
```
Expected output:
```bash
PID USER PR NI VIRT RES SHR S %CPU %MEM TIME+ COMMAND
1213867 root 20 0 2600 1528 1528 R 50.0 0.0 4:15.21 dd
3471 user 20 0 455124 7568 6492 S 8.3 0.0 1:43.64 ibus-en+
1 root 20 0 65576 37904 11116 S 0.0 0.1 0:40.00 systemd
```
## Connecting to QM container via podman
```console
# podman exec -it qm bash
bash-5.1#
```
## SSH guest CentOS Automotive Stream Distro
Make sure the CentOS Automotive Stream Distro Virtual Machine/Container is running with SSHD enabled
and permits ssh connection from root user.
Add **PermitRootLogin yes** into **sshd_config**
```bash
host> vi /etc/ssh/sshd_config
```
Restart systemctl restart sshd
```bash
host> systemctl restart sshd
```
Find the port the ssh is listening in the VM
```bash
host> netstat -na |more # Locate the port (2222 or 2223, etc)
```
Example connecting from the terminal to the Virtual Machine:
```bash
connect-to-VM-via-SSH> ssh root@127.0.0.1 \
-p 2222 \
-oStrictHostKeyChecking=no \
-oUserKnownHostsFile=/dev/null
```
## Check if HOST and Container are using different network namespace
### HOST
```console
[root@localhost ~]# ls -l /proc/self/ns/net
lrwxrwxrwx. 1 root root 0 May 1 04:33 /proc/self/ns/net -> 'net:[4026531840]'
```
### QM
```console
bash-5.1# ls -l /proc/self/ns/net
lrwxrwxrwx. 1 root root 0 May 1 04:33 /proc/self/ns/net -> 'net:[4026532287]'
```
## Debugging with podman in QM
```console
bash-5.1# podman --root /usr/share/containers/storage pull alpine
Error: creating runtime static files directory "/usr/share/containers/storage/libpod":
mkdir /usr/share/containers/storage: read-only file system
```
## Debugging with quadlet
Imagine a situation where you have a Quadlet container inside QM that isn't starting, and you're unsure why. The best approach is to log into the QM, run the ```quadlet --dryrun``` command, and analyze what's happening. Here's how you can troubleshoot the issue step by step.
```bash
$ sudo podman exec -it qm bash
bash-5.1# cd /etc/containers/systemd/
bash-5.1# ls
ros2.container
bash-5.1# /usr/libexec/podman/quadlet --dryrun
quadlet-generator[1068]: Loading source unit file /etc/containers/systemd/ros2.container
quadlet-generator[1068]: converting "ros2.container": unsupported key 'Command' in group 'Container' in /etc/containers/systemd/ros2.container
bash-5.1#
```
As you can see above, the error occurs because the Quadlet is attempting to use an unsupported key from the Service section in the Container group. Removing the unsupported key ```Command``` from ```ros2.container``` and then reloading or restarting the service should resolve the issue.

38
docs/mkdocs.yml Normal file
View File

@ -0,0 +1,38 @@
site_name: QM Documentation
repo_url: https://github.com/containers/qm
repo_name: qm
edit_uri: blob/main/docs/docs/
copyright: Copyright Contributors to the QM project
nav:
- Home: index.md
- Getting Started: getting_started.md
- Using QM: usage.md
- Setting up IPC: ipc.md
- How To:
- Android container: how_tos/android.md
- Using network modes with QM: how_tos/network.md
- Changing variables in QM: how_tos/qm_variables.md
- Experimental:
- QM Subpackages: experimental/subpackages.md
- Additional resources: resources.md
theme:
name: material
features:
- content.code.copy
- navigation.indexes
markdown_extensions:
- toc:
permalink: True
- sane_lists
- smarty
- admonition
- pymdownx.snippets:
base_path: ["docs"]
check_paths: True
- pymdownx.superfences:
- pymdownx.tabbed:
alternate_style: true

3
docs/requirements.txt Normal file
View File

@ -0,0 +1,3 @@
mkdocs>=1.3.0
mkdocs-material>=9.3.1
pymdown-extensions>=10.0.1

View File

@ -9,4 +9,3 @@ Mount=type=bind,source=/dev/tty4,target=/dev/tty4
Mount=type=bind,source=/dev/tty5,target=/dev/tty5
Mount=type=bind,source=/dev/tty6,target=/dev/tty6
Mount=type=bind,source=/dev/tty7,target=/dev/tty7
Mount=type=bind,source=/dev/tty0,target=/dev/tty0

View File

@ -24,6 +24,10 @@ adjust:
script: |
cd tests/e2e
./set-ffi-env-e2e "${FFI_SETUP_OPTIONS}"
- name: Place quadlet for ffi-qm container
how: shell
script: |
cp tests/ffi/common/ffi-qm.container /etc/qm/containers/systemd/
execute:
how: tmt

View File

@ -2,7 +2,7 @@ summary: Kvm Tier 0 - QM sanity test
discover:
how: fmf
filter: 'tier:0&tag:kvm'
filter: 'tier:0&tag:kvm|tier:0&tag:qmctl-test'
prepare+:
- name: Enable copr and install rpms

12
qm.8.md
View File

@ -40,7 +40,7 @@ systemctl status qm.service
Tasks: 11 (limit: 76801)
Memory: 275.1M (swap max: 0B)
CPU: 4.527s
CGroup: /QM.slice/qm.service
CGroup: /qm.service
├─libpod-payload-00de006493bc970788d6c830beb494a58a9a2847a5eda200812d3a8b4e214814
│ ├─init.scope
│ │ └─993676 /sbin/init
@ -53,11 +53,13 @@ systemctl status qm.service
...
```
## CGROUPS QM.slice
## CGroups and container configuration
Notice that the QM environment is running systemd and other services within the
QM.Slice. This slice can be used to modify the cgroups controls of all of the
processes within the QM environment.
The options in the qm.container file overridden by using drop-in files, in the
directories `/etc/containers/systemd/qm.container.d` or`
`/usr/lib/containers/systemd/qm.container.d. This allows overriding for example
CGroup options like Service.CPUWeight, or podman options like Container.Volume.
Such options will affect all the processes running in the qm container.
## Install Additional packages in QM

View File

@ -11,7 +11,7 @@ WantedBy=default.target
# ManagedOOMSwap=auto|kill: Specifies how systemd-oomd.service will act on qm.
# QM cgroup, pass directly to systemd and handled by it,
# please refer to `man systemd.resource-control` for details.
CPUWeight=50
CPUWeight=idle
Delegate=true
IOWeight=50
ManagedOOMSwap=kill
@ -34,7 +34,10 @@ MemorySwapMax=0
# Containers within the qm contain default set OOMScoreAdj to 750
OOMScoreAdjust=500
Restart=always
Slice=QM.slice
# qm.service is a toplevel cgroup, so CPUWeight is relative to all other cgroups in that
# parent (such as user.slice and system.slice), otherwise the CPUWeight of qm.service
# is only compared to the other children of its parent.
Slice=-.slice
Environment=ROOTFS=/usr/lib/qm/rootfs
Environment=RWETCFS=/etc/qm
Environment=RWVARFS=/var/qm
@ -50,12 +53,6 @@ TasksMax=50%
# For details see: https://docs.podman.io/en/latest/markdown/podman-systemd.unit.5.html#addcapability
AddCapability=all
# Unmask
# -------
# Specify the paths to unmask separated by a colon. unmask=ALL or /path/1:/path/2, or shell expanded paths (/proc/*):
# If set to ALL, Podman will unmask all the paths that are masked or made read-only by default.
# For details see: https://docs.podman.io/en/latest/markdown/podman-systemd.unit.5.html#unmask
Unmask=ALL
SecurityLabelNested=true
SeccompProfile=/usr/share/qm/seccomp-no-rt.json
@ -67,7 +64,7 @@ SeccompProfile=/usr/share/qm/seccomp-no-rt.json
PidsLimit=-1
# Comment DropCapability this will allow FFI Tools to surpass their defaults.
DropCapability=sys_resource
DropCapability=sys_boot sys_resource
AddDevice=-/dev/kvm
AddDevice=-/dev/fuse

6
qm.fc
View File

@ -10,4 +10,8 @@
/etc/qm(/.*)? gen_context(system_u:object_r:qm_file_t,s0)
# File context for ipc programs
/var/run/ipc(/.*)? gen_context(system_u:object_r:ipc_var_run_t,s0)
/usr/lib/qm/rootfs/run/ipc(/.*)? gen_context(system_u:object_r:ipc_var_run_t,s0)
/run/ipc(/.*)? gen_context(system_u:object_r:ipc_var_run_t,s0)
# File context for bluechi-agent inside QM
/usr/lib/qm/rootfs/usr/libexec/bluechi-agent -- gen_context(system_u:object_r:qm_bluechi_agent_exec_t,s0)

5
qm.if
View File

@ -15,6 +15,7 @@ template(`qm_domain_template',`
gen_require(`
class dbus { send_msg acquire_svc };
class passwd rootok;
class process setcurrent;
attribute container_domain;
attribute filesystem_type;
@ -60,6 +61,7 @@ template(`qm_domain_template',`
container_exec_share_files($1_t)
allow $1_t container_ro_file_t:file execmod;
allow $1_container_domain $1_file_type:chr_file { rw_inherited_file_perms };
allow $1_t self:process setcurrent;
attribute $1_file_type;
allow $1_file_type self:filesystem associate;
@ -83,6 +85,7 @@ template(`qm_domain_template',`
allow $1_t $1_file_type:chr_file mounton;
allow $1_t $1_file_type:sock_file mounton;
filetrans_pattern(ipc_t, $1_file_t, ipc_var_run_t, dir, "ipc")
list_dirs_pattern($1_t, ipc_var_run_t, ipc_var_run_t)
allow $1_t ipc_var_run_t:dir mounton;
@ -93,7 +96,7 @@ template(`qm_domain_template',`
manage_lnk_files_pattern($1_t, $1_file_type, $1_file_type)
manage_sock_files_pattern($1_t, $1_file_type, $1_file_type)
fs_tmpfs_filetrans($1_t, $1_file_t, { dir file lnk_file })
allow $1_t $1_file_type:chr_file { watch watch_reads };
allow $1_t $1_file_type:chr_file { watch watch_reads map };
allow $1_t $1_file_type:dir { mounton relabelfrom relabelto };
allow $1_t $1_file_type:filesystem all_filesystem_perms;

51
qm.te
View File

@ -1,4 +1,4 @@
policy_module(qm, 0.7.1)
policy_module(qm, 0.7.6)
gen_require(`
attribute container_file_type;
@ -30,11 +30,56 @@ unconfined_domain(ipc_t)
qm_domain_template(qm)
#########################################
#
# bluechi-agent inside QM
#
type qm_bluechi_agent_t;
type qm_bluechi_agent_exec_t;
init_daemon_domain(qm_bluechi_agent_t, qm_bluechi_agent_exec_t)
allow qm_bluechi_agent_t qm_file_t:chr_file read;
allow qm_bluechi_agent_t qm_file_t:dir { open read search getattr };
allow qm_bluechi_agent_t qm_file_t:file { execute getattr open read };
allow qm_bluechi_agent_t qm_file_t:file map;
allow qm_bluechi_agent_t qm_file_t:lnk_file read;
allow qm_bluechi_agent_t qm_file_t:sock_file write;
allow qm_bluechi_agent_t qm_t:unix_dgram_socket sendto;
allow qm_bluechi_agent_t qm_t:unix_stream_socket connectto;
allow qm_bluechi_agent_t self:unix_dgram_socket { create getopt setopt };
allow qm_bluechi_agent_t self:tcp_socket create_stream_socket_perms;
allow qm_bluechi_agent_t qm_t:dbus { send_msg acquire_svc };
allow qm_bluechi_agent_t qm_t:system status;
allow qm_bluechi_agent_t qm_t:system { reload start stop status };
allow qm_bluechi_agent_t qm_file_t:service { reload start stop status };
allow qm_t qm_bluechi_agent_t:dir search;
allow qm_t qm_bluechi_agent_t:file { getattr ioctl open read };
allow qm_t qm_bluechi_agent_t:lnk_file read;
allow qm_t qm_bluechi_agent_t:dbus send_msg;
allow qm_t qm_bluechi_agent_t:process { signull signal sigkill };
unconfined_server_stream_connectto(qm_bluechi_agent_t)
# Allow qm_bluechi_agent_t to connect to any port instead of labelled ones.
gen_tunable(qm_bluechi_agent_port_connect_any, true)
optional_policy(`
require{
type bluechi_var_run_t;
type bluechi_agent_port_t;
type bluechi_t;
}
stream_connect_pattern(qm_t, bluechi_var_run_t, bluechi_var_run_t, bluechi_t)
unconfined_server_stream_connectto(qm_t)
tunable_policy(`qm_bluechi_agent_port_connect_any',`
corenet_tcp_connect_all_ports(qm_bluechi_agent_t)
',`
allow qm_bluechi_agent_t bluechi_agent_port_t:tcp_socket name_connect;
')
stream_connect_pattern(qm_bluechi_agent_t, bluechi_var_run_t, bluechi_var_run_t, bluechi_t)
')

View File

@ -1,8 +1,5 @@
%global debug_package %{nil}
# Define the rootfs macros
%global rootfs_qm %{_prefix}/lib/qm/rootfs/
Name: qm-mount-bind-dvb
Version: 0
Release: 1%{?dist}
@ -12,7 +9,7 @@ URL: https://github.com/containers/qm
Source0: %{url}/archive/qm-dvb-%{version}.tar.gz
BuildArch: noarch
Requires: qm = %{version}-%{release}
Requires: qm >= %{version}
%description
This subpackage installs a drop-in configuration for QM containers to mount bind `/dev/dvb`.
@ -25,7 +22,7 @@ This subpackage installs a drop-in configuration for QM containers to mount bind
install -d %{buildroot}%{_sysconfdir}/containers/systemd/qm.container.d
# Install the dvb drop-in configuration file
install -m 644 %{_builddir}/qm-video-%{version}/etc/containers/systemd/qm.container.d/qm_dropin_mount_bind_dvb.conf \
install -m 644 %{_builddir}/qm-dvb-%{version}/etc/containers/systemd/qm.container.d/qm_dropin_mount_bind_dvb.conf \
%{buildroot}%{_sysconfdir}/containers/systemd/qm.container.d/qm_dropin_mount_bind_dvb.conf

View File

@ -1,30 +0,0 @@
Name: qm-dropin-img-tempdir
Version: 0
Release: 1%{?dist}
Summary: Drop-in configuration for QM nested containers using img tempdir
License: GPL-2.0-only
URL: https://github.com/containers/qm
Source0: %{url}/archive/qm-img_tempdir-%{version}.tar.gz
BuildArch: noarch
Requires: qm = %{version}-%{release}
%description
This sub-package installs drop-in configurations for QM nested containers that use img tempdir.
%prep
%autosetup -Sgit -n qm-img_tempdir-%{version}
%install
install -d %{buildroot}%{_sysconfdir}/qm/containers/containers.conf.d
install -m 644 %{_builddir}/qm-img_tempdir-%{version}/etc/qm/containers/containers.conf.d/qm_dropin_img_tempdir.conf \
%{buildroot}%{_sysconfdir}/qm/containers/containers.conf.d/
%files
%license LICENSE
%doc README.md
%{_sysconfdir}/qm/containers/containers.conf.d/qm_dropin_img_tempdir.conf
%changelog
* Fri Jul 21 2023 RH Container Bot <rhcontainerbot@fedoraproject.org>
- Added img_tempdir mount bind drop-in configuration.

View File

@ -1,6 +1,6 @@
%global debug_package %{nil}
Name: qm_mount_bind_input
Name: qm-mount-bind-input
Version: 0
Release: 1%{?dist}
Summary: Drop-in configuration for QM containers to mount bind input devices
@ -9,7 +9,7 @@ URL: https://github.com/containers/qm
Source0: %{url}/archive/qm-input-%{version}.tar.gz
BuildArch: noarch
Requires: qm = %{version}-%{release}
Requires: qm >= %{version}
%description
This sub-package installs drop-in configurations for QM containers to mount bind input devices.

View File

@ -1,10 +1,14 @@
%global debug_package %{nil}
# Define rootfs macro for QM environment
%global rootfs_qm %{_prefix}/lib/qm/rootfs/
# rootfs_qm, Define rootfs macro for QM environment not need, do to install command from host
# dnf install --setopt=reposdir=/etc/yum.repos.d <package>
# using qm_sysconfdir /etc/qm/ overlay preventing the detection of quadletfile, need to install
# in the overlay of etc under the host
%define qm_sysconfdir %{_sysconfdir}/qm
Name: qm-kvm
Version: 0
# Version: 0
Version: %{version}
Release: 1%{?dist}
Summary: Drop-in configuration for QM containers to mount bind /dev/kvm
License: GPL-2.0-only
@ -12,17 +16,7 @@ URL: https://github.com/containers/qm
Source0: %{url}/archive/qm-kvm-%{version}.tar.gz
BuildArch: noarch
# Build requirements
BuildRequires: make
BuildRequires: podman
BuildRequires: selinux-policy
BuildRequires: selinux-policy-devel
# Runtime dependencies
Requires: qm = %{version}-%{release}
Requires: selinux-policy >= %{_selinux_policy_version}
Requires: selinux-policy-base >= %{_selinux_policy_version}
Requires: podman
Requires: qm >= %{version}
%description -n qm-kvm
This subpackage provides a drop-in configuration for the QM environment to enable mount binding of `/dev/kvm` from the host system to containers. This configuration is essential for supporting KVM-based virtualization within QM containers.
@ -30,18 +24,24 @@ This subpackage provides a drop-in configuration for the QM environment to enabl
%prep
%autosetup -Sgit -n qm-kvm-%{version}
%build
%install
# Create the directory for drop-in configurations
install -d %{buildroot}%{_sysconfdir}/containers/systemd/qm.container.d
install -d %{buildroot}%{qm_sysconfdir}/containers/systemd
# Install the KVM drop-in configuration file
install -m 644 %{_builddir}/qm-kvm-%{version}/etc/containers/systemd/qm.container.d/qm_dropin_mount_bind_kvm.conf \
%{buildroot}%{_sysconfdir}/containers/systemd/qm.container.d/qm_dropin_mount_bind_kvm.conf
install -m 644 %{_builddir}/qm-kvm-%{version}/subsystems/kvm/etc/containers/systemd/kvm.container \
%{buildroot}%{qm_sysconfdir}/containers/systemd/kvm.container
%files -n qm-kvm
%license LICENSE
%doc README.md SECURITY.md
%{_sysconfdir}/containers/systemd/qm.container.d/qm_dropin_mount_bind_kvm.conf
%{qm_sysconfdir}/containers/systemd/kvm.container
%changelog
* Fri Jul 21 2023 RH Container Bot <rhcontainerbot@fedoraproject.org>

View File

@ -1,8 +1,5 @@
%global debug_package %{nil}
# rootfs macros
%global rootfs_qm %{_prefix}/lib/qm/rootfs/
# Define the feature flag: 1 to enable, 0 to disable
# By default it's disabled: 0
@ -19,6 +16,11 @@
# Format must contain '$x' somewhere to do anything useful
%global _format() export %1=""; for x in %{modulenames}; do %1+=%2; %%1+=" "; done;
# RHEL < 10 and Fedora < 40 use file context entries in /var/run
%if %{defined rhel} && 0%{?rhel} < 10 || %{defined fedora} && 0%{?fedora} < 40
%define legacy_var_run 1
%endif
# copr_username is only set on copr environments, not on others like koji
# Check if copr is owned by rhcontainerbot
%if "%{?copr_username}" != "rhcontainerbot"
@ -93,6 +95,10 @@ use container tools like Podman.
sed -i 's/^install: man all/install:/' Makefile
%build
%if %{defined legacy_var_run}
sed -i 's|^/run/|/var/run/|' qm.fc
%endif
%{__make} all
%install
@ -110,7 +116,8 @@ install -d %{buildroot}%{_sysconfdir}/containers/containers.conf.d
# Execute the script to create seccomp rules after the package is installed
/usr/share/qm/create-seccomp-rules
/usr/share/qm/comment-tz-local # FIX-ME GH-issue: 367
modprobe ip_tables # podmand netavark requires at host to load
# podmand netavark requires at host to load or let's ignore in case host don't have it and proceed with the installation
modprobe ip_tables || true
%preun
if [ $1 = 0 ]; then

View File

@ -9,7 +9,7 @@ URL: https://github.com/containers/qm
Source0: %{url}/archive/qm-radio-%{version}.tar.gz
BuildArch: noarch
Requires: qm = %{version}-%{release}
Requires: qm >= %{version}
%description
This subpackage installs a drop-in configuration for QM containers to mount bind `/dev/radio`.

View File

@ -1,10 +1,9 @@
%global debug_package %{nil}
# rootfs macros for QM ROS2 Rolling
%global rootfs_qm %{_prefix}/lib/qm/rootfs/
%define qm_sysconfdir %{_sysconfdir}/qm
Name: qm-ros2-rolling
Version: 0
Name: qm-ros2
Version: %{version}
Release: 1%{?dist}
Summary: Subpackage container for quadlet container to ROS2 Rolling environment
License: GPL-2.0-only
@ -12,7 +11,7 @@ URL: https://github.com/containers/qm
Source0: %{url}/archive/qm-ros2-%{version}.tar.gz
BuildArch: noarch
Requires: qm = %{version}-%{release}
Requires: qm >= %{version}
%description
This subpackage provides a containerized ROS2 Rolling environment within the
@ -27,18 +26,19 @@ containers managed by Podman and systemd within the QM environment.
%install
# Create the necessary directory structure
install -d %{buildroot}%{rootfs_qm}%{_sysconfdir}/containers/systemd
install -d %{buildroot}%{qm_sysconfdir}/containers/systemd
# Install the ROS2 Rolling container file
install -m 644 %{_builddir}/qm-ros2-%{version}/subsystems/ros2/etc/containers/systemd/ros2-rolling.container %{buildroot}%{rootfs_qm}%{_sysconfdir}/containers/systemd/ros2-rolling.container
install -m 644 %{_builddir}/qm-ros2-%{version}/subsystems/ros2/etc/containers/systemd/ros2.container \
%{buildroot}%{qm_sysconfdir}/containers/systemd/ros2.container
%files
%license LICENSE
%doc README.md SECURITY.md
%{rootfs_qm}%{_sysconfdir}/containers/systemd/ros2-rolling.container
%{qm_sysconfdir}/containers/systemd/ros2.container
%changelog
* Fri Jul 21 2023 RH Container Bot <rhcontainerbot@fedoraproject.org> - 0.6.8-1
- Initial release of qm-ros2-rolling
- Initial release of qm-ros2

View File

@ -1,10 +1,10 @@
%global debug_package %{nil}
# Define the rootfs macros
%global rootfs_qm %{_prefix}/lib/qm/rootfs/
%define qm_sysconfdir %{_sysconfdir}/qm
Name: qm-sound
Version: 0
Version: %{version}
Release: 1%{?dist}
Summary: Drop-in configuration for QM containers to mount bind /dev/snd
License: GPL-2.0-only
@ -12,7 +12,7 @@ URL: https://github.com/containers/qm
Source0: %{url}/archive/qm-sound-%{version}.tar.gz
BuildArch: noarch
Requires: qm = %{version}-%{release}
Requires: qm >= %{version}
%description
This subpackage installs a drop-in configuration for QM containers,
@ -29,9 +29,10 @@ the container and nested containers.
# Install drop-in configuration for /dev/snd
# Create the directory for drop-in configurations
install -d %{buildroot}%{_sysconfdir}/containers/systemd/qm.container.d
install -d %{buildroot}%{rootfs_qm}%{_sysconfdir}/containers/systemd
install -d %{buildroot}%{qm_sysconfdir}/containers/systemd
install -m 644 %{_builddir}/qm-sound-%{version}/subsystems/sound/etc/containers/systemd/audio.container %{buildroot}%{rootfs_qm}%{_sysconfdir}/containers/systemd/audio.container
install -m 644 %{_builddir}/qm-sound-%{version}/subsystems/sound/etc/containers/systemd/audio.container \
%{buildroot}%{qm_sysconfdir}/containers/systemd/audio.container
# Install the sound drop-in configuration file
install -m 644 %{_builddir}/qm-sound-%{version}/etc/containers/systemd/qm.container.d/qm_dropin_mount_bind_snd.conf \
%{buildroot}%{_sysconfdir}/containers/systemd/qm.container.d/qm_dropin_mount_bind_snd.conf
@ -40,7 +41,7 @@ install -m 644 %{_builddir}/qm-sound-%{version}/etc/containers/systemd/qm.contai
%license LICENSE
%doc README.md SECURITY.md
%{_sysconfdir}/containers/systemd/qm.container.d/qm_dropin_mount_bind_snd.conf
%{rootfs_qm}%{_sysconfdir}/containers/systemd/audio.container
%{qm_sysconfdir}/containers/systemd/audio.container
%changelog
* Fri Jul 21 2023 RH Container Bot <rhcontainerbot@fedoraproject.org>

View File

@ -1,8 +1,5 @@
%global debug_package %{nil}
# Define rootfs macro for QM environment
%global rootfs_qm %{_prefix}/lib/qm/rootfs/
Name: qm-text2speech
Version: 0
Release: 1%{?dist}
@ -12,18 +9,9 @@ URL: https://github.com/containers/qm
Source0: %{url}/archive/qm-text2speech-%{version}.tar.gz
BuildArch: noarch
# Build requirements
BuildRequires: make
BuildRequires: podman
BuildRequires: selinux-policy
BuildRequires: selinux-policy-devel
# Runtime dependencies
Requires: qm = %{version}-%{release}
Requires: qm >= %{version}
Requires: qm-mount-bind-sound
Requires: selinux-policy >= %{_selinux_policy_version}
Requires: selinux-policy-base >= %{_selinux_policy_version}
Requires: podman
Requires: espeak
%description -n qm-text2speech
@ -37,7 +25,7 @@ This subpackage provides a drop-in configuration for the QM environment to enabl
%install
%post
dnf --setopt=reposdir=/etc/qm/yum.repos.d --installroot /usr/lib/qm/rootfs/ install espeak -y
dnf install --setopt=reposdir=/etc/yum.repos.d --installroot /usr/lib/qm/rootfs/ espeak-ng
%files
%license LICENSE
@ -45,4 +33,4 @@ dnf --setopt=reposdir=/etc/qm/yum.repos.d --installroot /usr/lib/qm/rootfs/ in
%changelog
* Fri Jul 21 2023 RH Container Bot <rhcontainerbot@fedoraproject.org>
- Initial standalone spec for the QM KVM subpackage.
- Initial standalone spec for the QM espeak subpackage.

View File

@ -9,7 +9,7 @@ URL: https://github.com/containers/qm
Source0: %{url}/archive/qm-tty7-%{version}.tar.gz
BuildArch: noarch
Requires: qm = %{version}-%{release}
Requires: qm >= %{version}
%description
This subpackage installs a drop-in configuration for QM containers to mount bind `/dev/tty7`.

View File

@ -1,6 +1,6 @@
%global debug_package %{nil}
Name: qm_mount_bind_ttyUSB0
Name: qm-mount-bind-ttyUSB0
Version: 0
Release: 1%{?dist}
Summary: Drop-in configuration for QM containers to mount bind ttyUSB0
@ -9,7 +9,7 @@ URL: https://github.com/containers/qm
Source0: %{url}/archive/qm-ttyUSB0-%{version}.tar.gz
BuildArch: noarch
Requires: qm = %{version}-%{release}
Requires: qm >= %{version}
%description
This sub-package installs drop-in configurations for QM containers to mount bind ttyUSB0.

View File

@ -1,10 +1,10 @@
%global debug_package %{nil}
# Define the rootfs macros
%global rootfs_qm %{_prefix}/lib/qm/rootfs/
%define qm_sysconfdir %{_sysconfdir}/qm
Name: qm-mount-bind-video
Version: 0
Version: %{version}
Release: 1%{?dist}
Summary: Drop-in configuration for QM containers to mount bind /dev/video
License: GPL-2.0-only
@ -12,7 +12,7 @@ URL: https://github.com/containers/qm
Source0: %{url}/archive/qm-video-%{version}.tar.gz
BuildArch: noarch
Requires: qm = %{version}-%{release}
Requires: qm >= %{version}
%description
This subpackage installs a drop-in configuration for QM containers to mount bind `/dev/video`.
@ -26,10 +26,11 @@ This subpackage installs a drop-in configuration for QM containers to mount bind
%install
# Create the directory for drop-in configurations
install -d %{buildroot}%{_sysconfdir}/containers/systemd/qm.container.d
install -d %{buildroot}%{rootfs_qm}%{_sysconfdir}/containers/systemd
install -d %{buildroot}%{qm_sysconfdir}/containers/systemd
install -m 644 %{_builddir}/qm-video-%{version}/subsystems/video/etc/containers/systemd/rear-camera.container \
%{buildroot}%{qm_sysconfdir}/containers/systemd/rear-camera.container
install -m 644 %{_builddir}/qm-video-%{version}/subsystems/video/etc/containers/systemd/rear-camera.container %{buildroot}%{rootfs_qm}%{_sysconfdir}/containers/systemd/rear-camera.container
# Install the sound drop-in configuration file
install -m 644 %{_builddir}/qm-video-%{version}/etc/containers/systemd/qm.container.d/qm_dropin_mount_bind_video.conf \
%{buildroot}%{_sysconfdir}/containers/systemd/qm.container.d/qm_dropin_mount_bind_video.conf
@ -37,7 +38,7 @@ install -m 644 %{_builddir}/qm-video-%{version}/etc/containers/systemd/qm.contai
%license LICENSE
%doc README.md SECURITY.md
%{_sysconfdir}/containers/systemd/qm.container.d/qm_dropin_mount_bind_video.conf
%{rootfs_qm}%{_sysconfdir}/containers/systemd/rear-camera.container
%{qm_sysconfdir}/containers/systemd/rear-camera.container
%changelog
* Fri Jul 21 2023 RH Container Bot <rhcontainerbot@fedoraproject.org>

View File

@ -1,9 +1,9 @@
# Define the rootfs macros
%global rootfs_qm %{_prefix}/lib/qm/rootfs/
%define qm_sysconfdir %{_sysconfdir}/qm
Name: qm-windowmanager
Version: 0
Version: %{version}
Release: 1%{?dist}
Summary: Optional Window Manager for QM environment
License: GPL-2.0-only
@ -11,7 +11,7 @@ URL: https://github.com/containers/qm
Source0: %{url}/archive/qm-windowmanager-%{version}.tar.gz
BuildArch: noarch
Requires: qm = %{version}-%{release}
Requires: qm >= %{version}
%description
This sub-package installs an experimental window manager for the QM environment.
@ -23,23 +23,23 @@ This sub-package installs an experimental window manager for the QM environment.
# Create the directory for drop-in configurations
install -d %{buildroot}/%{_sysconfdir}/pam.d/
install -d %{buildroot}%{_sysconfdir}/containers/systemd/qm.container.d
install -d %{buildroot}%{rootfs_qm}%{_sysconfdir}/containers/systemd
install -d %{buildroot}%{qm_sysconfdir}/containers/systemd
# Install the Window manager drop-in configuration file
install -m 644 %{_builddir}/qm-windowmanager-%{version}/etc/containers/systemd/qm.container.d/qm_dropin_mount_bind_window_manager.conf \
%{buildroot}%{_sysconfdir}/containers/systemd/qm.container.d/qm_dropin_mount_bind_window_manager.conf
install -m 644 %{_builddir}/qm-windowmanager-%{version}/subsystems/windowmanager/etc/pam.d/wayland %{buildroot}/%{_sysconfdir}/pam.d/
install -m 644 %{_builddir}/qm-windowmanager-%{version}/subsystems/windowmanager/etc/containers/systemd/* %{buildroot}%{rootfs_qm}%{_sysconfdir}/containers/systemd/
install -m 644 %{_builddir}/qm-windowmanager-%{version}/subsystems/windowmanager/etc/containers/systemd/* %{buildroot}%{qm_sysconfdir}/containers/systemd/
%files
%license LICENSE
%doc README.md
%{_sysconfdir}/pam.d/wayland
%{_sysconfdir}/containers/systemd/qm.container.d/qm_dropin_mount_bind_window_manager.conf
%{rootfs_qm}%{_sysconfdir}/containers/systemd/gnome_mutter.container
%{rootfs_qm}%{_sysconfdir}/containers/systemd/session-activate.container
%{rootfs_qm}%{_sysconfdir}/containers/systemd/wayland-extra-devices.conf
%{rootfs_qm}%{_sysconfdir}/containers/systemd/weston_terminal.container
%{qm_sysconfdir}/containers/systemd/gnome_mutter.container
%{qm_sysconfdir}/containers/systemd/session-activate.container
%{qm_sysconfdir}/containers/systemd/wayland-extra-devices.conf
%{qm_sysconfdir}/containers/systemd/weston_terminal.container
%changelog
* Fri Jul 21 2023 RH Container Bot <rhcontainerbot@fedoraproject.org>

61
setup
View File

@ -35,10 +35,41 @@ CMDLINE_ARGUMENT_LIST=(
"skip-systemctl"
)
logger() {
{
local log_level="$1"
local message="$2"
local NC='\033[0m' # No Color
local log_col=$NC
} > /dev/null 2>&1
case "$log_level" in
INFO)
log_col='\033[0;36m' #BLUE
;;
WARNING)
log_col='\033[1;33m' #YELLOW
;;
ERROR)
log_col='\033[0;31m' #RED
;;
DEBUG)
log_col='\033[0;90m' #GREY
;;
SUCCESS)
log_col='\033[0;32m' #GREEN
;;
*)
echo -e "[\033[1;31mERROR\033[0m] Invalid log level: $log_level" >&2
return 1
;;
esac
echo -e "[$log_col${log_level}${NC}] $message"
}
root_check() {
if [ "$(id -u)" -ne 0 ];then
echo "Please run this script as root"
exit 1
logger "WARNING" "Please run this script as root"
exit 1
fi
}
@ -132,7 +163,7 @@ validate_qm_installation() {
for file in "${files[@]}"; do
if [[ ! -f "$file" ]]; then
echo "Exiting... '$file' not found. Try reinstall the QM package before continue." >&2
logger "ERROR" "Exiting... '$file' not found. Try reinstall the QM package before continuing."
exit 1
fi
done
@ -147,7 +178,7 @@ install() {
setupRW "${ROOTFS}" "${RWETCFS}" "${RWVARFS}"
EXTRA_FLAG=""
if grep -qi "^ID=fedora" /etc/os-release; then
if [ "$ID" == "fedora" ] && [ "$VERSION_ID" -ge 41 ]; then
EXTRA_FLAG="--use-host-config"
fi
@ -303,15 +334,23 @@ case "$1" in
if [ "$SYSTEMCTL_SKIP" == "N" ]; then
systemctl daemon-reload
systemctl start qm.service
if [ "$(systemctl is-active qm.service)" != "active" ]; then
journal=$(journalctl --no-pager -xu qm.service)
echo QM service is not up details:
echo "$journal"
exit 1
fi
systemctl start qm.service || {
logger "ERROR" "'systemctl start qm.service' has failed, see details below";
set +x
logger "DEBUG" "$(journalctl --no-pager -xu qm.service)"
set -x
exit 1;
}
if [ "$(systemctl is-active qm.service)" != "active" ]; then
logger "WARNING" "QM service is inactive, see details below:";
set +x
logger "DEBUG" "$(journalctl --no-pager -xu qm.service)"
set -x
exit 1
fi
else
/usr/libexec/podman/quadlet /run/systemd/generator/
fi
logger "SUCCESS" "Setup complete";
;;
esac

View File

@ -1,7 +1,8 @@
RPM_TOPDIR ?= $(PWD)/rpmbuild
VERSION ?= $(shell cat VERSION)
ROOTDIR ?= $(PWD)
SPECFILE_SUBPACKAGE_VIDEO ?= ${ROOTDIR}/rpm/dvb/dvb.spec
SPECFILE_SUBPACKAGE_DVB ?= ${ROOTDIR}/rpm/dvb/dvb.spec
PACKAGE_NAME = qm-mount-bind-dvb
.PHONY: dist
dist: ## - Creates the QM dvb package
@ -24,4 +25,8 @@ dvb: dist ## - Creates a local RPM package, useful for development
--define="_topdir ${RPM_TOPDIR}" \
--define="version ${VERSION}" \
${SPECFILE_SUBPACKAGE_DVB}
if [ ! -f ${RPM_TOPDIR}/RPMS/noarch/${PACKAGE_NAME}-${VERSION}*.noarch.rpm ]; then \
echo "rpmbuild failed to build: ${PACKAGE_NAME}"; \
exit 1; \
fi

View File

@ -1,33 +0,0 @@
RPM_TOPDIR ?= $(PWD)/rpmbuild
VERSION ?= $(shell cat VERSION)
ROOTDIR ?= $(PWD)
SPECFILE_SUBPACKAGE_IMG_TEMPDIR ?= ${ROOTDIR}/rpm/img_tempdir/img_tempdir.spec
.PHONY: dist
dist: ## - Creates the QM img_tempdir package
cd $(ROOTDIR) && tar cvz \
--dereference \
--transform 's|subsystems/img_tempdir/Makefile|Makefile|' \
--transform 's|rpm/img_tempdir/img_tempdir.spec|img_tempdir.spec|' \
--transform s/qm/qm-img_tempdir-${VERSION}/ \
-f /tmp/qm-img_tempdir-${VERSION}.tar.gz \
../qm/rpm/img_tempdir/img_tempdir.spec \
../qm/subsystems/img_tempdir/Makefile \
../qm/tools/version-update \
../qm/VERSION \
../qm/README.md \
../qm/SECURITY.md \
../qm/LICENSE \
../qm/etc/qm/containers/containers.conf.d/qm_dropin_img_tempdir.conf
cd $(ROOTDIR) && mv /tmp/qm-img_tempdir-${VERSION}.tar.gz ./rpm
.PHONY: img_tempdir
img_tempdir: dist ## - Creates a local RPM package, useful for development
cd $(ROOTDIR) && mkdir -p ${RPM_TOPDIR}/{RPMS,SRPMS,BUILD,SOURCES}
cd $(ROOTDIR) && tools/version-update -v ${VERSION}
cd $(ROOTDIR) && cp ./rpm/qm-img_tempdir-${VERSION}.tar.gz ${RPM_TOPDIR}/SOURCES
rpmbuild -ba \
--define="_topdir ${RPM_TOPDIR}" \
--define="version ${VERSION}" \
${SPECFILE_SUBPACKAGE_IMG_TEMPDIR}

View File

@ -2,6 +2,7 @@ RPM_TOPDIR ?= $(PWD)/rpmbuild
VERSION ?= $(shell cat VERSION)
ROOTDIR ?= $(PWD)
SPECFILE_SUBPACKAGE_INPUT ?= ${ROOTDIR}/rpm/input/input.spec
PACKAGE_NAME = qm-mount-bind-input
.PHONY: dist
dist: ## - Creates the QM input package
@ -24,3 +25,7 @@ input: dist ## - Creates a local RPM package, useful for developmen
--define="_topdir ${RPM_TOPDIR}" \
--define="version ${VERSION}" \
${SPECFILE_SUBPACKAGE_INPUT}
if [ ! -f ${RPM_TOPDIR}/RPMS/noarch/${PACKAGE_NAME}-${VERSION}*.noarch.rpm ]; then \
echo "rpmbuild failed to build: ${PACKAGE_NAME}"; \
exit 1; \
fi

View File

@ -1,18 +0,0 @@
# ContainerFile used to create the image available at quay.io/qm-images/kvm:latest
#
# How to build
# ==================
# podman login quay.io
# use build_kvm_container.sh to build container
# podman push quay.io/qm-images/kvm:latest
FROM fedora-minimal:latest
ENV PASSWORD_FEDORA_USER=fedora
RUN dnf install qemu-system-$(arch) -y \
&& dnf clean all && rm -rf /var/cache/dnf
COPY ./Fedora-Cloud-Base-Generic.qcow2 /var/lib/libvirt/images/
# Set container stay alive
ENTRYPOINT ["/usr/bin/qemu-system-x86_64","-smp","12","-enable-kvm","-m","2G","-machine","q35","-cpu","host","-device","virtio-net-pci,netdev=n0,mac=FE:30:26:a6:91:2d","-netdev","user,id=n0,net=10.0.2.0/24,hostfwd=tcp::2226-:22","-drive","file=/var/lib/libvirt/images/Fedora-Cloud-Base-Generic.qcow2,index=0,media=disk,format=qcow2,if=virtio,snapshot=off","-nographic"]

View File

@ -2,6 +2,7 @@ RPM_TOPDIR ?= $(PWD)/rpmbuild
VERSION ?= $(shell cat VERSION)
ROOTDIR ?= $(PWD)
SPECFILE_SUBPACKAGE_IMG_KVM ?= ${ROOTDIR}/rpm/kvm/qm-kvm.spec
PACKAGE_NAME = qm-kvm
.PHONY: dist
dist: ## - Creates the QM kvm package
@ -18,7 +19,9 @@ dist: ## - Creates the QM kvm package
../qm/README.md \
../qm/SECURITY.md \
../qm/LICENSE \
../qm/etc/containers/systemd/qm.container.d/qm_dropin_mount_bind_kvm.conf
../qm/etc/containers/systemd/qm.container.d/qm_dropin_mount_bind_kvm.conf \
../qm/subsystems/kvm/etc/containers/systemd/kvm.container
cd ${ROOTDIR} && mv /tmp/qm-kvm-${VERSION}.tar.gz ./rpm
.PHONY: kvm
@ -30,4 +33,7 @@ kvm: dist ## - Creates a local RPM kvm package, useful for developme
--define="_topdir ${RPM_TOPDIR}" \
--define="version ${VERSION}" \
${SPECFILE_SUBPACKAGE_IMG_KVM}
if [ ! -f ${RPM_TOPDIR}/RPMS/noarch/${PACKAGE_NAME}-${VERSION}*.noarch.rpm ]; then \
echo "rpmbuild failed to build: ${PACKAGE_NAME}"; \
exit 1; \
fi

View File

@ -1,21 +0,0 @@
#!/usr/bin/bash
# Install required repos
dnf install guestfs-tools \
curl \
perl -y
# Download fedora cloud image
curl -Lo ./Fedora-Cloud-Base-Generic.qcow2 https://download.fedoraproject.org/pub/fedora/linux/releases/41/Cloud/"$(arch)"/images/Fedora-Cloud-Base-Generic-41-1.4."$(arch)".qcow2
# Customize user:pass
export LIBGUESTFS_BACKEND=direct && \
virt-customize -a ./Fedora-Cloud-Base-Generic.qcow2 \
--edit '/etc/ssh/sshd_config: s/#PasswordAuthentication.*/PasswordAuthentication yes/' \
--uninstall cloud-init \
--firstboot-command "useradd -m -s /bin/bash -G wheel fedora" \
--firstboot-command "echo 'fedora:fedora' | chpasswd"
# Container build
podman build -t quay.io/qm-images/kvm:latest -f ContainerFile

View File

@ -4,6 +4,8 @@ After=network.target
[Container]
Image=quay.io/qm-images/kvm:latest
ContainerName=kvm-container
AddDevice=-/dev/kvm
[Install]
WantedBy=multi-user.target

View File

@ -0,0 +1,23 @@
# ContainerFile used to create the image available at quay.io/qm-images/kvm:latest
#
# How to build
# ==================
# podman login quay.io
# use build_kvm_container.sh to build container
# podman push quay.io/qm-images/kvm:latest
FROM fedora-minimal:latest
ARG ARCH_QEMU
ENV PASSWORD_FEDORA_USER=fedora
RUN echo "Using QEMU architecture: ${ARCH_QEMU}"
ENV ARCH_QEMU=${ARCH_QEMU}
RUN dnf install qemu-system-${ARCH_QEMU} -y \
&& dnf clean all && rm -rf /var/cache/dnf
COPY ./Fedora-Cloud-Base-Generic.qcow2 /var/lib/libvirt/images/
# Set container stay alive
ENTRYPOINT ["/bin/sh", "-c", "/usr/bin/qemu-system-${ARCH_QEMU} -smp 8 -enable-kvm -m 700M -machine q35 -cpu host -device virtio-net-pci,netdev=n0,mac=FE:30:26:a6:91:2d -netdev user,id=n0,net=10.0.2.0/24,hostfwd=tcp::2226-:22 -drive file=/var/lib/libvirt/images/Fedora-Cloud-Base-Generic.qcow2,index=0,media=disk,format=qcow2,if=virtio,snapshot=off -nographic"]

View File

@ -0,0 +1,43 @@
#!/usr/bin/bash
# Install required repos
sudo dnf -y install guestfs-tools curl perl qemu-user-static
ARCHS=("amd64" "aarch64")
IMAGE_NAME="kvm"
TAG="latest"
MANIFEST_NAME="${IMAGE_NAME}-manifest:${TAG}"
FEDORA_USER_PASSWORD=${FEDORA_USER_PASSWORD:-$(openssl rand -base64 12)}
#IMG_REG=quay.io
#IMG_ORG=qm-images
rm -f ./Fedora-Cloud-Base-Generic.qcow2
podman manifest rm "$MANIFEST_NAME"
podman manifest create "$MANIFEST_NAME" || exit 1
for ARCH in "${ARCHS[@]}"; do
ARCH_QEMU=$([[ "$ARCH" == "amd64" ]] && echo "x86_64" || echo "$ARCH")
curl -Lo ./Fedora-Cloud-Base-Generic.qcow2 "https://download.fedoraproject.org/pub/fedora/linux/releases/41/Cloud/${ARCH_QEMU}/images/Fedora-Cloud-Base-Generic-41-1.4.${ARCH_QEMU}.qcow2"
# Customize user:pass
export LIBGUESTFS_BACKEND=direct && \
virt-customize -a ./Fedora-Cloud-Base-Generic.qcow2 \
--edit '/etc/ssh/sshd_config: s/#PasswordAuthentication.*/PasswordAuthentication yes/' \
--firstboot-command 'dnf remove -y cloud-init' \
--firstboot-command "useradd -m -s /bin/bash -G wheel fedora" \
--firstboot-command "echo fedora:$FEDORA_USER_PASSWORD | chpasswd"
echo "Adding ${IMAGE_NAME}:${ARCH} to the manifest"
podman build \
--arch "${ARCH}" \
--build-arg ARCH_QEMU="${ARCH_QEMU}" \
--manifest ${MANIFEST_NAME} \
-f ContainerFile \
-t "${IMAGE_NAME}:${ARCH}"
rm -f ./Fedora-Cloud-Base-Generic.qcow2
done
#podman login --username "${REG_USERNAME}" --password "${REG_PASSWORD}" "${REG_URL}"
#podman push localhost/kvm-manifest quay.io/qm-images/kvm:latest

View File

@ -1,7 +1,8 @@
RPM_TOPDIR ?= $(PWD)/rpmbuild
VERSION ?= $(shell cat VERSION)
ROOTDIR ?= $(PWD)
SPECFILE_SUBPACKAGE_VIDEO ?= ${ROOTDIR}/rpm/radio/radio.spec
SPECFILE_SUBPACKAGE_RADIO ?= ${ROOTDIR}/rpm/radio/radio.spec
PACKAGE_NAME = qm-mount-bind-radio
.PHONY: dist
dist: ## - Creates the QM radio package
@ -12,7 +13,7 @@ dist: ## - Creates the QM radio package
../qm/README.md \
../qm/SECURITY.md \
../qm/LICENSE \
../qm/etc/containers/systemd/qm.container.d/qm_dropin_mount_bind_radio.conf
../qm/etc/containers/systemd/qm.container.d/qm_dropin_mount_bind_radio.conf
cd $(ROOTDIR) && mv /tmp/qm-radio-${VERSION}.tar.gz ./rpm
@ -25,4 +26,7 @@ radio: dist ## - Creates a local RPM package, useful for development
--define="_topdir ${RPM_TOPDIR}" \
--define="version ${VERSION}" \
${SPECFILE_SUBPACKAGE_RADIO}
if [ ! -f ${RPM_TOPDIR}/RPMS/noarch/${PACKAGE_NAME}-${VERSION}*.noarch.rpm ]; then \
echo "rpmbuild failed to build: ${PACKAGE_NAME}"; \
exit 1; \
fi

View File

@ -2,6 +2,7 @@ RPM_TOPDIR ?= $(PWD)/rpmbuild
VERSION ?= $(shell cat VERSION)
ROOTDIR ?= $(PWD)
SPECFILE_SUBPACKAGE_ROS2_ROLLING ?= ${ROOTDIR}/rpm/ros2/ros2_rolling.spec
PACKAGE_NAME = qm-ros2
.PHONY: dist
dist: ## - Creates the QM ros2 package
@ -18,7 +19,7 @@ dist: ## - Creates the QM ros2 package
../qm/README.md \
../qm/SECURITY.md \
../qm/LICENSE \
../qm/subsystems/ros2/etc/containers/systemd/ros2-rolling.container
../qm/subsystems/ros2/etc/containers/systemd/ros2.container
cd $(ROOTDIR) && mv /tmp/qm-ros2-${VERSION}.tar.gz ./rpm
@ -31,4 +32,7 @@ ros2: dist ## - Creates a local RPM package, useful for development
--define="_topdir ${RPM_TOPDIR}" \
--define="version ${VERSION}" \
${SPECFILE_SUBPACKAGE_ROS2_ROLLING}
if [ ! -f ${RPM_TOPDIR}/RPMS/noarch/${PACKAGE_NAME}-${VERSION}*.noarch.rpm ]; then \
echo "rpmbuild failed to build: ${PACKAGE_NAME}"; \
exit 1; \
fi

View File

@ -3,7 +3,8 @@ Description=ROS 2 Container Development env
After=network.target
[Container]
Image=quay.io/qm-images/ros2:rolling
Image=quay.io/fedora-sig-robotics/ros2:jazzy-cs9
Exec=sleep infinity
[Install]
WantedBy=multi-user.target

View File

@ -2,18 +2,25 @@ RPM_TOPDIR ?= $(PWD)/rpmbuild
VERSION ?= $(shell cat VERSION)
ROOTDIR ?= $(PWD)
SPECFILE_SUBPACKAGE_SOUND ?= ${ROOTDIR}/rpm/sound/sound.spec
PACKAGE_NAME = qm-sound
.PHONY: dist
dist: ## - Creates the QM sound package
cd $(ROOTDIR) && tar cvz \
--dereference \
--transform s/qm/qm-sound-${VERSION}/ \
--transform 's|subsystems/kvm/Makefile|Makefile|' \
--transform 's|rpm/sound/sound.spec|qm-sound.spec|' \
--transform 's|qm|qm-sound-${VERSION}|' \
-f /tmp/qm-sound-${VERSION}.tar.gz \
../qm/rpm/sound/sound.spec \
../qm/subsystems/sound/Makefile \
../qm/tools/version-update \
../qm/README.md \
../qm/SECURITY.md \
../qm/LICENSE \
../qm/etc/containers/systemd/qm.container.d/qm_dropin_mount_bind_snd.conf \
../qm/subsystems/sound/etc/containers/systemd/audio.container
cd $(ROOTDIR) && mv /tmp/qm-sound-${VERSION}.tar.gz ./rpm
.PHONY: sound
@ -25,4 +32,7 @@ sound: dist ## - Creates a local RPM package, useful for development
--define="_topdir ${RPM_TOPDIR}" \
--define="version ${VERSION}" \
${SPECFILE_SUBPACKAGE_SOUND}
if [ ! -f ${RPM_TOPDIR}/RPMS/noarch/${PACKAGE_NAME}-${VERSION}*.noarch.rpm ]; then \
echo "rpmbuild failed to build: ${PACKAGE_NAME}"; \
exit 1; \
fi

View File

@ -4,6 +4,8 @@ After=network.target
[Container]
Image=quay.io/qm-images/audio:latest
Network=host
AddDevice=/dev/snd
[Install]
WantedBy=multi-user.target
WantedBy=multi-user.target

View File

@ -2,6 +2,7 @@ RPM_TOPDIR ?= $(PWD)/rpmbuild
VERSION ?= $(shell cat VERSION)
ROOTDIR ?= $(PWD)
SPECFILE_SUBPACKAGE_TEXT2SPEECH ?= ${ROOTDIR}/rpm/text2speech/text2speech.spec
PACKAGE_NAME = qm-text2speech
.PHONY: dist
dist: ## - Creates the QM input package
@ -30,3 +31,7 @@ text2speech: dist ## - Creates a local RPM package, useful for develo
--define="_topdir ${RPM_TOPDIR}" \
--define="version ${VERSION}" \
${SPECFILE_SUBPACKAGE_TEXT2SPEECH}
if [ ! -f ${RPM_TOPDIR}/RPMS/noarch/${PACKAGE_NAME}-${VERSION}*.noarch.rpm ]; then \
echo "rpmbuild failed to build: ${PACKAGE_NAME}"; \
exit 1; \
fi

View File

@ -2,6 +2,7 @@ RPM_TOPDIR ?= $(PWD)/rpmbuild
VERSION ?= $(shell cat VERSION)
ROOTDIR ?= $(PWD)
SPECFILE_SUBPACKAGE_TTY7 ?= ${ROOTDIR}/rpm/tty7/tty7.spec
PACKAGE_NAME = qm-mount-bind-tty7
.PHONY: dist
dist: ## - Creates the QM tty7 package
@ -30,4 +31,7 @@ tty7: dist ## - Creates a local RPM package, useful for development
--define="_topdir ${RPM_TOPDIR}" \
--define="version ${VERSION}" \
${SPECFILE_SUBPACKAGE_TTY7}
if [ ! -f ${RPM_TOPDIR}/RPMS/noarch/${PACKAGE_NAME}-${VERSION}*.noarch.rpm ]; then \
echo "rpmbuild failed to build: ${PACKAGE_NAME}"; \
exit 1; \
fi

View File

@ -2,6 +2,7 @@ RPM_TOPDIR ?= $(PWD)/rpmbuild
VERSION ?= $(shell cat VERSION)
ROOTDIR ?= $(PWD)
SPECFILE_SUBPACKAGE_TTYUSB0 ?= ${ROOTDIR}/rpm/ttyUSB0/ttyUSB0.spec
PACKAGE_NAME = qm-mount-bind-ttyUSB0
.PHONY: dist
dist: ## - Creates the QM ttyUSB0 package
@ -30,4 +31,7 @@ ttyUSB0: dist ## - Creates a local RPM package, useful for developme
--define="_topdir ${RPM_TOPDIR}" \
--define="version ${VERSION}" \
${SPECFILE_SUBPACKAGE_TTYUSB0}
if [ ! -f ${RPM_TOPDIR}/RPMS/noarch/${PACKAGE_NAME}-${VERSION}*.noarch.rpm ]; then \
echo "rpmbuild failed to build: ${PACKAGE_NAME}"; \
exit 1; \
fi

View File

@ -2,6 +2,7 @@ RPM_TOPDIR ?= $(PWD)/rpmbuild
VERSION ?= $(shell cat VERSION)
ROOTDIR ?= $(PWD)
SPECFILE_SUBPACKAGE_VIDEO ?= ${ROOTDIR}/rpm/video/video.spec
PACKAGE_NAME = qm-mount-bind-video
.PHONY: dist
dist: ## - Creates the QM video package
@ -31,4 +32,7 @@ video: dist ## - Creates a local RPM package, useful for development
--define="_topdir ${RPM_TOPDIR}" \
--define="version ${VERSION}" \
${SPECFILE_SUBPACKAGE_VIDEO}
if [ ! -f ${RPM_TOPDIR}/RPMS/noarch/${PACKAGE_NAME}-${VERSION}*.noarch.rpm ]; then \
echo "rpmbuild failed to build: ${PACKAGE_NAME}"; \
exit 1; \
fi

View File

@ -12,4 +12,5 @@ WantedBy=multi-user.target
[Container]
Image=quay.io/qm-images/multimedia:latest
Exec=fswebcam -r 1024x768 --jpeg 100 /tmp/screenshot.jpg
Volume=/tmp:/tmp
Volume=/var/tmp:/tmp:Z
AddDevice=-/dev/video0

View File

@ -2,6 +2,7 @@ RPM_TOPDIR ?= $(PWD)/rpmbuild
VERSION ?= $(shell cat VERSION)
ROOTDIR ?= $(PWD)
SPECFILE_SUBPACKAGE_IMG_WINDOWMANAGER ?= ${ROOTDIR}/rpm/windowmanager/windowmanager.spec
PACKAGE_NAME = qm-windowmanager
.PHONY: dist
dist: ## - Creates the QM windowmanager package
@ -28,4 +29,7 @@ windowmanager: dist ## - Creates a local windowmanager package, useful f
--define="_topdir ${RPM_TOPDIR}" \
--define="version ${VERSION}" \
${SPECFILE_SUBPACKAGE_IMG_WINDOWMANAGER}
if [ ! -f ${RPM_TOPDIR}/RPMS/noarch/${PACKAGE_NAME}-${VERSION}*.noarch.rpm ]; then \
echo "rpmbuild failed to build: ${PACKAGE_NAME}"; \
exit 1; \
fi

View File

@ -9,6 +9,6 @@ COPR_URL="https://download.copr.fedorainfracloud.org/results/${USE_QM_COPR}/epel
EXTRA_REPOS='extra_repos=[{"id":"qm_build","baseurl":"'"$COPR_URL"'"}]'
# Run AIB in container
curl -o auto-image-builder.sh "https://gitlab.com/CentOS/automotive/sample-images/-/raw/main/auto-image-builder.sh?ref_type=heads"
curl -o auto-image-builder.sh "https://gitlab.com/CentOS/automotive/src/automotive-image-builder/-/raw/main/auto-image-builder.sh?ref_type=heads"
#shellcheck disable=SC2027,SC2090,SC2086
/bin/bash auto-image-builder.sh build --export qcow2 --define "'"$EXTRA_REPOS"'" qm.aib.yml qm.qcow2

View File

@ -74,7 +74,7 @@ install_qm_rpms() {
fi
fi
dnf install -y bluechi-ctl bluechi-agent bluechi-controller qm hostname
dnf install -y bluechi-ctl bluechi-agent bluechi-controller bluechi-is-online qm hostname
}
set_qm_rlimits() {

View File

@ -51,8 +51,8 @@ ${container_target}:/tmp/container-${srv}.container"
target_service_file=$(podman exec ${container_target} systemctl show -P SourcePath qm.service)
# START: remove DropCapability to run nested container
# TBD: use drop-in files to update qm.service
podman exec -it ${container_target} bash -c "sed -i '/^\s*DropCapability=sys_resource/ d' \"${target_service_file}\""
if_error_exit "unable to remove DropCapability=sys_resource in qm.container"
podman exec -it ${container_target} bash -c "sed -i '/^\s*DropCapability=/ d' \"${target_service_file}\""
if_error_exit "unable to remove DropCapability=<caps> in qm.container"
podman exec -it ${container_target} systemctl daemon-reload
if_error_exit "unable to execute daemon-reload"

View File

@ -1,3 +1,4 @@
#define _GNU_SOURCE
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
@ -5,24 +6,55 @@
#include <errno.h>
#include <string.h>
int main() {
int main(int argc, char *argv[]) {
int pid = getpid();
int policy = SCHED_FIFO; // Desired scheduling policy
int policy; // Desired scheduling policy
char *policy_name;
struct sched_param param;
// Assign the maximum priority for the SCHED_FIFO policy
if (argc == 2)
{
policy_name = argv[1];
if (strcmp(policy_name, "SCHED_OTHER")==0) {
policy = SCHED_OTHER;
} else if (strcmp(policy_name, "SCHED_BATCH")==0) {
policy = SCHED_BATCH;
} else if (strcmp(policy_name, "SCHED_IDLE")==0) {
policy = SCHED_IDLE;
} else if (strcmp(policy_name, "SCHED_FIFO")==0) {
policy = SCHED_FIFO;
} else if (strcmp(policy_name, "SCHED_RR")==0) {
policy = SCHED_RR;
} else {
printf("Unknown policy.\n");
return EXIT_FAILURE;
}
}
else if (argc > 2)
{
printf("Too many policies supplied.\n");
return EXIT_FAILURE;
}
else
{
printf("One policy expected.\n");
return EXIT_FAILURE;
}
// Assign the maximum priority for the policy
param.sched_priority = sched_get_priority_max(policy);
if (param.sched_priority == -1) {
fprintf(stderr, "Failed to get max priority for SCHED_FIFO: %s\n", strerror(errno));
fprintf(stderr, "Failed to get max priority for %s: %s\n", policy_name, strerror(errno));
return EXIT_FAILURE;
}
// Attempt to set the scheduling policy and priority
if (sched_setscheduler(pid, policy, &param) == -1) {
fprintf(stderr, "Failed to set scheduler: %s\n", strerror(errno));
printf("sched_setscheduler(%s) failed: errno=%d (%s)", policy_name, errno, strerror(errno));
return EXIT_FAILURE;
} else {
printf("sched_setscheduler(%s) succeeded.", policy_name);
return EXIT_SUCCESS;
}
printf("Scheduler set to SCHED_FIFO with priority %d\n", param.sched_priority);
return EXIT_SUCCESS;
}

View File

@ -10,8 +10,6 @@ fi
. ../common/prepare.sh
export QM_HOST_REGISTRY_DIR="/var/qm/lib/containers/registry"
export QM_REGISTRY_DIR="/var/lib/containers/registry"
export NUMBER_OF_NODES="${NUMBER_OF_NODES:-2}"
WAIT_BLUECHI_AGENT_CONNECT="${WAIT_BLUECHI_AGENT_CONNECT:-5}"
@ -26,12 +24,13 @@ Description=bluechi-tester-X
After=local-fs.target
[Container]
Image=dir:/var/lib/containers/registry/tools-ffi:latest
Image=quay.io/centos-sig-automotive/ffi-tools:latest
Exec=/root/tests/FFI/bin/bluechi-tester --url="tcp:host=${controller_host_ip},port=842" \
--nodename=bluechi-tester-X \
--numbersignals=11111111 \
--signal="JobDone"
Network=host
StopTimeout=1
EOF
sed -i -e "s/tester-X/tester-${i}/g" "/etc/qm/containers/systemd/bluechi-tester-${i}.container"
@ -79,8 +78,9 @@ get_qm_network_mode(){
echo "${qm_network_mode}"
}
init_ffi
prepare_images
trap disk_cleanup EXIT
prepare_test
reload_config
# Assign value to ${controller_host_ip} according to qm network mode
if [ "$(get_qm_network_mode)" == "private" ]; then

View File

@ -0,0 +1,16 @@
[Unit]
Description=Container ffi-tools with precompiled checks
After=local-fs.target
[Container]
ContainerName=ffi-qm
Image=quay.io/centos-sig-automotive/ffi-tools:latest
Exec=sleep infinity
StopTimeout=1
[Install]
# Start by default on qm boot
WantedBy=multi-user.target default.target
[Service]
Restart=always

View File

@ -2,13 +2,8 @@
# shellcheck disable=SC1091
. ../../e2e/lib/utils
DROP_IN_DIR="/etc/containers/systemd/qm.container.d/"
export DROP_IN_DIR="/etc/containers/systemd/qm.container.d/"
OSTREE_PATH="/run/ostree"
export QM_HOST_REGISTRY_DIR="/var/qm/lib/containers/registry"
export QM_REGISTRY_DIR="/var/lib/containers/registry"
export QM_TMP_DIR="/var/tmp.dir"
export CONTAINERS_CONF_DIR="/etc/qm/containers/containers.conf.d"
export QM_IMAGE_TMP_DIR_CONF="qm_image_tmp_dir.conf"
# Checks if the system is running under OSTree.
# This function determines if the system is using OSTree by checking for the
@ -38,12 +33,12 @@ prepare_test() {
}
disk_cleanup() {
exec_cmd "podman exec -it qm /bin/bash -c \"podman rmi -f --all\""
# Clean large size files created by tests inside qm part
remove_file=$(find /var/qm -size +2G)
exec_cmd "rm -rf $remove_file"
# Clean drop-in files used for tests
if test -d "${DROP_IN_DIR=}"; then
# Remove all containers in qm (don't care about stop in clean-up)
exec_cmd "podman exec -it qm /usr/bin/podman rm -af"
if test -d "${DROP_IN_DIR}"; then
exec_cmd "rm -rf ${DROP_IN_DIR}"
fi
exec_cmd "systemctl daemon-reload"
@ -58,60 +53,13 @@ reload_config() {
exec_cmd "systemctl restart qm"
}
prepare_images() {
# Update container image_copy_tmp_dir if the image is an OStree.
# Default location for storing temporary container image content. Can be overridden with the TMPDIR environment
# variable. If you specify "storage", then the location of the
# container/storage tmp directory will be used.
# By default image_copy_tmp_dir="/var/tmp"
# This is a work around and it should not be used constantly
# This script checks if the directory /run/ostree exists.
# If it does, it executes the following commands:
# 1. Creates the directory /var/qm/tmp.dir if it does not already exist.
# 2. Creates the directory /etc/qm/containers/containers.conf.d if it does not already exist.
# 3. Writes a configuration file qm_image_tmp_dir.conf in /etc/qm/containers/containers.conf.d
# with the content specifying the temporary directory for image copying as /var/tmp.dir.
if is_ostree; then
exec_cmd "mkdir -p /var/qm/tmp.dir"
exec_cmd "mkdir -p ${CONTAINERS_CONF_DIR}"
exec_cmd "echo -e '[engine]\nimage_copy_tmp_dir=\"${QM_TMP_DIR}\"' > ${CONTAINERS_CONF_DIR}/${QM_IMAGE_TMP_DIR_CONF}"
fi
exec_cmd "podman pull quay.io/centos-sig-automotive/ffi-tools:latest"
# Copy container image registry to /var/qm/lib/containers
image_id=$(podman images | grep quay.io/centos-sig-automotive/ffi-tools | awk -F " " '{print $3}')
if [ -d "${QM_HOST_REGISTRY_DIR}" ]; then
rm -rf ${QM_HOST_REGISTRY_DIR}
fi
exec_cmd "mkdir -p ${QM_HOST_REGISTRY_DIR}"
exec_cmd "podman push ${image_id} dir:${QM_HOST_REGISTRY_DIR}/tools-ffi:latest"
# Remove image to save /var space
exec_cmd "podman rmi -f ${image_id}"
}
run_container_in_qm() {
local container_name
local tmp_image_dir
local run_ctr_in_qm
# Clean tmp image directory
tmp_image_dir=$(podman info | grep CopyTmp | awk -F":" '{print $2}')
container_name="${1}"
exec_cmd "podman exec -it qm /bin/bash -c \
\"rm -rf ${tmp_image_dir}/*\""
run_ctr_in_qm="podman exec -it qm /bin/bash -c \
\"podman run -d --net host --replace --name ${container_name} \
dir:${QM_REGISTRY_DIR}/tools-ffi:latest \
tail -f /dev/null\""
exec_cmd "${run_ctr_in_qm}"
}
# Agregates 3 functions from this tool to a single init_ffi function, used to initialize environments before tests with a single function, instead of using three separate functions.
init_ffi() {
disk_cleanup
prepare_test
reload_config
running_container_in_qm() {
while true; do
if podman exec qm /usr/bin/systemctl is-active ffi-qm -q; then
info_message "ffi-qm container inside qm is fully started"
break
fi
sleep 1
done
info_message "qm was started: $(systemctl status qm | grep Active | cut -d ';' -f 2)"
}

View File

@ -5,20 +5,18 @@
expected_result="sched_setattr failed: Operation not permitted"
disk_cleanup
trap disk_cleanup EXIT
prepare_test
reload_config
prepare_images
run_container_in_qm "ffi-qm"
running_container_in_qm
return_from_sched_setattr=$(podman exec -it qm /bin/bash -c \
'podman exec -it ffi-qm ./QM/execute_sched_setattr')
return_from_sched_setattr=$(podman exec -it qm /usr/bin/podman exec -it ffi-qm ./QM/execute_sched_setattr)
# shellcheck disable=SC2076
if [[ "${return_from_sched_setattr}" =~ "${expected_result}" ]]; then
info_message "QM not allow SCHED_DEADLINE be set via sched_setattr() syscall."
info_message "PASS: QM not allow SCHED_DEADLINE be set via sched_setattr() syscall."
else
info_message "Failure: SCHED_DEADLINE can not be set via sched_setattr() syscall in QM."
info_message "FAIL: SCHED_DEADLINE can not be set via sched_setattr() syscall in QM."
exit 1
fi

View File

@ -3,21 +3,44 @@
# shellcheck source=tests/ffi/common/prepare.sh
. ../common/prepare.sh
expected_result="Failed to set scheduler: Operation not permitted"
policy_arr=(SCHED_OTHER SCHED_BATCH SCHED_IDLE SCHED_FIFO SCHED_RR)
num_of_failed_policy=0
disk_cleanup
trap disk_cleanup EXIT
prepare_test
reload_config
prepare_images
run_container_in_qm "ffi-qm"
running_container_in_qm
# Copy the test from ffi-qm container to qm container
podman exec -it qm /usr/bin/podman cp ffi-qm:/root/tests/FFI/bin/QM/test_sched_setscheduler /var/
return_from_setscheduler=$(podman exec -it qm /bin/bash -c \
'podman exec -it ffi-qm ./QM/test_sched_setscheduler')
for policy in "${policy_arr[@]}"; do
# Run the test inside qm container
return_from_setscheduler=$(podman exec -it qm ./var/test_sched_setscheduler "$policy")
if [[ "${return_from_setscheduler}" =~ ${expected_result} ]]; then
info_message "set_scheduler() syscall denied in QM."
else
info_message "set_scheduler() syscall can be executed in QM."
# Assign the expected result according to the policy
if [[ "$policy" == "SCHED_OTHER" || "$policy" == "SCHED_BATCH" || "$policy" == "SCHED_IDLE" ]]; then
expected_result="sched_setscheduler($policy) succeeded."
elif [[ "$policy" == "SCHED_FIFO" || "$policy" == "SCHED_RR" ]]; then
expected_result="sched_setscheduler($policy) failed: errno=38 (Function not implemented)"
fi
# Check that the result is the same as expected
if [[ "${return_from_setscheduler}" == "${expected_result}" ]]; then
info_message "$expected_result"
info_message "PASS: The result of sched_setscheduler($policy) is as expected in QM."
else
info_message "$return_from_setscheduler"
info_message "FAIL: The result of sched_setscheduler($policy) is not what is expected in QM."
((num_of_failed_policy++))
fi
done
# If there is a failed policy, then this test returns failure
if [[ $num_of_failed_policy -gt 0 ]]; then
info_message "FAIL: sched_setscheduler() test failed."
exit 1
else
info_message "PASS: sched_setscheduler() test passed."
exit 0
fi

View File

@ -1,4 +1,4 @@
summary: Test is calling systemd as stand alone test
summary: Test for separate var partition for qm
test: /bin/bash ./test.sh
duration: 10m
tag: [ffi, NoRenesas]

View File

@ -5,46 +5,57 @@
. ../common/prepare.sh
check_var_partition(){
name_of_qm_var_partition="part /var/qm"
# In the ostree image
if stat /run/ostree-booted > /dev/null 2>&1; then
qm_var_partition="part /var"
name_of_qm_var_partition="part /var"
else
qm_var_partition="part /usr/lib/qm/rootfs/var"
# In the centos cloud image
local release_id
release_id=$(grep -oP '(?<=^ID=)\w+' <<< "$(tr -d '"' < /etc/os-release)")
if [[ "$release_id" == "centos" ]]; then
name_of_qm_var_partition="part /usr/lib/qm/rootfs/var"
fi
fi
if [[ "$(lsblk -o 'MAJ:MIN,TYPE,MOUNTPOINTS')" =~ ${qm_var_partition} ]]; then
# Prints all available block devices to make it easier to debug
exec_cmd "lsblk"
exec_cmd "df -kh"
# If there is no separate /var partition this test will terminate early
if [[ "$(lsblk -o 'MAJ:MIN,TYPE,MOUNTPOINTS')" =~ ${name_of_qm_var_partition} ]]; then
info_message "A separate /var partition was detected on the image."
else
lsblk
df -kh
info_message "FAIL: No separate /var partition was detected on the image."
info_message "Test terminated, it requires a separate /var disk partition for QM to run this test."
exit 1
fi
}
set_PodmanArgs(){
podmanArgs_of_qm=$(grep "PodmanArgs" /usr/share/containers/systemd/qm.container)
if [ -n "$podmanArgs_of_qm" ]; then
podmanArgs_of_qm=$podmanArgs_of_qm" --memory 5G"
else
podmanArgs_of_qm="--memory 5G"
fi
}
check_var_partition
disk_cleanup
trap disk_cleanup EXIT
prepare_test
set_PodmanArgs
cat << EOF > "${DROP_IN_DIR}"/oom.conf
[Service]
OOMScoreAdjust=
OOMScoreAdjust=1000
[Container]
PodmanArgs=
PodmanArgs=--pids-limit=-1 --security-opt seccomp=/usr/share/qm/seccomp-no-rt.json --security-opt label=nested --security-opt unmask=all --memory 5G
PodmanArgs=${podmanArgs_of_qm}
EOF
reload_config
prepare_images
exec_cmd "podman exec -it qm /bin/bash -c \
'podman run -d --replace --name ffi-qm \
quay.io/centos-sig-automotive/ffi-tools:latest \
tail -f /dev/null'"
running_container_in_qm
exec_cmd "podman exec -it qm /bin/bash -c \
'podman exec -it ffi-qm ./QM/file-allocate'"

View File

@ -6,3 +6,4 @@ require:
pattern:
- /tests/e2e/lib/utils
- /tests/ffi/common/prepare.sh
- /tests/ffi/common/ffi-qm.container

View File

@ -1,4 +1,4 @@
summary: Test is calling systemd as stand alone test
summary: Test kernel OOM kills qm container on high score processes
test: /bin/bash ./test.sh
duration: 25m
tag: ffi

View File

@ -4,27 +4,19 @@
. ../common/prepare.sh
disk_cleanup
trap disk_cleanup EXIT
prepare_test
cat << EOF > "${DROP_IN_DIR}"/oom.conf
[Service]
OOMScoreAdjust=
OOMScoreAdjust=1000
EOF
reload_config
prepare_images
exec_cmd "podman run -d --rm --replace -d --name ffi-asil \
quay.io/centos-sig-automotive/ffi-tools:latest \
./ASIL/20_percent_memory_eat > /dev/null"
podman exec -it qm /bin/bash -c \
"podman run --replace --name ffi-qm dir:${QM_REGISTRY_DIR}/tools-ffi:latest \
./QM/90_percent_memory_eat > /dev/null"
reload_config
running_container_in_qm
podman exec qm podman exec ffi-qm ./QM/90_percent_memory_eat > /dev/null
if [ $? -eq 137 ]; then
echo ffi-qm was killed by SIGKILL
info_message "ffi-qm was killed by SIGKILL"
fi
exec_cmd "systemctl status qm --no-pager | grep \"qm.service: A process of this unit has been killed\""

View File

@ -1,22 +1,20 @@
#!/bin/bash -euvx
#!/bin/bash -uvx
# shellcheck disable=SC1091
. ../common/prepare.sh
disk_cleanup
trap disk_cleanup EXIT
prepare_test
reload_config
# Download ffi-tools container and push ffi-tools image into QM registry
prepare_images
# Run the ffi-tools container in qm vm
run_container_in_qm ffi-qm
running_container_in_qm
# Get result message of './modprobe_module'
msg=$(podman exec -it qm /bin/bash -c \
"podman exec ffi-qm ./modprobe_module 2>&1")
msg=$(podman exec -it qm /usr/bin/podman exec -it ffi-qm ./modprobe_module 2>&1)
info_message "Output is: $msg"
# Check result message displays right.
if grep -eq "modprobe: FATAL: Module ext4 not found in directory /lib/modules/*" "$msg"; then

View File

@ -16,10 +16,9 @@
. ../common/prepare.sh
disk_cleanup
trap disk_cleanup EXIT
prepare_test
reload_config
prepare_images
# Function to retrieve the PID with retries for a container
get_pid_with_retries() {
@ -54,8 +53,7 @@ get_oom_score_adj() {
}
# Start the FFI container inside qm
podman exec -it qm /bin/bash -c \
"podman run -d --replace --name ffi-qm dir:${QM_REGISTRY_DIR}/tools-ffi:latest /usr/bin/sleep infinity > /dev/null"
running_container_in_qm
# Check if ffi-qm container started successfully
QM_FFI_STATUS=$(podman exec -it qm /bin/bash -c "podman inspect ffi-qm --format '{{.State.Status}}'" | tr -d '\r')

View File

@ -3,8 +3,9 @@
# shellcheck disable=SC1091
. ../common/prepare.sh
# init_ffi uses 3in1 function from common.sh to initialize the environment before tests.
init_ffi
trap disk_cleanup EXIT
prepare_test
reload_config
# Declare global variables and initialize to "".
NESTED_NAME=""
@ -17,9 +18,8 @@ NESTED_STATUS=""
# NESTED_NAME: The nested container name in the QM container.
# NESTED_STATUS: The nested container status in the QM container.
create_nested() {
prepare_images
local nested_container_name="ffi-qm"
run_container_in_qm "${nested_container_name}"
running_container_in_qm
NESTED_NAME=$(podman exec -it qm bash -c "podman inspect ${nested_container_name} --format '{{.Name}}'")
if_error_exit "An error occured: failed to extract Name parameter of container from inside of QM."
echo "Container name is: ${NESTED_NAME}"

View File

@ -4,19 +4,15 @@
. ../common/prepare.sh
disk_cleanup
trap disk_cleanup EXIT
prepare_test
reload_config
# Download ffi-tools container and push ffi-tools image into QM registry
prepare_images
# Run the ffi-tools container in qm vm
run_container_in_qm ffi-qm
running_container_in_qm
# Get numbers of sysctl permission denied
sysctl_num=$(podman exec qm /bin/bash -c \
"podman exec ffi-qm ./setsysctl 2>&1" | grep -c "sysctl: permission denied on key")
sysctl_num=$(podman exec qm /usr/bin/podman exec ffi-qm ./setsysctl 2>&1 | grep -c "sysctl: permission denied on key")
# We execute 'X' sysctl call(s) inside a nested container running in a QM environment
# to determine if changes are allowed, which should be denied for:
@ -24,6 +20,6 @@ sysctl_num=$(podman exec qm /bin/bash -c \
# - Virtual memory subsystem
SYSCTL_DENIED_COUNT=5
if [ "$sysctl_num" -eq "${SYSCTL_DENIED_COUNT}" ];then
info_message "Attempt to change OS level are denied successfully inside QM container."
info_message "PASS: Attempt to change OS level are denied successfully inside QM container."
exit 0
fi

View File

@ -0,0 +1,7 @@
summary: Test libkrun in qm
test: /bin/bash ./check_libkrun.sh
duration: 10m
tier: 0
tag: [kvm,setup]
framework: shell

View File

@ -0,0 +1,26 @@
#!/bin/bash -x
# shellcheck disable=SC1091
source ../../e2e/lib/utils
enable_repo() {
info_message "enable_repo(): enable repo"
exec_cmd "cd /etc/yum.repos.d/"
exec_cmd "dnf copr enable -y copr.fedorainfracloud.org/@centos-automotive-sig/libkrun centos-stream-9-$(arch)"
}
install_libkrun() {
info_message "install_libkrun(): install libkrun and crun-krun"
exec_cmd "dnf install --setopt=reposdir=/etc/yum.repos.d --installroot=/usr/lib/qm/rootfs -y libkrun crun-krun"
}
check_libkrun() {
info_message "check_libkrun(): run virtualization-isolated containers."
exec_cmd "podman exec -it qm podman run --runtime=krun --rm -it alpine echo 'Hello libkrun.'"
info_message "PASS: libkrun runs successfully."
}
enable_repo
install_libkrun
check_libkrun

View File

@ -1,6 +0,0 @@
summary: Test bluechi-controller is active and bluechi-agent is online
test: /bin/bash ./check_bluechi_controller_is_ok.sh
duration: 10m
tier: 0
framework: shell
id: 44d1f92b-2885-49d3-900a-23cde296c9d8

View File

@ -1,33 +0,0 @@
#!/bin/bash -euvx
# shellcheck disable=SC1091
source ../e2e/lib/utils
# Verify bluechi-controller is up and bluechictl is ok
check_bluechi_controller_is_ok(){
if [ "$(systemctl is-active bluechi-controller)" == "active" ]; then
info_message "check_bluechi_controller_is_ok(): bluechi-controller is active."
info_message "PASS: check_bluechi_controller_is_ok()"
else
info_message "FAIL: check_bluechi_controller_is_ok(): bluechi-controller is not active."
exit 1
fi
regex_qm_localrootfs="qm.localrootfs * \| online"
regex_ASIL_localrootfs="localrootfs * \| online"
if [[ ! "$(bluechictl status)" =~ ${regex_qm_localrootfs} ]]; then
info_message "FAIL: check_bluechi_controller_is_ok: Checking QM bluechi-agent online failed.\n $(bluechictl status)"
exit 1
elif [[ ! "$(bluechictl status)" =~ ${regex_ASIL_localrootfs} ]]; then
info_message "FAIL: check_bluechi_controller_is_ok: Checking host bluechi-agent online failed.\n $(bluechictl status)"
exit 1
else
info_message "check_bluechi_controller_is_ok: QM bluechi-agent is online."
info_message "check_bluechi_controller_is_ok: host bluechi-agent is online."
info_message "PASS: check_bluechi_controller_is_ok()"
exit 0
fi
}
check_bluechi_controller_is_ok

View File

@ -3,25 +3,38 @@
# shellcheck disable=SC1091
source ../e2e/lib/utils
print_journal_for_bluechi() {
info_message "Journal for bluechi-controller:\n"
journalctl -r -u bluechi-controller -n 100
info_message "Journal for local bluechi-agent:\n"
journalctl -r -u bluechi-agent -n 100
info_message "Journal for qm bluechi-agent:\n"
journalctl -r -u qm -n 100
}
# Verify bluechi nodes are connected
check_bluechi_is_ok(){
bluechi_controller_status=$(systemctl status bluechi-controller | tail -2)
regex_ASIL_bluechi_agent="Registered managed node from fd [0-9]{1,2} as 'localrootfs'"
regex_QM_bluechi_agent="Registered managed node from fd [0-9]{1,2} as 'qm.localrootfs'"
LOCAL=localrootfs
LOCAL_QM=qm.localrootfs
if [[ ! "${bluechi_controller_status}" =~ ${regex_ASIL_bluechi_agent} ]]; then
info_message "FAIL: check_bluechi_is_ok: host bluechi-agent is not connected to controller.\n ${bluechi_controller_status}"
if ! bluechi-is-online node "${LOCAL}" --wait=5000; then
info_message "FAIL: check_bluechi_is_ok: host bluechi-agent ${LOCAL} is not connected to controller."
print_journal_for_bluechi
exit 1
elif [[ ! "${bluechi_controller_status}" =~ ${regex_QM_bluechi_agent} ]]; then
info_message "FAIL: check_bluechi_is_ok: QM bluechi-agent is not connected to controller.\n ${bluechi_controller_status}"
exit 1
else
info_message "check_bluechi_is_ok: host bluechi-agent is connected to controller."
info_message "check_bluechi_is_ok: QM bluechi-agent is connected to controller."
info_message "PASS: check_bluechi_is_ok()"
exit 0
fi
if ! bluechi-is-online node "${LOCAL_QM}" --wait=5000; then
info_message "FAIL: check_bluechi_is_ok: qm bluechi-agent ${LOCAL_QM} is not connected to controller."
print_journal_for_bluechi
exit 1
fi
info_message "check_bluechi_is_ok: host bluechi-agent is connected to controller."
info_message "check_bluechi_is_ok: QM bluechi-agent is connected to controller."
info_message "PASS: check_bluechi_is_ok()"
exit 0
}
check_bluechi_is_ok

View File

@ -0,0 +1 @@
output: This is the file to copy

View File

@ -0,0 +1 @@
This is the file to copy

View File

@ -0,0 +1,7 @@
summary: Test plan for QMCTL using TMT
test: ./test_qmctl.sh
duration: 10m
tag: qmctl-test
tier: 0
framework: shell
id: 9b3f962e-758a-473b-b8ea-540a177b9134

View File

@ -0,0 +1,22 @@
#!/bin/bash
# shellcheck disable=SC1091
. ../e2e/lib/utils
QMCTL_SCRIPT="../../tools/qmctl/qmctl"
python3 $QMCTL_SCRIPT cp ./files/file-to-copy.txt qm:/tmp
expected_output_file="./files/file-to-check-cp.txt"
actual_output_temp_file=$(mktemp)
python3 $QMCTL_SCRIPT exec cat /tmp/file-to-copy.txt > "$actual_output_temp_file"
if diff "$actual_output_temp_file" "$expected_output_file" > /dev/null; then
info_message "The output matches the content of '$expected_output_file'."
info_message "PASS: qmctl cp command executed successfully"
exit 0
else
echo "FAIL: The output does NOT match the content of '$expected_output_file'."
exit 1
fi

Some files were not shown because too many files have changed in this diff Show More