-
Notifications
You must be signed in to change notification settings - Fork 3.9k
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
docs: Settings Simplification ADR #36224
base: master
Are you sure you want to change the base?
Conversation
ba09230
to
57f550a
Compare
@feanil , could you take a first pass? Once it looks good to you, I'll circulate it more broadly. |
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.
A few minor comments but nothing major. I can re-review once those are addressed.
@regisb , your wisdom on this ADR would be invaluable. |
57f550a
to
c8e03af
Compare
Sorry @feanil , forgot to push. Ready now. |
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.
Looks good to me now.
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.
Reading this ADR, I found myself nodding and mumbling "yes, yes, ok..." all the way down. I used to tell people that there are just two things which are difficult in Open edX: static assets and settings. I'm grateful that you are tackling the latter after having greatly improved the state of the former.
My comments are mostly questions for my own understanding. As far as I'm concerned this is good to go.
(Tutor). Specifically, production edx-platform configuration currently works | ||
like this: | ||
|
||
* ``lms/envs/tutor/production.py``... |
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.
This looks accurate, but it's slightly depressing to read how complex it is...
setting, the preferred way to do so is to "make a Tutor plugin". This is a | ||
large amount of prior knowledge, boilerplate, and indirection, all required | ||
to simply do something which Django provides out-of-the-box via a custom | ||
``DJANGO_SETTINGS_MODULE``. |
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.
Again: depressing but true. As Tutor maintainers, we could certainly do a better job at explaining how to create such plugins: either via better documentation or plugin cookiecutters. But that's beyond the scope of this ADR.
|
||
* ``openedx/envs/common.py``: Defaults shared between LMS and CMS (new!). | ||
|
||
* ``lms/envs/common.py``: LMS default settings. Wherever possible, |
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.
Just to clarify:
- we don't need a production.py settings file because common.py will be (mostly) production-ready, right?
- and manage.py will default to loading common.py, right?
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.
Yes and yes. I will clarify both.
(lms,cms)/envs/production.py unchanged through this process. | ||
|
||
* Develop (cms,lms)/envs/development based off of (cms,lms)/envs/common.py. | ||
Iterate until we can run "bare metal" development server for LMS and CMS |
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.
Oh wow I'm really looking forward to that!
(cms,lms)/envs/common.py into openedx/envs/common.py. This may be iteratively | ||
done across multiple PRs. | ||
|
||
* BREAKING (major, just common.py): Find the best production-ready defaults |
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.
Is this really going to be a breaking change if production.py remains unchanged in the process? In other words: do we consider that changes to common.py are breaking changes?
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.
Well, since we don't have a well-defined edx-platform API contract, any non-additive change to any python object that isn't underscore-prefixed or literally called "internal" could be considered "breaking" 🥲.
But that's a rant for another day. Practically speaking, changes to common.py probably won't break anyone. So, I'll mark the common.py commits as feat!
, but we won't be wringing our hands or issuing DEPR tickets until we're trying to change/remove production.py.
* BREAKING (major): Deprecate and remove (cms,lms)/envs/devstack.py. | ||
Tools (like Tutor and 2U's devstack) will either need to maintain local | ||
copies of these modules, or "rebase" themselves onto | ||
(lms,cms)/envs/development.py. |
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.
👍
Decision | ||
******** | ||
|
||
This is our target edx-platform settings module structure: |
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.
This is a greatly simplified structure, and I'm all in favor of it. But I expect that it's going to create issues for some settings that derive from others.
To clarify, I'm talking about the following scenario:
- common.py defines
SETTING_BASE = ...
andDERIVED_SETTING1 = foobar1(SETTING_BASE)
andDERIVED_SETTING2 = foobar2(SETTING_BASE)
. - production.py modifies
SETTING_BASE
.DERIVED_SETTING1
andDERIVED_SETTING2
need to be re-defined.
This is for instance what currently happens with STATIC_ROOT_BASE
, from which STATIC_ROOT
, WEBPACK_LOADER
are derived.
How do you expect we are going to resolve these cases? I see 3 possible approaches:
- Be dumb about it and duplicate settings in common.py and production.py.
- Somehow preserve the existing
derive_settings
mechanism. (by the way, are we going to keep it around?) - Refactor settings such that we don't have to duplicate settings.
Approach 3 would probably be the "right" one, but I expect we'll have to make this decision on a case-by-case basis.
(I'm sure you've thought about this but I don't see it reflected in this ADR. Or is it part of the "Remove redundant overrides" paragraph below?)
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.
Great question, silly of me to omit that from the ADR.
Having looked through the modules with @feanil a lot lately, we feel that (1) would add lot more work for operators and (3) is just an infeasibly large amount of work and breaking changes. I don't love having bespoke tooling, but if we have to keep some bespokeness around, I think that derived_settings is pretty tame and well-defined. So I propose (2). Specifically, the three common.py files would have a lot of derived defaults. Lmk what you think.
Relatedly, in preparation for this, I have already made the derived_settings API a bit easier to work with: #36192
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.
I'm OK with some bespoke tooling. Like I said, I expect that we might be able to use approach 3 for some settings. If anything, derive_setting
will help us identify settings that should be simplified, and we can take on those further down the road.
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.
I expect that we might be able to use approach 3 for some settings. If anything, derive_setting will help us identify settings that should be simplified, and we can take on those further down the road.
I agree. The dependencies between different settings will become much clearer and easy-to-untangle once we have converted all the production.py-special-cases into explicit common.py Derived
settings.
derived from ``lms/envs/common.py``, and point their | ||
``DJANGO_SETTINGS_MODULE`` environment variable at this module. | ||
|
||
* ``lms/envs/yaml.py``: (Possibly) An alternative to third-party |
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.
For the record, I expect that Tutor will not be using this module at all.
c8e03af
to
7883fc4
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.
Thank you.
|
||
OEP-45 declares that sites will configure each IDA's (indepently-deployable | ||
application's) Django settings with an ``<APPNAME>_CFG`` yaml file, parsed and | ||
loaded by a single upstream-provided ``DJANGO_SETTINGS_MODULE``. this contrasts |
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.
loaded by a single upstream-provided ``DJANGO_SETTINGS_MODULE``. this contrasts | |
loaded by a single upstream-provided ``DJANGO_SETTINGS_MODULE``. This contrasts |
application's) Django settings with an ``<APPNAME>_CFG`` yaml file, parsed and | ||
loaded by a single upstream-provided ``DJANGO_SETTINGS_MODULE``. this contrasts | ||
with the django convention, which is that sites override Django settings using | ||
a their own ``DJANGO_SETTINGS_MODULE``. The rationale is that all Open edX |
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.
Fixed typo and tried to make it clear that this is rationale that you are going to change...
a their own ``DJANGO_SETTINGS_MODULE``. The rationale is that all Open edX | |
their own ``DJANGO_SETTINGS_MODULE``. The rationale was that all Open edX |
loaded by a single upstream-provided ``DJANGO_SETTINGS_MODULE``. this contrasts | ||
with the django convention, which is that sites override Django settings using | ||
a their own ``DJANGO_SETTINGS_MODULE``. The rationale is that all Open edX | ||
customization can be reasonably specified in YAML; therefore, it is |
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.
customization can be reasonably specified in YAML; therefore, it is | |
setting customization can be reasonably specified in YAML; therefore, it is |
successfully uses only YAML files for configuration. Furthermore, | ||
upstream-provided ``DJANGO_SETTINGS_MODULE`` which loads these yaml files |
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.
successfully uses only YAML files for configuration. Furthermore, | |
upstream-provided ``DJANGO_SETTINGS_MODULE`` which loads these yaml files | |
successfully uses only YAML files for configuration. Furthermore, the | |
upstream-provided ``DJANGO_SETTINGS_MODULE`` which loads these yaml files |
|
||
* and uses templates vars from Tutor configuration (``config.yml``), | ||
|
||
* and invokes hooks from any enable Tutor plugins; |
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.
* and invokes hooks from any enable Tutor plugins; | |
* and invokes hooks from any enabled Tutor plugins; |
* BREAKING (major, just common.py): Find the best production-ready defaults | ||
between both (lms,cms)/envs/production.py and Tutor's production.pys, and | ||
"bubble" them up to (openedx,cms,lms)/common.py. Keep | ||
(lms,cms)/envs/production.py unchanged through this process. |
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.
If the production.oy files remain unchanged, can you better explain the breaking change aspect of this, and what we expect to break or not break? Also, maybe note the action to be taken to workaround the breaking change, if applicable?
Iterate until we can run "bare metal" development server for LMS and CMS | ||
using these settings. | ||
|
||
* BREAKING (major): Deprecate and remove (cms,lms)/envs/devstack.py. |
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.
[inform] I think 2U already handled this as part of the DEPR work for devstack. So for 2U, I think it will just be a question of when and if we can take advantage of dev.py.
One alternative settings structure | ||
---------------------------------- | ||
|
||
Here is an alternate structure would de-dupe any shared LMS/CMS dev & test |
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.
Here is an alternate structure would de-dupe any shared LMS/CMS dev & test | |
Here is an alternate structure that would de-dupe any shared LMS/CMS dev & test |
Here is an alternate structure would de-dupe any shared LMS/CMS dev & test | ||
logic by creating more shared modules within openedx/envs folder. Although | ||
DRYer, this structure would increase the total number of edx-platform files and | ||
potentially encourage more LMS-CMS coupling. So, will not pursue this |
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.
potentially encourage more LMS-CMS coupling. So, will not pursue this | |
potentially encourage more LMS-CMS coupling. So, we will not pursue this |
the distressing level of complexity that developers and operators face when | ||
working with the platform. | ||
|
||
Decision |
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.
Consider adding a sentence or two in this Decision section about the decision to adjust OEP-45 in a separate effort to better align with the decisions noted in this ADR. You can also reference the Consequences section for more details.
https://github.com/kdmccormick/edx-platform/blob/kdmccormick/settings-adr/docs/decisions/0022-settings-simplification.rst