github.com/containers/libpod@v1.9.4-0.20220419124438-4284fd425507/cmd/podman/port.go (about) 1 package main 2 3 import ( 4 "fmt" 5 "strconv" 6 "strings" 7 8 "github.com/containers/libpod/cmd/podman/cliconfig" 9 "github.com/containers/libpod/pkg/adapter" 10 "github.com/docker/go-connections/nat" 11 "github.com/pkg/errors" 12 "github.com/spf13/cobra" 13 ) 14 15 var ( 16 portCommand cliconfig.PortValues 17 portDescription = `List port mappings for the CONTAINER, or lookup the public-facing port that is NAT-ed to the PRIVATE_PORT 18 ` 19 _portCommand = &cobra.Command{ 20 Use: "port [flags] CONTAINER [PORT]", 21 Short: "List port mappings or a specific mapping for the container", 22 Long: portDescription, 23 RunE: func(cmd *cobra.Command, args []string) error { 24 portCommand.InputArgs = args 25 portCommand.GlobalFlags = MainGlobalOpts 26 portCommand.Remote = remoteclient 27 return portCmd(&portCommand) 28 }, 29 Args: func(cmd *cobra.Command, args []string) error { 30 return checkAllLatestAndCIDFile(cmd, args, true, false) 31 }, 32 Example: `podman port --all 33 podman port ctrID 80/tcp 34 podman port --latest 80`, 35 } 36 ) 37 38 func init() { 39 portCommand.Command = _portCommand 40 portCommand.SetHelpTemplate(HelpTemplate()) 41 portCommand.SetUsageTemplate(UsageTemplate()) 42 flags := portCommand.Flags() 43 44 flags.BoolVarP(&portCommand.All, "all", "a", false, "Display port information for all containers") 45 flags.BoolVarP(&portCommand.Latest, "latest", "l", false, "Act on the latest container podman is aware of") 46 47 markFlagHiddenForRemoteClient("latest", flags) 48 } 49 50 func portCmd(c *cliconfig.PortValues) error { 51 var ( 52 userPort nat.Port 53 err error 54 ) 55 args := c.InputArgs 56 57 if c.Latest && c.All { 58 return errors.Errorf("the 'all' and 'latest' options cannot be used together") 59 } 60 if c.All && len(args) > 0 { 61 return errors.Errorf("no additional arguments can be used with 'all'") 62 } 63 if len(args) == 0 && !c.Latest && !c.All { 64 return errors.Errorf("you must supply a running container name or id") 65 } 66 67 port := "" 68 if len(args) > 1 && !c.Latest { 69 port = args[1] 70 } 71 if len(args) == 1 && c.Latest { 72 port = args[0] 73 } 74 if len(port) > 0 { 75 fields := strings.Split(port, "/") 76 if len(fields) > 2 || len(fields) < 1 { 77 return errors.Errorf("port formats are port/protocol. '%s' is invalid", port) 78 } 79 if len(fields) == 1 { 80 fields = append(fields, "tcp") 81 } 82 83 userPort, err = nat.NewPort(fields[1], fields[0]) 84 if err != nil { 85 return err 86 } 87 } 88 89 runtime, err := adapter.GetRuntime(getContext(), &c.PodmanCommand) 90 if err != nil { 91 return errors.Wrapf(err, "could not get runtime") 92 } 93 defer runtime.DeferredShutdown(false) 94 containers, err := runtime.Port(c) 95 if err != nil { 96 return err 97 } 98 for _, con := range containers { 99 portmappings, err := con.PortMappings() 100 if err != nil { 101 return err 102 } 103 var found bool 104 // Iterate mappings 105 for _, v := range portmappings { 106 hostIP := v.HostIP 107 // Set host IP to 0.0.0.0 if blank 108 if hostIP == "" { 109 hostIP = "0.0.0.0" 110 } 111 if c.All { 112 fmt.Printf("%s\t", con.ID()[:12]) 113 } 114 // If not searching by port or port/proto, then dump what we see 115 if port == "" { 116 fmt.Printf("%d/%s -> %s:%d\n", v.ContainerPort, v.Protocol, hostIP, v.HostPort) 117 continue 118 } 119 containerPort, err := nat.NewPort(v.Protocol, strconv.Itoa(int(v.ContainerPort))) 120 if err != nil { 121 return err 122 } 123 if containerPort == userPort { 124 fmt.Printf("%s:%d\n", hostIP, v.HostPort) 125 found = true 126 break 127 } 128 } 129 if !found && port != "" { 130 return errors.Errorf("failed to find published port %q", port) 131 } 132 } 133 134 return nil 135 }