Skip to content

Commit

Permalink
Merge pull request #184 from ThePorgs/fix/missing_iface
Browse files Browse the repository at this point in the history
Catching exception when interface missing for Desktop beta feature
  • Loading branch information
Dramelac authored Sep 28, 2023
2 parents 35bc0d7 + c9866c2 commit 9b697f1
Showing 1 changed file with 34 additions and 13 deletions.
47 changes: 34 additions & 13 deletions exegol/model/ContainerConfig.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
import errno
import logging
import os
import random
import re
import socket
import string
from datetime import datetime
from enum import Enum
Expand All @@ -12,9 +14,9 @@
from docker.types import Mount
from rich.prompt import Prompt

from exegol.config.ConstantConfig import ConstantConfig
from exegol.config.EnvInfo import EnvInfo
from exegol.config.UserConfig import UserConfig
from exegol.config.ConstantConfig import ConstantConfig
from exegol.console.ConsoleFormat import boolFormatter, getColor
from exegol.console.ExegolPrompt import Confirm
from exegol.console.cli.ParametersManager import ParametersManager
Expand Down Expand Up @@ -480,7 +482,7 @@ def enableDesktop(self, desktop_config: str = ""):
"""Procedure to enable exegol desktop feature"""
if not self.isDesktopEnabled():
logger.verbose("Config: Enabling exegol desktop")
self.configureDesktop(desktop_config)
self.configureDesktop(desktop_config, create_mode=True)
assert self.__desktop_proto is not None
assert self.__desktop_host is not None
assert self.__desktop_port is not None
Expand All @@ -498,7 +500,7 @@ def enableDesktop(self, desktop_config: str = ""):
# Exposing desktop service
self.addPort(port_host=self.__desktop_port, port_container=self.__default_desktop_port[self.__desktop_proto], host_ip=self.__desktop_host)

def configureDesktop(self, desktop_config: str):
def configureDesktop(self, desktop_config: str, create_mode: bool = False):
"""Configure the exegol desktop feature from user parameters.
Accepted format: 'mode:host:port'
"""
Expand All @@ -508,16 +510,18 @@ def configureDesktop(self, desktop_config: str):
for i, data in enumerate(desktop_config.split(":")):
if not data:
continue
if i == 0:
if i == 0: # protocol
logger.debug(f"Desktop proto set: {data}")
data = data.lower()
if data in UserConfig.desktop_available_proto:
self.__desktop_proto = data
else:
logger.critical(f"The desktop mode '{data}' is not supported. Please choose a supported mode: [green]{', '.join(UserConfig.desktop_available_proto)}[/green].")
elif i == 1 and data:
elif i == 1 and data: # host
logger.debug(f"Desktop host set: {data}")
self.__desktop_host = data
self.__desktop_port = self.__findAvailableRandomPort(self.__desktop_host)
elif i == 2:
elif i == 2: # port
logger.debug(f"Desktop port set: {data}")
try:
self.__desktop_port = int(data)
except ValueError:
Expand All @@ -526,7 +530,21 @@ def configureDesktop(self, desktop_config: str):
logger.critical(f"Your configuration is invalid, please use the following format:[green]mode:host:port[/green]")

if self.__desktop_port is None:
self.__desktop_port = self.__findAvailableRandomPort()
logger.debug(f"Desktop port will be set automatically")
self.__desktop_port = self.__findAvailableRandomPort(self.__desktop_host)

if create_mode:
# Check if the port is available
with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as s:
try:
s.bind((self.__desktop_host, self.__desktop_port))
except socket.error as e:
if e.errno == errno.EADDRINUSE:
logger.critical(f"The port {self.__desktop_host}:{self.__desktop_port} is already in use !")
elif e.errno == errno.EADDRNOTAVAIL:
logger.critical(f"The network {self.__desktop_host}:{self.__desktop_port} is not available !")
else:
logger.critical(f"The supplied network configuration {self.__desktop_host}:{self.__desktop_port} is not available ! ([{e.errno}] {e})")

def __disableDesktop(self):
"""Procedure to disable exegol desktop feature"""
Expand Down Expand Up @@ -744,11 +762,14 @@ def generateRandomPassword(length: int = 30) -> str:
@staticmethod
def __findAvailableRandomPort(interface: str = 'localhost') -> int:
"""Find an available random port. Using the socket system to """
import socket
sock = socket.socket()
sock.bind((interface, 0)) # Using port 0 let the system decide for a random port
random_port = sock.getsockname()[1]
sock.close()
logger.debug(f"Attempting to bind to interface {interface}")
with socket.socket() as sock:
try:
sock.bind((interface, 0)) # Using port 0 let the system decide for a random port
except OSError as e:
logger.critical(f"Unable to bind a port to the interface {interface} ({e})")
random_port = sock.getsockname()[1]
logger.debug(f"Found available port {random_port}")
return random_port

# ===== Apply config section =====
Expand Down

0 comments on commit 9b697f1

Please sign in to comment.