Quadlet - print warning when fail to parse

Fixes: #26542

Signed-off-by: Ygal Blum <ygal.blum@gmail.com>
This commit is contained in:
Ygal Blum
2025-07-07 14:49:32 -04:00
parent 462df8f894
commit cd807f8ff6
5 changed files with 39 additions and 18 deletions

View File

@ -827,15 +827,16 @@ func (f *UnitFile) LookupAllArgs(groupName string, key string) []string {
// array of words. The split code is exec-like, and both unquotes and
// applied c-style c escapes. This is typically used for keys like
// ExecStart
func (f *UnitFile) LookupLastArgs(groupName string, key string) ([]string, bool) {
func (f *UnitFile) LookupLastArgs(groupName string, key string) ([]string, bool, error) {
execKey, ok := f.LookupLast(groupName, key)
if ok {
execArgs, err := splitString(execKey, WhitespaceSeparators, SplitRelax|SplitUnquote|SplitCUnescape)
if err == nil {
return execArgs, true
}
if !ok {
return nil, false, nil
}
return nil, false
execArgs, err := splitString(execKey, WhitespaceSeparators, SplitRelax|SplitUnquote|SplitCUnescape)
if err != nil {
return nil, false, err
}
return execArgs, true, nil
}
// Look up 'Environment' style key-value keys

View File

@ -621,7 +621,9 @@ func ConvertContainer(container *parser.UnitFile, isUser bool, unitsInfoMap map[
serviceStopCmd.Args[0] = fmt.Sprintf("-%s", serviceStopCmd.Args[0])
service.AddCmdline(ServiceGroup, "ExecStopPost", serviceStopCmd.Args)
if err := handleExecReload(container, service, ContainerGroup, containerName); err != nil {
warn, err = handleExecReload(container, service, ContainerGroup, containerName)
warnings = errors.Join(warnings, warn)
if err != nil {
return nil, warnings, err
}
@ -888,10 +890,11 @@ func ConvertContainer(container *parser.UnitFile, isUser bool, unitsInfoMap map[
podman.add("--rootfs", rootfs)
}
execArgs, ok := container.LookupLastArgs(ContainerGroup, KeyExec)
execArgs, ok, warn := container.LookupLastArgs(ContainerGroup, KeyExec)
if ok {
podman.add(execArgs...)
}
warnings = errors.Join(warnings, warn)
service.AddCmdline(ServiceGroup, "ExecStart", podman.Args)
@ -2169,18 +2172,22 @@ func addDefaultDependencies(service *parser.UnitFile, isUser bool) {
}
}
func handleExecReload(quadletUnitFile, serviceUnitFile *parser.UnitFile, groupName, containerName string) error {
// handleExecReload handles the ExecReload key.
// If return (warning, error)
// An error is returned if both KeyReloadCmd and KeyReloadSignal are set,
// and a warning is returned if it failed to parse the ReloadCmd key.
func handleExecReload(quadletUnitFile, serviceUnitFile *parser.UnitFile, groupName, containerName string) (error, error) {
reloadSignal, signalOk := quadletUnitFile.Lookup(groupName, KeyReloadSignal)
signalOk = signalOk && len(reloadSignal) > 0
reloadcmd, cmdOk := quadletUnitFile.LookupLastArgs(groupName, KeyReloadCmd)
reloadcmd, cmdOk, warn := quadletUnitFile.LookupLastArgs(groupName, KeyReloadCmd)
cmdOk = cmdOk && len(reloadcmd) > 0
if !cmdOk && !signalOk {
return nil
return warn, nil
}
if cmdOk && signalOk {
return fmt.Errorf("%s and %s are mutually exclusive but both are set", KeyReloadCmd, KeyReloadSignal)
return warn, fmt.Errorf("%s and %s are mutually exclusive but both are set", KeyReloadCmd, KeyReloadSignal)
}
serviceReloadCmd := createBasePodmanCommand(quadletUnitFile, groupName)
@ -2192,7 +2199,7 @@ func handleExecReload(quadletUnitFile, serviceUnitFile *parser.UnitFile, groupNa
}
serviceUnitFile.AddCmdline(ServiceGroup, "ExecReload", serviceReloadCmd.Args)
return nil
return warn, nil
}
func translateUnitDependencies(serviceUnitFile *parser.UnitFile, unitsInfoMap map[string]*UnitInfo) error {

View File

@ -0,0 +1,5 @@
## assert-podman-final-args localhost/imagename
[Container]
Image=localhost/imagename
Exec='test\.com'

View File

@ -0,0 +1,5 @@
## assert-podman-final-args localhost/imagename
[Container]
Image=localhost/imagename
ReloadCmd='test\.sh'

View File

@ -232,7 +232,7 @@ func (t *quadletTestcase) assertKeyNotContains(args []string, unit *parser.UnitF
}
func (t *quadletTestcase) assertPodmanArgs(args []string, unit *parser.UnitFile, key string, allowRegex, globalOnly bool) bool {
podmanArgs, _ := unit.LookupLastArgs("Service", key)
podmanArgs, _, _ := unit.LookupLastArgs("Service", key)
if globalOnly {
podmanCmdLocation := findSublist(podmanArgs, []string{args[0]})
if podmanCmdLocation == -1 {
@ -287,7 +287,7 @@ func keyValMapEqualRegex(expectedKeyValMap, actualKeyValMap map[string]string) b
}
func (t *quadletTestcase) assertPodmanArgsKeyVal(args []string, unit *parser.UnitFile, key string, allowRegex, globalOnly bool) bool {
podmanArgs, _ := unit.LookupLastArgs("Service", key)
podmanArgs, _, _ := unit.LookupLastArgs("Service", key)
if globalOnly {
podmanCmdLocation := findSublist(podmanArgs, []string{args[0]})
@ -334,7 +334,7 @@ func (t *quadletTestcase) assertPodmanArgsKeyVal(args []string, unit *parser.Uni
}
func (t *quadletTestcase) assertPodmanFinalArgs(args []string, unit *parser.UnitFile, key string) bool {
podmanArgs, _ := unit.LookupLastArgs("Service", key)
podmanArgs, _, _ := unit.LookupLastArgs("Service", key)
if len(podmanArgs) < len(args) {
return false
}
@ -342,7 +342,7 @@ func (t *quadletTestcase) assertPodmanFinalArgs(args []string, unit *parser.Unit
}
func (t *quadletTestcase) assertPodmanFinalArgsRegex(args []string, unit *parser.UnitFile, key string) bool {
podmanArgs, _ := unit.LookupLastArgs("Service", key)
podmanArgs, _, _ := unit.LookupLastArgs("Service", key)
if len(podmanArgs) < len(args) {
return false
}
@ -1106,6 +1106,9 @@ BOGUS=foo
Entry("Unsupported Service Key - DynamicUser.network", "service-dynamicuser.network", "Warning: using key DynamicUser in the Service group is not supported"),
Entry("Unsupported Service Key - DynamicUser.pod", "service-dynamicuser.pod", "Warning: using key DynamicUser in the Service group is not supported"),
Entry("Unsupported Service Key - DynamicUser.volume", "service-dynamicuser.volume", "Warning: using key DynamicUser in the Service group is not supported"),
Entry("exec-unsupported-escape.container", "exec-unsupported-escape.container", "unsupported escape char"),
Entry("reloadcmd-unsupported-escape.container", "reloadcmd-unsupported-escape.container", "unsupported escape char"),
)
DescribeTable("Running expected error quadlet test case",