createCluster: ask OS/kernel for free port...

... instead of leaving this up to docker, since then we don't know about
it when creating the labels, etc. used e.g. for updating the kubeconfig with
the correct port
pull/279/head
iwilltry42 4 years ago
parent 711e1ed048
commit 3205cbac67
No known key found for this signature in database
GPG Key ID: 7BA57AD1CFF16110
  1. 44
      cmd/util/ports.go

@ -54,19 +54,25 @@ func ParseAPIPort(portString string) (k3d.ExposeAPI, error) {
}
// Verify 'port' is an integer and within port ranges
if exposeAPI.Port != "" {
p, err := strconv.Atoi(exposeAPI.Port)
if err != nil {
log.Errorln("Failed to parse port mapping")
if exposeAPI.Port == "" {
log.Debugf("API-Port Mapping didn't specify hostPort, choosing one randomly...")
freePort, err := GetFreePort()
if err != nil || freePort == 0 {
log.Errorln("Failed to get a free port")
return exposeAPI, err
}
exposeAPI.Port = strconv.Itoa(freePort)
log.Debugf("Got free port for API: '%d'", freePort)
}
p, err := strconv.Atoi(exposeAPI.Port)
if err != nil {
log.Errorln("Failed to parse port mapping")
return exposeAPI, err
}
if p < 0 || p > 65535 {
log.Errorln("Failed to parse API Port specification")
return exposeAPI, fmt.Errorf("port value '%d' out of range", p)
}
} else {
log.Debugf("API-Port Mapping didn't specify hostPort!")
if p < 0 || p > 65535 {
log.Errorln("Failed to parse API Port specification")
return exposeAPI, fmt.Errorf("Port value '%d' out of range", p)
}
return exposeAPI, nil
@ -77,3 +83,21 @@ func ParseAPIPort(portString string) (k3d.ExposeAPI, error) {
func ValidatePortMap(portmap string) (string, error) {
return portmap, nil // TODO: ValidatePortMap: add validation of port mapping
}
// GetFreePort tries to fetch an open port from the OS-Kernel
func GetFreePort() (int, error) {
tcpAddress, err := net.ResolveTCPAddr("tcp", "localhost:0")
if err != nil {
log.Errorln("Failed to resolve address")
return 0, err
}
tcpListener, err := net.ListenTCP("tcp", tcpAddress)
if err != nil {
log.Errorln("Failed to create TCP Listener")
return 0, err
}
defer tcpListener.Close()
return tcpListener.Addr().(*net.TCPAddr).Port, nil
}

Loading…
Cancel
Save