class IRServer(object): ############################################################ # __init__ ############################################################ def __init__(self): super(IRServer, self).__init__() self.numparams = 4 self._service = IRService() self._log = self._service.getLog() self._repoconf = self._service.getRepoConf() self.port = self._repoconf.getPort() self.proc_max = self._repoconf.getProcMax() self.refresh_status = self._repoconf.getRefreshStatus() self._authorizedUsers = self._repoconf.getAuthorizedUsers() self._ca_certs = self._repoconf.getCaCerts() self._certfile = self._repoconf.getCertFile() self._keyfile = self._repoconf.getKeyFile() def start(self): sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM) sock.bind(('', self.port)) sock.listen(1) #Maximum of system unaccepted connections. Maximum value depend of the system (usually 5) self._log.info('Starting Server on port ' + str(self.port)) proc_list = [] total_count = 0 while True: if len(proc_list) == self.proc_max: full = True while full: for i in range(len(proc_list) - 1, -1, -1): #self._log.debug(str(proc_list[i])) if not proc_list[i].is_alive(): #print "dead" proc_list.pop(i) #put here terminate?? just in case the process is not done but neither alive?? I have noticed that when IOError the process keep running full = False if full: time.sleep(self.refresh_status) total_count += 1 #channel, details = sock.accept() newsocket, fromaddr = sock.accept() connstream = None try: connstream = ssl.wrap_socket(newsocket, server_side=True, ca_certs=self._ca_certs, cert_reqs=ssl.CERT_REQUIRED, certfile=self._certfile, keyfile=self._keyfile, ssl_version=ssl.PROTOCOL_TLSv1) #print connstream proc_list.append(Process(target=self.repo, args=(connstream,))) proc_list[len(proc_list) - 1].start() except ssl.SSLError: self._log.error("Unsuccessful connection attempt from: " + repr(fromaddr) + " " + str(sys.exc_info())) except socket.error: self._log.error("Error with the socket connection") except: self._log.error("Uncontrolled Error: " + str(sys.exc_info())) if type(connstream) is ssl.SSLSocket: connstream.shutdown(socket.SHUT_RDWR) connstream.close() #def auth(self, userCred): # return FGAuth.auth(self.user, userCred) def repo(self, channel): self._log = self._log.getLogger("Img Repo Server." + str(os.getpid())) self._service.setLog(self._log) self._log.info('Processing request') #it will have the IP of the VM vmaddr = "" options = '' vmID = 0 #receive the message data = channel.read(2048) self._log.debug("received data: " + data) params = data.split('|') #params[0] is user that authenticates #params[1] is the user password #params[2] is the type of password #params[3] is the command #params[4] is the user that interact with the repo. Usually is the same that params[0] #params[5...] are the options if (len(params) <= self.numparams): msg = "ERROR: Invalid Number of Parameters" self.errormsg(channel, msg) sys.exit(1) self.user = params[0].strip() #ONLY for authentication. To specify the user that call methods you need to use params[4] passwd = params[1].strip() passwdtype = params[2].strip() command = params[3].strip() for i in range(len(params)): params[i] = params[i].strip() if not self.user in self._authorizedUsers: if not (self.user == params[4]): msg = "ERROR: You are not authorized to act in behalf of other user" self.errormsg(channel, msg) sys.exit(1) retry = 0 maxretry = 3 endloop = False while (not endloop): #userCred = FGCredential(passwd, passwdtype) status = self._service.auth(self.user, passwd, passwdtype) if status == True: channel.write("OK") endloop = True elif status == False: #_authorizedUsers is not used currently. If we want to activate it, we need to make sure that the authizedUsers are in the Repository database if self.user in self._authorizedUsers: #because these users are services that cannot retry. msg = "ERROR: authentication failed" self.errormsg(channel, msg) sys.exit(1) else: msg = "ERROR: authentication failed. Try again" self._log.error(msg) retry += 1 if retry < maxretry: channel.write("TryAuthAgain") passwd = channel.read(2048) else: msg = "ERROR: authentication failed" self.errormsg(channel, msg) sys.exit(1) else: msg = status #this is NoActive or NoUser self.errormsg(channel, msg) sys.exit(1) #channel.write("OK") ## For test, remove previous line needtoclose = False if (command == "list"): if (len(params) == self.numparams + 2): #user, query string #print params[5] output = self._service.query(params[4], params[5]) channel.write(str(output)) needtoclose = True else: msg = "Invalid Number of Parameters" self.errormsg(channel, msg) elif (command == "get"): #user, img/uri, imgid if (len(params) == self.numparams + 3): output = self._service.get(params[4], params[5], params[6]) channel.write(str(output)) if output != None: status = channel.read(1024) ##just to wait for client answer. if status != 'OK': self._log.error("ERROR: Client did not receive the image") needtoclose = False else: needtoclose = True if (self._service.getBackend() != "mysql"): cmdrm = " rm -f " + output self._log.debug("Deleting Temporal file: " + cmdrm) os.system(cmdrm) else: msg = "Invalid Number of Parameters" self.errormsg(channel, msg) elif (command == "put"): #user, img_size, extension, attributeString if (len(params) == self.numparams + 4): self._log.debug("Before uploadValidator ") output = self._service.uploadValidator(params[4], long(params[5])) self._log.debug("After uploadValidator "+str(output)) if str(output) == 'True': self._log.debug("Before genImgId ") imgId = self._service.genImgId() self._log.debug("After genImgId "+str(imgId)) if imgId != None: self._log.debug("sending to the client: "+str(self._service.getImgStore())+ " , "+str(imgId)) channel.write(self._service.getImgStore() + "," + str(imgId)) self._log.debug("sent and waiting in the read") #waiting for client to upload image output = channel.read(2048) if output != 'Fail': #user, imgId, imgFile(uri), attributeString, size, extension output = self._service.put(params[4], imgId, output, params[7], long(params[5]), params[6]) channel.write(str(output)) needtoclose = True else: os.system("rm -f "+self._service.getImgStore() + "/" + str(imgId)) self._log.debug("rm -f "+self._service.getImgStore() + "/" + str(imgId)) else: channel.write() msg = "ERROR: The imgId generation failed" self.errormsg(channel, msg) else: output = str(output) if output == "NoUser": status = "ERROR: The User does not exist" elif (output == "NoActive"): status = "ERROR: The User is not active" elif (output == 'False'): status = "ERROR: The file exceed the quota" else: status = "ERROR: " + output msg = status self.errormsg(channel, msg) else: msg = "ERROR: Invalid Number of Parameters" self.errormsg(channel, msg) #send storage directory, temporal or not #receive the OK, meaning that the image is already there elif (command == "modify"): #userid, imgid, attributestring if (len(params) == self.numparams + 3): output = self._service.updateItem(params[4], params[5], params[6]) channel.write(str(output)) else: msg = "Invalid Number of Parameters" self.errormsg(channel, msg) elif (command == "remove"): #user, imgid if (len(params) == self.numparams + 2): output = self._service.remove(params[4], params[5]) channel.write(str(output)) else: msg = "Invalid Number of Parameters" self.errormsg(channel, msg) elif (command == "setPermission"): #user, imgid, query if (len(params) == self.numparams + 3): output = self._service.updateItem(params[4], params[5], "permission=" + params[6]) channel.write(str(output)) else: msg = "Invalid Number of Parameters" self.errormsg(channel, msg) elif (command == "histimg"): #userId, imgId if (len(params) == self.numparams + 2): output = self._service.histImg(params[4], params[5]) channel.write(str(output)) else: msg = "Invalid Number of Parameters" self.errormsg(channel, msg) elif (command == "histuser"): #userId, userId if (len(params) == self.numparams + 2): output = self._service.histUser(params[4], params[5]) channel.write(str(output)) else: msg = "Invalid Number of Parameters" self.errormsg(channel, msg) #elif (command == "uploadValidator"): # #user, size of the img to upload # if (len(optionlist) != 2): # output = self._service.uploadValidator(optionlist[0], long(optionlist[1])) # channel.write(str(output)) # else: # msg = "Invalid Number of Parameters" # self.errormsg(channel, msg) #elif (command == "genImgId"): # if (len(optionlist) != 1): # output = self._service.genImgId() # channel.write(str(output)) # else: # msg = "Invalid Number of Parameters" # self.errormsg(channel, msg) elif (command == "getBackend"): if (len(params) == self.numparams + 1): output = self._service.getBackend() output1 = self._service.getImgStore() channel.write(str(output) + str(output1)) else: msg = "Invalid Number of Parameters" self.errormsg(channel, msg) elif (command == "useradd"): #userid, useridtoadd if (len(params) == self.numparams + 2): output = self._service.userAdd(params[4], params[5]) channel.write(str(output)) else: msg = "Invalid Number of Parameters" self.errormsg(channel, msg) elif (command == "userdel"): #userid, useridtodel if (len(params) == self.numparams + 2): output = self._service.userDel(params[4], params[5]) channel.write(str(output)) else: msg = "Invalid Number of Parameters" self.errormsg(channel, msg) elif (command == "userlist"): #userid if (len(params) == self.numparams + 1): output = self._service.userList(params[4]) channel.write(str(output)) else: msg = "Invalid Number of Parameters" self.errormsg(channel, msg) elif (command == "setUserQuota"): #userid, useridtomodify, quota in bytes if (len(params) == self.numparams + 3): output = self._service.setUserQuota(params[4], params[5], long(params[6])) channel.write(str(output)) else: msg = "Invalid Number of Parameters" self.errormsg(channel, msg) elif (command == "setUserRole"): #userid, useridtomodify, role if (len(params) == self.numparams + 3): output = self._service.setUserRole(params[4], params[5], params[6]) channel.write(str(output)) else: msg = "Invalid Number of Parameters" self.errormsg(channel, msg) elif (command == "setUserStatus"): if (len(params) == self.numparams + 3): output = self._service.setUserStatus(params[4], params[5], params[6]) channel.write(str(output)) else: msg = "Invalid Number of Parameters" self.errormsg(channel, msg) elif (command == "getUserStatus"): #userId if (len(params) == self.numparams + 1): output = self._service.getUserStatus(params[4]) channel.write(str(output)) else: msg = "Invalid Number of Parameters" self.errormsg(channel, msg) else: msg = "Invalid Command: " + command self.errormsg(channel, msg) needtoclose = False if needtoclose: channel.shutdown(socket.SHUT_RDWR) channel.close() self._log.info("Image Repository Request DONE") else: self._log.info("Image Repository Request DONE") def errormsg(self, channel, msg): self._log.error(msg) try: channel.write(msg) channel.shutdown(socket.SHUT_RDWR) channel.close() except: self._log.debug("In errormsg: " + str(sys.exc_info())) self._log.info("Image Repository Request DONE")