-
Notifications
You must be signed in to change notification settings - Fork 0
Improve workflow for platform plugin development #77
Comments
👀 |
On this duplicate issue Régis had said
It sounds like the first uncached step might be |
I think the first link the issue description should be: https://docs.tutor.overhang.io/configuration.html?highlight=private%20txt#installing-extra-xblocks-and-requirements |
What's happening:
My recommened solution: We should recommend a different method for toggling private requirements during development. For example, creating a small Tutor plugin that modifies the from tutor import hooks
hooks.Filters.ENV_PATCHES.add_item((
"openedx-dev-dockerfile-post-python-requirements",
"RUN pip install -e /path/to/my/python/lib -e ../path/to/another",
)) |
Wait, that ^ on its own will not work because your local Python lib needs to exist in the build context ( |
I spent a bit of time this week debugging issues I've been having trying to do local development with edx-platform plugins. I've narrowed down my problem to when private.txt gets pip installed during the docker build. Basically you can run into later steps overriding your intended requirements changes or conflicts if the library is already in edx-platform requirements. (development.txt for example) Different issue, but it seems directly related to the potential solution here. LMK if I should open something separate for this. |
@zacharis278 just confirming my understanding: if you're using private.txt to install local platform plugins, have you been putting those plugin repos at Would a potential solution to all these problems be to
If this seems like a good workflow, we could also use the recent work on mounting & tasks to shorten it to:
|
@kdmccormick yeah I've been using that config folder which is certainly a pain point. Installing these requirements after the image has been built sounds like a way better workflow. I'll play around with this and see if I have any other feedback. Maybe we can work it into the persistent mounting solution. I guess the only potential negative point here is adding 'more ways to do the same thing' since I assume this wouldn't necessarily replace the tutor config w/ private.txt way of doing this. |
This is true. I think it's OK, though, because the two methods have different strengths:
If this ends up working well for you, then I'd like to update the docs to explain when to use which method. |
Just wanted to clarify a point, in case it wasn't already clear: the reason why private requirements are installed before static assets are compiled/collected is because these extra dependencies may in some cases include static assets. In development we might (?) be able to bypass this step, because the static asset pipeline works differently than in production, but I'm not too sure about it. |
@regisb That clarification does indeed help. I guess, I see two ways forward:
Of course, we could do both, but I'd still want to choose one of them to be the officially recommended development workflow and have the other be more of a footnote / advanced user workflow. |
@regisb Let me know if you have an opinion here. This is currently my top priority because almost every dev team at 2U will need this workflow. |
For what it's worth: I'm interested in (1) because we recently put a lot of work into the mounting interface, but at the same time, it requires the user to understand virtual environment mounting, and I am unsure whether that would be too much mental overhead for the average plugin developer. If we were able to make (2) work reliably and quickly, then it might be simpler from the end user's point of view. |
There is one other option I'm excited about and hacking on currently:
To the end-user, this would manifest as: Every time I'm not 100% sure this will all work, so I'm going to prototype it and see how it goes. |
@kdmccormick I'm very sorry for my late reply, this flew under my radar...
In theory that would be the best solution, yes. But in practice I'm not sure what's the best way to make this work? AFAIU there will be many commands involved, right? The approach would be simpler for dependencies that are already installed in the openedx-dev container, but more tricky for newer dependencies.
I have a feeling this would require extensive, non-trivial changes in order to work properly...
Would that work? Unless I'm mistaken, the
I'm not a big fan, to be honest. To get this to work consistently (e.g: in
😨
😨 😨 😨 This is getting really complex! I'm not even sure I understand this myself. I'm sorry that I am not being very constructive... I understand that the current solution for hacking on edx-platform requirements is suboptimal, but I don't have a better idea... |
Thanks for your feedback Régis. I found that I was having trouble reasoning & talking about all this without actually trying it, so I started on a prototype in the form of a plugin which I hope to share soon. Spoiler alert: it uses ENTRYPOINT, which I understand you don't like... but at least this will give us a chance to discuss specifically why you don't like ENTRYPOINT and then look for a different solution. |
Allow to suggest something that might or might be relevant: What about utilizing
I haven't tested this on tutor, it was just something I learned about when I was dealing with discourse docker/boostrap scripts, so the moment I learnt about it, I was wondering if that can be useful in tutor when minor changes are needed to the image. Footnotes |
The newer image will be overwritten the next time we run |
The latest thing I am trying, with promising results, is using named volumes (not bind-mounted volumes) for the virtualenv and node_modules when in development mode. With those volumes set up, running this:
installs requirements for all cms*/lms* containers, and the changes persist between restart (obviously). The performance is good--in fact, I think |
A cool thing I learned while prototyping this is the
That is, if we have this in the
then when someone runs |
Yes, I was just thinking what if for same example I suggested above we would add the relevant command to Dockerfile-patch https://github.com/overhangio/tutor/blob/7453e70fa08943652f72bb7956872ce44e2b1bdf/tutor/templates/build/openedx/Dockerfile#L263
And then we could have tutor private file plugin, where we write to it whenever that specific cli is triggered.
This still sound complicated though, and it assume the command will always be computable to run in the end.
|
OK, I think I figured out how to get The key is to mount everything we need (that is: requirements, static assets, and the egg-info file) using named volumes. Shockingly, these named volumes work and play nicely with a bind-mounted edx-platform, even though most of them are assigned to subdirectories of edx-platform itself:
That's right: you can have a container, with /openedx/edx-platform bind-mounted to a host directory, and /openedx/edx-platform/node_modules mounted to a shared named volume, and it all seems to just work (TM). This already makes the platform plugin development story better, because it means you can mount packages and install them into a container once, and the installation will persist across all lms & cms containers. No image rebuild or any wonky virtual environment bind-mounting necessary. (I'm still looking for ways to make it automatic; i.e., you mount an edx-platform package, and it automatically gets installed). Sorry if this doesn't make sense @regisb ; I'm polishing up a plugin now that I hope will illustrate everything by example. Do let me know if what I wrote raises any red flags for you, though. |
Do you need to declare the named volumes in docker-compose.dev.yml?
There is one thing that worries me: it's that we end up with a stateful installation of Open edX. What I mean by that is that the state of the Open edX platform will depend on the user's past actions. This breaks the contract of Tutor to make everything explicit as much as possible. This by itself does not mean that I am against it. I'm curious to see the implementation details because there are a few things about named volumes that elude me. |
Yes.
Noted! |
Alright, as promised, here is the plugin: https://github.com/kdmccormick/tutor-contrib-kdmccormick/blob/master/quickdev.rst I need to test that it works under macOS. Once I do that successfully, I'll open a TEP proposing to merge the contents of the plugin into core Tutor. |
Everything works good on macOS. Here's the TEP for incorporating the plugin upstream: https://discuss.openedx.org/t/tutor-enhancement-proposal-tep-for-a-quicker-development-workflow/8595 Marking this as "In Review". |
Closing this in favor #144, where we'll continue the work. |
Following https://github.com/overhangio/2u-tutor-adoption/issues requires running
tutor images build openedx
every time private.txt is changed. This is a pretty major slowdown when one may be working on different combinations of platform plugins in rapid succession.The slowest step seems to be the calls to
openedx-assets
, which reruns every time I build. My knowledge of Docker is pretty shaky so I don't understand why this bit isn't cached.The text was updated successfully, but these errors were encountered: