diff --git a/src/master/bugreporter.py b/src/master/bugreporter.py new file mode 100644 index 0000000..de1c1c0 --- /dev/null +++ b/src/master/bugreporter.py @@ -0,0 +1,53 @@ +from master.settings import settings +import smtplib +from utils.log import logger +from utils import env +from email.mime.text import MIMEText +from email.mime.multipart import MIMEMultipart +from email.header import Header +from datetime import datetime +import json + +def send_bug_mail(username, bugmessage): + #admin_email_address = env.getenv('ADMIN_EMAIL_ADDRESS') + nulladdr = ['\'\'', '\"\"', ''] + email_from_address = settings.get('EMAIL_FROM_ADDRESS') + admin_email_address = settings.get('ADMIN_EMAIL_ADDRESS') + logger.info("receive bug from %s: %s" % (username, bugmessage)) + if (email_from_address in nulladdr or admin_email_address in nulladdr): + return {'success': 'false'} + #text = 'Dear '+ username + ':\n' + ' Your account in docklet has been activated' + text = '
A bug has been report by %s.
+Please check it !
+Docklet Team, SEI, PKU
+ ''' % (username, bugmessage) + text += ''+ str(datetime.utcnow()) + '
' + text += '' + subject = 'A bug of Docklet has been reported' + if admin_email_address[0] == '"': + admins_addr = admin_email_address[1:-1].split(" ") + else: + admins_addr = admin_email_address.split(" ") + alladdr="" + for addr in admins_addr: + alladdr = alladdr+addr+", " + alladdr=alladdr[:-2] + msg = MIMEMultipart() + textmsg = MIMEText(text,'html','utf-8') + msg['Subject'] = Header(subject, 'utf-8') + msg['From'] = email_from_address + msg['To'] = alladdr + msg.attach(textmsg) + s = smtplib.SMTP() + s.connect() + try: + s.sendmail(email_from_address, admins_addr, msg.as_string()) + except Exception as e: + logger.error(e) + s.close() + return {'success':'true'} diff --git a/src/master/vclustermgr.py b/src/master/vclustermgr.py index 54ceea1..caef4ad 100755 --- a/src/master/vclustermgr.py +++ b/src/master/vclustermgr.py @@ -116,6 +116,8 @@ class VclusterMgr(object): def create_cluster(self, clustername, username, image, user_info, setting): if self.is_cluster(clustername, username): return [False, "cluster:%s already exists" % clustername] + if self.imgmgr.get_image_size(image) + 100 > int(setting["disk"]): + return [False, "the size of disk is not big enough for the image"] clustersize = int(self.defaultsize) logger.info ("starting cluster %s with %d containers for %s" % (clustername, int(clustersize), username)) workers = self.nodemgr.get_base_nodeips() @@ -202,6 +204,8 @@ class VclusterMgr(object): def scale_out_cluster(self,clustername,username, image,user_info, setting): if not self.is_cluster(clustername,username): return [False, "cluster:%s not found" % clustername] + if self.imgmgr.get_image_size(image) + 100 > int(setting["disk"]): + return [False, "the size of disk is not big enough for the image"] workers = self.nodemgr.get_base_nodeips() if (len(workers) == 0): logger.warning("no workers to start containers, scale out failed") diff --git a/src/utils/imagemgr.py b/src/utils/imagemgr.py index fcb8873..889023a 100755 --- a/src/utils/imagemgr.py +++ b/src/utils/imagemgr.py @@ -380,6 +380,29 @@ class ImageMgr(): return "" return image.description + def get_image_size(self, image): + imagename = image['name'] + imagetype = image['type'] + imageowner = image['owner'] + if imagename == "base" and imagetype == "base": + return 0 + if imagetype == "private": + imgpath = self.imgpath + "private/" + user + "/" + else: + imgpath = self.imgpath + "public/" + imageowner + "/" + return os.stat(os.path.join(imgpath, imagename)).st_size // (1024*1024) + + + def format_size(self, size_in_byte): + if size_in_byte < 1024: + return str(size_in_byte) + "B" + elif size_in_byte < 1024*1024: + return str(size_in_byte//1024) + "KB" + elif size_in_byte < 1024*1024*1024: + return str(size_in_byte//(1024*1024)) + "MB" + else: + return str(size_in_byte//(1024*1024*1024)) + "GB" + def list_images(self,user): images = {} images["private"] = [] @@ -398,6 +421,9 @@ class ImageMgr(): [time, description] = self.get_image_info(user, imagename, "private") fimage["time"] = time fimage["description"] = description + fimage["size"] = os.stat(os.path.join(imgpath, image)).st_size + fimage["size_format"] = self.format_size(fimage["size"]) + fimage["size_in_mb"] = fimage["size"] // (1024*1024) images["private"].append(fimage) except Exception as e: logger.error(e) @@ -423,6 +449,9 @@ class ImageMgr(): [time, description] = self.get_image_info(public_user, imagename, "public") fimage["time"] = time fimage["description"] = description + fimage["size"] = os.stat(os.path.join(imgpath, image)).st_size + fimage["size_format"] = self.format_size(fimage["size"]) + fimage["size_in_mb"] = fimage["size"] // (1024*1024) images["public"][public_user].append(fimage) except Exception as e: logger.error(e) diff --git a/user/user.py b/user/user.py index 9a38c7f..522aa93 100755 --- a/user/user.py +++ b/user/user.py @@ -34,6 +34,7 @@ from utils.model import User,db from httplib2 import Http from urllib.parse import urlencode from master.settings import settings +from master.bugreporter import send_bug_mail external_login = env.getenv('EXTERNAL_LOGIN') if(external_login == 'TRUE'): @@ -472,6 +473,13 @@ def query_self_notifications_infos(cur_user, user, form): result = G_notificationmgr.query_self_notifications_infos(cur_user=cur_user, form=form) return json.dumps(result) +@app.route("/bug/report/", methods=['POST']) +@login_required +def report_bug(cur_user, user, form): + logger.info("handle request: bug/report") + result = send_bug_mail(user, form.get("bugmessage", None)) + return json.dumps(result) + @app.route("/billing/beans/", methods=['POST']) @auth_key_required def billing_beans(): diff --git a/web/templates/addCluster.html b/web/templates/addCluster.html index 8d24c24..de6ac2e 100644 --- a/web/templates/addCluster.html +++ b/web/templates/addCluster.html @@ -64,6 +64,7 @@{{message}}+