Quadlet .pod - add support for the Volume Key

Add e2e tests
Update documentation

Signed-off-by: Ygal Blum <ygal.blum@gmail.com>
This commit is contained in:
Ygal Blum
2023-12-03 10:23:13 +02:00
parent 212b4c9e93
commit 7e2a8d58ab
4 changed files with 75 additions and 31 deletions

View File

@ -697,6 +697,7 @@ Valid options for `[Container]` are listed below:
| Network=host | --network host | | Network=host | --network host |
| PodmanArgs=\-\-cpus=2 | --cpus=2 | | PodmanArgs=\-\-cpus=2 | --cpus=2 |
| PodName=name | --name=name | | PodName=name | --name=name |
| Volume=/source:/dest | --volume /source:/dest |
Supported keys in the `[Pod]` section are: 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. Please note that pods and containers cannot have the same name.
So, if PodName is set, it must not conflict with any container. 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 [Kube]
Kube units are named with a `.kube` extension and contain a `[Kube]` section describing Kube units are named with a `.kube` extension and contain a `[Kube]` section describing

View File

@ -324,6 +324,7 @@ var (
KeyNetwork: true, KeyNetwork: true,
KeyPodmanArgs: true, KeyPodmanArgs: true,
KeyPodName: true, KeyPodName: true,
KeyVolume: true,
} }
) )
@ -667,37 +668,8 @@ func ConvertContainer(container *parser.UnitFile, names map[string]string, isUse
podman.add("--tmpfs", tmpfs) podman.add("--tmpfs", tmpfs)
} }
volumes := container.LookupAll(ContainerGroup, KeyVolume) if err := addVolumes(container, service, ContainerGroup, names, podman); err != nil {
for _, volume := range volumes { return nil, err
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)
}
} }
update, ok := container.Lookup(ContainerGroup, KeyAutoUpdate) 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) addNetworks(podUnit, PodGroup, service, names, execStartPre)
if err := addVolumes(podUnit, service, PodGroup, names, execStartPre); err != nil {
return nil, err
}
execStartPre.addf("--name=%s", podName) execStartPre.addf("--name=%s", podName)
handlePodmanArgs(podUnit, PodGroup, execStartPre) handlePodmanArgs(podUnit, PodGroup, execStartPre)
@ -1824,3 +1800,40 @@ func handlePod(quadletUnitFile, serviceUnitFile *parser.UnitFile, groupName stri
} }
return nil 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
}

View File

@ -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

View File

@ -904,6 +904,7 @@ BOGUS=foo
Entry("network.pod", "network.pod", 0, ""), Entry("network.pod", "network.pod", 0, ""),
Entry("network-quadlet.pod", "network.quadlet.pod", 0, ""), Entry("network-quadlet.pod", "network.quadlet.pod", 0, ""),
Entry("podmanargs.pod", "podmanargs.pod", 0, ""), Entry("podmanargs.pod", "podmanargs.pod", 0, ""),
Entry("volume.pod", "volume.pod", 0, ""),
) )
}) })