Complete releasemgr

This commit is contained in:
Firmlyzhu 2019-05-07 17:34:17 +08:00
parent 677465209d
commit 332a8b8ae1
6 changed files with 52 additions and 14 deletions

View File

@ -183,6 +183,16 @@
# Only when you deploy docklet on the cloud can you set it to True # Only when you deploy docklet on the cloud can you set it to True
# ALLOW_SCALE_OUT=False # ALLOW_SCALE_OUT=False
# WARNING_DAYS: user will receive a warning email for releasing
# when his/her vcluster has been stopped for more then the days.
# Default: 7
# WARNING_DAYS=7
# RELEASE_DAYS: the vcluster will be released when it has been
# stopped for more then the days. Needs to be larger then WARNING_DAYS.
# Default: 14
# RELEASE_DAYS=14
# ================================================== # ==================================================
# #
# Batch Config # Batch Config

View File

@ -29,7 +29,7 @@ from socketserver import ThreadingMixIn
from utils import etcdlib, imagemgr from utils import etcdlib, imagemgr
from master import nodemgr, vclustermgr, notificationmgr, lockmgr, cloudmgr, jobmgr, taskmgr from master import nodemgr, vclustermgr, notificationmgr, lockmgr, cloudmgr, jobmgr, taskmgr
from utils.logs import logs from utils.logs import logs
from master import userManager, beansapplicationmgr, monitor, sysmgr, network from master import userManager, beansapplicationmgr, monitor, sysmgr, network, releasemgr
from worker.monitor import History_Manager from worker.monitor import History_Manager
import threading import threading
import requests import requests
@ -1162,6 +1162,10 @@ if __name__ == '__main__':
G_imagemgr = imagemgr.ImageMgr() G_imagemgr = imagemgr.ImageMgr()
logger.info("imagemgr started") logger.info("imagemgr started")
G_releasemgr = releasemgr.ReleaseMgr(G_vclustermgr,G_ulockmgr,10)
G_releasemgr.start()
logger.info("releasemgr started")
logger.info("startting to listen on: ") logger.info("startting to listen on: ")
masterip = env.getenv('MASTER_IP') masterip = env.getenv('MASTER_IP')
logger.info("using MASTER_IP %s", masterip) logger.info("using MASTER_IP %s", masterip)

View File

@ -2,7 +2,11 @@ import threading, time
from utils import env from utils import env
from utils.log import logger from utils.log import logger
from utils.model import db, VCluster, Container from utils.model import db, VCluster, Container
import datetime import smtplib, datetime
from email.mime.text import MIMEText
from email.mime.multipart import MIMEMultipart
from email.header import Header
from master.settings import settings
userpoint = "http://" + env.getenv('USER_IP') + ":" + str(env.getenv('USER_PORT')) userpoint = "http://" + env.getenv('USER_IP') + ":" + str(env.getenv('USER_PORT'))
def post_to_user(url = '/', data={}): def post_to_user(url = '/', data={}):
@ -18,8 +22,10 @@ class ReleaseMgr(threading.Thread):
self.vclustermgr = vclustermgr self.vclustermgr = vclustermgr
self.ulockmgr = ulockmgr self.ulockmgr = ulockmgr
self.check_interval = check_interval self.check_interval = check_interval
self.warning_days = 7 self.warning_days = int(env.getenv("WARNING_DAYS"))
self.release_days = 14 self.release_days = int(env.getenv("RELEASE_DAYS"))
if self.release_days <= self.warning_days:
self.release_days = self.warning_days+1
def _send_email(to_address, username, vcluster, days, is_released=True): def _send_email(to_address, username, vcluster, days, is_released=True):
email_from_address = settings.get('EMAIL_FROM_ADDRESS') email_from_address = settings.get('EMAIL_FROM_ADDRESS')
@ -35,10 +41,11 @@ class ReleaseMgr(threading.Thread):
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;You can create new workspace/vcluster if you need.</p> <p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;You can create new workspace/vcluster if you need.</p>
''' '''
else: else:
day_d = self.release_days - self.warning_days #day_d = self.release_days - (datetime.datetime.now() - vcluster.stop_time).days
release_date = datetime.datetime.now() + datetime.timedelta(days=day_d) release_date = vcluster.stop_time + datetime.timedelta(days=self.release_days)
day_d = (release_date - vcluster.stop_time).days
rd_str = release_date.strftime("%Y-%m-%d %H:%M:%S") rd_str = release_date.strftime("%Y-%m-%d %H:%M:%S")
text += '''<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;It will be released at <b>%s(in about %d days)</b>.</p> text += '''<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;It will be released after <b>%s(in about %d days)</b>.</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<b>And the data in it couldn't be recoverd after releasing.</b></p> <p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<b>And the data in it couldn't be recoverd after releasing.</b></p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Please start or save it before <b>%s(in about %d days)</b> if you want to keep the data.</p> <p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Please start or save it before <b>%s(in about %d days)</b> if you want to keep the data.</p>
''' % (rd_str, day_d, rd_str, day_d) ''' % (rd_str, day_d, rd_str, day_d)
@ -78,6 +85,7 @@ class ReleaseMgr(threading.Thread):
if vc.stop_time is None: if vc.stop_time is None:
continue continue
days = (datetime.datetime.now() - vc.stop_time).days days = (datetime.datetime.now() - vc.stop_time).days
if days >= self.release_days: if days >= self.release_days:
logger.info("[ReleaseMgr] VCluster(id:%d,user:%s) has been stopped(%s) for more than %d days, it will be released." logger.info("[ReleaseMgr] VCluster(id:%d,user:%s) has been stopped(%s) for more than %d days, it will be released."
% (vc.clusterid, vc.ownername, vc.stop_time.strftime("%Y-%m-%d %H:%M:%S"), self.release_days)) % (vc.clusterid, vc.ownername, vc.stop_time.strftime("%Y-%m-%d %H:%M:%S"), self.release_days))
@ -85,13 +93,24 @@ class ReleaseMgr(threading.Thread):
logger.info("[ReleaseMgr] %s"%str(rc_info)) logger.info("[ReleaseMgr] %s"%str(rc_info))
groupname = rc_info['groupname'] groupname = rc_info['groupname']
user_info = {"data":{"id":rc_info['uid'],"groupinfo":quotas[groupname]}} user_info = {"data":{"id":rc_info['uid'],"groupinfo":quotas[groupname]}}
success, msg = self.vclustermgr.delete_cluster(vc.clustername, vc.ownername, user_info) self.ulockmgr.acquire(vc.ownername)
if not success: try:
logger.error("[ReleaseMgr] Can't release VCluster(id:%d,user:%s) for %s"%(vc.clusterid, vc.ownername, msg)) success, msg = self.vclustermgr.delete_cluster(vc.clustername, vc.ownername, user_info)
else: if not success:
self._send_email() logger.error("[ReleaseMgr] Can't release VCluster(id:%d,user:%s) for %s"%(vc.clusterid, vc.ownername, msg))
else:
self._send_email(rc_info['email'], vc.ownername, vc, days)
except Exception as err:
logger.error(err)
finally:
self.ulockmgr.release(vc.ownername)
elif days >= self.warning_days: elif days >= self.warning_days:
pass #send warning logger.info("[ReleaseMgr] VCluster(id:%d,user:%s) has been stopped(%s) for more than %d days. A warning email will be sent to the user."
% (vc.clusterid, vc.ownername, vc.stop_time.strftime("%Y-%m-%d %H:%M:%S"), self.warning_days))
rc_info = post_to_user("/master/user/recoverinfo/", {'username':username,'auth_key':auth_key})
logger.info("[ReleaseMgr] %s"%str(rc_info))
self._send_email(rc_info['email'], vc.ownername, vc, days, False)
time.sleep(self.check_interval) time.sleep(self.check_interval)
def stop(self): def stop(self):

View File

@ -707,6 +707,7 @@ class VclusterMgr(object):
[status, vcluster] = self.get_vcluster(clustername, username) [status, vcluster] = self.get_vcluster(clustername, username)
vcluster.status = 'stopped' vcluster.status = 'stopped'
vcluster.start_time ="------" vcluster.start_time ="------"
vcluster.stop_time = datetime.datetime.now()
if not db_commit(): if not db_commit():
return [False, "Commit Errror"] return [False, "Commit Errror"]
return [True, "stop cluster"] return [True, "stop cluster"]

View File

@ -79,6 +79,10 @@ def getenv(key):
return os.environ.get("ALLOCATED_PORTS","10000-65535") return os.environ.get("ALLOCATED_PORTS","10000-65535")
elif key =="ALLOW_SCALE_OUT": elif key =="ALLOW_SCALE_OUT":
return os.environ.get("ALLOW_SCALE_OUT", "False") return os.environ.get("ALLOW_SCALE_OUT", "False")
elif key == "WARNING_DAYS":
return os.environ.get("WARNING_DAYS"."7")
elif key == "RELEASE_DAYS":
return os.environ.get("RELEASE_DAYS"."14")
elif key == "BATCH_ON": elif key == "BATCH_ON":
return os.environ.get("BATCH_ON","True") return os.environ.get("BATCH_ON","True")
elif key == "BATCH_MASTER_PORT": elif key == "BATCH_MASTER_PORT":

View File

@ -314,7 +314,7 @@ def get_master_recoverinfo():
return json.dumps({'success':'false', 'message':'username field is required.'}) return json.dumps({'success':'false', 'message':'username field is required.'})
else: else:
user = User.query.filter_by(username=username).first() user = User.query.filter_by(username=username).first()
return json.dumps({'success':'true', 'uid':user.id, 'groupname':user.user_group}) return json.dumps({'success':'true', 'uid':user.id, 'email':user.e_mail, 'groupname':user.user_group})
@app.route("/master/user/groupinfo/", methods=['POST']) @app.route("/master/user/groupinfo/", methods=['POST'])
@auth_key_required @auth_key_required