Merge pull request #23427 from ygalblum/quadlet-pod-service-name

Allow setting the service name of Quadlet .pod units
This commit is contained in:
openshift-merge-bot[bot] 2024-07-30 12:54:29 +00:00 • committed by GitHub
commit b4d0c95f4e
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
4 changed files with 250 additions and 226 deletions

View file

@ -863,6 +863,7 @@ Valid options for `[Pod]` are listed below:
| PodmanArgs=\-\-cpus=2 | --cpus=2 |
| PodName=name | --name=name |
| PublishPort=50-59 | --publish 50-59 |
| ServiceName=name | Name the systemd unit `name.service` |
| Volume=/source:/dest | --volume /source:/dest |
Supported keys in the `[Pod]` section are:
@ -947,6 +948,14 @@ When using `host` networking via `Network=host`, the `PublishPort=` option canno
This key can be listed multiple times.
### `ServiceName=`
By default, Quadlet will name the systemd service unit by appending `-pod` to the name of the Quadlet.
Setting this key overrides this behavior by instructing Quadlet to use the provided name.
Note, the name should not include the `.service` file extension
### `Volume=`
Mount a volume in the pod. This is equivalent to the Podman `--volume` option, and

View file

@ -143,6 +143,7 @@ const (
KeySecurityLabelLevel = "SecurityLabelLevel"
KeySecurityLabelNested = "SecurityLabelNested"
KeySecurityLabelType = "SecurityLabelType"
KeyServiceName = "ServiceName"
KeySetWorkingDirectory = "SetWorkingDirectory"
KeyShmSize = "ShmSize"
KeyStopSignal = "StopSignal"
@ -373,6 +374,7 @@ var (
KeyPodName: true,
KeyPodmanArgs: true,
KeyPublishPort: true,
KeyServiceName: true,
KeyVolume: true,
}
)
@ -1474,6 +1476,9 @@ func GetBuiltImageName(buildUnit *parser.UnitFile) string {
}
func GetPodServiceName(podUnit *parser.UnitFile) string {
if serviceName, ok := podUnit.Lookup(PodGroup, KeyServiceName); ok {
return serviceName
}
return replaceExtension(podUnit.Filename, "", "", "-pod")
}

View file

@ -0,0 +1,5 @@
## assert-podman-pre-args "--name=test-pod"
[Pod]
PodName=test-pod
ServiceName=test-pod

View file

@ -36,24 +36,29 @@ func getGenericTemplateFile(fileName string) (bool, string) {
return false, ""
}
func loadQuadletTestcase(path string) *quadletTestcase {
func loadQuadletTestcase(path, serviceName string) *quadletTestcase {
data, err := os.ReadFile(path)
Expect(err).ToNot(HaveOccurred())
base := filepath.Base(path)
ext := filepath.Ext(base)
service := base[:len(base)-len(ext)]
switch ext {
case ".volume":
service += "-volume"
case ".network":
service += "-network"
case ".image":
service += "-image"
case ".build":
service += "-build"
case ".pod":
service += "-pod"
var service string
if len(serviceName) > 0 {
service = serviceName
} else {
base := filepath.Base(path)
ext := filepath.Ext(base)
service = base[:len(base)-len(ext)]
switch ext {
case ".volume":
service += "-volume"
case ".network":
service += "-network"
case ".image":
service += "-image"
case ".build":
service += "-build"
case ".pod":
service += "-pod"
}
}
service += ".service"
@ -609,8 +614,8 @@ var _ = Describe("quadlet system generator", func() {
generatedDir string
quadletDir string
runQuadletTestCase = func(fileName string, exitCode int, errString string) {
testcase := loadQuadletTestcase(filepath.Join("quadlet", fileName))
runQuadletTestCase = func(fileName string, exitCode int, errString string, serviceName string) {
testcase := loadQuadletTestcase(filepath.Join("quadlet", fileName), serviceName)
// Write the tested file to the quadlet dir
err = os.WriteFile(filepath.Join(quadletDir, fileName), testcase.data, 0644)
@ -670,7 +675,7 @@ var _ = Describe("quadlet system generator", func() {
Describe("Running quadlet dryrun tests", func() {
It("Should exit with an error because of no files are found to parse", func() {
fileName := "basic.kube"
testcase := loadQuadletTestcase(filepath.Join("quadlet", fileName))
testcase := loadQuadletTestcase(filepath.Join("quadlet", fileName), "")
// Write the tested file to the quadlet dir
err = os.WriteFile(filepath.Join(quadletDir, fileName), testcase.data, 0644)
@ -733,7 +738,7 @@ BOGUS=foo
It("Should parse a kube file and print it to stdout", func() {
fileName := "basic.kube"
testcase := loadQuadletTestcase(filepath.Join("quadlet", fileName))
testcase := loadQuadletTestcase(filepath.Join("quadlet", fileName), "")
// quadlet uses PODMAN env to get a stable podman path
podmanPath, found := os.LookupEnv("PODMAN")
@ -788,229 +793,229 @@ BOGUS=foo
DescribeTable("Running quadlet test case",
runQuadletTestCase,
Entry("Basic container", "basic.container", 0, ""),
Entry("annotation.container", "annotation.container", 0, ""),
Entry("autoupdate.container", "autoupdate.container", 0, ""),
Entry("basepodman.container", "basepodman.container", 0, ""),
Entry("capabilities.container", "capabilities.container", 0, ""),
Entry("capabilities2.container", "capabilities2.container", 0, ""),
Entry("comment-with-continuation.container", "comment-with-continuation.container", 0, ""),
Entry("devices.container", "devices.container", 0, ""),
Entry("disableselinux.container", "disableselinux.container", 0, ""),
Entry("dns-options.container", "dns-options.container", 0, ""),
Entry("dns-search.container", "dns-search.container", 0, ""),
Entry("dns.container", "dns.container", 0, ""),
Entry("env-file.container", "env-file.container", 0, ""),
Entry("env-host-false.container", "env-host-false.container", 0, ""),
Entry("env-host.container", "env-host.container", 0, ""),
Entry("env.container", "env.container", 0, ""),
Entry("entrypoint.container", "entrypoint.container", 0, ""),
Entry("escapes.container", "escapes.container", 0, ""),
Entry("exec.container", "exec.container", 0, ""),
Entry("group-add.container", "group-add.container", 0, ""),
Entry("health.container", "health.container", 0, ""),
Entry("hostname.container", "hostname.container", 0, ""),
Entry("idmapping.container", "idmapping.container", 0, ""),
Entry("idmapping-with-remap.container", "idmapping-with-remap.container", 1, "converting \"idmapping-with-remap.container\": deprecated Remap keys are set along with explicit mapping keys"),
Entry("image.container", "image.container", 0, ""),
Entry("install.container", "install.container", 0, ""),
Entry("ip.container", "ip.container", 0, ""),
Entry("label.container", "label.container", 0, ""),
Entry("line-continuation-whitespace.container", "line-continuation-whitespace.container", 0, ""),
Entry("logdriver.container", "logdriver.container", 0, ""),
Entry("logopt.container", "logopt.container", 0, ""),
Entry("mask.container", "mask.container", 0, ""),
Entry("mount.container", "mount.container", 0, ""),
Entry("name.container", "name.container", 0, ""),
Entry("nestedselinux.container", "nestedselinux.container", 0, ""),
Entry("network.container", "network.container", 0, ""),
Entry("network.quadlet.container", "network.quadlet.container", 0, ""),
Entry("noimage.container", "noimage.container", 1, "converting \"noimage.container\": no Image or Rootfs key specified"),
Entry("notify.container", "notify.container", 0, ""),
Entry("notify-healthy.container", "notify-healthy.container", 0, ""),
Entry("oneshot.container", "oneshot.container", 0, ""),
Entry("other-sections.container", "other-sections.container", 0, ""),
Entry("pod.non-quadlet.container", "pod.non-quadlet.container", 1, "converting \"pod.non-quadlet.container\": pod test-pod is not Quadlet based"),
Entry("pod.not-found.container", "pod.not-found.container", 1, "converting \"pod.not-found.container\": quadlet pod unit not-found.pod does not exist"),
Entry("podmanargs.container", "podmanargs.container", 0, ""),
Entry("ports.container", "ports.container", 0, ""),
Entry("ports_ipv6.container", "ports_ipv6.container", 0, ""),
Entry("pull.container", "pull.container", 0, ""),
Entry("quotes.container", "quotes.container", 0, ""),
Entry("readonly.container", "readonly.container", 0, ""),
Entry("readonly-tmpfs.container", "readonly-tmpfs.container", 0, ""),
Entry("readonly-notmpfs.container", "readonly-notmpfs.container", 0, ""),
Entry("readwrite-notmpfs.container", "readwrite-notmpfs.container", 0, ""),
Entry("volatiletmp-readwrite.container", "volatiletmp-readwrite.container", 0, ""),
Entry("volatiletmp-readonly.container", "volatiletmp-readonly.container", 0, ""),
Entry("remap-auto.container", "remap-auto.container", 0, ""),
Entry("remap-auto2.container", "remap-auto2.container", 0, ""),
Entry("remap-keep-id.container", "remap-keep-id.container", 0, ""),
Entry("remap-keep-id2.container", "remap-keep-id2.container", 0, ""),
Entry("remap-manual.container", "remap-manual.container", 0, ""),
Entry("rootfs.container", "rootfs.container", 0, ""),
Entry("seccomp.container", "seccomp.container", 0, ""),
Entry("secrets.container", "secrets.container", 0, ""),
Entry("selinux.container", "selinux.container", 0, ""),
Entry("shmsize.container", "shmsize.container", 0, ""),
Entry("shortname.container", "shortname.container", 0, "Warning: shortname.container specifies the image \"shortname\" which not a fully qualified image name. This is not ideal for performance and security reasons. See the podman-pull manpage discussion of short-name-aliases.conf for details."),
Entry("stopsigal.container", "stopsignal.container", 0, ""),
Entry("stoptimeout.container", "stoptimeout.container", 0, ""),
Entry("subidmapping.container", "subidmapping.container", 0, ""),
Entry("subidmapping-with-remap.container", "subidmapping-with-remap.container", 1, "converting \"subidmapping-with-remap.container\": deprecated Remap keys are set along with explicit mapping keys"),
Entry("sysctl.container", "sysctl.container", 0, ""),
Entry("timezone.container", "timezone.container", 0, ""),
Entry("ulimit.container", "ulimit.container", 0, ""),
Entry("unmask.container", "unmask.container", 0, ""),
Entry("user.container", "user.container", 0, ""),
Entry("userns.container", "userns.container", 0, ""),
Entry("userns-with-remap.container", "userns-with-remap.container", 1, "converting \"userns-with-remap.container\": deprecated Remap keys are set along with explicit mapping keys"),
Entry("volume.container", "volume.container", 0, ""),
Entry("workingdir.container", "workingdir.container", 0, ""),
Entry("Container - global args", "globalargs.container", 0, ""),
Entry("Container - Containers Conf Modules", "containersconfmodule.container", 0, ""),
Entry("merged.container", "merged.container", 0, ""),
Entry("merged-override.container", "merged-override.container", 0, ""),
Entry("template@.container", "template@.container", 0, ""),
Entry("template@instance.container", "template@instance.container", 0, ""),
Entry("Unit After Override", "unit-after-override.container", 0, ""),
Entry("NetworkAlias", "network-alias.container", 0, ""),
Entry("Basic container", "basic.container", 0, "", ""),
Entry("annotation.container", "annotation.container", 0, "", ""),
Entry("autoupdate.container", "autoupdate.container", 0, "", ""),
Entry("basepodman.container", "basepodman.container", 0, "", ""),
Entry("capabilities.container", "capabilities.container", 0, "", ""),
Entry("capabilities2.container", "capabilities2.container", 0, "", ""),
Entry("comment-with-continuation.container", "comment-with-continuation.container", 0, "", ""),
Entry("devices.container", "devices.container", 0, "", ""),
Entry("disableselinux.container", "disableselinux.container", 0, "", ""),
Entry("dns-options.container", "dns-options.container", 0, "", ""),
Entry("dns-search.container", "dns-search.container", 0, "", ""),
Entry("dns.container", "dns.container", 0, "", ""),
Entry("env-file.container", "env-file.container", 0, "", ""),
Entry("env-host-false.container", "env-host-false.container", 0, "", ""),
Entry("env-host.container", "env-host.container", 0, "", ""),
Entry("env.container", "env.container", 0, "", ""),
Entry("entrypoint.container", "entrypoint.container", 0, "", ""),
Entry("escapes.container", "escapes.container", 0, "", ""),
Entry("exec.container", "exec.container", 0, "", ""),
Entry("group-add.container", "group-add.container", 0, "", ""),
Entry("health.container", "health.container", 0, "", ""),
Entry("hostname.container", "hostname.container", 0, "", ""),
Entry("idmapping.container", "idmapping.container", 0, "", ""),
Entry("idmapping-with-remap.container", "idmapping-with-remap.container", 1, "converting \"idmapping-with-remap.container\": deprecated Remap keys are set along with explicit mapping keys", ""),
Entry("image.container", "image.container", 0, "", ""),
Entry("install.container", "install.container", 0, "", ""),
Entry("ip.container", "ip.container", 0, "", ""),
Entry("label.container", "label.container", 0, "", ""),
Entry("line-continuation-whitespace.container", "line-continuation-whitespace.container", 0, "", ""),
Entry("logdriver.container", "logdriver.container", 0, "", ""),
Entry("logopt.container", "logopt.container", 0, "", ""),
Entry("mask.container", "mask.container", 0, "", ""),
Entry("mount.container", "mount.container", 0, "", ""),
Entry("name.container", "name.container", 0, "", ""),
Entry("nestedselinux.container", "nestedselinux.container", 0, "", ""),
Entry("network.container", "network.container", 0, "", ""),
Entry("network.quadlet.container", "network.quadlet.container", 0, "", ""),
Entry("noimage.container", "noimage.container", 1, "converting \"noimage.container\": no Image or Rootfs key specified", ""),
Entry("notify.container", "notify.container", 0, "", ""),
Entry("notify-healthy.container", "notify-healthy.container", 0, "", ""),
Entry("oneshot.container", "oneshot.container", 0, "", ""),
Entry("other-sections.container", "other-sections.container", 0, "", ""),
Entry("pod.non-quadlet.container", "pod.non-quadlet.container", 1, "converting \"pod.non-quadlet.container\": pod test-pod is not Quadlet based", ""),
Entry("pod.not-found.container", "pod.not-found.container", 1, "converting \"pod.not-found.container\": quadlet pod unit not-found.pod does not exist", ""),
Entry("podmanargs.container", "podmanargs.container", 0, "", ""),
Entry("ports.container", "ports.container", 0, "", ""),
Entry("ports_ipv6.container", "ports_ipv6.container", 0, "", ""),
Entry("pull.container", "pull.container", 0, "", ""),
Entry("quotes.container", "quotes.container", 0, "", ""),
Entry("readonly.container", "readonly.container", 0, "", ""),
Entry("readonly-tmpfs.container", "readonly-tmpfs.container", 0, "", ""),
Entry("readonly-notmpfs.container", "readonly-notmpfs.container", 0, "", ""),
Entry("readwrite-notmpfs.container", "readwrite-notmpfs.container", 0, "", ""),
Entry("volatiletmp-readwrite.container", "volatiletmp-readwrite.container", 0, "", ""),
Entry("volatiletmp-readonly.container", "volatiletmp-readonly.container", 0, "", ""),
Entry("remap-auto.container", "remap-auto.container", 0, "", ""),
Entry("remap-auto2.container", "remap-auto2.container", 0, "", ""),
Entry("remap-keep-id.container", "remap-keep-id.container", 0, "", ""),
Entry("remap-keep-id2.container", "remap-keep-id2.container", 0, "", ""),
Entry("remap-manual.container", "remap-manual.container", 0, "", ""),
Entry("rootfs.container", "rootfs.container", 0, "", ""),
Entry("seccomp.container", "seccomp.container", 0, "", ""),
Entry("secrets.container", "secrets.container", 0, "", ""),
Entry("selinux.container", "selinux.container", 0, "", ""),
Entry("shmsize.container", "shmsize.container", 0, "", ""),
Entry("shortname.container", "shortname.container", 0, "Warning: shortname.container specifies the image \"shortname\" which not a fully qualified image name. This is not ideal for performance and security reasons. See the podman-pull manpage discussion of short-name-aliases.conf for details.", ""),
Entry("stopsigal.container", "stopsignal.container", 0, "", ""),
Entry("stoptimeout.container", "stoptimeout.container", 0, "", ""),
Entry("subidmapping.container", "subidmapping.container", 0, "", ""),
Entry("subidmapping-with-remap.container", "subidmapping-with-remap.container", 1, "converting \"subidmapping-with-remap.container\": deprecated Remap keys are set along with explicit mapping keys", ""),
Entry("sysctl.container", "sysctl.container", 0, "", ""),
Entry("timezone.container", "timezone.container", 0, "", ""),
Entry("ulimit.container", "ulimit.container", 0, "", ""),
Entry("unmask.container", "unmask.container", 0, "", ""),
Entry("user.container", "user.container", 0, "", ""),
Entry("userns.container", "userns.container", 0, "", ""),
Entry("userns-with-remap.container", "userns-with-remap.container", 1, "converting \"userns-with-remap.container\": deprecated Remap keys are set along with explicit mapping keys", ""),
Entry("volume.container", "volume.container", 0, "", ""),
Entry("workingdir.container", "workingdir.container", 0, "", ""),
Entry("Container - global args", "globalargs.container", 0, "", ""),
Entry("Container - Containers Conf Modules", "containersconfmodule.container", 0, "", ""),
Entry("merged.container", "merged.container", 0, "", ""),
Entry("merged-override.container", "merged-override.container", 0, "", ""),
Entry("template@.container", "template@.container", 0, "", ""),
Entry("template@instance.container", "template@instance.container", 0, "", ""),
Entry("Unit After Override", "unit-after-override.container", 0, "", ""),
Entry("NetworkAlias", "network-alias.container", 0, "", ""),
Entry("basic.volume", "basic.volume", 0, ""),
Entry("device-copy.volume", "device-copy.volume", 0, ""),
Entry("device.volume", "device.volume", 0, ""),
Entry("label.volume", "label.volume", 0, ""),
Entry("name.volume", "name.volume", 0, ""),
Entry("podmanargs.volume", "podmanargs.volume", 0, ""),
Entry("uid.volume", "uid.volume", 0, ""),
Entry("image.volume", "image.volume", 0, ""),
Entry("image-no-image.volume", "image-no-image.volume", 1, "converting \"image-no-image.volume\": the key Image is mandatory when using the image driver"),
Entry("Volume - global args", "globalargs.volume", 0, ""),
Entry("Volume - Containers Conf Modules", "containersconfmodule.volume", 0, ""),
Entry("Volume - Quadlet image (.build) not found", "build-not-found.quadlet.volume", 1, "converting \"build-not-found.quadlet.volume\": requested Quadlet image not-found.build was not found"),
Entry("Volume - Quadlet image (.image) not found", "image-not-found.quadlet.volume", 1, "converting \"image-not-found.quadlet.volume\": requested Quadlet image not-found.image was not found"),
Entry("basic.volume", "basic.volume", 0, "", ""),
Entry("device-copy.volume", "device-copy.volume", 0, "", ""),
Entry("device.volume", "device.volume", 0, "", ""),
Entry("label.volume", "label.volume", 0, "", ""),
Entry("name.volume", "name.volume", 0, "", ""),
Entry("podmanargs.volume", "podmanargs.volume", 0, "", ""),
Entry("uid.volume", "uid.volume", 0, "", ""),
Entry("image.volume", "image.volume", 0, "", ""),
Entry("image-no-image.volume", "image-no-image.volume", 1, "converting \"image-no-image.volume\": the key Image is mandatory when using the image driver", ""),
Entry("Volume - global args", "globalargs.volume", 0, "", ""),
Entry("Volume - Containers Conf Modules", "containersconfmodule.volume", 0, "", ""),
Entry("Volume - Quadlet image (.build) not found", "build-not-found.quadlet.volume", 1, "converting \"build-not-found.quadlet.volume\": requested Quadlet image not-found.build was not found", ""),
Entry("Volume - Quadlet image (.image) not found", "image-not-found.quadlet.volume", 1, "converting \"image-not-found.quadlet.volume\": requested Quadlet image not-found.image was not found", ""),
Entry("Absolute Path", "absolute.path.kube", 0, ""),
Entry("Basic kube", "basic.kube", 0, ""),
Entry("Kube - ConfigMap", "configmap.kube", 0, ""),
Entry("Kube - Exit Code Propagation", "exit_code_propagation.kube", 0, ""),
Entry("Kube - Logdriver", "logdriver.kube", 0, ""),
Entry("Kube - Logopt", "logopt.kube", 0, ""),
Entry("Kube - Network", "network.kube", 0, ""),
Entry("Kube - PodmanArgs", "podmanargs.kube", 0, ""),
Entry("Kube - Publish IPv4 ports", "ports.kube", 0, ""),
Entry("Kube - Publish IPv6 ports", "ports_ipv6.kube", 0, ""),
Entry("Kube - Quadlet Network", "network.quadlet.kube", 0, ""),
Entry("Kube - User Remap Auto with IDs", "remap-auto2.kube", 0, ""),
Entry("Kube - User Remap Auto", "remap-auto.kube", 0, ""),
Entry("Kube - User Remap Manual", "remap-manual.kube", 1, "converting \"remap-manual.kube\": RemapUsers=manual is not supported"),
Entry("Syslog Identifier", "syslog.identifier.kube", 0, ""),
Entry("Kube - Working Directory YAML Absolute Path", "workingdir-yaml-abs.kube", 0, ""),
Entry("Kube - Working Directory YAML Relative Path", "workingdir-yaml-rel.kube", 0, ""),
Entry("Kube - Working Directory Unit", "workingdir-unit.kube", 0, ""),
Entry("Kube - Working Directory already in Service", "workingdir-service.kube", 0, ""),
Entry("Kube - global args", "globalargs.kube", 0, ""),
Entry("Kube - Containers Conf Modules", "containersconfmodule.kube", 0, ""),
Entry("Kube - Service Type=oneshot", "oneshot.kube", 0, ""),
Entry("Kube - Down force", "downforce.kube", 0, ""),
Entry("Absolute Path", "absolute.path.kube", 0, "", ""),
Entry("Basic kube", "basic.kube", 0, "", ""),
Entry("Kube - ConfigMap", "configmap.kube", 0, "", ""),
Entry("Kube - Exit Code Propagation", "exit_code_propagation.kube", 0, "", ""),
Entry("Kube - Logdriver", "logdriver.kube", 0, "", ""),
Entry("Kube - Logopt", "logopt.kube", 0, "", ""),
Entry("Kube - Network", "network.kube", 0, "", ""),
Entry("Kube - PodmanArgs", "podmanargs.kube", 0, "", ""),
Entry("Kube - Publish IPv4 ports", "ports.kube", 0, "", ""),
Entry("Kube - Publish IPv6 ports", "ports_ipv6.kube", 0, "", ""),
Entry("Kube - Quadlet Network", "network.quadlet.kube", 0, "", ""),
Entry("Kube - User Remap Auto with IDs", "remap-auto2.kube", 0, "", ""),
Entry("Kube - User Remap Auto", "remap-auto.kube", 0, "", ""),
Entry("Kube - User Remap Manual", "remap-manual.kube", 1, "converting \"remap-manual.kube\": RemapUsers=manual is not supported", ""),
Entry("Syslog Identifier", "syslog.identifier.kube", 0, "", ""),
Entry("Kube - Working Directory YAML Absolute Path", "workingdir-yaml-abs.kube", 0, "", ""),
Entry("Kube - Working Directory YAML Relative Path", "workingdir-yaml-rel.kube", 0, "", ""),
Entry("Kube - Working Directory Unit", "workingdir-unit.kube", 0, "", ""),
Entry("Kube - Working Directory already in Service", "workingdir-service.kube", 0, "", ""),
Entry("Kube - global args", "globalargs.kube", 0, "", ""),
Entry("Kube - Containers Conf Modules", "containersconfmodule.kube", 0, "", ""),
Entry("Kube - Service Type=oneshot", "oneshot.kube", 0, "", ""),
Entry("Kube - Down force", "downforce.kube", 0, "", ""),
Entry("Network - Basic", "basic.network", 0, ""),
Entry("Network - Disable DNS", "disable-dns.network", 0, ""),
Entry("Network - DNS", "dns.network", 0, ""),
Entry("Network - Driver", "driver.network", 0, ""),
Entry("Network - Gateway not enough Subnet", "gateway.less-subnet.network", 1, "converting \"gateway.less-subnet.network\": cannot set more gateways than subnets"),
Entry("Network - Gateway without Subnet", "gateway.no-subnet.network", 1, "converting \"gateway.no-subnet.network\": cannot set gateway or range without subnet"),
Entry("Network - Gateway", "gateway.network", 0, ""),
Entry("Network - IPAM Driver", "ipam-driver.network", 0, ""),
Entry("Network - IPv6", "ipv6.network", 0, ""),
Entry("Network - Internal network", "internal.network", 0, ""),
Entry("Network - Label", "label.network", 0, ""),
Entry("Network - Multiple Options", "options.multiple.network", 0, ""),
Entry("Network - Name", "name.network", 0, ""),
Entry("Network - Options", "options.network", 0, ""),
Entry("Network - PodmanArgs", "podmanargs.network", 0, ""),
Entry("Network - Range not enough Subnet", "range.less-subnet.network", 1, "converting \"range.less-subnet.network\": cannot set more ranges than subnets"),
Entry("Network - Range without Subnet", "range.no-subnet.network", 1, "converting \"range.no-subnet.network\": cannot set gateway or range without subnet"),
Entry("Network - Range", "range.network", 0, ""),
Entry("Network - Subnets", "subnets.network", 0, ""),
Entry("Network - multiple subnet, gateway and range", "subnet-trio.multiple.network", 0, ""),
Entry("Network - subnet, gateway and range", "subnet-trio.network", 0, ""),
Entry("Network - global args", "globalargs.network", 0, ""),
Entry("Network - Containers Conf Modules", "containersconfmodule.network", 0, ""),
Entry("Network - Basic", "basic.network", 0, "", ""),
Entry("Network - Disable DNS", "disable-dns.network", 0, "", ""),
Entry("Network - DNS", "dns.network", 0, "", ""),
Entry("Network - Driver", "driver.network", 0, "", ""),
Entry("Network - Gateway not enough Subnet", "gateway.less-subnet.network", 1, "converting \"gateway.less-subnet.network\": cannot set more gateways than subnets", ""),
Entry("Network - Gateway without Subnet", "gateway.no-subnet.network", 1, "converting \"gateway.no-subnet.network\": cannot set gateway or range without subnet", ""),
Entry("Network - Gateway", "gateway.network", 0, "", ""),
Entry("Network - IPAM Driver", "ipam-driver.network", 0, "", ""),
Entry("Network - IPv6", "ipv6.network", 0, "", ""),
Entry("Network - Internal network", "internal.network", 0, "", ""),
Entry("Network - Label", "label.network", 0, "", ""),
Entry("Network - Multiple Options", "options.multiple.network", 0, "", ""),
Entry("Network - Name", "name.network", 0, "", ""),
Entry("Network - Options", "options.network", 0, "", ""),
Entry("Network - PodmanArgs", "podmanargs.network", 0, "", ""),
Entry("Network - Range not enough Subnet", "range.less-subnet.network", 1, "converting \"range.less-subnet.network\": cannot set more ranges than subnets", ""),
Entry("Network - Range without Subnet", "range.no-subnet.network", 1, "converting \"range.no-subnet.network\": cannot set gateway or range without subnet", ""),
Entry("Network - Range", "range.network", 0, "", ""),
Entry("Network - Subnets", "subnets.network", 0, "", ""),
Entry("Network - multiple subnet, gateway and range", "subnet-trio.multiple.network", 0, "", ""),
Entry("Network - subnet, gateway and range", "subnet-trio.network", 0, "", ""),
Entry("Network - global args", "globalargs.network", 0, "", ""),
Entry("Network - Containers Conf Modules", "containersconfmodule.network", 0, "", ""),
Entry("Image - Basic", "basic.image", 0, ""),
Entry("Image - No Image", "no-image.image", 1, "converting \"no-image.image\": no Image key specified"),
Entry("Image - Architecture", "arch.image", 0, ""),
Entry("Image - Auth File", "auth.image", 0, ""),
Entry("Image - Certificates", "certs.image", 0, ""),
Entry("Image - Credentials", "creds.image", 0, ""),
Entry("Image - Decryption Key", "decrypt.image", 0, ""),
Entry("Image - OS Key", "os.image", 0, ""),
Entry("Image - Variant Key", "variant.image", 0, ""),
Entry("Image - All Tags", "all-tags.image", 0, ""),
Entry("Image - TLS Verify", "tls-verify.image", 0, ""),
Entry("Image - Arch and OS", "arch-os.image", 0, ""),
Entry("Image - global args", "globalargs.image", 0, ""),
Entry("Image - Containers Conf Modules", "containersconfmodule.image", 0, ""),
Entry("Image - Unit After Override", "unit-after-override.image", 0, ""),
Entry("Image - Basic", "basic.image", 0, "", ""),
Entry("Image - No Image", "no-image.image", 1, "converting \"no-image.image\": no Image key specified", ""),
Entry("Image - Architecture", "arch.image", 0, "", ""),
Entry("Image - Auth File", "auth.image", 0, "", ""),
Entry("Image - Certificates", "certs.image", 0, "", ""),
Entry("Image - Credentials", "creds.image", 0, "", ""),
Entry("Image - Decryption Key", "decrypt.image", 0, "", ""),
Entry("Image - OS Key", "os.image", 0, "", ""),
Entry("Image - Variant Key", "variant.image", 0, "", ""),
Entry("Image - All Tags", "all-tags.image", 0, "", ""),
Entry("Image - TLS Verify", "tls-verify.image", 0, "", ""),
Entry("Image - Arch and OS", "arch-os.image", 0, "", ""),
Entry("Image - global args", "globalargs.image", 0, "", ""),
Entry("Image - Containers Conf Modules", "containersconfmodule.image", 0, "", ""),
Entry("Image - Unit After Override", "unit-after-override.image", 0, "", ""),
Entry("Build - Basic", "basic.build", 0, ""),
Entry("Build - Annotation Key", "annotation.build", 0, ""),
Entry("Build - Arch Key", "arch.build", 0, ""),
Entry("Build - AuthFile Key", "authfile.build", 0, ""),
Entry("Build - DNS Key", "dns.build", 0, ""),
Entry("Build - DNSOptions Key", "dns-options.build", 0, ""),
Entry("Build - DNSSearch Key", "dns-search.build", 0, ""),
Entry("Build - Environment Key", "env.build", 0, ""),
Entry("Build - File Key absolute", "file-abs.build", 0, ""),
Entry("Build - File Key relative", "file-rel.build", 0, ""),
Entry("Build - File Key relative no WD", "file-rel-no-wd.build", 1, "converting \"file-rel-no-wd.build\": relative path in File key requires SetWorkingDirectory key to be set"),
Entry("Build - File Key HTTP(S) URL", "file-https.build", 0, ""),
Entry("Build - ForceRM Key", "force-rm.build", 0, ""),
Entry("Build - GlobalArgs", "globalargs.build", 0, ""),
Entry("Build - GroupAdd Key", "group-add.build", 0, ""),
Entry("Build - Containers Conf Modules", "containersconfmodule.build", 0, ""),
Entry("Build - Label Key", "label.build", 0, ""),
Entry("Build - Neither WorkingDirectory nor File Key", "neither-workingdirectory-nor-file.build", 1, "converting \"neither-workingdirectory-nor-file.build\": neither SetWorkingDirectory, nor File key specified"),
Entry("Build - Network Key host", "network.build", 0, ""),
Entry("Build - Network Key quadlet", "network.quadlet.build", 0, ""),
Entry("Build - No ImageTag Key", "no-imagetag.build", 1, "converting \"no-imagetag.build\": no ImageTag key specified"),
Entry("Build - PodmanArgs", "podmanargs.build", 0, ""),
Entry("Build - Pull Key", "pull.build", 0, ""),
Entry("Build - Secrets", "secrets.build", 0, ""),
Entry("Build - SetWorkingDirectory is absolute path", "setworkingdirectory-is-abs.build", 0, ""),
Entry("Build - SetWorkingDirectory is absolute File= path", "setworkingdirectory-is-file-abs.build", 0, ""),
Entry("Build - SetWorkingDirectory is relative path", "setworkingdirectory-is-rel.build", 0, ""),
Entry("Build - SetWorkingDirectory is relative File= path", "setworkingdirectory-is-file-rel.build", 0, ""),
Entry("Build - SetWorkingDirectory is https://.git URL", "setworkingdirectory-is-https-git.build", 0, ""),
Entry("Build - SetWorkingDirectory is git:// URL", "setworkingdirectory-is-git.build", 0, ""),
Entry("Build - SetWorkingDirectory is github.com URL", "setworkingdirectory-is-github.build", 0, ""),
Entry("Build - SetWorkingDirectory is archive URL", "setworkingdirectory-is-archive.build", 0, ""),
Entry("Build - Target Key", "target.build", 0, ""),
Entry("Build - TLSVerify Key", "tls-verify.build", 0, ""),
Entry("Build - Variant Key", "variant.build", 0, ""),
Entry("Build - Volume Key", "volume.build", 0, ""),
Entry("Build - Volume Key quadlet", "volume.quadlet.build", 0, ""),
Entry("Build - Basic", "basic.build", 0, "", ""),
Entry("Build - Annotation Key", "annotation.build", 0, "", ""),
Entry("Build - Arch Key", "arch.build", 0, "", ""),
Entry("Build - AuthFile Key", "authfile.build", 0, "", ""),
Entry("Build - DNS Key", "dns.build", 0, "", ""),
Entry("Build - DNSOptions Key", "dns-options.build", 0, "", ""),
Entry("Build - DNSSearch Key", "dns-search.build", 0, "", ""),
Entry("Build - Environment Key", "env.build", 0, "", ""),
Entry("Build - File Key absolute", "file-abs.build", 0, "", ""),
Entry("Build - File Key relative", "file-rel.build", 0, "", ""),
Entry("Build - File Key relative no WD", "file-rel-no-wd.build", 1, "converting \"file-rel-no-wd.build\": relative path in File key requires SetWorkingDirectory key to be set", ""),
Entry("Build - File Key HTTP(S) URL", "file-https.build", 0, "", ""),
Entry("Build - ForceRM Key", "force-rm.build", 0, "", ""),
Entry("Build - GlobalArgs", "globalargs.build", 0, "", ""),
Entry("Build - GroupAdd Key", "group-add.build", 0, "", ""),
Entry("Build - Containers Conf Modules", "containersconfmodule.build", 0, "", ""),
Entry("Build - Label Key", "label.build", 0, "", ""),
Entry("Build - Neither WorkingDirectory nor File Key", "neither-workingdirectory-nor-file.build", 1, "converting \"neither-workingdirectory-nor-file.build\": neither SetWorkingDirectory, nor File key specified", ""),
Entry("Build - Network Key host", "network.build", 0, "", ""),
Entry("Build - Network Key quadlet", "network.quadlet.build", 0, "", ""),
Entry("Build - No ImageTag Key", "no-imagetag.build", 1, "converting \"no-imagetag.build\": no ImageTag key specified", ""),
Entry("Build - PodmanArgs", "podmanargs.build", 0, "", ""),
Entry("Build - Pull Key", "pull.build", 0, "", ""),
Entry("Build - Secrets", "secrets.build", 0, "", ""),
Entry("Build - SetWorkingDirectory is absolute path", "setworkingdirectory-is-abs.build", 0, "", ""),
Entry("Build - SetWorkingDirectory is absolute File= path", "setworkingdirectory-is-file-abs.build", 0, "", ""),
Entry("Build - SetWorkingDirectory is relative path", "setworkingdirectory-is-rel.build", 0, "", ""),
Entry("Build - SetWorkingDirectory is relative File= path", "setworkingdirectory-is-file-rel.build", 0, "", ""),
Entry("Build - SetWorkingDirectory is https://.git URL", "setworkingdirectory-is-https-git.build", 0, "", ""),
Entry("Build - SetWorkingDirectory is git:// URL", "setworkingdirectory-is-git.build", 0, "", ""),
Entry("Build - SetWorkingDirectory is github.com URL", "setworkingdirectory-is-github.build", 0, "", ""),
Entry("Build - SetWorkingDirectory is archive URL", "setworkingdirectory-is-archive.build", 0, "", ""),
Entry("Build - Target Key", "target.build", 0, "", ""),
Entry("Build - TLSVerify Key", "tls-verify.build", 0, "", ""),
Entry("Build - Variant Key", "variant.build", 0, "", ""),
Entry("Build - Volume Key", "volume.build", 0, "", ""),
Entry("Build - Volume Key quadlet", "volume.quadlet.build", 0, "", ""),
Entry("basic.pod", "basic.pod", 0, ""),
Entry("name.pod", "name.pod", 0, ""),
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, ""),
Entry("Pod - NetworkAlias", "network-alias.pod", 0, ""),
Entry("basic.pod", "basic.pod", 0, "", ""),
Entry("name.pod", "name.pod", 0, "", ""),
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, "", ""),
Entry("Pod - NetworkAlias", "network-alias.pod", 0, "", ""),
)
DescribeTable("Running quadlet test case with dependencies",
func(fileName string, exitCode int, errString string, dependencyFiles []string) {
// Write additional files this test depends on to the quadlet dir
for _, dependencyFileName := range dependencyFiles {
dependencyTestCase := loadQuadletTestcase(filepath.Join("quadlet", dependencyFileName))
dependencyTestCase := loadQuadletTestcase(filepath.Join("quadlet", dependencyFileName), "")
err = os.WriteFile(filepath.Join(quadletDir, dependencyFileName), dependencyTestCase.data, 0644)
Expect(err).ToNot(HaveOccurred())
}
runQuadletTestCase(fileName, exitCode, errString)
runQuadletTestCase(fileName, exitCode, errString, "")
},
Entry("Volume - Quadlet image (.build)", "build.quadlet.volume", 0, "", []string{"basic.build"}),
Entry("Volume - Quadlet image (.image)", "image.quadlet.volume", 0, "", []string{"basic.image"}),