YunoHost / issues

General issue tracker for the YunoHost project
71 stars 7 forks source link

Edge case in port availability check #2404

Open FranzMari opened 1 month ago

FranzMari commented 1 month ago

Describe the bug

There is an edge case issue in the port-availability check, performed when updating an application, that can prevent user from updating apps on their environments.

The PortsResource's function provision_or_update() performs a check to see if the ports required by an application are being used by any other service/app in the system. This check is performed via the port_is_used()method, which considers two conditions:

This means that the latter check will always fail when users are upgrading an app whose new version requires to open a port that was already listed in the app's own settings.yml, even if they correctly remove the port from the firewall's configuration.

That's the case, for instance, for AdGuard:

$ python3
Python 3.9.2 (default, Feb 28 2021, 17:03:44) 
[GCC 10.2.1 20210110] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> port = 853
>>> os.system(f"grep --extended-regexp \"port: '?{port}'?\" /etc/yunohost/apps/*/settings.yml")
/etc/yunohost/apps/adguardhome/settings.yml:adguard_DoT_port: '853'
0

A possible workaround would be to exclude the app's directory from the second check listed above, using a command like this: os.system(f"grep --extended-regexp \"port: '?{port}'?\" /etc/yunohost/apps/*/settings.yml | grep -v --extended-regexp '^/etc/yunohost/apps/{appname}/'")

>>> appname = 'adguardhome'
>>> os.system(f"grep --extended-regexp \"port: '?{port}'?\" /etc/yunohost/apps/*/settings.yml | grep -v --extended-regexp '^/etc/yunohost/apps/{appname}/'")
256

I found out this by trying to upgrade AdGuard Home on my server, and the same issue was experienced by other users as well.

Context

Logs

https://paste.yunohost.org/raw/esokoyilez

wiggins-philip commented 2 weeks ago

Is there a workaround for this? I'm running into the same problem.

tituspijean commented 2 weeks ago

Sure, apply the aforementioned fix over there: https://github.com/YunoHost/yunohost/blob/dd394e94dc2bc4582a2471f7fe90106713189110/src/utils/resources.py#L1277

The file is in /usr/lib/python3/dist-packages/yunohost/utils/resources.py

Report back if that fixes the issue or not.

GoustiFruit commented 2 weeks ago

I don't understand what is needed to be changed on that line 1277 ? (my file already has that exact line, and the update doesn't work, "...port 853 is used...")

FranzMari commented 2 weeks ago

@wiggins-philip @GoustiFruit Unfortunately, the fix I proposed in the OP cannot be implemented with just one line, as the function doesn't have access to the app name. I tried to set up a development environment to apply all the required changes and test the fix, but I couldn't make it successfully access the network and I had to give up (at least for now). A quick workaround is to edit the app's settings.yml file removing both the ports that block the upgrade, run the upgrade again and restore the ports in the file.

GoustiFruit commented 1 week ago

Would uninstalling/reinstalling AdGuard work ?

FranzMari commented 1 week ago

@GoustiFruit I think it should, but I didn't try.

Bluesmoothie commented 1 week ago

Temporary workaround tested and functionnal for me : In https://github.com/YunoHost/yunohost/blob/dd394e94dc2bc4582a2471f7fe90106713189110/src/utils/resources.py#L1291 The file is in /usr/lib/python3/dist-packages/yunohost/utils/resources.py Step 1: Replace

        return used_by_process or used_by_app or used_by_self_provisioning

By

        return 0

Step 2: Reboot (for the changes to take effect) Step 3: Update AdGuard normally via yunohost Step 4: Restore resources.py to it's original state Step 5: Reboot again And it's all good

GoustiFruit commented 1 week ago

It made it for me. Thanks !