Share dependencies between bundles
Closed this issue · 5 comments
Is your feature request related to a problem? Please describe.
During today's community meeting a problem surfaced from how bundles do not share dependencies. As each installation is its own autonomous unit of "bundle", sharing dependencies could show merits from allowing the installations to not re-install and/or share components to one another.
e.g:
Bundle A is a front-end web app that has a mysql backend
Bundle B is a back-end that does mysql backend things that needs to do those things with the Bundle A's mysql backend
Question is: shouldn't this just be one bundle, perhaps but this contrived example is to provide a point that if it isn't, can we share dependencies between two bundles.
Describe the solution you'd like
The ability to share dependencies between the bundles meaning that we can utilize a flag --weak-dependencies
to not install the second bundles dependency but make sure the dependency is installed. Whatever surface (layer) it needs to interact with that is the bundles expectation.
Should this be a mixin? Can a mixin handle this?
Describe alternatives you've considered
Looking at the PEP for Advanced Dependencies, that may be something we can do but is a longer term solution that can provide value but not specifically for this use case.
Additional context
Realizing that the advanced Dependencies PEP may resolve this, this community ask was a way to get around that implementation currently not built.
An issue I am having with the PEP is that I have a use-case that is only mentioned in passing but which I think could be relevant here. In essence the PEP mostly considers dependencies and sharing thereof as a concern at bundle creation time, whereas I would stress the need for it to be (also) an install-time concern.
Consider the scenario:
- I have three bundles,
A
,B
, andMySQL
that makes up my application. A
andB
are developed by different teams (i.e. I do not want a single bundle)A
andB
both need a database- My application is deployed in many instances for customers of very varying sizes
- For very small installations, I want
A
andB
to share a singleMySQL
instance - For larger installations,
A
andB
should have separateMySQL
instances
- For very small installations, I want
I do not see that it would be possible to model this at bundle creation time, except if I create different bundles e.g. A_small
, A_large
, which feels very wrong as the number of combinations will quickly explode.
But I said that the PEP "mostly considers", because there is this (emphasis mine):
When an installation is created to represent a dependency, the sharing mode and group should be copied from the bundle definition to the installation so that we can quickly query for suitable candidates without evaluating every bundle definition of every installation. The sharing mode can be edited by the user, to allow for "break glass" situations that may arise where the user needs to accomplish something we didn't anticipate.
So given this, could a step toward implementing the whole PEP be to start with this special case? That you can specify the sharing mode
/group
on the command-line instead of the bundle definition, e.g.:
porter install mybundle --sharing-mode group --sharing-group mygroup
If two bundles have the same group, the dependency is only created on first. For different groups, or if not specified the dependency is not shared.
Just a thought...
Going back to the Szyperski definition of components (independent unit of deployment, explicit interfaces, 3rd party composition), you may wonder if this use-case should solved with an extra '3rd party composition layer' that describes how bundle installations are linked (leveraging the interface they expose or consume). Bit similar to how docker-compose relates to docker. Such a composition manifest would reference the different bundles and could 'override' configurations, such as references to instance names. For @edespong use case, composition manifests could be created for the different types of customers. I can think of more (related) use-cases here: specific compositions for test or development environments, HA variants for production, etc. etc.
Well, @reuzel I could not agree more. What you are describing is very much the route we are currently heading down, with a slight modification. We are leveraging the custom
section in porter.yaml
to specify dependencies slighly differently that Porter's current approach. Then we have a separate manifest, the system definition, that does the referencing and the wiring. Finally, we are creating a program that can read, validate, and apply the system definition.
The reason why we need the custom section in the porter.yaml
is because in our case the bundle authors and the creator/maintainer of the system definition are not the same. It is up to the bundle authors to define the dependencies, but up to the system definition creator to wire them up.
Hey @edespong and @reuzel - thank you for all this amazing information. I'm currently working on implementing shared dependencies, and I would love to get more information on your use case/what you're doing with Porter/etc. If you ever have time, please feel very much encouraged to hop in our community call :)
Solved in #2940