Skip to content

podman-systemd templated containers unable to work with templated volumes (and templated volumes separately have a failure and an inconvenience) #25136

@Domini

Description

@Domini

Issue Description

  1. Volume failure
    When you define a templated volume and an instance, e.g. test@.volume, ln -s test@.volume test@abc.volume, generator creates a test@abc-volume.service with an ExecStart=/usr/bin/podman volume create --ignore systemd-test@abc. It fails as volume names cannot contain special characters (Error: running volume create option: names must match [a-zA-Z0-9][a-zA-Z0-9_.-]*: invalid argument). Note, here instance name is properly hardcoded as abc.

  2. Volume inconvenience
    It is somewhat easy to fix - you add [Volume] VolumeName=test-%i, ExecStart now looks right ExecStart=/usr/bin/podman volume create --ignore test-%i.

But remember, the generated service is called test@abc-volume.service, not test@abc.service. When systemd starts this service, instance name is abc-volume, not abc, and volume created is test-abc-volume, not test-abc.

  1. Interoperability failure

3.1.
Now you define templated service and an instance, e.g. test@.service, ln -s test@.service test@abc.service. You include the templated volume with one of the two ways.

Mount=type=volume,source=test@abc.volume,target=/tmp
Volume=test@abc.volume:/tmp

Generator generates a somewhat proper service, inheriting VolumeName from test@.volume, and creates the following ExecStart, Requires and After

--mount type=volume,source=test-%i,target=/tmp
Requires=test@abc-volume.service
After=test@abc-volume.service

But, remember, service instance name is abc, but when it calls test@abc-volume.service its instance name is abc-volume. systemctl start test@abc.service creates volume test-abc-volume explicitly by calling test@abc-volume.service, then podman runs a container referencing volume test-abc (not test-abc-volume), and a volume test-abc is implicitly created and used by the container. Volume test-abc-volume is left dangling.

3.2. If you change templated volume inclusion to

Mount=type=volume,source=test@%i.volume,target=/tmp
Volume=test@%i.volume:/tmp

service unit would fail to generate.

3.3. If you change templated volume inclusion to (the way I think it was intended)

Mount=type=volume,source=test@.volume,target=/tmp
Volume=test@.volume:/tmp

generator creates the following ExecStart, Requires and After

--mount type=volume,source=test-%i,target=/tmp
Requires=test@-volume.service
After=test@-volume.service

It's the worst of both worlds:

  • wrong volume service is being explicitly called, it creates a dangling test--volume as instance name for the volume call is -volume
  • podman run implicitly creates test-abc and uses it.

Steps to reproduce the issue

Please, see description.

Describe the results you received

Please, see description.

Describe the results you expected

Without VolumeName, volume name should be something like systemd-test-abc.
With VolumeName, -volume suffix should be stripped from the instance name, and the volume created should be test-abc.
Container service should reference test@abc.volume in all cases.

Preferably this should be fixed by changing the generated volume services name pattern for test@.volume to test-volume@abc.service instead of test@abc-volume.service, so that instance name is the same in the generated container and volume.

This could be fixed by ugly hacks with ExecStart using sh and modifying %i value in runtime (see my comment below where this is done for a temporary workaround), however, that would be a pity.

podman info output

# podman info
host:
  arch: amd64
  buildahVersion: 1.38.1
  cgroupControllers:
  - cpuset
  - cpu
  - io
  - memory
  - hugetlb
  - pids
  - rdma
  - misc
  cgroupManager: systemd
  cgroupVersion: v2
  conmon:
    package: conmon-2.1.12-3.fc41.x86_64
    path: /usr/bin/conmon
    version: 'conmon version 2.1.12, commit: '
  cpuUtilization:
    idlePercent: 99.88
    systemPercent: 0.08
    userPercent: 0.05
  cpus: 8
  databaseBackend: sqlite
  distribution:
    distribution: fedora
    version: "41"
  eventLogger: journald
  freeLocks: 2044
  hostname: fedora
  idMappings:
    gidmap: null
    uidmap: null
  kernel: 6.12.10-200.fc41.x86_64
  linkmode: dynamic
  logDriver: journald
  memFree: 13824925696
  memTotal: 16661622784
  networkBackend: netavark
  networkBackendInfo:
    backend: netavark
    dns:
      package: aardvark-dns-1.13.1-1.fc41.x86_64
      path: /usr/libexec/podman/aardvark-dns
      version: aardvark-dns 1.13.1
    package: netavark-1.13.1-1.fc41.x86_64
    path: /usr/libexec/podman/netavark
    version: netavark 1.13.1
  ociRuntime:
    name: crun
    package: crun-1.19.1-1.fc41.x86_64
    path: /usr/bin/crun
    version: |-
      crun version 1.19.1
      commit: 3e32a70c93f5aa5fea69b50256cca7fd4aa23c80
      rundir: /run/user/0/crun
      spec: 1.0.0
      +SYSTEMD +SELINUX +APPARMOR +CAP +SECCOMP +EBPF +CRIU +LIBKRUN +WASM:wasmedge +YAJL
  os: linux
  pasta:
    executable: /usr/bin/pasta
    package: passt-0^20250121.g4f2c8e7-2.fc41.x86_64
    version: |
      pasta 0^20250121.g4f2c8e7-2.fc41.x86_64
      Copyright Red Hat
      GNU General Public License, version 2 or later
        <https://www.gnu.org/licenses/old-licenses/gpl-2.0.html>
      This is free software: you are free to change and redistribute it.
      There is NO WARRANTY, to the extent permitted by law.
  remoteSocket:
    exists: true
    path: /run/podman/podman.sock
  rootlessNetworkCmd: pasta
  security:
    apparmorEnabled: false
    capabilities: CAP_CHOWN,CAP_DAC_OVERRIDE,CAP_FOWNER,CAP_FSETID,CAP_KILL,CAP_NET_BIND_SERVICE,CAP_SETFCAP,CAP_SETGID,CAP_SETPCAP,CAP_SETUID,CAP_SYS_CHROOT
    rootless: false
    seccompEnabled: true
    seccompProfilePath: /usr/share/containers/seccomp.json
    selinuxEnabled: true
  serviceIsRemote: false
  slirp4netns:
    executable: ""
    package: ""
    version: ""
  swapFree: 8589930496
  swapTotal: 8589930496
  uptime: 22h 9m 53.00s (Approximately 0.92 days)
  variant: ""
plugins:
  authorization: null
  log:
  - k8s-file
  - none
  - passthrough
  - journald
  network:
  - bridge
  - macvlan
  - ipvlan
  volume:
  - local
registries:
  search:
  - registry.fedoraproject.org
  - registry.access.redhat.com
  - docker.io
store:
  configFile: /etc/containers/storage.conf
  containerStore:
    number: 1
    paused: 0
    running: 1
    stopped: 0
  graphDriverName: btrfs
  graphOptions: {}
  graphRoot: /var/lib/containers/storage
  graphRootAllocated: 724490518528
  graphRootUsed: 8092454912
  graphStatus:
    Build Version: Btrfs v6.12
    Library Version: "104"
  imageCopyTmpDir: /var/tmp
  imageStore:
    number: 43
  runRoot: /run/containers/storage
  transientStore: false
  volumePath: /var/lib/containers/storage/volumes
version:
  APIVersion: 5.3.2
  Built: 1737504000
  BuiltTime: Wed Jan 22 00:00:00 2025
  GitCommit: ""
  GoVersion: go1.23.4
  Os: linux
  OsArch: linux/amd64
  Version: 5.3.2

Podman in a container

No

Privileged Or Rootless

None

Upstream Latest Release

No

Additional environment details

Additional environment details

Additional information

Additional information like issue happens only occasionally or issue happens with a particular architecture or on a particular setting

Metadata

Metadata

Assignees

No one assigned

    Labels

    kind/bugCategorizes issue or PR as related to a bug.quadlet

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions