diff --git a/cmd/quadlet/main.go b/cmd/quadlet/main.go index 88483b78d9..ff113499da 100644 --- a/cmd/quadlet/main.go +++ b/cmd/quadlet/main.go @@ -449,6 +449,18 @@ func generateServiceFile(service *parser.UnitFile) error { return nil } +func gatherDependentSymlinks(service *parser.UnitFile, key, dir, filename string) []string { + symlinks := make([]string, 0) + groupBy := service.LookupAllStrv(quadlet.InstallGroup, key) + for _, groupByUnit := range groupBy { + // Only allow filenames, not paths + if !strings.Contains(groupByUnit, "/") { + symlinks = append(symlinks, fmt.Sprintf("%s.%s/%s", groupByUnit, dir, filename)) + } + } + return symlinks +} + // This parses the `Install` group of the unit file and creates the required // symlinks to get systemd to start the newly generated file as needed. // In a traditional setup this is done by "systemctl enable", but that doesn't @@ -476,21 +488,9 @@ func enableServiceFile(outputPath string, service *parser.UnitFile) { } if serviceFilename != "" { - wantedBy := service.LookupAllStrv(quadlet.InstallGroup, "WantedBy") - for _, wantedByUnit := range wantedBy { - // Only allow filenames, not paths - if !strings.Contains(wantedByUnit, "/") { - symlinks = append(symlinks, fmt.Sprintf("%s.wants/%s", wantedByUnit, serviceFilename)) - } - } - - requiredBy := service.LookupAllStrv(quadlet.InstallGroup, "RequiredBy") - for _, requiredByUnit := range requiredBy { - // Only allow filenames, not paths - if !strings.Contains(requiredByUnit, "/") { - symlinks = append(symlinks, fmt.Sprintf("%s.requires/%s", requiredByUnit, serviceFilename)) - } - } + symlinks = append(symlinks, gatherDependentSymlinks(service, "WantedBy", "wants", serviceFilename)...) + symlinks = append(symlinks, gatherDependentSymlinks(service, "RequiredBy", "requires", serviceFilename)...) + symlinks = append(symlinks, gatherDependentSymlinks(service, "UpheldBy", "upholds", serviceFilename)...) } for _, symlinkRel := range symlinks { diff --git a/docs/source/markdown/podman-systemd.unit.5.md b/docs/source/markdown/podman-systemd.unit.5.md index b5dfd8970e..1eb05d522f 100644 --- a/docs/source/markdown/podman-systemd.unit.5.md +++ b/docs/source/markdown/podman-systemd.unit.5.md @@ -129,7 +129,7 @@ For example, to start a container on boot, add something like this to the file: WantedBy=default.target ``` -Currently, only the `Alias`, `WantedBy` and `RequiredBy` keys are supported. +Currently, only the `Alias`, `WantedBy`, `RequiredBy`, and `UpheldBy` keys are supported. The Install section can be part of the main file, or it can be in a separate drop-in file as described above. The latter allows you to diff --git a/test/e2e/quadlet/install.container b/test/e2e/quadlet/install.container index 80c1cd19a1..2d79fcffca 100644 --- a/test/e2e/quadlet/install.container +++ b/test/e2e/quadlet/install.container @@ -7,6 +7,9 @@ ## assert-symlink req1.service.requires/install.service ../install.service ## assert-symlink req2.service.requires/install.service ../install.service ## assert-symlink req3.service.requires/install.service ../install.service +## assert-symlink up1.service.upholds/install.service ../install.service +## assert-symlink up2.service.upholds/install.service ../install.service +## assert-symlink up3.service.upholds/install.service ../install.service [Container] Image=localhost/imagename @@ -19,3 +22,5 @@ WantedBy=want1.service want2.service WantedBy=want3.service RequiredBy=req1.service req2.service RequiredBy=req3.service +UpheldBy=up1.service up2.service +UpheldBy=up3.service