Quadlet - add support for global arguments

Add support for adding podman level arguments before subcommand
Add specific key for Containers Conf Modules
Global arguments are added for both start and stop commands
Adjust testing environment
Add tests
Add to man page

Signed-off-by: Ygal Blum <ygal.blum@gmail.com>
This commit is contained in:
Ygal Blum
2023-10-04 16:42:54 +03:00
parent c14e8f6cc0
commit d321d427dc
14 changed files with 472 additions and 150 deletions

View File

@ -121,67 +121,69 @@ There is only one required key, `Image`, which defines the container image the s
Valid options for `[Container]` are listed below: Valid options for `[Container]` are listed below:
| **[Container] options** | **podman run equivalent** | | **[Container] options** | **podman run equivalent** |
|--------------------------------|------------------------------------------------------| |--------------------------------------|------------------------------------------------------|
| AddCapability=CAP | --cap-add CAP | | AddCapability=CAP | --cap-add CAP |
| AddDevice=/dev/foo | --device /dev/foo | | AddDevice=/dev/foo | --device /dev/foo |
| Annotation="XYZ" | --annotation "XYZ" | | Annotation="XYZ" | --annotation "XYZ" |
| AutoUpdate=registry | --label "io.containers.autoupdate=registry" | | AutoUpdate=registry | --label "io.containers.autoupdate=registry" |
| ContainerName=name | --name name | | ContainerName=name | --name name |
| DNS=192.168.55.1 | --dns=192.168.55.1 | | ContainersConfModule=/etc/nvd\.conf | --module=/etc/nvd\.conf |
| DNSSearch=foo.com | --dns-search=foo.com | | DNS=192.168.55.1 | --dns=192.168.55.1 |
| DNSOption=ndots:1 | --dns-option=ndots:1 | | DNSSearch=foo.com | --dns-search=foo.com |
| DropCapability=CAP | --cap-drop=CAP | | DNSOption=ndots:1 | --dns-option=ndots:1 |
| Environment=foo=bar | --env foo=bar | | DropCapability=CAP | --cap-drop=CAP |
| EnvironmentFile=/tmp/env | --env-file /tmp/env | | Environment=foo=bar | --env foo=bar |
| EnvironmentHost=true | --env-host | | EnvironmentFile=/tmp/env | --env-file /tmp/env |
| Exec=/usr/bin/command | Command after image specification - /usr/bin/command | | EnvironmentHost=true | --env-host |
| ExposeHostPort=50-59 | --expose 50-59 | | Exec=/usr/bin/command | Command after image specification - /usr/bin/command |
| Group=1234 | --user UID:1234 | | ExposeHostPort=50-59 | --expose 50-59 |
| HealthCmd="/usr/bin/command" | --health-cmd="/usr/bin/command" | | Group=1234 | --user UID:1234 |
| HealthInterval=2m | --health-interval=2m | | GlobalArgs=--log-level=debug | --log-level=debug |
| HealthOnFailure=kill | --health-on-failure=kill | | HealthCmd="/usr/bin/command" | --health-cmd="/usr/bin/command" |
| HealthRetries=5 | --health-retries=5 | | HealthInterval=2m | --health-interval=2m |
| HealthStartPeriod=1m | --health-start-period=period=1m | | HealthOnFailure=kill | --health-on-failure=kill |
| HealthStartupCmd="command" | --health-startup-cmd="command" | | HealthRetries=5 | --health-retries=5 |
| HealthStartupInterval=1m | --health-startup-interval=1m | | HealthStartPeriod=1m | --health-start-period=period=1m |
| HealthStartupRetries=8 | --health-startup-retries=8 | | HealthStartupCmd="command" | --health-startup-cmd="command" |
| HealthStartupSuccess=2 | --health-startup-success=2 | | HealthStartupInterval=1m | --health-startup-interval=1m |
| HealthStartupTimeout=1m33s | --health-startup-timeout=1m33s | | HealthStartupRetries=8 | --health-startup-retries=8 |
| HealthTimeout=20s | --health-timeout=20s | | HealthStartupSuccess=2 | --health-startup-success=2 |
| HostName=new-host-name | --hostname="new-host-name" | | HealthStartupTimeout=1m33s | --health-startup-timeout=1m33s |
| Image=ubi8 | Image specification - ubi8 | | HealthTimeout=20s | --health-timeout=20s |
| IP=192.5.0.1 | --ip 192.5.0.1 | | HostName=new-host-name | --hostname="new-host-name" |
| IP6=2001:db8::1 | --ip6 2001:db8::1 | | Image=ubi8 | Image specification - ubi8 |
| Label="XYZ" | --label "XYZ" | | IP=192.5.0.1 | --ip 192.5.0.1 |
| LogDriver=journald | --log-driver journald | | IP6=2001:db8::1 | --ip6 2001:db8::1 |
| Mount=type=... | --mount type=... | | Label="XYZ" | --label "XYZ" |
| Network=host | --net host | | LogDriver=journald | --log-driver journald |
| NoNewPrivileges=true | --security-opt no-new-privileges | | Mount=type=... | --mount type=... |
| Rootfs=/var/lib/rootfs | --rootfs /var/lib/rootfs | | Network=host | --net host |
| Notify=true | --sdnotify container | | NoNewPrivileges=true | --security-opt no-new-privileges |
| PidsLimit=10000 | --pids-limit 10000 | | Rootfs=/var/lib/rootfs | --rootfs /var/lib/rootfs |
| PodmanArgs=--add-host foobar | --add-host foobar | | Notify=true | --sdnotify container |
| PublishPort=50-59 | --publish 50-59 | | PidsLimit=10000 | --pids-limit 10000 |
| Pull=never | --pull=never | | PodmanArgs=--add-host foobar | --add-host foobar |
| ReadOnly=true | --read-only | | PublishPort=50-59 | --publish 50-59 |
| RunInit=true | --init | | Pull=never | --pull=never |
| SeccompProfile=/tmp/s.json | --security-opt seccomp=/tmp/s.json | | ReadOnly=true | --read-only |
| SecurityLabelDisable=true | --security-opt label=disable | | RunInit=true | --init |
| SecurityLabelFileType=usr_t | --security-opt label=filetype:usr_t | | SeccompProfile=/tmp/s.json | --security-opt seccomp=/tmp/s.json |
| SecurityLabelLevel=s0:c1,c2 | --security-opt label=level:s0:c1,c2 | | SecurityLabelDisable=true | --security-opt label=disable |
| SecurityLabelNested=true | --security-opt label=nested | | SecurityLabelFileType=usr_t | --security-opt label=filetype:usr_t |
| SecurityLabelType=spc_t | --security-opt label=type:spc_t | | SecurityLabelLevel=s0:c1,c2 | --security-opt label=level:s0:c1,c2 |
| ShmSize=100m | --shm-size=100m | | SecurityLabelNested=true | --security-opt label=nested |
| Sysctl=name=value | --sysctl=name=value | | SecurityLabelType=spc_t | --security-opt label=type:spc_t |
| Timezone=local | --tz local | | ShmSize=100m | --shm-size=100m |
| Tmpfs=/work | --tmpfs /work | | Sysctl=name=value | --sysctl=name=value |
| Ulimit=nofile:1000:10000 | --ulimit nofile:1000:10000 | | Timezone=local | --tz local |
| User=bin | --user bin | | Tmpfs=/work | --tmpfs /work |
| UserNS=keep-id:uid=200,gid=210 | --userns keep-id:uid=200,gid=210 | | Ulimit=nofile:1000:10000 | --ulimit nofile:1000:10000 |
| VolatileTmp=true | --tmpfs /tmp | | User=bin | --user bin |
| Volume=/source:/dest | --volume /source:/dest | | UserNS=keep-id:uid=200,gid=210 | --userns keep-id:uid=200,gid=210 |
| WorkingDir=$HOME | --workdir $HOME | | VolatileTmp=true | --tmpfs /tmp |
| Volume=/source:/dest | --volume /source:/dest |
| WorkingDir=$HOME | --workdir $HOME |
Description of `[Container]` section are: Description of `[Container]` section are:
@ -228,6 +230,12 @@ The (optional) name of the Podman container. If this is not specified, the defau
of `systemd-%N` is used, which is the same as the service name but with a `systemd-` of `systemd-%N` is used, which is the same as the service name but with a `systemd-`
prefix to avoid conflicts with user-managed containers. prefix to avoid conflicts with user-managed containers.
### `ContainersConfModule=`
Load the specified containers.conf(5) module. Equivalent to the Podman `--module` option.
This key can be listed multiple times.
### `DNS=` ### `DNS=`
Set network-scoped DNS resolver/nameserver for containers in this network. Set network-scoped DNS resolver/nameserver for containers in this network.
@ -286,6 +294,19 @@ to the Podman `--expose` option.
This key can be listed multiple times. This key can be listed multiple times.
### `GlobalArgs=`
This key contains a list of arguments passed directly between `podman` and `run`
in the generated file (right before the image name in the command line). It can be used to
access Podman features otherwise unsupported by the generator. Since the generator is unaware
of what unexpected interactions can be caused by these arguments, it is not recommended to use
this option.
The format of this is a space separated list of arguments, which can optionally be individually
escaped to allow inclusion of whitespace and other control characters.
This key can be listed multiple times.
### `Group=` ### `Group=`
The (numeric) GID to run as inside the container. This does not need to match the GID on the host, The (numeric) GID to run as inside the container. This does not need to match the GID on the host,
@ -598,9 +619,11 @@ There is only one required key, `Yaml`, which defines the path to the Kubernetes
Valid options for `[Kube]` are listed below: Valid options for `[Kube]` are listed below:
| **[Kube] options** | **podman kube play equivalent** | | **[Kube] options** | **podman kube play equivalent** |
| ----------------------------------- | -----------------------------------------------------------------| | ------------------------------------| -----------------------------------------------------------------|
| AutoUpdate=registry | --annotation "io.containers.autoupdate=registry" | | AutoUpdate=registry | --annotation "io.containers.autoupdate=registry" |
| ConfigMap=/tmp/config.map | --config-map /tmp/config.map | | ConfigMap=/tmp/config.map | --config-map /tmp/config.map |
| ContainersConfModule=/etc/nvd\.conf | --module=/etc/nvd\.conf |
| GlobalArgs=--log-level=debug | --log-level=debug |
| LogDriver=journald | --log-driver journald | | LogDriver=journald | --log-driver journald |
| Network=host | --net host | | Network=host | --net host |
| PodmanArgs=\-\-annotation=key=value | --annotation=key=value | | PodmanArgs=\-\-annotation=key=value | --annotation=key=value |
@ -629,6 +652,12 @@ it may be absolute or relative to the location of the unit file.
This key may be used multiple times This key may be used multiple times
### `ContainersConfModule=`
Load the specified containers.conf(5) module. Equivalent to the Podman `--module` option.
This key can be listed multiple times.
### `ExitCodePropagation=` ### `ExitCodePropagation=`
Control how the main PID of the systemd service should exit. The following values are supported: Control how the main PID of the systemd service should exit. The following values are supported:
@ -638,6 +667,20 @@ Control how the main PID of the systemd service should exit. The following value
The current default value is `none`. The current default value is `none`.
### `GlobalArgs=`
This key contains a list of arguments passed directly between `podman` and `kube`
in the generated file (right before the image name in the command line). It can be used to
access Podman features otherwise unsupported by the generator. Since the generator is unaware
of what unexpected interactions can be caused by these arguments, it is not recommended to use
this option.
The format of this is a space separated list of arguments, which can optionally be individually
escaped to allow inclusion of whitespace and other control characters.
This key can be listed multiple times.
### `LogDriver=` ### `LogDriver=`
Set the log-driver Podman uses when running the container. Set the log-driver Podman uses when running the container.
@ -739,24 +782,32 @@ particularly interesting when using special options to control network creation,
Valid options for `[Network]` are listed below: Valid options for `[Network]` are listed below:
| **[Network] options** | **podman network create equivalent** | | **[Network] options** | **podman network create equivalent** |
|-------------------------------|--------------------------------------| |-------------------------------------|--------------------------------------|
| DisableDNS=true | --disable-dns | | ContainersConfModule=/etc/nvd\.conf | --module=/etc/nvd\.conf |
| DNS=192.168.55.1 | --dns=192.168.55.1 | | DisableDNS=true | --disable-dns |
| Driver=bridge | --driver bridge | | DNS=192.168.55.1 | --dns=192.168.55.1 |
| Gateway=192.168.55.3 | --gateway 192.168.55.3 | | Driver=bridge | --driver bridge |
| Internal=true | --internal | | Gateway=192.168.55.3 | --gateway 192.168.55.3 |
| IPAMDriver=dhcp | --ipam-driver dhcp | | GlobalArgs=--log-level=debug | --log-level=debug |
| IPRange=192.168.55.128/25 | --ip-range 192.168.55.128/25 | | Internal=true | --internal |
| IPv6=true | --ipv6 | | IPAMDriver=dhcp | --ipam-driver dhcp |
| Label="XYZ" | --label "XYZ" | | IPRange=192.168.55.128/25 | --ip-range 192.168.55.128/25 |
| NetworkName=foo | podman network create foo | | IPv6=true | --ipv6 |
| Options=isolate | --opt isolate | | Label="XYZ" | --label "XYZ" |
| PodmanArgs=--dns=192.168.55.1 | --dns=192.168.55.1 | | NetworkName=foo | podman network create foo |
| Subnet=192.5.0.0/16 | --subnet 192.5.0.0/16 | | Options=isolate | --opt isolate |
| PodmanArgs=--dns=192.168.55.1 | --dns=192.168.55.1 |
| Subnet=192.5.0.0/16 | --subnet 192.5.0.0/16 |
Supported keys in `[Network]` section are: Supported keys in `[Network]` section are:
### `ContainersConfModule=`
Load the specified containers.conf(5) module. Equivalent to the Podman `--module` option.
This key can be listed multiple times.
### `DisableDNS=` (defaults to `no`) ### `DisableDNS=` (defaults to `no`)
If enabled, disables the DNS plugin for this network. If enabled, disables the DNS plugin for this network.
@ -783,6 +834,19 @@ This is equivalent to the Podman `--gateway` option
This key can be listed multiple times. This key can be listed multiple times.
### `GlobalArgs=`
This key contains a list of arguments passed directly between `podman` and `network`
in the generated file (right before the image name in the command line). It can be used to
access Podman features otherwise unsupported by the generator. Since the generator is unaware
of what unexpected interactions can be caused by these arguments, it is not recommended to use
this option.
The format of this is a space separated list of arguments, which can optionally be individually
escaped to allow inclusion of whitespace and other control characters.
This key can be listed multiple times.
### `Internal=` (defaults to `no`) ### `Internal=` (defaults to `no`)
Restrict external access of this network. Restrict external access of this network.
@ -870,9 +934,11 @@ Valid options for `[Volume]` are listed below:
| **[Volume] options** | **podman volume create equivalent** | | **[Volume] options** | **podman volume create equivalent** |
|-------------------------------------|-------------------------------------------| |-------------------------------------|-------------------------------------------|
| ContainersConfModule=/etc/nvd\.conf | --module=/etc/nvd\.conf |
| Copy=true | --opt copy |
| Device=tmpfs | --opt device=tmpfs | | Device=tmpfs | --opt device=tmpfs |
| Driver=image | --driver=image | | Driver=image | --driver=image |
| Copy=true | --opt copy | | GlobalArgs=--log-level=debug | --log-level=debug |
| Group=192 | --opt group=192 | | Group=192 | --opt group=192 |
| Image=quay.io/centos/centos\:latest | --opt image=quay.io/centos/centos\:latest | | Image=quay.io/centos/centos\:latest | --opt image=quay.io/centos/centos\:latest |
| Label="foo=bar" | --label "foo=bar" | | Label="foo=bar" | --label "foo=bar" |
@ -882,6 +948,12 @@ Valid options for `[Volume]` are listed below:
Supported keys in `[Volume]` section are: Supported keys in `[Volume]` section are:
### `ContainersConfModule=`
Load the specified containers.conf(5) module. Equivalent to the Podman `--module` option.
This key can be listed multiple times.
### `Copy=` (default to `yes`) ### `Copy=` (default to `yes`)
If enabled, the content of the image located at the mountpoint of the volume is copied into the If enabled, the content of the image located at the mountpoint of the volume is copied into the
@ -897,6 +969,19 @@ Specify the volume driver name. When set to `image`, the `Image` key must also b
This is equivalent to the Podman `--driver` option. This is equivalent to the Podman `--driver` option.
### `GlobalArgs=`
This key contains a list of arguments passed directly between `podman` and `volume`
in the generated file (right before the image name in the command line). It can be used to
access Podman features otherwise unsupported by the generator. Since the generator is unaware
of what unexpected interactions can be caused by these arguments, it is not recommended to use
this option.
The format of this is a space separated list of arguments, which can optionally be individually
escaped to allow inclusion of whitespace and other control characters.
This key can be listed multiple times.
### `Group=` ### `Group=`
The host (numeric) GID, or group name to use as the group for the volume The host (numeric) GID, or group name to use as the group for the volume
@ -970,8 +1055,10 @@ Valid options for `[Image]` are listed below:
| Arch=aarch64 | --arch=aarch64 | | Arch=aarch64 | --arch=aarch64 |
| AuthFile=/etc/registry/auth\.json | --authfile=/etc/registry/auth\.json | | AuthFile=/etc/registry/auth\.json | --authfile=/etc/registry/auth\.json |
| CertDir=/etc/registery/certs | --cert-dir=/etc/registery/certs | | CertDir=/etc/registery/certs | --cert-dir=/etc/registery/certs |
| ContainersConfModule=/etc/nvd\.conf | --module=/etc/nvd\.conf |
| Creds=myname\:mypassword | --creds=myname\:mypassword | | Creds=myname\:mypassword | --creds=myname\:mypassword |
| DecryptionKey=/etc/registery\.key | --decryption-key=/etc/registery\.key | | DecryptionKey=/etc/registery\.key | --decryption-key=/etc/registery\.key |
| GlobalArgs=--log-level=debug | --log-level=debug |
| Image=quay.io/centos/centos\:latest | podman image pull quay.io/centos/centos\:latest | | Image=quay.io/centos/centos\:latest | podman image pull quay.io/centos/centos\:latest |
| OS=windows | --os=windows | | OS=windows | --os=windows |
| PodmanArgs=--os=linux | --os=linux | | PodmanArgs=--os=linux | --os=linux |
@ -1002,6 +1089,12 @@ Use certificates at path (*.crt, *.cert, *.key) to connect to the registry.
This is equivalent to the Podman `--cert-dir` option. This is equivalent to the Podman `--cert-dir` option.
### `ContainersConfModule=`
Load the specified containers.conf(5) module. Equivalent to the Podman `--module` option.
This key can be listed multiple times.
### `Creds=` ### `Creds=`
The `[username[:password]]` to use to authenticate with the registry, if required. The `[username[:password]]` to use to authenticate with the registry, if required.
@ -1014,6 +1107,19 @@ The `[key[:passphrase]]` to be used for decryption of images.
This is equivalent to the Podman `--decryption-key` option. This is equivalent to the Podman `--decryption-key` option.
### `GlobalArgs=`
This key contains a list of arguments passed directly between `podman` and `image`
in the generated file (right before the image name in the command line). It can be used to
access Podman features otherwise unsupported by the generator. Since the generator is unaware
of what unexpected interactions can be caused by these arguments, it is not recommended to use
this option.
The format of this is a space separated list of arguments, which can optionally be individually
escaped to allow inclusion of whitespace and other control characters.
This key can be listed multiple times.
### `Image=` ### `Image=`
The image to pull. The image to pull.

View File

@ -59,6 +59,7 @@ const (
KeyDecryptionKey = "DecryptionKey" KeyDecryptionKey = "DecryptionKey"
KeyConfigMap = "ConfigMap" KeyConfigMap = "ConfigMap"
KeyContainerName = "ContainerName" KeyContainerName = "ContainerName"
KeyContainersConfModule = "ContainersConfModule"
KeyCopy = "Copy" KeyCopy = "Copy"
KeyDevice = "Device" KeyDevice = "Device"
KeyDNS = "DNS" KeyDNS = "DNS"
@ -72,6 +73,7 @@ const (
KeyExec = "Exec" KeyExec = "Exec"
KeyExitCodePropagation = "ExitCodePropagation" KeyExitCodePropagation = "ExitCodePropagation"
KeyExposeHostPort = "ExposeHostPort" KeyExposeHostPort = "ExposeHostPort"
KeyGlobalArgs = "GlobalArgs"
KeyGroup = "Group" KeyGroup = "Group"
KeyHealthCmd = "HealthCmd" KeyHealthCmd = "HealthCmd"
KeyHealthInterval = "HealthInterval" KeyHealthInterval = "HealthInterval"
@ -154,6 +156,7 @@ var (
KeyAnnotation: true, KeyAnnotation: true,
KeyAutoUpdate: true, KeyAutoUpdate: true,
KeyContainerName: true, KeyContainerName: true,
KeyContainersConfModule: true,
KeyDNS: true, KeyDNS: true,
KeyDNSOption: true, KeyDNSOption: true,
KeyDNSSearch: true, KeyDNSSearch: true,
@ -163,6 +166,7 @@ var (
KeyEnvironmentHost: true, KeyEnvironmentHost: true,
KeyExec: true, KeyExec: true,
KeyExposeHostPort: true, KeyExposeHostPort: true,
KeyGlobalArgs: true,
KeyGroup: true, KeyGroup: true,
KeyHealthCmd: true, KeyHealthCmd: true,
KeyHealthInterval: true, KeyHealthInterval: true,
@ -219,67 +223,75 @@ var (
// Supported keys in "Volume" group // Supported keys in "Volume" group
supportedVolumeKeys = map[string]bool{ supportedVolumeKeys = map[string]bool{
KeyCopy: true, KeyContainersConfModule: true,
KeyDevice: true, KeyCopy: true,
KeyDriver: true, KeyDevice: true,
KeyGroup: true, KeyDriver: true,
KeyImage: true, KeyGlobalArgs: true,
KeyLabel: true, KeyGroup: true,
KeyOptions: true, KeyImage: true,
KeyPodmanArgs: true, KeyLabel: true,
KeyType: true, KeyOptions: true,
KeyUser: true, KeyPodmanArgs: true,
KeyVolumeName: true, KeyType: true,
KeyUser: true,
KeyVolumeName: true,
} }
// Supported keys in "Network" group // Supported keys in "Network" group
supportedNetworkKeys = map[string]bool{ supportedNetworkKeys = map[string]bool{
KeyLabel: true, KeyLabel: true,
KeyDNS: true, KeyDNS: true,
KeyNetworkDisableDNS: true, KeyContainersConfModule: true,
KeyNetworkDriver: true, KeyGlobalArgs: true,
KeyNetworkGateway: true, KeyNetworkDisableDNS: true,
KeyNetworkIPAMDriver: true, KeyNetworkDriver: true,
KeyNetworkIPRange: true, KeyNetworkGateway: true,
KeyNetworkIPv6: true, KeyNetworkIPAMDriver: true,
KeyNetworkInternal: true, KeyNetworkIPRange: true,
KeyNetworkName: true, KeyNetworkIPv6: true,
KeyNetworkOptions: true, KeyNetworkInternal: true,
KeyNetworkSubnet: true, KeyNetworkName: true,
KeyPodmanArgs: true, KeyNetworkOptions: true,
KeyNetworkSubnet: true,
KeyPodmanArgs: true,
} }
// Supported keys in "Kube" group // Supported keys in "Kube" group
supportedKubeKeys = map[string]bool{ supportedKubeKeys = map[string]bool{
KeyAutoUpdate: true, KeyAutoUpdate: true,
KeyConfigMap: true, KeyConfigMap: true,
KeyExitCodePropagation: true, KeyContainersConfModule: true,
KeyLogDriver: true, KeyExitCodePropagation: true,
KeyNetwork: true, KeyGlobalArgs: true,
KeyPodmanArgs: true, KeyLogDriver: true,
KeyPublishPort: true, KeyNetwork: true,
KeyRemapGID: true, KeyPodmanArgs: true,
KeyRemapUID: true, KeyPublishPort: true,
KeyRemapUIDSize: true, KeyRemapGID: true,
KeyRemapUsers: true, KeyRemapUID: true,
KeySetWorkingDirectory: true, KeyRemapUIDSize: true,
KeyUserNS: true, KeyRemapUsers: true,
KeyYaml: true, KeySetWorkingDirectory: true,
KeyUserNS: true,
KeyYaml: true,
} }
// Supported keys in "Image" group // Supported keys in "Image" group
supportedImageKeys = map[string]bool{ supportedImageKeys = map[string]bool{
KeyAllTags: true, KeyAllTags: true,
KeyArch: true, KeyArch: true,
KeyAuthFile: true, KeyAuthFile: true,
KeyCertDir: true, KeyCertDir: true,
KeyCreds: true, KeyContainersConfModule: true,
KeyDecryptionKey: true, KeyCreds: true,
KeyImage: true, KeyDecryptionKey: true,
KeyOS: true, KeyGlobalArgs: true,
KeyPodmanArgs: true, KeyImage: true,
KeyTLSVerify: true, KeyOS: true,
KeyVariant: true, KeyPodmanArgs: true,
KeyTLSVerify: true,
KeyVariant: true,
} }
) )
@ -416,14 +428,19 @@ func ConvertContainer(container *parser.UnitFile, names map[string]string, isUse
// If conmon exited uncleanly it may not have removed the container, so // If conmon exited uncleanly it may not have removed the container, so
// force it, -i makes it ignore non-existing files. // force it, -i makes it ignore non-existing files.
service.Add(ServiceGroup, "ExecStop", podmanBinary()+" rm -v -f -i --cidfile=%t/%N.cid") serviceStopCmd := createBasePodmanCommand(container, ContainerGroup)
serviceStopCmd.add("rm", "-v", "-f", "-i", "--cidfile=%t/%N.cid")
service.AddCmdline(ServiceGroup, "ExecStop", serviceStopCmd.Args)
// The ExecStopPost is needed when the main PID (i.e., conmon) gets killed. // The ExecStopPost is needed when the main PID (i.e., conmon) gets killed.
// In that case, ExecStop is not executed but *Post only. If both are // In that case, ExecStop is not executed but *Post only. If both are
// fired in sequence, *Post will exit when detecting that the --cidfile // fired in sequence, *Post will exit when detecting that the --cidfile
// has already been removed by the previous `rm`.. // has already been removed by the previous `rm`..
service.Add(ServiceGroup, "ExecStopPost", "-"+podmanBinary()+" rm -v -f -i --cidfile=%t/%N.cid") serviceStopCmd.Args[0] = fmt.Sprintf("-%s", serviceStopCmd.Args[0])
service.AddCmdline(ServiceGroup, "ExecStopPost", serviceStopCmd.Args)
podman := NewPodmanCmdline("run") podman := createBasePodmanCommand(container, ContainerGroup)
podman.add("run")
podman.addf("--name=%s", containerName) podman.addf("--name=%s", containerName)
@ -794,7 +811,9 @@ func ConvertNetwork(network *parser.UnitFile, name string) (*parser.UnitFile, st
// Need the containers filesystem mounted to start podman // Need the containers filesystem mounted to start podman
service.Add(UnitGroup, "RequiresMountsFor", "%t/containers") service.Add(UnitGroup, "RequiresMountsFor", "%t/containers")
podman := NewPodmanCmdline("network", "create", "--ignore") podman := createBasePodmanCommand(network, NetworkGroup)
podman.add("network", "create", "--ignore")
if disableDNS := network.LookupBooleanWithDefault(NetworkGroup, KeyNetworkDisableDNS, false); disableDNS { if disableDNS := network.LookupBooleanWithDefault(NetworkGroup, KeyNetworkDisableDNS, false); disableDNS {
podman.add("--disable-dns") podman.add("--disable-dns")
@ -898,7 +917,9 @@ func ConvertVolume(volume *parser.UnitFile, name string, names map[string]string
labels := volume.LookupAllKeyVal(VolumeGroup, "Label") labels := volume.LookupAllKeyVal(VolumeGroup, "Label")
podman := NewPodmanCmdline("volume", "create", "--ignore") podman := createBasePodmanCommand(volume, VolumeGroup)
podman.add("volume", "create", "--ignore")
driver, ok := volume.Lookup(VolumeGroup, KeyDriver) driver, ok := volume.Lookup(VolumeGroup, KeyDriver)
if ok { if ok {
@ -1050,7 +1071,9 @@ func ConvertKube(kube *parser.UnitFile, names map[string]string, isUser bool) (*
service.Set(ServiceGroup, "SyslogIdentifier", "%N") service.Set(ServiceGroup, "SyslogIdentifier", "%N")
} }
execStart := NewPodmanCmdline("kube", "play") execStart := createBasePodmanCommand(kube, KubeGroup)
execStart.add("kube", "play")
execStart.add( execStart.add(
// Replace any previous container with the same name, not fail // Replace any previous container with the same name, not fail
@ -1107,8 +1130,8 @@ func ConvertKube(kube *parser.UnitFile, names map[string]string, isUser bool) (*
// Use `ExecStopPost` to make sure cleanup happens even in case of // Use `ExecStopPost` to make sure cleanup happens even in case of
// errors; otherwise containers, pods, etc. would be left behind. // errors; otherwise containers, pods, etc. would be left behind.
execStop := NewPodmanCmdline("kube", "down") execStop := createBasePodmanCommand(kube, KubeGroup)
execStop.add(yamlPath) execStop.add("kube", "down", yamlPath)
service.AddCmdline(ServiceGroup, "ExecStopPost", execStop.Args) service.AddCmdline(ServiceGroup, "ExecStopPost", execStop.Args)
err = handleSetWorkingDirectory(kube, service) err = handleSetWorkingDirectory(kube, service)
@ -1142,7 +1165,9 @@ func ConvertImage(image *parser.UnitFile) (*parser.UnitFile, string, error) {
// Need the containers filesystem mounted to start podman // Need the containers filesystem mounted to start podman
service.Add(UnitGroup, "RequiresMountsFor", "%t/containers") service.Add(UnitGroup, "RequiresMountsFor", "%t/containers")
podman := NewPodmanCmdline("image", "pull") podman := createBasePodmanCommand(image, ImageGroup)
podman.add("image", "pull")
stringKeys := map[string]string{ stringKeys := map[string]string{
KeyArch: "--arch", KeyArch: "--arch",
@ -1571,3 +1596,19 @@ func convertToCSV(s []string) (string, error) {
return ret, nil return ret, nil
} }
func createBasePodmanCommand(unitFile *parser.UnitFile, groupName string) *PodmanCmdline {
podman := NewPodmanCmdline()
containersConfModules := unitFile.LookupAll(groupName, KeyContainersConfModule)
for _, containersConfModule := range containersConfModules {
podman.addf("--module=%s", containersConfModule)
}
globalArgs := unitFile.LookupAllArgs(groupName, KeyGlobalArgs)
if len(globalArgs) > 0 {
podman.add(globalArgs...)
}
return podman
}

View File

@ -12,7 +12,7 @@
## assert-key-is "Service" "Type" "notify" ## assert-key-is "Service" "Type" "notify"
## assert-key-is "Service" "NotifyAccess" "all" ## assert-key-is "Service" "NotifyAccess" "all"
## assert-key-is "Service" "SyslogIdentifier" "%N" ## assert-key-is "Service" "SyslogIdentifier" "%N"
## assert-key-is-regex "Service" "ExecStopPost" "-.*/podman rm -v -f -i --cidfile=%t/%N.cid" ## assert-key-is-regex "Service" "ExecStopPost" "-[/S].*/podman rm -v -f -i --cidfile=%t/%N.cid"
## assert-key-is-regex "Service" "ExecStop" ".*/podman rm -v -f -i --cidfile=%t/%N.cid" ## assert-key-is-regex "Service" "ExecStop" ".*/podman rm -v -f -i --cidfile=%t/%N.cid"
## assert-key-is "Service" "Environment" "PODMAN_SYSTEMD_UNIT=%n" ## assert-key-is "Service" "Environment" "PODMAN_SYSTEMD_UNIT=%n"

View File

@ -0,0 +1,7 @@
## assert-podman-global-args "run" "--module=/etc/container/1.conf"
## assert-podman-global-args "run" "--module=/etc/container/2.conf"
[Container]
Image=image
ContainersConfModule=/etc/container/1.conf
ContainersConfModule=/etc/container/2.conf

View File

@ -0,0 +1,7 @@
## assert-podman-global-args "image" "--module=/etc/container/1.conf"
## assert-podman-global-args "image" "--module=/etc/container/2.conf"
[Image]
Image=image:latest
ContainersConfModule=/etc/container/1.conf
ContainersConfModule=/etc/container/2.conf

View File

@ -0,0 +1,7 @@
## assert-podman-global-args "kube" "--module=/etc/container/1.conf"
## assert-podman-global-args "kube" "--module=/etc/container/2.conf"
[Kube]
Yaml=file.yml
ContainersConfModule=/etc/container/1.conf
ContainersConfModule=/etc/container/2.conf

View File

@ -0,0 +1,6 @@
## assert-podman-global-args "network" "--module=/etc/container/1.conf"
## assert-podman-global-args "network" "--module=/etc/container/2.conf"
[Network]
ContainersConfModule=/etc/container/1.conf
ContainersConfModule=/etc/container/2.conf

View File

@ -0,0 +1,6 @@
## assert-podman-global-args "volume" "--module=/etc/container/1.conf"
## assert-podman-global-args "volume" "--module=/etc/container/2.conf"
[Volume]
ContainersConfModule=/etc/container/1.conf
ContainersConfModule=/etc/container/2.conf

View File

@ -0,0 +1,16 @@
## assert-podman-global-args "run" "--conmon=/usr/bin/somewhere"
## assert-podman-global-args "run" "--imagestore=/var/lib/somestore"
## assert-podman-global-args "run" "--log-level=debug"
## assert-podman-stop-global-args "rm" "--conmon=/usr/bin/somewhere"
## assert-podman-stop-global-args "rm" "--imagestore=/var/lib/somestore"
## assert-podman-stop-global-args "rm" "--log-level=debug"
## assert-podman-stop-post-global-args "rm" "--conmon=/usr/bin/somewhere"
## assert-podman-stop-post-global-args "rm" "--imagestore=/var/lib/somestore"
## assert-podman-stop-post-global-args "rm" "--log-level=debug"
[Container]
Image=image
GlobalArgs=--conmon=/usr/bin/somewhere
GlobalArgs=--imagestore=/var/lib/somestore --log-level=debug

View File

@ -0,0 +1,8 @@
## assert-podman-global-args "image" "--identity=path=/etc/identity"
## assert-podman-global-args "image" "--syslog"
## assert-podman-global-args "image" "--log-level=debug"
[Image]
Image=image:latest
GlobalArgs=--identity=path=/etc/identity
GlobalArgs=--syslog --log-level=debug

View File

@ -0,0 +1,12 @@
## assert-podman-global-args "kube" "--conmon=/usr/bin/somewhere"
## assert-podman-global-args "kube" "--imagestore=/var/lib/somestore"
## assert-podman-global-args "kube" "--log-level=debug"
## assert-podman-stop-post-global-args "kube" "--conmon=/usr/bin/somewhere"
## assert-podman-stop-post-global-args "kube" "--imagestore=/var/lib/somestore"
## assert-podman-stop-post-global-args "kube" "--log-level=debug"
[Kube]
Yaml=file.yml
GlobalArgs=--conmon=/usr/bin/somewhere
GlobalArgs=--imagestore=/var/lib/somestore --log-level=debug

View File

@ -0,0 +1,7 @@
## assert-podman-global-args "network" "--network-cmd-path=/usr/bin/network-cmd"
## assert-podman-global-args "network" "--network-config-dir=/etc/network-config"
## assert-podman-global-args "network" "--log-level=debug"
[Network]
GlobalArgs=--network-cmd-path=/usr/bin/network-cmd
GlobalArgs=--network-config-dir=/etc/network-config --log-level=debug

View File

@ -0,0 +1,7 @@
## assert-podman-global-args "volume" "--volumepath=/var/lib/somewhere"
## assert-podman-global-args "volume" "--imagestore=/var/lib/store"
## assert-podman-global-args "volume" "--log-level=debug"
[Volume]
GlobalArgs=--volumepath=/var/lib/somewhere
GlobalArgs=--imagestore=/var/lib/store --log-level=debug

View File

@ -169,14 +169,26 @@ func (t *quadletTestcase) assertKeyContains(args []string, unit *parser.UnitFile
return ok && strings.Contains(realValue, value) return ok && strings.Contains(realValue, value)
} }
func (t *quadletTestcase) assertPodmanArgs(args []string, unit *parser.UnitFile, key string) bool { 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)
return findSublist(podmanArgs, args) != -1 if globalOnly {
} podmanCmdLocation := findSublist(podmanArgs, []string{args[0]})
if podmanCmdLocation == -1 {
return false
}
func (t *quadletTestcase) assertPodmanArgsRegex(args []string, unit *parser.UnitFile, key string) bool { podmanArgs = podmanArgs[:podmanCmdLocation]
podmanArgs, _ := unit.LookupLastArgs("Service", key) args = args[1:]
return findSublistRegex(podmanArgs, args) != -1 }
var location int
if allowRegex {
location = findSublistRegex(podmanArgs, args)
} else {
location = findSublist(podmanArgs, args)
}
return location != -1
} }
func keyValueStringToMap(keyValueString, separator string) (map[string]string, error) { func keyValueStringToMap(keyValueString, separator string) (map[string]string, error) {
@ -216,9 +228,19 @@ func keyValMapEqualRegex(expectedKeyValMap, actualKeyValMap map[string]string) b
return true return true
} }
func (t *quadletTestcase) assertPodmanArgsKeyVal(args []string, unit *parser.UnitFile, key string, allowRegex bool) bool { 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]})
if podmanCmdLocation == -1 {
return false
}
podmanArgs = podmanArgs[:podmanCmdLocation]
args = args[1:]
}
expectedKeyValMap, err := keyValueStringToMap(args[2], args[1]) expectedKeyValMap, err := keyValueStringToMap(args[2], args[1])
if err != nil { if err != nil {
return false return false
@ -270,19 +292,35 @@ func (t *quadletTestcase) assertPodmanFinalArgsRegex(args []string, unit *parser
} }
func (t *quadletTestcase) assertStartPodmanArgs(args []string, unit *parser.UnitFile) bool { func (t *quadletTestcase) assertStartPodmanArgs(args []string, unit *parser.UnitFile) bool {
return t.assertPodmanArgs(args, unit, "ExecStart") return t.assertPodmanArgs(args, unit, "ExecStart", false, false)
} }
func (t *quadletTestcase) assertStartPodmanArgsRegex(args []string, unit *parser.UnitFile) bool { func (t *quadletTestcase) assertStartPodmanArgsRegex(args []string, unit *parser.UnitFile) bool {
return t.assertPodmanArgsRegex(args, unit, "ExecStart") return t.assertPodmanArgs(args, unit, "ExecStart", true, false)
}
func (t *quadletTestcase) assertStartPodmanGlobalArgs(args []string, unit *parser.UnitFile) bool {
return t.assertPodmanArgs(args, unit, "ExecStart", false, true)
}
func (t *quadletTestcase) assertStartPodmanGlobalArgsRegex(args []string, unit *parser.UnitFile) bool {
return t.assertPodmanArgs(args, unit, "ExecStart", true, true)
} }
func (t *quadletTestcase) assertStartPodmanArgsKeyVal(args []string, unit *parser.UnitFile) bool { func (t *quadletTestcase) assertStartPodmanArgsKeyVal(args []string, unit *parser.UnitFile) bool {
return t.assertPodmanArgsKeyVal(args, unit, "ExecStart", false) return t.assertPodmanArgsKeyVal(args, unit, "ExecStart", false, false)
} }
func (t *quadletTestcase) assertStartPodmanArgsKeyValRegex(args []string, unit *parser.UnitFile) bool { func (t *quadletTestcase) assertStartPodmanArgsKeyValRegex(args []string, unit *parser.UnitFile) bool {
return t.assertPodmanArgsKeyVal(args, unit, "ExecStart", true) return t.assertPodmanArgsKeyVal(args, unit, "ExecStart", true, false)
}
func (t *quadletTestcase) assertStartPodmanGlobalArgsKeyVal(args []string, unit *parser.UnitFile) bool {
return t.assertPodmanArgsKeyVal(args, unit, "ExecStart", false, true)
}
func (t *quadletTestcase) assertStartPodmanGlobalArgsKeyValRegex(args []string, unit *parser.UnitFile) bool {
return t.assertPodmanArgsKeyVal(args, unit, "ExecStart", true, true)
} }
func (t *quadletTestcase) assertStartPodmanFinalArgs(args []string, unit *parser.UnitFile) bool { func (t *quadletTestcase) assertStartPodmanFinalArgs(args []string, unit *parser.UnitFile) bool {
@ -294,7 +332,11 @@ func (t *quadletTestcase) assertStartPodmanFinalArgsRegex(args []string, unit *p
} }
func (t *quadletTestcase) assertStopPodmanArgs(args []string, unit *parser.UnitFile) bool { func (t *quadletTestcase) assertStopPodmanArgs(args []string, unit *parser.UnitFile) bool {
return t.assertPodmanArgs(args, unit, "ExecStop") return t.assertPodmanArgs(args, unit, "ExecStop", false, false)
}
func (t *quadletTestcase) assertStopPodmanGlobalArgs(args []string, unit *parser.UnitFile) bool {
return t.assertPodmanArgs(args, unit, "ExecStop", false, true)
} }
func (t *quadletTestcase) assertStopPodmanFinalArgs(args []string, unit *parser.UnitFile) bool { func (t *quadletTestcase) assertStopPodmanFinalArgs(args []string, unit *parser.UnitFile) bool {
@ -305,8 +347,20 @@ func (t *quadletTestcase) assertStopPodmanFinalArgsRegex(args []string, unit *pa
return t.assertPodmanFinalArgsRegex(args, unit, "ExecStop") return t.assertPodmanFinalArgsRegex(args, unit, "ExecStop")
} }
func (t *quadletTestcase) assertStopPodmanArgsKeyVal(args []string, unit *parser.UnitFile) bool {
return t.assertPodmanArgsKeyVal(args, unit, "ExecStop", false, false)
}
func (t *quadletTestcase) assertStopPodmanArgsKeyValRegex(args []string, unit *parser.UnitFile) bool {
return t.assertPodmanArgsKeyVal(args, unit, "ExecStop", true, false)
}
func (t *quadletTestcase) assertStopPostPodmanArgs(args []string, unit *parser.UnitFile) bool { func (t *quadletTestcase) assertStopPostPodmanArgs(args []string, unit *parser.UnitFile) bool {
return t.assertPodmanArgs(args, unit, "ExecStopPost") return t.assertPodmanArgs(args, unit, "ExecStopPost", false, false)
}
func (t *quadletTestcase) assertStopPostPodmanGlobalArgs(args []string, unit *parser.UnitFile) bool {
return t.assertPodmanArgs(args, unit, "ExecStopPost", false, true)
} }
func (t *quadletTestcase) assertStopPostPodmanFinalArgs(args []string, unit *parser.UnitFile) bool { func (t *quadletTestcase) assertStopPostPodmanFinalArgs(args []string, unit *parser.UnitFile) bool {
@ -317,6 +371,14 @@ func (t *quadletTestcase) assertStopPostPodmanFinalArgsRegex(args []string, unit
return t.assertPodmanFinalArgsRegex(args, unit, "ExecStopPost") return t.assertPodmanFinalArgsRegex(args, unit, "ExecStopPost")
} }
func (t *quadletTestcase) assertStopPostPodmanArgsKeyVal(args []string, unit *parser.UnitFile) bool {
return t.assertPodmanArgsKeyVal(args, unit, "ExecStopPost", false, false)
}
func (t *quadletTestcase) assertStopPostPodmanArgsKeyValRegex(args []string, unit *parser.UnitFile) bool {
return t.assertPodmanArgsKeyVal(args, unit, "ExecStopPost", 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]
@ -366,6 +428,14 @@ func (t *quadletTestcase) doAssert(check []string, unit *parser.UnitFile, sessio
ok = t.assertStartPodmanArgsKeyVal(args, unit) ok = t.assertStartPodmanArgsKeyVal(args, unit)
case "assert-podman-args-key-val-regex": case "assert-podman-args-key-val-regex":
ok = t.assertStartPodmanArgsKeyValRegex(args, unit) ok = t.assertStartPodmanArgsKeyValRegex(args, unit)
case "assert-podman-global-args":
ok = t.assertStartPodmanGlobalArgs(args, unit)
case "assert-podman-global-args-regex":
ok = t.assertStartPodmanGlobalArgsRegex(args, unit)
case "assert-podman-global-args-key-val":
ok = t.assertStartPodmanGlobalArgsKeyVal(args, unit)
case "assert-podman-global-args-key-val-regex":
ok = t.assertStartPodmanGlobalArgsKeyValRegex(args, unit)
case "assert-podman-final-args": case "assert-podman-final-args":
ok = t.assertStartPodmanFinalArgs(args, unit) ok = t.assertStartPodmanFinalArgs(args, unit)
case "assert-podman-final-args-regex": case "assert-podman-final-args-regex":
@ -374,16 +444,28 @@ func (t *quadletTestcase) doAssert(check []string, unit *parser.UnitFile, sessio
ok = t.assertSymlink(args, unit) ok = t.assertSymlink(args, unit)
case "assert-podman-stop-args": case "assert-podman-stop-args":
ok = t.assertStopPodmanArgs(args, unit) ok = t.assertStopPodmanArgs(args, unit)
case "assert-podman-stop-global-args":
ok = t.assertStopPodmanGlobalArgs(args, unit)
case "assert-podman-stop-final-args": case "assert-podman-stop-final-args":
ok = t.assertStopPodmanFinalArgs(args, unit) ok = t.assertStopPodmanFinalArgs(args, unit)
case "assert-podman-stop-final-args-regex": case "assert-podman-stop-final-args-regex":
ok = t.assertStopPodmanFinalArgsRegex(args, unit) ok = t.assertStopPodmanFinalArgsRegex(args, unit)
case "assert-podman-stop-args-key-val":
ok = t.assertStopPodmanArgsKeyVal(args, unit)
case "assert-podman-stop-args-key-val-regex":
ok = t.assertStopPodmanArgsKeyValRegex(args, unit)
case "assert-podman-stop-post-args": case "assert-podman-stop-post-args":
ok = t.assertStopPostPodmanArgs(args, unit) ok = t.assertStopPostPodmanArgs(args, unit)
case "assert-podman-stop-post-global-args":
ok = t.assertStopPostPodmanGlobalArgs(args, unit)
case "assert-podman-stop-post-final-args": case "assert-podman-stop-post-final-args":
ok = t.assertStopPostPodmanFinalArgs(args, unit) ok = t.assertStopPostPodmanFinalArgs(args, unit)
case "assert-podman-stop-post-final-args-regex": case "assert-podman-stop-post-final-args-regex":
ok = t.assertStopPostPodmanFinalArgsRegex(args, unit) ok = t.assertStopPostPodmanFinalArgsRegex(args, unit)
case "assert-podman-stop-post-args-key-val":
ok = t.assertStopPostPodmanArgsKeyVal(args, unit)
case "assert-podman-stop-post-args-key-val-regex":
ok = t.assertStopPostPodmanArgsKeyValRegex(args, unit)
default: default:
return fmt.Errorf("Unsupported assertion %s", op) return fmt.Errorf("Unsupported assertion %s", op)
@ -647,6 +729,8 @@ BOGUS=foo
Entry("user.container", "user.container", 0, ""), Entry("user.container", "user.container", 0, ""),
Entry("volume.container", "volume.container", 0, ""), Entry("volume.container", "volume.container", 0, ""),
Entry("workingdir.container", "workingdir.container", 0, ""), Entry("workingdir.container", "workingdir.container", 0, ""),
Entry("Container - global args", "globalargs.container", 0, ""),
Entry("Container - Containers Conf Modules", "containersconfmodule.container", 0, ""),
Entry("basic.volume", "basic.volume", 0, ""), Entry("basic.volume", "basic.volume", 0, ""),
Entry("device-copy.volume", "device-copy.volume", 0, ""), Entry("device-copy.volume", "device-copy.volume", 0, ""),
@ -657,6 +741,8 @@ BOGUS=foo
Entry("uid.volume", "uid.volume", 0, ""), Entry("uid.volume", "uid.volume", 0, ""),
Entry("image.volume", "image.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("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("Absolute Path", "absolute.path.kube", 0, ""), Entry("Absolute Path", "absolute.path.kube", 0, ""),
Entry("Basic kube", "basic.kube", 0, ""), Entry("Basic kube", "basic.kube", 0, ""),
@ -676,6 +762,8 @@ BOGUS=foo
Entry("Kube - Working Directory YAML Relative Path", "workingdir-yaml-rel.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 Unit", "workingdir-unit.kube", 0, ""),
Entry("Kube - Working Directory already in Service", "workingdir-service.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("Network - Basic", "basic.network", 0, ""), Entry("Network - Basic", "basic.network", 0, ""),
Entry("Network - Disable DNS", "disable-dns.network", 0, ""), Entry("Network - Disable DNS", "disable-dns.network", 0, ""),
@ -698,6 +786,8 @@ BOGUS=foo
Entry("Network - Subnets", "subnets.network", 0, ""), Entry("Network - Subnets", "subnets.network", 0, ""),
Entry("Network - multiple subnet, gateway and range", "subnet-trio.multiple.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 - 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 - Basic", "basic.image", 0, ""),
Entry("Image - No Image", "no-image.image", 1, "converting \"no-image.image\": no Image key specified"), Entry("Image - No Image", "no-image.image", 1, "converting \"no-image.image\": no Image key specified"),
@ -711,6 +801,8 @@ BOGUS=foo
Entry("Image - All Tags", "all-tags.image", 0, ""), Entry("Image - All Tags", "all-tags.image", 0, ""),
Entry("Image - TLS Verify", "tls-verify.image", 0, ""), Entry("Image - TLS Verify", "tls-verify.image", 0, ""),
Entry("Image - Arch and OS", "arch-os.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, ""),
) )
}) })