Skip to content

Commit

Permalink
🌅
Browse files Browse the repository at this point in the history
  • Loading branch information
regisb committed Aug 21, 2019
0 parents commit bbc9dfc
Show file tree
Hide file tree
Showing 18 changed files with 290 additions and 0 deletions.
7 changes: 7 additions & 0 deletions .gitignore
@@ -0,0 +1,7 @@
.*.swp
!.gitignore
TODO
__pycache__
*.egg-info/
/build/
/dist/
40 changes: 40 additions & 0 deletions .gitlab-ci.yml
@@ -0,0 +1,40 @@
build:image:
script:
- apk add --no-cache docker
- python setup.py install
- tutor plugins enable xqueue
- tutor config save
- tutor images build xqueue
only:
refs:
- master
tags:
- private
stage: build

deploy:image:
script:
- apk add --no-cache docker
- docker login -u "$DOCKER_USERNAME" -p "$DOCKER_PASSWORD"
- python setup.py install
- tutor plugins enable xqueue
- tutor config save
- tutor images push xqueue
only:
refs:
- master
tags:
- private
stage: deploy

deploy:pypi:
script:
- pip3 install -U setuptools twine
- python3 setup.py sdist
- twine upload --skip-existing dist/tutor-xqueue*.tar.gz
only:
refs:
- master
tags:
- private
stage: deploy
2 changes: 2 additions & 0 deletions MANIFEST.in
@@ -0,0 +1,2 @@
recursive-include tutorxqueue/patches *
recursive-include tutorxqueue/templates *
28 changes: 28 additions & 0 deletions README.rst
@@ -0,0 +1,28 @@
Xqueue external grading system plugin for `Tutor <https://docs.tutor.overhang.io>`_
===================================================================================

This is a plugin for `Tutor <https://docs.tutor.overhang.io>`_ that provides the Xqueue external grading system for Open edX platforms. If you don't know what it is, you probably don't need it.

Installation
------------

The plugin is currently bundled with the `binary releases of Tutor <https://github.com/overhangio/tutor/releases>`_. If you have installed Tutor from source, you will have to install this plugin from source, too::
pip install tutor-xqueue

Then, to enable this plugin, run::
tutor plugins enable xqueue

Configuration
-------------

- ``XQUEUE_AUTH_PASSWORD`` (default: ``"{{ 8|random_string }}"``)
- ``XQUEUE_MYSQL_PASSWORD`` (default: ``"{{ 8|random_string }}"``)
- ``XQUEUE_SECRET_KEY`` (default: ``"{{ 24|random_string }}"``)
- ``XQUEUE_DOCKER_IMAGE`` (default: ``"overhangio/openedx-xqueue:{{ TUTOR_VERSION }}"``)
- ``XQUEUE_AUTH_USERNAME`` (default: ``"lms"``)
- ``XQUEUE_MYSQL_DATABASE`` (default: ``"xqueue"``
- ``XQUEUE_MYSQL_USERNAME`` (default: ``"xqueue"``)

These values can be modified with ``tutor config save --set PARAM_NAME=VALUE`` commands.
46 changes: 46 additions & 0 deletions setup.py
@@ -0,0 +1,46 @@
import io
import os
from setuptools import setup, find_packages

here = os.path.abspath(os.path.dirname(__file__))

with io.open(os.path.join(here, "README.rst"), "rt", encoding="utf8") as f:
readme = f.read()

about = {}
with io.open(
os.path.join(here, "tutorxqueue", "__about__.py"), "rt", encoding="utf-8"
) as f:
exec(f.read(), about)

setup(
name="tutor-xqueue",
version=about["__version__"],
url="https://docs.tutor.overhang.io/",
project_urls={
"Documentation": "https://docs.tutor.overhang.io/",
"Code": "https://github.com/overhangio/tutor/tree/master/plugins/xqueue",
"Issue tracker": "https://github.com/overhangio/tutor/issues",
"Community": "https://discuss.overhang.io",
},
license="AGPLv3",
author="Overhang.io",
author_email="contact@overhang.io",
description="A Tutor plugin for Xqueue (external grading system)",
long_description=readme,
packages=find_packages(exclude=["tests*"]),
include_package_data=True,
python_requires=">=3.5",
install_requires=["tutor-openedx"],
entry_points={"tutor.plugin.v0": ["xqueue = tutorxqueue.plugin"]},
classifiers=[
"Development Status :: 3 - Alpha",
"Intended Audience :: Developers",
"License :: OSI Approved :: GNU Affero General Public License v3",
"Operating System :: OS Independent",
"Programming Language :: Python",
"Programming Language :: Python :: 3.5",
"Programming Language :: Python :: 3.6",
"Programming Language :: Python :: 3.7",
],
)
Empty file added tests/__init__.py
Empty file.
1 change: 1 addition & 0 deletions tutorxqueue/__about__.py
@@ -0,0 +1 @@
__version__ = "0.1.1"
Empty file added tutorxqueue/__init__.py
Empty file.
43 changes: 43 additions & 0 deletions tutorxqueue/patches/k8s-deployments
@@ -0,0 +1,43 @@
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: xqueue
labels:
app.kubernetes.io/name: xqueue
spec:
selector:
matchLabels:
app.kubernetes.io/name: xqueue
template:
metadata:
labels:
app.kubernetes.io/name: xqueue
spec:
containers:
- name: xqueue
image: {{ DOCKER_REGISTRY }}{{ XQUEUE_DOCKER_IMAGE }}
ports:
- containerPort: 8040
env:
- name: DJANGO_SETTINGS_MODULE
value: xqueue.tutor
volumeMounts:
- mountPath: /openedx/xqueue/xqueue/tutor.py
name: settings
subPath: tutor.py
- name: xqueue-consumer
image: {{ DOCKER_REGISTRY }}{{ XQUEUE_DOCKER_IMAGE }}
command: ["sh", "-e", "-c"]
args: ["while true; do echo 'running consumers'; ./manage.py run_consumer; sleep 10; done"]
env:
- name: DJANGO_SETTINGS_MODULE
value: xqueue.tutor
volumeMounts:
- mountPath: /openedx/xqueue/xqueue/tutor.py
name: settings
subPath: tutor.py
volumes:
- name: settings
configMap:
name: xqueue-settings
12 changes: 12 additions & 0 deletions tutorxqueue/patches/k8s-services
@@ -0,0 +1,12 @@
---
apiVersion: v1
kind: Service
metadata:
name: xqueue
spec:
type: NodePort
ports:
- port: 8040
protocol: TCP
selector:
app.kubernetes.io/name: xqueue
3 changes: 3 additions & 0 deletions tutorxqueue/patches/kustomization-configmapgenerator
@@ -0,0 +1,3 @@
- name: xqueue-settings
files:
- plugins/xqueue/apps/xqueue/settings/tutor.py
24 changes: 24 additions & 0 deletions tutorxqueue/patches/local-docker-compose-services
@@ -0,0 +1,24 @@
############# Xqueue: external grading of Open edX problems
xqueue:
image: {{ DOCKER_REGISTRY }}{{ XQUEUE_DOCKER_IMAGE }}
volumes:
- ../plugins/xqueue/apps/settings/tutor.py:/openedx/xqueue/xqueue/tutor.py
- ../../data/xqueue:/openedx/data
environment:
DJANGO_SETTINGS_MODULE: xqueue.tutor
restart: unless-stopped
{% if ACTIVATE_MYSQL %}depends_on:
- mysql{% endif %}

xqueue_consumer:
image: {{ DOCKER_REGISTRY }}{{ XQUEUE_DOCKER_IMAGE }}
volumes:
- ../plugins/xqueue/apps/settings/tutor.py:/openedx/xqueue/xqueue/tutor.py
- ../../data/xqueue:/openedx/data
environment:
DJANGO_SETTINGS_MODULE: xqueue.tutor
restart: unless-stopped
entrypoint: ["sh", "-e", "-c"]
command: ["while true; do echo 'running consumers'; ./manage.py run_consumer; sleep 10; done"]
{% if ACTIVATE_MYSQL %}depends_on:
- mysql{% endif %}
7 changes: 7 additions & 0 deletions tutorxqueue/patches/openedx-common-settings
@@ -0,0 +1,7 @@
XQUEUE_INTERFACE = {
"django_auth": {
"username": "{{ XQUEUE_AUTH_USERNAME }}",
"password": "{{ XQUEUE_AUTH_PASSWORD }}"
},
"url": "http://xqueue:8040"
}
41 changes: 41 additions & 0 deletions tutorxqueue/plugin.py
@@ -0,0 +1,41 @@
from glob import glob
import os

import pkg_resources

from .__about__ import __version__


config = {
"add": {
"AUTH_PASSWORD": "{{ 8|random_string }}",
"MYSQL_PASSWORD": "{{ 8|random_string }}",
"SECRET_KEY": "{{ 24|random_string }}",
},
"defaults": {
"VERSION": __version__,
"DOCKER_IMAGE": "overhangio/openedx-xqueue:{{ XQUEUE_VERSION }}",
"AUTH_USERNAME": "lms",
"MYSQL_DATABASE": "xqueue",
"MYSQL_USERNAME": "xqueue",
},
}

templates = pkg_resources.resource_filename("tutorxqueue", "templates")
hooks = {
"init": ["mysql-client", "xqueue"],
"build-image": {"xqueue": "{{ XQUEUE_DOCKER_IMAGE }}"},
"remote-image": {"xqueue": "{{ XQUEUE_DOCKER_IMAGE }}"},
}


def patches():
all_patches = {}
for path in glob(
os.path.join(pkg_resources.resource_filename("tutorxqueue", "patches"), "*")
):
with open(path) as patch_file:
name = os.path.basename(path)
content = patch_file.read()
all_patches[name] = content
return all_patches
18 changes: 18 additions & 0 deletions tutorxqueue/templates/xqueue/apps/settings/tutor.py
@@ -0,0 +1,18 @@
from .settings import *

DATABASES = {
"default": {
"ENGINE": "django.db.backends.mysql",
"HOST": "{{ MYSQL_HOST }}",
"PORT": {{MYSQL_PORT}},
"NAME": "{{ XQUEUE_MYSQL_DATABASE }}",
"USER": "{{ XQUEUE_MYSQL_USERNAME }}",
"PASSWORD": "{{ XQUEUE_MYSQL_PASSWORD }}",
}
}

LOGGING = get_logger_config(log_dir="/openedx/data/", logging_env="tutor", dev_env=True)

SECRET_KEY = "{{ XQUEUE_SECRET_KEY }}"

XQUEUE_USERS = {"{{ XQUEUE_AUTH_USERNAME }}": "{{ XQUEUE_AUTH_PASSWORD}}"}
15 changes: 15 additions & 0 deletions tutorxqueue/templates/xqueue/build/xqueue/Dockerfile
@@ -0,0 +1,15 @@
FROM ubuntu:18.04
MAINTAINER Overhang.io <contact@overhang.io>

RUN apt update && \
apt upgrade -y && \
apt install -y language-pack-en git python-pip libmysqlclient-dev

RUN mkdir /openedx /openedx/data
RUN git clone https://github.com/edx/xqueue --branch open-release/ironwood.2 --depth 1 /openedx/xqueue
WORKDIR /openedx/xqueue

RUN pip install -r requirements.txt

EXPOSE 8040
CMD gunicorn --workers=2 --name xqueue --bind=0.0.0.0:8040 --max-requests=1000 xqueue.wsgi:application
2 changes: 2 additions & 0 deletions tutorxqueue/templates/xqueue/hooks/mysql-client/init
@@ -0,0 +1,2 @@
mysql -u root --password="{{ MYSQL_ROOT_PASSWORD }}" --host "{{ MYSQL_HOST }}" --port {{ MYSQL_PORT }} -e 'CREATE DATABASE IF NOT EXISTS {{ XQUEUE_MYSQL_DATABASE }};'
mysql -u root --password="{{ MYSQL_ROOT_PASSWORD }}" --host "{{ MYSQL_HOST }}" --port {{ MYSQL_PORT }} -e 'GRANT ALL ON {{ XQUEUE_MYSQL_DATABASE }}.* TO "{{ XQUEUE_MYSQL_USERNAME }}"@"%" IDENTIFIED BY "{{ XQUEUE_MYSQL_PASSWORD }}";'
1 change: 1 addition & 0 deletions tutorxqueue/templates/xqueue/hooks/xqueue/init
@@ -0,0 +1 @@
./manage.py migrate

0 comments on commit bbc9dfc

Please sign in to comment.