From b24cb48eb0b8051a58820676def0f8508d3f218d Mon Sep 17 00:00:00 2001 From: Kyle McCormick Date: Thu, 3 Sep 2020 11:47:08 -0400 Subject: [PATCH] Decentralized Devstack changes: Add and push Dockerfile; add decentralized devstack settings (#24666) * Add and push Dockerfile; add decentralized devstack settings Co-Authored-By: Diana Huang Co-Authored-By: Kyle McCormick * Remove Python requirements hack Remove the attempted optimization to the installation of Python package dependencies. The dependencies in edx-platform change about three times per day, so this was of dubious value. And because npm is run through nodeenv, which is a Python package, the Python dependencies installation has to happen first. * ARCHBOM-1439: Changing workdir to /edx/app/edxapp/edx-platform (#24835) Context: The Dockerfile tries to stay in sych with legacy stuff. In the ansible we configure the directory structure such that things relating to the app but not in the codebase, such as the env file wind up in /edx/app/edxapp/. And the codebase winds up in /edx/app/edxapp/edx-platform. I think due to accident, the dockerfile does /edx/app/edx-platform/edx-platform instead of /edx/app/edxapp/edx-platform. This commit tries to have Dockerfile more reflect what is currently happening in production * Update ports for decentralized devstack ARCHBOM-1447 (#24841) Switch from the LMS ports we've historically used for NGINX to those used for gunicorn, and fix the Studio ports to match the ones we've historically used for its gunicorn service. Also removed some leftover bits of the requirements hack. Co-authored-by: Adam Blackwell Co-authored-by: Diana Huang Co-authored-by: jinder1s Co-authored-by: Jeremy Bowman Co-authored-by: Manjinder Singh <49171515+jinder1s@users.noreply.github.com> --- .dockerignore | 153 ++++---- Dockerfile | 89 +++-- Makefile | 4 + cms/devstack.yml | 496 ++++++++++++++++++++++++ cms/docker_cms_gunicorn.py | 2 - cms/envs/devstack_decentralized.py | 185 +++++++++ lms/devstack.yml | 601 +++++++++++++++++++++++++++++ lms/docker_lms_gunicorn.py | 2 - lms/envs/devstack_decentralized.py | 379 ++++++++++++++++++ 9 files changed, 1802 insertions(+), 109 deletions(-) create mode 100644 cms/devstack.yml create mode 100644 cms/envs/devstack_decentralized.py create mode 100644 lms/devstack.yml create mode 100644 lms/envs/devstack_decentralized.py diff --git a/.dockerignore b/.dockerignore index 6804bcfcb2..496a05a3ac 100644 --- a/.dockerignore +++ b/.dockerignore @@ -5,7 +5,6 @@ /test_root/ .git -Dockerfile ### Files private to developers @@ -20,98 +19,96 @@ cms/envs/private.py # end-noclean ### Python artifacts -*.pyc +**/*.pyc ### Editor and IDE artifacts -*~ -*.swp -*.orig -/nbproject -.idea/ -.redcar/ -codekit-config.json -.pycharm_helpers/ -/_mac/* -/IntelliLang.xml -/conda_packages.xml -/databaseSettings.xml -/diff.xml -/debugger.xml -/editor.xml -/ide.general.xml -/inspection/Default.xml -/other.xml -/packages.xml -/web-browsers.xml +**/*~ +**/*.swp +**/*.orig +**/nbproject +**/.idea/ +**/.redcar/ +**/codekit-config.json +**/.pycharm_helpers/ +**/_mac/* +**/IntelliLang.xml +**/conda_packages.xml +**/databaseSettings.xml +**/diff.xml +**/debugger.xml +**/editor.xml +**/ide.general.xml +**/inspection/Default.xml +**/other.xml +**/packages.xml +**/web-browsers.xml ### NFS artifacts -.nfs* +**/.nfs* ### OS X artifacts -*.DS_Store -.AppleDouble -:2e_* -:2e# +**/*.DS_Store +**/.AppleDouble +**/:2e_* +**/:2e# ### Internationalization artifacts -*.mo -*.po -*.prob -*.dup -!django.po -!django.mo -!djangojs.po -!djangojs.mo +**/*.mo +**/*.po +**/*.prob +**/*.dup +!**/django.po +!**/django.mo +!**/djangojs.po +!**/djangojs.mo conf/locale/en/LC_MESSAGES/*.mo conf/locale/fake*/LC_MESSAGES/*.po conf/locale/fake*/LC_MESSAGES/*.mo -# this was a mistake in i18n_tools, now fixed. -conf/locale/messages.mo ### Testing artifacts -.testids/ -.noseids -nosetests.xml -.cache/ -.coverage -.coverage.* -coverage.xml -cover/ -cover_html/ -reports/ -jscover.log -jscover.log.* -.pytest_cache/ -pytest_task*.txt -.tddium* +**/.testids/ +**/.noseids +**/nosetests.xml +**/.cache/ +**/.coverage +**/.coverage.* +**/coverage.xml +**/cover/ +**/cover_html/ +**/reports/ +**/jscover.log +**/jscover.log.* +**/.pytest_cache/ +**/pytest_task*.txt +**/.tddium* common/test/data/test_unicode/static/ test_root/courses/ test_root/data/test_bare.git/ test_root/export_course_repos/ test_root/paver_logs/ test_root/uploads/ -django-pyfs -.tox/ +**/django-pyfs +**/.tox/ common/test/db_cache/bok_choy_*.yaml common/test/data/badges/*.png ### Installation artifacts -*.egg-info -.pip_download_cache/ -.prereqs_cache -.vagrant/ -node_modules -bin/ +**/*.egg-info +**/.pip_download_cache/ +**/.prereqs_cache +**/.vagrant/ +**/node_modules +**/bin/ ### Static assets pipeline artifacts -*.scssc +**/*.scssc lms/static/css/ lms/static/certificates/css/ cms/static/css/ common/static/common/js/vendor/ common/static/common/css/vendor/ common/static/bundles -webpack-stats.json +**/webpack-stats.json ### Styling generated from templates lms/static/sass/*.css @@ -125,30 +122,30 @@ cms/static/themed_sass/ themes/**/css ### Logging artifacts -log/ -logs -chromedriver.log -ghostdriver.log +**/log/ +**/logs +**/chromedriver.log +**/ghostdriver.log ### Celery artifacts ### -celerybeat-schedule +**/celerybeat-schedule ### Unknown artifacts -database.sqlite -courseware/static/js/mathjax/* -flushdb.sh -build +**/database.sqlite +**/courseware/static/js/mathjax/* +**/flushdb.sh +**/build /src/ \#*\# -.env/ +**/.env/ openedx/core/djangoapps/django_comment_common/comment_client/python -autodeploy.properties -.ws_migrations_complete -dist -*.bak +**/autodeploy.properties +**/.ws_migrations_complete +**/dist +**/*.bak # Visual Studio Code -.vscode +**/.vscode # Locally generated PII reports -pii_report \ No newline at end of file +**/pii_report diff --git a/Dockerfile b/Dockerfile index 850e70ae89..b0057cbdb1 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,9 +1,11 @@ FROM ubuntu:xenial as base +# Warning: This file is experimental. + # Install system requirements -RUN apt update && \ +RUN apt-get update && \ # Global requirements - DEBIAN_FRONTEND=noninteractive apt install -y \ + DEBIAN_FRONTEND=noninteractive apt-get install --yes \ build-essential \ curl \ # If we don't need gcc, we should remove it. @@ -40,7 +42,7 @@ RUN apt update && \ python3-dev \ python3-pip \ python3.5 \ - -qy && rm -rf /var/lib/apt/lists/* + && rm -rf /var/lib/apt/lists/* RUN locale-gen en_US.UTF-8 ENV LANG en_US.UTF-8 @@ -50,42 +52,75 @@ ENV LC_ALL en_US.UTF-8 RUN ln -s /usr/bin/pip3 /usr/bin/pip RUN ln -s /usr/bin/python3 /usr/bin/python -WORKDIR /edx/app/edx-platform/edx-platform +WORKDIR /edx/app/edxapp/edx-platform -COPY . /edx/app/edx-platform/edx-platform - -ENV PATH /edx/app/edx-platform/nodeenv/bin:${PATH} +ENV PATH /edx/app/edxapp/nodeenv/bin:${PATH} ENV PATH ./node_modules/.bin:${PATH} -ENV PATH /edx/app/edx-platform/edx-platform/bin:${PATH} +ENV CONFIG_ROOT /edx/etc/ +ENV PATH /edx/app/edxapp/edx-platform/bin:${PATH} ENV SETTINGS production - -# TODO: Install requirements before copying in code. -RUN pip install setuptools==39.0.1 pip==9.0.3 -RUN pip install -r requirements/edx/base.txt - -RUN nodeenv /edx/app/edx-platform/nodeenv --node=8.9.3 --prebuilt - -RUN npm set progress=false \ - && npm install - RUN mkdir -p /edx/etc/ -EXPOSE 18000 +# Install Python requirements +RUN pip install pip==20.0.2 +COPY setup.py setup.py +COPY common common +COPY openedx openedx +COPY lms lms +COPY cms cms +COPY requirements/edx/base.txt requirements/edx/base.txt +RUN pip install -r requirements/edx/base.txt + +# Copy just JS requirements and install them. +COPY package.json package.json +COPY package-lock.json package-lock.json +RUN nodeenv /edx/app/edxapp/nodeenv --node=12.11.1 --prebuilt +RUN npm set progress=false && npm install + +ENV LMS_CFG /edx/etc/lms.yml +ENV STUDIO_CFG /edx/etc/studio.yml +COPY lms/devstack.yml /edx/etc/lms.yml +COPY cms/devstack.yml /edx/etc/studio.yml + +# Copy over remaining code. +# We do this as late as possible so that small changes to the repo don't bust +# the requirements cache. +COPY . . FROM base as lms ENV SERVICE_VARIANT lms -ENV LMS_CFG /edx/etc/lms.yaml -CMD gunicorn -c /edx/app/edx-platform/edx-platform/lms/docker_lms_gunicorn.py --name lms --bind=0.0.0.0:18000 --max-requests=1000 --access-logfile - lms.wsgi:application +ENV DJANGO_SETTINGS_MODULE lms.envs.production +EXPOSE 8000 +CMD gunicorn -c /edx/app/edxapp/edx-platform/lms/docker_lms_gunicorn.py --name lms --bind=0.0.0.0:8000 --max-requests=1000 --access-logfile - lms.wsgi:application FROM lms as lms-newrelic RUN pip install newrelic -CMD newrelic-admin run-program gunicorn -c /edx/app/edx-platform/edx-platform/lms/docker_lms_gunicorn.py --name lms --bind=0.0.0.0:8000 --max-requests=1000 --access-logfile - lms.wsgi:application +CMD newrelic-admin run-program gunicorn -c /edx/app/edxapp/edx-platform/lms/docker_lms_gunicorn.py --name lms --bind=0.0.0.0:8000 --max-requests=1000 --access-logfile - lms.wsgi:application -FROM base as cms +FROM lms as lms-devstack +# TODO: This compiles static assets. +# However, it's a bit of a hack, it's slow, and it's inefficient because makes the final Docker cache layer very large. +# We ought to be able to this higher up in the Dockerfile, and do it the same for Prod and Devstack. +RUN mkdir -p test_root/log +ENV DJANGO_SETTINGS_MODULE "" +RUN NO_PREREQ_INSTALL=1 paver update_assets lms --settings devstack_decentralized +ENV DJANGO_SETTINGS_MODULE lms.envs.devstack_decentralized + +FROM base as studio ENV SERVICE_VARIANT cms -ENV STUDIO_CFG /edx/etc/studio.yaml -CMD gunicorn -c /edx/app/edx-platform/edx-platform/cms/docker_cms_gunicorn.py --name cms --bind=0.0.0.0:8000 --max-requests=1000 --access-logfile - cms.wsgi:application +ENV DJANGO_SETTINGS_MODULE cms.envs.production +EXPOSE 8010 +CMD gunicorn -c /edx/app/edxapp/edx-platform/cms/docker_cms_gunicorn.py --name cms --bind=0.0.0.0:8010 --max-requests=1000 --access-logfile - cms.wsgi:application -FROM cms as cms-newrelic +FROM studio as studio-newrelic RUN pip install newrelic -CMD newrelic-admin run-program gunicorn -c /edx/app/edx-platform/edx-platform/cms/docker_cms_gunicorn.py --name cms --bind=0.0.0.0:8000 --max-requests=1000 --access-logfile - cms.wsgi:application +CMD newrelic-admin run-program gunicorn -c /edx/app/edxapp/edx-platform/cms/docker_cms_gunicorn.py --name cms --bind=0.0.0.0:8010 --max-requests=1000 --access-logfile - cms.wsgi:application + +FROM studio as studio-devstack +# TODO: This compiles static assets. +# However, it's a bit of a hack, it's slow, and it's inefficient because makes the final Docker cache layer very large. +# We ought to be able to this higher up in the Dockerfile, and do it the same for Prod and Devstack. +RUN mkdir -p test_root/log +ENV DJANGO_SETTINGS_MODULE "" +RUN NO_PREREQ_INSTALL=1 paver update_assets cms --settings devstack_decentralized +ENV DJANGO_SETTINGS_MODULE cms.envs.devstack_decentralized diff --git a/Makefile b/Makefile index 28226a4ff7..47e19bfe7b 100644 --- a/Makefile +++ b/Makefile @@ -109,10 +109,12 @@ upgrade: ## update the pip requirements files to use the latest releases satisfy docker_build: docker build . -f Dockerfile --target lms -t openedx/edx-platform docker build . -f Dockerfile --target lms-newrelic -t openedx/edx-platform:latest-newrelic + docker build . -f Dockerfile --target lms-devstack -t openedx/edx-platform:latest-devstack docker_tag: docker_build docker tag openedx/edx-platform openedx/edx-platform:${GITHUB_SHA} docker tag openedx/edx-platform:latest-newrelic openedx/edx-platform:${GITHUB_SHA}-newrelic + docker tag openedx/edx-platform:latest-devstack openedx/edx-platform:${GITHUB_SHA}-devstack docker_auth: echo "$$DOCKERHUB_PASSWORD" | docker login -u "$$DOCKERHUB_USERNAME" --password-stdin @@ -122,4 +124,6 @@ docker_push: docker_tag docker_auth ## push to docker hub docker push "openedx/edx-platform:${GITHUB_SHA}" docker push 'openedx/edx-platform:latest-newrelic' docker push "openedx/edx-platform:${GITHUB_SHA}-newrelic" + docker push 'openedx/edx-platform:latest-devstack' + docker push "openedx/edx-platform:${GITHUB_SHA}-devstack" diff --git a/cms/devstack.yml b/cms/devstack.yml new file mode 100644 index 0000000000..02dcb4a30a --- /dev/null +++ b/cms/devstack.yml @@ -0,0 +1,496 @@ +ACTIVATION_EMAIL_SUPPORT_LINK: '' +AFFILIATE_COOKIE_NAME: dev_affiliate_id +ALTERNATE_WORKER_QUEUES: lms +ANALYTICS_DASHBOARD_NAME: Your Platform Name Here Insights +ANALYTICS_DASHBOARD_URL: http://localhost:18110/courses +AUTH_PASSWORD_VALIDATORS: +- NAME: django.contrib.auth.password_validation.UserAttributeSimilarityValidator +- NAME: util.password_policy_validators.MinimumLengthValidator + OPTIONS: + min_length: 2 +- NAME: util.password_policy_validators.MaximumLengthValidator + OPTIONS: + max_length: 75 +AWS_ACCESS_KEY_ID: null +AWS_QUERYSTRING_AUTH: false +AWS_S3_CUSTOM_DOMAIN: SET-ME-PLEASE (ex. bucket-name.s3.amazonaws.com) +AWS_SECRET_ACCESS_KEY: null +AWS_SES_REGION_ENDPOINT: email.us-east-1.amazonaws.com +AWS_SES_REGION_NAME: us-east-1 +AWS_STORAGE_BUCKET_NAME: SET-ME-PLEASE (ex. bucket-name) +BASE_COOKIE_DOMAIN: localhost +BLOCKSTORE_API_URL: http://localhost:18250/api/v1 +BLOCKSTORE_PUBLIC_URL_ROOT: http://localhost:18250 +BLOCK_STRUCTURES_SETTINGS: + COURSE_PUBLISH_TASK_DELAY: 30 + PRUNING_ACTIVE: false + TASK_DEFAULT_RETRY_DELAY: 30 + TASK_MAX_RETRIES: 5 +BRANCH_IO_KEY: '' +BUGS_EMAIL: bugs@example.com +BULK_EMAIL_DEFAULT_FROM_EMAIL: no-reply@example.com +BULK_EMAIL_EMAILS_PER_TASK: 500 +BULK_EMAIL_LOG_SENT_EMAILS: false +CACHES: + celery: + BACKEND: django.core.cache.backends.memcached.MemcachedCache + KEY_FUNCTION: util.memcache.safe_key + KEY_PREFIX: celery + LOCATION: + - edx.devstack.memcached:11211 + TIMEOUT: '7200' + configuration: + BACKEND: django.core.cache.backends.memcached.MemcachedCache + KEY_FUNCTION: util.memcache.safe_key + KEY_PREFIX: 1001c6274ca4 + LOCATION: + - edx.devstack.memcached:11211 + course_structure_cache: + BACKEND: django.core.cache.backends.memcached.MemcachedCache + KEY_FUNCTION: util.memcache.safe_key + KEY_PREFIX: course_structure + LOCATION: + - edx.devstack.memcached:11211 + TIMEOUT: '7200' + default: + BACKEND: django.core.cache.backends.memcached.MemcachedCache + KEY_FUNCTION: util.memcache.safe_key + KEY_PREFIX: default + LOCATION: + - edx.devstack.memcached:11211 + VERSION: '1' + general: + BACKEND: django.core.cache.backends.memcached.MemcachedCache + KEY_FUNCTION: util.memcache.safe_key + KEY_PREFIX: general + LOCATION: + - edx.devstack.memcached:11211 + mongo_metadata_inheritance: + BACKEND: django.core.cache.backends.memcached.MemcachedCache + KEY_FUNCTION: util.memcache.safe_key + KEY_PREFIX: mongo_metadata_inheritance + LOCATION: + - edx.devstack.memcached:11211 + TIMEOUT: 300 + staticfiles: + BACKEND: django.core.cache.backends.memcached.MemcachedCache + KEY_FUNCTION: util.memcache.safe_key + KEY_PREFIX: 1001c6274ca4_general + LOCATION: + - edx.devstack.memcached:11211 +CAS_ATTRIBUTE_CALLBACK: '' +CAS_EXTRA_LOGIN_PARAMS: '' +CAS_SERVER_URL: '' +CELERY_BROKER_HOSTNAME: localhost +CELERY_BROKER_PASSWORD: celery +CELERY_BROKER_TRANSPORT: amqp +CELERY_BROKER_USER: celery +CELERY_BROKER_USE_SSL: false +CELERY_BROKER_VHOST: '' +CELERY_EVENT_QUEUE_TTL: null +CELERY_QUEUES: +- edx.cms.core.default +- edx.cms.core.high +CELERY_TIMEZONE: UTC +CERTIFICATE_TEMPLATE_LANGUAGES: + en: English + es: Español +CERT_QUEUE: certificates +CMS_BASE: edx.devstack.studio:8010 +CODE_JAIL: + limits: + CPU: 1 + FSIZE: 1048576 + PROXY: 0 + REALTIME: 3 + VMEM: 536870912 + python_bin: /edx/app/edxapp/venvs/edxapp-sandbox/bin/python + user: sandbox +COMMENTS_SERVICE_KEY: password +COMMENTS_SERVICE_URL: http://localhost:18080 +COMPREHENSIVE_THEME_DIRS: +- '' +COMPREHENSIVE_THEME_LOCALE_PATHS: [] +CONTACT_EMAIL: info@example.com +CONTENTSTORE: + ADDITIONAL_OPTIONS: {} + DOC_STORE_CONFIG: + authsource: '' + collection: modulestore + connectTimeoutMS: 2000 + db: edxapp + host: + - edx.devstack.mongo + password: password + port: 27017 + read_preference: PRIMARY + replicaSet: '' + socketTimeoutMS: 3000 + ssl: false + user: edxapp + ENGINE: xmodule.contentstore.mongo.MongoContentStore + OPTIONS: + auth_source: '' + db: edxapp + host: + - edx.devstack.mongo + password: password + port: 27017 + ssl: false + user: edxapp +CORS_ORIGIN_ALLOW_ALL: false +CORS_ORIGIN_WHITELIST: [] +COURSES_WITH_UNSAFE_CODE: [] +COURSE_ABOUT_VISIBILITY_PERMISSION: see_exists +COURSE_AUTHORING_MICROFRONTEND_URL: null +COURSE_CATALOG_API_URL: http://localhost:8008/api/v1 +COURSE_CATALOG_URL_ROOT: http://localhost:8008 +COURSE_CATALOG_VISIBILITY_PERMISSION: see_exists +COURSE_IMPORT_EXPORT_BUCKET: '' +CREDENTIALS_INTERNAL_SERVICE_URL: http://localhost:8005 +CREDENTIALS_PUBLIC_SERVICE_URL: http://localhost:8005 +CREDIT_PROVIDER_SECRET_KEYS: {} +CROSS_DOMAIN_CSRF_COOKIE_DOMAIN: '' +CROSS_DOMAIN_CSRF_COOKIE_NAME: '' +CSRF_COOKIE_SECURE: false +CSRF_TRUSTED_ORIGINS: [] +DASHBOARD_COURSE_LIMIT: null +DATABASES: + default: + ATOMIC_REQUESTS: true + CONN_MAX_AGE: 0 + ENGINE: django.db.backends.mysql + HOST: edx.devstack.mysql + NAME: edxapp + OPTIONS: {} + PASSWORD: password + PORT: '3306' + USER: edxapp001 + read_replica: + CONN_MAX_AGE: 0 + ENGINE: django.db.backends.mysql + HOST: edx.devstack.mysql + NAME: edxapp + OPTIONS: {} + PASSWORD: password + PORT: '3306' + USER: edxapp001 + student_module_history: + CONN_MAX_AGE: 0 + ENGINE: django.db.backends.mysql + HOST: edx.devstack.mysql + NAME: edxapp_csmh + OPTIONS: {} + PASSWORD: password + PORT: '3306' + USER: edxapp001 +DATA_DIR: /edx/var/edxapp +DEFAULT_COURSE_VISIBILITY_IN_CATALOG: both +DEFAULT_FEEDBACK_EMAIL: feedback@example.com +DEFAULT_FILE_STORAGE: django.core.files.storage.FileSystemStorage +DEFAULT_FROM_EMAIL: registration@example.com +DEFAULT_JWT_ISSUER: + AUDIENCE: lms-key + ISSUER: http://edx.devstack.lms:8000/oauth2 + SECRET_KEY: lms-secret +DEFAULT_MOBILE_AVAILABLE: false +DEFAULT_SITE_THEME: '' +DEPRECATED_ADVANCED_COMPONENT_TYPES: [] +DJFS: + directory_root: /edx/var/edxapp/django-pyfs/static/django-pyfs + type: osfs + url_root: /static/django-pyfs +DOC_STORE_CONFIG: + authsource: '' + collection: modulestore + connectTimeoutMS: 2000 + db: edxapp + host: + - edx.devstack.mongo + password: password + port: 27017 + read_preference: PRIMARY + replicaSet: '' + socketTimeoutMS: 3000 + ssl: false + user: edxapp +ECOMMERCE_API_SIGNING_KEY: lms-secret +ECOMMERCE_API_URL: http://localhost:8002/api/v2 +ECOMMERCE_PUBLIC_URL_ROOT: http://localhost:8002 +EDXMKTG_USER_INFO_COOKIE_NAME: edx-user-info +EDX_PLATFORM_REVISION: master +ELASTIC_SEARCH_CONFIG: +- host: edx.devstack.elasticsearch + port: 9200 + use_ssl: false +EMAIL_BACKEND: django.core.mail.backends.smtp.EmailBackend +EMAIL_HOST: localhost +EMAIL_HOST_PASSWORD: '' +EMAIL_HOST_USER: '' +EMAIL_PORT: 25 +EMAIL_USE_TLS: false +ENABLE_COMPREHENSIVE_THEMING: false +ENTERPRISE_API_URL: http://edx.devstack.lms:8000/enterprise/api/v1 +ENTERPRISE_MARKETING_FOOTER_QUERY_PARAMS: {} +ENTERPRISE_SERVICE_WORKER_USERNAME: enterprise_worker +EVENT_TRACKING_SEGMENTIO_EMIT_WHITELIST: [] +EXTRA_MIDDLEWARE_CLASSES: [] +FACEBOOK_API_VERSION: v2.1 +FACEBOOK_APP_ID: FACEBOOK_APP_ID +FACEBOOK_APP_SECRET: FACEBOOK_APP_SECRET +FEATURES: + AUTH_USE_OPENID_PROVIDER: true + AUTOMATIC_AUTH_FOR_TESTING: false + CUSTOM_COURSES_EDX: false + ENABLE_COMBINED_LOGIN_REGISTRATION: true + ENABLE_CORS_HEADERS: false + ENABLE_COUNTRY_ACCESS: false + ENABLE_CREDIT_API: false + ENABLE_CREDIT_ELIGIBILITY: false + ENABLE_CROSS_DOMAIN_CSRF_COOKIE: false + ENABLE_CSMH_EXTENDED: true + ENABLE_DISCUSSION_HOME_PANEL: true + ENABLE_DISCUSSION_SERVICE: true + ENABLE_EDXNOTES: true + ENABLE_ENROLLMENT_RESET: false + ENABLE_GRADE_DOWNLOADS: true + ENABLE_INSTRUCTOR_ANALYTICS: false + ENABLE_MKTG_SITE: false + ENABLE_MOBILE_REST_API: false + ENABLE_OAUTH2_PROVIDER: false + ENABLE_PUBLISHER: false + ENABLE_READING_FROM_MULTIPLE_HISTORY_TABLES: true + ENABLE_SPECIAL_EXAMS: false + ENABLE_SYSADMIN_DASHBOARD: false + ENABLE_THIRD_PARTY_AUTH: true + ENABLE_VIDEO_UPLOAD_PIPELINE: false + PREVIEW_LMS_BASE: preview.localhost:8000 + SHOW_FOOTER_LANGUAGE_SELECTOR: false + SHOW_HEADER_LANGUAGE_SELECTOR: false +FEEDBACK_SUBMISSION_EMAIL: '' +FERNET_KEYS: +- DUMMY KEY CHANGE BEFORE GOING TO PRODUCTION +FILE_UPLOAD_STORAGE_BUCKET_NAME: SET-ME-PLEASE (ex. bucket-name) +FILE_UPLOAD_STORAGE_PREFIX: submissions_attachments +FINANCIAL_REPORTS: + BUCKET: null + ROOT_PATH: sandbox + STORAGE_TYPE: localfs +FOOTER_ORGANIZATION_IMAGE: images/logo.png +GITHUB_REPO_ROOT: /edx/var/edxapp/data +GIT_REPO_EXPORT_DIR: /edx/var/edxapp/export_course_repos +GOOGLE_ANALYTICS_ACCOUNT: null +GRADES_DOWNLOAD: + BUCKET: '' + ROOT_PATH: '' + STORAGE_CLASS: django.core.files.storage.FileSystemStorage + STORAGE_KWARGS: + location: /tmp/edx-s3/grades + STORAGE_TYPE: '' +HELP_TOKENS_BOOKS: + course_author: http://edx.readthedocs.io/projects/open-edx-building-and-running-a-course + learner: http://edx.readthedocs.io/projects/open-edx-learner-guide +ICP_LICENSE: null +ICP_LICENSE_INFO: {} +IDA_LOGOUT_URI_LIST: [] +ID_VERIFICATION_SUPPORT_LINK: '' +JWT_AUTH: + JWT_AUDIENCE: lms-key + JWT_AUTH_COOKIE_HEADER_PAYLOAD: edx-jwt-cookie-header-payload + JWT_AUTH_COOKIE_SIGNATURE: edx-jwt-cookie-signature + JWT_AUTH_REFRESH_COOKIE: edx-jwt-refresh-cookie + JWT_ISSUER: http://edx.devstack.lms:8000/oauth2 + JWT_ISSUERS: + - AUDIENCE: lms-key + ISSUER: http://edx.devstack.lms:8000/oauth2 + SECRET_KEY: lms-secret + JWT_PRIVATE_SIGNING_JWK: None + JWT_PUBLIC_SIGNING_JWK_SET: '' + JWT_SECRET_KEY: lms-secret + JWT_SIGNING_ALGORITHM: null +JWT_EXPIRATION: 30 +JWT_ISSUER: http://edx.devstack.lms:8000/oauth2 +JWT_PRIVATE_SIGNING_KEY: null +LANGUAGE_CODE: en +LANGUAGE_COOKIE: openedx-language-preference +LEARNER_PORTAL_URL_ROOT: https://learner-portal-edx.devstack.lms:8000 +LMS_BASE: edx.devstack.lms:8000 +LMS_INTERNAL_ROOT_URL: http://edx.devstack.lms:8000 +LMS_ROOT_URL: http://edx.devstack.lms:8000 +LOCAL_LOGLEVEL: INFO +LOGGING_ENV: sandbox +LOGIN_REDIRECT_WHITELIST: [] +LOG_DIR: /edx/var/log/edx +MAINTENANCE_BANNER_TEXT: Sample banner message +MEDIA_ROOT: /edx/var/edxapp/media/ +MEDIA_URL: /media/ +MICROSITE_CONFIGURATION: {} +MICROSITE_ROOT_DIR: /edx/app/edxapp/edx-microsite +MKTG_URLS: {} +MKTG_URL_LINK_MAP: {} +MOBILE_STORE_URLS: {} +MODULESTORE: + default: + ENGINE: xmodule.modulestore.mixed.MixedModuleStore + OPTIONS: + mappings: {} + stores: + - DOC_STORE_CONFIG: + authsource: '' + collection: modulestore + connectTimeoutMS: 2000 + db: edxapp + host: + - edx.devstack.mongo + password: password + port: 27017 + read_preference: PRIMARY + replicaSet: '' + socketTimeoutMS: 3000 + ssl: false + user: edxapp + ENGINE: xmodule.modulestore.split_mongo.split_draft.DraftVersioningModuleStore + NAME: split + OPTIONS: + default_class: xmodule.hidden_module.HiddenDescriptor + fs_root: /edx/var/edxapp/data + render_template: edxmako.shortcuts.render_to_string + - DOC_STORE_CONFIG: + authsource: '' + collection: modulestore + connectTimeoutMS: 2000 + db: edxapp + host: + - edx.devstack.mongo + password: password + port: 27017 + read_preference: PRIMARY + replicaSet: '' + socketTimeoutMS: 3000 + ssl: false + user: edxapp + ENGINE: xmodule.modulestore.mongo.DraftMongoModuleStore + NAME: draft + OPTIONS: + default_class: xmodule.hidden_module.HiddenDescriptor + fs_root: /edx/var/edxapp/data + render_template: edxmako.shortcuts.render_to_string +ORA2_FILE_PREFIX: default_env-default_deployment/ora2 +PARSE_KEYS: {} +PARTNER_SUPPORT_EMAIL: '' +PASSWORD_POLICY_COMPLIANCE_ROLLOUT_CONFIG: + ENFORCE_COMPLIANCE_ON_LOGIN: false +PASSWORD_RESET_SUPPORT_LINK: '' +PAYMENT_SUPPORT_EMAIL: billing@example.com +PLATFORM_DESCRIPTION: Your Platform Description Here +PLATFORM_FACEBOOK_ACCOUNT: http://www.facebook.com/YourPlatformFacebookAccount +PLATFORM_NAME: Your Platform Name Here +PLATFORM_TWITTER_ACCOUNT: '@YourPlatformTwitterAccount' +POLICY_CHANGE_GRADES_ROUTING_KEY: edx.lms.core.default +PRESS_EMAIL: press@example.com +PROCTORING_BACKENDS: + DEFAULT: 'null' + 'null': {} +PROCTORING_SETTINGS: {} +REGISTRATION_EXTRA_FIELDS: + city: hidden + confirm_email: hidden + country: required + gender: optional + goals: optional + honor_code: required + level_of_education: optional + mailing_address: hidden + terms_of_service: hidden + year_of_birth: optional +RETIRED_EMAIL_DOMAIN: retired.invalid +RETIRED_EMAIL_PREFIX: retired__user_ +RETIRED_USERNAME_PREFIX: retired__user_ +RETIRED_USER_SALTS: +- OVERRIDE ME WITH A RANDOM VALUE +- ROTATE SALTS BY APPENDING NEW VALUES +RETIREMENT_SERVICE_WORKER_USERNAME: retirement_worker +RETIREMENT_STATES: +- PENDING +- ERRORED +- ABORTED +- COMPLETE +SECRET_KEY: DUMMY KEY ONLY FOR TO DEVSTACK +SEGMENT_KEY: null +SERVER_EMAIL: devops@example.com +SESSION_COOKIE_DOMAIN: '' +SESSION_COOKIE_NAME: sessionid +SESSION_COOKIE_SECURE: false +SESSION_SAVE_EVERY_REQUEST: false +SITE_NAME: localhost +SOCIAL_AUTH_SAML_SP_PRIVATE_KEY: '' +SOCIAL_AUTH_SAML_SP_PRIVATE_KEY_DICT: {} +SOCIAL_AUTH_SAML_SP_PUBLIC_CERT: '' +SOCIAL_AUTH_SAML_SP_PUBLIC_CERT_DICT: {} +SOCIAL_MEDIA_FOOTER_URLS: {} +SOCIAL_SHARING_SETTINGS: + CERTIFICATE_FACEBOOK: false + CERTIFICATE_TWITTER: false + CUSTOM_COURSE_URLS: false + DASHBOARD_FACEBOOK: false + DASHBOARD_TWITTER: false +STATIC_ROOT_BASE: /edx/var/edxapp/staticfiles +STATIC_URL_BASE: /static/ +STUDIO_NAME: Studio +STUDIO_SHORT_NAME: Studio +SUPPORT_SITE_LINK: '' +SWIFT_AUTH_URL: null +SWIFT_AUTH_VERSION: null +SWIFT_KEY: null +SWIFT_REGION_NAME: null +SWIFT_TEMP_URL_DURATION: 1800 +SWIFT_TEMP_URL_KEY: null +SWIFT_TENANT_ID: null +SWIFT_TENANT_NAME: null +SWIFT_USERNAME: null +SWIFT_USE_TEMP_URLS: false +SYSLOG_SERVER: '' +SYSTEM_WIDE_ROLE_CLASSES: [] +TECH_SUPPORT_EMAIL: technical@example.com +TIME_ZONE: America/New_York +UNIVERSITY_EMAIL: university@example.com +USERNAME_REPLACEMENT_WORKER: OVERRIDE THIS WITH A VALID USERNAME +VIDEO_IMAGE_MAX_AGE: 31536000 +VIDEO_IMAGE_SETTINGS: + DIRECTORY_PREFIX: video-images/ + STORAGE_KWARGS: + base_url: /media/ + location: edx/var/edxapp/media/ + VIDEO_IMAGE_MAX_BYTES: 2097152 + VIDEO_IMAGE_MIN_BYTES: 2048 +VIDEO_TRANSCRIPTS_MAX_AGE: 31536000 +VIDEO_TRANSCRIPTS_SETTINGS: + DIRECTORY_PREFIX: video-transcripts/ + STORAGE_KWARGS: + base_url: /media/ + location: edx/var/edxapp/media/ + VIDEO_TRANSCRIPTS_MAX_BYTES: 3145728 +VIDEO_UPLOAD_PIPELINE: + BUCKET: '' + ROOT_PATH: '' +WIKI_ENABLED: true +XBLOCK_FS_STORAGE_BUCKET: null +XBLOCK_FS_STORAGE_PREFIX: null +XBLOCK_SETTINGS: {} +XQUEUE_INTERFACE: + basic_auth: + - edx + - edx + django_auth: + password: password + username: lms + url: http://edx.devstack.xqueue:18040 +X_FRAME_OPTIONS: DENY +YOUTUBE_API_KEY: PUT_YOUR_API_KEY_HERE +ZENDESK_API_KEY: '' +ZENDESK_CUSTOM_FIELDS: {} +ZENDESK_GROUP_ID_MAPPING: {} +ZENDESK_OAUTH_ACCESS_TOKEN: '' +ZENDESK_URL: '' +ZENDESK_USER: '' + diff --git a/cms/docker_cms_gunicorn.py b/cms/docker_cms_gunicorn.py index c95d06c3a0..54fbf31dd6 100644 --- a/cms/docker_cms_gunicorn.py +++ b/cms/docker_cms_gunicorn.py @@ -1,7 +1,5 @@ """ gunicorn configuration file: http://docs.gunicorn.org/en/stable/configure.html - -This file is created and updated by ansible, edit at your peril """ preload_app = False diff --git a/cms/envs/devstack_decentralized.py b/cms/envs/devstack_decentralized.py new file mode 100644 index 0000000000..4b33d18c40 --- /dev/null +++ b/cms/envs/devstack_decentralized.py @@ -0,0 +1,185 @@ +""" +Settings file for decentralized devstack +""" + +import logging +from os.path import abspath, dirname, join + +from .production import * # pylint: disable=wildcard-import, unused-wildcard-import + +# Don't use S3 in devstack, fall back to filesystem +del DEFAULT_FILE_STORAGE +COURSE_IMPORT_EXPORT_STORAGE = 'django.core.files.storage.FileSystemStorage' +USER_TASKS_ARTIFACT_STORAGE = COURSE_IMPORT_EXPORT_STORAGE + +DEBUG = True +USE_I18N = True +DEFAULT_TEMPLATE_ENGINE['OPTIONS']['debug'] = DEBUG +SITE_NAME = 'localhost:8001' +HTTPS = 'off' + +CMS_BASE = 'localhost:8010' + +################################ LOGGERS ###################################### + + +# Disable noisy loggers +for pkg_name in ['track.contexts', 'track.middleware']: + logging.getLogger(pkg_name).setLevel(logging.CRITICAL) + +# Docker does not support the syslog socket at /dev/log. Rely on the console. +LOGGING['handlers']['local'] = LOGGING['handlers']['tracking'] = { + 'class': 'logging.NullHandler', +} + +LOGGING['loggers']['tracking']['handlers'] = ['console'] + +################################ EMAIL ######################################## + +EMAIL_BACKEND = 'django.core.mail.backends.filebased.EmailBackend' +EMAIL_FILE_PATH = '/edx/src/ace_messages/' + +################################# LMS INTEGRATION ############################# + +LMS_BASE = 'localhost:8000' +LMS_ROOT_URL = 'http://{}'.format(LMS_BASE) +FEATURES['PREVIEW_LMS_BASE'] = "preview." + LMS_BASE + +########################### PIPELINE ################################# + +# Skip packaging and optimization in development +PIPELINE['PIPELINE_ENABLED'] = False +STATICFILES_STORAGE = 'openedx.core.storage.DevelopmentStorage' + +# Revert to the default set of finders as we don't want the production pipeline +STATICFILES_FINDERS = [ + 'openedx.core.djangoapps.theming.finders.ThemeFilesFinder', + 'django.contrib.staticfiles.finders.FileSystemFinder', + 'django.contrib.staticfiles.finders.AppDirectoriesFinder', +] + +# Load development webpack donfiguration +WEBPACK_CONFIG_PATH = 'webpack.dev.config.js' + +############################ PYFS XBLOCKS SERVICE ############################# +# Set configuration for Django pyfilesystem + +DJFS = { + 'type': 'osfs', + 'directory_root': 'cms/static/djpyfs', + 'url_root': '/static/djpyfs', +} + +################################# CELERY ###################################### + +# By default don't use a worker, execute tasks as if they were local functions +CELERY_ALWAYS_EAGER = True + + +def should_show_debug_toolbar(request): + return False + + +################################ MILESTONES ################################ +FEATURES['MILESTONES_APP'] = True + + +################################ ENTRANCE EXAMS ################################ +FEATURES['ENTRANCE_EXAMS'] = True + +################################ COURSE LICENSES ################################ +FEATURES['LICENSING'] = True +# Needed to enable licensing on video modules +XBLOCK_SETTINGS.update({'VideoBlock': {'licensing_enabled': True}}) + +################################ SEARCH INDEX ################################ +FEATURES['ENABLE_COURSEWARE_INDEX'] = False +FEATURES['ENABLE_LIBRARY_INDEX'] = False +SEARCH_ENGINE = "search.elastic.ElasticSearchEngine" + +################################ COURSE DISCUSSIONS ########################### +FEATURES['ENABLE_DISCUSSION_SERVICE'] = True + +################################ CREDENTIALS ########################### +CREDENTIALS_SERVICE_USERNAME = 'credentials_worker' + +########################## Certificates Web/HTML View ####################### +FEATURES['CERTIFICATES_HTML_VIEW'] = True + +########################## AUTHOR PERMISSION ####################### +FEATURES['ENABLE_CREATOR_GROUP'] = False + +################### FRONTEND APPLICATION PUBLISHER URL ################### +FEATURES['FRONTEND_APP_PUBLISHER_URL'] = 'http://localhost:18400' + +################################# DJANGO-REQUIRE ############################### + +# Whether to run django-require in debug mode. +REQUIRE_DEBUG = DEBUG + +########################### OAUTH2 ################################# +JWT_AUTH.update({ + 'JWT_ISSUER': '{}/oauth2'.format(LMS_ROOT_URL), + 'JWT_ISSUERS': [{ + 'AUDIENCE': 'lms-key', + 'ISSUER': '{}/oauth2'.format(LMS_ROOT_URL), + 'SECRET_KEY': 'lms-secret', + }], + 'JWT_SECRET_KEY': 'lms-secret', + 'JWT_AUDIENCE': 'lms-key', + 'JWT_PUBLIC_SIGNING_JWK_SET': ( + '{"keys": [{"kid": "devstack_key", "e": "AQAB", "kty": "RSA", "n": "smKFSYowG6nNUAdeqH1jQQnH1PmIHphzBmwJ5vRf1vu' + '48BUI5VcVtUWIPqzRK_LDSlZYh9D0YFL0ZTxIrlb6Tn3Xz7pYvpIAeYuQv3_H5p8tbz7Fb8r63c1828wXPITVTv8f7oxx5W3lFFgpFAyYMmROC' + '4Ee9qG5T38LFe8_oAuFCEntimWxN9F3P-FJQy43TL7wG54WodgiM0EgzkeLr5K6cDnyckWjTuZbWI-4ffcTgTZsL_Kq1owa_J2ngEfxMCObnzG' + 'y5ZLcTUomo4rZLjghVpq6KZxfS6I1Vz79ZsMVUWEdXOYePCKKsrQG20ogQEkmTf9FT_SouC6jPcHLXw"}]}' + ), + + # TODO Remove this once CMS redirects to LMS for Login + 'JWT_PRIVATE_SIGNING_JWK': ( + '{"e": "AQAB", "d": "RQ6k4NpRU3RB2lhwCbQ452W86bMMQiPsa7EJiFJUg-qBJthN0FMNQVbArtrCQ0xA1BdnQHThFiUnHcXfsTZUwmwvTu' + 'iqEGR_MI6aI7h5D8vRj_5x-pxOz-0MCB8TY8dcuK9FkljmgtYvV9flVzCk_uUb3ZJIBVyIW8En7n7nV7JXpS9zey1yVLld2AbRG6W5--Pgqr9J' + 'CI5-bLdc2otCLuen2sKyuUDHO5NIj30qGTaKUL-OW_PgVmxrwKwccF3w5uGNEvMQ-IcicosCOvzBwdIm1uhdm9rnHU1-fXz8VLRHNhGVv7z6mo' + 'ghjNI0_u4smhUkEsYeshPv7RQEWTdkOQ", "n": "smKFSYowG6nNUAdeqH1jQQnH1PmIHphzBmwJ5vRf1vu48BUI5VcVtUWIPqzRK_LDSlZYh' + '9D0YFL0ZTxIrlb6Tn3Xz7pYvpIAeYuQv3_H5p8tbz7Fb8r63c1828wXPITVTv8f7oxx5W3lFFgpFAyYMmROC4Ee9qG5T38LFe8_oAuFCEntimW' + 'xN9F3P-FJQy43TL7wG54WodgiM0EgzkeLr5K6cDnyckWjTuZbWI-4ffcTgTZsL_Kq1owa_J2ngEfxMCObnzGy5ZLcTUomo4rZLjghVpq6KZxfS' + '6I1Vz79ZsMVUWEdXOYePCKKsrQG20ogQEkmTf9FT_SouC6jPcHLXw", "q": "7KWj7l-ZkfCElyfvwsl7kiosvi-ppOO7Imsv90cribf88Dex' + 'cO67xdMPesjM9Nh5X209IT-TzbsOtVTXSQyEsy42NY72WETnd1_nAGLAmfxGdo8VV4ZDnRsA8N8POnWjRDwYlVBUEEeuT_MtMWzwIKU94bzkWV' + 'nHCY5vbhBYLeM", "p": "wPkfnjavNV1Hqb5Qqj2crBS9HQS6GDQIZ7WF9hlBb2ofDNe2K2dunddFqCOdvLXr7ydRcK51ZwSeHjcjgD1aJkHA' + '9i1zqyboxgd0uAbxVDo6ohnlVqYLtap2tXXcavKm4C9MTpob_rk6FBfEuq4uSsuxFvCER4yG3CYBBa4gZVU", "kid": "devstack_key", "' + 'kty": "RSA"}' + ), +}) + +# pylint: enable=unicode-format-string + +IDA_LOGOUT_URI_LIST = [ + 'http://localhost:18130/logout/', # ecommerce + 'http://localhost:18150/logout/', # credentials +] + +############################### BLOCKSTORE ##################################### +BLOCKSTORE_API_URL = "http://edx.devstack.blockstore:18250/api/v1/" + +##################################################################### + +# pylint: disable=wrong-import-order, wrong-import-position +from openedx.core.djangoapps.plugins.constants import ProjectType, SettingsType +# pylint: disable=wrong-import-order, wrong-import-position +from edx_django_utils.plugins import add_plugins + +add_plugins(__name__, ProjectType.CMS, SettingsType.DEVSTACK) + + +OPENAPI_CACHE_TIMEOUT = 0 + +##################################################################### +# Lastly, run any migrations, if needed. +MODULESTORE = convert_module_store_setting_if_needed(MODULESTORE) + +# Dummy secret key for dev +SECRET_KEY = '85920908f28904ed733fe576320db18cabd7b6cd' + +############################################################################### +# See if the developer has any local overrides. +if os.path.isfile(join(dirname(abspath(__file__)), 'private.py')): + from .private import * # pylint: disable=import-error,wildcard-import diff --git a/lms/devstack.yml b/lms/devstack.yml new file mode 100644 index 0000000000..4eb59456c2 --- /dev/null +++ b/lms/devstack.yml @@ -0,0 +1,601 @@ +ACCOUNT_MICROFRONTEND_URL: null +ACE_CHANNEL_DEFAULT_EMAIL: django_email +ACE_CHANNEL_SAILTHRU_API_KEY: '' +ACE_CHANNEL_SAILTHRU_API_SECRET: '' +ACE_CHANNEL_SAILTHRU_DEBUG: true +ACE_CHANNEL_SAILTHRU_TEMPLATE_NAME: null +ACE_CHANNEL_TRANSACTIONAL_EMAIL: django_email +ACE_ENABLED_CHANNELS: +- django_email +ACE_ENABLED_POLICIES: +- bulk_email_optout +ACE_ROUTING_KEY: edx.lms.core.default +ACTIVATION_EMAIL_SUPPORT_LINK: '' +AFFILIATE_COOKIE_NAME: dev_affiliate_id +ALTERNATE_WORKER_QUEUES: cms +ANALYTICS_API_KEY: '' +ANALYTICS_API_URL: http://localhost:18100 +ANALYTICS_DASHBOARD_NAME: Your Platform Name Here Insights +ANALYTICS_DASHBOARD_URL: http://localhost:18110/courses +API_ACCESS_FROM_EMAIL: api-requests@example.com +API_ACCESS_MANAGER_EMAIL: api-access@example.com +API_DOCUMENTATION_URL: http://course-catalog-api-guide.readthedocs.io/en/latest/ +AUDIT_CERT_CUTOFF_DATE: null +AUTH_DOCUMENTATION_URL: http://course-catalog-api-guide.readthedocs.io/en/latest/authentication/index.html +AUTH_PASSWORD_VALIDATORS: +- NAME: django.contrib.auth.password_validation.UserAttributeSimilarityValidator +- NAME: util.password_policy_validators.MinimumLengthValidator + OPTIONS: + min_length: 2 +- NAME: util.password_policy_validators.MaximumLengthValidator + OPTIONS: + max_length: 75 +AWS_ACCESS_KEY_ID: null +AWS_QUERYSTRING_AUTH: false +AWS_S3_CUSTOM_DOMAIN: SET-ME-PLEASE (ex. bucket-name.s3.amazonaws.com) +AWS_SECRET_ACCESS_KEY: null +AWS_SES_REGION_ENDPOINT: email.us-east-1.amazonaws.com +AWS_SES_REGION_NAME: us-east-1 +AWS_STORAGE_BUCKET_NAME: SET-ME-PLEASE (ex. bucket-name) +BASE_COOKIE_DOMAIN: localhost +BLOCKSTORE_API_URL: http://localhost:18250/api/v1 +BLOCKSTORE_PUBLIC_URL_ROOT: http://localhost:18250 +BLOCK_STRUCTURES_SETTINGS: + COURSE_PUBLISH_TASK_DELAY: 30 + PRUNING_ACTIVE: false + TASK_DEFAULT_RETRY_DELAY: 30 + TASK_MAX_RETRIES: 5 +BRANCH_IO_KEY: '' +BUGS_EMAIL: bugs@example.com +BULK_EMAIL_DEFAULT_FROM_EMAIL: no-reply@example.com +BULK_EMAIL_EMAILS_PER_TASK: 500 +BULK_EMAIL_LOG_SENT_EMAILS: false +BULK_EMAIL_ROUTING_KEY_SMALL_JOBS: edx.lms.core.default +CACHES: + celery: + BACKEND: django.core.cache.backends.memcached.MemcachedCache + KEY_FUNCTION: util.memcache.safe_key + KEY_PREFIX: celery + LOCATION: + - edx.devstack.memcached:11211 + TIMEOUT: '7200' + configuration: + BACKEND: django.core.cache.backends.memcached.MemcachedCache + KEY_FUNCTION: util.memcache.safe_key + KEY_PREFIX: 1001c6274ca4 + LOCATION: + - edx.devstack.memcached:11211 + course_structure_cache: + BACKEND: django.core.cache.backends.memcached.MemcachedCache + KEY_FUNCTION: util.memcache.safe_key + KEY_PREFIX: course_structure + LOCATION: + - edx.devstack.memcached:11211 + TIMEOUT: '7200' + default: + BACKEND: django.core.cache.backends.memcached.MemcachedCache + KEY_FUNCTION: util.memcache.safe_key + KEY_PREFIX: default + LOCATION: + - edx.devstack.memcached:11211 + VERSION: '1' + general: + BACKEND: django.core.cache.backends.memcached.MemcachedCache + KEY_FUNCTION: util.memcache.safe_key + KEY_PREFIX: general + LOCATION: + - edx.devstack.memcached:11211 + mongo_metadata_inheritance: + BACKEND: django.core.cache.backends.memcached.MemcachedCache + KEY_FUNCTION: util.memcache.safe_key + KEY_PREFIX: mongo_metadata_inheritance + LOCATION: + - edx.devstack.memcached:11211 + TIMEOUT: 300 + staticfiles: + BACKEND: django.core.cache.backends.memcached.MemcachedCache + KEY_FUNCTION: util.memcache.safe_key + KEY_PREFIX: 1001c6274ca4_general + LOCATION: + - edx.devstack.memcached:11211 +CAS_ATTRIBUTE_CALLBACK: '' +CAS_EXTRA_LOGIN_PARAMS: '' +CAS_SERVER_URL: '' +CC_PROCESSOR: + CyberSource: + MERCHANT_ID: '' + ORDERPAGE_VERSION: '7' + PURCHASE_ENDPOINT: '' + SERIAL_NUMBER: '' + SHARED_SECRET: '' + CyberSource2: + ACCESS_KEY: '' + PROFILE_ID: '' + PURCHASE_ENDPOINT: '' + SECRET_KEY: '' +CC_PROCESSOR_NAME: CyberSource2 +CELERY_BROKER_HOSTNAME: localhost +CELERY_BROKER_PASSWORD: celery +CELERY_BROKER_TRANSPORT: amqp +CELERY_BROKER_USER: celery +CELERY_BROKER_USE_SSL: false +CELERY_BROKER_VHOST: '' +CELERY_EVENT_QUEUE_TTL: null +CELERY_QUEUES: +- edx.lms.core.default +- edx.lms.core.high +- edx.lms.core.high_mem +CELERY_TIMEZONE: UTC +CERTIFICATE_TEMPLATE_LANGUAGES: + en: English + es: Español +CERT_QUEUE: certificates +CMS_BASE: edx.devstack.studio:18010 +CODE_JAIL: + limits: + CPU: 1 + FSIZE: 1048576 + PROXY: 0 + REALTIME: 3 + VMEM: 536870912 + python_bin: /edx/app/edxapp/venvs/edxapp-sandbox/bin/python + user: sandbox +COMMENTS_SERVICE_KEY: password +COMMENTS_SERVICE_URL: http://localhost:18080 +COMPREHENSIVE_THEME_DIRS: +- '' +COMPREHENSIVE_THEME_LOCALE_PATHS: [] +CONTACT_EMAIL: info@example.com +CONTACT_MAILING_ADDRESS: SET-ME-PLEASE +CONTENTSTORE: + ADDITIONAL_OPTIONS: {} + DOC_STORE_CONFIG: + authsource: '' + collection: modulestore + connectTimeoutMS: 2000 + db: edxapp + host: + - edx.devstack.mongo + password: password + port: 27017 + read_preference: SECONDARY_PREFERRED + replicaSet: '' + socketTimeoutMS: 3000 + ssl: false + user: edxapp + ENGINE: xmodule.contentstore.mongo.MongoContentStore + OPTIONS: + auth_source: '' + db: edxapp + host: + - edx.devstack.mongo + password: password + port: 27017 + ssl: false + user: edxapp +CORS_ORIGIN_ALLOW_ALL: false +CORS_ORIGIN_WHITELIST: [] +COURSES_WITH_UNSAFE_CODE: [] +COURSE_ABOUT_VISIBILITY_PERMISSION: see_exists +COURSE_CATALOG_API_URL: http://localhost:8008/api/v1 +COURSE_CATALOG_URL_ROOT: http://localhost:8008 +COURSE_CATALOG_VISIBILITY_PERMISSION: see_exists +CREDENTIALS_INTERNAL_SERVICE_URL: http://localhost:8005 +CREDENTIALS_PUBLIC_SERVICE_URL: http://localhost:8005 +CREDIT_HELP_LINK_URL: '' +CREDIT_PROVIDER_SECRET_KEYS: {} +CROSS_DOMAIN_CSRF_COOKIE_DOMAIN: '' +CROSS_DOMAIN_CSRF_COOKIE_NAME: '' +CSRF_COOKIE_SECURE: false +CSRF_TRUSTED_ORIGINS: [] +DASHBOARD_COURSE_LIMIT: null +DATABASES: + default: + ATOMIC_REQUESTS: true + CONN_MAX_AGE: 0 + ENGINE: django.db.backends.mysql + HOST: edx.devstack.mysql + NAME: edxapp + OPTIONS: {} + PASSWORD: password + PORT: '3306' + USER: edxapp001 + read_replica: + CONN_MAX_AGE: 0 + ENGINE: django.db.backends.mysql + HOST: edx.devstack.mysql + NAME: edxapp + OPTIONS: {} + PASSWORD: password + PORT: '3306' + USER: edxapp001 + student_module_history: + CONN_MAX_AGE: 0 + ENGINE: django.db.backends.mysql + HOST: edx.devstack.mysql + NAME: edxapp_csmh + OPTIONS: {} + PASSWORD: password + PORT: '3306' + USER: edxapp001 +DATA_DIR: /edx/var/edxapp +DEFAULT_COURSE_VISIBILITY_IN_CATALOG: both +DEFAULT_FEEDBACK_EMAIL: feedback@example.com +DEFAULT_FILE_STORAGE: django.core.files.storage.FileSystemStorage +DEFAULT_FROM_EMAIL: registration@example.com +DEFAULT_JWT_ISSUER: + AUDIENCE: lms-key + ISSUER: http://edx.devstack.lms:18000/oauth2 + SECRET_KEY: lms-secret +DEFAULT_MOBILE_AVAILABLE: false +DEFAULT_SITE_THEME: '' +DEPRECATED_ADVANCED_COMPONENT_TYPES: [] +DJFS: + directory_root: /edx/var/edxapp/django-pyfs/static/django-pyfs + type: osfs + url_root: /static/django-pyfs +DOC_STORE_CONFIG: + authsource: '' + collection: modulestore + connectTimeoutMS: 2000 + db: edxapp + host: + - edx.devstack.mongo + password: password + port: 27017 + read_preference: SECONDARY_PREFERRED + replicaSet: '' + socketTimeoutMS: 3000 + ssl: false + user: edxapp +ECOMMERCE_API_SIGNING_KEY: lms-secret +ECOMMERCE_API_URL: http://localhost:8002/api/v2 +ECOMMERCE_PUBLIC_URL_ROOT: http://localhost:8002 +EDXMKTG_USER_INFO_COOKIE_NAME: edx-user-info +EDXNOTES_INTERNAL_API: http://edx.devstack.edx_notes_api:18120/api/v1 +EDXNOTES_PUBLIC_API: http://localhost:18120/api/v1 +EDX_API_KEY: PUT_YOUR_API_KEY_HERE +EDX_PLATFORM_REVISION: master +ELASTIC_SEARCH_CONFIG: +- host: edx.devstack.elasticsearch + port: 9200 + use_ssl: false +EMAIL_BACKEND: django.core.mail.backends.smtp.EmailBackend +EMAIL_HOST: localhost +EMAIL_HOST_PASSWORD: '' +EMAIL_HOST_USER: '' +EMAIL_PORT: 25 +EMAIL_USE_TLS: false +ENABLE_COMPREHENSIVE_THEMING: false +ENTERPRISE_API_URL: http://edx.devstack.lms:18000/enterprise/api/v1 +ENTERPRISE_COURSE_ENROLLMENT_AUDIT_MODES: +- audit +- honor +ENTERPRISE_CUSTOMER_SUCCESS_EMAIL: customersuccess@edx.org +ENTERPRISE_ENROLLMENT_API_URL: http://edx.devstack.lms:18000/api/enrollment/v1/ +ENTERPRISE_INTEGRATIONS_EMAIL: enterprise-integrations@edx.org +ENTERPRISE_MARKETING_FOOTER_QUERY_PARAMS: {} +ENTERPRISE_SERVICE_WORKER_USERNAME: enterprise_worker +ENTERPRISE_SUPPORT_URL: '' +ENTERPRISE_TAGLINE: '' +EVENT_TRACKING_SEGMENTIO_EMIT_WHITELIST: [] +EXTRA_MIDDLEWARE_CLASSES: [] +FACEBOOK_API_VERSION: v2.1 +FACEBOOK_APP_ID: FACEBOOK_APP_ID +FACEBOOK_APP_SECRET: FACEBOOK_APP_SECRET +FEATURES: + AUTH_USE_OPENID_PROVIDER: true + AUTOMATIC_AUTH_FOR_TESTING: false + CUSTOM_COURSES_EDX: false + ENABLE_COMBINED_LOGIN_REGISTRATION: true + ENABLE_CORS_HEADERS: false + ENABLE_COUNTRY_ACCESS: false + ENABLE_CREDIT_API: false + ENABLE_CREDIT_ELIGIBILITY: false + ENABLE_CROSS_DOMAIN_CSRF_COOKIE: false + ENABLE_CSMH_EXTENDED: true + ENABLE_DISCUSSION_HOME_PANEL: true + ENABLE_DISCUSSION_SERVICE: true + ENABLE_EDXNOTES: true + ENABLE_ENROLLMENT_RESET: false + ENABLE_GRADE_DOWNLOADS: true + ENABLE_INSTRUCTOR_ANALYTICS: false + ENABLE_MKTG_SITE: false + ENABLE_MOBILE_REST_API: false + ENABLE_OAUTH2_PROVIDER: false + ENABLE_PUBLISHER: false + ENABLE_READING_FROM_MULTIPLE_HISTORY_TABLES: true + ENABLE_SPECIAL_EXAMS: false + ENABLE_SYSADMIN_DASHBOARD: false + ENABLE_THIRD_PARTY_AUTH: true + ENABLE_VIDEO_UPLOAD_PIPELINE: false + PREVIEW_LMS_BASE: preview.localhost:18000 + SHOW_FOOTER_LANGUAGE_SELECTOR: false + SHOW_HEADER_LANGUAGE_SELECTOR: false +FEEDBACK_SUBMISSION_EMAIL: '' +FERNET_KEYS: +- DUMMY KEY CHANGE BEFORE GOING TO PRODUCTION +FILE_UPLOAD_STORAGE_BUCKET_NAME: SET-ME-PLEASE (ex. bucket-name) +FILE_UPLOAD_STORAGE_PREFIX: submissions_attachments +FINANCIAL_REPORTS: + BUCKET: null + ROOT_PATH: sandbox + STORAGE_TYPE: localfs +FOOTER_ORGANIZATION_IMAGE: images/logo.png +GITHUB_REPO_ROOT: /edx/var/edxapp/data +GIT_REPO_DIR: /edx/var/edxapp/course_repos +GOOGLE_ANALYTICS_ACCOUNT: null +GOOGLE_ANALYTICS_LINKEDIN: '' +GOOGLE_ANALYTICS_TRACKING_ID: '' +GOOGLE_SITE_VERIFICATION_ID: '' +GRADES_DOWNLOAD: + BUCKET: '' + ROOT_PATH: '' + STORAGE_CLASS: django.core.files.storage.FileSystemStorage + STORAGE_KWARGS: + location: /tmp/edx-s3/grades + STORAGE_TYPE: '' +HELP_TOKENS_BOOKS: + course_author: http://edx.readthedocs.io/projects/open-edx-building-and-running-a-course + learner: http://edx.readthedocs.io/projects/open-edx-learner-guide +HTTPS: 'on' +ICP_LICENSE: null +ICP_LICENSE_INFO: {} +IDA_LOGOUT_URI_LIST: [] +ID_VERIFICATION_SUPPORT_LINK: '' +JWT_AUTH: + JWT_AUDIENCE: lms-key + JWT_AUTH_COOKIE_HEADER_PAYLOAD: edx-jwt-cookie-header-payload + JWT_AUTH_COOKIE_SIGNATURE: edx-jwt-cookie-signature + JWT_AUTH_REFRESH_COOKIE: edx-jwt-refresh-cookie + JWT_ISSUER: http://edx.devstack.lms:18000/oauth2 + JWT_ISSUERS: + - AUDIENCE: lms-key + ISSUER: http://edx.devstack.lms:18000/oauth2 + SECRET_KEY: lms-secret + JWT_PRIVATE_SIGNING_JWK: None + JWT_PUBLIC_SIGNING_JWK_SET: '' + JWT_SECRET_KEY: lms-secret + JWT_SIGNING_ALGORITHM: null +JWT_EXPIRATION: 30 +JWT_ISSUER: http://edx.devstack.lms:18000/oauth2 +JWT_PRIVATE_SIGNING_KEY: null +LANGUAGE_CODE: en +LANGUAGE_COOKIE: openedx-language-preference +LEARNER_PORTAL_URL_ROOT: https://learner-portal-edx.devstack.lms:18000 +LEARNING_MICROFRONTEND_URL: null +LMS_BASE: edx.devstack.lms:18000 +LMS_INTERNAL_ROOT_URL: http://edx.devstack.lms:18000 +LMS_ROOT_URL: http://edx.devstack.lms:18000 +LOCAL_LOGLEVEL: INFO +LOGGING_ENV: sandbox +LOGIN_REDIRECT_WHITELIST: [] +LOG_DIR: /edx/var/log/edx +LTI_AGGREGATE_SCORE_PASSBACK_DELAY: 900 +LTI_USER_EMAIL_DOMAIN: lti.example.com +MAILCHIMP_NEW_USER_LIST_ID: null +MAINTENANCE_BANNER_TEXT: Sample banner message +MEDIA_ROOT: /edx/var/edxapp/media/ +MEDIA_URL: /media/ +MICROSITE_CONFIGURATION: {} +MICROSITE_ROOT_DIR: /edx/app/edxapp/edx-microsite +MKTG_URLS: {} +MKTG_URL_LINK_MAP: {} +MOBILE_STORE_URLS: {} +MODULESTORE: + default: + ENGINE: xmodule.modulestore.mixed.MixedModuleStore + OPTIONS: + mappings: {} + stores: + - DOC_STORE_CONFIG: + authsource: '' + collection: modulestore + connectTimeoutMS: 2000 + db: edxapp + host: + - edx.devstack.mongo + password: password + port: 27017 + read_preference: SECONDARY_PREFERRED + replicaSet: '' + socketTimeoutMS: 3000 + ssl: false + user: edxapp + ENGINE: xmodule.modulestore.split_mongo.split_draft.DraftVersioningModuleStore + NAME: split + OPTIONS: + default_class: xmodule.hidden_module.HiddenDescriptor + fs_root: /edx/var/edxapp/data + render_template: edxmako.shortcuts.render_to_string + - DOC_STORE_CONFIG: + authsource: '' + collection: modulestore + connectTimeoutMS: 2000 + db: edxapp + host: + - edx.devstack.mongo + password: password + port: 27017 + read_preference: PRIMARY + replicaSet: '' + socketTimeoutMS: 3000 + ssl: false + user: edxapp + ENGINE: xmodule.modulestore.mongo.DraftMongoModuleStore + NAME: draft + OPTIONS: + default_class: xmodule.hidden_module.HiddenDescriptor + fs_root: /edx/var/edxapp/data + render_template: edxmako.shortcuts.render_to_string +OAUTH_DELETE_EXPIRED: true +OAUTH_ENFORCE_SECURE: false +OAUTH_EXPIRE_CONFIDENTIAL_CLIENT_DAYS: 365 +OAUTH_EXPIRE_PUBLIC_CLIENT_DAYS: 30 +OPTIMIZELY_PROJECT_ID: null +ORA2_FILE_PREFIX: default_env-default_deployment/ora2 +ORDER_HISTORY_MICROFRONTEND_URL: null +PAID_COURSE_REGISTRATION_CURRENCY: +- usd +- $ +PARENTAL_CONSENT_AGE_LIMIT: 13 +PARTNER_SUPPORT_EMAIL: '' +PASSWORD_POLICY_COMPLIANCE_ROLLOUT_CONFIG: + ENFORCE_COMPLIANCE_ON_LOGIN: false +PASSWORD_RESET_SUPPORT_LINK: '' +PAYMENT_SUPPORT_EMAIL: billing@example.com +PDF_RECEIPT_BILLING_ADDRESS: 'Enter your receipt billing + + address here. + + ' +PDF_RECEIPT_COBRAND_LOGO_PATH: '' +PDF_RECEIPT_DISCLAIMER_TEXT: 'ENTER YOUR RECEIPT DISCLAIMER TEXT HERE. + + ' +PDF_RECEIPT_FOOTER_TEXT: 'Enter your receipt footer text here. + + ' +PDF_RECEIPT_LOGO_PATH: '' +PDF_RECEIPT_TAX_ID: 00-0000000 +PDF_RECEIPT_TAX_ID_LABEL: fake Tax ID +PDF_RECEIPT_TERMS_AND_CONDITIONS: 'Enter your receipt terms and conditions here. + + ' +PLATFORM_DESCRIPTION: Your Platform Description Here +PLATFORM_FACEBOOK_ACCOUNT: http://www.facebook.com/YourPlatformFacebookAccount +PLATFORM_NAME: Your Platform Name Here +PLATFORM_TWITTER_ACCOUNT: '@YourPlatformTwitterAccount' +POLICY_CHANGE_GRADES_ROUTING_KEY: edx.lms.core.default +PRESS_EMAIL: press@example.com +PROCTORING_BACKENDS: + DEFAULT: 'null' + 'null': {} +PROCTORING_SETTINGS: {} +PROFILE_IMAGE_BACKEND: + class: openedx.core.storage.OverwriteStorage + options: + base_url: /media/profile-images/ + location: /edx/var/edxapp/media/profile-images/ +PROFILE_IMAGE_MAX_BYTES: 1048576 +PROFILE_IMAGE_MIN_BYTES: 100 +PROFILE_IMAGE_SECRET_KEY: placeholder_secret_key +PROFILE_IMAGE_SIZES_MAP: + full: 500 + large: 120 + medium: 50 + small: 30 +PROFILE_MICROFRONTEND_URL: null +PROGRAM_CERTIFICATES_ROUTING_KEY: edx.lms.core.default +PROGRAM_MANAGER_MICROFRONTEND_URL: null +RECALCULATE_GRADES_ROUTING_KEY: edx.lms.core.default +REGISTRATION_EXTRA_FIELDS: + city: hidden + confirm_email: hidden + country: required + gender: optional + goals: optional + honor_code: required + level_of_education: optional + mailing_address: hidden + terms_of_service: hidden + year_of_birth: optional +RETIRED_EMAIL_DOMAIN: retired.invalid +RETIRED_EMAIL_PREFIX: retired__user_ +RETIRED_USERNAME_PREFIX: retired__user_ +RETIRED_USER_SALTS: +- OVERRIDE ME WITH A RANDOM VALUE +- ROTATE SALTS BY APPENDING NEW VALUES +RETIREMENT_SERVICE_WORKER_USERNAME: retirement_worker +RETIREMENT_STATES: +- PENDING +- ERRORED +- ABORTED +- COMPLETE +SECRET_KEY: DUMMY KEY ONLY FOR TO DEVSTACK +SEGMENT_KEY: null +SERVER_EMAIL: devops@example.com +SESSION_COOKIE_DOMAIN: '' +SESSION_COOKIE_NAME: sessionid +SESSION_COOKIE_SECURE: false +SESSION_SAVE_EVERY_REQUEST: false +SITE_NAME: localhost +SOCIAL_AUTH_OAUTH_SECRETS: '' +SOCIAL_AUTH_SAML_SP_PRIVATE_KEY: '' +SOCIAL_AUTH_SAML_SP_PRIVATE_KEY_DICT: {} +SOCIAL_AUTH_SAML_SP_PUBLIC_CERT: '' +SOCIAL_AUTH_SAML_SP_PUBLIC_CERT_DICT: {} +SOCIAL_MEDIA_FOOTER_URLS: {} +SOCIAL_SHARING_SETTINGS: + CERTIFICATE_FACEBOOK: false + CERTIFICATE_TWITTER: false + CUSTOM_COURSE_URLS: false + DASHBOARD_FACEBOOK: false + DASHBOARD_TWITTER: false +STATIC_ROOT_BASE: /edx/var/edxapp/staticfiles +STATIC_URL_BASE: /static/ +STUDIO_NAME: Studio +STUDIO_SHORT_NAME: Studio +SUPPORT_SITE_LINK: '' +SWIFT_AUTH_URL: null +SWIFT_AUTH_VERSION: null +SWIFT_KEY: null +SWIFT_REGION_NAME: null +SWIFT_TEMP_URL_DURATION: 1800 +SWIFT_TEMP_URL_KEY: null +SWIFT_TENANT_ID: null +SWIFT_TENANT_NAME: null +SWIFT_USERNAME: null +SWIFT_USE_TEMP_URLS: false +SYSLOG_SERVER: '' +SYSTEM_WIDE_ROLE_CLASSES: [] +TECH_SUPPORT_EMAIL: technical@example.com +TIME_ZONE: America/New_York +TRACKING_SEGMENTIO_WEBHOOK_SECRET: '' +UNIVERSITY_EMAIL: university@example.com +USERNAME_REPLACEMENT_WORKER: OVERRIDE THIS WITH A VALID USERNAME +VERIFY_STUDENT: + DAYS_GOOD_FOR: 365 + EXPIRING_SOON_WINDOW: 28 +VIDEO_CDN_URL: + EXAMPLE_COUNTRY_CODE: http://example.com/edx/video?s3_url= +VIDEO_IMAGE_MAX_AGE: 31536000 +VIDEO_IMAGE_SETTINGS: + DIRECTORY_PREFIX: video-images/ + STORAGE_KWARGS: + base_url: /media/ + location: edx/var/edxapp/media/ + VIDEO_IMAGE_MAX_BYTES: 2097152 + VIDEO_IMAGE_MIN_BYTES: 2048 +VIDEO_TRANSCRIPTS_MAX_AGE: 31536000 +VIDEO_TRANSCRIPTS_SETTINGS: + DIRECTORY_PREFIX: video-transcripts/ + STORAGE_KWARGS: + base_url: /media/ + location: edx/var/edxapp/media/ + VIDEO_TRANSCRIPTS_MAX_BYTES: 3145728 +VIDEO_UPLOAD_PIPELINE: + BUCKET: '' + ROOT_PATH: '' +WIKI_ENABLED: true +WRITABLE_GRADEBOOK_URL: null +XBLOCK_FS_STORAGE_BUCKET: null +XBLOCK_FS_STORAGE_PREFIX: null +XBLOCK_SETTINGS: {} +XQUEUE_INTERFACE: + basic_auth: + - edx + - edx + django_auth: + password: password + username: lms + url: http://edx.devstack.xqueue:18040 +X_FRAME_OPTIONS: DENY +YOUTUBE_API_KEY: PUT_YOUR_API_KEY_HERE +ZENDESK_API_KEY: '' +ZENDESK_CUSTOM_FIELDS: {} +ZENDESK_GROUP_ID_MAPPING: {} +ZENDESK_OAUTH_ACCESS_TOKEN: '' +ZENDESK_URL: '' +ZENDESK_USER: '' + diff --git a/lms/docker_lms_gunicorn.py b/lms/docker_lms_gunicorn.py index aa7a41321f..163e13be33 100644 --- a/lms/docker_lms_gunicorn.py +++ b/lms/docker_lms_gunicorn.py @@ -1,7 +1,5 @@ """ gunicorn configuration file: http://docs.gunicorn.org/en/stable/configure.html - -This file is created and updated by ansible, edit at your peril """ preload_app = False diff --git a/lms/envs/devstack_decentralized.py b/lms/envs/devstack_decentralized.py new file mode 100644 index 0000000000..df6ac65428 --- /dev/null +++ b/lms/envs/devstack_decentralized.py @@ -0,0 +1,379 @@ +""" +Settings file for decentralized devstack +""" + +# Silence noisy logs +import logging +from os.path import abspath, dirname, join + +from corsheaders.defaults import default_headers as corsheaders_default_headers + +# pylint: enable=unicode-format-string +##################################################################### +from edx_django_utils.plugins import add_plugins + +from openedx.core.djangoapps.plugins.constants import ProjectType, SettingsType + +from .production import * # pylint: disable=wildcard-import, unused-wildcard-import + +# Don't use S3 in devstack, fall back to filesystem +del DEFAULT_FILE_STORAGE +MEDIA_ROOT = "/edx/var/edxapp/uploads" +ORA2_FILEUPLOAD_BACKEND = 'django' + + +DEBUG = True +USE_I18N = True +DEFAULT_TEMPLATE_ENGINE['OPTIONS']['debug'] = True +LMS_BASE = 'localhost:18000' +CMS_BASE = 'localhost:18010' +SITE_NAME = LMS_BASE + +# By default don't use a worker, execute tasks as if they were local functions +CELERY_ALWAYS_EAGER = True +HTTPS = 'off' + +LMS_ROOT_URL = 'http://{}'.format(LMS_BASE) +LMS_INTERNAL_ROOT_URL = LMS_ROOT_URL +ENTERPRISE_API_URL = '{}/enterprise/api/v1/'.format(LMS_INTERNAL_ROOT_URL) +IDA_LOGOUT_URI_LIST = [ + 'http://localhost:18130/logout/', # ecommerce + 'http://localhost:18150/logout/', # credentials + 'http://localhost:18381/logout/', # discovery +] + +################################ LOGGERS ###################################### + +LOG_OVERRIDES = [ + ('track.contexts', logging.CRITICAL), + ('track.middleware', logging.CRITICAL), + ('lms.djangoapps.discussion.django_comment_client.utils', logging.CRITICAL), +] +for log_name, log_level in LOG_OVERRIDES: + logging.getLogger(log_name).setLevel(log_level) + +# Docker does not support the syslog socket at /dev/log. Rely on the console. +LOGGING['handlers']['local'] = LOGGING['handlers']['tracking'] = { + 'class': 'logging.NullHandler', +} + +LOGGING['loggers']['tracking']['handlers'] = ['console'] + +################################ EMAIL ######################################## + +EMAIL_BACKEND = 'django.core.mail.backends.filebased.EmailBackend' +EMAIL_FILE_PATH = '/edx/src/ace_messages/' + +############################ PYFS XBLOCKS SERVICE ############################# +# Set configuration for Django pyfilesystem + +DJFS = { + 'type': 'osfs', + 'directory_root': 'lms/static/djpyfs', + 'url_root': '/static/djpyfs', +} + + +def should_show_debug_toolbar(request): + return False + +########################### PIPELINE ################################# + +PIPELINE['PIPELINE_ENABLED'] = False +STATICFILES_STORAGE = 'openedx.core.storage.DevelopmentStorage' + +# Revert to the default set of finders as we don't want the production pipeline +STATICFILES_FINDERS = [ + 'openedx.core.djangoapps.theming.finders.ThemeFilesFinder', + 'django.contrib.staticfiles.finders.FileSystemFinder', + 'django.contrib.staticfiles.finders.AppDirectoriesFinder', +] + +# Disable JavaScript compression in development +PIPELINE['JS_COMPRESSOR'] = None + +# Whether to run django-require in debug mode. +REQUIRE_DEBUG = DEBUG + +PIPELINE['SASS_ARGUMENTS'] = '--debug-info' + +# Load development webpack donfiguration +WEBPACK_CONFIG_PATH = 'webpack.dev.config.js' + +########################### VERIFIED CERTIFICATES ################################# + +FEATURES['AUTOMATIC_VERIFY_STUDENT_IDENTITY_FOR_TESTING'] = True +FEATURES['ENABLE_PAYMENT_FAKE'] = True + +CC_PROCESSOR_NAME = 'CyberSource2' +CC_PROCESSOR = { + 'CyberSource2': { + "PURCHASE_ENDPOINT": '/shoppingcart/payment_fake/', + "SECRET_KEY": 'abcd123', + "ACCESS_KEY": 'abcd123', + "PROFILE_ID": 'edx', + } +} + +########################### External REST APIs ################################# +FEATURES['ENABLE_OAUTH2_PROVIDER'] = True +FEATURES['ENABLE_MOBILE_REST_API'] = True +FEATURES['ENABLE_VIDEO_ABSTRACTION_LAYER_API'] = True + +########################## SECURITY ####################### +FEATURES['ENABLE_MAX_FAILED_LOGIN_ATTEMPTS'] = False +FEATURES['SQUELCH_PII_IN_LOGS'] = False +FEATURES['PREVENT_CONCURRENT_LOGINS'] = False + +########################### Milestones ################################# +FEATURES['MILESTONES_APP'] = True + +########################### Milestones ################################# +FEATURES['ORGANIZATIONS_APP'] = True + +########################### Entrance Exams ################################# +FEATURES['ENTRANCE_EXAMS'] = True + +################################ COURSE LICENSES ################################ +FEATURES['LICENSING'] = True + + +########################## Courseware Search ####################### +FEATURES['ENABLE_COURSEWARE_SEARCH'] = False +FEATURES['ENABLE_COURSEWARE_SEARCH_FOR_COURSE_STAFF'] = True +SEARCH_ENGINE = 'search.elastic.ElasticSearchEngine' + + +########################## Dashboard Search ####################### +FEATURES['ENABLE_DASHBOARD_SEARCH'] = False + + +########################## Certificates Web/HTML View ####################### +FEATURES['CERTIFICATES_HTML_VIEW'] = True + + +########################## Course Discovery ####################### +LANGUAGE_MAP = {'terms': {lang: display for lang, display in ALL_LANGUAGES}, 'name': 'Language'} +COURSE_DISCOVERY_MEANINGS = { + 'org': { + 'name': 'Organization', + }, + 'modes': { + 'name': 'Course Type', + 'terms': { + 'honor': 'Honor', + 'verified': 'Verified', + }, + }, + 'language': LANGUAGE_MAP, +} + +FEATURES['ENABLE_COURSE_DISCOVERY'] = False +# Setting for overriding default filtering facets for Course discovery +# COURSE_DISCOVERY_FILTERS = ["org", "language", "modes"] +FEATURES['COURSES_ARE_BROWSEABLE'] = True +HOMEPAGE_COURSE_MAX = 9 + +# Software secure fake page feature flag +FEATURES['ENABLE_SOFTWARE_SECURE_FAKE'] = False + +# Setting for the testing of Software Secure Result Callback +VERIFY_STUDENT["SOFTWARE_SECURE"] = { + "API_ACCESS_KEY": "BBBBBBBBBBBBBBBBBBBB", + "API_SECRET_KEY": "CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC", +} +DISABLE_ACCOUNT_ACTIVATION_REQUIREMENT_SWITCH = "verify_student_disable_account_activation_requirement" + +# Skip enrollment start date filtering +SEARCH_SKIP_ENROLLMENT_START_DATE_FILTERING = True + + +########################## Shopping cart ########################## +FEATURES['ENABLE_SHOPPING_CART'] = True +FEATURES['STORE_BILLING_INFO'] = True +FEATURES['ENABLE_PAID_COURSE_REGISTRATION'] = True +FEATURES['ENABLE_COSMETIC_DISPLAY_PRICE'] = True + +######################### Program Enrollments ##################### +FEATURES['ENABLE_ENROLLMENT_RESET'] = True + +######################### New Courseware MFE ##################### +FEATURES['ENABLE_COURSEWARE_MICROFRONTEND'] = True + +########################## Third Party Auth ####################### + +if FEATURES.get('ENABLE_THIRD_PARTY_AUTH') and 'third_party_auth.dummy.DummyBackend' not in AUTHENTICATION_BACKENDS: + AUTHENTICATION_BACKENDS = ['third_party_auth.dummy.DummyBackend'] + list(AUTHENTICATION_BACKENDS) + +############## ECOMMERCE API CONFIGURATION SETTINGS ############### +ECOMMERCE_PUBLIC_URL_ROOT = 'http://localhost:18130' +ECOMMERCE_API_URL = 'http://edx.devstack.ecommerce:18130/api/v2' + +############## Comments CONFIGURATION SETTINGS ############### +COMMENTS_SERVICE_URL = 'http://edx.devstack.forum:4567' + +############## Credentials CONFIGURATION SETTINGS ############### +CREDENTIALS_INTERNAL_SERVICE_URL = 'http://edx.devstack.credentials:18150' +CREDENTIALS_PUBLIC_SERVICE_URL = 'http://localhost:18150' + +############################### BLOCKSTORE ##################################### +BLOCKSTORE_API_URL = "http://edx.devstack.blockstore:18250/api/v1/" + +###################### Cross-domain requests ###################### +FEATURES['ENABLE_CORS_HEADERS'] = True +CORS_ALLOW_CREDENTIALS = True +CORS_ORIGIN_WHITELIST = () +CORS_ORIGIN_ALLOW_ALL = True +CORS_ALLOW_HEADERS = corsheaders_default_headers + ( + 'use-jwt-cookie', +) + +LOGIN_REDIRECT_WHITELIST = [CMS_BASE] + +###################### JWTs ###################### +JWT_AUTH.update({ + 'JWT_AUDIENCE': 'lms-key', + 'JWT_ISSUER': '{}/oauth2'.format(LMS_ROOT_URL), + 'JWT_ISSUERS': [{ + 'AUDIENCE': 'lms-key', + 'ISSUER': '{}/oauth2'.format(LMS_ROOT_URL), + 'SECRET_KEY': 'lms-secret', + }], + 'JWT_SECRET_KEY': 'lms-secret', + 'JWT_SIGNING_ALGORITHM': 'RS512', + 'JWT_PRIVATE_SIGNING_JWK': ( + '{"e": "AQAB", "d": "RQ6k4NpRU3RB2lhwCbQ452W86bMMQiPsa7EJiFJUg-qBJthN0FMNQVbArtrCQ0xA1BdnQHThFiUnHcXfsTZUwmwvTu' + 'iqEGR_MI6aI7h5D8vRj_5x-pxOz-0MCB8TY8dcuK9FkljmgtYvV9flVzCk_uUb3ZJIBVyIW8En7n7nV7JXpS9zey1yVLld2AbRG6W5--Pgqr9J' + 'CI5-bLdc2otCLuen2sKyuUDHO5NIj30qGTaKUL-OW_PgVmxrwKwccF3w5uGNEvMQ-IcicosCOvzBwdIm1uhdm9rnHU1-fXz8VLRHNhGVv7z6mo' + 'ghjNI0_u4smhUkEsYeshPv7RQEWTdkOQ", "n": "smKFSYowG6nNUAdeqH1jQQnH1PmIHphzBmwJ5vRf1vu48BUI5VcVtUWIPqzRK_LDSlZYh' + '9D0YFL0ZTxIrlb6Tn3Xz7pYvpIAeYuQv3_H5p8tbz7Fb8r63c1828wXPITVTv8f7oxx5W3lFFgpFAyYMmROC4Ee9qG5T38LFe8_oAuFCEntimW' + 'xN9F3P-FJQy43TL7wG54WodgiM0EgzkeLr5K6cDnyckWjTuZbWI-4ffcTgTZsL_Kq1owa_J2ngEfxMCObnzGy5ZLcTUomo4rZLjghVpq6KZxfS' + '6I1Vz79ZsMVUWEdXOYePCKKsrQG20ogQEkmTf9FT_SouC6jPcHLXw", "q": "7KWj7l-ZkfCElyfvwsl7kiosvi-ppOO7Imsv90cribf88Dex' + 'cO67xdMPesjM9Nh5X209IT-TzbsOtVTXSQyEsy42NY72WETnd1_nAGLAmfxGdo8VV4ZDnRsA8N8POnWjRDwYlVBUEEeuT_MtMWzwIKU94bzkWV' + 'nHCY5vbhBYLeM", "p": "wPkfnjavNV1Hqb5Qqj2crBS9HQS6GDQIZ7WF9hlBb2ofDNe2K2dunddFqCOdvLXr7ydRcK51ZwSeHjcjgD1aJkHA' + '9i1zqyboxgd0uAbxVDo6ohnlVqYLtap2tXXcavKm4C9MTpob_rk6FBfEuq4uSsuxFvCER4yG3CYBBa4gZVU", "kid": "devstack_key", "' + 'kty": "RSA"}' + ), + 'JWT_PUBLIC_SIGNING_JWK_SET': ( + '{"keys": [{"kid": "devstack_key", "e": "AQAB", "kty": "RSA", "n": "smKFSYowG6nNUAdeqH1jQQnH1PmIHphzBmwJ5vRf1vu' + '48BUI5VcVtUWIPqzRK_LDSlZYh9D0YFL0ZTxIrlb6Tn3Xz7pYvpIAeYuQv3_H5p8tbz7Fb8r63c1828wXPITVTv8f7oxx5W3lFFgpFAyYMmROC' + '4Ee9qG5T38LFe8_oAuFCEntimWxN9F3P-FJQy43TL7wG54WodgiM0EgzkeLr5K6cDnyckWjTuZbWI-4ffcTgTZsL_Kq1owa_J2ngEfxMCObnzG' + 'y5ZLcTUomo4rZLjghVpq6KZxfS6I1Vz79ZsMVUWEdXOYePCKKsrQG20ogQEkmTf9FT_SouC6jPcHLXw"}]}' + ), +}) +add_plugins(__name__, ProjectType.LMS, SettingsType.DEVSTACK) + + +######################### Django Rest Framework ######################## + +REST_FRAMEWORK['DEFAULT_RENDERER_CLASSES'] += ( + 'rest_framework.renderers.BrowsableAPIRenderer', +) + +OPENAPI_CACHE_TIMEOUT = 0 + +##################################################################### +# Lastly, run any migrations, if needed. +MODULESTORE = convert_module_store_setting_if_needed(MODULESTORE) + +SECRET_KEY = '85920908f28904ed733fe576320db18cabd7b6cd' + +EDXNOTES_INTERNAL_API = 'http://edx.devstack.edxnotesapi:18120/api/v1' +EDXNOTES_CLIENT_NAME = 'edx_notes_api-backend-service' + +############## Settings for Microfrontends ######################### +LEARNING_MICROFRONTEND_URL = 'http://localhost:2000' +ACCOUNT_MICROFRONTEND_URL = 'http://localhost:1997' + +############## Docker based devstack settings ####################### + +FEATURES.update({ + 'AUTOMATIC_AUTH_FOR_TESTING': True, + 'ENABLE_DISCUSSION_SERVICE': True, + 'SHOW_HEADER_LANGUAGE_SELECTOR': True, + + # Enable enterprise integration by default. + # See https://github.com/edx/edx-enterprise/blob/master/docs/development.rst for + # more background on edx-enterprise. + # Toggle this off if you don't want anything to do with enterprise in devstack. + 'ENABLE_ENTERPRISE_INTEGRATION': True, +}) + +ENABLE_MKTG_SITE = os.environ.get('ENABLE_MARKETING_SITE', False) +MARKETING_SITE_ROOT = os.environ.get('MARKETING_SITE_ROOT', 'http://localhost:8080') + +MKTG_URLS = { + 'ABOUT': '/about', + 'ACCESSIBILITY': '/accessibility', + 'AFFILIATES': '/affiliate-program', + 'BLOG': '/blog', + 'CAREERS': '/careers', + 'CONTACT': '/support/contact_us', + 'COURSES': '/course', + 'DONATE': '/donate', + 'ENTERPRISE': '/enterprise', + 'FAQ': '/student-faq', + 'HONOR': '/edx-terms-service', + 'HOW_IT_WORKS': '/how-it-works', + 'MEDIA_KIT': '/media-kit', + 'NEWS': '/news-announcements', + 'PRESS': '/press', + 'PRIVACY': '/edx-privacy-policy', + 'ROOT': MARKETING_SITE_ROOT, + 'SCHOOLS': '/schools-partners', + 'SITE_MAP': '/sitemap', + 'TRADEMARKS': '/trademarks', + 'TOS': '/edx-terms-service', + 'TOS_AND_HONOR': '/edx-terms-service', + 'WHAT_IS_VERIFIED_CERT': '/verified-certificate', +} + +ENTERPRISE_LEARNER_PORTAL_BASE_URL = 'http://localhost:8734' + +ENTERPRISE_MARKETING_FOOTER_QUERY_PARAMS = {} + +CREDENTIALS_SERVICE_USERNAME = 'credentials_worker' + +COURSE_CATALOG_URL_ROOT = 'http://edx.devstack.discovery:18381' +COURSE_CATALOG_API_URL = '{}/api/v1'.format(COURSE_CATALOG_URL_ROOT) + +SYSTEM_WIDE_ROLE_CLASSES = os.environ.get("SYSTEM_WIDE_ROLE_CLASSES", SYSTEM_WIDE_ROLE_CLASSES) +SYSTEM_WIDE_ROLE_CLASSES.append( + 'system_wide_roles.SystemWideRoleAssignment', +) + +if FEATURES.get('ENABLE_ENTERPRISE_INTEGRATION'): + SYSTEM_WIDE_ROLE_CLASSES.append( + 'enterprise.SystemWideEnterpriseUserRoleAssignment', + ) + +# List of enterprise customer uuids to exclude from transition to use of enterprise-catalog +ENTERPRISE_CUSTOMERS_EXCLUDED_FROM_CATALOG = () + +##################################################################### +# See if the developer has any local overrides. +if os.path.isfile(join(dirname(abspath(__file__)), 'private.py')): + from .private import * # pylint: disable=import-error,wildcard-import + +########################## THEMING ####################### +# If you want to enable theming in devstack, uncomment this section and add any relevant +# theme directories to COMPREHENSIVE_THEME_DIRS + +# We have to import the private method here because production.py calls +# derive_settings('lms.envs.production') which runs _make_mako_template_dirs with +# the settings from production, which doesn't include these theming settings. Thus, +# the templating engine is unable to find the themed templates because they don't exist +# in it's path. Re-calling derive_settings doesn't work because the settings was already +# changed from a function to a list, and it can't be derived again. + +# from .common import _make_mako_template_dirs +# ENABLE_COMPREHENSIVE_THEMING = True +# COMPREHENSIVE_THEME_DIRS = [ +# "/edx/app/edxapp/edx-platform/themes/" +# ] +# TEMPLATES[1]["DIRS"] = _make_mako_template_dirs +# derive_settings(__name__) + +# Uncomment the lines below if you'd like to see SQL statements in your devstack LMS log. +# LOGGING['handlers']['console']['level'] = 'DEBUG' +# LOGGING['loggers']['django.db.backends'] = {'handlers': ['console'], 'level': 'DEBUG', 'propagate': False}