Closed kdmccormick closed 1 year ago
@arbrandes or @ghassanmas , would either of you have time to take a look?
Kyle, would it be acceptable if we just amended the docs to say that developers must build the dev image themselves with tutor images build library-authoring-dev
?
other way to resolve would be in this patch https://github.com/overhangio/tutor-mfe/blob/master/tutormfe/patches/local-docker-compose-dev-services instead of iterating on all MFE_APP
suffix we only iterate on the one that we officially support i.e. have an image built for them. OR we could add if clause at the image
part and only write if it in the official repos. I am just putting another opinion on the table I haven't tested consequence of this approahce if exits
@regisb tutor images build library-authoring-dev
does not work because that image is not added to IMAGES_BUILD
; it's only defined in dev/docker-compose.yml, just like the openedx-dev
. I tried building it using dev dc
, but that docker-compose doesn't like that either:
$ tutor dev dc build library-authoring
docker-compose -f /home/kyle/openedx/tutor-root/env/local/docker-compose.yml -f /home/kyle/openedx/tutor-root/env/dev/docker-compose.yml -f /home/kyle/openedx/tutor-root/env/dev/docker-compose.tmp.yml --project-name tutor_nightly_dev build library-authoring
library-authoring uses an image, skipping
For the record, I like @ghassanmas's idea. The *_MFE_APP
iteration coupled with the assumption that the image exists results in surprising behavior, which I think we should avoid. We should instead only iterate on a list composed of specific MFEs.
Relatedly, @kdmccormick, FYI @brian-smith-tcril is working on improvements to that plugin, which you may want to look at.
instead of iterating on all MFE_APP suffix we only iterate on the one that we officially support
This would mean that we no longer support adding MFE apps via the "*_MFE_APP" config, right? I agree that this extension mechanism is a little clunky. It could certainly be improved thanks to the plugin v1 API, which did not exist at the time we created tutor-mfe.
With @ghassanmas' suggestion we would no longer have issues starting the custom MFEs in development mode, but we would also lose the possibility of running custom MFEs in a development environment. So we need to find a better solution.
tutor images build library-authoring-dev does not work because that image is not added to IMAGES_BUILD
Right. But if it did work, would it be an acceptable solution @kdmccormick? Or would we need something more transparent, like auto-build on start?
I think there are two issues here:
*_MFE_APP
app system is a little janky. Funnily enough, it reminds me of a Filter: it's a global list of things you can iterate over and that plugins can extend. Given that, it seems like we should modernize it by turning it into a proper filter.I think we can solve these both, but I want to consider the solutions separately:
We add a new field to the *_MFE_APP
dictionaries: "dev_image_url"
. When that is set to a remote URL, such as {{ DOCKER_REGISTRY }}overhangio/openedx/authn-dev
, then the dev image will be pulled. When it let unset, the image will be built locally. That way, custom MFEs can be added, and if their "dev_image_url"
is not set, then the dev image will be built locally just like before.
Implementing this would mean adding some additional conditional logic to the dev/docker-compose.yml template.
We create a new Filter, call it MFE_APPS
, which yields a of dictionary like:
{
"authn": {
# These are the same values that are in *_MFE_APP today.
"repository": "https://github.com/openedx/frontend-app-authn",
"port": 1999,
"version": "open-release/nutmeg.2", # Optional. Defaults to {{ MFE_COMMON_VERSION }}.
# This is the new dev_image_url proposal.
# Optional. Defaults to None, in which case it's always built instead of pulled.
"dev_image_url": "{{ DOCKER_REGISTRY }}overhangio/openedx/authn-dev",
},
"account": {
"repository": ...,
"port": ...,
},
"profile": {
...,
},
...,
}
User plugins could add or modify MFEs like such:
# (aside: This would be our first instance of having a plugin-defined hook.
# Here, I suggest a convention: plugins can define custom Actions
# and Filters catalog classes under <pluginpackage>/hooks.py)
# an define their own Actions and Filters catalogs under <package>/hooks.py)
from tutormfe.hooks import Filters as MfeFilters
MfeFilters.MFE_APPS.add()
def _add_cool_new_mfe(mfe_apps: dict) -> dict:
mfe_apps["coolnew"] = {
"repository": "https://github.com/arbrandes/frontend-app-cool-new-feature",
"port": 2023,
}
MfeFilters.MFE_APPS.add()
def _use_custom_profile_version(mfe_apps: dict) -> dict:
mfe_apps["profile"]["repository"] = "https://github.com/arbrandes/frontend-app-profile"
mfe_apps["profile"]["version"] = "arbrandes/profile-rework"
Inside tutor-mfe, the MFE_APPS
filter would be used where the *_MFE_APPS
settings are used right now. We would deprecate *_MFE_APPS
, although we could add a backwards-compatibility shim for the next release or two.
One consideration with this proposal is that users could no longer add or modify MFEs just with tutor config
; they'd need to create a plugin for any change. Given that we now require a plugin just to change MFE app settings, though, I think this change is in line with our current direction.
tutor images build library-authoring-dev does not work because that image is not added to IMAGES_BUILD
Right. But if it did work, would it be an acceptable solution @kdmccormick? Or would we need something more transparent, like auto-build on start?
@regisb , I think it would be acceptable if forgetting to build led you to a helpful error message. Something like "image does not exist" seems OK to me, but "pull access denied" does not. Auto-build on start would be even better.
@kdmccormick re: proposed solution 2 above:
In this scenario, would custom MFEs (or tutor plugins used to install the custom MFEs) include the code to _add_cool_new_mfe
?
@brian-smith-tcril Yes.
I vote for @kdmccormick's "Bigger Proposal". It reads very much in line with the rest of the landscape.
Yes, Kyle's "bigger proposal©" is great.
A couple of notes:
Filters.IMAGES_PULL
. If not present, then build at runtime. Actually, now that I think of it, we can implement this change right now to auto-build dev images without introducing any breaking change.Filter.add_item
.tutormfe.hooks
API.Not a fan of "dev_image_url": this introduces yet another Docker image setting. Instead, we can simply check for the presence of "mymfe-dev" in Filters.IMAGES_PULL. If not present, then build at runtime. Actually, now that I think of it, we can implement this change right now to auto-build dev images without introducing any breaking change.
💯
I'm not 100% sure about this one yet, but I feel like MFE_APPS should be a list, not a dict, because order might be important. Also, lists play better with Filter.add_item.
@regisb Yeah, I went back and forth on this one. I chose the dict because it lends itself well to partially or fully overriding parameters for an MFE, like:
MfeFilters.MFE_APPS.add()
def _use_custom_profile_version(mfe_apps: dict) -> dict:
mfe_apps["profile"]["repository"] = "https://github.com/arbrandes/frontend-app-profile"
mfe_apps["profile"]["version"] = "arbrandes/profile-rework"
return mfe_apps
How would you see that working with a list? Perhaps: if multiple MFE_APPS entries exist with the same name, use the last one?
if multiple MFE_APPS entries exist with the same name, use the last one?
~I don't think I would treat that as a special case. docker-compose will crash on discovering multiple services with the same name, and I'm fine with that. Else, just raise a TutorError.~
EDIT: no, this is not a good idea. See below.
@regisb If we go with that, then changing the repository or branch for an MFE would require something like this:
MfeFilters.MFE_APPS.add()
def _use_custom_profile_version(mfe_apps: list[dict]) -> list[dict]:
for mfe_app in mfe_apps:
if mfe_app["name"] == "profile":
mfe_app["repository"] = "https://github.com/arbrandes/frontend-app-profile"
mfe_app["version"] = "arbrandes/profile-rework"
return mfe_apps
Do you all like that? Personally, I feel like this is too much code for such a common task. Perhaps I'm overestimating how often users will want to override an MFE's repo & branch.
Do you all like that? Personally, I feel like this is too much code for such a common task.
I agree, it's too much. You're right, I think we should go with a dict and your initial proposal.
Hello everyone, I was just going through the same issue that is I was unable to start tutor dev start
when added my custom_mfe
. Got this error.
Error response from daemon: pull access denied for overhangio/openedx-custom_mfe-dev, repository does not exist or may require 'docker login': denied: requested access to the resource is denied
Also, I was unable to build the custom-mfe image for dev environment using tutor images build custom_mfe-dev
. [getting no image of this name exist]
The reason I found is that in tutor-mfe/plugin.py
there is a tuple named ALL_MFES
which is used to build images for dev
environment. I have added my custom_mfe
in that tuple and then tutor images build custom_mfe-dev
worked perfectly.
I propose the below solution to that.
Add custom_mfe name as a list in tutor config variable like [example: tutor config save --set CUSTOM_MFES="['mfe1', 'mfe2']"]. and then pick its value in tutor-mfe
and add to the ALL_MFES
variable.
Looking forward for your thoughts.
@Hina-softwareEngineer, I think we're going to go with @kdmccormick initial proposal. It achieves the same results as yours, but with plugins instead of configuration variables. (Which, at this point, we prefer.)
The only thing is that currently nobody is working on an implementation.
Working on this for Palm.
Hey @kdmccormick, @arbrandes, I'm really pleased with how this fix turned out. Please have a look at the upcoming changes for Palm, and in particular the README: https://github.com/overhangio/tutor-mfe/commit/9e9f94df7c58562e8480c36e85e5ca3831052c7f#diff-7b3ed02bc73dc06b7db906cf97aa91dec2b2eb21f2d92bc5caa761df5bbc168f
The workflow is short and sweet, I think:
tutor config save --append MOUNTS=/path/to/frontend-app-profile
tutor dev launch # tutor local launch works as well
Eager to discuss this with you. I'll present this during the next DevEx meetup on Monday.
I tested the changes, and I approve whole-heartedly!
The README describes how to add extra MFEs to the plugin. I've used this method successfully in the past.
I'm trying to run the tutor-contrib-library-authoring-mfe plugin, which uses that same method in order to add frontend-app-library-authoring. I ran the following:
This all worked fine. However when I try to start the MFE:
I get:
It looks like Tutor is trying to pull the non-existent
docker.io/overhangio/openedx-library-authoring-dev
image. I think it should try to instead build that image, since we wouldn't expect it to exist in the overhangio DockerHub repo.Looking at
$(tutor config printroot)/env/dev/docker-compose.yml
, I see:I suspect this is related the the MFE runtime config change, because up until that change, all MFE images were build locally; none of them were pulled down from DockerHub.
tutor version: 15.2.0-nightly tutor-mfe version: 15.0.5 nightly