-
Notifications
You must be signed in to change notification settings - Fork 488
[WIP] feat: add xblocks at runtime without rebuilding image #1257
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: release
Are you sure you want to change the base?
[WIP] feat: add xblocks at runtime without rebuilding image #1257
Conversation
This change introduces: 1) A persistent volume where Xblocks can be installed at runtime without the need to rebuild images. 2) A do command that actually installs the Xblock and its dependecies inside said volume. 3) Addition to the PYTHOPATH variable so the newelly installed Xblocks can be discovered.
This is interesting, as a first step, but we need to address a few issues before we actually start supporting this. Let me ask a few questions then offer my own answers:
I think my answers to questions 1-5 are sufficient. I'm stuck at 6, though. |
Would we be supporting Kubernetes and Django apps from the start or send patches later on? I can see that we should probably have a separate command group for xblocks which supports: Similarly for Django apps: A txbi (tutor xblock index) similar to what we have with tpi (tutor plugins index) so xblocks integrate nicely with tutor deck. |
@regisb I added the uninstall and list functions. I do need help understanding why we can't use volumes for k8s as well. What problem does a zip file in django storage solve? |
We can support just docker compose for now, but we need an approach that will work with Kubernetes in the future.
In general, it's very difficult to create volumes with write access that are accessible by multiple nodes in Kubernetes. Think: many different LMS/CMS containers which all need to access the same volume. This is why media storage is usually moved to S3 or MinIO in k8s. |
FYI this is what I have for installation of dependencies in a pip prefix that is then stored as a zip file in django storage:
|
I am facing the following issues with the current PR as it stands: On the first run, there is no I can attempt to create the file by running:
I fixed this by running: Then, my uwsgi processes are not restarting when I simply "touch" the file. I need to write content to it to trigger a reload. I had to update the PR as follows:
Still, I managed to get this to work. So let's keep it as it is for now and revisit after the demo. |
Cool!! |
Note that live dependencies have some limitations for now. We are not handling: migrations, translations or static assets. |
@regisb Can you see the mounted volume in the job runner container? I had the same problem but it went away when I updated the volumes for job runners.
This should go away the first time you touch the file, still I can look into it so its already present on the first run. |
Update: I've added a few new tutor commands |
61ea255
to
6ad39cd
Compare
6ad39cd
to
08ea6ad
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
- PR is still in draft
- The readme and/or documentation updates are missing. This is a new feature and we need to add proper documentation for community to follow
- Add if anything is intended for a followup PR (any k8s related pending action)
This version will work for both docker-compose and k8s (still requires additional k8s configs) but is now dependent on minio plugin. Having core depend on a plugin does not seem like the right way. Perhaps this should be a separate xblocks installer plugins that depends on minio. |
7ffa000
to
44f50d4
Compare
Let's continue this discussion internally. Having the core depend upon a plugin is not desirable. We can have a dedicated plugin to achieve this if we cannot find a way without minio. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There is a misunderstanding with how MinIO should be used. It is unnecessary to depend on MinIO, boto3 or s3. Tutor does not need to know about the storage backend. Instead, Tutor should use Django Storages for loading/saving the live dependencies.
It is then the role of the MinIO plugin (or whichever plugin we use for storage, such as s3) to configure Django Storages to use MinIO (or s3), as it currently done: https://github.com/overhangio/tutor-minio/blob/04c5f1149b51e12a33f10caab9428425a69aed7a/tutorminio/patches/openedx-common-settings#L1
tutor/templates/build/openedx/settings/download_packages_from_minio.py
Outdated
Show resolved
Hide resolved
36345c2
to
73272a7
Compare
73272a7
to
dd3eb35
Compare
Hello, everyone. I am new to this conversation and to Tutor development, so if I am missing something or this is not the right place, please let me know. I am currently working on a Tutor plugin to set up and configure development environments on top of Tutor's current development capabilities. At the moment, for development environments, we can work with a local repository of edx-platform using Tutor mounts, but, when working with xblocks or djangoapps, things change, and after a quick search, there are different ways to approach this. In my opinion, having live dependencies (or a way to install local Python packages with pip inside of a running container) only makes sense when working in development environments, just like with the openedx dev image, which has vim or ipdb only for dev environments. For end environments (local or production) using K8s, having live dependencies is, in my opinion, like changing a stateless deployment to an almost statefulset one, since the openedx deployment would now depend on an underlying volume to work, or at least to work in the desired manner. I believe that if we limited this to dev environments, we would only need to rely on the state of the Docker container to share the volumes where the xblocks and djangoapps are located and then run pip install inside the container as needed, since in other environments (local) it should not be possible to do so unless a new image was created with all the packages necessary for the application to work as expected. Looking forward to continue this conversation, thanks!. |
@Squirrel18 This is an anti pattern. I am not going to deny that. Here is our rational behind doing this:
We will allow this on all environments (dev/local/k8s) and it is going to be up to the user to decide where they want to use it. The classic way of installing dependencies will always be there though. |
Hi, @mlabeeb03 Thank you very much for the explanation and sharing the rationale behind. Just out of curiosity, I have two questions:
Thanks again! |
@Squirrel18 Yes, this will be moved to a separate plugin. This PR was opened in tutor core for higher visibility. Uploading: Job runner container downloads packages from pypy -> zip them -> upload to django storage (minio in this case). Where would devpi come into this? |
Hi, @mlabeeb03 You are correct, according to the PR description, the approach is to use PYTHOPATH to add live dependencies and I think avoid using pip to install or uninstall Python packages (inside openedx containers), so Devpi will not simplify the approach. I was thinking of using Devpi to centralise package management and storage (for public and private repositories), but since the goal is to avoid using pip, it doesn't make sense to use it. Thank you for taking the time to answer my questions and to provide more context about this. |
closes #1208
This PR is an enhancement meant to allow the ability to install python packages at runtime without the need to rebuild images as explained in #1208.
This requires minio to work. We are not using mounted volumes because those would not work with k8s.
This change introduces:
In order to use this you should build the openedx docker image and add packages name to the
LIVE_DEPENDENCIES
config variable:tutor config save --append LIVE_DEPENDENCIES="ai-coach-xblock"
And then run the do command:
tutor local do build-live-dependencies
Your lms and cms containers would automatically detect the change after 10 seconds and you would be able to access these packages/xblocks in studio and lms.