mirror of
https://github.com/containers/podman.git
synced 2025-05-20 08:36:23 +08:00
Quadlet - Add support for adding ExecReload command
Add tests Update man page Signed-off-by: Ygal Blum <ygal.blum@gmail.com>
This commit is contained in:
@ -333,6 +333,8 @@ Valid options for `[Container]` are listed below:
|
|||||||
| Pull=never | --pull never |
|
| Pull=never | --pull never |
|
||||||
| ReadOnly=true | --read-only |
|
| ReadOnly=true | --read-only |
|
||||||
| ReadOnlyTmpfs=true | --read-only-tmpfs |
|
| ReadOnlyTmpfs=true | --read-only-tmpfs |
|
||||||
|
| ReloadCmd=/usr/bin/command | Add ExecReload and run exec with the value |
|
||||||
|
| ReloadSignal=SIGHUP | Add ExecReload and run kill with the signal |
|
||||||
| Retry=5 | --retry=5 |
|
| Retry=5 | --retry=5 |
|
||||||
| RetryDelay=5s | --retry-delay=5s |
|
| RetryDelay=5s | --retry-delay=5s |
|
||||||
| Rootfs=/var/lib/rootfs | --rootfs /var/lib/rootfs |
|
| Rootfs=/var/lib/rootfs | --rootfs /var/lib/rootfs |
|
||||||
@ -784,6 +786,22 @@ If enabled, makes the image read-only.
|
|||||||
|
|
||||||
If ReadOnly is set to `true`, mount a read-write tmpfs on /dev, /dev/shm, /run, /tmp, and /var/tmp.
|
If ReadOnly is set to `true`, mount a read-write tmpfs on /dev, /dev/shm, /run, /tmp, and /var/tmp.
|
||||||
|
|
||||||
|
### `ReloadCmd=`
|
||||||
|
|
||||||
|
Add `ExecReload` line to the `Service` that runs ` podman exec` with this command in this container.
|
||||||
|
|
||||||
|
In order to execute the reload run `systemctl reload <Service>`
|
||||||
|
|
||||||
|
Mutually exclusive with `ReloadSignal`
|
||||||
|
|
||||||
|
### `ReloadSignal=`
|
||||||
|
|
||||||
|
Add `ExecReload` line to the `Service` that runs `podman kill` with this signal which sends the signal to the main container process.
|
||||||
|
|
||||||
|
In order to execute the reload run `systemctl reload <Service>`
|
||||||
|
|
||||||
|
Mutually exclusive with `ReloadCmd`
|
||||||
|
|
||||||
### `Retry=`
|
### `Retry=`
|
||||||
|
|
||||||
Number of times to retry the image pull when a HTTP error occurs. Equivalent to the Podman `--retry` option.
|
Number of times to retry the image pull when a HTTP error occurs. Equivalent to the Podman `--retry` option.
|
||||||
|
@ -139,6 +139,8 @@ const (
|
|||||||
KeyPull = "Pull"
|
KeyPull = "Pull"
|
||||||
KeyReadOnly = "ReadOnly"
|
KeyReadOnly = "ReadOnly"
|
||||||
KeyReadOnlyTmpfs = "ReadOnlyTmpfs"
|
KeyReadOnlyTmpfs = "ReadOnlyTmpfs"
|
||||||
|
KeyReloadCmd = "ReloadCmd"
|
||||||
|
KeyReloadSignal = "ReloadSignal"
|
||||||
KeyRemapGid = "RemapGid" // deprecated
|
KeyRemapGid = "RemapGid" // deprecated
|
||||||
KeyRemapUid = "RemapUid" // deprecated
|
KeyRemapUid = "RemapUid" // deprecated
|
||||||
KeyRemapUidSize = "RemapUidSize" // deprecated
|
KeyRemapUidSize = "RemapUidSize" // deprecated
|
||||||
@ -256,6 +258,8 @@ var (
|
|||||||
KeyPull: true,
|
KeyPull: true,
|
||||||
KeyReadOnly: true,
|
KeyReadOnly: true,
|
||||||
KeyReadOnlyTmpfs: true,
|
KeyReadOnlyTmpfs: true,
|
||||||
|
KeyReloadCmd: true,
|
||||||
|
KeyReloadSignal: true,
|
||||||
KeyRemapGid: true,
|
KeyRemapGid: true,
|
||||||
KeyRemapUid: true,
|
KeyRemapUid: true,
|
||||||
KeyRemapUidSize: true,
|
KeyRemapUidSize: true,
|
||||||
@ -578,6 +582,10 @@ func ConvertContainer(container *parser.UnitFile, isUser bool, unitsInfoMap map[
|
|||||||
serviceStopCmd.Args[0] = fmt.Sprintf("-%s", serviceStopCmd.Args[0])
|
serviceStopCmd.Args[0] = fmt.Sprintf("-%s", serviceStopCmd.Args[0])
|
||||||
service.AddCmdline(ServiceGroup, "ExecStopPost", serviceStopCmd.Args)
|
service.AddCmdline(ServiceGroup, "ExecStopPost", serviceStopCmd.Args)
|
||||||
|
|
||||||
|
if err := handleExecReload(container, service, ContainerGroup); err != nil {
|
||||||
|
return nil, warnings, err
|
||||||
|
}
|
||||||
|
|
||||||
podman := createBasePodmanCommand(container, ContainerGroup)
|
podman := createBasePodmanCommand(container, ContainerGroup)
|
||||||
|
|
||||||
podman.add("run")
|
podman.add("run")
|
||||||
@ -2226,3 +2234,29 @@ func addDefaultDependencies(service *parser.UnitFile, isUser bool) {
|
|||||||
service.PrependUnitLine(UnitGroup, "Wants", networkUnit)
|
service.PrependUnitLine(UnitGroup, "Wants", networkUnit)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func handleExecReload(quadletUnitFile, serviceUnitFile *parser.UnitFile, groupName string) error {
|
||||||
|
reloadSignal, signalOk := quadletUnitFile.Lookup(groupName, KeyReloadSignal)
|
||||||
|
signalOk = signalOk && len(reloadSignal) > 0
|
||||||
|
reloadcmd, cmdOk := quadletUnitFile.LookupLastArgs(groupName, KeyReloadCmd)
|
||||||
|
cmdOk = cmdOk && len(reloadcmd) > 0
|
||||||
|
|
||||||
|
if !cmdOk && !signalOk {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
if cmdOk && signalOk {
|
||||||
|
return fmt.Errorf("%s and %s are mutually exclusive but both are set", KeyReloadCmd, KeyReloadSignal)
|
||||||
|
}
|
||||||
|
|
||||||
|
serviceReloadCmd := createBasePodmanCommand(quadletUnitFile, groupName)
|
||||||
|
if cmdOk {
|
||||||
|
serviceReloadCmd.add("exec", "--cidfile=%t/%N.cid")
|
||||||
|
serviceReloadCmd.add(reloadcmd...)
|
||||||
|
} else {
|
||||||
|
serviceReloadCmd.add("kill", "--cidfile=%t/%N.cid", "--signal", reloadSignal)
|
||||||
|
}
|
||||||
|
serviceUnitFile.AddCmdline(ServiceGroup, "ExecReload", serviceReloadCmd.Args)
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
7
test/e2e/quadlet/reloadboth.container
Normal file
7
test/e2e/quadlet/reloadboth.container
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
## assert-failed
|
||||||
|
## assert-stderr-contains "ReloadCmd and ReloadSignal are mutually exclusive but both are set"
|
||||||
|
|
||||||
|
[Container]
|
||||||
|
Image=localhost/imagename
|
||||||
|
ReloadCmd=/usr/bin/command
|
||||||
|
ReloadSignal=SIGHUP
|
8
test/e2e/quadlet/reloadcmd.container
Normal file
8
test/e2e/quadlet/reloadcmd.container
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
## assert-podman-reload-args "exec"
|
||||||
|
## assert-podman-reload-args "--cidfile=%t/%N.cid"
|
||||||
|
## assert-podman-reload-final-args "/some/binary file" "--arg1" "arg 2"
|
||||||
|
|
||||||
|
[Container]
|
||||||
|
Image=localhost/imagename
|
||||||
|
ReloadCmd="/some/binary file" --arg1 \
|
||||||
|
"arg 2"
|
7
test/e2e/quadlet/reloadsignal.container
Normal file
7
test/e2e/quadlet/reloadsignal.container
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
## assert-podman-reload-args "kill"
|
||||||
|
## assert-podman-reload-args "--cidfile=%t/%N.cid"
|
||||||
|
## assert-podman-reload-args "--signal" "SIGHUP"
|
||||||
|
|
||||||
|
[Container]
|
||||||
|
Image=localhost/imagename
|
||||||
|
ReloadSignal=SIGHUP
|
@ -477,6 +477,30 @@ func (t *quadletTestcase) assertStopPostPodmanArgsKeyValRegex(args []string, uni
|
|||||||
return t.assertPodmanArgsKeyVal(args, unit, "ExecStopPost", true, false)
|
return t.assertPodmanArgsKeyVal(args, unit, "ExecStopPost", true, false)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (t *quadletTestcase) assertReloadPodmanArgs(args []string, unit *parser.UnitFile) bool {
|
||||||
|
return t.assertPodmanArgs(args, unit, "ExecReload", false, false)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (t *quadletTestcase) assertReloadPodmanGlobalArgs(args []string, unit *parser.UnitFile) bool {
|
||||||
|
return t.assertPodmanArgs(args, unit, "ExecReload", false, true)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (t *quadletTestcase) assertReloadPodmanFinalArgs(args []string, unit *parser.UnitFile) bool {
|
||||||
|
return t.assertPodmanFinalArgs(args, unit, "ExecReload")
|
||||||
|
}
|
||||||
|
|
||||||
|
func (t *quadletTestcase) assertReloadPodmanFinalArgsRegex(args []string, unit *parser.UnitFile) bool {
|
||||||
|
return t.assertPodmanFinalArgsRegex(args, unit, "ExecReload")
|
||||||
|
}
|
||||||
|
|
||||||
|
func (t *quadletTestcase) assertReloadPodmanArgsKeyVal(args []string, unit *parser.UnitFile) bool {
|
||||||
|
return t.assertPodmanArgsKeyVal(args, unit, "ExecReload", false, false)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (t *quadletTestcase) assertReloadPodmanArgsKeyValRegex(args []string, unit *parser.UnitFile) bool {
|
||||||
|
return t.assertPodmanArgsKeyVal(args, unit, "ExecReload", true, false)
|
||||||
|
}
|
||||||
|
|
||||||
func (t *quadletTestcase) assertSymlink(args []string, unit *parser.UnitFile) bool {
|
func (t *quadletTestcase) assertSymlink(args []string, unit *parser.UnitFile) bool {
|
||||||
Expect(args).To(HaveLen(2))
|
Expect(args).To(HaveLen(2))
|
||||||
symlink := args[0]
|
symlink := args[0]
|
||||||
@ -590,6 +614,18 @@ func (t *quadletTestcase) doAssert(check []string, unit *parser.UnitFile, sessio
|
|||||||
ok = t.assertStopPostPodmanArgsKeyVal(args, unit)
|
ok = t.assertStopPostPodmanArgsKeyVal(args, unit)
|
||||||
case "assert-podman-stop-post-args-key-val-regex":
|
case "assert-podman-stop-post-args-key-val-regex":
|
||||||
ok = t.assertStopPostPodmanArgsKeyValRegex(args, unit)
|
ok = t.assertStopPostPodmanArgsKeyValRegex(args, unit)
|
||||||
|
case "assert-podman-reload-args":
|
||||||
|
ok = t.assertReloadPodmanArgs(args, unit)
|
||||||
|
case "assert-podman-reload-global-args":
|
||||||
|
ok = t.assertReloadPodmanGlobalArgs(args, unit)
|
||||||
|
case "assert-podman-reload-final-args":
|
||||||
|
ok = t.assertReloadPodmanFinalArgs(args, unit)
|
||||||
|
case "assert-podman-reload-final-args-regex":
|
||||||
|
ok = t.assertReloadPodmanFinalArgsRegex(args, unit)
|
||||||
|
case "assert-podman-reload-args-key-val":
|
||||||
|
ok = t.assertReloadPodmanArgsKeyVal(args, unit)
|
||||||
|
case "assert-podman-reload-args-key-val-regex":
|
||||||
|
ok = t.assertReloadPodmanArgsKeyValRegex(args, unit)
|
||||||
|
|
||||||
default:
|
default:
|
||||||
return fmt.Errorf("Unsupported assertion %s", op)
|
return fmt.Errorf("Unsupported assertion %s", op)
|
||||||
@ -926,6 +962,8 @@ BOGUS=foo
|
|||||||
Entry("CgroupMode", "cgroups-mode.container"),
|
Entry("CgroupMode", "cgroups-mode.container"),
|
||||||
Entry("Container - No Default Dependencies", "no_deps.container"),
|
Entry("Container - No Default Dependencies", "no_deps.container"),
|
||||||
Entry("retry.container", "retry.container"),
|
Entry("retry.container", "retry.container"),
|
||||||
|
Entry("reloadcmd.container", "reloadcmd.container"),
|
||||||
|
Entry("reloadsignal.container", "reloadsignal.container"),
|
||||||
|
|
||||||
Entry("basic.volume", "basic.volume"),
|
Entry("basic.volume", "basic.volume"),
|
||||||
Entry("device-copy.volume", "device-copy.volume"),
|
Entry("device-copy.volume", "device-copy.volume"),
|
||||||
@ -1063,6 +1101,7 @@ BOGUS=foo
|
|||||||
Entry("pod.not-found.container", "pod.not-found.container", "converting \"pod.not-found.container\": quadlet pod unit not-found.pod does not exist"),
|
Entry("pod.not-found.container", "pod.not-found.container", "converting \"pod.not-found.container\": quadlet pod unit not-found.pod does not exist"),
|
||||||
Entry("subidmapping-with-remap.container", "subidmapping-with-remap.container", "converting \"subidmapping-with-remap.container\": deprecated Remap keys are set along with explicit mapping keys"),
|
Entry("subidmapping-with-remap.container", "subidmapping-with-remap.container", "converting \"subidmapping-with-remap.container\": deprecated Remap keys are set along with explicit mapping keys"),
|
||||||
Entry("userns-with-remap.container", "userns-with-remap.container", "converting \"userns-with-remap.container\": deprecated Remap keys are set along with explicit mapping keys"),
|
Entry("userns-with-remap.container", "userns-with-remap.container", "converting \"userns-with-remap.container\": deprecated Remap keys are set along with explicit mapping keys"),
|
||||||
|
Entry("reloadboth.container", "reloadboth.container", "converting \"reloadboth.container\": ReloadCmd and ReloadSignal are mutually exclusive but both are set"),
|
||||||
|
|
||||||
Entry("image-no-image.volume", "image-no-image.volume", "converting \"image-no-image.volume\": the key Image is mandatory when using the image driver"),
|
Entry("image-no-image.volume", "image-no-image.volume", "converting \"image-no-image.volume\": the key Image is mandatory when using the image driver"),
|
||||||
Entry("Volume - Quadlet image (.build) not found", "build-not-found.quadlet.volume", "converting \"build-not-found.quadlet.volume\": requested Quadlet image not-found.build was not found"),
|
Entry("Volume - Quadlet image (.build) not found", "build-not-found.quadlet.volume", "converting \"build-not-found.quadlet.volume\": requested Quadlet image not-found.build was not found"),
|
||||||
|
Reference in New Issue
Block a user