mirror of https://github.com/containers/podman.git
commit
0cd120507a
|
@ -0,0 +1,123 @@
|
|||
package containers
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"strconv"
|
||||
"strings"
|
||||
|
||||
"github.com/containers/libpod/cmd/podman/parse"
|
||||
"github.com/containers/libpod/cmd/podman/registry"
|
||||
"github.com/containers/libpod/pkg/domain/entities"
|
||||
"github.com/cri-o/ocicni/pkg/ocicni"
|
||||
"github.com/pkg/errors"
|
||||
"github.com/spf13/cobra"
|
||||
)
|
||||
|
||||
var (
|
||||
portDescription = `List port mappings for the CONTAINER, or lookup the public-facing port that is NAT-ed to the PRIVATE_PORT
|
||||
`
|
||||
portCommand = &cobra.Command{
|
||||
Use: "port [flags] CONTAINER [PORT]",
|
||||
Short: "List port mappings or a specific mapping for the container",
|
||||
Long: portDescription,
|
||||
RunE: port,
|
||||
Args: func(cmd *cobra.Command, args []string) error {
|
||||
return parse.CheckAllLatestAndCIDFile(cmd, args, true, false)
|
||||
},
|
||||
Example: `podman port --all
|
||||
podman port ctrID 80/tcp
|
||||
podman port --latest 80`,
|
||||
}
|
||||
)
|
||||
|
||||
var (
|
||||
portOpts entities.ContainerPortOptions
|
||||
)
|
||||
|
||||
func init() {
|
||||
registry.Commands = append(registry.Commands, registry.CliCommand{
|
||||
Mode: []entities.EngineMode{entities.ABIMode},
|
||||
Command: portCommand,
|
||||
})
|
||||
flags := portCommand.Flags()
|
||||
flags.BoolVarP(&portOpts.All, "all", "a", false, "Display port information for all containers")
|
||||
flags.BoolVarP(&portOpts.Latest, "latest", "l", false, "Act on the latest container podman is aware of")
|
||||
if registry.IsRemote() {
|
||||
_ = flags.MarkHidden("latest")
|
||||
}
|
||||
}
|
||||
|
||||
func port(cmd *cobra.Command, args []string) error {
|
||||
var (
|
||||
container string
|
||||
err error
|
||||
userPort ocicni.PortMapping
|
||||
)
|
||||
|
||||
if len(args) == 0 && !portOpts.Latest && !portOpts.All {
|
||||
return errors.Errorf("you must supply a running container name or id")
|
||||
}
|
||||
if !portOpts.Latest && len(args) >= 1 {
|
||||
container = args[0]
|
||||
}
|
||||
port := ""
|
||||
if len(args) > 1 && !portOpts.Latest {
|
||||
port = args[1]
|
||||
}
|
||||
if len(args) == 1 && portOpts.Latest {
|
||||
port = args[0]
|
||||
}
|
||||
if len(port) > 0 {
|
||||
fields := strings.Split(port, "/")
|
||||
if len(fields) > 2 || len(fields) < 1 {
|
||||
return errors.Errorf("port formats are port/protocol. '%s' is invalid", port)
|
||||
}
|
||||
if len(fields) == 1 {
|
||||
fields = append(fields, "tcp")
|
||||
}
|
||||
|
||||
portNum, err := strconv.Atoi(fields[0])
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
userPort = ocicni.PortMapping{
|
||||
HostPort: 0,
|
||||
ContainerPort: int32(portNum),
|
||||
Protocol: fields[1],
|
||||
HostIP: "",
|
||||
}
|
||||
}
|
||||
|
||||
reports, err := registry.ContainerEngine().ContainerPort(registry.GetContext(), container, portOpts)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
var found bool
|
||||
// Iterate mappings
|
||||
for _, report := range reports {
|
||||
for _, v := range report.Ports {
|
||||
hostIP := v.HostIP
|
||||
// Set host IP to 0.0.0.0 if blank
|
||||
if hostIP == "" {
|
||||
hostIP = "0.0.0.0"
|
||||
}
|
||||
if portOpts.All {
|
||||
fmt.Printf("%s\t", report.Id[:12])
|
||||
}
|
||||
// If not searching by port or port/proto, then dump what we see
|
||||
if port == "" {
|
||||
fmt.Printf("%d/%s -> %s:%d\n", v.ContainerPort, v.Protocol, hostIP, v.HostPort)
|
||||
continue
|
||||
}
|
||||
if v == userPort {
|
||||
fmt.Printf("%s:%d\n", hostIP, v.HostPort)
|
||||
found = true
|
||||
break
|
||||
}
|
||||
}
|
||||
if !found && port != "" {
|
||||
return errors.Errorf("failed to find published port %q", port)
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
|
@ -8,6 +8,7 @@ import (
|
|||
|
||||
"github.com/containers/libpod/libpod/define"
|
||||
"github.com/containers/libpod/pkg/specgen"
|
||||
"github.com/cri-o/ocicni/pkg/ocicni"
|
||||
)
|
||||
|
||||
type WaitOptions struct {
|
||||
|
@ -341,3 +342,17 @@ type ContainerPruneReport struct {
|
|||
ID map[string]int64
|
||||
Err map[string]error
|
||||
}
|
||||
|
||||
// ContainerPortOptions describes the options to obtain
|
||||
// port information on containers
|
||||
type ContainerPortOptions struct {
|
||||
All bool
|
||||
Latest bool
|
||||
}
|
||||
|
||||
// ContainerPortReport describes the output needed for
|
||||
// the CLI to output ports
|
||||
type ContainerPortReport struct {
|
||||
Id string
|
||||
Ports []ocicni.PortMapping
|
||||
}
|
||||
|
|
|
@ -28,6 +28,7 @@ type ContainerEngine interface {
|
|||
ContainerLogs(ctx context.Context, containers []string, options ContainerLogsOptions) error
|
||||
ContainerMount(ctx context.Context, nameOrIds []string, options ContainerMountOptions) ([]*ContainerMountReport, error)
|
||||
ContainerPause(ctx context.Context, namesOrIds []string, options PauseUnPauseOptions) ([]*PauseUnpauseReport, error)
|
||||
ContainerPort(ctx context.Context, nameOrId string, options ContainerPortOptions) ([]*ContainerPortReport, error)
|
||||
ContainerRestart(ctx context.Context, namesOrIds []string, options RestartOptions) ([]*RestartReport, error)
|
||||
ContainerRestore(ctx context.Context, namesOrIds []string, options RestoreOptions) ([]*RestoreReport, error)
|
||||
ContainerRm(ctx context.Context, namesOrIds []string, options RmOptions) ([]*RmReport, error)
|
||||
|
|
|
@ -929,3 +929,31 @@ func (ic *ContainerEngine) ContainerUnmount(ctx context.Context, nameOrIds []str
|
|||
func (ic *ContainerEngine) Config(_ context.Context) (*config.Config, error) {
|
||||
return ic.Libpod.GetConfig()
|
||||
}
|
||||
|
||||
func (ic *ContainerEngine) ContainerPort(ctx context.Context, nameOrId string, options entities.ContainerPortOptions) ([]*entities.ContainerPortReport, error) {
|
||||
var reports []*entities.ContainerPortReport
|
||||
ctrs, err := getContainersByContext(options.All, false, []string{nameOrId}, ic.Libpod)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
for _, con := range ctrs {
|
||||
state, err := con.State()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if state != define.ContainerStateRunning {
|
||||
continue
|
||||
}
|
||||
portmappings, err := con.PortMappings()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if len(portmappings) > 0 {
|
||||
reports = append(reports, &entities.ContainerPortReport{
|
||||
Id: con.ID(),
|
||||
Ports: portmappings,
|
||||
})
|
||||
}
|
||||
}
|
||||
return reports, nil
|
||||
}
|
||||
|
|
|
@ -371,3 +371,7 @@ func (ic *ContainerEngine) ContainerUnmount(ctx context.Context, nameOrIds []str
|
|||
func (ic *ContainerEngine) Config(_ context.Context) (*config.Config, error) {
|
||||
return config.Default()
|
||||
}
|
||||
|
||||
func (ic *ContainerEngine) ContainerPort(ctx context.Context, nameOrId string, options entities.ContainerPortOptions) ([]*entities.ContainerPortReport, error) {
|
||||
return nil, errors.New("not implemented")
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue