From 970eaf003328cab69aa4ccaa78cf908f5a87fff0 Mon Sep 17 00:00:00 2001 From: baude Date: Mon, 30 Apr 2018 15:22:50 -0500 Subject: podman should assign a host port to -p when omitted If the user does not provide a host port when adding -p to create/run, podman should inject an available random port. podman run -p 80 .... podman should assign a random port to the host and expose the container port 80 to it Signed-off-by: baude Closes: #703 Approved by: rhatdan --- cmd/podman/create.go | 43 ++++++++++++++++++++++++++++++++----------- 1 file changed, 32 insertions(+), 11 deletions(-) (limited to 'cmd/podman/create.go') diff --git a/cmd/podman/create.go b/cmd/podman/create.go index 856fbfa83..54a542ee5 100644 --- a/cmd/podman/create.go +++ b/cmd/podman/create.go @@ -371,26 +371,47 @@ func exposedPorts(c *cli.Context, imageExposedPorts map[string]struct{}) (map[na if err != nil { return nil, err } - l, err := net.Listen("tcp", ":0") + rp, err := getRandomPort() if err != nil { - return nil, errors.Wrapf(err, "unable to get free port") - } - defer l.Close() - _, randomPort, err := net.SplitHostPort(l.Addr().String()) - if err != nil { - return nil, errors.Wrapf(err, "unable to determine free port") + return nil, err } - rp, err := strconv.Atoi(randomPort) + logrus.Debug(fmt.Sprintf("Using random host port %d with container port %d", rp, p.Int())) + portBindings[p] = CreatePortBinding(rp, "") + } + } + + // We need to see if any host ports are not populated and if so, we need to assign a + // random port to them. + for k, pb := range portBindings { + if pb[0].HostPort == "" { + hostPort, err := getRandomPort() if err != nil { - return nil, errors.Wrapf(err, "unable to convert random port to int") + return nil, err } - logrus.Debug(fmt.Sprintf("Using random host port %s with container port %d", randomPort, p.Int())) - portBindings[p] = CreatePortBinding(rp, "") + logrus.Debug(fmt.Sprintf("Using random host port %d with container port %s", hostPort, k.Port())) + pb[0].HostPort = strconv.Itoa(hostPort) } } return portBindings, nil } +func getRandomPort() (int, error) { + l, err := net.Listen("tcp", ":0") + if err != nil { + return 0, errors.Wrapf(err, "unable to get free port") + } + defer l.Close() + _, randomPort, err := net.SplitHostPort(l.Addr().String()) + if err != nil { + return 0, errors.Wrapf(err, "unable to determine free port") + } + rp, err := strconv.Atoi(randomPort) + if err != nil { + return 0, errors.Wrapf(err, "unable to convert random port to int") + } + return rp, nil +} + // Parses CLI options related to container creation into a config which can be // parsed into an OCI runtime spec func parseCreateOpts(c *cli.Context, runtime *libpod.Runtime, imageName string, data *inspect.ImageData) (*createConfig, error) { -- cgit v1.2.3-54-g00ecf