Skip to content

Commit

Permalink
Fix port reuse during provisionning.
Browse files Browse the repository at this point in the history
Before this, provisionning might use twice the same port (second app install for example).
Indeed, _port_is_used only checks processes and already installed apps. Not the current
app being installed.
  • Loading branch information
Salamandar committed Jan 28, 2024
1 parent fc12cb1 commit 3559fd1
Showing 1 changed file with 11 additions and 4 deletions.
15 changes: 11 additions & 4 deletions src/utils/resources.py
Original file line number Diff line number Diff line change
Expand Up @@ -1216,17 +1216,23 @@ def __init__(self, properties: Dict[str, Any], *args, **kwargs):
if properties[port]["default"] is None:
properties[port]["default"] = random.randint(10000, 60000)

# This is to prevent using twice the same port during provisionning.
self.used_ports: list[int] = []

super().__init__({"ports": properties}, *args, **kwargs)

def _port_is_used(self, port):
# FIXME : this could be less brutal than two os.system...
cmd1 = (
used_by_process = os.system(
"ss --numeric --listening --tcp --udp | awk '{print$5}' | grep --quiet --extended-regexp ':%s$'"
% port
)
) == 0
# This second command is mean to cover (most) case where an app is using a port yet ain't currently using it for some reason (typically service ain't up)
cmd2 = f"grep --quiet --extended-regexp \"port: '?{port}'?\" /etc/yunohost/apps/*/settings.yml"
return os.system(cmd1) == 0 or os.system(cmd2) == 0
used_by_app = os.system(
f"grep --quiet --extended-regexp \"port: '?{port}'?\" /etc/yunohost/apps/*/settings.yml")
used_by_self_provisioning = port in self.used_ports

return used_by_process or used_by_app or used_by_self_provisioning

def provision_or_update(self, context: Dict = {}):
from yunohost.firewall import firewall_allow, firewall_disallow
Expand Down Expand Up @@ -1256,6 +1262,7 @@ def provision_or_update(self, context: Dict = {}):
while self._port_is_used(port_value):
port_value += 1

self.used_ports.append(port_value)
self.set_setting(setting_name, port_value)

if infos["exposed"]:
Expand Down

0 comments on commit 3559fd1

Please sign in to comment.