umbrel icon indicating copy to clipboard operation
umbrel copied to clipboard

Allow apps to have optional dependencies

Open oren-z0 opened this issue 2 years ago • 2 comments

Some apps can communicate with other apps, but should not require the user to install the other apps, and can still work fine even without them. This leads to multiple "flavors" of the app, i.e. Node-Red vs Node-Red (Bitcoin) and WoofBot (LND) vs WoofBot (without Lightning). This is obviously not scalable: if the number of "optionally dependent" apps grows, the number of flavors grows exponentially - i.e. if the app wants to be able to communicate with 1 more app, we need to duplicate all the previous flavors by 2: one for the flavor that does not require the new app and one for the flavor that does.

I've looked into how the installation mechanism works, and here is my idea for the changes:

  • The scripts/app install command should accept a second parameter in addition to the app id, which will be a path of some additional metadata file for the installation. This file could contain a json that looks like: {"useOptionalDependencies": ["app1", "app2", ...]}.
  • After all the app files were copied in the rsync call here, we could have a script to edit the umbrel-app.yml of the newly installed app, according to the metadata file, and add the dependencies. For safety, the umbral-app.yml file could have its own optional_dependencies list, so we could verify that all the apps in useOptionalDependencies are indeed listed in the apps' intended optional_dependencies (and nothing funny is going on). All of this could be done with jq and yq, or simply with a Python script.
  • The triggers/app script that calls scripts/app should also pass ${2} here. We should make sure that the other commands (except install) ignore it.
  • When Karen builds the args for the triggers/app script here, it should also include the original $event file-path.
  • In packages/manager/logic/apps.js, the install function should accept an additional string content parameter, then write it to the signal file here. writeSignalFile already supports passing a contents parameter.
  • In packages/manager/routes/v1/apps.js, the POST requests to /:id/install should call appsLogic.install(id, request.body) here, allowing the frontend to pass the {"useOptionalDependencies": ["app1", "app2", ...]} json in the request body (would also be nice to verify that the body is a valid json).

Then there is also the UI part...

If you give me a green light, I'll be happy to try implementing this myself and will send you a PR.

oren-z0 avatar Sep 28 '23 22:09 oren-z0

@lukechilds @mayankchhabra @nevets963 @nmfretz @louneskmt I'm just tagging some of you to get attention... I may have some free time to work on this, and I think it's an important feature. Please let me know if you have plans to implement this differently, or give me a green light to implement it in the way suggested above.

oren-z0 avatar Nov 08 '23 21:11 oren-z0