Commit 9cfc35dc authored by Daniele Venzano's avatar Daniele Venzano

Fixes and improvements

Remove the notebooks table
Add more general proxy management
Add back links to user web pages
parent 35caaf19
......@@ -12,6 +12,7 @@
<column name="user_id" sqlType="INT" precision="10" scale="0" nullable="false" jdbcType="4"/>
<column name="master_address" sqlType="VARCHAR" precision="512" scale="0" nullable="false" jdbcType="12"/>
<column name="name" sqlType="VARCHAR" precision="256" scale="0" nullable="false" jdbcType="12"/>
<column name="time_created" sqlType="TIMESTAMP" precision="19" scale="0" nullable="false" jdbcType="93" def="Q1VSUkVOVF9USU1FU1RBTVA="/>
<primary-key name="PRIMARY" columns="id"/>
</table>
<table name="containers" schema="" catalog="caaas" type="TABLE">
......@@ -23,21 +24,12 @@
<column name="contents" sqlType="VARCHAR" precision="512" scale="0" nullable="false" jdbcType="12"/>
<primary-key name="PRIMARY" columns="id"/>
</table>
<table name="notebooks" schema="" catalog="caaas" type="TABLE">
<column name="id" sqlType="INT" precision="10" scale="0" nullable="false" jdbcType="4" autoIncrement="true"/>
<column name="cluster_id" sqlType="INT" precision="10" scale="0" nullable="false" jdbcType="4"/>
<column name="time_created" sqlType="TIMESTAMP" precision="19" scale="0" nullable="false" jdbcType="93" def="Q1VSUkVOVF9USU1FU1RBTVA="/>
<column name="address" sqlType="VARCHAR" precision="512" scale="0" nullable="false" jdbcType="12"/>
<column name="user_id" sqlType="INT" precision="10" scale="0" nullable="false" jdbcType="4"/>
<column name="container_id" sqlType="INT" precision="10" scale="0" nullable="false" jdbcType="4"/>
<primary-key name="PRIMARY" columns="id"/>
</table>
<table name="proxy" schema="" catalog="caaas" type="TABLE">
<column name="id" sqlType="INT" precision="10" scale="0" nullable="false" jdbcType="4" autoIncrement="true"/>
<column name="proxy_id" sqlType="VARCHAR" precision="512" scale="0" nullable="false" jdbcType="12"/>
<column name="url" sqlType="VARCHAR" precision="512" scale="0" nullable="false" jdbcType="12"/>
<column name="internal_url" sqlType="VARCHAR" precision="512" scale="0" nullable="true" jdbcType="12"/>
<column name="cluster_id" sqlType="INT" precision="10" scale="0" nullable="false" jdbcType="4"/>
<column name="proxy_type" sqlType="VARCHAR" precision="64" scale="0" nullable="false" jdbcType="12"/>
<column name="service_name" sqlType="VARCHAR" precision="64" scale="0" nullable="true" jdbcType="12"/>
<column name="container_id" sqlType="INT" precision="10" scale="0" nullable="false" jdbcType="4"/>
<primary-key name="PRIMARY" columns="id"/>
</table>
......
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="DataSourceManagerImpl" format="xml" hash="2263423227">
<component name="DataSourceManagerImpl" format="xml" hash="3069628127">
<data-source source="LOCAL" name="MySQL - @m1" uuid="a32fd6de-3ffa-40c0-9ec8-8953a89c53e0">
<driver-ref>mysql</driver-ref>
<synchronize>true</synchronize>
......
This diff is collapsed.
......@@ -9,16 +9,22 @@ from caaas import CAaaState
OUTFILE = "/tmp/caaas-proxy.conf"
ENTRY_TEMPLATE = """
# CAaaS proxy entry for service {{ service_name }}
<Location /proxy/{{ proxy_id }}>
ProxyHtmlEnable On
ProxyHTMLExtended On
ProxyPass {{ proxy_url }}
ProxyPass {{ proxy_url }} retry=1
ProxyPassReverse {{ proxy_url }}
{% if proxy_type != "spark-notebook" %}
{% if service_name != "notebook" %}
ProxyHTMLURLMap ^/(.*)$ /proxy/{{ proxy_id }}/$1 RL
ProxyHTMLURLMap ^logPage(.*)$ /proxy/{{ proxy_id }}/logPage$1 RL
ProxyHTMLURLMap ^app(.*)$ /proxy/{{ proxy_id }}/app$1 RL
{% for node in nodes %}
ProxyHTMLURLMap ^http://{{ node[0] }}(.*)$ /proxy/{{node[1]}}$1 RL
{% endfor %}
{% endif %}
</Location>
{% if proxy_type == "spark-notebook" %}
{% if service_name == "notebook" %}
<Location /proxy/{{ proxy_id }}/ws/>
ProxyPass ws://{{ netloc }}/proxy/{{ proxy_id }}/ws/
</Location>
......@@ -28,19 +34,24 @@ ENTRY_TEMPLATE = """
def get_proxy_entries():
db = CAaaState()
return db.get_all_proxy()
return db.get_proxies()
def generate_file(proxy_entries):
output = ""
jinja_template = Template(ENTRY_TEMPLATE)
for proxy_id, proxy_url, proxy_type, cont_id in proxy_entries:
netloc = urlparse(proxy_url)[1]
node_list = []
for p in proxy_entries:
netloc = urlparse(p["internal_url"])[1]
node_list.append((netloc, p["proxy_id"]))
for p in proxy_entries:
netloc = urlparse(p["internal_url"])[1]
jinja_dict = {
"proxy_id": proxy_id,
"proxy_url": proxy_url,
"proxy_type": proxy_type,
"netloc": netloc
"proxy_id": p["proxy_id"],
"proxy_url": p["internal_url"],
"service_name": p["service_name"],
"netloc": netloc,
"nodes": node_list
}
apache_entry = jinja_template.render(jinja_dict)
output += apache_entry + "\n"
......
......@@ -5,4 +5,7 @@ swarm-manager = tcp://127.0.0.1:2380
user = caaas
pass = changeme
server = 127.0.0.1
db = caaas
\ No newline at end of file
db = caaas
[proxy]
base_url = http://some-host/some-path
from caaas import CAaaState
from utils.config import get_proxy_base
def _generate_proxied_url(proxy_id):
return get_proxy_base() + "/" + proxy_id
def get_container_addresses(container_id):
state = CAaaState()
proxy_list = state.get_proxies(container_id=container_id)
urls = []
for p in proxy_list:
external_url = _generate_proxied_url(p["proxy_id"])
urls.append((p["service_name"], external_url))
return urls
def get_notebook_address(cluster_id):
state = CAaaState()
proxy_id = state.get_proxy_for_service(cluster_id, "notebook")
return _generate_proxied_url(proxy_id)
......@@ -94,16 +94,15 @@ class CAaaState:
def get_notebook(self, user_id):
cursor = self._get_cursor(dictionary=True)
q = "SELECT * FROM notebooks WHERE user_id=%s"
q = "SELECT id FROM clusters WHERE user_id=%s and name='notebook'"
cursor.execute(q, (user_id,))
if cursor.rowcount == 0:
self.cnx.commit()
cursor.close()
self._close_cursor(cursor)
return None
else:
row = cursor.fetchone()
self._close_cursor(cursor)
return row
return row["id"]
def has_notebook(self, user_id):
ret = self.get_notebook(user_id)
......@@ -111,7 +110,7 @@ class CAaaState:
def get_url_proxy(self, proxy_id):
cursor = self._get_cursor()
q = "SELECT url FROM proxy WHERE proxy_id=%s"
q = "SELECT internal_url FROM proxy WHERE proxy_id=%s"
cursor.execute(q, (proxy_id,))
if cursor.rowcount == 0:
self._close_cursor(cursor)
......@@ -121,15 +120,17 @@ class CAaaState:
self._close_cursor(cursor)
return row[0]
def get_all_proxy(self):
def get_proxy_for_service(self, cluster_id, service_name):
cursor = self._get_cursor()
q = "SELECT proxy_id, url, proxy_type, container_id FROM proxy"
cursor.execute(q)
proxy_list = []
for proxy_id, url, proxy_type, container_id in cursor:
proxy_list.append((proxy_id, url, proxy_type, container_id))
self._close_cursor(cursor)
return proxy_list
q = "SELECT proxy_id FROM proxy WHERE cluster_id=%s AND service_name=%s"
cursor.execute(q, (cluster_id, service_name))
if cursor.rowcount == 0:
self._close_cursor(cursor)
return None
else:
row = cursor.fetchone()
self._close_cursor(cursor)
return row[0]
def new_cluster(self, user_id, name):
cursor = self._get_cursor()
......@@ -154,21 +155,13 @@ class CAaaState:
self._close_cursor(cursor)
return cont_id
def new_proxy_entry(self, proxy_id, cluster_id, address, proxy_type, container_id):
def new_proxy_entry(self, proxy_id, cluster_id, address, service_name, container_id):
cursor = self._get_cursor()
q = "INSERT INTO proxy (proxy_id, url, cluster_id, proxy_type, container_id) VALUES (%s, %s, %s, %s, %s)"
cursor.execute(q, (proxy_id, address, cluster_id, proxy_type, container_id))
q = "INSERT INTO proxy (proxy_id, internal_url, cluster_id, service_name, container_id) VALUES (%s, %s, %s, %s, %s)"
cursor.execute(q, (proxy_id, address, cluster_id, service_name, container_id))
self._close_cursor(cursor)
return proxy_id
def new_notebook(self, cluster_id, address, user_id, container_id):
cursor = self._get_cursor()
q = "INSERT INTO notebooks (cluster_id, address, user_id, container_id) VALUES (%s, %s, %s, %s)"
cursor.execute(q, (cluster_id, address, user_id, container_id))
nb_id = cursor.lastrowid
self._close_cursor(cursor)
return nb_id
def get_clusters(self, user_id=None):
cursor = self._get_cursor(dictionary=True)
res = {}
......@@ -187,6 +180,20 @@ class CAaaState:
self._close_cursor(cursor)
return res
def get_cluster(self, cluster_id):
cursor = self._get_cursor(dictionary=True)
q = "SELECT user_id, master_address, name, time_created FROM clusters WHERE id=%s"
cursor.execute(q, (cluster_id,))
row = cursor.fetchone()
res = {
"user_id": row["user_id"],
"master_address": row["master_address"],
"name": row["name"],
"time_created": row["time_created"]
}
self._close_cursor(cursor)
return res
def get_containers(self, user_id=None, cluster_id=None):
cursor = self._get_cursor(dictionary=True)
res = {}
......@@ -214,15 +221,31 @@ class CAaaState:
self._close_cursor(cursor)
return res
def remove_proxy(self, container_id):
def get_proxies(self, cluster_id=None, container_id=None):
cursor = self._get_cursor()
q = "DELETE FROM proxy WHERE container_id=%s"
cursor.execute(q, (container_id,))
if cluster_id is None and container_id is None:
q = "SELECT proxy_id, internal_url, service_name, container_id FROM proxy"
cursor.execute(q)
elif container_id is not None:
q = "SELECT proxy_id, internal_url, service_name, container_id FROM proxy WHERE container_id=%s"
cursor.execute(q, (container_id,))
else:
q = "SELECT proxy_id, internal_url, service_name, container_id FROM proxy WHERE cluster_id=%s"
cursor.execute(q, (cluster_id,))
proxy_list = []
for proxy_id, url, service_name, container_id in cursor:
proxy_list.append({
'proxy_id': proxy_id,
'internal_url': url,
'service_name': service_name,
'container_id': container_id
})
self._close_cursor(cursor)
return proxy_list
def remove_notebook(self, container_id):
def remove_proxy(self, container_id):
cursor = self._get_cursor()
q = "DELETE FROM notebooks WHERE container_id=%s"
q = "DELETE FROM proxy WHERE container_id=%s"
cursor.execute(q, (container_id,))
self._close_cursor(cursor)
......
......@@ -6,6 +6,7 @@ from uuid import uuid4 as uuid
from caaas import CAaaState
from caaas import SparkClusterDescription
from caaas.proxy_manager import get_notebook_address
from utils import config
REGISTRY = "10.0.0.2:5000"
......@@ -49,7 +50,7 @@ class SwarmManager:
if nb is None:
self.start_cluster_with_notebook(user_id)
nb = db.get_notebook(user_id)
return nb["address"]
return get_notebook_address(nb)
def start_cluster_with_notebook(self, user_id):
cluster_descr = SparkClusterDescription()
......@@ -78,7 +79,7 @@ class SwarmManager:
info = self._spawn_container(MASTER_IMAGE, options)
info["spark_master_address"] = "http://" + info["docker_ip"] + ":8080"
cont_id = db.new_container(cluster_id, user_id, info["docker_id"], info["docker_ip"], "spark-master")
db.new_proxy_entry(get_uuid(), cluster_id, info["spark_master_address"], "spark-master", cont_id)
db.new_proxy_entry(get_uuid(), cluster_id, info["spark_master_address"], "web interface", cont_id)
return info
def _spawn_spark_worker(self, cluster_id, user_id, cluster_descr, master_info):
......@@ -92,7 +93,7 @@ class SwarmManager:
}
info = self._spawn_container(WORKER_IMAGE, options)
cont_id = db.new_container(cluster_id, user_id, info["docker_id"], info["docker_ip"], "spark-worker")
db.new_proxy_entry(get_uuid(), cluster_id, "http://" + info["docker_ip"] + ":8081", "spark-worker", cont_id)
db.new_proxy_entry(get_uuid(), cluster_id, "http://" + info["docker_ip"] + ":8081", "web interface", cont_id)
return info
def _spawn_spark_notebook(self, cluster_id, user_id, cluster_descr, master_info):
......@@ -107,8 +108,8 @@ class SwarmManager:
}
info = self._spawn_container(CONTAINER_IMAGE, options)
cont_id = db.new_container(cluster_id, user_id, info["docker_id"], info["docker_ip"], "spark-notebook")
db.new_proxy_entry(proxy_id, cluster_id, "http://" + info["docker_ip"] + ":9000/proxy/" + proxy_id, "spark-notebook", cont_id)
db.new_notebook(cluster_id, "http://bigfoot-m2.eurecom.fr/proxy/" + proxy_id, user_id, cont_id)
db.new_proxy_entry(proxy_id, cluster_id, "http://" + info["docker_ip"] + ":9000/proxy/" + proxy_id, "notebook", cont_id)
db.new_proxy_entry(get_uuid(), cluster_id, "http://" + info["docker_ip"] + ":4040", "spark application", cont_id)
return info
def _spawn_container(self, image, options):
......@@ -129,8 +130,6 @@ class SwarmManager:
def _terminate_container(self, container_id, docker_id, contents):
db = CAaaState()
db.remove_proxy(container_id)
if contents == "spark-notebook":
db.remove_notebook(container_id)
self.cli.remove_container(docker_id, force=True)
db.remove_container(container_id)
......@@ -141,4 +140,3 @@ class SwarmManager:
self._terminate_container(cid, cinfo["docker_id"], cinfo["contents"])
db.remove_cluster(cluster_id)
return True
......@@ -11,7 +11,6 @@
{% endblock %}
</head>
<body>
<div class="header"><em>CAaaS</em> -- Available nodes: <span id="num_nodes">0</span> Containers: <span id="num_containers">0</span></div>
<script>
function update_status() {
$.getJSON( api_endpoint + "/status")
......@@ -23,10 +22,12 @@
update_status();
window.setInterval(update_status, 5000);
</script>
<h1>DSG CAaaS system - Analytics on demand</h1>
<div id="content">{% block content %}{% endblock %}</div>
<div id="footer">
{% block footer %}
&copy; Copyright 2015 by <a href="http://distsysgroup.wordpress.com/">DSG</a>.
<div class="caaas_status"><p><em>CAaaS</em> status: <span id="num_nodes">0</span> available nodes, <span id="num_containers">0</span> containers running</p></div>
<h6>&copy; Copyright 2015 by <a href="http://distsysgroup.wordpress.com/">DSG</a></h6>
{% endblock %}
</div>
</body>
......
{% extends "base.html" %}
{% block footer %}
<p>Back to the <a href="/web/{{ user }}">user home page</a></p>
{{ super() }}
{% endblock %}
{% extends "base.html" %}
{% extends "base_user.html" %}
{% block title %}Home{% endblock %}
{% block content %}
<h1>DSG CAaaS system - Analytics on demand</h1>
<p>Start an activity:</p>
<ul>
<li><a href="/web/{{ user }}/spark-notebook">Give me a Spark notebook</a></li>
......
......@@ -11,8 +11,6 @@ return false;
}
</script>
<h1>DSG CAaaS system - Analytics on demand</h1>
<form onSubmit="return process();">
<label>Type your username to start:
<input id="user" autofocus required pattern="[a-z]+"></label>
......
{% extends "base_user.html" %}
{% block title %}Inspect cluster {{ cluster_name }}{% endblock %}
{% block content %}
<h2>Detailed information for cluster {{ cluster_name }}</h2>
<p>Containers:</p>
<ul>
{% for c in containers %}
<li>{{ c[0] }}</li>
<ul>
{% for p in c[1] %}
<li><a href="{{ p[1] }}">{{ p[0] }}</a></li>
{% endfor %}
</ul>
{% endfor %}
</ul>
{% endblock %}
\ No newline at end of file
{% extends "base.html" %}
{% extends "base_user.html" %}
{% block title %}Spark notebook{% endblock %}
{% block content %}
<h1>Notebook</h1>
<h2>Notebook</h2>
<p>You notebook is available at: <a href="{{ notebook_address }}">{{ notebook_address }}</a></p>
......
{% extends "base.html" %}
{% extends "base_user.html" %}
{% block title %}Status{% endblock %}
{% block content %}
<script type="application/javascript">
......@@ -22,7 +22,7 @@
})();
</script>
<h1>System status overview</h1>
<h2>System status overview</h2>
<div id="userlist"></div>
{% endblock %}
\ No newline at end of file
{% extends "base_user.html" %}
{% block title %}Terminate cluster {{ cluster_name }}{% endblock %}
{% block content %}
<script type="application/javascript">
(function() {
$.getJSON( api_endpoint + "/{{ user }}/cluster/{{ cluster_id }}/terminate")
.done(function( data ) {
if (data.status == "ok") {
$("#result").empty().append("Cluster terminated succesfully");
} else {
$("#result").empty().append("Cluster did not terminate succesfully, something happened")
}
});
})();
</script>
<h2>Termination request for cluster {{ cluster_name }}</h2>
<p id="result">Request sent...</p>
{% endblock %}
\ No newline at end of file
{% extends "base.html" %}
{% extends "base_user.html" %}
{% block title %}{{ user }} status{% endblock %}
{% block content %}
<script type="application/javascript">
function gen_one_cluster(i, item) {
var block = $("<div></div>");
var cluster_name = item.name;
if (item.is_notebook) {
cluster_name += " (<a href=\"/api/{{ user }}/cluster/" + i + "/terminate\">terminate</a>)";
}
block.append("<p></p>").html(cluster_name);
var ul = $("<ul></ul>");
ul.append($("<li></li>").text("Num. containers: " + item.num_containers));
ul.append($("<li></li>").text("Notebook cluster: " + item.is_notebook));
block.append(ul);
return block;
}
(function() {
$.getJSON( api_endpoint + "/{{ user }}/status")
.done(function( data ) {
$.each(data, function(i, item) {
$("#cluster_list").append(gen_one_cluster(i, item))
})
});
})();
</script>
<h2>Status overview for user {{ user }}</h2>
<h1>Status overview for user {{ user }}</h1>
<div id="cluster_list">
{% if clusters|length == 0 %}
<p>You have no clusters running at this time</p>
{% endif %}
<div id="cluster_list"></div>
{% for c in clusters %}
<div class="cluster">
<p>{{ clusters[c]["name"] }} (<a href="/web/{{ user }}/cluster/{{ c }}/inspect">inspect</a>,
<a href="/web/{{ user }}/cluster/{{ c }}/terminate">terminate</a>)</p>
<ul>
<li>Num. containers: {{ clusters[c]["num_containers"] }}</li>
<li>Notebook cluster: {{ clusters[c]["is_notebook"] }}</li>
</ul>
</div>
{% endfor %}
</div>
{% endblock %}
\ No newline at end of file
from flask import render_template
from caaas import app, sm, CAaaState
from caaas.proxy_manager import get_container_addresses
@app.route("/web/")
......@@ -8,6 +9,11 @@ def index():
return render_template('index.html')
@app.route("/web/status")
def web_status():
return render_template('status.html')
@app.route("/web/<username>")
def web_index(username):
state = CAaaState()
......@@ -20,8 +26,15 @@ def web_index(username):
@app.route("/web/<username>/status")
def web_user_status(username):
db = CAaaState()
user_id = db.get_user_id(username)
cluster_list = db.get_clusters(user_id)
for clid in cluster_list:
cluster_list[clid]["is_notebook"] = cluster_list[clid]["name"] == "notebook"
cluster_list[clid]["num_containers"] = db.count_containers(user_id, clid)
template_vars = {
"user": username
"user": username,
"clusters": cluster_list
}
return render_template('user-status.html', **template_vars)
......@@ -37,6 +50,36 @@ def web_notebook(username):
return render_template('notebook.html', **template_vars)
@app.route("/web/status")
def web_status():
return render_template('status.html')
@app.route("/web/<username>/cluster/<cluster_id>/inspect")
def web_inspect(username, cluster_id):
state = CAaaState()
user_id = state.get_user_id(username)
cluster = state.get_cluster(cluster_id)
if cluster["user_id"] != user_id:
return "" # TODO
containers = state.get_containers(cluster_id=cluster_id)
clist = []
for cid, cinfo in containers.items():
plist = get_container_addresses(cid)
clist.append([cinfo["contents"], plist])
template_vars = {
"cluster_name": cluster["name"],
"containers": clist,
"user": username
}
return render_template('inspect.html', **template_vars)
@app.route("/web/<username>/cluster/<cluster_id>/terminate")
def web_terminate(username, cluster_id):
state = CAaaState()
user_id = state.get_user_id(username)
cluster = state.get_cluster(cluster_id)
if cluster["user_id"] != user_id:
return "" # TODO
template_vars = {
"cluster_name": cluster["name"],
"cluster_id": cluster_id,
"user": username
}
return render_template('terminate.html', **template_vars)
......@@ -3,7 +3,7 @@
-- http://www.phpmyadmin.net
--
-- Host: localhost
-- Generation Time: Aug 03, 2015 at 12:09 PM
-- Generation Time: Aug 06, 2015 at 10:16 AM
-- Server version: 5.5.44-MariaDB-1ubuntu0.14.04.1
-- PHP Version: 5.5.9-1ubuntu4.11
......@@ -32,10 +32,10 @@ DROP TABLE IF EXISTS `clusters`;
CREATE TABLE IF NOT EXISTS `clusters` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`user_id` int(11) NOT NULL,
`master_address` varchar(512) CHARACTER SET ascii COLLATE ascii_bin NOT NULL,
`name` varchar(256) CHARACTER SET utf8 COLLATE utf8_bin NOT NULL,
`master_address` varchar(512) CHARACTER SET ascii NOT NULL,
`name` varchar(256) NOT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 AUTO_INCREMENT=1 ;
) ENGINE=InnoDB DEFAULT CHARSET=utf8 AUTO_INCREMENT=11 ;
-- --------------------------------------------------------
......@@ -46,11 +46,13 @@ CREATE TABLE IF NOT EXISTS `clusters` (
DROP TABLE IF EXISTS `containers`;
CREATE TABLE IF NOT EXISTS `containers` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`docker_id` varchar(1024) CHARACTER SET ascii COLLATE ascii_bin NOT NULL,
`docker_id` varchar(1024) CHARACTER SET ascii NOT NULL,
`cluster_id` int(11) NOT NULL,
`user_id` int(11) NOT NULL,
`ip_address` varchar(16) NOT NULL,
`contents` varchar(512) NOT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 AUTO_INCREMENT=1 ;
) ENGINE=InnoDB DEFAULT CHARSET=utf8 AUTO_INCREMENT=37 ;
-- --------------------------------------------------------
......@@ -63,10 +65,28 @@ CREATE TABLE IF NOT EXISTS `notebooks` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`cluster_id` int(11) NOT NULL,
`time_created` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,
`address` varchar(512) CHARACTER SET ascii COLLATE ascii_bin NOT NULL,
`address` varchar(512) CHARACTER SET ascii NOT NULL,
`user_id` int(11) NOT NULL,
`container_id` int(11) NOT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 AUTO_INCREMENT=1 ;
) ENGINE=InnoDB DEFAULT CHARSET=utf8 AUTO_INCREMENT=10 ;
-- --------------------------------------------------------
--
-- Table structure for table `proxy`
--
DROP TABLE IF EXISTS `proxy`;
CREATE TABLE IF NOT EXISTS `proxy` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`proxy_id` varchar(512) NOT NULL,
`url` varchar(512) NOT NULL,
`cluster_id` int(11) NOT NULL,
`proxy_type` varchar(64) NOT NULL,
`container_id` int(11) NOT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 AUTO_INCREMENT=37 ;
-- --------------------------------------------------------
......@@ -77,9 +97,9 @@ CREATE TABLE IF NOT EXISTS `notebooks` (
DROP TABLE IF EXISTS `users`;
CREATE TABLE IF NOT EXISTS `users` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`username` varchar(32) COLLATE utf8_bin NOT NULL,
`username` varchar(32) NOT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_bin AUTO_INCREMENT=1 ;
) ENGINE=InnoDB DEFAULT CHARSET=utf8 AUTO_INCREMENT=3 ;
/*!40101 SET CHARACTER_SET_CLIENT=@OLD_CHARACTER_SET_CLIENT */;
/*!40101 SET CHARACTER_SET_RESULTS=@OLD_CHARACTER_SET_RESULTS */;
......
......@@ -20,3 +20,7 @@ def get_database_config():
'buffered': True
}
return db_config
def get_proxy_base():
return conf["proxy"]["base_url"]
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