umbrel
umbrel copied to clipboard
Allow apps to have optional dependencies
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 installcommand 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.ymlof the newly installed app, according to the metadata file, and add the dependencies. For safety, theumbral-app.ymlfile could have its ownoptional_dependencieslist, so we could verify that all the apps inuseOptionalDependenciesare indeed listed in the apps' intendedoptional_dependencies(and nothing funny is going on). All of this could be done withjqandyq, or simply with a Python script. - The
triggers/appscript that callsscripts/appshould also pass${2}here. We should make sure that the other commands (exceptinstall) ignore it. - When Karen builds the args for the
triggers/appscript here, it should also include the original$eventfile-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.writeSignalFilealready supports passing acontentsparameter. - In
packages/manager/routes/v1/apps.js, the POST requests to/:id/installshould callappsLogic.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.
@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.