Commit 357507f4 by John Jarvis

Merge pull request #332 from edx/jarv/nginx-refactor

Jarv/nginx refactor
parents f0968aaa a6629604
...@@ -7,8 +7,17 @@ ...@@ -7,8 +7,17 @@
migrate_db: "yes" migrate_db: "yes"
openid_workaround: True openid_workaround: True
roles: roles:
- ansible_debug
- common - common
- nginx - role: nginx
nginx_sites:
- cms
- lms
- lms-preview
- ora
- xqueue
- xserver
#- discern
- edxlocal - edxlocal
- edxapp - edxapp
- { role: 'rabbitmq', rabbitmq_ip: '127.0.0.1' } - { role: 'rabbitmq', rabbitmq_ip: '127.0.0.1' }
...@@ -27,3 +36,4 @@ ...@@ -27,3 +36,4 @@
- { role: "xqueue", update_users: True } - { role: "xqueue", update_users: True }
- xserver - xserver
- ora - ora
#- discern
...@@ -16,7 +16,11 @@ ...@@ -16,7 +16,11 @@
roles: roles:
- common - common
- datadog - datadog
- nginx - role: nginx
nginx_sites:
- lms
- cms
- lms-preview
- role: 'edxapp' - role: 'edxapp'
EDXAPP_LMS_NGINX_PORT: 80 EDXAPP_LMS_NGINX_PORT: 80
EDXAPP_CMS_NGINX_PORT: 80 EDXAPP_CMS_NGINX_PORT: 80
...@@ -31,7 +35,11 @@ ...@@ -31,7 +35,11 @@
roles: roles:
- common - common
- datadog - datadog
- nginx - role: nginx
nginx_sites:
- lms
- cms
- lms-preview
- role: 'edxapp' - role: 'edxapp'
edxapp_lms_env: 'lms.envs.load_test' edxapp_lms_env: 'lms.envs.load_test'
celery_worker: True celery_worker: True
......
...@@ -8,7 +8,11 @@ ...@@ -8,7 +8,11 @@
roles: roles:
- common - common
- datadog - datadog
- nginx - role: nginx
nginx_sites:
- lms
- cms
- lms-preview
- role: 'edxapp' - role: 'edxapp'
edxapp_lms_env: 'lms.envs.load_test' edxapp_lms_env: 'lms.envs.load_test'
edx_platform_commit: 'release' edx_platform_commit: 'release'
...@@ -22,7 +26,11 @@ ...@@ -22,7 +26,11 @@
roles: roles:
- common - common
- datadog - datadog
- nginx - role: nginx
nginx_sites:
- lms
- cms
- lms-preview
- role: 'edxapp' - role: 'edxapp'
edxapp_lms_env: 'lms.envs.load_test' edxapp_lms_env: 'lms.envs.load_test'
celery_worker: True celery_worker: True
...@@ -35,7 +43,9 @@ ...@@ -35,7 +43,9 @@
- "{{ secure_dir }}/vars/users.yml" - "{{ secure_dir }}/vars/users.yml"
roles: roles:
- common - common
- nginx - role: nginx
nginx_sites:
- xserver
- xserver - xserver
- splunkforwarder - splunkforwarder
- hosts: tag_aws_cloudformation_stack-name_feanilsandbox:&tag_group_rabbitmq - hosts: tag_aws_cloudformation_stack-name_feanilsandbox:&tag_group_rabbitmq
...@@ -55,6 +65,8 @@ ...@@ -55,6 +65,8 @@
- "{{ secure_dir }}/vars/users.yml" - "{{ secure_dir }}/vars/users.yml"
roles: roles:
- common - common
- nginx - role: nginx
nginx_sites:
- xqueue
- xqueue - xqueue
- splunkforwarder - splunkforwarder
...@@ -13,7 +13,11 @@ ...@@ -13,7 +13,11 @@
mysql5_workaround: True mysql5_workaround: True
roles: roles:
- common - common
- nginx - role: nginx
nginx_sites:
- lms
- cms
- lms-preview
- edxlocal - edxlocal
- edxapp - edxapp
- rabbitmq - rabbitmq
......
...@@ -24,7 +24,7 @@ ...@@ -24,7 +24,7 @@
secure_dir: '../../../edx-secret/ansible' secure_dir: '../../../edx-secret/ansible'
# this indicates the path to site-specific (with precedence) # this indicates the path to site-specific (with precedence)
# things like nginx template files # things like nginx template files
local_dir: '{{ secure_dir }}/local' local_dir: '../../../../../../edx-secret/ansible/local'
not_prod: true not_prod: true
vars_files: vars_files:
- "{{ secure_dir }}/vars/edxapp_cme_vars.yml" - "{{ secure_dir }}/vars/edxapp_cme_vars.yml"
...@@ -32,7 +32,12 @@ ...@@ -32,7 +32,12 @@
- "{{ secure_dir }}/vars/edxapp_prod_users.yml" - "{{ secure_dir }}/vars/edxapp_prod_users.yml"
roles: roles:
- common - common
- {'role': 'nginx', 'nginx_conf': true} - role: nginx
nginx_conf: true
nginx_sites:
- lms
- cms
- lms-preview
- {'role': 'edxapp', 'openid_workaround': true, 'template_subdir': 'cme'} - {'role': 'edxapp', 'openid_workaround': true, 'template_subdir': 'cme'}
# run this role last # run this role last
# - in_production # - in_production
...@@ -15,7 +15,11 @@ ...@@ -15,7 +15,11 @@
state: 'absent' state: 'absent'
roles: roles:
- common - common
- nginx - role: nginx
nginx_sites:
- lms
- cms
- lms-preview
- edxapp - edxapp
- ruby - ruby
post_tasks: post_tasks:
......
...@@ -26,7 +26,11 @@ ...@@ -26,7 +26,11 @@
- "{{ secure_dir }}/vars/shib_prod_vars.yml" - "{{ secure_dir }}/vars/shib_prod_vars.yml"
roles: roles:
- common - common
- nginx - role: nginx
nginx_sites:
- lms
- cms
- lms-preview
- edxapp - edxapp
- apache - apache
- shibboleth - shibboleth
......
...@@ -18,5 +18,7 @@ ...@@ -18,5 +18,7 @@
- "{{ secure_dir }}/vars/edxapp_prod_users.yml" - "{{ secure_dir }}/vars/edxapp_prod_users.yml"
roles: roles:
- common - common
- nginx - role: nginx
nginx_sites:
- ora
- ora - ora
...@@ -15,5 +15,7 @@ ...@@ -15,5 +15,7 @@
- "{{ secure_dir }}/vars/edxapp_prod_users.yml" - "{{ secure_dir }}/vars/edxapp_prod_users.yml"
roles: roles:
- common - common
- nginx - role: nginx
nginx_sites:
- xqueue
- xqueue - xqueue
...@@ -17,7 +17,11 @@ ...@@ -17,7 +17,11 @@
- "{{ secure_dir }}/vars/shib_stage_vars.yml" - "{{ secure_dir }}/vars/shib_stage_vars.yml"
roles: roles:
- common - common
- nginx - role: nginx
nginx_sites:
- lms
- cms
- lms-preview
- edxapp - edxapp
- apache - apache
- shibboleth - shibboleth
...@@ -12,7 +12,11 @@ ...@@ -12,7 +12,11 @@
#- "{{ secure_dir }}/vars/shib_stage_vars.yml" #- "{{ secure_dir }}/vars/shib_stage_vars.yml"
roles: roles:
- common - common
- nginx - role: nginx
nginx_sites:
- lms
- cms
- lms-preview
- edxapp - edxapp
- ansible_debug - ansible_debug
#- apache #- apache
......
...@@ -10,6 +10,8 @@ ...@@ -10,6 +10,8 @@
- "{{ secure_dir }}/vars/edxapp_stage_users.yml" - "{{ secure_dir }}/vars/edxapp_stage_users.yml"
roles: roles:
- common - common
- nginx - role: nginx
nginx_sites:
- ora
- ora - ora
...@@ -10,7 +10,9 @@ ...@@ -10,7 +10,9 @@
- "{{ secure_dir }}/vars/edxapp_stage_users.yml" - "{{ secure_dir }}/vars/edxapp_stage_users.yml"
roles: roles:
- common - common
- nginx - role: nginx
nginx_sites:
- xqueue
- xqueue - xqueue
#- hosts: tag_aws_cloudformation_stack-name_feanilpractice:&tag_group_edxapp #- hosts: tag_aws_cloudformation_stack-name_feanilpractice:&tag_group_edxapp
......
...@@ -14,7 +14,14 @@ ...@@ -14,7 +14,14 @@
- "{{ secure_dir }}/vars/edx_jenkins_tests.yml" - "{{ secure_dir }}/vars/edx_jenkins_tests.yml"
roles: roles:
- common - common
- nginx - role: nginx
nginx_sites:
- lms
- cms
- lms-preview
- xqueue
- xserver
- ora
- edxlocal - edxlocal
- edxapp - edxapp
- xqueue - xqueue
......
...@@ -26,7 +26,13 @@ ...@@ -26,7 +26,13 @@
- "{{ secure_dir }}/vars/edx_jenkins_tests.yml" - "{{ secure_dir }}/vars/edx_jenkins_tests.yml"
roles: roles:
- common - common
- nginx - role: nginx
nginx_sites:
- lms
- cms
- lms-preview
- xserver
- xqueue
- edxlocal - edxlocal
- edxapp - edxapp
- xqueue - xqueue
......
...@@ -23,7 +23,12 @@ ...@@ -23,7 +23,12 @@
openid_workaround: True openid_workaround: True
roles: roles:
- common - common
- nginx - role: nginx
nginx_sites:
- lms
- cms
- lms-preview
- ora
- edxlocal - edxlocal
- edxapp - edxapp
- { role: 'rabbitmq', rabbitmq_ip: '127.0.0.1' } - { role: 'rabbitmq', rabbitmq_ip: '127.0.0.1' }
......
...@@ -5,7 +5,11 @@ ...@@ -5,7 +5,11 @@
- "{{ secure_dir }}/vars/edxapp_ref_users.yml" - "{{ secure_dir }}/vars/edxapp_ref_users.yml"
roles: roles:
- common - common
- nginx - role: nginx
nginx_sites:
- lms
- cms
- lms-preview
- gunicorn - gunicorn
- edxapp - edxapp
- ruby - ruby
......
...@@ -15,7 +15,11 @@ ...@@ -15,7 +15,11 @@
state: 'absent' state: 'absent'
roles: roles:
- common - common
- nginx - role: nginx
nginx_sites:
- lms
- cms
- lms-preview
- edxapp - edxapp
- ruby - ruby
post_tasks: post_tasks:
......
...@@ -2,3 +2,9 @@ ...@@ -2,3 +2,9 @@
- name: common | restart rsyslogd - name: common | restart rsyslogd
service: name=rsyslog state=restarted service: name=rsyslog state=restarted
sudo: True sudo: True
- name: common | restart logrotate
service: name=logrotate state=restarted
sudo: True
DISCERN_NGINX_PORT: 18070
DISCERN_BASIC_AUTH: False
discern_source_repo: https://github.com/edx/discern.git discern_source_repo: https://github.com/edx/discern.git
ease_source_repo: https://github.com/edx/ease.git ease_source_repo: https://github.com/edx/ease.git
ease_dir: $app_base_dir/ease ease_dir: $app_base_dir/ease
...@@ -6,7 +9,7 @@ discern_settings: discern.aws ...@@ -6,7 +9,7 @@ discern_settings: discern.aws
nltk_data_dir: /usr/share/nltk_data nltk_data_dir: /usr/share/nltk_data
ease_branch: master ease_branch: master
discern_branch: dev discern_branch: dev
nginx_listen_port: 80 discern_gunicorn_port: 8070
gunicorn_port: 7999 discern_gunicorn_host: 127.0.0.1
discern_user: discern discern_user: discern
site_name: discern site_name: discern
...@@ -4,6 +4,3 @@ ...@@ -4,6 +4,3 @@
- name: discern | restart celery - name: discern | restart celery
service: name=celery state=restarted service: name=celery state=restarted
- name: discern | restart nginx
service: name=nginx state=restarted
...@@ -109,20 +109,3 @@ ...@@ -109,20 +109,3 @@
#Have this separate from the other three because it doesn't take the noinput flag #Have this separate from the other three because it doesn't take the noinput flag
- name: discern | django update_index for discern - name: discern | django update_index for discern
shell: ${venv_dir}/bin/python {{discern_dir}}/manage.py update_index --settings={{discern_settings}} --pythonpath={{discern_dir}} shell: ${venv_dir}/bin/python {{discern_dir}}/manage.py update_index --settings={{discern_settings}} --pythonpath={{discern_dir}}
- name: discern | create nginx directory and set perms
file: path=/etc/nginx/sites-available owner=root group=edx mode=2775 state=directory
#Install nginx sites available
#remove default link, render template, link template to sites-enabled to activate
- name: discern | Removing default nginx config
file: path=/etc/nginx/sites-enabled/default state=absent
notify: discern | restart nginx
- name: discern | render nginx sites available
template: src=nginx-discern.j2 dest=/etc/nginx/sites-available/{{ site_name }}
notify: discern | restart nginx
- name: discern | Creating nginx config link {{ site_name }}
file: src=/etc/nginx/sites-available/{{ site_name }} dest=/etc/nginx/sites-enabled/{{ site_name }} state=link owner=root group=root
notify: discern | restart nginx
...@@ -11,11 +11,12 @@ respawn limit 3 30 ...@@ -11,11 +11,12 @@ respawn limit 3 30
env PID=/var/run/gunicorn/discern.pid env PID=/var/run/gunicorn/discern.pid
env WORKERS={{ ansible_processor_cores * 2 }} env WORKERS={{ ansible_processor_cores * 2 }}
env PORT={{ gunicorn_port }} env PORT={{ discern_gunicorn_port }}
env ADDRESS={{ discern_gunicorn_host }}
env LANG=en_US.UTF-8 env LANG=en_US.UTF-8
env DJANGO_SETTINGS_MODULE={{discern_settings}} env DJANGO_SETTINGS_MODULE={{discern_settings}}
chdir {{discern_dir}} chdir {{discern_dir}}
setuid {{discern_user}} setuid {{discern_user}}
exec {{venv_dir}}/bin/gunicorn --preload -b 127.0.0.1:$PORT -w $WORKERS --timeout=30 --pythonpath={{discern_dir}} discern.wsgi exec {{venv_dir}}/bin/gunicorn --preload -b $ADDRESS:$PORT -w $WORKERS --timeout=30 --pythonpath={{discern_dir}} discern.wsgi
\ No newline at end of file
...@@ -82,6 +82,10 @@ EDXAPP_LMS_NGINX_PORT: 80 ...@@ -82,6 +82,10 @@ EDXAPP_LMS_NGINX_PORT: 80
EDXAPP_LMS_PREVIEW_NGINX_PORT: 18020 EDXAPP_LMS_PREVIEW_NGINX_PORT: 18020
EDXAPP_CMS_NGINX_PORT: 18010 EDXAPP_CMS_NGINX_PORT: 18010
EDXAPP_LMS_BASIC_AUTH: False
EDXAPP_CMS_BASIC_AUTH: False
EDXAPP_LMS_PREVIEW_BASIC_AUTH: False
#-------- Everything below this line is internal to the role ------------ #-------- Everything below this line is internal to the role ------------
...@@ -234,23 +238,19 @@ lms_preview_env_config: ...@@ -234,23 +238,19 @@ lms_preview_env_config:
edx_platform_code_dir: "{{ app_base_dir }}/edx-platform" edx_platform_code_dir: "{{ app_base_dir }}/edx-platform"
# gunicorn ports, these shouldn't need to be overridden # gunicorn ports/hosts, these shouldn't need to be overridden
edxapp_cms_app_port: 8010 edxapp_cms_gunicorn_port: 8010
edxapp_lms_app_port: 8000 edxapp_cms_gunicorn_host: 127.0.0.1
edxapp_lms_preview_app_port: 8020 edxapp_lms_gunicorn_port: 8000
edxapp_lms_gunicorn_host: 127.0.0.1
edxapp_lms_preview_gunicorn_port: 8020
edxapp_lms_preview_gunicorn_host: 127.0.0.1
edxapp_cms_app_address: 127.0.0.1
edxapp_lms_app_address: 127.0.0.1
edxapp_lms_preview_app_address: 127.0.0.1
# These vars are for creating the application json config # These vars are for creating the application json config
# files. There are two for each service that uses the # files. There are two for each service that uses the
# 'edx-platform' code. Defining them will create the upstart # 'edx-platform' code. Defining them will create the upstart
# job and nginx configuration for the corresponding service. # job. It will also enable the corresponding section in the
# It will also enable the corresponding section in the
# 'edxapp' upstart job. # 'edxapp' upstart job.
service_variants_enabled: service_variants_enabled:
......
# requires: # requires:
# - group_vars/all # - group_vars/all
# - common/tasks/main.yml # - common/tasks/main.yml
# - nginx/tasks/main.yml
--- ---
- name: create cms application config - name: create cms application config
template: src=cms.env.json.j2 dest=$app_base_dir/cms.env.json mode=640 owner=www-data group=adm template: src=cms.env.json.j2 dest=$app_base_dir/cms.env.json mode=640 owner=www-data group=adm
...@@ -19,12 +18,6 @@ ...@@ -19,12 +18,6 @@
- update - update
- deploy - deploy
- include: ../../nginx/tasks/nginx_site.yml state=link site_name=cms
when: celery_worker is not defined
- include: ../../nginx/tasks/nginx_site.yml state=link site_name=cms-backend
when: celery_worker is not defined
- name: Create CMS log target directory - name: Create CMS log target directory
file: path={{log_base_dir}}/cms state=directory owner=syslog group=syslog mode=2750 file: path={{log_base_dir}}/cms state=directory owner=syslog group=syslog mode=2750
tags: tags:
......
# requires: # requires:
# - group_vars/all # - group_vars/all
# - common/tasks/main.yml # - common/tasks/main.yml
# - nginx/tasks/main.yml
--- ---
- name: create lms application config - name: create lms application config
template: src=lms-preview.env.json.j2 dest=$app_base_dir/lms-preview.env.json mode=640 owner=www-data group=adm template: src=lms-preview.env.json.j2 dest=$app_base_dir/lms-preview.env.json mode=640 owner=www-data group=adm
...@@ -26,11 +25,5 @@ ...@@ -26,11 +25,5 @@
- update - update
- deploy - deploy
- include: ../../nginx/tasks/nginx_site.yml state=link site_name=lms-preview
when: celery_worker is not defined
- include: ../../nginx/tasks/nginx_site.yml state=link site_name=lms-preview-backend
when: celery_worker is not defined
# Creates LMS Preview upstart file # Creates LMS Preview upstart file
- include: upstart.yml basename=lms-preview - include: upstart.yml basename=lms-preview
...@@ -24,12 +24,6 @@ ...@@ -24,12 +24,6 @@
- update - update
- deploy - deploy
- include: ../../nginx/tasks/nginx_site.yml state=link site_name=lms
when: celery_worker is not defined
- include: ../../nginx/tasks/nginx_site.yml state=link site_name=lms-backend
when: celery_worker is not defined
# Creates LMS upstart file # Creates LMS upstart file
- include: upstart.yml basename=lms - include: upstart.yml basename=lms
when: celery_worker is not defined when: celery_worker is not defined
......
# requires: # requires:
# - group_vars/all # - group_vars/all
# - common/tasks/main.yml # - common/tasks/main.yml
# - nginx/tasks/main.yml
--- ---
- name: Change permissions on datadir - name: Change permissions on datadir
file: path={{ app_base_dir }}/data state=directory owner=www-data group=www-data file: path={{ app_base_dir }}/data state=directory owner=www-data group=www-data
......
...@@ -16,8 +16,8 @@ env WORKERS={{ ansible_processor|length * worker_core_mult.cms }} ...@@ -16,8 +16,8 @@ env WORKERS={{ ansible_processor|length * worker_core_mult.cms }}
{% else %} {% else %}
env WORKERS={{ worker_core_mult.cms }} env WORKERS={{ worker_core_mult.cms }}
{% endif %} {% endif %}
env PORT={{edxapp_cms_app_port}} env PORT={{edxapp_cms_gunicorn_port}}
env ADDRESS={{edxapp_cms_app_address}} env ADDRESS={{edxapp_cms_gunicorn_host}}
env LANG=en_US.UTF-8 env LANG=en_US.UTF-8
env DJANGO_SETTINGS_MODULE=cms.envs.aws env DJANGO_SETTINGS_MODULE=cms.envs.aws
env SERVICE_VARIANT="cms" env SERVICE_VARIANT="cms"
......
...@@ -17,8 +17,8 @@ env WORKERS={{ ansible_processor|length * worker_core_mult.lms_preview }} ...@@ -17,8 +17,8 @@ env WORKERS={{ ansible_processor|length * worker_core_mult.lms_preview }}
{% else %} {% else %}
env WORKERS={{ worker_core_mult.lms_preview }} env WORKERS={{ worker_core_mult.lms_preview }}
{% endif %} {% endif %}
env PORT={{edxapp_lms_preview_app_port}} env PORT={{edxapp_lms_preview_gunicorn_port}}
env ADDRESS={{edxapp_lms_preview_app_address}} env ADDRESS={{edxapp_lms_preview_gunicorn_host}}
env LANG=en_US.UTF-8 env LANG=en_US.UTF-8
env DJANGO_SETTINGS_MODULE=lms.envs.aws env DJANGO_SETTINGS_MODULE=lms.envs.aws
env SERVICE_VARIANT="lms-preview" env SERVICE_VARIANT="lms-preview"
......
...@@ -14,8 +14,8 @@ env WORKERS={{ ansible_processor|length * worker_core_mult.lms }} ...@@ -14,8 +14,8 @@ env WORKERS={{ ansible_processor|length * worker_core_mult.lms }}
{% else %} {% else %}
env WORKERS={{ worker_core_mult.lms }} env WORKERS={{ worker_core_mult.lms }}
{% endif %} {% endif %}
env PORT={{edxapp_lms_app_port}} env PORT={{edxapp_lms_gunicorn_port}}
env ADDRESS={{edxapp_lms_app_address}} env ADDRESS={{edxapp_lms_gunicorn_host}}
env LANG=en_US.UTF-8 env LANG=en_US.UTF-8
env DJANGO_SETTINGS_MODULE={{ edxapp_lms_env }} env DJANGO_SETTINGS_MODULE={{ edxapp_lms_env }}
env SERVICE_VARIANT="lms" env SERVICE_VARIANT="lms"
......
...@@ -2,7 +2,6 @@ ...@@ -2,7 +2,6 @@
# requires: # requires:
# - group_vars/all # - group_vars/all
# - common/tasks/main.yml # - common/tasks/main.yml
# - nginx/tasks/main.yml
# #
# This installs mysql-server-5.5 though # This installs mysql-server-5.5 though
# in production we use mysql-5.1.62. # in production we use mysql-5.1.62.
......
--- ---
- name: forum | test that the required service are listening - name: forum | test that the required service are listening
wait_for: port={{ item.port }} host={{ item.host }} timeout=10 wait_for: port={{ item.port }} host={{ item.host }} timeout=30
with_items: "{{ forum_services }}" with_items: "{{ forum_services }}"
tags: tags:
- forum - forum
......
...@@ -4,6 +4,18 @@ pkgs: ...@@ -4,6 +4,18 @@ pkgs:
nginx: nginx:
state: installed state: installed
nginx_xserver_gunicorn_hosts:
- 127.0.0.1
nginx_xqueue_gunicorn_hosts:
- 127.0.0.1
nginx_ora_gunicorn_hosts:
- 127.0.0.1
nginx_lms_gunicorn_hosts:
- 127.0.0.1
nginx_lms_preview_gunicorn_hosts:
- 127.0.0.1
nginx_cms_gunicorn_hosts:
- 127.0.0.1
nginx_cfg: nginx_cfg:
# - link - turn on # - link - turn on
......
--- ---
- name: nginx | restart nginx - name: nginx | restart nginx
service: name=nginx state=restarted service: name=nginx state=restarted
sudo: True
- name: nginx | reload nginx
service: name=nginx state=reloaded
...@@ -11,16 +11,36 @@ ...@@ -11,16 +11,36 @@
- name: nginx | Server configuration file - name: nginx | Server configuration file
copy: src={{secure_dir}}/files/nginx.conf dest=/etc/nginx/nginx.conf owner=root group=root mode=0644 copy: src={{secure_dir}}/files/nginx.conf dest=/etc/nginx/nginx.conf owner=root group=root mode=0644
when: nginx_conf is defined when: nginx_conf is defined
notify: nginx | restart nginx notify: nginx | reload nginx
tags: tags:
- nginx - nginx
- install - install
# Standard configuration that is common across all roles - name: nginx | Creating common nginx configuration
# Default values for these variables are set in group_vars/all template: src=edx-release.j2 dest=/etc/nginx/sites-available/edx-release owner=root group=root mode=0600
# Note: remove spaces in {{..}}, otherwise you will get a template parsing error. notify: nginx | reload nginx
- include: nginx_site.yml state={{nginx_cfg.sites_enabled.edx_release}} site_name=edx-release tags:
- include: nginx_site.yml state={{nginx_cfg.sites_enabled.basic_auth}} site_name=basic-auth - nginx
- name: nginx | Creating link for common nginx configuration
file: src=/etc/nginx/sites-available/edx-release dest=/etc/nginx/sites-enabled/edx-release state=link owner=root group=root
notify: nginx | reload nginx
tags:
- nginx
- name: nginx | Copying nginx configs for {{ nginx_sites }}
template: src={{ item }}.j2 dest=/etc/nginx/sites-available/{{ item }} owner=root group=root mode=0600
notify: nginx | reload nginx
with_items: nginx_sites
tags:
- nginx
- name: nginx | Creating nginx config links for {{ nginx_sites }}
file: src=/etc/nginx/sites-available/{{ item }} dest=/etc/nginx/sites-enabled/{{ item }} state=link owner=root group=root
notify: nginx | reload nginx
with_items: nginx_sites
tags:
- nginx
- name: nginx | Write out default htpasswd file - name: nginx | Write out default htpasswd file
copy: content={{ nginx_cfg.htpasswd }} dest=/etc/nginx/nginx.htpasswd owner=www-data group=www-data mode=0600 copy: content={{ nginx_cfg.htpasswd }} dest=/etc/nginx/nginx.htpasswd owner=www-data group=www-data mode=0600
...@@ -38,7 +58,7 @@ ...@@ -38,7 +58,7 @@
# removing default link # removing default link
- name: nginx | Removing default nginx config and restart (enabled) - name: nginx | Removing default nginx config and restart (enabled)
file: path=/etc/nginx/sites-enabled/default state=absent file: path=/etc/nginx/sites-enabled/default state=absent
notify: nginx | restart nginx notify: nginx | reload nginx
tags: tags:
- nginx - nginx
- update - update
...@@ -47,29 +67,25 @@ ...@@ -47,29 +67,25 @@
- name: nginx | Set up nginx access log rotation - name: nginx | Set up nginx access log rotation
template: dest=/etc/logrotate.d/nginx-access src=edx_logrotate_nginx_access.j2 owner=root group=root mode=644 template: dest=/etc/logrotate.d/nginx-access src=edx_logrotate_nginx_access.j2 owner=root group=root mode=644
notify: common | restart logrotate
tags: tags:
- logging - logging
- update - update
- name: nginx | Set up nginx access log rotation - name: nginx | Set up nginx access log rotation
template: dest=/etc/logrotate.d/nginx-error src=edx_logrotate_nginx_error.j2 owner=root group=root mode=644 template: dest=/etc/logrotate.d/nginx-error src=edx_logrotate_nginx_error.j2 owner=root group=root mode=644
notify: common | restart logrotate
tags: tags:
- logging - logging
- update - update
- name: nginx | Removing default nginx config (available) - name: nginx | Removing default nginx config (available)
file: path=/etc/nginx/sites-available/default state=absent file: path=/etc/nginx/sites-available/default state=absent
notify: nginx | reload nginx
tags: tags:
- nginx - nginx
- update - update
- name: nginx | Register the fact that nginx has run
command: echo True
register: nginx_role_run
tags:
- nginx
- update
# If tasks that notify restart nginx don't change the state of the remote system # If tasks that notify restart nginx don't change the state of the remote system
# their corresponding notifications don't get run. If nginx has been stopped for # their corresponding notifications don't get run. If nginx has been stopped for
# any reason, this will ensure that it is started up again. # any reason, this will ensure that it is started up again.
......
# Requires nginx package
---
- name: nginx | Copying nginx config {{ site_name }}
template: src={{ item }} dest=/etc/nginx/sites-available/{{ site_name }} owner=root group=root mode=0600
first_available_file:
- "{{ local_dir }}/nginx/templates/{{ template_subdir }}/{{ site_name }}.j2"
- "{{ local_dir }}/nginx/templates/{{ site_name }}.j2"
# seems like paths in first_available_file must be relative to the playbooks dir
- "roles/nginx/templates/{{ site_name }}.j2"
notify: nginx | restart nginx
when: nginx_role_run is defined
tags:
- nginx
- lms
- cms
- nginx-env
- update
- deploy
- name: nginx | Creating nginx config link {{ site_name }}
file: src=/etc/nginx/sites-available/{{ site_name }} dest=/etc/nginx/sites-enabled/{{ site_name }} state={{ state }} owner=root group=root
notify: nginx | restart nginx
when: nginx_role_run is defined
tags:
- nginx
- lms
- cms
- nginx-env
- update
- deploy
server {
listen 80;
location / {
auth_basic "Restricted"; auth_basic "Restricted";
auth_basic_user_file /etc/nginx/nginx.htpasswd; auth_basic_user_file /etc/nginx/nginx.htpasswd;
root {{app_base_dir}}/main_static; root {{ app_base_dir }}/main_static;
index index.html index index.html
proxy_set_header X-Forwarded-Proto https; proxy_set_header X-Forwarded-Proto https;
}
}
upstream cms-backend {
# For a TCP configuration:
server 127.0.0.1:8010 fail_timeout=0;
}
upstream cms-backend {
{% for host in nginx_cms_gunicorn_hosts %}
server {{ host }}:{{ edxapp_cms_gunicorn_port }} fail_timeout=0;
{% endfor %}
}
server { server {
# CMS configuration file for nginx, templated by ansible # CMS configuration file for nginx, templated by ansible
...@@ -26,6 +32,9 @@ server { ...@@ -26,6 +32,9 @@ server {
} }
location / { location / {
{% if EDXAPP_CMS_BASIC_AUTH %}
{% include "basic-auth.j2" %}
{% endif %}
try_files $uri @proxy_to_cms_app; try_files $uri @proxy_to_cms_app;
} }
......
server { server {
listen {{nginx_listen_port}}; listen {{ DISCERN_NGINX_PORT }};
server_name localhost; server_name localhost;
set $my_host $http_host; set $my_host $http_host;
...@@ -9,7 +9,7 @@ server { ...@@ -9,7 +9,7 @@ server {
# https://docs.djangoproject.com/en/dev/howto/static-files/#serving-static-files-in-production # https://docs.djangoproject.com/en/dev/howto/static-files/#serving-static-files-in-production
location /static/ { # STATIC_URL location /static/ { # STATIC_URL
alias {{discern_dir}}/staticfiles/; alias {{ discern_dir }}/staticfiles/;
expires 1m; expires 1m;
autoindex on; autoindex on;
} }
...@@ -20,6 +20,9 @@ server { ...@@ -20,6 +20,9 @@ server {
} }
location / { location / {
{% if DISCERN_BASIC_AUTH %}
{% include "basic-auth.j2" %}
{% endif %}
proxy_set_header X-Forwarded-Proto $http_x_forwarded_proto; proxy_set_header X-Forwarded-Proto $http_x_forwarded_proto;
proxy_set_header X-Forwarded-Port $http_x_forwarded_port; proxy_set_header X-Forwarded-Port $http_x_forwarded_port;
proxy_set_header X-Forwarded-For $http_x_forwarded_for; proxy_set_header X-Forwarded-For $http_x_forwarded_for;
......
server { server {
listen 8099 default_server; listen 8099 default_server;
server_name mitx_release.*;
location = /versions.html { location = /versions.html {
alias {{ nginx_cfg.version_html }}; alias {{ nginx_cfg.version_html }};
} }
......
upstream lms-backend {
# For a TCP configuration:
server 127.0.0.1:8000 fail_timeout=0;
}
upstream lms-preview-backend {
# For a TCP configuration:
server 127.0.0.1:8020 fail_timeout=0;
}
upstream lms-preview-backend {
{% for host in nginx_lms_preview_gunicorn_hosts %}
server {{ host }}:{{ edxapp_lms_preview_gunicorn_port }} fail_timeout=0;
{% endfor %}
}
server { server {
# LMS-preview configuration file for nginx, templated by ansible # LMS-preview configuration file for nginx, templated by ansible
...@@ -23,6 +29,10 @@ server { ...@@ -23,6 +29,10 @@ server {
} }
location / { location / {
{% if EDXAPP_LMS_PREVIEW_BASIC_AUTH %}
{% include "basic-auth.j2" %}
{% endif %}
try_files $uri @proxy_to_lms-preview_app; try_files $uri @proxy_to_lms-preview_app;
} }
......
upstream lms-backend {
{% for host in nginx_lms_gunicorn_hosts %}
server {{ host }}:{{ edxapp_lms_gunicorn_port }} fail_timeout=0;
{% endfor %}
}
server { server {
# LMS configuration file for nginx, templated by ansible # LMS configuration file for nginx, templated by ansible
...@@ -25,6 +31,10 @@ server { ...@@ -25,6 +31,10 @@ server {
} }
location / { location / {
{% if EDXAPP_LMS_BASIC_AUTH %}
{% include "basic-auth.j2" %}
{% endif %}
try_files $uri @proxy_to_lms_app; try_files $uri @proxy_to_lms_app;
} }
......
upstream app_server { upstream app_server {
# For a TCP configuration: {% for host in nginx_ora_gunicorn_hosts %}
server 127.0.0.1:{{ ora_gunicorn_port }} fail_timeout=0; server {{ host }}:{{ ora_gunicorn_port }} fail_timeout=0;
{% endfor %}
} }
server { server {
listen {{ ora_nginx_port}} default_server; listen {{ ORA_NGINX_PORT }} default_server;
location / { location / {
{% if ORA_BASIC_AUTH %}
{% include "basic-auth.j2" %}
{% endif %}
try_files $uri @proxy_to_app; try_files $uri @proxy_to_app;
} }
......
upstream xqueue_app_server { upstream xqueue_app_server {
# For a TCP configuration: {% for host in nginx_xqueue_gunicorn_hosts %}
server 127.0.0.1:{{ xqueue_gunicorn_port }} fail_timeout=0; server {{ host }}:{{ xqueue_gunicorn_port }} fail_timeout=0;
{% endfor %}
} }
server { server {
listen {{ xqueue_nginx_port }} default_server; listen {{ XQUEUE_NGINX_PORT }} default_server;
location / { location / {
{% if XQUEUE_BASIC_AUTH %}
{% include "basic-auth.j2" %}
{% endif %}
try_files $uri @proxy_to_app; try_files $uri @proxy_to_app;
} }
......
...@@ -9,14 +9,18 @@ ...@@ -9,14 +9,18 @@
# Please see /usr/share/doc/nginx-doc/examples/ for more detailed examples. # Please see /usr/share/doc/nginx-doc/examples/ for more detailed examples.
## ##
upstream xserver_app_server { upstream xserver_app_server {
# For a TCP configuration: {% for host in nginx_xserver_gunicorn_hosts %}
server 127.0.0.1:{{ xserver_port }} fail_timeout=0; server {{ host }}:{{ xserver_gunicorn_port }} fail_timeout=0;
{% endfor %}
} }
server { server {
listen {{ xserver_nginx_port }} default_server; listen {{ XSERVER_NGINX_PORT }} default_server;
location / { location / {
{% if XSERVER_BASIC_AUTH %}
{% include "basic-auth.j2" %}
{% endif %}
try_files $uri @proxy_to_app; try_files $uri @proxy_to_app;
} }
......
# vars for the ORA role # vars for the ORA role
--- ---
ORA_NGINX_PORT: 18060
ORA_BASIC_AUTH: False
ora_code_dir: "{{ app_base_dir }}/edx-ora" ora_code_dir: "{{ app_base_dir }}/edx-ora"
# Default nginx listen port # Default nginx listen port
# These should be overrided if you want # These should be overrided if you want
...@@ -9,8 +12,8 @@ ora_user_home: "/opt/edx-ora" ...@@ -9,8 +12,8 @@ ora_user_home: "/opt/edx-ora"
ora_venv_dir: "{{ ora_user_home }}/virtualenvs/{{ ora_user }}" ora_venv_dir: "{{ ora_user_home }}/virtualenvs/{{ ora_user }}"
ease_venv_dir: "{{ ora_venv_dir }}" ease_venv_dir: "{{ ora_venv_dir }}"
ora_gunicorn_workers: 4 ora_gunicorn_workers: 4
ora_nginx_port: 18091 ora_gunicorn_port: 8060
ora_gunicorn_port: 8091 ora_gunicorn_host: 127.0.0.1
# ora_env_config and ora_auth_config # ora_env_config and ora_auth_config
# should be overridden for your # should be overridden for your
......
...@@ -53,10 +53,6 @@ ...@@ -53,10 +53,6 @@
- ora - ora
- deploy - deploy
# Install nginx site
- include: ../../nginx/tasks/nginx_site.yml state=link site_name=ora
# Do A Checkout # Do A Checkout
- name: ora | git checkout ora repo into $app_base_dir - name: ora | git checkout ora repo into $app_base_dir
git: dest={{ora_code_dir}} repo={{ora_source_repo}} version={{ora_version}} git: dest={{ora_code_dir}} repo={{ora_source_repo}} version={{ora_version}}
......
# requires: # requires:
# - group_vars/all # - group_vars/all
# - common/tasks/main.yml # - common/tasks/main.yml
# - nginx/tasks/main.yml
--- ---
- name: ora | create the ora application user - name: ora | create the ora application user
user: name={{ ora_user }} user: name={{ ora_user }}
......
...@@ -12,6 +12,7 @@ respawn limit 3 30 ...@@ -12,6 +12,7 @@ respawn limit 3 30
env PID=/var/run/gunicorn/edx-ora.pid env PID=/var/run/gunicorn/edx-ora.pid
env WORKERS={{ ora_gunicorn_workers }} env WORKERS={{ ora_gunicorn_workers }}
env PORT={{ ora_gunicorn_port }} env PORT={{ ora_gunicorn_port }}
env ADDRESS={{ ora_gunicorn_host }}
env LANG=en_US.UTF-8 env LANG=en_US.UTF-8
env DJANGO_SETTINGS_MODULE=edx_ora.aws env DJANGO_SETTINGS_MODULE=edx_ora.aws
env SERVICE_VARIANT=ora env SERVICE_VARIANT=ora
...@@ -22,4 +23,4 @@ end script ...@@ -22,4 +23,4 @@ end script
chdir {{ ora_code_dir }} chdir {{ ora_code_dir }}
setuid {{ ora_user }} setuid {{ ora_user }}
exec {{ ora_venv_dir}}/bin/gunicorn --preload -b 127.0.0.1:$PORT -w $WORKERS --timeout=90 --pythonpath={{ ora_code_dir}} edx_ora.wsgi exec {{ ora_venv_dir}}/bin/gunicorn --preload -b $ADDRESS:$PORT -w $WORKERS --timeout=90 --pythonpath={{ ora_code_dir}} edx_ora.wsgi
# variables common to the xqueue role, automatically loaded # variables common to the xqueue role, automatically loaded
# when the role is included # when the role is included
--- ---
XQUEUE_NGINX_PORT: 18040
XQUEUE_BASIC_AUTH: False
xqueue_code_dir: "{{ app_base_dir }}/xqueue" xqueue_code_dir: "{{ app_base_dir }}/xqueue"
# Default nginx listen port # Default nginx listen port
# These should be overrided if you want # These should be overrided if you want
# to serve all content on port 80 # to serve all content on port 80
xqueue_code_dir: "{{ app_base_dir }}/xqueue" xqueue_code_dir: "{{ app_base_dir }}/xqueue"
xqueue_nginx_port: 18040
xqueue_gunicorn_port: 8040 xqueue_gunicorn_port: 8040
xqueue_gunicorn_host: 127.0.0.1
xqueue_user: "xqueue" xqueue_user: "xqueue"
xqueue_user_home: "/opt/xqueue" xqueue_user_home: "/opt/xqueue"
......
...@@ -23,21 +23,6 @@ ...@@ -23,21 +23,6 @@
- xqueue - xqueue
- deploy - deploy
- name: xqueue | creating xqueue upstart script
template: src=xqueue.conf.j2 dest=/etc/init/xqueue.conf mode=0640 owner=root group=adm
tags:
- xqueue
- deploy
- name: xqueue | create xqueue consumer upstart script
template: src=xqueue_consumer.conf.j2 dest=/etc/init/xqueue_consumer.conf mode=0640 owner=root group=adm
tags:
- xqueue
- deploy
# Install nginx site
- include: ../../nginx/tasks/nginx_site.yml state=link site_name=xqueue
# Do A Checkout # Do A Checkout
- name: xqueue | git checkout xqueue repo into {{app_base_dir}} - name: xqueue | git checkout xqueue repo into {{app_base_dir}}
git: dest={{xqueue_code_dir}} repo={{xqueue_source_repo}} version={{xqueue_version}} git: dest={{xqueue_code_dir}} repo={{xqueue_source_repo}} version={{xqueue_version}}
......
# requires: # requires:
# - group_vars/all # - group_vars/all
# - common/tasks/main.yml # - common/tasks/main.yml
# - nginx/tasks/main.yml
--- ---
# Check out xqueue repo to {{xqueue_code_dir}} # Check out xqueue repo to {{xqueue_code_dir}}
- name: xqueue | install git and its recommends - name: xqueue | install git and its recommends
...@@ -55,4 +54,19 @@ ...@@ -55,4 +54,19 @@
encoding=utf8 encoding=utf8
when: xqueue_create_db is defined and xqueue_create_db|lower == "yes" when: xqueue_create_db is defined and xqueue_create_db|lower == "yes"
- name: xqueue | creating xqueue upstart script
template: src=xqueue.conf.j2 dest=/etc/init/xqueue.conf mode=0640 owner=root group=adm
tags:
- xqueue
- deploy
- name: xqueue | create xqueue consumer upstart script
template: src=xqueue_consumer.conf.j2 dest=/etc/init/xqueue_consumer.conf mode=0640 owner=root group=adm
tags:
- xqueue
- deploy
- include: deploy.yml - include: deploy.yml
...@@ -13,6 +13,7 @@ env WORKERS={{ ansible_processor|length * 2 }} ...@@ -13,6 +13,7 @@ env WORKERS={{ ansible_processor|length * 2 }}
env WORKERS=2 env WORKERS=2
{% endif %} {% endif %}
env PORT={{ xqueue_gunicorn_port }} env PORT={{ xqueue_gunicorn_port }}
env ADDRESS={{ xqueue_gunicorn_host }}
env LANG=en_US.UTF-8 env LANG=en_US.UTF-8
env DJANGO_SETTINGS_MODULE=xqueue.aws_settings env DJANGO_SETTINGS_MODULE=xqueue.aws_settings
env SERVICE_VARIANT="xqueue" env SERVICE_VARIANT="xqueue"
...@@ -21,4 +22,4 @@ env SERVICE_VARIANT="xqueue" ...@@ -21,4 +22,4 @@ env SERVICE_VARIANT="xqueue"
chdir {{ xqueue_code_dir }} chdir {{ xqueue_code_dir }}
setuid {{ xqueue_user }} setuid {{ xqueue_user }}
exec {{ xqueue_venv_dir }}/bin/gunicorn --preload -b 127.0.0.1:$PORT -w $WORKERS --timeout=300 --pythonpath={{ xqueue_code_dir }} xqueue.wsgi exec {{ xqueue_venv_dir }}/bin/gunicorn --preload -b $ADDRESS:$PORT -w $WORKERS --timeout=300 --pythonpath={{ xqueue_code_dir }} xqueue.wsgi
# Variables for the xserver. # Variables for the xserver.
--- ---
XSERVER_NGINX_PORT: 18050
XSERVER_BASIC_AUTH: False
RABBIT_RUN_URL: '' RABBIT_RUN_URL: ''
RABBIT_GRADER_ROOT: '' RABBIT_GRADER_ROOT: ''
RABBIT_LOGGING_ENV: 'sandbox' RABBIT_LOGGING_ENV: 'sandbox'
...@@ -34,8 +37,8 @@ xserver_sandbox_venv_dir: "{{ venv_dir }}_apparmor_sandbox" ...@@ -34,8 +37,8 @@ xserver_sandbox_venv_dir: "{{ venv_dir }}_apparmor_sandbox"
xserver_requirements_file: "{{ xserver_code_dir }}/requirements.txt" xserver_requirements_file: "{{ xserver_code_dir }}/requirements.txt"
xserver_port: 8050 xserver_gunicorn_port: 8050
xserver_nginx_port: 18050 xserver_gunicorn_host: 8050
xserver_debian_pkgs: xserver_debian_pkgs:
- build-essential - build-essential
......
- name: xserver | restart nginx
service: name=nginx state=restarted
...@@ -53,6 +53,4 @@ ...@@ -53,6 +53,4 @@
- name: xserver | upload ssh script - name: xserver | upload ssh script
copy: src=git_ssh.sh dest=/tmp/git_ssh.sh force=yes owner=root group=adm mode=750 copy: src=git_ssh.sh dest=/tmp/git_ssh.sh force=yes owner=root group=adm mode=750
- include: nginx.yml
- include: deploy.yml - include: deploy.yml
- name: xserver | add xserver nginx configuration
template: src=simple-proxy.j2 dest=/etc/nginx/sites-available/simple-proxy
notify:
- xserver | restart nginx
- name: xserver | enable xserver nginx configuration
file: src=/etc/nginx/sites-available/simple-proxy dest=/etc/nginx/sites-enabled/simple-proxy state=link
notify:
- xserver | restart nginx
...@@ -13,7 +13,8 @@ env PID=/var/tmp/xserver.pid ...@@ -13,7 +13,8 @@ env PID=/var/tmp/xserver.pid
env NEW_RELIC_CONFIG_FILE={{ app_base_dir }}/newrelic.ini env NEW_RELIC_CONFIG_FILE={{ app_base_dir }}/newrelic.ini
env NEWRELIC={{ venv_dir }}/bin/newrelic-admin env NEWRELIC={{ venv_dir }}/bin/newrelic-admin
env WORKERS={{ ansible_processor|length }} env WORKERS={{ ansible_processor|length }}
env PORT={{ xserver_port }} env PORT={{ xserver_gunicorn_port }}
env ADDRESS={{ xserver_gunicorn_host }}
env LANG=en_US.UTF-8 env LANG=en_US.UTF-8
env DJANGO_SETTINGS_MODULE=xserver_aws_settings env DJANGO_SETTINGS_MODULE=xserver_aws_settings
env SERVICE_VARIANT="xserver" env SERVICE_VARIANT="xserver"
...@@ -22,5 +23,5 @@ env SERVICE_VARIANT="xserver" ...@@ -22,5 +23,5 @@ env SERVICE_VARIANT="xserver"
chdir {{ xserver_code_dir }} chdir {{ xserver_code_dir }}
setuid www-data setuid www-data
exec {{ venv_dir }}/bin/gunicorn --preload -b 127.0.0.1:$PORT -w $WORKERS --timeout=30 --pythonpath={{ xserver_code_dir }} pyxserver_wsgi:application exec {{ venv_dir }}/bin/gunicorn --preload -b $ADDRESS:$PORT -w $WORKERS --timeout=30 --pythonpath={{ xserver_code_dir }} pyxserver_wsgi:application
...@@ -9,7 +9,13 @@ ...@@ -9,7 +9,13 @@
- "group_vars/all" - "group_vars/all"
roles: roles:
- common - common
- nginx - role: nginx
nginx_sites:
- lms
- cms
- lms-preview
- xserver
- xqueue
- edxlocal - edxlocal
- edxapp - edxapp
- { role: 'rabbitmq', rabbitmq_ip: '127.0.0.1' } - { role: 'rabbitmq', rabbitmq_ip: '127.0.0.1' }
...@@ -26,4 +32,4 @@ ...@@ -26,4 +32,4 @@
virtualenv_user_home: "{{ xqueue_user_home }}" virtualenv_user_home: "{{ xqueue_user_home }}"
virtualenv_name: "{{ xqueue_user }}" virtualenv_name: "{{ xqueue_user }}"
- { role: "xqueue", update_users: True } - { role: "xqueue", update_users: True }
- xserver - xserver
\ No newline at end of file
...@@ -9,6 +9,10 @@ ...@@ -9,6 +9,10 @@
- "group_vars/all" - "group_vars/all"
roles: roles:
- common - common
- nginx - role: nginx
nginx_sites:
- lms
- cms
- lms-preview
- edxlocal - edxlocal
- { role: 'edxapp', EDXAPP_LMS_NGINX_PORT: 18030, EDXAPP_LMS_XML_NGINX_PORT: 80 } - { role: 'edxapp', EDXAPP_LMS_NGINX_PORT: 18030, EDXAPP_LMS_XML_NGINX_PORT: 80 }
...@@ -9,7 +9,11 @@ ...@@ -9,7 +9,11 @@
- "group_vars/all" - "group_vars/all"
roles: roles:
- common - common
- nginx - role: nginx
nginx_sites:
- lms
- cms
- lms-preview
- edxlocal - edxlocal
- edxapp - edxapp
- oraclejdk - oraclejdk
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment