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}