Skip to content

Exit policy for Quadlet pods is stop instead of continue (the default) #25596

Open
@Exagone313

Description

@Exagone313

Issue Description

The generated systemd service for a .pod file creates the pod with the --exit-policy=stop argument, meaning it will be deleted when the last container of the pod exits (except infra).

This is a change of behavior from the default, and it is not documented.

Steps to reproduce the issue

  1. Create these files in ~/.config/containers/systemd
  • foo.pod
    [Pod]
    PodName=foobar
    Network=pasta
    
    [Install]
    WantedBy=default.target
    
  • foo.container
    [Container]
    ContainerName=foo
    Pod=foobar.pod
    Image=docker.io/library/alpine:latest
    Exec=/bin/echo foo container command
    
    [Service]
    Type=oneshot
    RemainAfterExit=yes
    Restart=on-failure
    RestartSec=3
    
    [Install]
    WantedBy=default.target
    
  1. Restart the systemd default target
    systemctl --user restart default.target

Describe the results you received

The foobar pod is deleted once the foo container exits.

Describe the results you expected

The foobar pod is kept alive after the foo container exits.

podman info output

host:
  arch: amd64
  buildahVersion: 1.39.2
  cgroupControllers:
  - cpu
  - memory
  - pids
  cgroupManager: systemd
  cgroupVersion: v2
  conmon:
    package: conmon-1:2.1.13-1
    path: /usr/bin/conmon
    version: 'conmon version 2.1.13, commit: 82de887596ed8ee6d9b2ee85e4f167f307bb569b'
  cpuUtilization:
    idlePercent: 98.05
    systemPercent: 0.39
    userPercent: 1.55
  cpus: 16
  databaseBackend: sqlite
  distribution:
    distribution: arch
    version: unknown
  eventLogger: journald
  freeLocks: 2045
  hostname: treacle
  idMappings:
    gidmap:
    - container_id: 0
      host_id: 1008
      size: 1
    - container_id: 1
      host_id: 624288
      size: 65536
    uidmap:
    - container_id: 0
      host_id: 1008
      size: 1
    - container_id: 1
      host_id: 624288
      size: 65536
  kernel: 6.13.4-arch1-1
  linkmode: dynamic
  logDriver: journald
  memFree: 2220281856
  memTotal: 32666664960
  networkBackend: netavark
  networkBackendInfo:
    backend: netavark
    dns:
      package: aardvark-dns-1.14.0-1
      path: /usr/lib/podman/aardvark-dns
      version: aardvark-dns 1.14.0
    package: netavark-1.14.0-1
    path: /usr/lib/podman/netavark
    version: netavark 1.14.0
  ociRuntime:
    name: crun
    package: crun-1.20-1
    path: /usr/bin/crun
    version: |-
      crun version 1.20
      commit: 9c9a76ac11994701dd666c4f0b869ceffb599a66
      rundir: /run/user/1008/crun
      spec: 1.0.0
      +SYSTEMD +SELINUX +APPARMOR +CAP +SECCOMP +EBPF +CRIU +YAJL
  os: linux
  pasta:
    executable: /usr/bin/pasta
    package: passt-2025_02_17.a1e48a0-1
    version: ""
  remoteSocket:
    exists: true
    path: /run/user/1008/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: true
    seccompEnabled: true
    seccompProfilePath: /etc/containers/seccomp.json
    selinuxEnabled: false
  serviceIsRemote: false
  slirp4netns:
    executable: ""
    package: ""
    version: ""
  swapFree: 7745626112
  swapTotal: 8589930496
  uptime: redacted
  variant: ""
plugins:
  authorization: null
  log:
  - k8s-file
  - none
  - passthrough
  - journald
  network:
  - bridge
  - macvlan
  - ipvlan
  volume:
  - local
registries: {}
store:
  configFile: /home/foobar/.config/containers/storage.conf
  containerStore:
    number: 2
    paused: 0
    running: 2
    stopped: 0
  graphDriverName: overlay
  graphOptions: {}
  graphRoot: /home/foobar/.local/share/containers/storage
  graphRootAllocated: 1011306463232
  graphRootUsed: 359770730496
  graphStatus:
    Backing Filesystem: btrfs
    Native Overlay Diff: "true"
    Supports d_type: "true"
    Supports shifting: "false"
    Supports volatile: "true"
    Using metacopy: "false"
  imageCopyTmpDir: /home/foobar/tmp
  imageStore:
    number: 6
  runRoot: /run/user/1008/containers
  transientStore: false
  volumePath: /home/foobar/.local/share/containers/storage/volumes
version:
  APIVersion: 5.4.1
  Built: 1741727220
  BuiltTime: Tue Mar 11 21:07:00 2025
  GitCommit: b79bc8afe796cba51dd906270a7e1056ccdfcf9e
  GoVersion: go1.24.1
  Os: linux
  OsArch: linux/amd64
  Version: 5.4.1

Podman in a container

No

Privileged Or Rootless

Rootless

Upstream Latest Release

Yes

Additional environment details

No response

Additional information

$ systemctl --user cat --no-pager foobar-pod

# /run/user/1008/systemd/generator/foobar-pod.service
# Automatically generated by /usr/lib/systemd/user-generators/podman-user-generator
# 
[X-Pod]
PodName=foobar
Network=pasta

[Install]
WantedBy=default.target

[Unit]
Wants=podman-user-wait-network-online.service
After=podman-user-wait-network-online.service
SourcePath=/home/foobar/.config/containers/systemd/foobar.pod
RequiresMountsFor=%t/containers

[Service]
SyslogIdentifier=%N
ExecStart=/usr/bin/podman pod start --pod-id-file=%t/%N.pod-id
ExecStop=/usr/bin/podman pod stop --pod-id-file=%t/%N.pod-id --ignore --time=10
ExecStopPost=/usr/bin/podman pod rm --pod-id-file=%t/%N.pod-id --ignore --force
ExecStartPre=/usr/bin/podman pod create --infra-conmon-pidfile=%t/%N.pid --pod-id-file=%t/%N.pod-id --exit-policy=stop --replace --network pasta --infra-name foobar-infra --name foobar
Environment=PODMAN_SYSTEMD_UNIT=%n
Type=forking
Restart=on-failure
PIDFile=%t/%N.pid

Notice the --exit-policy=stop in the command.

Workaround:

[Pod]
PodmanArgs=--exit-policy=continue

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