Skip to content

Commit

Permalink
Merge b6c30fd into 1f48235
Browse files Browse the repository at this point in the history
  • Loading branch information
Mropat committed Nov 29, 2020
2 parents 1f48235 + b6c30fd commit 81d49dc
Show file tree
Hide file tree
Showing 9 changed files with 177 additions and 16 deletions.
11 changes: 11 additions & 0 deletions .dockerignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
alembic
tests
trailblazer.egg-info
.pytest_cache
.github
.editorconfig
.gitignore
.gitlint.yaml
.pre-commit-config.yaml
DEPLOYMENT.md

26 changes: 26 additions & 0 deletions Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
FROM python:3.7-slim

ENV GUNICORN_WORKERS=1
ENV GUNICORN_TREADS=1
ENV GUNICORN_BIND="0.0.0.0:5000"
ENV GUNICORN_TIMEOUT=400

WORKDIR /home/src/app
COPY . /home/src/app

RUN pip install -r requirements.txt
RUN pip install -e .

EXPOSE 5000

RUN useradd worker
RUN chown -R worker:worker /home/src
USER worker

CMD gunicorn \
--workers=$GUNICORN_WORKERS \
--bind=$GUNICORN_BIND \
--threads=$GUNICORN_TREADS \
--timeout=$GUNICORN_TIMEOUT \
trailblazer.server.app:app

3 changes: 1 addition & 2 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,9 +1,8 @@
# Trailblazer [![Coverage Status][coveralls-image]][coveralls-url]

### Automate, monitor, and simplify running the [MIP][mip] analysis pipeline
### Monitor the progress of analysis workflows submitted to SLURM

Trailblazer is a tool that aims to provide:

- a Python interface to interact with MIP in an automated fashion
- a limited command line interface to simplify running MIP using an opinionated setup

Expand Down
42 changes: 42 additions & 0 deletions docker-compose.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
version: '3.8'

services:
mysql-server:
image: mysql:5.6
container_name: trailblazer-database
restart: always
volumes:
- ../testing/tb_dump:/docker-entrypoint-initdb.d:rw
ports:
- '3306'
environment:
MYSQL_ROOT_PASSWORD: rootpass
MYSQL_USER: user
MYSQL_PASSWORD: userpass
MYSQL_DATABASE: trailblazer-stage
networks:
- trailblazer-network

trailblazer:
image: mropat/trailblazer
container_name: trailblazer-api
environment:
SQLALCHEMY_DATABASE_URI: "mysql+pymysql://user:userpass@mysql-server:3306/trailblazer-stage"
SCOPE: "DEVELOPMENT"
GUNICORN_WORKERS: "3"
GUNICORN_BIND: "0.0.0.0:5000"
GUNICORN_TIMEOUT: "400"
ports:
- 7076:5000
networks:
- trailblazer-network
depends_on:
- mysql-server

networks:
trailblazer-network:
driver: bridge
ipam:
driver: default


2 changes: 2 additions & 0 deletions requirements.txt
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,9 @@ Flask-SQLAlchemy==2.1
Flask-CORS
Flask-Reverse-Proxy
google-auth
gunicorn

# misc
pymysql
python-dateutil
cryptography
83 changes: 83 additions & 0 deletions trailblazer-pod.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,83 @@
# Generation of Kubernetes YAML is still under development!
#
# Save the output of this file and use kubectl create -f to import
# it into Kubernetes.
#
# Created with podman-2.0.6
apiVersion: v1
kind: Pod
metadata:
creationTimestamp: "2020-11-29T09:43:55Z"
labels:
app: trailblazer-pod
name: trailblazer-pod
spec:
containers:
- name: trailblazer-stage-db
env:
- name: MYSQL_PASSWORD
value: userpass
- name: MYSQL_ROOT_PASSWORD
value: rootpass
- name: MYSQL_USER
value: user
- name: MYSQL_DATABASE
value: trailblazer-stage
image: docker.io/library/mysql:5.6
ports:
- contrinerPort: 3306
resources: {}
securityContext:
allowPrivilegeEscalation: true
capabilities: {}
privileged: false
readOnlyRootFilesystem: false
seLinuxOptions: {}
volumeMounts:
- mountPath: /docker-entrypoint-initdb.d
name: home-admin-Documents-CG-testing-tb_dump
workingDir: /

- name: trailblazer-api
env:
- name: GUNICORN_TREADS
value: "1"
- name: GUNICORN_BIND
value: 0.0.0.0:5000
- name: SCOPE
value: DEVELOPMENT
- name: GUNICORN_TIMEOUT
value: "400"
- name: SQLALCHEMY_DATABASE_URI
value: mysql+pymysql://user:userpass@localhost:3306/trailblazer-stage
- name: GUNICORN_WORKERS
value: "1"
image: docker.io/mropat/trailblazer:latest
ports:
- containerPort: 5000
hostPort: 7076
protocol: TCP
resources: {}
securityContext:
allowPrivilegeEscalation: true
capabilities: {}
privileged: false
readOnlyRootFilesystem: false
runAsGroup: 1000
runAsUser: 1000
seLinuxOptions: {}
workingDir: /home/src/app

volumes:
- hostPath:
path: /home/admin/Documents/CG/testing/tb_dump
type: Directory
name: home-admin-Documents-CG-testing-tb_dump
status: {}
---
metadata:
creationTimestamp: null
spec: {}
status:
loadBalancer: {}

12 changes: 5 additions & 7 deletions trailblazer/cli/core.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
import logging

import os
import click
import coloredlogs
import ruamel.yaml
from dateutil.parser import parse as parse_date

Expand All @@ -16,15 +15,14 @@
@click.group()
@click.option("-c", "--config", type=click.File())
@click.option("-d", "--database", help="path/URI of the SQL database")
@click.option("-l", "--log-level", default="INFO")
@click.version_option(trailblazer.__version__, prog_name=trailblazer.__title__)
@click.pass_context
def base(context, config, database, log_level):
def base(context, config, database):
"""Trailblazer - Monitor analyses"""
coloredlogs.install(level=log_level)

context.obj = ruamel.yaml.safe_load(config) if config else {}
context.obj["database"] = database or context.obj.get("database")
context.obj["database"] = database or os.environ.get(
"SQLALCHEMY_DATABASE_URI", "sqlite:///:memory:"
)
context.obj["trailblazer"] = Store(context.obj["database"])


Expand Down
5 changes: 4 additions & 1 deletion trailblazer/server/api.py
Original file line number Diff line number Diff line change
@@ -1,9 +1,10 @@
import datetime
import os

from dateutil.parser import parse as parse_datestr
from flask import abort, g, Blueprint, jsonify, make_response, request
from google.auth import jwt
from typing import Dict
import subprocess
import multiprocessing

from trailblazer.server.ext import store
Expand All @@ -24,6 +25,8 @@ def before_request():
"""Authentication that is run before processing requests to the application"""
if request.method == "OPTIONS":
return make_response(jsonify(ok=True), 204)
if os.environ.get("SCOPE") == "DEVELOPMENT":
return
auth_header = request.headers.get("Authorization")
if auth_header:
jwt_token = auth_header.split("Bearer ")[-1]
Expand Down
9 changes: 3 additions & 6 deletions trailblazer/server/app.py
Original file line number Diff line number Diff line change
@@ -1,21 +1,18 @@
# -*- coding: utf-8 -*-
import os

import coloredlogs
from flask import Flask
from flask_cors import CORS
from flask_reverse_proxy import FlaskReverseProxied

from trailblazer.server import api, ext

coloredlogs.install(level="INFO")
app = Flask(__name__)

SECRET_KEY = "unsafe!!!"
TEMPLATES_AUTO_RELOAD = True
SQLALCHEMY_DATABASE_URI = os.environ["SQLALCHEMY_DATABASE_URI"]
SQLALCHEMY_POOL_RECYCLE = 7200
SQLALCHEMY_TRACK_MODIFICATIONS = "FLASK_DEBUG" in os.environ
SQLALCHEMY_DATABASE_URI = os.environ.get("SQLALCHEMY_DATABASE_URI", "sqlite:///:memory:")
SQLALCHEMY_POOL_RECYCLE = os.environ.get("SQLALCHEMY_POOL_RECYCLE", 7200)
SQLALCHEMY_TRACK_MODIFICATIONS = os.environ.get("FLASK_DEBUG", False)

app.config.from_object(__name__)

Expand Down

0 comments on commit 81d49dc

Please sign in to comment.