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
|
||||
|
||||
#### `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 files are named with a `.volume` extension and contain a section `[Volume]` describing the
|
||||
|
@ -141,6 +141,7 @@ var (
|
||||
KeyRemapUIDSize: true,
|
||||
KeyNetwork: true,
|
||||
KeyConfigMap: true,
|
||||
KeyPublishPort: true,
|
||||
}
|
||||
)
|
||||
|
||||
@ -454,63 +455,8 @@ func ConvertContainer(container *parser.UnitFile, isUser bool) (*parser.UnitFile
|
||||
podman.addf("--expose=%s", exposedPort)
|
||||
}
|
||||
|
||||
publishPorts := container.LookupAll(ContainerGroup, 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 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)
|
||||
}
|
||||
if err := handlePublishPorts(container, ContainerGroup, podman); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
podman.addEnv(podmanEnv)
|
||||
@ -775,6 +721,10 @@ func ConvertKube(kube *parser.UnitFile, isUser bool) (*parser.UnitFile, error) {
|
||||
execStart.add("--configmap", configMapPath)
|
||||
}
|
||||
|
||||
if err := handlePublishPorts(kube, KubeGroup, execStart); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
execStart.add(yamlPath)
|
||||
|
||||
service.AddCmdline(ServiceGroup, "ExecStart", execStart.Args)
|
||||
@ -876,3 +826,67 @@ func getAbsolutePath(quadletUnitFile *parser.UnitFile, filePath string) (string,
|
||||
}
|
||||
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
|
||||
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
|
||||
|
||||
## assert-podman-args -p=80:91
|
||||
## assert-podman-args --publish 80:91
|
||||
PublishPort=0.0.0.0:80:91
|
||||
|
||||
## assert-podman-args -p=80:92
|
||||
## assert-podman-args --publish 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
|
||||
|
||||
## assert-podman-args -p=94
|
||||
## assert-podman-args --publish 94
|
||||
PublishPort=0.0.0.0::94
|
||||
|
||||
## assert-podman-args -p=95
|
||||
## assert-podman-args --publish 95
|
||||
PublishPort=::95
|
||||
|
||||
## assert-podman-args -p=80:96
|
||||
## assert-podman-args --publish 80:96
|
||||
PublishPort=80:96
|
||||
|
||||
## assert-podman-args -p=97
|
||||
## assert-podman-args --publish 97
|
||||
PublishPort=97
|
||||
|
||||
## assert-podman-args -p=1234/udp
|
||||
## assert-podman-args --publish 1234/udp
|
||||
PublishPort=1234/udp
|
||||
|
||||
## assert-podman-args -p=1234:1234/udp
|
||||
## assert-podman-args --publish 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
|
||||
|
||||
## assert-podman-args -p=1234/tcp
|
||||
## assert-podman-args --publish 1234/tcp
|
||||
PublishPort=1234/tcp
|
||||
|
||||
## assert-podman-args -p=1234:1234/tcp
|
||||
## assert-podman-args --publish 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
|
||||
|
||||
## 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]
|
||||
Image=localhost/imagename
|
||||
## assert-podman-args -p=[::1]:80:90
|
||||
## assert-podman-args --publish [::1]:80:90
|
||||
PublishPort=[::1]:80:90
|
||||
|
||||
## assert-podman-args -p=[::]:80:91
|
||||
## assert-podman-args --publish [::]: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
|
||||
|
||||
## assert-podman-args -p=[::1]::93
|
||||
## assert-podman-args --publish [::1]::93
|
||||
PublishPort=[::1]::93
|
||||
|
||||
## assert-podman-args -p=[::]::94
|
||||
## assert-podman-args --publish [::]::94
|
||||
PublishPort=[::]::94
|
||||
|
||||
## assert-podman-args -p=[2001:db8::42]::94
|
||||
## assert-podman-args --publish [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
|
||||
|
||||
## assert-podman-args -p=[::1]:1234:1234/tcp
|
||||
## assert-podman-args --publish [::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
|
||||
|
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 - Quadlet Network", "network.quadlet.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 - Label", "label.network"),
|
||||
|
Reference in New Issue
Block a user