add page for migrate host
This commit is contained in:
parent
0f099c7145
commit
8323cb62d4
|
@ -432,6 +432,27 @@ def migrate_cluster():
|
||||||
finally:
|
finally:
|
||||||
G_ulockmgr.release(user)
|
G_ulockmgr.release(user)
|
||||||
|
|
||||||
|
@app.route("/host/migrate/", methods=['POST'])
|
||||||
|
@login_required
|
||||||
|
def migrate_host(user, beans, form):
|
||||||
|
global G_vclustermgr
|
||||||
|
global G_ulockmgr
|
||||||
|
src_host = request.form.get('src_host', None)
|
||||||
|
dst_host_list = request.form.getlist('dst_host_list', None)
|
||||||
|
|
||||||
|
if src_host is None or dst_host_list is None:
|
||||||
|
return json.dumps({'success':'false', 'message': 'src host or dst host list is null'})
|
||||||
|
logger.info(str(src_host))
|
||||||
|
logger.info(type(dst_host_list))
|
||||||
|
logger.info(str(dst_host_list))
|
||||||
|
#[status, msg] = G_vclustermgr.migrate_host(src_host, dst_host_list)
|
||||||
|
status = True
|
||||||
|
if status:
|
||||||
|
return json.dumps({'success': 'true', 'action': 'migrate_host'})
|
||||||
|
else:
|
||||||
|
return json.dumps({'success': 'false', 'message': msg})
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@app.route("/image/list/", methods=['POST'])
|
@app.route("/image/list/", methods=['POST'])
|
||||||
@login_required
|
@login_required
|
||||||
|
|
|
@ -789,14 +789,14 @@ class VclusterMgr(object):
|
||||||
self.imgmgr.removeImage(username,imagename)
|
self.imgmgr.removeImage(username,imagename)
|
||||||
return [True,""]
|
return [True,""]
|
||||||
|
|
||||||
def migrate_cluster(self, clustername, username, new_host_list, user_info):
|
def migrate_cluster(self, clustername, username, src_host, new_host_list, user_info):
|
||||||
[status, info] = self.get_clusterinfo(clustername, username)
|
[status, info] = self.get_clusterinfo(clustername, username)
|
||||||
if not status:
|
if not status:
|
||||||
return [False, "cluster not found"]
|
return [False, "cluster not found"]
|
||||||
prestatus = info['status']
|
prestatus = info['status']
|
||||||
self.stop_cluster(clustername, username)
|
self.stop_cluster(clustername, username)
|
||||||
for container in info['containers']:
|
for container in info['containers']:
|
||||||
if container['host'] in new_host_list:
|
if container['host'] == src_host:
|
||||||
continue
|
continue
|
||||||
random.shuffle(new_host_list)
|
random.shuffle(new_host_list)
|
||||||
for new_host in new_host_list:
|
for new_host in new_host_list:
|
||||||
|
@ -816,6 +816,27 @@ class VclusterMgr(object):
|
||||||
return [False, msg]
|
return [False, msg]
|
||||||
return [True, ""]
|
return [True, ""]
|
||||||
|
|
||||||
|
def migrate_host(self, src_host, new_host_list):
|
||||||
|
vcluster_list = self.get_all_clusterinfo()
|
||||||
|
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']
|
||||||
|
|
||||||
|
for vcluster in vcluster_list:
|
||||||
|
try:
|
||||||
|
clustername = vcluster['clustername']
|
||||||
|
username = vcluster['ownername']
|
||||||
|
rc_info = post_to_user("/master/user/recoverinfo/", {'username':username,'auth_key':auth_key})
|
||||||
|
groupname = rc_info['groupname']
|
||||||
|
user_info = {"data":{"id":rc_info['uid'],"groupinfo":quotas[groupname]}}
|
||||||
|
self.migrate_cluster(clustername, username, src_host, new_host_list, user_info)
|
||||||
|
except Exception as ex:
|
||||||
|
return [False, str(ex)]
|
||||||
|
return [True, ""]
|
||||||
|
|
||||||
def is_cluster(self, clustername, username):
|
def is_cluster(self, clustername, username):
|
||||||
[status, clusters] = self.list_clusters(username)
|
[status, clusters] = self.list_clusters(username)
|
||||||
if clustername in clusters:
|
if clustername in clusters:
|
||||||
|
@ -862,6 +883,14 @@ class VclusterMgr(object):
|
||||||
else:
|
else:
|
||||||
return [True, vcluster]
|
return [True, vcluster]
|
||||||
|
|
||||||
|
def get_all_clusterinfo(self):
|
||||||
|
vcluster_list = VCluster.query.all()
|
||||||
|
logger.info(str(vcluster_list))
|
||||||
|
if vcluster_list is None:
|
||||||
|
return [False, None]
|
||||||
|
else:
|
||||||
|
return [True, json.loads(str(vcluster_list))]
|
||||||
|
|
||||||
# acquire cluster id from etcd
|
# acquire cluster id from etcd
|
||||||
def _acquire_id(self):
|
def _acquire_id(self):
|
||||||
self.clusterid_locks.acquire()
|
self.clusterid_locks.acquire()
|
||||||
|
|
|
@ -15,6 +15,12 @@
|
||||||
</ol>
|
</ol>
|
||||||
{% endblock %}
|
{% endblock %}
|
||||||
|
|
||||||
|
{% block css_src %}
|
||||||
|
<link href="//cdn.bootcss.com/datatables/1.10.11/css/dataTables.bootstrap.min.css" rel="stylesheet">
|
||||||
|
<link href="//cdn.bootcss.com/datatables/1.10.11/css/jquery.dataTables_themeroller.css" rel="stylesheet">
|
||||||
|
<link href="/static/dist/css/modalconfig.css" rel="stylesheet">
|
||||||
|
{% endblock %}
|
||||||
|
|
||||||
{% block content %}
|
{% block content %}
|
||||||
<ul class="nav nav-tabs" role="tablist" id="myTabs">
|
<ul class="nav nav-tabs" role="tablist" id="myTabs">
|
||||||
{% for master in allmachines %}
|
{% for master in allmachines %}
|
||||||
|
@ -59,7 +65,7 @@
|
||||||
<th>Mem used</th>
|
<th>Mem used</th>
|
||||||
<th>Disk used</th>
|
<th>Disk used</th>
|
||||||
<th>Summary</th>
|
<th>Summary</th>
|
||||||
<th>Delete</th>
|
<th>Operation</th>
|
||||||
</tr>
|
</tr>
|
||||||
</thead>
|
</thead>
|
||||||
<tbody>
|
<tbody>
|
||||||
|
@ -80,7 +86,50 @@
|
||||||
<td id='{{master.split("@")[1]}}_{{ loop.index }}_mem'>--</td>
|
<td id='{{master.split("@")[1]}}_{{ loop.index }}_mem'>--</td>
|
||||||
<td id='{{master.split("@")[1]}}_{{ loop.index }}_disk'>--</td>
|
<td id='{{master.split("@")[1]}}_{{ loop.index }}_disk'>--</td>
|
||||||
<td><a class="btn btn-info btn-xs" href='/hosts/{{master.split("@")[0]}}/{{ phym['ip'] }}/'>Realtime</a></td>
|
<td><a class="btn btn-info btn-xs" href='/hosts/{{master.split("@")[0]}}/{{ phym['ip'] }}/'>Realtime</a></td>
|
||||||
<td><button class="btn btn-xs btn-default">Delete</button></td>
|
<td><button class="btn btn-xs btn-default">Delete</button>
|
||||||
|
<button class="btn btn-xs btn-danger" data-toggle="modal" data-target="#Migrate_{{loop.index}}_{{master.split("@")[1]}}">Migrate</button>
|
||||||
|
<div class="modal inmodal" id="Migrate_{{loop.index}}_{{master.split("@")[1]}}" 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">×</span><span class="sr-only">Close</span></button>
|
||||||
|
<i class="fa fa-plus modal-icon"></i>
|
||||||
|
<h4 class="modal-title">Migrate Container from {{phym['ip']}} to Another Hosts [dangerous!!!]</h4>
|
||||||
|
</div>
|
||||||
|
<div class="modal-body">
|
||||||
|
<form action="/hosts/{{master.split("@")[0]}}/migrate/{{ phym['ip'] }}/" method="POST" id="MigrateForm">
|
||||||
|
<input type="hidden" name="csrf_token" value="{{ csrf_token() }}">
|
||||||
|
<table class="table table-striped table-bordered table-hover table-image">
|
||||||
|
<thead>
|
||||||
|
<tr>
|
||||||
|
<th>HostIp</th>
|
||||||
|
<th>Nodes</th>
|
||||||
|
<th>choose</th>
|
||||||
|
</tr>
|
||||||
|
</thead>
|
||||||
|
<tbody>
|
||||||
|
{% for tphym in allmachines[master] %}
|
||||||
|
{% if not phym == tphym %}
|
||||||
|
<tr>
|
||||||
|
<td>{{ tphym['ip'] }}</td>
|
||||||
|
<td>{{ tphym['containers']['running']}} / {{ tphym['containers']['total'] }}</td>
|
||||||
|
<td><input type="checkbox" name="target" value="{{tphym['ip']}}"></td>
|
||||||
|
</tr>
|
||||||
|
{% endif %}
|
||||||
|
{% endfor %}
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
<div class="modal-footer">
|
||||||
|
<button type="button" class="btn btn-white" data-dismiss="modal">Close</button>
|
||||||
|
<button type="submit" class="btn btn-primary">Submit</button>
|
||||||
|
</div>
|
||||||
|
</form>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
{% endfor %}
|
{% endfor %}
|
||||||
</tbody>
|
</tbody>
|
||||||
|
|
|
@ -315,6 +315,7 @@ def masterdesc(mastername):
|
||||||
descriptionMasterView.desc=env.getenv(mastername+"_desc")[1:-1]
|
descriptionMasterView.desc=env.getenv(mastername+"_desc")[1:-1]
|
||||||
return descriptionMasterView.as_view()
|
return descriptionMasterView.as_view()
|
||||||
|
|
||||||
|
|
||||||
@app.route("/image/<masterip>/list/", methods=['POST'])
|
@app.route("/image/<masterip>/list/", methods=['POST'])
|
||||||
@login_required
|
@login_required
|
||||||
def image_list(masterip):
|
def image_list(masterip):
|
||||||
|
@ -376,6 +377,14 @@ def updatebaseImage(image,masterip):
|
||||||
def hosts():
|
def hosts():
|
||||||
return hostsView.as_view()
|
return hostsView.as_view()
|
||||||
|
|
||||||
|
@app.route("/hosts/<masterip>/migrate/<hostip>/", methods=['POST'])
|
||||||
|
@administration_required
|
||||||
|
def hostMigrate(hostip, masterip):
|
||||||
|
hostMigrateView.hostip = hostip
|
||||||
|
hostMigrateView.masterip = masterip
|
||||||
|
hostMigrateView.target = request.form.getlist('target')
|
||||||
|
return hostMigrateView.as_view()
|
||||||
|
|
||||||
@app.route("/hosts/<masterip>/<com_ip>/", methods=['GET'])
|
@app.route("/hosts/<masterip>/<com_ip>/", methods=['GET'])
|
||||||
@administration_required
|
@administration_required
|
||||||
def hostsRealtime(com_ip,masterip):
|
def hostsRealtime(com_ip,masterip):
|
||||||
|
|
|
@ -113,3 +113,13 @@ class updatebaseImageView(normalView):
|
||||||
}
|
}
|
||||||
dockletRequest.post('/image/updatebase/', data)
|
dockletRequest.post('/image/updatebase/', data)
|
||||||
return redirect("/settings/")
|
return redirect("/settings/")
|
||||||
|
|
||||||
|
class hostMigrateView(normalView):
|
||||||
|
@classmethod
|
||||||
|
def post(self):
|
||||||
|
data = {
|
||||||
|
"src_host": self.hostip,
|
||||||
|
"dst_host_list": self.target
|
||||||
|
}
|
||||||
|
dockletRequest.post("/host/migrate/", data, self.masterip)
|
||||||
|
return redirect("/hosts/")
|
||||||
|
|
Loading…
Reference in New Issue