From 7e2a8d58abaf56f8f81ac2bfa213a40a5f7f967c Mon Sep 17 00:00:00 2001 From: Ygal Blum Date: Sun, 3 Dec 2023 10:23:13 +0200 Subject: [PATCH] Quadlet .pod - add support for the Volume Key Add e2e tests Update documentation Signed-off-by: Ygal Blum --- docs/source/markdown/podman-systemd.unit.5.md | 15 ++++ pkg/systemd/quadlet/quadlet.go | 75 +++++++++++-------- test/e2e/quadlet/volume.pod | 15 ++++ test/e2e/quadlet_test.go | 1 + 4 files changed, 75 insertions(+), 31 deletions(-) create mode 100644 test/e2e/quadlet/volume.pod diff --git a/docs/source/markdown/podman-systemd.unit.5.md b/docs/source/markdown/podman-systemd.unit.5.md index fd11811e31..b90695d2ba 100644 --- a/docs/source/markdown/podman-systemd.unit.5.md +++ b/docs/source/markdown/podman-systemd.unit.5.md @@ -697,6 +697,7 @@ Valid options for `[Container]` are listed below: | Network=host | --network host | | PodmanArgs=\-\-cpus=2 | --cpus=2 | | PodName=name | --name=name | +| Volume=/source:/dest | --volume /source:/dest | Supported keys in the `[Pod]` section are: @@ -754,6 +755,20 @@ prefix to avoid conflicts with user-managed containers. Please note that pods and containers cannot have the same name. So, if PodName is set, it must not conflict with any container. +### `Volume=` + +Mount a volume in the pod. This is equivalent to the Podman `--volume` option, and +generally has the form `[[SOURCE-VOLUME|HOST-DIR:]CONTAINER-DIR[:OPTIONS]]`. + +If `SOURCE-VOLUME` starts with `.`, Quadlet resolves the path relative to the location of the unit file. + +As a special case, if `SOURCE-VOLUME` ends with `.volume`, Quadlet will look for the corresponding `.volume` Quadlet unit. +If found, Quadlet will use the name of the Volume set in the Unit, otherwise, `systemd-$name` is used. +The generated systemd service contains a dependency on the service unit generated for that `.volume` unit, +or on `$name-volume.service` if the `.volume` unit is not found + +This key can be listed multiple times. + ## Kube units [Kube] Kube units are named with a `.kube` extension and contain a `[Kube]` section describing diff --git a/pkg/systemd/quadlet/quadlet.go b/pkg/systemd/quadlet/quadlet.go index 74d1c33c74..349d55bc79 100644 --- a/pkg/systemd/quadlet/quadlet.go +++ b/pkg/systemd/quadlet/quadlet.go @@ -324,6 +324,7 @@ var ( KeyNetwork: true, KeyPodmanArgs: true, KeyPodName: true, + KeyVolume: true, } ) @@ -667,37 +668,8 @@ func ConvertContainer(container *parser.UnitFile, names map[string]string, isUse podman.add("--tmpfs", tmpfs) } - volumes := container.LookupAll(ContainerGroup, KeyVolume) - for _, volume := range volumes { - parts := strings.SplitN(volume, ":", 3) - - source := "" - var dest string - options := "" - if len(parts) >= 2 { - source = parts[0] - dest = parts[1] - } else { - dest = parts[0] - } - if len(parts) >= 3 { - options = ":" + parts[2] - } - - if source != "" { - var err error - source, err = handleStorageSource(container, service, source, names) - if err != nil { - return nil, err - } - } - - podman.add("-v") - if source == "" { - podman.add(dest) - } else { - podman.addf("%s:%s%s", source, dest, options) - } + if err := addVolumes(container, service, ContainerGroup, names, podman); err != nil { + return nil, err } update, ok := container.Lookup(ContainerGroup, KeyAutoUpdate) @@ -1325,6 +1297,10 @@ func ConvertPod(podUnit *parser.UnitFile, name string, podsInfoMap map[string]*P addNetworks(podUnit, PodGroup, service, names, execStartPre) + if err := addVolumes(podUnit, service, PodGroup, names, execStartPre); err != nil { + return nil, err + } + execStartPre.addf("--name=%s", podName) handlePodmanArgs(podUnit, PodGroup, execStartPre) @@ -1824,3 +1800,40 @@ func handlePod(quadletUnitFile, serviceUnitFile *parser.UnitFile, groupName stri } return nil } + +func addVolumes(quadletUnitFile, serviceUnitFile *parser.UnitFile, groupName string, names map[string]string, podman *PodmanCmdline) error { + volumes := quadletUnitFile.LookupAll(groupName, KeyVolume) + for _, volume := range volumes { + parts := strings.SplitN(volume, ":", 3) + + source := "" + var dest string + options := "" + if len(parts) >= 2 { + source = parts[0] + dest = parts[1] + } else { + dest = parts[0] + } + if len(parts) >= 3 { + options = ":" + parts[2] + } + + if source != "" { + var err error + source, err = handleStorageSource(quadletUnitFile, serviceUnitFile, source, names) + if err != nil { + return err + } + } + + podman.add("-v") + if source == "" { + podman.add(dest) + } else { + podman.addf("%s:%s%s", source, dest, options) + } + } + + return nil +} diff --git a/test/e2e/quadlet/volume.pod b/test/e2e/quadlet/volume.pod new file mode 100644 index 0000000000..7950b0ab54 --- /dev/null +++ b/test/e2e/quadlet/volume.pod @@ -0,0 +1,15 @@ +## assert-podman-pre-args -v /host/dir:/container/volume +## assert-podman-pre-args -v /host/dir2:/container/volume2:Z +## assert-podman-pre-args-regex -v .*/podman_test.*/quadlet/host/dir3:/container/volume3 +## assert-podman-pre-args -v named:/container/named +## assert-podman-pre-args -v systemd-quadlet:/container/quadlet +## assert-podman-pre-args -v %h/container:/container/volume4 + +[Pod] +Volume=/host/dir:/container/volume +Volume=/host/dir2:/container/volume2:Z +Volume=./host/dir3:/container/volume3 +Volume=/container/empty +Volume=named:/container/named +Volume=quadlet.volume:/container/quadlet +Volume=%h/container:/container/volume4 diff --git a/test/e2e/quadlet_test.go b/test/e2e/quadlet_test.go index ee71cd6231..a89107e13d 100644 --- a/test/e2e/quadlet_test.go +++ b/test/e2e/quadlet_test.go @@ -904,6 +904,7 @@ BOGUS=foo Entry("network.pod", "network.pod", 0, ""), Entry("network-quadlet.pod", "network.quadlet.pod", 0, ""), Entry("podmanargs.pod", "podmanargs.pod", 0, ""), + Entry("volume.pod", "volume.pod", 0, ""), ) })