# -*- coding: utf-8 -*- from flask import Flask, request, redirect, url_for, \ render_template, flash, jsonify, session from utils import * import os import shutil import md5 from gittools import cloneRepo, gitStatus, switchBranch, addBranch, getDiff, \ gitPush, gitPull app = Flask(__name__) #Access Control: Only static files and login pages are allowed to guest @app.before_request def before_request(): if not request.path.startswith('/static'): account = getSession(app.config) if account: if request.path != '/login' and request.path != '/doLogin' and \ not checkSession(app.config, session, account): return redirect(url_for('login')) session['title'] = getProjectTitle(app.config) else: session.pop('account', None) session['title'] = "No account is defined" if request.path != "/updateAccount" and request.path != "/myAccount": return redirect(url_for('myAccount')) # general views @app.route('/') def home(): return render_template('index.html') @app.route("/login") def login(): return render_template('login.html') @app.route("/myAccount") def myAccount(): if 'account' in session: return render_template('account.html', username=session['account'][0], email=session['account'][2], name=session['account'][3].decode('utf-8')) else: return render_template('account.html') @app.route("/logout") def logout(): session.pop('account', None) return redirect(url_for('login')) @app.route('/configRepo') def configRepo(): public_key = open(app.config['public_key'], 'r').read() return render_template('cloneRepository.html', workDir='workspace', public_key=public_key, name=session['account'][3].decode('utf-8'), email=session['account'][2]) @app.route("/doLogin", methods=['POST']) def doLogin(): check_user = checkLogin(app.config, request.form['clogin'], request.form['cpwd']) if not check_user: return jsonify(code=0, result="Login or password is incorrect, please check it!") else: session['account'] = check_user return jsonify(code=1, result=check_user) # software views @app.route('/editSoftwareProfile') def editSoftwareProfile(): profile = getProfilePath(app.config['runner_workdir'], app.config['software_profile']) if profile == "": flash('Error: can not open profile, please select your project first') return render_template('updateSoftwareProfile.html', workDir='workspace', profile=profile, projectList=getProjectList(app.config['workspace'])) @app.route('/inspectSoftware', methods=['GET']) def inspectSoftware(): if not os.path.exists(app.config['software_root']): result = "" else: result = app.config['software_root'] return render_template('runResult.html', softwareRoot='software_root', softwares=loadSoftwareData(app.config['runner_workdir'])) #remove content of compiled software release @app.route('/removeSoftware') def removeSoftware(): file_config = os.path.join(app.config['runner_workdir'], ".softdata") if isSoftwareRunning(app.config) or isInstanceRunning(app.config): flash('Software installation or instantiation in progress, cannot remove') elif os.path.exists(file_config): svcStopAll(app.config) shutil.rmtree(app.config['software_root']) os.remove(os.path.join(app.config['runner_workdir'], ".softdata")) flash('Software removed') return redirect(url_for('inspectSoftware')) @app.route('/runSoftwareProfile', methods=['POST']) def runSoftwareProfile(): if runSoftwareWithLock(app.config): return jsonify(result = True) else: return jsonify(result = False) @app.route('/viewSoftwareLog', methods=['GET']) def viewSoftwareLog(): if os.path.exists(app.config['software_log']): result = tail(open(app.config['software_log'], 'r'), lines=1500) else: result = 'Not found yet' return render_template('viewLog.html', type='software', result=result) # instance views @app.route('/editInstanceProfile') def editInstanceProfile(): profile = getProfilePath(app.config['runner_workdir'], app.config['instance_profile']) if profile == "": flash('Error: can not open instance profile for this Software Release') return render_template('updateInstanceProfile.html', workDir='workspace', profile=profile, projectList=getProjectList(app.config['workspace'])) # get status of all computer partitions and process state @app.route('/inspectInstance', methods=['GET']) def inspectInstance(): file_content = '' result = '' if os.path.exists(app.config['instance_root']): file_content = 'instance_root' result = getSvcStatus(app.config) if len(result) == 0: result = [] return render_template('instanceInspect.html', file_path=file_content, supervisor=result, slap_status=getSlapStatus(app.config), supervisore=result, partition_amount=app.config['partition_amount']) #Reload instance process ans returns new value to ajax @app.route('/supervisordStatus', methods=['GET']) def supervisordStatus(): result = getSvcStatus(app.config) if not (result): return jsonify(code=0, result="") html = "<tr><th>Partition and Process name</th><th>Status</th><th>Process PID </th><th> UpTime</th><th></th></tr>" for item in result: html += "<tr>" html +="<td class='first'><b><a href='" + url_for('tailProcess', process=item[0])+"'>"+item[0]+"</a></b></td>" html +="<td align='center'><a href='"+url_for('startStopProccess', process=item[0], action=item[1])+"'>"+item[1]+"</a></td>" html +="<td align='center'>"+item[3]+"</td><td>"+item[5]+"</td>" html +="<td align='center'><a href='"+url_for('startStopProccess', process=item[0], action='RESTART')+"'>Restart</a></td>" html +="</tr>" return jsonify(code=1, result=html) @app.route('/removeInstance') def removeInstance(): if isInstanceRunning(app.config): flash('Instantiation in progress, cannot remove') else: stopProxy(app.config) removeProxyDb(app.config) startProxy(app.config) removeInstanceRoot(app.config) param_path = os.path.join(app.config['runner_workdir'], ".parameter.xml") if os.path.exists(param_path): os.remove(param_path) flash('Instance removed') return redirect(url_for('inspectInstance')) @app.route('/runInstanceProfile', methods=['POST']) def runInstanceProfile(): if not os.path.exists(app.config['instance_root']): os.mkdir(app.config['instance_root']) if runInstanceWithLock(app.config): return jsonify(result = True) else: return jsonify(result = False) @app.route('/viewInstanceLog', methods=['GET']) def viewInstanceLog(): if os.path.exists(app.config['instance_log']): result = open(app.config['instance_log'], 'r').read() else: result = 'Not found yet' return render_template('viewLog.html', type='instance', result=result) @app.route('/stopAllPartition', methods=['GET']) def stopAllPartition(): svcStopAll(app.config) return redirect(url_for('inspectInstance')) @app.route('/tailProcess/name/<process>', methods=['GET']) def tailProcess(process): return render_template('processTail.html', process_log=getSvcTailProcess(app.config, process), process=process) @app.route('/startStopProccess/name/<process>/cmd/<action>', methods=['GET']) def startStopProccess(process, action): svcStartStopProcess(app.config, process, action) return redirect(url_for('inspectInstance')) @app.route('/showBuildoudAnnotate', methods=['GET']) def showBuildoudAnnotate(): if runBuildoutAnnotate(app.config): flash('Started.') else: flash('Please run software before') return redirect(url_for('viewBuildoudAnnotate')) @app.route('/viewBuildoudAnnotate', methods=['GET']) def viewBuildoudAnnotate(): if os.path.exists(app.config['annotate_log']): result = open(app.config['annotate_log'], 'r').read() else: result = 'Not found yet' return render_template('viewLog.html', type='Instance', result=result, running=isInstanceRunning(app.config)) @app.route('/openProject/<method>', methods=['GET']) def openProject(method): return render_template('projectFolder.html', method=method, workDir='workspace') @app.route('/cloneRepository', methods=['POST']) def cloneRepository(): path = realpath(app.config, request.form['name'], False) data = {"repo":request.form['repo'], "user":request.form['user'], "email":request.form['email'], "path":path} return cloneRepo(data) @app.route('/readFolder', methods=['POST']) def readFolder(): return getFolderContent(app.config, request.form['dir']) @app.route('/openFolder', methods=['POST']) def openFolder(): return getFolder(app.config, request.form['dir']) @app.route('/createSoftware', methods=['POST']) def createSoftware(): return newSoftware(request.form['folder'], app.config, session) @app.route("/checkFolder", methods=['POST']) def checkFolder(): return checkSoftwareFolder(request.form['path'], app.config) @app.route("/setCurrentProject", methods=['POST']) def setCurrentProject(): if configNewSR(app.config, request.form['path']): session['title'] = getProjectTitle(app.config) return jsonify(code=1, result="") else: return jsonify(code=0, result=("Can not setup this Software Release")) @app.route("/manageProject", methods=['GET']) def manageProject(): return render_template('manageProject.html', workDir='workspace', project=getProjectList(app.config['workspace'])) @app.route("/getProjectStatus", methods=['POST']) def getProjectStatus(): path = realpath(app.config, request.form['project']) if path: return gitStatus(path) else: return jsonify(code=0, result="Can not read folder: Permission Denied") #view for current software release files @app.route("/editCurrentProject") def editCurrentProject(): project = os.path.join(app.config['runner_workdir'], ".project") if os.path.exists(project): return render_template('softwareFolder.html', workDir='workspace', project=open(project).read(), projectList=getProjectList(app.config['workspace'])) return redirect(url_for('configRepo')) #create file or directory @app.route("/createFile", methods=['POST']) def createFile(): path = realpath(app.config, request.form['file'], False) if not path: return jsonify(code=0, result="Error when creating your " + \ request.form['type'] + ": Permission Denied") try: if request.form['type'] == "file": f = open(path, 'w').write(" ") else: os.mkdir(path) return jsonify(code=1, result="") except Exception, e: return jsonify(code=0, result=str(e)) #remove file or directory @app.route("/removeFile", methods=['POST']) def removeFile(): try: if request.form['type'] == "folder": shutil.rmtree(request.form['path']) else: os.remove(request.form['path']) return jsonify(code=1, result="") except Exception, e: return jsonify(code=0, result=str(e)) @app.route("/removeSoftwareDir", methods=['POST']) def removeSoftwareDir(): try: data = removeSoftwareByName(app.config, request.form['name']) return jsonify(code=1, result=data) except Exception, e: return jsonify(code=0, result=str(e)) #read file and return content to ajax @app.route("/getFileContent", methods=['POST']) def getFileContent(): file_path = realpath(app.config, request.form['file']) if file_path: if not request.form.has_key('truncate'): return jsonify(code=1, result=open(file_path, 'r').read()) else: content = tail(open(file_path, 'r'), int(request.form['truncate'])) return jsonify(code=1, result=content) else: return jsonify(code=0, result="Error: No such file!") @app.route("/saveFileContent", methods=['POST']) def saveFileContent(): file_path = realpath(app.config, request.form['file']) if file_path: open(file_path, 'w').write(request.form['content'].encode("utf-8")) return jsonify(code=1, result="") else: return jsonify(code=0, result="Error: No such file!") @app.route("/changeBranch", methods=['POST']) def changeBranch(): path = realpath(app.config, request.form['project']) if path: return switchBranch(path, request.form['name']) else: return jsonify(code=0, result="Can not read folder: Permission Denied") @app.route("/newBranch", methods=['POST']) def newBranch(): path = realpath(app.config, request.form['project']) if path: if request.form['create'] == '1': return addBranch(path, request.form['name']) else: return addBranch(path, request.form['name'], True) else: return jsonify(code=0, result="Can not read folder: Permission Denied") @app.route("/getProjectDiff/<project>", methods=['GET']) def getProjectDiff(project): path = os.path.join(app.config['workspace'], project) return render_template('projectDiff.html', project=project, diff=getDiff(path)) @app.route("/pushProjectFiles", methods=['POST']) def pushProjectFiles(): path = realpath(app.config, request.form['project']) if path: return gitPush(path, request.form['msg']) else: return jsonify(code=0, result="Can not read folder: Permission Denied") @app.route("/pullProjectFiles", methods=['POST']) def pullProjectFiles(): path = realpath(app.config, request.form['project']) if path: return gitPull(path) else: return jsonify(code=0, result="Can not read folder: Permission Denied") @app.route("/checkFileType", methods=['POST']) def checkFileType(): path = realpath(app.config, request.form['path']) if not path: return jsonify(code=0, result="Can not open file: Permission Denied!") if isText(path): return jsonify(code=1, result="text") else: return jsonify(code=0, result="Can not open a binary file, please select a text file!") @app.route("/getmd5sum", methods=['POST']) def getmd5sum(): realfile = realpath(app.config, request.form['file']) if not realfile: return jsonify(code=0, result="Can not open file: Permission Denied!") md5 = md5sum(realfile) if md5: return jsonify(code=1, result=md5) else: return jsonify(code=0, result="Can not get md5sum for this file!") #return informations about state of slapgrid process @app.route("/slapgridResult", methods=['POST']) def slapgridResult(): software_state = isSoftwareRunning(app.config) instance_state = isInstanceRunning(app.config) log_result = {"content":"", "position":0} if request.form['log'] == "software" or\ request.form['log'] == "instance": log_file = request.form['log'] + "_log" if os.path.exists(app.config[log_file]): log_result = readFileFrom(open(app.config[log_file], 'r'), int(request.form['position'])) return jsonify(software=software_state, instance=instance_state, result=(instance_state or software_state), content=log_result) @app.route("/stopSlapgrid", methods=['POST']) def stopSlapgrid(): result = killRunningSlapgrid(app.config, request.form['type']) return jsonify(result=result) @app.route("/getPath", methods=['POST']) def getPath(): files = request.form['file'].split('#') list = [] for p in files: path = realpath(app.config, p) if not p: list = [] break else: list.append(path) realfile = string.join(list, "#") if not realfile: return jsonify(code=0, result="Can not access to this file: Permission Denied!") else: return jsonify(code=1, result=realfile) #update instance parameter into a local xml file @app.route("/saveParameterXml", methods=['POST']) def saveParameterXml(): project = os.path.join(app.config['runner_workdir'], ".project") if not os.path.exists(project): return jsonify(code=0, result="Please first open a Software Release") content = request.form['parameter'].encode("utf-8") param_path = os.path.join(app.config['runner_workdir'], ".parameter.xml") try: f = open(param_path, 'w') f.write(content) f.close() result = readParameters(param_path) except Exception, e: result = str(e) software_type = None if(request.form['software_type']): software_type = request.form['software_type'] if type(result) == type(''): return jsonify(code=0, result=result) else: try: updateInstanceParameter(app.config, software_type) except Exception, e: return jsonify(code=0, result="An error occurred while applying your settings!<br/>" + str(e)) return jsonify(code=1, result="") #read instance parameters into the local xml file and return a dict @app.route("/getParameterXml/<request>", methods=['GET']) def getParameterXml(request): param_path = os.path.join(app.config['runner_workdir'], ".parameter.xml") if not os.path.exists(param_path): default = '<?xml version="1.0" encoding="utf-8"?>\n' default += '<instance>\n</instance>' return jsonify(code=1, result=default) if request == "xml": parameters = open(param_path, 'r').read() else: parameters = readParameters(param_path) if type(parameters) == type('') and request != "xml": return jsonify(code=0, result=parameters) else: return jsonify(code=1, result=parameters) #update user account data @app.route("/updateAccount", methods=['POST']) def updateAccount(): account = [] user = os.path.join(app.config['runner_workdir'], '.users') account.append(request.form['username'].strip()) account.append(request.form['password'].strip()) account.append(request.form['email'].strip()) account.append(request.form['name'].strip()) result = saveSession(app.config, session, account) if type(result) == type(""): return jsonify(code=0, result=result) else: return jsonify(code=1, result="")