add releasemgr
This commit is contained in:
parent
fb3258e395
commit
677465209d
|
@ -0,0 +1,99 @@
|
||||||
|
import threading, time
|
||||||
|
from utils import env
|
||||||
|
from utils.log import logger
|
||||||
|
from utils.model import db, VCluster, Container
|
||||||
|
import datetime
|
||||||
|
|
||||||
|
userpoint = "http://" + env.getenv('USER_IP') + ":" + str(env.getenv('USER_PORT'))
|
||||||
|
def post_to_user(url = '/', data={}):
|
||||||
|
return requests.post(userpoint+url,data=data).json()
|
||||||
|
|
||||||
|
_ONE_DAY_IN_SECONDS = 60 * 60 * 24
|
||||||
|
|
||||||
|
class ReleaseMgr(threading.Thread):
|
||||||
|
|
||||||
|
def __init__(self, vclustermgr, ulockmgr, check_interval=_ONE_DAY_IN_SECONDS):
|
||||||
|
threading.Thread.__init__(self)
|
||||||
|
self.thread_stop = False
|
||||||
|
self.vclustermgr = vclustermgr
|
||||||
|
self.ulockmgr = ulockmgr
|
||||||
|
self.check_interval = check_interval
|
||||||
|
self.warning_days = 7
|
||||||
|
self.release_days = 14
|
||||||
|
|
||||||
|
def _send_email(to_address, username, vcluster, days, is_released=True):
|
||||||
|
email_from_address = settings.get('EMAIL_FROM_ADDRESS')
|
||||||
|
if (email_from_address in ['\'\'', '\"\"', '']):
|
||||||
|
return
|
||||||
|
text = '<html><h4>Dear '+ username + ':</h4>'
|
||||||
|
text += '''<p> Your workspace/vcluster(name:%s id:%d) in <a href='%s'>%s</a>
|
||||||
|
has been stopped more than %d days now. </p>
|
||||||
|
''' % (vc.clustername, vc.clusterid, env.getenv("PORTAL_URL"), env.getenv("PORTAL_URL"), days)
|
||||||
|
if is_released:
|
||||||
|
text += '''<p> Therefore, the workspace/vcluster has been released now.</p>
|
||||||
|
<p> <b>And the data in it couldn't be recoverd</b> unless you save it.</p>
|
||||||
|
<p> You can create new workspace/vcluster if you need.</p>
|
||||||
|
'''
|
||||||
|
else:
|
||||||
|
day_d = self.release_days - self.warning_days
|
||||||
|
release_date = datetime.datetime.now() + datetime.timedelta(days=day_d)
|
||||||
|
rd_str = release_date.strftime("%Y-%m-%d %H:%M:%S")
|
||||||
|
text += '''<p> It will be released at <b>%s(in about %d days)</b>.</p>
|
||||||
|
<p> <b>And the data in it couldn't be recoverd after releasing.</b></p>
|
||||||
|
<p> 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)
|
||||||
|
text += '''<br>
|
||||||
|
<p> Note: DO NOT reply to this email!</p>
|
||||||
|
<br><br>
|
||||||
|
<p> <a href='http://docklet.unias.org'>Docklet Team</a>, SEI, PKU</p>
|
||||||
|
'''
|
||||||
|
subject = 'Docklet workspace/vcluster releasing alert'
|
||||||
|
msg = MIMEMultipart()
|
||||||
|
textmsg = MIMEText(text,'html','utf-8')
|
||||||
|
msg['Subject'] = Header(subject, 'utf-8')
|
||||||
|
msg['From'] = email_from_address
|
||||||
|
msg['To'] = to_address
|
||||||
|
msg.attach(textmsg)
|
||||||
|
s = smtplib.SMTP()
|
||||||
|
s.connect()
|
||||||
|
try:
|
||||||
|
s.sendmail(email_from_address, to_address, msg.as_string())
|
||||||
|
except Exception as err:
|
||||||
|
logger.error(traceback.format_exc())
|
||||||
|
s.close()
|
||||||
|
|
||||||
|
def run(self):
|
||||||
|
while not self.thread_stop:
|
||||||
|
logger.info("[ReleaseMgr] Begin checking each vcluster if it needs to be released...")
|
||||||
|
|
||||||
|
auth_key = env.getenv('AUTH_KEY')
|
||||||
|
res = post_to_user("/master/user/groupinfo/", {'auth_key':auth_key})
|
||||||
|
groups = json.loads(res['groups'])
|
||||||
|
quotas = {}
|
||||||
|
for group in groups:
|
||||||
|
quotas[group['name']] = group['quotas']
|
||||||
|
|
||||||
|
vcs = VCluster.query.filter_by(status='stopped').all()
|
||||||
|
for vc in vcs:
|
||||||
|
if vc.stop_time is None:
|
||||||
|
continue
|
||||||
|
days = (datetime.datetime.now() - vc.stop_time).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."
|
||||||
|
% (vc.clusterid, vc.ownername, vc.stop_time.strftime("%Y-%m-%d %H:%M:%S"), self.release_days))
|
||||||
|
rc_info = post_to_user("/master/user/recoverinfo/", {'username':username,'auth_key':auth_key})
|
||||||
|
logger.info("[ReleaseMgr] %s"%str(rc_info))
|
||||||
|
groupname = rc_info['groupname']
|
||||||
|
user_info = {"data":{"id":rc_info['uid'],"groupinfo":quotas[groupname]}}
|
||||||
|
success, msg = self.vclustermgr.delete_cluster(vc.clustername, vc.ownername, user_info)
|
||||||
|
if not success:
|
||||||
|
logger.error("[ReleaseMgr] Can't release VCluster(id:%d,user:%s) for %s"%(vc.clusterid, vc.ownername, msg))
|
||||||
|
else:
|
||||||
|
self._send_email()
|
||||||
|
elif days >= self.warning_days:
|
||||||
|
pass #send warning
|
||||||
|
time.sleep(self.check_interval)
|
||||||
|
|
||||||
|
def stop(self):
|
||||||
|
self.thread_stop = True
|
||||||
|
return
|
|
@ -378,6 +378,7 @@ class VCluster(db.Model):
|
||||||
nextcid = db.Column(db.Integer)
|
nextcid = db.Column(db.Integer)
|
||||||
create_time = db.Column(db.DateTime)
|
create_time = db.Column(db.DateTime)
|
||||||
start_time = db.Column(db.String(20))
|
start_time = db.Column(db.String(20))
|
||||||
|
stop_time = db.Column(db.DateTime)
|
||||||
proxy_server_ip = db.Column(db.String(20))
|
proxy_server_ip = db.Column(db.String(20))
|
||||||
proxy_public_ip = db.Column(db.String(20))
|
proxy_public_ip = db.Column(db.String(20))
|
||||||
port_mapping = db.relationship('PortMapping', backref='v_cluster', lazy='dynamic')
|
port_mapping = db.relationship('PortMapping', backref='v_cluster', lazy='dynamic')
|
||||||
|
@ -397,6 +398,7 @@ class VCluster(db.Model):
|
||||||
self.billing_history = []
|
self.billing_history = []
|
||||||
self.create_time = datetime.now()
|
self.create_time = datetime.now()
|
||||||
self.start_time = "------"
|
self.start_time = "------"
|
||||||
|
self.stop_time = None
|
||||||
|
|
||||||
def __repr__(self):
|
def __repr__(self):
|
||||||
info = {}
|
info = {}
|
||||||
|
@ -410,6 +412,10 @@ class VCluster(db.Model):
|
||||||
info["nextcid"] = self.nextcid
|
info["nextcid"] = self.nextcid
|
||||||
info["create_time"] = self.create_time.strftime("%Y-%m-%d %H:%M:%S")
|
info["create_time"] = self.create_time.strftime("%Y-%m-%d %H:%M:%S")
|
||||||
info["start_time"] = self.start_time
|
info["start_time"] = self.start_time
|
||||||
|
if self.stop_time is None:
|
||||||
|
info['stop_time'] = "------"
|
||||||
|
else:
|
||||||
|
info['stop_time'] = self.stop_time.strftime("%Y-%m-%d %H:%M:%S")
|
||||||
info["containers"] = [dict(eval(str(con))) for con in self.containers]
|
info["containers"] = [dict(eval(str(con))) for con in self.containers]
|
||||||
info["port_mapping"] = [dict(eval(str(pm))) for pm in self.port_mapping]
|
info["port_mapping"] = [dict(eval(str(pm))) for pm in self.port_mapping]
|
||||||
info["billing_history"] = [dict(eval(str(bh))) for bh in self.billing_history]
|
info["billing_history"] = [dict(eval(str(bh))) for bh in self.billing_history]
|
||||||
|
@ -517,7 +523,7 @@ class Batchtask(db.Model):
|
||||||
self.running_time = 0
|
self.running_time = 0
|
||||||
self.billing = 0
|
self.billing = 0
|
||||||
self.tried_times = 0
|
self.tried_times = 0
|
||||||
|
|
||||||
def __repr__(self):
|
def __repr__(self):
|
||||||
info = {}
|
info = {}
|
||||||
info['id'] = self.id
|
info['id'] = self.id
|
||||||
|
|
Loading…
Reference in New Issue