mirror of https://github.com/containers/qm.git
Compare commits
105 Commits
Author | SHA1 | Date |
---|---|---|
|
85a8640c15 | |
|
0bea8fa121 | |
|
6dd6ec4fa4 | |
|
19c6d30934 | |
|
d3e4209241 | |
|
c4f1ed9cf0 | |
|
7d9bc52e5c | |
|
5c4aa9546d | |
|
dcd89dddbe | |
|
72e7f5adc8 | |
|
648f6416ca | |
|
3923c628f1 | |
|
f5c47e2bee | |
|
1758aab6a3 | |
|
5e98e5826f | |
|
fb6116c5cf | |
|
2e70fe16d3 | |
|
9f2b3fa700 | |
|
daec692be0 | |
|
647e56c900 | |
|
3ab116d733 | |
|
f4314581b1 | |
|
4fbfebc24b | |
|
b4b399c927 | |
|
10c87d916d | |
|
2ca6668b12 | |
|
4b3d2dfc61 | |
|
0f170e8967 | |
|
45f3e6e569 | |
|
4eba902d46 | |
|
8b53cea2ae | |
|
018318c844 | |
|
735a8dc733 | |
|
a55521851e | |
|
bdaec559e3 | |
|
8b91f7b631 | |
|
5095f24b49 | |
|
279289e581 | |
|
974f65b506 | |
|
893417b4b6 | |
|
a30be64c2c | |
|
7ca5b38338 | |
|
5c1e4202d5 | |
|
13c8a2c88d | |
|
8ee206668c | |
|
d96a3f587c | |
|
69ac992063 | |
|
80f8746fa7 | |
|
f50555cfd7 | |
|
a6e289ffe0 | |
|
122677c853 | |
|
738632738f | |
|
d02de8f746 | |
|
49637001c6 | |
|
1fa5ddfb83 | |
|
eb9016d8b0 | |
|
1280331fbc | |
|
56f0b0f968 | |
|
e8eb967ccc | |
|
c91df0bc1e | |
|
81d79a4ec7 | |
|
c5da37a8c5 | |
|
9db5cde521 | |
|
3a95050279 | |
|
f6cb3efadc | |
|
8f990c7f24 | |
|
5ba1055155 | |
|
5301363274 | |
|
b7d0eda13d | |
|
27cfd18e54 | |
|
e7b369c43c | |
|
949029be51 | |
|
e6c664db85 | |
|
10585de109 | |
|
d2c835982b | |
|
6f3bf2add4 | |
|
a0ddb2dd81 | |
|
8ec51ba47e | |
|
9d814fc6e7 | |
|
eb7b9229ea | |
|
20542d7279 | |
|
9b2f82970e | |
|
74a169bc9c | |
|
f2f13569c0 | |
|
7a423be4d4 | |
|
22e22781e4 | |
|
3a27c8b4ed | |
|
157a7843f0 | |
|
2229e960c4 | |
|
b581ff71cc | |
|
cb6bb2cdf3 | |
|
11aef5ccaa | |
|
558cc12c15 | |
|
7be55d6ffa | |
|
6558b5b63a | |
|
59bc58b38e | |
|
21c9895b25 | |
|
d4a5732ebd | |
|
c74db387c2 | |
|
38374ff2c7 | |
|
6e15f6cba5 | |
|
05cfa40e7e | |
|
c95f521942 | |
|
950f07d91b | |
|
a09ba109d9 |
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
@ -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
|
||||
|
|
@ -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
|
|
@ -6,3 +6,4 @@ qm.pp.bz2
|
|||
qm_file_contexts
|
||||
*.8
|
||||
tests/e2e/ContainerFile.template
|
||||
__pycache__/
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
653
README.md
|
@ -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.
|
||||
|
|
|
@ -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"
|
||||
|
|
|
@ -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
|
||||
}
|
||||
|
|
15
demos/demo
15
demos/demo
|
@ -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
|
||||
}
|
||||
|
|
|
@ -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
|
||||
```
|
|
@ -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**
|
||||

|
||||
|
||||
**Draft a new release**
|
||||

|
||||
|
||||
**Create a new tag**
|
||||

|
||||
|
||||
**Generate release notes**
|
||||

|
||||
|
||||
**Publish Release**
|
||||

|
|
@ -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 |
|
@ -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'
|
||||
```
|
|
@ -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/)
|
|
@ -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
|
|
@ -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
|
||||
```
|
|
@ -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.
|
|
@ -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.
|
|
@ -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
|
||||
```
|
|
@ -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)
|
|
@ -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.
|
|
@ -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
|
|
@ -0,0 +1,3 @@
|
|||
mkdocs>=1.3.0
|
||||
mkdocs-material>=9.3.1
|
||||
pymdown-extensions>=10.0.1
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
12
qm.8.md
|
@ -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
|
||||
|
||||
|
|
15
qm.container
15
qm.container
|
@ -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
6
qm.fc
|
@ -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
5
qm.if
|
@ -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
51
qm.te
|
@ -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)
|
||||
')
|
||||
|
|
|
@ -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
|
||||
|
||||
|
||||
|
|
|
@ -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.
|
|
@ -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.
|
||||
|
|
|
@ -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>
|
||||
|
|
15
rpm/qm.spec
15
rpm/qm.spec
|
@ -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
|
||||
|
|
|
@ -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`.
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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>
|
||||
|
|
|
@ -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.
|
||||
|
|
|
@ -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`.
|
||||
|
|
|
@ -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.
|
||||
|
|
|
@ -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>
|
||||
|
|
|
@ -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
61
setup
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
|
@ -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}
|
||||
|
|
@ -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
|
|
@ -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"]
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
@ -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
|
|
@ -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"]
|
|
@ -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
|
|
@ -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
|
|
@ -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
|
||||
|
|
|
@ -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
|
|
@ -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
|
|
@ -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
|
|
@ -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
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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() {
|
||||
|
|
|
@ -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"
|
||||
|
|
|
@ -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, ¶m) == -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;
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
|
@ -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)"
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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]
|
||||
|
|
|
@ -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'"
|
||||
|
||||
|
|
|
@ -6,3 +6,4 @@ require:
|
|||
pattern:
|
||||
- /tests/e2e/lib/utils
|
||||
- /tests/ffi/common/prepare.sh
|
||||
- /tests/ffi/common/ffi-qm.container
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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\""
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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')
|
||||
|
|
|
@ -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}"
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -0,0 +1,7 @@
|
|||
summary: Test libkrun in qm
|
||||
test: /bin/bash ./check_libkrun.sh
|
||||
duration: 10m
|
||||
tier: 0
|
||||
tag: [kvm,setup]
|
||||
framework: shell
|
||||
|
|
@ -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
|
||||
|
|
@ -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
|
|
@ -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
|
|
@ -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
|
|
@ -0,0 +1 @@
|
|||
output: This is the file to copy
|
|
@ -0,0 +1 @@
|
|||
This is the file to copy
|
|
@ -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
|
|
@ -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
Loading…
Reference in New Issue