From 4b2dc48d0bcde9d9dccb05f829019a52f3eddec7 Mon Sep 17 00:00:00 2001 From: Paul Holzinger Date: Tue, 24 Aug 2021 10:23:10 +0200 Subject: podman inspect show exposed ports Podman inspect has to show exposed ports to match docker. This requires storing the exposed ports in the container config. A exposed port is shown as `"80/tcp": null` while a forwarded port is shown as `"80/tcp": [{"HostIp": "", "HostPort": "8080" }]`. Also make sure to add the exposed ports to the new image when the container is commited. Fixes #10777 Signed-off-by: Paul Holzinger --- libpod/container_commit.go | 5 +++++ libpod/container_config.go | 6 ++++++ libpod/container_inspect.go | 2 +- libpod/networking_linux.go | 2 +- libpod/options.go | 3 ++- libpod/pod_api.go | 2 +- libpod/runtime_pod_infra_linux.go | 3 ++- libpod/util.go | 13 +++++++++++-- 8 files changed, 29 insertions(+), 7 deletions(-) (limited to 'libpod') diff --git a/libpod/container_commit.go b/libpod/container_commit.go index c1dd42942..87e5d511c 100644 --- a/libpod/container_commit.go +++ b/libpod/container_commit.go @@ -99,6 +99,11 @@ func (c *Container) Commit(ctx context.Context, destImage string, options Contai for _, p := range c.config.PortMappings { importBuilder.SetPort(fmt.Sprintf("%d/%s", p.ContainerPort, p.Protocol)) } + for port, protocols := range c.config.ExposedPorts { + for _, protocol := range protocols { + importBuilder.SetPort(fmt.Sprintf("%d/%s", port, protocol)) + } + } // Labels for k, v := range c.Labels() { importBuilder.SetLabel(k, v) diff --git a/libpod/container_config.go b/libpod/container_config.go index e15030c15..b80b23c25 100644 --- a/libpod/container_config.go +++ b/libpod/container_config.go @@ -229,6 +229,12 @@ type ContainerNetworkConfig struct { // namespace // These are not used unless CreateNetNS is true PortMappings []ocicni.PortMapping `json:"portMappings,omitempty"` + // ExposedPorts are the ports which are exposed but not forwarded + // into the container. + // The map key is the port and the string slice contains the protocols, + // e.g. tcp and udp + // These are only set when exposed ports are given but not published. + ExposedPorts map[uint16][]string `json:"exposedPorts,omitempty"` // UseImageResolvConf indicates that resolv.conf should not be // bind-mounted inside the container. // Conflicts with DNSServer, DNSSearch, DNSOption. diff --git a/libpod/container_inspect.go b/libpod/container_inspect.go index 8c662c488..97318a2e8 100644 --- a/libpod/container_inspect.go +++ b/libpod/container_inspect.go @@ -624,7 +624,7 @@ func (c *Container) generateInspectContainerHostConfig(ctrSpec *spec.Spec, named // Port bindings. // Only populate if we're using CNI to configure the network. if c.config.CreateNetNS { - hostConfig.PortBindings = makeInspectPortBindings(c.config.PortMappings) + hostConfig.PortBindings = makeInspectPortBindings(c.config.PortMappings, c.config.ExposedPorts) } else { hostConfig.PortBindings = make(map[string][]define.InspectHostPort) } diff --git a/libpod/networking_linux.go b/libpod/networking_linux.go index 2ed2bb01b..dbe2274d3 100644 --- a/libpod/networking_linux.go +++ b/libpod/networking_linux.go @@ -1015,7 +1015,7 @@ func (c *Container) getContainerNetworkInfo() (*define.InspectNetworkSettings, e } settings := new(define.InspectNetworkSettings) - settings.Ports = makeInspectPortBindings(c.config.PortMappings) + settings.Ports = makeInspectPortBindings(c.config.PortMappings, c.config.ExposedPorts) networks, isDefault, err := c.networks() if err != nil { diff --git a/libpod/options.go b/libpod/options.go index 59aec66c6..0bcd1e3a6 100644 --- a/libpod/options.go +++ b/libpod/options.go @@ -1041,7 +1041,7 @@ func WithDependencyCtrs(ctrs []*Container) CtrCreateOption { // namespace with a minimal configuration. // An optional array of port mappings can be provided. // Conflicts with WithNetNSFrom(). -func WithNetNS(portMappings []ocicni.PortMapping, postConfigureNetNS bool, netmode string, networks []string) CtrCreateOption { +func WithNetNS(portMappings []ocicni.PortMapping, exposedPorts map[uint16][]string, postConfigureNetNS bool, netmode string, networks []string) CtrCreateOption { return func(ctr *Container) error { if ctr.valid { return define.ErrCtrFinalized @@ -1051,6 +1051,7 @@ func WithNetNS(portMappings []ocicni.PortMapping, postConfigureNetNS bool, netmo ctr.config.NetMode = namespaces.NetworkMode(netmode) ctr.config.CreateNetNS = true ctr.config.PortMappings = portMappings + ctr.config.ExposedPorts = exposedPorts ctr.config.Networks = networks diff --git a/libpod/pod_api.go b/libpod/pod_api.go index 716eb2e5b..53fb9538f 100644 --- a/libpod/pod_api.go +++ b/libpod/pod_api.go @@ -616,7 +616,7 @@ func (p *Pod) Inspect() (*define.InspectPodData, error) { infraConfig.Networks = append(infraConfig.Networks, p.config.InfraContainer.Networks...) } infraConfig.NetworkOptions = p.config.InfraContainer.NetworkOptions - infraConfig.PortBindings = makeInspectPortBindings(p.config.InfraContainer.PortBindings) + infraConfig.PortBindings = makeInspectPortBindings(p.config.InfraContainer.PortBindings, nil) } inspectData := define.InspectPodData{ diff --git a/libpod/runtime_pod_infra_linux.go b/libpod/runtime_pod_infra_linux.go index 49213032e..9236fb1f5 100644 --- a/libpod/runtime_pod_infra_linux.go +++ b/libpod/runtime_pod_infra_linux.go @@ -112,7 +112,8 @@ func (r *Runtime) makeInfraContainer(ctx context.Context, p *Pod, imgName, rawIm options = append(options, WithNetworkOptions(p.config.InfraContainer.NetworkOptions)) } } - options = append(options, WithNetNS(p.config.InfraContainer.PortBindings, !p.config.InfraContainer.Userns.IsHost(), netmode, p.config.InfraContainer.Networks)) + // FIXME allow pods to have exposed ports + options = append(options, WithNetNS(p.config.InfraContainer.PortBindings, nil, !p.config.InfraContainer.Userns.IsHost(), netmode, p.config.InfraContainer.Networks)) } // For each option in InfraContainerConfig - if set, pass into diff --git a/libpod/util.go b/libpod/util.go index 3b32fb264..ed5c4e6c6 100644 --- a/libpod/util.go +++ b/libpod/util.go @@ -295,8 +295,8 @@ func writeHijackHeader(r *http.Request, conn io.Writer) { } // Convert OCICNI port bindings into Inspect-formatted port bindings. -func makeInspectPortBindings(bindings []ocicni.PortMapping) map[string][]define.InspectHostPort { - portBindings := make(map[string][]define.InspectHostPort) +func makeInspectPortBindings(bindings []ocicni.PortMapping, expose map[uint16][]string) map[string][]define.InspectHostPort { + portBindings := make(map[string][]define.InspectHostPort, len(bindings)) for _, port := range bindings { key := fmt.Sprintf("%d/%s", port.ContainerPort, port.Protocol) hostPorts := portBindings[key] @@ -309,6 +309,15 @@ func makeInspectPortBindings(bindings []ocicni.PortMapping) map[string][]define. }) portBindings[key] = hostPorts } + // add exposed ports without host port information to match docker + for port, protocols := range expose { + for _, protocol := range protocols { + key := fmt.Sprintf("%d/%s", port, protocol) + if _, ok := portBindings[key]; !ok { + portBindings[key] = nil + } + } + } return portBindings } -- cgit v1.2.3-54-g00ecf