user can copy an image to other masters
This commit is contained in:
parent
0e0cd8110b
commit
d9cc0c2c9f
|
@ -398,6 +398,16 @@ def delete_image(user, beans, form):
|
|||
G_imagemgr.removeImage(user,image)
|
||||
return json.dumps({'success':'true', 'action':'delete'})
|
||||
|
||||
@app.route("/image/copy/", methods=['POST'])
|
||||
@login_required
|
||||
def copy_image(user, beans, form):
|
||||
global G_imagemgr
|
||||
image = form.get('image', None)
|
||||
target = form.get('target',None)
|
||||
res = G_imagemgr.copyImage(user,image,target)
|
||||
return json.dumps(res)
|
||||
|
||||
|
||||
@app.route("/addproxy/", methods=['POST'])
|
||||
@login_required
|
||||
def addproxy(user, beans, form):
|
||||
|
|
|
@ -257,6 +257,33 @@ class ImageMgr():
|
|||
except Exception as e:
|
||||
logger.error(e)
|
||||
|
||||
def copyImage(self,user,image,target):
|
||||
path = "/opt/docklet/global/images/private/"+user+"/"
|
||||
image_info_file = open(path+"."+image+".info", 'r')
|
||||
[createtime, isshare] = image_info_file.readlines()
|
||||
recordshare = isshare
|
||||
isshare = "unshared"
|
||||
image_info_file.close()
|
||||
image_info_file = open(path+"."+image+".info", 'w')
|
||||
image_info_file.writelines([createtime, isshare])
|
||||
image_info_file.close()
|
||||
try:
|
||||
sys_run('ssh root@%s "mkdir -p %s"' % (target,path))
|
||||
sys_run('scp %s%s.tz root@%s:%s' % (path,image,target,path))
|
||||
sys_run('scp %s.%s.description root@%s:%s' % (path,image,target,path))
|
||||
sys_run('scp %s.%s.info root@%s:%s' % (path,image,target,path))
|
||||
except Exception as e:
|
||||
logger.error(e)
|
||||
image_info_file = open(path+"."+image+".info", 'w')
|
||||
image_info_file.writelines([createtime, recordshare])
|
||||
image_info_file.close()
|
||||
return {'success':'false', 'message':str(e)}
|
||||
image_info_file = open(path+"."+image+".info", 'w')
|
||||
image_info_file.writelines([createtime, recordshare])
|
||||
image_info_file.close()
|
||||
logger.info("copy image %s of %s to %s success" % (image,user,target))
|
||||
return {'success':'true', 'action':'copy image'}
|
||||
|
||||
def update_basefs(self,image):
|
||||
imgpath = self.imgpath + "private/root/"
|
||||
basefs = self.NFS_PREFIX+"/local/packagefs/"
|
||||
|
|
|
@ -358,12 +358,51 @@
|
|||
<td>
|
||||
<a href="/image/{{master.split("@")[0]}}/share/{{ image['name'] }}/"><button type="button" class="btn btn-xs btn-success">share</button></a>
|
||||
<a href="/image/{{master.split("@")[0]}}/delete/{{ image['name'] }}/"><button type="button" class="btn btn-xs btn-danger">delete</button></a>
|
||||
<button type="button" class="btn btn-primary btn-xs" data-toggle="modal" data-target="#Copyimage_{{ image['name'] }}_{{master.split("@")[1]}}">copy</button>
|
||||
<div class="modal inmodal" id="Copyimage_{{ image['name'] }}_{{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">Copy image to other location</h4>
|
||||
</div>
|
||||
<div class="modal-body">
|
||||
<form action="/image/{{master.split("@")[0]}}/copy/{{image['name']}}/" method="POST" id="CopyImageForm">
|
||||
<table class="table table-striped table-bordered table-hover table-image">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>Location</th>
|
||||
<th>choose</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{% for targetmaster in masterips %}
|
||||
{% if not master==targetmaster %}
|
||||
<tr>
|
||||
<td>{{ targetmaster.split("@")[1]}}</td>
|
||||
<td><input type="radio" name="target" value="{{targetmaster.split("@")[0]}}"></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>
|
||||
</td>
|
||||
{% else %}
|
||||
<td>shared</td>
|
||||
<td>
|
||||
<a href="/image/{{master.split("@")[0]}}/unshare/{{ image['name'] }}/"><button type="button" class="btn btn-xs btn-warning">unshare</button></a>
|
||||
<a href="/image/{{master.split("@")[0]}}/delete/{{ image['name'] }}/"><button type="button" class="btn btn-xs btn-danger">delete</button></a>
|
||||
<button type="button" class="btn btn-primary btn-sm" data-toggle="modal" data-target="#Copyimage_{{ image['name'] }}_{{master.split("@")[1]}}"><i class="fa fa-plus"></i>Copy</button>
|
||||
</td>
|
||||
{% endif %}
|
||||
</tr>
|
||||
|
|
|
@ -294,6 +294,15 @@ def deleteImage(image,masterip):
|
|||
deleteImageView.masterip = masterip
|
||||
return deleteImageView.as_view()
|
||||
|
||||
@app.route("/image/<masterip>/copy/<image>/", methods=['POST'])
|
||||
@login_required
|
||||
def copyImage(image,masterip):
|
||||
copyImageView.image = image
|
||||
copyImageView.masterip = masterip
|
||||
copyImageView.target = request.form['target']
|
||||
return copyImageView.as_view()
|
||||
|
||||
|
||||
@app.route("/image/<masterip>/updatebase/<image>/", methods=['GET'])
|
||||
@login_required
|
||||
def updatebaseImage(image,masterip):
|
||||
|
|
|
@ -298,6 +298,25 @@ class unshareImageView(normalView):
|
|||
else:
|
||||
self.error()
|
||||
|
||||
class copyImageView(normalView):
|
||||
error_path = "error.html"
|
||||
|
||||
@classmethod
|
||||
def post(self):
|
||||
masterip = self.masterip
|
||||
data = {
|
||||
"image": self.image,
|
||||
"target": self.target
|
||||
}
|
||||
result = dockletRequest.post("/image/copy/", data, masterip)
|
||||
if result:
|
||||
if result.get('success') == 'true':
|
||||
return redirect("/config/")
|
||||
else:
|
||||
return self.render(self.error_path,message=result.get('message'))
|
||||
else:
|
||||
self.error()
|
||||
|
||||
class deleteImageView(normalView):
|
||||
template_path = "dashboard.html"
|
||||
|
||||
|
@ -350,6 +369,7 @@ class deleteproxyView(normalView):
|
|||
class configView(normalView):
|
||||
@classmethod
|
||||
def get(self):
|
||||
masterips = dockletRequest.post_to_all()
|
||||
allimages = dockletRequest.post_to_all('/image/list/')
|
||||
for master in allimages:
|
||||
allimages[master] = allimages[master].get('images')
|
||||
|
@ -398,7 +418,7 @@ class configView(normalView):
|
|||
'memory': defaultmemory,
|
||||
'disk': defaultdisk
|
||||
}
|
||||
return self.render("config.html", allimages = allimages, allclusters = allclusters_info, mysession=dict(session), quota = quota, usage = usage, defaultsetting = defaultsetting)
|
||||
return self.render("config.html", allimages = allimages, allclusters = allclusters_info, mysession=dict(session), quota = quota, usage = usage, defaultsetting = defaultsetting, masterips = masterips)
|
||||
|
||||
@classmethod
|
||||
def post(self):
|
||||
|
|
|
@ -97,8 +97,11 @@ class dockletRequest():
|
|||
except Exception as e:
|
||||
logger.debug(e)
|
||||
continue
|
||||
result[masterip] = res
|
||||
logger.debug("get result from " + getip(masterip))
|
||||
if 'success' in res and res['success'] == 'true':
|
||||
result[masterip] = res
|
||||
logger.info("get result from %s success" % getip(masterip))
|
||||
else:
|
||||
logger.error("get result from %s failed" % getip(masterip))
|
||||
|
||||
return result
|
||||
|
||||
|
|
Loading…
Reference in New Issue