Use db in imagemgr
This commit is contained in:
parent
6870d16bc3
commit
3f54ff3952
115
src/imagemgr.py
115
src/imagemgr.py
|
@ -10,7 +10,7 @@ design:
|
|||
out of time.
|
||||
4. We can show every user their own images and the images are shared by other. User can new a
|
||||
cluster or scale out a new node by them. And user can remove his own images.
|
||||
5. When a remove option occur, the image server will delete it. But some physical host may
|
||||
5. When a remove option occur, the image server will delete it. But some physical host may
|
||||
also maintain it. I think it doesn't matter.
|
||||
6. The manage of lvm has been including in this module.
|
||||
"""
|
||||
|
@ -20,6 +20,7 @@ from configparser import ConfigParser
|
|||
from io import StringIO
|
||||
import os,sys,subprocess,time,re,datetime,threading,random
|
||||
import xmlrpc.client
|
||||
from model import db, Image
|
||||
|
||||
from log import logger
|
||||
import env
|
||||
|
@ -30,37 +31,43 @@ class ImageMgr():
|
|||
#def sys_call(self,command):
|
||||
# output = subprocess.getoutput(command).strip()
|
||||
# return None if output == '' else output
|
||||
|
||||
|
||||
def sys_return(self,command):
|
||||
return_value = subprocess.call(command,shell=True)
|
||||
return return_value
|
||||
|
||||
|
||||
def __init__(self):
|
||||
self.NFS_PREFIX = env.getenv('FS_PREFIX')
|
||||
self.NFS_PREFIX = env.getenv('FS_PREFIX')
|
||||
self.imgpath = self.NFS_PREFIX + "/global/images/"
|
||||
self.srcpath = env.getenv('DOCKLET_LIB') + "/"
|
||||
self.srcpath = env.getenv('DOCKLET_LIB') + "/"
|
||||
self.imageserver = "192.168.6.249"
|
||||
|
||||
|
||||
def datetime_toString(self,dt):
|
||||
return dt.strftime("%Y-%m-%d %H:%M:%S")
|
||||
|
||||
def string_toDatetime(self,string):
|
||||
return datetime.datetime.strptime(string, "%Y-%m-%d %H:%M:%S")
|
||||
|
||||
def updateinfo(self,imgpath,image,description):
|
||||
image_info_file = open(imgpath+"."+image+".info",'w')
|
||||
|
||||
def updateinfo(self,user,image,description):
|
||||
'''image_info_file = open(imgpath+"."+image+".info",'w')
|
||||
image_info_file.writelines([self.datetime_toString(datetime.datetime.now()) + "\n", "unshare"])
|
||||
image_info_file.close()
|
||||
image_description_file = open(imgpath+"."+image+".description", 'w')
|
||||
image_description_file.write(description)
|
||||
image_description_file.close()
|
||||
image_description_file.close()'''
|
||||
image = Image.query.filter_by(ownername=user,imagename=image).first()
|
||||
if image is None:
|
||||
image = Image(image,False,user,description)
|
||||
db.session.add(image)
|
||||
db.session.commit()
|
||||
|
||||
|
||||
def dealpath(self,fspath):
|
||||
if fspath[-1:] == "/":
|
||||
return self.dealpath(fspath[:-1])
|
||||
else:
|
||||
return fspath
|
||||
|
||||
|
||||
def createImage(self,user,image,lxc,description="Not thing", imagenum=10):
|
||||
fspath = self.NFS_PREFIX + "/local/volume/" + lxc
|
||||
imgpath = self.imgpath + "private/" + user + "/"
|
||||
|
@ -80,14 +87,14 @@ class ImageMgr():
|
|||
sys_run("tar -cvf %s -C %s ." % (imgpath+image+".tz",self.dealpath(fspath)), True)
|
||||
except Exception as e:
|
||||
logger.error(e)
|
||||
#try:
|
||||
#try:
|
||||
#sys_run("cp %s %s" % (tmppath+tmpimage, imgpath+image+".tz"), True)
|
||||
#sys_run("rsync -a --delete --exclude=lost+found/ --exclude=root/nfs/ --exclude=dev/ --exclude=mnt/ --exclude=tmp/ --exclude=media/ --exclude=proc/ --exclude=sys/ %s/ %s/" % (self.dealpath(fspath),imgpath+image),True)
|
||||
#except Exception as e:
|
||||
# logger.error(e)
|
||||
#sys_run("rm -f %s" % tmppath+tmpimage, True)
|
||||
#sys_run("rm -f %s" % tmppath+tmpimage, True)
|
||||
#sys_run("rm -f %s" % (imgpath+"."+image+"_docklet_share"),True)
|
||||
self.updateinfo(imgpath,image,description)
|
||||
self.updateinfo(user,image,description)
|
||||
logger.info("image:%s from LXC:%s create success" % (image,lxc))
|
||||
return [True, "create image success"]
|
||||
|
||||
|
@ -116,8 +123,8 @@ class ImageMgr():
|
|||
|
||||
#self.sys_call("rsync -a --delete --exclude=nfs/ %s/ %s/" % (imgpath+image,self.dealpath(fspath)))
|
||||
#self.updatetime(imgpath,image)
|
||||
return
|
||||
|
||||
return
|
||||
|
||||
def prepareFS(self,user,image,lxc,size="1000",vgname="docklet-group"):
|
||||
rootfs = "/var/lib/lxc/%s/rootfs" % lxc
|
||||
layer = self.NFS_PREFIX + "/local/volume/" + lxc
|
||||
|
@ -130,14 +137,14 @@ class ImageMgr():
|
|||
if Ret.returncode == 0:
|
||||
logger.info("%s not clean" % layer)
|
||||
sys_run("umount -l %s" % layer)
|
||||
|
||||
|
||||
try:
|
||||
sys_run("rm -rf %s %s" % (rootfs, layer))
|
||||
sys_run("mkdir -p %s %s" % (rootfs, layer))
|
||||
except Exception as e:
|
||||
logger.error(e)
|
||||
|
||||
|
||||
|
||||
#prepare volume
|
||||
if check_volume(vgname,lxc):
|
||||
logger.info("volume %s already exists, delete it")
|
||||
|
@ -145,7 +152,7 @@ class ImageMgr():
|
|||
if not new_volume(vgname,lxc,size):
|
||||
logger.error("volume %s create failed" % lxc)
|
||||
return False
|
||||
|
||||
|
||||
try:
|
||||
sys_run("mkfs.ext4 /dev/%s/%s" % (vgname,lxc),True)
|
||||
sys_run("mount /dev/%s/%s %s" %(vgname,lxc,layer),True)
|
||||
|
@ -184,7 +191,7 @@ class ImageMgr():
|
|||
logger.error(e)
|
||||
|
||||
return True
|
||||
|
||||
|
||||
def detachFS(self, lxc, vgname="docklet-group"):
|
||||
rootfs = "/var/lib/lxc/%s/rootfs" % lxc
|
||||
Ret = sys_run("umount %s" % rootfs)
|
||||
|
@ -192,7 +199,7 @@ class ImageMgr():
|
|||
logger.error("cannot umount rootfs:%s" % rootfs)
|
||||
return False
|
||||
return True
|
||||
|
||||
|
||||
def checkFS(self, lxc, vgname="docklet-group"):
|
||||
rootfs = "/var/lib/lxc/%s/rootfs" % lxc
|
||||
layer = self.NFS_PREFIX + "/local/volume/" + lxc
|
||||
|
@ -211,49 +218,58 @@ class ImageMgr():
|
|||
def removeImage(self,user,image):
|
||||
imgpath = self.imgpath + "private/" + user + "/"
|
||||
try:
|
||||
image = Image.query.filter_by(imagename=image,ownername=user).first()
|
||||
db.session.delete(image)
|
||||
db.session.commit()
|
||||
sys_run("rm -rf %s/" % imgpath+image+".tz", True)
|
||||
sys_run("rm -f %s" % imgpath+"."+image+".info", True)
|
||||
sys_run("rm -f %s" % (imgpath+"."+image+".description"), True)
|
||||
#sys_run("rm -f %s" % imgpath+"."+image+".info", True)
|
||||
#sys_run("rm -f %s" % (imgpath+"."+image+".description"), True)
|
||||
except Exception as e:
|
||||
logger.error(e)
|
||||
|
||||
def shareImage(self,user,image):
|
||||
imgpath = self.imgpath + "private/" + user + "/"
|
||||
share_imgpath = self.imgpath + "public/" + user + "/"
|
||||
image_info_file = open(imgpath+"."+image+".info", 'r')
|
||||
'''image_info_file = open(imgpath+"."+image+".info", 'r')
|
||||
[createtime, isshare] = image_info_file.readlines()
|
||||
isshare = "shared"
|
||||
image_info_file.close()
|
||||
image_info_file = open(imgpath+"."+image+".info", 'w')
|
||||
image_info_file.writelines([createtime, isshare])
|
||||
image_info_file.close()
|
||||
sys_run("mkdir -p %s" % share_imgpath, True)
|
||||
image_info_file.close()'''
|
||||
try:
|
||||
image = Image.query.filter_by(imagename=image,ownername=user).first()
|
||||
image.isshared = True
|
||||
db.session.commit()
|
||||
sys_run("mkdir -p %s" % share_imgpath, True)
|
||||
sys_run("cp %s %s" % (imgpath+image+".tz", share_imgpath+image+".tz"), True)
|
||||
#sys_run("rsync -a --delete %s/ %s/" % (imgpath+image,share_imgpath+image), True)
|
||||
except Exception as e:
|
||||
logger.error(e)
|
||||
sys_run("cp %s %s" % (imgpath+"."+image+".info",share_imgpath+"."+image+".info"), True)
|
||||
sys_run("cp %s %s" % (imgpath+"."+image+".description",share_imgpath+"."+image+".description"), True)
|
||||
#$sys_run("cp %s %s" % (imgpath+"."+image+".info",share_imgpath+"."+image+".info"), True)
|
||||
#sys_run("cp %s %s" % (imgpath+"."+image+".description",share_imgpath+"."+image+".description"), True)
|
||||
|
||||
|
||||
|
||||
|
||||
def unshareImage(self,user,image):
|
||||
public_imgpath = self.imgpath + "public/" + user + "/"
|
||||
imgpath = self.imgpath + "private/" + user + "/"
|
||||
if os.path.isfile(imgpath + image + ".tz"):
|
||||
'''if os.path.isfile(imgpath + image + ".tz"):
|
||||
image_info_file = open(imgpath+"."+image+".info", 'r')
|
||||
[createtime, isshare] = image_info_file.readlines()
|
||||
isshare = "unshare"
|
||||
image_info_file.close()
|
||||
image_info_file = open(imgpath+"."+image+".info", 'w')
|
||||
image_info_file = open(imgpath+"."+image+".info", 'w')
|
||||
image_info_file.writelines([createtime, isshare])
|
||||
image_info_file.close()
|
||||
image_info_file.close()'''
|
||||
try:
|
||||
#sys_run("rm -rf %s/" % public_imgpath+image, True)
|
||||
image = Image.query.filter_by(imagename=image,ownername=user).first()
|
||||
image.isshared = False
|
||||
db.session.commit()
|
||||
sys_run("rm -f %s" % public_imgpath+image+".tz", True)
|
||||
sys_run("rm -f %s" % public_imgpath+"."+image+".info", True)
|
||||
sys_run("rm -f %s" % public_imgpath+"."+image+".description", True)
|
||||
#sys_run("rm -f %s" % public_imgpath+"."+image+".info", True)
|
||||
#sys_run("rm -f %s" % public_imgpath+"."+image+".description", True)
|
||||
except Exception as e:
|
||||
logger.error(e)
|
||||
|
||||
|
@ -272,7 +288,7 @@ class ImageMgr():
|
|||
logger.error(e)
|
||||
sys_run("rm -rf %s" % tmppath+tmpimage)
|
||||
return True
|
||||
|
||||
|
||||
def update_base_image(self, user, vclustermgr, image):
|
||||
if not user == "root":
|
||||
logger.info("only root can update base image")
|
||||
|
@ -291,7 +307,7 @@ class ImageMgr():
|
|||
return [True, "update base image"]
|
||||
|
||||
def get_image_info(self, user, image, imagetype):
|
||||
if imagetype == "private":
|
||||
'''if imagetype == "private":
|
||||
imgpath = self.imgpath + "private/" + user + "/"
|
||||
else:
|
||||
imgpath = self.imgpath + "public/" + user + "/"
|
||||
|
@ -300,20 +316,28 @@ class ImageMgr():
|
|||
image_info_file.close()
|
||||
image_description_file = open(imgpath+"."+image+".description",'r')
|
||||
description = image_description_file.read()
|
||||
image_description_file.close()
|
||||
image_description_file.close()'''
|
||||
image = Image.query.filter_by(imagename=image,ownername=user).first()
|
||||
if image is None:
|
||||
return ["", ""]
|
||||
time = image.create_time.strftime("%Y-%m-%d %H:%M:%S")
|
||||
description = image.description
|
||||
if len(description) > 15:
|
||||
description = description[:15] + "......"
|
||||
return [time, description]
|
||||
|
||||
def get_image_description(self, user, image):
|
||||
if image['type'] == "private":
|
||||
'''if image['type'] == "private":
|
||||
imgpath = self.imgpath + "private/" + user + "/"
|
||||
else:
|
||||
imgpath = self.imgpath + "public/" + image['owner'] + "/"
|
||||
image_description_file = open(imgpath+"."+image['name']+".description", 'r')
|
||||
description = image_description_file.read()
|
||||
image_description_file.close()
|
||||
return description
|
||||
image_description_file.close()'''
|
||||
image = Image.query.filter_by(imagename=image,ownername=user).first()
|
||||
if image is None:
|
||||
return ""
|
||||
return image.description
|
||||
|
||||
def list_images(self,user):
|
||||
images = {}
|
||||
|
@ -363,13 +387,16 @@ class ImageMgr():
|
|||
logger.error(e)
|
||||
|
||||
return images
|
||||
|
||||
|
||||
def isshared(self,user,image):
|
||||
imgpath = self.imgpath + "private/" + user + "/"
|
||||
'''imgpath = self.imgpath + "private/" + user + "/"
|
||||
image_info_file = open(imgpath+"."+image+".info",'r')
|
||||
[time, isshare] = image_info_file.readlines()
|
||||
image_info_file.close()
|
||||
if isshare == "shared":
|
||||
image_info_file.close()'''
|
||||
image = Image.query.filter_by(imagename=image,ownername=user).first()
|
||||
if image is None:
|
||||
return ""
|
||||
if image.isshared == True:
|
||||
return "true"
|
||||
else:
|
||||
return "false"
|
||||
|
|
13
src/model.py
13
src/model.py
|
@ -365,7 +365,18 @@ class VCluster(db.Model):
|
|||
class Image(db.Model):
|
||||
__bind_key__ = 'system'
|
||||
imagename = db.Column(db.String(50))
|
||||
id = db.Column(db.BigInteger, primary_key=True)
|
||||
id = db.Column(db.Integer, primary_key=True)
|
||||
isshared = db.Column(db.Boolean)
|
||||
ownername = db.Column(db.String(20))
|
||||
create_time = db.Colum(db.DateTime)
|
||||
description = db.Column(db.Text)
|
||||
|
||||
def __init__(self,imagename,isshared,ownername,description):
|
||||
self.imagename = imagename
|
||||
self.isshared = isshared
|
||||
self.ownername = ownername
|
||||
self.description = description
|
||||
self.create_time = datetime.now()
|
||||
|
||||
def __repr__(self):
|
||||
return "{\"id\":\"%d\",\"imagename\":\"%s\",\"isshared\":\"%s\",\"ownername\":\"%s\",\"updatetime\":\"%s\",\"description\":\"%s\"}" % (self.id,self.imagename,str(self.isshared),self.create_time.strftime("%Y-%m-%d %H:%M:%S"),self.ownername,self.description)
|
||||
|
|
|
@ -424,27 +424,24 @@ class VclusterMgr(object):
|
|||
return [True, "image not exists"]
|
||||
|
||||
def create_image(self,username,clustername,containername,imagename,description,imagenum=10):
|
||||
[status, info] = self.get_clusterinfo(clustername,username)
|
||||
[status, vcluster] = self.get_vcluster(clustername,username)
|
||||
if not status:
|
||||
return [False, "cluster not found"]
|
||||
containers = info['containers']
|
||||
containers = vcluster.containers
|
||||
for container in containers:
|
||||
if container['containername'] == containername:
|
||||
if container.containername == containername:
|
||||
logger.info("container: %s found" % containername)
|
||||
worker = xmlrpc.client.ServerProxy("http://%s:%s" % (container['host'], env.getenv("WORKER_PORT")))
|
||||
worker = xmlrpc.client.ServerProxy("http://%s:%s" % (containe.host, env.getenv("WORKER_PORT")))
|
||||
if worker is None:
|
||||
return [False, "The worker can't be found or has been stopped."]
|
||||
res = worker.create_image(username,imagename,containername,description,imagenum)
|
||||
container['lastsave'] = datetime.datetime.now().strftime("%Y-%m-%d %H:%M:%S")
|
||||
container['image'] = imagename
|
||||
container.lastsave = datetime.datetime.now()
|
||||
container.image = imagename
|
||||
break
|
||||
else:
|
||||
res = [False, "container not found"]
|
||||
logger.error("container: %s not found" % containername)
|
||||
clusterpath = self.fspath + "/global/users/" + username + "/clusters/" + clustername
|
||||
infofile = open(clusterpath, 'w')
|
||||
infofile.write(json.dumps(info))
|
||||
infofile.close()
|
||||
db.session.commit()
|
||||
return res
|
||||
|
||||
def delete_cluster(self, clustername, username, user_info):
|
||||
|
|
Loading…
Reference in New Issue