Add -expose flag to expose ports without publishing

This commit is contained in:
Michael Crosby
2013-10-04 09:51:34 -07:00
parent 675f1a8069
commit 3e4c9d723c
3 changed files with 54 additions and 12 deletions
+29 -7
View File
@@ -124,6 +124,10 @@ func (p Port) Port() string {
return strings.Split(string(p), "/")[1]
}
func NewPort(proto, port string) Port {
return Port(fmt.Sprintf("%s/%s", proto, port))
}
func ParseRun(args []string, capabilities *Capabilities) (*Config, *HostConfig, *flag.FlagSet, error) {
cmd := Subcmd("run", "[OPTIONS] IMAGE [COMMAND] [ARG...]", "Run a command in a new container")
if os.Getenv("TEST") != "" {
@@ -152,8 +156,11 @@ func ParseRun(args []string, capabilities *Capabilities) (*Config, *HostConfig,
flCpuShares := cmd.Int64("c", 0, "CPU shares (relative weight)")
var flPorts ListOpts
cmd.Var(&flPorts, "p", "Expose a container's port to the host (use 'docker port' to see the actual mapping)")
var flPublish ListOpts
cmd.Var(&flPublish, "p", "Publish a container's port to the host (use 'docker port' to see the actual mapping)")
var flExpose ListOpts
cmd.Var(&flExpose, "expose", "Expose a port from the container without publishing it to your host")
var flEnv ListOpts
cmd.Var(&flEnv, "e", "Set environment variables")
@@ -238,11 +245,22 @@ func ParseRun(args []string, capabilities *Capabilities) (*Config, *HostConfig,
domainname = parts[1]
}
ports, portBindings, err := parsePortSpecs(flPorts)
ports, portBindings, err := parsePortSpecs(flPublish)
if err != nil {
return nil, nil, cmd, err
}
// Merge in exposed ports to the map of published ports
for _, e := range flExpose {
if strings.Contains(e, ":") {
return nil, nil, cmd, fmt.Errorf("Invalid port format for -expose: %s", e)
}
p := NewPort(splitProtoPort(e))
if _, exists := ports[p]; !exists {
ports[p] = struct{}{}
}
}
config := &Config{
Hostname: *flHostname,
Domainname: domainname,
@@ -301,8 +319,15 @@ type NetworkSettings struct {
func (settings *NetworkSettings) PortMappingAPI() []APIPort {
var mapping []APIPort
for port, bindings := range settings.Ports {
p, _ := parsePort(port.Port())
if len(bindings) == 0 {
mapping = append(mapping, APIPort{
PublicPort: int64(p),
Type: port.Proto(),
})
continue
}
for _, binding := range bindings {
p, _ := parsePort(port.Port())
h, _ := parsePort(binding.HostPort)
mapping = append(mapping, APIPort{
PrivatePort: int64(p),
@@ -945,9 +970,6 @@ func (container *Container) allocateNetwork(hostConfig *HostConfig) error {
for port := range portSpecs {
binding := bindings[port]
if len(binding) == 0 {
binding = append(binding, PortBinding{})
}
for i := 0; i < len(binding); i++ {
b := binding[i]
nat, err := iface.AllocatePort(port, b)
+4 -3
View File
@@ -12,7 +12,7 @@
Run a command in a new container
-a=map[]: Attach to stdin, stdout or stderr.
-a=map[]: Attach to stdin, stdout or stderr
-c=0: CPU shares (relative weight)
-cidfile="": Write the container ID to the file
-d=false: Detached mode: Run container in the background, print new container id
@@ -28,10 +28,11 @@
-u="": Username or UID
-dns=[]: Set custom dns servers for the container
-v=[]: Create a bind mount with: [host-dir]:[container-dir]:[rw|ro]. If "container-dir" is missing, then docker creates a new volume.
-volumes-from="": Mount all volumes from the given container.
-entrypoint="": Overwrite the default entrypoint set by the image.
-volumes-from="": Mount all volumes from the given container
-entrypoint="": Overwrite the default entrypoint set by the image
-w="": Working directory inside the container
-lxc-conf=[]: Add custom lxc options -lxc-conf="lxc.cgroup.cpuset.cpus = 0,1"
-expose=[]: Expose a port from the container without publishing it to your host
Examples
--------
+21 -2
View File
@@ -223,7 +223,8 @@ func parsePortSpecs(ports []string) (map[Port]struct{}, map[Port][]PortBinding,
if containerPort == "" {
return nil, nil, fmt.Errorf("No port specified: %s<empty>", rawPort)
}
port := Port(fmt.Sprintf("%s/%s", proto, containerPort))
port := NewPort(proto, containerPort)
if _, exists := exposedPorts[port]; !exists {
exposedPorts[port] = struct{}{}
}
@@ -241,6 +242,18 @@ func parsePortSpecs(ports []string) (map[Port]struct{}, map[Port][]PortBinding,
return exposedPorts, bindings, nil
}
func splitProtoPort(rawPort string) (string, string) {
parts := strings.Split(rawPort, "/")
l := len(parts)
if l == 0 {
return "", ""
}
if l == 1 {
return "tcp", rawPort
}
return parts[1], parts[0]
}
func parsePort(rawPort string) (int, error) {
port, err := strconv.ParseUint(rawPort, 10, 16)
if err != nil {
@@ -258,7 +271,13 @@ func migratePortMappings(config *Config) error {
return err
}
config.PortSpecs = nil
config.ExposedPorts = ports
if config.ExposedPorts == nil {
config.ExposedPorts = make(map[Port]struct{}, len(ports))
}
for k, v := range ports {
config.ExposedPorts[k] = v
}
}
return nil
}