Toward running quay in a docker container.
This commit is contained in:
parent
6e2b8d96b8
commit
8e9faf6121
11 changed files with 138 additions and 38 deletions
36
Dockerfile
Normal file
36
Dockerfile
Normal file
|
@ -0,0 +1,36 @@
|
||||||
|
FROM ubuntu:13.10
|
||||||
|
|
||||||
|
ENV DEBIAN_FRONTEND noninteractive
|
||||||
|
RUN apt-get update
|
||||||
|
RUN apt-get install -y git python-virtualenv python-dev phantomjs libjpeg8 libjpeg62-dev libfreetype6 libfreetype6-dev libevent-dev gdebi-core
|
||||||
|
|
||||||
|
ADD binary_dependencies binary_dependencies
|
||||||
|
RUN gdebi --n binary_dependencies/*.deb
|
||||||
|
|
||||||
|
ADD requirements.txt requirements.txt
|
||||||
|
RUN virtualenv --distribute venv
|
||||||
|
RUN venv/bin/pip install -r requirements.txt
|
||||||
|
|
||||||
|
ADD auth auth
|
||||||
|
ADD buildstatus buildstatus
|
||||||
|
ADD conf conf
|
||||||
|
ADD data data
|
||||||
|
ADD endpoints endpoints
|
||||||
|
ADD features features
|
||||||
|
ADD screenshots screenshots
|
||||||
|
ADD static static
|
||||||
|
ADD storage storage
|
||||||
|
ADD templates templates
|
||||||
|
ADD util util
|
||||||
|
ADD workers workers
|
||||||
|
|
||||||
|
ADD app.py app.py
|
||||||
|
ADD application.py application.py
|
||||||
|
ADD config.py config.py
|
||||||
|
ADD run.sh run.sh
|
||||||
|
|
||||||
|
VOLUME ["/conf/override", "/mnt/logs"]
|
||||||
|
|
||||||
|
EXPOSE 443
|
||||||
|
|
||||||
|
ENTRYPOINT ["./run.sh"]
|
4
app.py
4
app.py
|
@ -13,6 +13,7 @@ import features
|
||||||
from storage import Storage
|
from storage import Storage
|
||||||
from config import DefaultConfig
|
from config import DefaultConfig
|
||||||
from data.userfiles import Userfiles
|
from data.userfiles import Userfiles
|
||||||
|
from util.analytics import Analytics
|
||||||
|
|
||||||
|
|
||||||
app = Flask(__name__)
|
app = Flask(__name__)
|
||||||
|
@ -50,4 +51,5 @@ userfiles.init_app(app)
|
||||||
|
|
||||||
stripe.api_key = app.config.get('STRIPE_SECRET_KEY', None)
|
stripe.api_key = app.config.get('STRIPE_SECRET_KEY', None)
|
||||||
|
|
||||||
mixpanel = app.config['ANALYTICS'].init_app(app)
|
analytics = Analytics()
|
||||||
|
analytics.init_app(app)
|
||||||
|
|
30
conf/nginx-enterprise.conf
Normal file
30
conf/nginx-enterprise.conf
Normal file
|
@ -0,0 +1,30 @@
|
||||||
|
include root-base.conf;
|
||||||
|
|
||||||
|
worker_processes 2;
|
||||||
|
|
||||||
|
user root nogroup;
|
||||||
|
|
||||||
|
http {
|
||||||
|
include http-base.conf;
|
||||||
|
|
||||||
|
include hosted-http-base.conf;
|
||||||
|
|
||||||
|
server {
|
||||||
|
include server-base.conf;
|
||||||
|
|
||||||
|
listen 443 default;
|
||||||
|
|
||||||
|
ssl on;
|
||||||
|
ssl_certificate ./certs/quay-staging-unified.cert;
|
||||||
|
ssl_certificate_key ./certs/quay-staging.key;
|
||||||
|
ssl_session_timeout 5m;
|
||||||
|
ssl_protocols SSLv3 TLSv1;
|
||||||
|
ssl_ciphers ALL:!ADH:!EXPORT56:RC4+RSA:+HIGH:+MEDIUM:+LOW:+SSLv3:+EXP;
|
||||||
|
ssl_prefer_server_ciphers on;
|
||||||
|
|
||||||
|
location /static/ {
|
||||||
|
# checks for static file, if not found proxy to app
|
||||||
|
alias /static/;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
29
config.py
29
config.py
|
@ -7,9 +7,6 @@ from peewee import MySQLDatabase, SqliteDatabase
|
||||||
from data.buildlogs import BuildLogs
|
from data.buildlogs import BuildLogs
|
||||||
from data.userevent import UserEventBuilder
|
from data.userevent import UserEventBuilder
|
||||||
|
|
||||||
from test import analytics as fake_analytics
|
|
||||||
from test.testlogs import TestBuildLogs
|
|
||||||
|
|
||||||
|
|
||||||
def build_requests_session():
|
def build_requests_session():
|
||||||
sess = requests.Session()
|
sess = requests.Session()
|
||||||
|
@ -88,7 +85,7 @@ class DefaultConfig(object):
|
||||||
USERFILES_PATH = 'test/data/userfiles'
|
USERFILES_PATH = 'test/data/userfiles'
|
||||||
|
|
||||||
# Analytics
|
# Analytics
|
||||||
ANALYTICS = fake_analytics
|
ANALYTICS_TYPE = "FakeAnalytics"
|
||||||
|
|
||||||
# Github Config
|
# Github Config
|
||||||
GITHUB_TOKEN_URL = 'https://github.com/login/oauth/access_token'
|
GITHUB_TOKEN_URL = 'https://github.com/login/oauth/access_token'
|
||||||
|
@ -130,21 +127,21 @@ class FakeTransaction(object):
|
||||||
pass
|
pass
|
||||||
|
|
||||||
|
|
||||||
class TestConfig(DefaultConfig):
|
# class TestConfig(DefaultConfig):
|
||||||
TESTING = True
|
# TESTING = True
|
||||||
|
|
||||||
DB_NAME = ':memory:'
|
# DB_NAME = ':memory:'
|
||||||
DB_CONNECTION_ARGS = {}
|
# DB_CONNECTION_ARGS = {}
|
||||||
|
|
||||||
@staticmethod
|
# @staticmethod
|
||||||
def create_transaction(db):
|
# def create_transaction(db):
|
||||||
return FakeTransaction()
|
# return FakeTransaction()
|
||||||
|
|
||||||
DB_TRANSACTION_FACTORY = create_transaction
|
# DB_TRANSACTION_FACTORY = create_transaction
|
||||||
|
|
||||||
STORAGE_TYPE = 'FakeStorage'
|
# STORAGE_TYPE = 'FakeStorage'
|
||||||
|
|
||||||
BUILDLOGS = TestBuildLogs('logs.quay.io', 'devtable', 'building',
|
# BUILDLOGS = TestBuildLogs('logs.quay.io', 'devtable', 'building',
|
||||||
'deadbeef-dead-beef-dead-beefdeadbeef')
|
# 'deadbeef-dead-beef-dead-beefdeadbeef')
|
||||||
|
|
||||||
USERFILES_TYPE = 'FakeUserfiles'
|
# USERFILES_TYPE = 'FakeUserfiles'
|
||||||
|
|
|
@ -4,7 +4,7 @@ from flask import request, redirect, url_for, Blueprint
|
||||||
from flask.ext.login import current_user
|
from flask.ext.login import current_user
|
||||||
|
|
||||||
from endpoints.common import render_page_template, common_login, route_show_if
|
from endpoints.common import render_page_template, common_login, route_show_if
|
||||||
from app import app, mixpanel
|
from app import app, analytics
|
||||||
from data import model
|
from data import model
|
||||||
from util.names import parse_repository_name
|
from util.names import parse_repository_name
|
||||||
from util.http import abort
|
from util.http import abort
|
||||||
|
@ -85,13 +85,13 @@ def github_oauth_callback():
|
||||||
to_login = model.create_federated_user(username, found_email, 'github',
|
to_login = model.create_federated_user(username, found_email, 'github',
|
||||||
github_id)
|
github_id)
|
||||||
|
|
||||||
# Success, tell mixpanel
|
# Success, tell analytics
|
||||||
mixpanel.track(to_login.username, 'register', {'service': 'github'})
|
analytics.track(to_login.username, 'register', {'service': 'github'})
|
||||||
|
|
||||||
state = request.args.get('state', None)
|
state = request.args.get('state', None)
|
||||||
if state:
|
if state:
|
||||||
logger.debug('Aliasing with state: %s' % state)
|
logger.debug('Aliasing with state: %s' % state)
|
||||||
mixpanel.alias(to_login.username, state)
|
analytics.alias(to_login.username, state)
|
||||||
|
|
||||||
except model.DataModelException, ex:
|
except model.DataModelException, ex:
|
||||||
return render_page_template('githuberror.html', error_message=ex.message)
|
return render_page_template('githuberror.html', error_message=ex.message)
|
||||||
|
|
|
@ -9,7 +9,7 @@ from collections import OrderedDict
|
||||||
from data import model
|
from data import model
|
||||||
from data.model import oauth
|
from data.model import oauth
|
||||||
from data.queue import webhook_queue
|
from data.queue import webhook_queue
|
||||||
from app import mixpanel, app
|
from app import analytics, app
|
||||||
from auth.auth import process_auth
|
from auth.auth import process_auth
|
||||||
from auth.auth_context import get_authenticated_user, get_validated_token, get_validated_oauth_token
|
from auth.auth_context import get_authenticated_user, get_validated_token, get_validated_oauth_token
|
||||||
from util.names import parse_repository_name
|
from util.names import parse_repository_name
|
||||||
|
@ -227,7 +227,7 @@ def create_repository(namespace, repository):
|
||||||
}
|
}
|
||||||
|
|
||||||
if get_validated_oauth_token():
|
if get_validated_oauth_token():
|
||||||
mixpanel.track(username, 'push_repo', extra_params)
|
analytics.track(username, 'push_repo', extra_params)
|
||||||
|
|
||||||
oauth_token = get_validated_oauth_token()
|
oauth_token = get_validated_oauth_token()
|
||||||
metadata['oauth_token_id'] = oauth_token.id
|
metadata['oauth_token_id'] = oauth_token.id
|
||||||
|
@ -236,7 +236,7 @@ def create_repository(namespace, repository):
|
||||||
elif get_authenticated_user():
|
elif get_authenticated_user():
|
||||||
username = get_authenticated_user().username
|
username = get_authenticated_user().username
|
||||||
|
|
||||||
mixpanel.track(username, 'push_repo', extra_params)
|
analytics.track(username, 'push_repo', extra_params)
|
||||||
metadata['username'] = username
|
metadata['username'] = username
|
||||||
|
|
||||||
# Mark that the user has started pushing the repo.
|
# Mark that the user has started pushing the repo.
|
||||||
|
@ -250,7 +250,7 @@ def create_repository(namespace, repository):
|
||||||
event.publish_event_data('docker-cli', user_data)
|
event.publish_event_data('docker-cli', user_data)
|
||||||
|
|
||||||
elif get_validated_token():
|
elif get_validated_token():
|
||||||
mixpanel.track(get_validated_token().code, 'push_repo', extra_params)
|
analytics.track(get_validated_token().code, 'push_repo', extra_params)
|
||||||
metadata['token'] = get_validated_token().friendly_name
|
metadata['token'] = get_validated_token().friendly_name
|
||||||
metadata['token_code'] = get_validated_token().code
|
metadata['token_code'] = get_validated_token().code
|
||||||
|
|
||||||
|
@ -374,7 +374,7 @@ def get_repository_images(namespace, repository):
|
||||||
'repository': '%s/%s' % (namespace, repository),
|
'repository': '%s/%s' % (namespace, repository),
|
||||||
}
|
}
|
||||||
|
|
||||||
mixpanel.track(pull_username, 'pull_repo', extra_params)
|
analytics.track(pull_username, 'pull_repo', extra_params)
|
||||||
model.log_action('pull_repo', namespace,
|
model.log_action('pull_repo', namespace,
|
||||||
performer=get_authenticated_user(),
|
performer=get_authenticated_user(),
|
||||||
ip=request.remote_addr, metadata=metadata,
|
ip=request.remote_addr, metadata=metadata,
|
||||||
|
|
|
@ -15,7 +15,7 @@ argparse==1.2.1
|
||||||
beautifulsoup4==4.3.2
|
beautifulsoup4==4.3.2
|
||||||
blinker==1.3
|
blinker==1.3
|
||||||
boto==2.27.0
|
boto==2.27.0
|
||||||
distribute==0.6.34
|
distribute==0.7.3
|
||||||
git+https://github.com/DevTable/docker-py.git
|
git+https://github.com/DevTable/docker-py.git
|
||||||
ecdsa==0.11
|
ecdsa==0.11
|
||||||
gevent==1.0
|
gevent==1.0
|
||||||
|
|
10
run.sh
Executable file
10
run.sh
Executable file
|
@ -0,0 +1,10 @@
|
||||||
|
#! /bin/bash
|
||||||
|
|
||||||
|
/usr/local/nginx/sbin/nginx -c /conf/nginx-enterprise.conf
|
||||||
|
venv/bin/gunicorn -c conf/gunicorn_config.py application:application
|
||||||
|
|
||||||
|
while true
|
||||||
|
do
|
||||||
|
sleep 60
|
||||||
|
echo "stuff"
|
||||||
|
done
|
Binary file not shown.
|
@ -33,13 +33,38 @@ class SendToMixpanel(Process):
|
||||||
self._consumer.send(*json.loads(mp_request))
|
self._consumer.send(*json.loads(mp_request))
|
||||||
|
|
||||||
|
|
||||||
def init_app(app):
|
class FakeMixpanel(object):
|
||||||
logger.debug('Initializing mixpanel with key: %s' %
|
def track(*args, **kwargs):
|
||||||
app.config['MIXPANEL_KEY'])
|
pass
|
||||||
|
|
||||||
request_queue = Queue()
|
|
||||||
mixpanel = Mixpanel(app.config['MIXPANEL_KEY'],
|
|
||||||
MixpanelQueingConsumer(request_queue))
|
|
||||||
SendToMixpanel(request_queue).start()
|
|
||||||
|
|
||||||
return mixpanel
|
class Analytics(object):
|
||||||
|
def __init__(self, app=None):
|
||||||
|
self.app = app
|
||||||
|
if app is not None:
|
||||||
|
self.state = self.init_app(app)
|
||||||
|
else:
|
||||||
|
self.state = None
|
||||||
|
|
||||||
|
def init_app(self, app):
|
||||||
|
analytics_type = app.config.get('ANALYTICS_TYPE', 'FakeAnalytics')
|
||||||
|
|
||||||
|
if analytics_type == 'Mixpanel':
|
||||||
|
mixpanel_key = app.config.get('MIXPANEL_KEY', '')
|
||||||
|
logger.debug('Initializing mixpanel with key: %s' %
|
||||||
|
app.config['MIXPANEL_KEY'])
|
||||||
|
|
||||||
|
request_queue = Queue()
|
||||||
|
analytics = Mixpanel(mixpanel_key, MixpanelQueingConsumer(request_queue))
|
||||||
|
SendToMixpanel(request_queue).start()
|
||||||
|
|
||||||
|
else:
|
||||||
|
analytics = FakeMixpanel()
|
||||||
|
|
||||||
|
# register extension with app
|
||||||
|
app.extensions = getattr(app, 'extensions', {})
|
||||||
|
app.extensions['analytics'] = analytics
|
||||||
|
return analytics
|
||||||
|
|
||||||
|
def __getattr__(self, name):
|
||||||
|
return getattr(self.state, name, None)
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
import logging
|
import logging
|
||||||
import json
|
import json
|
||||||
|
|
||||||
from app import mixpanel
|
from app import analytics
|
||||||
from flask import request, abort as flask_abort, make_response, current_app
|
from flask import request, abort as flask_abort, make_response, current_app
|
||||||
from auth.auth_context import get_authenticated_user, get_validated_token
|
from auth.auth_context import get_authenticated_user, get_validated_token
|
||||||
|
|
||||||
|
@ -32,10 +32,10 @@ def abort(status_code, message=None, issue=None, headers=None, **kwargs):
|
||||||
auth_user = get_authenticated_user()
|
auth_user = get_authenticated_user()
|
||||||
auth_token = get_validated_token()
|
auth_token = get_validated_token()
|
||||||
if auth_user:
|
if auth_user:
|
||||||
mixpanel.track(auth_user.username, 'http_error', params)
|
analytics.track(auth_user.username, 'http_error', params)
|
||||||
message = '%s (user: %s)' % (message, auth_user.username)
|
message = '%s (user: %s)' % (message, auth_user.username)
|
||||||
elif auth_token:
|
elif auth_token:
|
||||||
mixpanel.track(auth_token.code, 'http_error', params)
|
analytics.track(auth_token.code, 'http_error', params)
|
||||||
message = '%s (token: %s)' % (message,
|
message = '%s (token: %s)' % (message,
|
||||||
auth_token.friendly_name or auth_token.code)
|
auth_token.friendly_name or auth_token.code)
|
||||||
|
|
||||||
|
|
Reference in a new issue