add disk quota, add button on adminpage to add quota #7

move system data to global/sys #41
This commit is contained in:
zhongyehong 2016-04-12 15:03:00 +08:00
parent 62a2b86e34
commit fd120f4232
10 changed files with 194 additions and 159 deletions

View File

@ -75,6 +75,8 @@ pre_start_master () {
[ ! -d $FS_PREFIX/global ] && mkdir -p $FS_PREFIX/global
[ ! -d $FS_PREFIX/local ] && mkdir -p $FS_PREFIX/local
[ ! -d $FS_PREFIX/global/users ] && mkdir -p $FS_PREFIX/global/users
[ ! -d $FS_PREFIX/global/sys ] && mkdir -p $FS_PREFIX/global/sys
[ ! -d $FS_PREFIX/global/images ] && mkdir -p $FS_PREFIX/global/images
[ ! -d $FS_PREFIX/local/volume ] && mkdir -p $FS_PREFIX/local/volume
[ ! -d $FS_PREFIX/local/temp ] && mkdir -p $FS_PREFIX/local/temp
[ ! -d $FS_PREFIX/local/run ] && mkdir -p $FS_PREFIX/local/run

View File

@ -27,8 +27,9 @@ class Container(object):
user_info = json.loads(user_info)
cpu = user_info["data"]["groupinfo"]["cpu"]
memory = user_info["data"]["groupinfo"]["memory"]
disk = user_info["data"]["groupinfo"]["disk"]
image = json.loads(image)
status = self.imgmgr.prepareFS(username,image,lxc_name)
status = self.imgmgr.prepareFS(username,image,lxc_name,disk)
if not status:
return [False, "Create container failed when preparing filesystem, possibly insufficient space"]

View File

@ -423,6 +423,9 @@ class DockletHttpHandler(http.server.BaseHTTPRequestHandler):
elif cmds[1] == 'groupadd':
result = G_usermgr.groupadd(form = form, cur_user = cur_user)
self.response(200, result)
elif cmds[1] == 'quotaadd':
result = G_usermgr.quotaadd(form = form, cur_user = cur_user)
self.response(200, result)
elif cmds[1] == 'groupdel':
result = G_usermgr.groupdel(name = form.getvalue('name', None), cur_user = cur_user)
self.response(200, result)

View File

@ -40,7 +40,7 @@ import env
fsdir = env.getenv('FS_PREFIX')
app = Flask(__name__)
app.config['SQLALCHEMY_DATABASE_URI'] = 'sqlite:///'+fsdir+'/local/UserTable.db'
app.config['SQLALCHEMY_DATABASE_URI'] = 'sqlite:///'+fsdir+'/global/sys/UserTable.db'
try:
secret_key_file = open(env.getenv('FS_PREFIX') + '/local/token_secret_key.txt')
app.secret_key = secret_key_file.read()

View File

@ -20,6 +20,7 @@ from email.mime.multipart import MIMEMultipart
from email.header import Header
from datetime import datetime
import json
from log import logger
email_from_address = env.getenv('EMAIL_FROM_ADDRESS')
admin_email_address = env.getenv('ADMIN_EMAIL_ADDRESS')
@ -145,12 +146,13 @@ class userManager:
path = env.getenv('DOCKLET_LIB')
subprocess.call([path+"/userinit.sh", username])
db.session.commit()
if not os.path.exists(fspath+"/global/group"):
groupfile = open(fspath+"/global/group",'w')
if not os.path.exists(fspath+"/global/sys/quota"):
groupfile = open(fspath+"/global/sys/quota",'w')
groups = []
groups.append({'name':'root', 'cpu':'100000', 'memory':'2000', 'imageQuantity':'10', 'lifeCycle':'24'})
groups.append({'name':'admin', 'cpu':'100000', 'memory':'2000', 'imageQuantity':'10', 'lifeCycle':'24'})
groups.append({'name':'primary', 'cpu':'100000', 'memory':'2000', 'imageQuantity':'10', 'lifeCycle':'24'})
groups.append({'name':'root', 'quotas':{ 'cpu':'100000', 'disk':'2000', 'memory':'2000', 'imageQuantity':'10', 'lifeCycle':'24'}})
groups.append({'name':'admin', 'quotas':{'cpu':'100000', 'disk':'2000', 'memory':'2000', 'imageQuantity':'10', 'lifeCycle':'24'}})
groups.append({'name':'primary', 'quotas':{'cpu':'100000', 'disk':'2000', 'memory':'2000', 'imageQuantity':'10', 'lifeCycle':'24'}})
groups.append({'name':'fundamental', 'quotas':{'cpu':'100000', 'disk':'2000', 'memory':'2000', 'imageQuantity':'10', 'lifeCycle':'24'}})
groupfile.write(json.dumps(groups))
groupfile.close()
@ -356,18 +358,18 @@ class userManager:
List informantion for oneself
'''
user = kwargs['cur_user']
groupfile = open(fspath+"/global/group",'r')
groupfile = open(fspath+"/global/sys/quota",'r')
groups = json.loads(groupfile.read())
groupfile.close()
group = None
for one_group in groups:
if one_group['name'] == user.user_group:
group = one_group
group = one_group['quotas']
break
else:
for one_group in groups:
if one_group['name'] == "primary":
group = one_group
group = one_group['quotas']
break
result = {
"success": 'true',
@ -385,12 +387,7 @@ class userManager:
"tel" : user.tel,
"register_date" : "%s"%(user.register_date),
"group" : user.user_group,
"groupinfo": {
"cpu": group['cpu'],
"memory": group['memory'],
"imageQuantity": group['imageQuantity'],
"lifeCycle":group['lifeCycle'],
},
"groupinfo": group,
},
}
return result
@ -458,24 +455,14 @@ class userManager:
Usage: list(cur_user = token_from_auth)
List all groups for an administrator
'''
groupfile = open(fspath+"/global/group",'r')
groupfile = open(fspath+"/global/sys/quota",'r')
groups = json.loads(groupfile.read())
groupfile.close()
result = {
"success": 'true',
"data":[]
"groups": groups,
"quotas": list(groups[0]['quotas'].keys()),
}
for group in groups:
groupinfo = [
group['name'],
group['cpu'],
group['memory'],
group['imageQuantity'],
group['lifeCycle'],
'',
]
result["data"].append(groupinfo)
return result
@administration_required
@ -484,20 +471,14 @@ class userManager:
Usage: groupQuery(name = XXX, cur_user = token_from_auth)
List a group for an administrator
'''
groupfile = open(fspath+"/global/group",'r')
groupfile = open(fspath+"/global/sys/quota",'r')
groups = json.loads(groupfile.read())
groupfile.close()
for group in groups:
if group['name'] == kwargs['name']:
result = {
"success":'true',
"data":{
"name" : group['name'] ,
"cpu" : group['cpu'] ,
"memory" : group['memory'],
"imageQuantity" : group['imageQuantity'],
"lifeCycle" : group['lifeCycle'],
}
"data": group,
}
return result
else:
@ -509,7 +490,7 @@ class userManager:
Usage: grouplist(cur_user = token_from_auth)
List all group names for an administrator
'''
groupfile = open(fspath+"/global/group",'r')
groupfile = open(fspath+"/global/sys/quota",'r')
groups = json.loads(groupfile.read())
groupfile.close()
result = {
@ -524,17 +505,18 @@ class userManager:
'''
Usage: groupModify(newValue = dict_from_form, cur_user = token_from_auth)
'''
groupfile = open(fspath+"/global/group",'r')
groupfile = open(fspath+"/global/sys/quota",'r')
groups = json.loads(groupfile.read())
groupfile.close()
for group in groups:
if group['name'] == kwargs['newValue'].getvalue('groupname',None):
form = kwargs['newValue']
group['cpu'] = form.getvalue('cpu', '')
group['memory'] = form.getvalue('memory', '')
group['imageQuantity'] = form.getvalue('image', '')
group['lifeCycle'] = form.getvalue('lifecycle', '')
groupfile = open(fspath+"/global/group",'w')
for key in form.keys():
if key == "groupname" or key == "token":
pass
else:
group['quotas'][key] = form.getvalue(key)
groupfile = open(fspath+"/global/sys/quota",'w')
groupfile.write(json.dumps(groups))
groupfile.close()
return {"success":'true'}
@ -622,15 +604,44 @@ class userManager:
return {"success":'true'}
@administration_required
def groupadd(*args, **kwargs):
def quotaadd(*args, **kwargs):
form = kwargs.get('form')
if (form.getvalue("name") == None):
return {"success":'false', "reason": "Empty group name"}
groupfile = open(fspath+"/global/group",'r')
quotaname = form.getvalue("quotaname")
default_value = form.getvalue("default_value")
if (quotaname == None):
return { "success":'false', "reason": "Empty quota name"}
if (default_value == None):
default_value = "--"
groupfile = open(fspath+"/global/sys/quota",'r')
groups = json.loads(groupfile.read())
groupfile.close()
groups.append({'name':form.getvalue("name"), 'cpu':form.getvalue("cpu"), 'memory':form.getvalue("memory"), 'imageQuantity':form.getvalue("image"), 'lifeCycle':form.getvalue("lifecycle")})
groupfile = open(fspath+"/global/group",'w')
for group in groups:
group['quotas'][quotaname] = default_value
groupfile = open(fspath+"/global/sys/quota",'w')
groupfile.write(json.dumps(groups))
groupfile.close()
return {"success":'true'}
@administration_required
def groupadd(*args, **kwargs):
form = kwargs.get('form')
groupname = form.getvalue("groupname")
if (groupname == None):
return {"success":'false', "reason": "Empty group name"}
groupfile = open(fspath+"/global/sys/quota",'r')
groups = json.loads(groupfile.read())
groupfile.close()
group = {
'name': groupname,
'quotas': {}
}
for key in form.keys():
if key == "groupname" or key == "token":
pass
else:
group['quotas'][key] = form.getvalue(key)
groups.append(group)
groupfile = open(fspath+"/global/sys/quota",'w')
groupfile.write(json.dumps(groups))
groupfile.close()
return {"success":'true'}
@ -640,14 +651,14 @@ class userManager:
name = kwargs.get('name', None)
if (name == None):
return {"success":'false', "reason": "Empty group name"}
groupfile = open(fspath+"/global/group",'r')
groupfile = open(fspath+"/global/sys/quota",'r')
groups = json.loads(groupfile.read())
groupfile.close()
for group in groups:
if group['name'] == name:
groups.remove(group)
break
groupfile = open(fspath+"/global/group",'w')
groupfile = open(fspath+"/global/sys/quota",'w')
groupfile.write(json.dumps(groups))
groupfile.close()
return {"success":'true'}

View File

@ -52,26 +52,15 @@
<form action="/group/add/" method="POST" id="addGroupForm">
<div class="form-group">
<label>Group Name</label>
<input type = "text" placeholder="Enter GroupName" class="form-control" name="name" id="mymyname">
<label>Name</label>
<input type="text" placeholder="Enter Name" class="form-control" name="name"/>
</div>
{% for quota in quotas %}
<div class="form-group">
<label>CPU Quota</label>
<input type = "text" placeholder="Enter CPU Quota" class="form-control" name="cpu" id="myCpu" value="100000">
<label>{{ quota }}</label>
<input type="text" placeholder="Enter {{ quota }}" class="form-control" name={{ quota }} />
</div>
<div class="form-group">
<label>Memory Quota</label>
<input type="text" placeholder="Enter Memory Quota" class="form-control" name="memory" id="myMemory" value="2000">
</div>
<div class="form-group">
<label>Image Quantity</label>
<input type = "text" placeholder="Enter Image Quantity" class="form-control" name="image" id="myImage" value="10">
</div>
<div class="form-group">
<label>Life Cycle</label>
<input type = "text" placeholder="Enter Life Cycle" class="form-control" name="lifecycle" id="myLifecycle" value="24">
</div>
{% endfor %}
</form>
</div>
@ -82,20 +71,61 @@
</div>
</div>
</div>
<button type="button" class="btn btn-primary btn-sm" data-toggle="modal" data-target="#AddQuotaModal"><i class="fa fa-plus"></i> Add Quota</button>
<div class="modal inmodal" id="AddQuotaModal" tabindex="-1" role="dialog" aria-hidden="true">
<div class="modal-dialog">
<div class="modal-content animated fadeIn">
<div class="modal-header">
<button type="button" class="close" data-dismiss="modal"><span aria-hidden="true">&times;</span><span class="sr-only">Close</span></button>
<i class="fa fa-laptop modal-icon"></i>
<h4 class="modal-title">Add Quota</h4>
<small class="font-bold">Add a quota to Docklet</small>
</div>
<div class="modal-body">
<form action="/quota/add/" method="POST" id="addQuotaForm">
<div class="form-group">
<label>Name</label>
<input type="text" placeholder="Enter Name" class="form-control" name="quotaname"/>
</div>
<div class="form-group">
<label>Default Value</label>
<input type="text" placeholder="Enter Default Value" class="form-control" name="default_value"/>
</div>
</form>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-white" data-dismiss="modal">Close</button>
<button type="button" class="btn btn-primary" onClick="javascript:sendAddQuota();">Submit</button>
</div>
</div>
</div>
</div>
<table id="myGroupTable" class="table table-striped table-bordered">
<thead>
<tr>
<th>Name</th>
<th>CPU</th>
<th>Memory</th>
<th>ImageQuantity</th>
<th>LifeCycle</th>
{% for quota in quotas %}
<th> {{ quota }} </th>
{% endfor %}
<th>Command</th>
</tr>
</thead>
<tbody>
</tbody>
<div class="modal inmodal" id="ModifyGroupModal" tabindex="-1" role="dialog" aria-hidden="true">
{% for group in groups %}
<tr>
<th>{{ group['name'] }}</th>
{% for quota in quotas %}
<th> {{ group['quotas'][quota] }} </th>
{% endfor %}
<th><a class="btn btn-xs btn-info" data-toggle="modal" data-target="#ModifyGroupModal_{{ group['name'] }}">Edit</a>&nbsp;
{% if group['name'] in [ "root", "primary", "admin", "fundamental" ] %}
<a class="btn btn-xs btn-default" href="javascript:void(0)">Delete</a></th>
{% else %}
<a class="btn btn-xs btn-danger" href="/group/delete/{{group['name']}}">Delete</a></th>
{% endif %}
<div class="modal inmodal" id="ModifyGroupModal_{{ group['name'] }}" tabindex="-1" role="dialog" aria-hidden="true">
<div class="modal-dialog">
<div class="modal-content animated fadeIn">
<div class="modal-header">
@ -104,37 +134,30 @@
<h4 class="modal-title">Modify Group</h4>
<small class="font-bold">Modify a group in Docklet</small>
</div>
<form action="/group/modify/{{group['name']}}/" method="POST" >
<div class="modal-body">
<form action="/group/modify/" method="POST" id="modifyGroupForm">
<div class="form-group">
<label>Group Name</label>
<input type = "text" placeholder="Enter Groupname" class="form-control" name="groupname" id="mGroupname" readonly="readonly">
<label>Name</label>
<input type="text" placeholder="Enter Name" class="form-control" name="groupname" readonly="true" value={{ group['name'] }} />
</div>
{% for quota in quotas %}
<div class="form-group">
<label>CPU Quota</label>
<input type = "text" placeholder="Enter CPU Quota" class="form-control" name="cpu" id="mCpu">
<label> {{ quota }}</label>
<input type="text" placeholder="Enter {{ quota }}" class="form-control" name={{ quota }} value={{ group['quotas'][quota] }} />
</div>
<div class="form-group">
<label>Memory Quota</label>
<input type="text" placeholder="Enter Memory Quota" class="form-control" name="memory" id="mMemory">
</div>
<div class="form-group">
<label>Image Quantity</label>
<input type = "text" placeholder="Enter Image Quantity" class="form-control" name="image" id="mImage">
</div>
<div class="form-group">
<label>Life Cycle</label>
<input type = "text" placeholder="Enter Life Cycle" class="form-control" name="lifecycle" id="mLifecycle">
</div>
</form>
{% endfor %}
</div>
<div class="modal-footer">
<button type="button" class="btn btn-white" data-dismiss="modal">Close</button>
<button type="button" class="btn btn-primary" onClick="javascript:sendModifyGroup();">Submit</button>
</div>
<button type="submit" class="btn btn-primary">Submit</button>
</div>
</form>
</div>
</div>
</div>
</tr>
{% endfor %}
</tbody>
</table>
</div>
</div>
@ -149,30 +172,11 @@
<script type="text/javascript">
$(document).ready(function() {
var gTable = $('#myGroupTable').dataTable({
"ajax": {
"url": "/group/detail/",
"type": "POST"
},
//"scrollX": true,
"columnDefs": [
{
"render": function ( data, type, row ) {
return '<a class="btn btn-xs btn-info" data-toggle="modal" data-target="#ModifyGroupModal" onClick="javascript:setFormGroup('+ "'" + row[0] + "'" + ');">' + 'Edit' + '</a>'
+ '&nbsp;' +'<a class="btn btn-xs btn-danger" href="/group/delete/' + row[0] +'">' + 'Delete' + '</a>';
},
"targets": 5
},
]
});
});
function sendAddGroup(){
document.getElementById("addGroupForm").submit();
}
function sendModifyGroup(){
document.getElementById("modifyGroupForm").submit();
function sendAddQuota(){
document.getElementById("addQuotaForm").submit();
}
function setFormGroup(arg){
$.post("/group/query/",

View File

@ -68,7 +68,7 @@
</div>
<div class="modal-body">
<div class="form-group">
<form action="/workspace/scaleout/{{ clustername }}/" method="POST" id="scaleout">
<form action="/workspace/scaleout/{{ clustername }}/" method="POST" >
<table class="table table-striped table-bordered table-hover table-image">
<thead>
<tr>

View File

@ -20,7 +20,7 @@ from webViews.log import logger
from flask import Flask, request, session, render_template, redirect, send_from_directory, make_response, url_for, abort
from webViews.dashboard import dashboardView
from webViews.user.userlist import userlistView, useraddView, usermodifyView, groupaddView, groupdelView, userdataView, userqueryView
from webViews.user.userlist import userlistView, useraddView, usermodifyView, userdataView, userqueryView
from webViews.user.userinfo import userinfoView
from webViews.user.userActivate import userActivateView
from webViews.user.grouplist import grouplistView, groupqueryView, groupdetailView, groupmodifyView
@ -303,9 +303,9 @@ def groupdetail():
def groupquery():
return groupqueryView.as_view()
@app.route("/group/modify/", methods=['POST'])
@app.route("/group/modify/<groupname>/", methods=['POST'])
@administration_required
def groupmodify():
def groupmodify(groupname):
return groupmodifyView.as_view()
@app.route("/user/data/", methods=['GET', 'POST'])
@ -323,6 +323,11 @@ def useradd():
def usermodify():
return usermodifyView.as_view()
@app.route("/quota/add/", methods=['POST'])
@administration_required
def quotaadd():
return quotaaddView.as_view()
@app.route("/group/add/", methods=['POST'])
@administration_required
def groupadd():

View File

@ -1,14 +1,40 @@
from flask import session
from flask import session, render_template, redirect, request
from webViews.view import normalView
from webViews.dockletrequest import dockletRequest
from webViews.dashboard import *
import time, re
import time, re, json
class adminView(normalView):
template_path = "admin.html"
@classmethod
def get(self):
groups = dockletRequest.post('/user/groupNameList/')["groups"]
return self.render(self.template_path, groups = groups)
result = dockletRequest.post('/user/groupList/')
groups = result["groups"]
quotas = result["quotas"]
return self.render(self.template_path, groups = groups, quotas = quotas)
class groupaddView(normalView):
@classmethod
def post(self):
dockletRequest.post('/user/groupadd', request.form)
return redirect('/admin/')
class quotaaddView(normalView):
@classmethod
def post(self):
dockletRequest.post('/user/quotaadd', request.form)
return redirect('/admin/')
class groupdelView(normalView):
@classmethod
def post(self):
data = {
"name" : self.groupname,
}
dockletRequest.post('/user/groupdel', data)
return redirect('/admin/')
@classmethod
def get(self):
return self.post()

View File

@ -49,21 +49,4 @@ class usermodifyView(normalView):
return self.render('user/mailservererror.html')
return redirect('/user/list/')
class groupaddView(normalView):
@classmethod
def post(self):
dockletRequest.post('/user/groupadd', request.form)
return redirect('/admin/')
class groupdelView(normalView):
@classmethod
def post(self):
data = {
"name" : self.groupname,
}
dockletRequest.post('/user/groupdel', data)
return redirect('/admin/')
@classmethod
def get(self):
return self.post()