mirror of
https://github.com/containers/podman.git
synced 2025-07-15 03:02:52 +08:00
Merge pull request #17068 from ygalblum/quadlet-kube-publish-ports
Quadlet Kube - add support for PublishPort key
This commit is contained in:
@ -365,6 +365,23 @@ 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
|
||||||
|
|
||||||
|
#### `PublishPort=`
|
||||||
|
|
||||||
|
Exposes a port, or a range of ports (e.g. `50-59`), from the container to the host. Equivalent
|
||||||
|
to the `podman kube play`'s `--publish` option. The format is similar to the Podman options, which is of
|
||||||
|
the form `ip:hostPort:containerPort`, `ip::containerPort`, `hostPort:containerPort` or
|
||||||
|
`containerPort`, where the number of host and container ports must be the same (in the case
|
||||||
|
of a range).
|
||||||
|
|
||||||
|
If the IP is set to 0.0.0.0 or not set at all, the port will be bound on all IPv4 addresses on
|
||||||
|
the host; use [::] for IPv6.
|
||||||
|
|
||||||
|
The list of published ports specified in the unit file will be merged with the list of ports specified
|
||||||
|
in the Kubernetes YAML file. If the same container port and protocol is specified in both, the
|
||||||
|
entry from the unit file will take precedence
|
||||||
|
|
||||||
|
This key can be listed multiple times.
|
||||||
|
|
||||||
### Volume units
|
### Volume units
|
||||||
|
|
||||||
Volume files are named with a `.volume` extension and contain a section `[Volume]` describing the
|
Volume files are named with a `.volume` extension and contain a section `[Volume]` describing the
|
||||||
|
@ -141,6 +141,7 @@ var (
|
|||||||
KeyRemapUIDSize: true,
|
KeyRemapUIDSize: true,
|
||||||
KeyNetwork: true,
|
KeyNetwork: true,
|
||||||
KeyConfigMap: true,
|
KeyConfigMap: true,
|
||||||
|
KeyPublishPort: true,
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -454,63 +455,8 @@ func ConvertContainer(container *parser.UnitFile, isUser bool) (*parser.UnitFile
|
|||||||
podman.addf("--expose=%s", exposedPort)
|
podman.addf("--expose=%s", exposedPort)
|
||||||
}
|
}
|
||||||
|
|
||||||
publishPorts := container.LookupAll(ContainerGroup, KeyPublishPort)
|
if err := handlePublishPorts(container, ContainerGroup, podman); err != nil {
|
||||||
for _, publishPort := range publishPorts {
|
return nil, err
|
||||||
publishPort = strings.TrimSpace(publishPort) // Allow whitespace after
|
|
||||||
|
|
||||||
// IP address could have colons in it. For example: "[::]:8080:80/tcp, so use custom splitter
|
|
||||||
parts := splitPorts(publishPort)
|
|
||||||
|
|
||||||
var containerPort string
|
|
||||||
ip := ""
|
|
||||||
hostPort := ""
|
|
||||||
|
|
||||||
// format (from podman run):
|
|
||||||
// ip:hostPort:containerPort | ip::containerPort | hostPort:containerPort | containerPort
|
|
||||||
//
|
|
||||||
// ip could be IPv6 with minimum of these chars "[::]"
|
|
||||||
// containerPort can have a suffix of "/tcp" or "/udp"
|
|
||||||
//
|
|
||||||
|
|
||||||
switch len(parts) {
|
|
||||||
case 1:
|
|
||||||
containerPort = parts[0]
|
|
||||||
|
|
||||||
case 2:
|
|
||||||
hostPort = parts[0]
|
|
||||||
containerPort = parts[1]
|
|
||||||
|
|
||||||
case 3:
|
|
||||||
ip = parts[0]
|
|
||||||
hostPort = parts[1]
|
|
||||||
containerPort = parts[2]
|
|
||||||
|
|
||||||
default:
|
|
||||||
return nil, fmt.Errorf("invalid published port '%s'", publishPort)
|
|
||||||
}
|
|
||||||
|
|
||||||
if ip == "0.0.0.0" {
|
|
||||||
ip = ""
|
|
||||||
}
|
|
||||||
|
|
||||||
if len(hostPort) > 0 && !isPortRange(hostPort) {
|
|
||||||
return nil, fmt.Errorf("invalid port format '%s'", hostPort)
|
|
||||||
}
|
|
||||||
|
|
||||||
if len(containerPort) > 0 && !isPortRange(containerPort) {
|
|
||||||
return nil, fmt.Errorf("invalid port format '%s'", containerPort)
|
|
||||||
}
|
|
||||||
|
|
||||||
switch {
|
|
||||||
case len(ip) > 0 && len(hostPort) > 0:
|
|
||||||
podman.addf("-p=%s:%s:%s", ip, hostPort, containerPort)
|
|
||||||
case len(ip) > 0:
|
|
||||||
podman.addf("-p=%s::%s", ip, containerPort)
|
|
||||||
case len(hostPort) > 0:
|
|
||||||
podman.addf("-p=%s:%s", hostPort, containerPort)
|
|
||||||
default:
|
|
||||||
podman.addf("-p=%s", containerPort)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
podman.addEnv(podmanEnv)
|
podman.addEnv(podmanEnv)
|
||||||
@ -775,6 +721,10 @@ func ConvertKube(kube *parser.UnitFile, isUser bool) (*parser.UnitFile, error) {
|
|||||||
execStart.add("--configmap", configMapPath)
|
execStart.add("--configmap", configMapPath)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if err := handlePublishPorts(kube, KubeGroup, execStart); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
execStart.add(yamlPath)
|
execStart.add(yamlPath)
|
||||||
|
|
||||||
service.AddCmdline(ServiceGroup, "ExecStart", execStart.Args)
|
service.AddCmdline(ServiceGroup, "ExecStart", execStart.Args)
|
||||||
@ -876,3 +826,67 @@ func getAbsolutePath(quadletUnitFile *parser.UnitFile, filePath string) (string,
|
|||||||
}
|
}
|
||||||
return filePath, nil
|
return filePath, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func handlePublishPorts(unitFile *parser.UnitFile, groupName string, podman *PodmanCmdline) error {
|
||||||
|
publishPorts := unitFile.LookupAll(groupName, KeyPublishPort)
|
||||||
|
for _, publishPort := range publishPorts {
|
||||||
|
publishPort = strings.TrimSpace(publishPort) // Allow whitespace after
|
||||||
|
|
||||||
|
// IP address could have colons in it. For example: "[::]:8080:80/tcp, so use custom splitter
|
||||||
|
parts := splitPorts(publishPort)
|
||||||
|
|
||||||
|
var containerPort string
|
||||||
|
ip := ""
|
||||||
|
hostPort := ""
|
||||||
|
|
||||||
|
// format (from podman run):
|
||||||
|
// ip:hostPort:containerPort | ip::containerPort | hostPort:containerPort | containerPort
|
||||||
|
//
|
||||||
|
// ip could be IPv6 with minimum of these chars "[::]"
|
||||||
|
// containerPort can have a suffix of "/tcp" or "/udp"
|
||||||
|
//
|
||||||
|
|
||||||
|
switch len(parts) {
|
||||||
|
case 1:
|
||||||
|
containerPort = parts[0]
|
||||||
|
|
||||||
|
case 2:
|
||||||
|
hostPort = parts[0]
|
||||||
|
containerPort = parts[1]
|
||||||
|
|
||||||
|
case 3:
|
||||||
|
ip = parts[0]
|
||||||
|
hostPort = parts[1]
|
||||||
|
containerPort = parts[2]
|
||||||
|
|
||||||
|
default:
|
||||||
|
return fmt.Errorf("invalid published port '%s'", publishPort)
|
||||||
|
}
|
||||||
|
|
||||||
|
if ip == "0.0.0.0" {
|
||||||
|
ip = ""
|
||||||
|
}
|
||||||
|
|
||||||
|
if len(hostPort) > 0 && !isPortRange(hostPort) {
|
||||||
|
return fmt.Errorf("invalid port format '%s'", hostPort)
|
||||||
|
}
|
||||||
|
|
||||||
|
if len(containerPort) > 0 && !isPortRange(containerPort) {
|
||||||
|
return fmt.Errorf("invalid port format '%s'", containerPort)
|
||||||
|
}
|
||||||
|
|
||||||
|
podman.add("--publish")
|
||||||
|
switch {
|
||||||
|
case len(ip) > 0 && len(hostPort) > 0:
|
||||||
|
podman.addf("%s:%s:%s", ip, hostPort, containerPort)
|
||||||
|
case len(ip) > 0:
|
||||||
|
podman.addf("%s::%s", ip, containerPort)
|
||||||
|
case len(hostPort) > 0:
|
||||||
|
podman.addf("%s:%s", hostPort, containerPort)
|
||||||
|
default:
|
||||||
|
podman.addf("%s", containerPort)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
@ -5,46 +5,46 @@ ExposeHostPort=1000
|
|||||||
## assert-podman-args --expose=2000-3000
|
## assert-podman-args --expose=2000-3000
|
||||||
ExposeHostPort=2000-3000
|
ExposeHostPort=2000-3000
|
||||||
|
|
||||||
## assert-podman-args -p=127.0.0.1:80:90
|
## assert-podman-args --publish 127.0.0.1:80:90
|
||||||
PublishPort=127.0.0.1:80:90
|
PublishPort=127.0.0.1:80:90
|
||||||
|
|
||||||
## assert-podman-args -p=80:91
|
## assert-podman-args --publish 80:91
|
||||||
PublishPort=0.0.0.0:80:91
|
PublishPort=0.0.0.0:80:91
|
||||||
|
|
||||||
## assert-podman-args -p=80:92
|
## assert-podman-args --publish 80:92
|
||||||
PublishPort=:80:92
|
PublishPort=:80:92
|
||||||
|
|
||||||
## assert-podman-args -p=127.0.0.1::93
|
## assert-podman-args --publish 127.0.0.1::93
|
||||||
PublishPort=127.0.0.1::93
|
PublishPort=127.0.0.1::93
|
||||||
|
|
||||||
## assert-podman-args -p=94
|
## assert-podman-args --publish 94
|
||||||
PublishPort=0.0.0.0::94
|
PublishPort=0.0.0.0::94
|
||||||
|
|
||||||
## assert-podman-args -p=95
|
## assert-podman-args --publish 95
|
||||||
PublishPort=::95
|
PublishPort=::95
|
||||||
|
|
||||||
## assert-podman-args -p=80:96
|
## assert-podman-args --publish 80:96
|
||||||
PublishPort=80:96
|
PublishPort=80:96
|
||||||
|
|
||||||
## assert-podman-args -p=97
|
## assert-podman-args --publish 97
|
||||||
PublishPort=97
|
PublishPort=97
|
||||||
|
|
||||||
## assert-podman-args -p=1234/udp
|
## assert-podman-args --publish 1234/udp
|
||||||
PublishPort=1234/udp
|
PublishPort=1234/udp
|
||||||
|
|
||||||
## assert-podman-args -p=1234:1234/udp
|
## assert-podman-args --publish 1234:1234/udp
|
||||||
PublishPort=1234:1234/udp
|
PublishPort=1234:1234/udp
|
||||||
|
|
||||||
## assert-podman-args -p=127.0.0.1:1234:1234/udp
|
## assert-podman-args --publish 127.0.0.1:1234:1234/udp
|
||||||
PublishPort=127.0.0.1:1234:1234/udp
|
PublishPort=127.0.0.1:1234:1234/udp
|
||||||
|
|
||||||
## assert-podman-args -p=1234/tcp
|
## assert-podman-args --publish 1234/tcp
|
||||||
PublishPort=1234/tcp
|
PublishPort=1234/tcp
|
||||||
|
|
||||||
## assert-podman-args -p=1234:1234/tcp
|
## assert-podman-args --publish 1234:1234/tcp
|
||||||
PublishPort=1234:1234/tcp
|
PublishPort=1234:1234/tcp
|
||||||
|
|
||||||
## assert-podman-args -p=127.0.0.1:1234:1234/tcp
|
## assert-podman-args --publish 127.0.0.1:1234:1234/tcp
|
||||||
PublishPort=127.0.0.1:1234:1234/tcp
|
PublishPort=127.0.0.1:1234:1234/tcp
|
||||||
|
|
||||||
## assert-podman-args --expose=2000-3000/udp
|
## assert-podman-args --expose=2000-3000/udp
|
||||||
|
44
test/e2e/quadlet/ports.kube
Normal file
44
test/e2e/quadlet/ports.kube
Normal file
@ -0,0 +1,44 @@
|
|||||||
|
[Kube]
|
||||||
|
Yaml=/opt/k8s/deployment.yml
|
||||||
|
|
||||||
|
## assert-podman-args --publish 127.0.0.1:80:90
|
||||||
|
PublishPort=127.0.0.1:80:90
|
||||||
|
|
||||||
|
## assert-podman-args --publish 80:91
|
||||||
|
PublishPort=0.0.0.0:80:91
|
||||||
|
|
||||||
|
## assert-podman-args --publish 80:92
|
||||||
|
PublishPort=:80:92
|
||||||
|
|
||||||
|
## assert-podman-args --publish 127.0.0.1::93
|
||||||
|
PublishPort=127.0.0.1::93
|
||||||
|
|
||||||
|
## assert-podman-args --publish 94
|
||||||
|
PublishPort=0.0.0.0::94
|
||||||
|
|
||||||
|
## assert-podman-args --publish 95
|
||||||
|
PublishPort=::95
|
||||||
|
|
||||||
|
## assert-podman-args --publish 80:96
|
||||||
|
PublishPort=80:96
|
||||||
|
|
||||||
|
## assert-podman-args --publish 97
|
||||||
|
PublishPort=97
|
||||||
|
|
||||||
|
## assert-podman-args --publish 1234/udp
|
||||||
|
PublishPort=1234/udp
|
||||||
|
|
||||||
|
## assert-podman-args --publish 1234:1234/udp
|
||||||
|
PublishPort=1234:1234/udp
|
||||||
|
|
||||||
|
## assert-podman-args --publish 127.0.0.1:1234:1234/udp
|
||||||
|
PublishPort=127.0.0.1:1234:1234/udp
|
||||||
|
|
||||||
|
## assert-podman-args --publish 1234/tcp
|
||||||
|
PublishPort=1234/tcp
|
||||||
|
|
||||||
|
## assert-podman-args --publish 1234:1234/tcp
|
||||||
|
PublishPort=1234:1234/tcp
|
||||||
|
|
||||||
|
## assert-podman-args --publish 127.0.0.1:1234:1234/tcp
|
||||||
|
PublishPort=127.0.0.1:1234:1234/tcp
|
@ -1,28 +1,28 @@
|
|||||||
[Container]
|
[Container]
|
||||||
Image=localhost/imagename
|
Image=localhost/imagename
|
||||||
## assert-podman-args -p=[::1]:80:90
|
## assert-podman-args --publish [::1]:80:90
|
||||||
PublishPort=[::1]:80:90
|
PublishPort=[::1]:80:90
|
||||||
|
|
||||||
## assert-podman-args -p=[::]:80:91
|
## assert-podman-args --publish [::]:80:91
|
||||||
PublishPort=[::]:80:91
|
PublishPort=[::]:80:91
|
||||||
|
|
||||||
## assert-podman-args -p=[2001:DB8::23]:80:91
|
## assert-podman-args --publish [2001:DB8::23]:80:91
|
||||||
PublishPort=[2001:DB8::23]:80:91
|
PublishPort=[2001:DB8::23]:80:91
|
||||||
|
|
||||||
## assert-podman-args -p=[::1]::93
|
## assert-podman-args --publish [::1]::93
|
||||||
PublishPort=[::1]::93
|
PublishPort=[::1]::93
|
||||||
|
|
||||||
## assert-podman-args -p=[::]::94
|
## assert-podman-args --publish [::]::94
|
||||||
PublishPort=[::]::94
|
PublishPort=[::]::94
|
||||||
|
|
||||||
## assert-podman-args -p=[2001:db8::42]::94
|
## assert-podman-args --publish [2001:db8::42]::94
|
||||||
PublishPort=[2001:db8::42]::94
|
PublishPort=[2001:db8::42]::94
|
||||||
|
|
||||||
## assert-podman-args -p=[::1]:1234:1234/udp
|
## assert-podman-args --publish [::1]:1234:1234/udp
|
||||||
PublishPort=[::1]:1234:1234/udp
|
PublishPort=[::1]:1234:1234/udp
|
||||||
|
|
||||||
## assert-podman-args -p=[::1]:1234:1234/tcp
|
## assert-podman-args --publish [::1]:1234:1234/tcp
|
||||||
PublishPort=[::1]:1234:1234/tcp
|
PublishPort=[::1]:1234:1234/tcp
|
||||||
|
|
||||||
## assert-podman-args -p=[2001:db8:c0:ff:ee::1]:1234:1234/udp
|
## assert-podman-args --publish [2001:db8:c0:ff:ee::1]:1234:1234/udp
|
||||||
PublishPort=[2001:db8:c0:ff:ee::1]:1234:1234/udp
|
PublishPort=[2001:db8:c0:ff:ee::1]:1234:1234/udp
|
||||||
|
29
test/e2e/quadlet/ports_ipv6.kube
Normal file
29
test/e2e/quadlet/ports_ipv6.kube
Normal file
@ -0,0 +1,29 @@
|
|||||||
|
[Kube]
|
||||||
|
Yaml=/opt/k8s/deployment.yml
|
||||||
|
|
||||||
|
## assert-podman-args --publish [::1]:80:90
|
||||||
|
PublishPort=[::1]:80:90
|
||||||
|
|
||||||
|
## assert-podman-args --publish [::]:80:91
|
||||||
|
PublishPort=[::]:80:91
|
||||||
|
|
||||||
|
## assert-podman-args --publish [2001:DB8::23]:80:91
|
||||||
|
PublishPort=[2001:DB8::23]:80:91
|
||||||
|
|
||||||
|
## assert-podman-args --publish [::1]::93
|
||||||
|
PublishPort=[::1]::93
|
||||||
|
|
||||||
|
## assert-podman-args --publish [::]::94
|
||||||
|
PublishPort=[::]::94
|
||||||
|
|
||||||
|
## assert-podman-args --publish [2001:db8::42]::94
|
||||||
|
PublishPort=[2001:db8::42]::94
|
||||||
|
|
||||||
|
## assert-podman-args --publish [::1]:1234:1234/udp
|
||||||
|
PublishPort=[::1]:1234:1234/udp
|
||||||
|
|
||||||
|
## assert-podman-args --publish [::1]:1234:1234/tcp
|
||||||
|
PublishPort=[::1]:1234:1234/tcp
|
||||||
|
|
||||||
|
## assert-podman-args --publish [2001:db8:c0:ff:ee::1]:1234:1234/udp
|
||||||
|
PublishPort=[2001:db8:c0:ff:ee::1]:1234:1234/udp
|
@ -492,6 +492,8 @@ var _ = Describe("quadlet system generator", func() {
|
|||||||
Entry("Kube - Network", "network.kube"),
|
Entry("Kube - Network", "network.kube"),
|
||||||
Entry("Kube - Quadlet Network", "network.quadlet.kube"),
|
Entry("Kube - Quadlet Network", "network.quadlet.kube"),
|
||||||
Entry("Kube - ConfigMap", "configmap.kube"),
|
Entry("Kube - ConfigMap", "configmap.kube"),
|
||||||
|
Entry("Kube - Publish IPv4 ports", "ports.kube"),
|
||||||
|
Entry("Kube - Publish IPv6 ports", "ports_ipv6.kube"),
|
||||||
|
|
||||||
Entry("Network - Basic", "basic.network"),
|
Entry("Network - Basic", "basic.network"),
|
||||||
Entry("Network - Label", "label.network"),
|
Entry("Network - Label", "label.network"),
|
||||||
|
Reference in New Issue
Block a user