Compare commits
2 Commits
e6ece70620
...
7addbfdc27
| Author | SHA1 | Date |
|---|---|---|
|
|
7addbfdc27 | 2 weeks ago |
|
|
897b484196 | 2 weeks ago |
23 changed files with 496 additions and 0 deletions
@ -0,0 +1,18 @@ |
|||||
|
##
|
||||
|
## Makefile for Asterisk quadlet
|
||||
|
##
|
||||
|
|
||||
|
# Asterisk and its TFTP server run as UID 10036 (asterisk) / GID 10000 (itix-svc) on the host
|
||||
|
PROJECT_UID = 10036 |
||||
|
PROJECT_GID = 10000 |
||||
|
|
||||
|
# Spool and logs of Asterisk, created by the package and not by systemd-tmpfiles:
|
||||
|
# see the comment in tmpfiles.d/asterisk.conf.
|
||||
|
TARGET_FILES += $(TARGET_CHROOT)/var/lib/quadlets/asterisk/spool |
||||
|
TARGET_FILES += $(TARGET_CHROOT)/var/lib/quadlets/asterisk/log |
||||
|
|
||||
|
# Include common Makefile
|
||||
|
include ../../scripts/common.mk |
||||
|
|
||||
|
$(TARGET_CHROOT)/var/lib/quadlets/asterisk/spool $(TARGET_CHROOT)/var/lib/quadlets/asterisk/log: $(TARGET_CHROOT)/var/lib/quadlets/asterisk |
||||
|
install -d -m 0750 -o $(PROJECT_UID) -g $(PROJECT_GID) $@ |
||||
@ -0,0 +1,116 @@ |
|||||
|
# Podman Quadlet: Asterisk |
||||
|
|
||||
|
## Overview |
||||
|
|
||||
|
[Asterisk](https://www.asterisk.org/) is an open source PBX. This cookbook runs it as a SIP server for |
||||
|
phones on the local network, together with the TFTP server the phones fetch their configuration and |
||||
|
firmware from. |
||||
|
|
||||
|
This cookbook: |
||||
|
|
||||
|
- Builds a container image locally, from Alpine Linux 3.24, with the Asterisk 22 (LTS) and dnsmasq |
||||
|
packages of the distribution. |
||||
|
- Runs Asterisk directly as a dedicated, unprivileged UID/GID (no user namespace mapping), with |
||||
|
PJSIP as its only channel driver. |
||||
|
- Runs dnsmasq as a TFTP server only (no DNS, no DHCP), from the same image, as the same user. |
||||
|
- Loads an explicit list of Asterisk modules: what calls between SIP phones need, and nothing else. |
||||
|
- Includes a timer to rebuild the container image daily. |
||||
|
|
||||
|
It does not provide voicemail, call recording, conferencing, a trunk to an operator, nor a web |
||||
|
interface. |
||||
|
|
||||
|
## Prerequisites |
||||
|
|
||||
|
- The `base` cookbook (implicit dependency), for the virtiofs mount. |
||||
|
- A virtiofs mount on `/var/lib/virtiofs/data`, which holds the TFTP root. |
||||
|
- 1 vCPU and 1 GB of RAM are enough for a household (not measured beyond that). |
||||
|
- Network access at the first boot, to pull `docker.io/library/alpine:3.24` and the Alpine packages. |
||||
|
|
||||
|
## Files provided by the operator |
||||
|
|
||||
|
| Path | Content | |
||||
|
|------|---------| |
||||
|
| `/etc/quadlets/asterisk/etc/pjsip.conf` | Transport, endpoints, authentication and AOR of each phone. Required. | |
||||
|
| `/etc/quadlets/asterisk/etc/extensions.conf` | Dialplan. Required. | |
||||
|
| `/etc/quadlets/asterisk/etc/indications.conf` | Call progress tones of the country. Optional: without it, Asterisk logs a warning and uses no tones of its own; the phones play theirs. | |
||||
|
| `/var/lib/virtiofs/data/asterisk/tftp/` | Configuration files and firmware images of the phones, as each vendor names them. Optional: the TFTP server also runs on an empty directory, so that files written later are served without a restart. | |
||||
|
|
||||
|
Asterisk does not start without `pjsip.conf` and `extensions.conf`. Examples of both are in |
||||
|
`config/examples/etc/`. |
||||
|
|
||||
|
The TFTP root is on the virtiofs mount rather than under `/etc/quadlets`, so that the host can write |
||||
|
it: a firmware image weighs tens of megabytes, which an Ignition file cannot carry. The files must be |
||||
|
readable by UID 10036. |
||||
|
|
||||
|
The other files of `/etc/quadlets/asterisk/etc/` are part of the cookbook. Some are empty on purpose: |
||||
|
Asterisk reads them at startup whether or not the feature is used, and logs an error when they are |
||||
|
missing. |
||||
|
|
||||
|
## Ports |
||||
|
|
||||
|
| Port | Protocol | Service | |
||||
|
|------|----------|---------| |
||||
|
| 5060 | UDP | SIP | |
||||
|
| 10000-10999 | UDP | RTP (set in `rtp.conf`) | |
||||
|
| 69 | UDP | TFTP | |
||||
|
|
||||
|
Both containers use host networking. |
||||
|
|
||||
|
## UID and GID |
||||
|
|
||||
|
| UID | GID | Usage | |
||||
|
|-----|-----|-------| |
||||
|
| 10036 | 10000 | Asterisk and dnsmasq | |
||||
|
|
||||
|
## Usage |
||||
|
|
||||
|
In a separate terminal, follow the logs. |
||||
|
|
||||
|
```sh |
||||
|
sudo make tail-logs |
||||
|
``` |
||||
|
|
||||
|
Install the Podman Quadlets and start Asterisk. |
||||
|
|
||||
|
```sh |
||||
|
sudo make clean install |
||||
|
``` |
||||
|
|
||||
|
The **asterisk-build.service** builds the image, then **asterisk.service** starts. Check the |
||||
|
endpoints and the dialplan: |
||||
|
|
||||
|
```sh |
||||
|
sudo podman exec asterisk asterisk -rx "pjsip show endpoints" |
||||
|
sudo podman exec asterisk asterisk -rx "dialplan show" |
||||
|
``` |
||||
|
|
||||
|
Make a phone ring without a second phone (`res_clioriginate`): |
||||
|
|
||||
|
```sh |
||||
|
sudo podman exec asterisk asterisk -rx "channel originate PJSIP/101 application Wait 10" |
||||
|
``` |
||||
|
|
||||
|
Trace the SIP messages: |
||||
|
|
||||
|
```sh |
||||
|
sudo podman exec asterisk asterisk -rx "pjsip set logger on" |
||||
|
``` |
||||
|
|
||||
|
Finally, remove the quadlets, their configuration and their data. |
||||
|
|
||||
|
```sh |
||||
|
sudo make uninstall clean |
||||
|
``` |
||||
|
|
||||
|
## Known messages |
||||
|
|
||||
|
At every start, `res_pjsip` logs twice: `There are no local system nameservers configured, resorting |
||||
|
to system resolution`. Measured on Alpine 3.24 with a populated `/etc/resolv.conf`. Name resolution |
||||
|
still works through the system resolver, and calls between phones addressed by IP do not use it. |
||||
|
|
||||
|
## Container image updates |
||||
|
|
||||
|
The daily rebuild pulls a newer `alpine:3.24` when there is one, and the containers restart on the |
||||
|
new image through `AutoUpdate=local`. A rebuild reuses the cached package layer as long as the base |
||||
|
image is unchanged: an Asterisk update published in the Alpine repository between two releases of |
||||
|
the base image is not picked up until the next one. |
||||
@ -0,0 +1,10 @@ |
|||||
|
[Unit] |
||||
|
Description=Rebuild the Asterisk container image |
||||
|
PartOf=asterisk.target |
||||
|
|
||||
|
[Timer] |
||||
|
OnCalendar=daily |
||||
|
Persistent=true |
||||
|
|
||||
|
[Install] |
||||
|
WantedBy=asterisk.target |
||||
@ -0,0 +1,50 @@ |
|||||
|
[Unit] |
||||
|
Description=Asterisk - TFTP server for the provisioning of the phones |
||||
|
Documentation=https://thekelleys.org.uk/dnsmasq/docs/dnsmasq-man.html |
||||
|
|
||||
|
Wants=asterisk-build.service |
||||
|
After=network.target asterisk-build.service var-lib-virtiofs-data.mount |
||||
|
Requires=var-lib-virtiofs-data.mount |
||||
|
|
||||
|
# The provisioning files are operator-provided, on the precious-data mount so |
||||
|
# that the host can write them -- firmware images do not fit in an Ignition |
||||
|
# file. No condition on their presence: the host may write them after the |
||||
|
# first boot, and a unit skipped by its condition is not started again when |
||||
|
# the files arrive. An empty TFTP root only answers "file not found". |
||||
|
|
||||
|
# Start/stop this unit when the target is started/stopped |
||||
|
PartOf=asterisk.target |
||||
|
|
||||
|
[Container] |
||||
|
ContainerName=asterisk-tftp |
||||
|
Image=localhost/asterisk:latest |
||||
|
AutoUpdate=local |
||||
|
|
||||
|
User=10036 |
||||
|
Group=10000 |
||||
|
|
||||
|
# TFTP listens on 69/udp, a privileged port. |
||||
|
AddCapability=CAP_NET_BIND_SERVICE |
||||
|
|
||||
|
# Host networking: TFTP answers from an ephemeral port, which port publishing |
||||
|
# does not follow. |
||||
|
Network=host |
||||
|
|
||||
|
# dnsmasq as a TFTP server and nothing else: |
||||
|
# --port=0 disables DNS, and no dhcp-range means no DHCP; |
||||
|
# --conf-file=/dev/null ignores the configuration file of the image; |
||||
|
# --pid-file= (empty) writes no PID file, which this user could not write. |
||||
|
Entrypoint=/usr/sbin/dnsmasq |
||||
|
Exec=--keep-in-foreground --conf-file=/dev/null --pid-file= --port=0 --log-facility=- --enable-tftp --tftp-root=/var/lib/virtiofs/data/asterisk/tftp |
||||
|
|
||||
|
# Read-only: the phones fetch, they never upload. |
||||
|
Volume=/var/lib/virtiofs/data/asterisk/tftp:/var/lib/virtiofs/data/asterisk/tftp:ro,z |
||||
|
|
||||
|
[Service] |
||||
|
Restart=always |
||||
|
RestartSec=10 |
||||
|
TimeoutStartSec=300 |
||||
|
TimeoutStopSec=30 |
||||
|
|
||||
|
[Install] |
||||
|
WantedBy=asterisk.target |
||||
@ -0,0 +1,28 @@ |
|||||
|
[Unit] |
||||
|
Description=Build of the Asterisk container image |
||||
|
Documentation=https://www.asterisk.org/ |
||||
|
Wants=network-online.target |
||||
|
After=network-online.target |
||||
|
|
||||
|
# Keep trying. A build that fails because the network is not there yet would |
||||
|
# otherwise never run again, and the default start limit (5 attempts in 10 s) |
||||
|
# turns the unit "failed" for good. Same reasoning as the image units of the |
||||
|
# other cookbooks. |
||||
|
StartLimitIntervalSec=0 |
||||
|
|
||||
|
# Stopping the target stops a build that is still retrying. |
||||
|
PartOf=asterisk.target |
||||
|
|
||||
|
[Build] |
||||
|
File=/etc/quadlets/asterisk/container/Containerfile |
||||
|
ImageTag=localhost/asterisk:latest |
||||
|
SetWorkingDirectory=/etc/quadlets/asterisk/container |
||||
|
|
||||
|
# Pull the base image only when the registry has a newer one. Pull errors are |
||||
|
# ignored when a local image exists, so a rebuild without network keeps the |
||||
|
# current image instead of failing. |
||||
|
Pull=newer |
||||
|
|
||||
|
[Service] |
||||
|
Restart=on-failure |
||||
|
RestartSec=60 |
||||
@ -0,0 +1,58 @@ |
|||||
|
[Unit] |
||||
|
Description=Asterisk PBX |
||||
|
Documentation=https://docs.asterisk.org/ |
||||
|
|
||||
|
# Wants= and not Requires= on the build: a failed build -- no network at boot -- |
||||
|
# must not keep a container whose image is already in local storage from |
||||
|
# starting. A genuinely missing image fails the container, and Restart= below |
||||
|
# retries until the build has produced it. |
||||
|
Wants=asterisk-build.service |
||||
|
After=network.target asterisk-build.service |
||||
|
|
||||
|
# The SIP endpoints and the dialplan are operator-provided: without them, |
||||
|
# Asterisk would start and accept no phone. |
||||
|
ConditionPathExists=/etc/quadlets/asterisk/etc/pjsip.conf |
||||
|
ConditionPathExists=/etc/quadlets/asterisk/etc/extensions.conf |
||||
|
|
||||
|
# Start/stop this unit when the target is started/stopped |
||||
|
PartOf=asterisk.target |
||||
|
|
||||
|
[Container] |
||||
|
ContainerName=asterisk |
||||
|
Image=localhost/asterisk:latest |
||||
|
AutoUpdate=local |
||||
|
|
||||
|
# No need for root: SIP listens on 5060 and RTP on 10000-10999, all above 1024. |
||||
|
User=10036 |
||||
|
Group=10000 |
||||
|
|
||||
|
# Host networking: RTP takes a range of a thousand UDP ports, which port |
||||
|
# publishing handles badly, and SIP must see the real addresses of the phones. |
||||
|
Network=host |
||||
|
|
||||
|
# Configuration (read-only). The etc/ sub-directory only, never the whole |
||||
|
# /etc/quadlets/asterisk: ":Z" relabels what it mounts, and the build context |
||||
|
# next to it must stay readable by the build. |
||||
|
Volume=/etc/quadlets/asterisk/etc:/etc/asterisk:ro,Z |
||||
|
|
||||
|
# Internal database and spool. Nothing precious: no voicemail, no recordings. |
||||
|
Volume=/var/lib/quadlets/asterisk:/var/lib/quadlets/asterisk:Z |
||||
|
|
||||
|
# Control socket, used by "asterisk -rx" and by the health check. |
||||
|
Tmpfs=/run/asterisk:rw,mode=1777 |
||||
|
|
||||
|
# Health check: the CLI answers only when the core is up. |
||||
|
HealthCmd=asterisk -rx "core show uptime" |
||||
|
HealthInterval=30s |
||||
|
HealthTimeout=10s |
||||
|
HealthStartPeriod=30s |
||||
|
HealthRetries=3 |
||||
|
|
||||
|
[Service] |
||||
|
Restart=always |
||||
|
RestartSec=10 |
||||
|
TimeoutStartSec=300 |
||||
|
TimeoutStopSec=30 |
||||
|
|
||||
|
[Install] |
||||
|
WantedBy=asterisk.target |
||||
@ -0,0 +1,12 @@ |
|||||
|
[Unit] |
||||
|
Description=Asterisk Service Target |
||||
|
Documentation=man:systemd.target(5) |
||||
|
Requires=asterisk.service asterisk-build.timer |
||||
|
Wants=asterisk-tftp.service |
||||
|
After=asterisk.service asterisk-tftp.service asterisk-build.timer |
||||
|
|
||||
|
# Allow isolation - can stop/start this target independently |
||||
|
AllowIsolate=yes |
||||
|
|
||||
|
[Install] |
||||
|
WantedBy=multi-user.target |
||||
@ -0,0 +1,15 @@ |
|||||
|
FROM docker.io/library/alpine:3.24 |
||||
|
|
||||
|
# Asterisk 22 (the LTS branch), PJSIP included: Alpine bundles pjproject in the |
||||
|
# main package. dnsmasq serves the provisioning files of the phones over TFTP, |
||||
|
# from the same image, so that a single build keeps both up to date. |
||||
|
RUN apk add --no-cache asterisk dnsmasq |
||||
|
|
||||
|
# /etc/asterisk is empty: the sample files are in asterisk-sample-config, which |
||||
|
# is not installed. The configuration is mounted read-only there at run time. |
||||
|
|
||||
|
# SIP signalling. RTP uses 10000-10999/udp, as set in rtp.conf. |
||||
|
EXPOSE 5060/udp |
||||
|
|
||||
|
ENTRYPOINT [ "/usr/sbin/asterisk" ] |
||||
|
CMD [ "-f", "-n", "-vv" ] |
||||
@ -0,0 +1,3 @@ |
|||||
|
; Core configuration files Asterisk reads at startup whether or not the |
||||
|
; feature is used. Present and empty, so that a missing file does not log an |
||||
|
; error at every start. |
||||
@ -0,0 +1,20 @@ |
|||||
|
; Asterisk runs as UID 10036, which owns nothing in the image: every directory |
||||
|
; it writes to is moved out of the image, onto a path the container mounts. |
||||
|
; |
||||
|
; - /var/lib/quadlets/asterisk: the internal database and the spool, mounted |
||||
|
; from the host. Nothing there is precious: no voicemail, no recordings. |
||||
|
; - /run/asterisk: the control socket, on a tmpfs. |
||||
|
; |
||||
|
; The read-only directories stay where the Alpine package puts them. |
||||
|
[directories] |
||||
|
astetcdir => /etc/asterisk |
||||
|
astmoddir => /usr/lib/asterisk/modules |
||||
|
astvarlibdir => /var/lib/asterisk |
||||
|
astdbdir => /var/lib/quadlets/asterisk |
||||
|
astkeydir => /var/lib/asterisk |
||||
|
astdatadir => /var/lib/asterisk |
||||
|
astagidir => /var/lib/asterisk/agi-bin |
||||
|
astspooldir => /var/lib/quadlets/asterisk/spool |
||||
|
astrundir => /run/asterisk |
||||
|
astlogdir => /var/lib/quadlets/asterisk/log |
||||
|
astsbindir => /usr/sbin |
||||
@ -0,0 +1,4 @@ |
|||||
|
; Core configuration files Asterisk reads at startup whether or not the |
||||
|
; feature is used. Present and empty, so that a missing file does not log an |
||||
|
; error at every start. |
||||
|
[general] |
||||
@ -0,0 +1,3 @@ |
|||||
|
; No call detail records: nothing reads them. |
||||
|
[general] |
||||
|
enable = no |
||||
@ -0,0 +1,3 @@ |
|||||
|
; No channel event logging: nothing reads it. |
||||
|
[general] |
||||
|
enable = no |
||||
@ -0,0 +1,3 @@ |
|||||
|
; Default transfer and pickup settings. The phones transfer with SIP REFER, |
||||
|
; handled by res_pjsip_refer, not with DTMF feature codes. |
||||
|
[general] |
||||
@ -0,0 +1,6 @@ |
|||||
|
; Everything goes to the console, i.e. to the standard output of the container, |
||||
|
; i.e. to the journal. No log file: there is no log rotation in the container. |
||||
|
[general] |
||||
|
|
||||
|
[logfiles] |
||||
|
console => notice,warning,error,verbose |
||||
@ -0,0 +1,51 @@ |
|||||
|
; An explicit list rather than autoload: autoload brings some three hundred |
||||
|
; modules, most of which have no configuration and decline to load with an |
||||
|
; error, which buries the messages that matter. |
||||
|
; |
||||
|
; What is listed is what calls between local SIP phones need: PJSIP, RTP, the |
||||
|
; static dialplan, Dial() and the codecs the phones offer. A feature that needs |
||||
|
; another module needs a line here. |
||||
|
[modules] |
||||
|
autoload = no |
||||
|
|
||||
|
; Configuration storage for PJSIP |
||||
|
load => res_sorcery_config.so |
||||
|
load => res_sorcery_memory.so |
||||
|
load => res_sorcery_astdb.so |
||||
|
|
||||
|
; PJSIP: transport, registration, authentication, calls |
||||
|
load => res_pjproject.so |
||||
|
load => res_pjsip.so |
||||
|
load => res_pjsip_session.so |
||||
|
load => res_pjsip_pubsub.so |
||||
|
load => res_pjsip_authenticator_digest.so |
||||
|
load => res_pjsip_endpoint_identifier_user.so |
||||
|
load => res_pjsip_registrar.so |
||||
|
load => res_pjsip_sdp_rtp.so |
||||
|
load => res_pjsip_caller_id.so |
||||
|
load => res_pjsip_dtmf_info.so |
||||
|
load => res_pjsip_rfc3326.so |
||||
|
load => res_pjsip_diversion.so |
||||
|
load => res_pjsip_header_funcs.so |
||||
|
; Transfer button of the phones (SIP REFER) |
||||
|
load => res_pjsip_refer.so |
||||
|
load => res_pjsip_logger.so |
||||
|
load => chan_pjsip.so |
||||
|
|
||||
|
; Media |
||||
|
load => res_rtp_asterisk.so |
||||
|
load => res_timing_timerfd.so |
||||
|
load => bridge_simple.so |
||||
|
load => bridge_native_rtp.so |
||||
|
load => codec_g722.so |
||||
|
load => codec_alaw.so |
||||
|
load => codec_ulaw.so |
||||
|
load => codec_a_mu.so |
||||
|
|
||||
|
; Dialplan |
||||
|
load => pbx_config.so |
||||
|
load => app_dial.so |
||||
|
load => func_callerid.so |
||||
|
|
||||
|
; "channel originate" from the CLI, to test a phone without a second one |
||||
|
load => res_clioriginate.so |
||||
@ -0,0 +1,4 @@ |
|||||
|
; Core configuration files Asterisk reads at startup whether or not the |
||||
|
; feature is used. Present and empty, so that a missing file does not log an |
||||
|
; error at every start. |
||||
|
|
||||
@ -0,0 +1,5 @@ |
|||||
|
; One thousand ports, i.e. five hundred simultaneous calls: far more than a |
||||
|
; household needs, and a range small enough to be named in a firewall rule. |
||||
|
[general] |
||||
|
rtpstart = 10000 |
||||
|
rtpend = 10999 |
||||
@ -0,0 +1,4 @@ |
|||||
|
; Core configuration files Asterisk reads at startup whether or not the |
||||
|
; feature is used. Present and empty, so that a missing file does not log an |
||||
|
; error at every start. |
||||
|
[general] |
||||
@ -0,0 +1,11 @@ |
|||||
|
; Example: the two phones of pjsip.conf call each other. Any other number is |
||||
|
; rejected: there is no route out. |
||||
|
[general] |
||||
|
static = yes |
||||
|
writeprotect = yes |
||||
|
|
||||
|
[phones] |
||||
|
exten => _10[12],1,Dial(PJSIP/${EXTEN},30) |
||||
|
same => n,Hangup() |
||||
|
|
||||
|
exten => _X.,1,Hangup(1) |
||||
@ -0,0 +1,48 @@ |
|||||
|
; Example: two phones, 101 and 102, registering over UDP. |
||||
|
; The operator provides the real file, with real secrets. |
||||
|
[transport-udp] |
||||
|
type = transport |
||||
|
protocol = udp |
||||
|
bind = 0.0.0.0:5060 |
||||
|
|
||||
|
[phone](!) |
||||
|
type = endpoint |
||||
|
context = phones |
||||
|
disallow = all |
||||
|
allow = g722 |
||||
|
allow = alaw |
||||
|
allow = ulaw |
||||
|
direct_media = no |
||||
|
dtmf_mode = rfc4733 |
||||
|
|
||||
|
[phone-auth](!) |
||||
|
type = auth |
||||
|
auth_type = userpass |
||||
|
|
||||
|
[phone-aor](!) |
||||
|
type = aor |
||||
|
max_contacts = 1 |
||||
|
remove_existing = yes |
||||
|
qualify_frequency = 60 |
||||
|
|
||||
|
[101](phone) |
||||
|
auth = 101 |
||||
|
aors = 101 |
||||
|
callerid = "Phone 101" <101> |
||||
|
|
||||
|
[101](phone-auth) |
||||
|
username = 101 |
||||
|
password = example-only-101 |
||||
|
|
||||
|
[101](phone-aor) |
||||
|
|
||||
|
[102](phone) |
||||
|
auth = 102 |
||||
|
aors = 102 |
||||
|
callerid = "Phone 102" <102> |
||||
|
|
||||
|
[102](phone-auth) |
||||
|
username = 102 |
||||
|
password = example-only-102 |
||||
|
|
||||
|
[102](phone-aor) |
||||
@ -0,0 +1,9 @@ |
|||||
|
variant: fcos |
||||
|
version: 1.4.0 |
||||
|
passwd: |
||||
|
users: |
||||
|
- name: asterisk |
||||
|
uid: 10036 |
||||
|
gecos: Asterisk PBX |
||||
|
home_dir: /var/lib/quadlets/asterisk |
||||
|
primary_group: itix-svc |
||||
@ -0,0 +1,15 @@ |
|||||
|
# Provisioning files of the phones, served over TFTP. Operator-provided, on the |
||||
|
# precious-data mount so that the host can write them. The "$" marks it for |
||||
|
# removal on `systemd-tmpfiles --purge` (i.e. `make uninstall`). |
||||
|
# |
||||
|
# /var/lib/quadlets/asterisk is NOT declared here, and must not be. The package |
||||
|
# creates it, once. A "d" line adjusts the directory again at every run of |
||||
|
# systemd-tmpfiles, and resets its SELinux label to var_lib_t on the way. Such a |
||||
|
# run happens AFTER the containers start on the first boot of a Fedora CoreOS |
||||
|
# machine: rpm-ostree applies the qemu-guest-agent package live, then runs |
||||
|
# "systemd-tmpfiles --create --prefix=/var". Asterisk then loses access to the |
||||
|
# directory Podman had just relabeled, and every REGISTER fails with |
||||
|
# "ast_db_put: SQL logic error". Measured on 2026-10-25. The virtiofs mount is |
||||
|
# not affected: its label is fixed by the mount. |
||||
|
d$ /var/lib/virtiofs/data/asterisk 0750 10036 10000 - |
||||
|
d$ /var/lib/virtiofs/data/asterisk/tftp 0750 10036 10000 - |
||||
Loading…
Reference in new issue