From decbd4b3e5b3a18b6e015c4df55d57fe7b56cc8a Mon Sep 17 00:00:00 2001
From: Alain Takoudjou <talino@tiolive.com>
Date: Fri, 29 Jun 2012 18:03:42 +0200
Subject: [PATCH] Adding comments

---
 slapos/runner/gittools.py |  33 ++++++++
 slapos/runner/utils.py    | 165 +++++++++++++++++++++++++++++++++++++-
 slapos/runner/views.py    |  11 +++
 3 files changed, 205 insertions(+), 4 deletions(-)

diff --git a/slapos/runner/gittools.py b/slapos/runner/gittools.py
index 65534a9..6e32586 100644
--- a/slapos/runner/gittools.py
+++ b/slapos/runner/gittools.py
@@ -23,6 +23,15 @@ class Popen(subprocess.Popen):
     self.stdin = None
 
 def cloneRepo(data):
+  """Clonne a repository
+  Args:
+    data: a dictionnary of parameters to use:
+      data['path'] is the path of the new project
+      data['repo'] is the url of the repository to be cloned
+      data['email'] is the user email
+      data['user'] is the name of the user
+  Returns:
+    a jsonify data"""
   workDir = data['path']
   if not workDir:
     return jsonify(code=0,
@@ -47,6 +56,11 @@ def cloneRepo(data):
   return jsonify(code=code, result=json)
 
 def gitStatus(project):
+  """Run git status and return status of specified project folder
+  Args:
+    project: path of the projet ti get status
+  Returns:
+    a parsed string that contains the result of git status"""
   code = 0
   json = ""
   try:
@@ -61,6 +75,12 @@ def gitStatus(project):
   return jsonify(code=code, result=json, branch=branch, dirty=isdirty)
 
 def switchBranch(project, name):
+  """Switch a git branch
+  Args:
+    project: directory of the local git repository
+    name: switch from current branch to `name` branch
+  Returns:
+    a jsonify data"""
   code = 0
   json = ""
   try:
@@ -78,6 +98,13 @@ def switchBranch(project, name):
   return jsonify(code=code, result=json)
 
 def addBranch(project, name, onlyCheckout=False):
+  """Add new git branch to the repository
+  Args:
+    project: directory of the local git repository
+    name: name of the new branch
+    onlyCheckout: if True then the branch `name` is created before checkout
+  Returns:
+    a jsonify data"""
   code = 0
   json = ""
   try:
@@ -93,6 +120,7 @@ def addBranch(project, name, onlyCheckout=False):
   return jsonify(code=code, result=json)
 
 def getDiff(project):
+  """Get git diff for the specified project directory"""
   result = ""
   try:
     repo = Repo(project)
@@ -104,6 +132,10 @@ def getDiff(project):
   return result
 
 def gitPush(project, msg):
+  """Commit and Push changes for the specified repository
+  Args:
+    project: directory of the local repository
+    msg: commit message"""
   code = 0
   json = ""
   undo_commit = False
@@ -145,5 +177,6 @@ def gitPull(project):
   return jsonify(code=code, result=result)
 
 def safeResult(result):
+  """Parse string and remove credential of the user"""
   regex=re.compile("(https:\/\/)([\w\d\._-]+:[\w\d\._-]+)\@([\S]+\s)", re.VERBOSE)
   return regex.sub(r'\1\3', result)
\ No newline at end of file
diff --git a/slapos/runner/utils.py b/slapos/runner/utils.py
index b1f10bd..e3f1303 100755
--- a/slapos/runner/utils.py
+++ b/slapos/runner/utils.py
@@ -41,6 +41,17 @@ def html_escape(text):
   return "".join(html_escape_table.get(c,c) for c in text)
 
 def checkLogin(config, login, pwd):
+  """
+  User authentication method
+
+  Args:
+    config: Slaprunner configuration.
+    login: username of the user.
+    pwd: password associate to username.
+
+  Returns:
+    a list of user informations or False if authentication fail.
+  """
   user = getSession(config)
   salt = "runner81" #to be changed
   current_pwd = hashlib.md5( salt + pwd ).hexdigest()
@@ -49,6 +60,11 @@ def checkLogin(config, login, pwd):
   return False
 
 def getSession(config):
+  """
+  Get the session data of current user.
+  Returns:
+    a list of user informations or False if fail to read data.
+  """
   user_path = os.path.join(config['runner_workdir'], '.users')
   user = ""
   if os.path.exists(user_path):
@@ -63,6 +79,17 @@ def getSession(config):
   return user
 
 def saveSession(config, session, account):
+  """
+  Save account information for the current user
+
+  Args:
+    config: Slaprunner configuration
+    session: Flask session
+    account: New session data to be save
+
+  Returns:
+    True if all goes well or str (error message) if fail
+  """
   user = os.path.join(config['runner_workdir'], '.users')
   backup = False
   try:
@@ -88,6 +115,10 @@ def saveSession(config, session, account):
     return str(e)
 
 def updateProxy(config):
+  """
+  Configure Slapos Node computer and partitions.
+  Send current Software Release to Slapproxy for compilation and deployment.
+  """
   if not os.path.exists(config['instance_root']):
     os.mkdir(config['instance_root'])
   slap = slapos.slap.slap()
@@ -141,6 +172,7 @@ def updateProxy(config):
   return True
 
 def readPid(file):
+  """Read process pid from file `file`"""
   if os.path.exists(file):
     data = open(file).read().strip()
     try:
@@ -151,9 +183,17 @@ def readPid(file):
 
 
 def writePid(file, pid):
+  """Save process pid into a file `file`"""
   open(file, 'w').write(str(pid))
 
 def updateInstanceParameter(config, software_type=None):
+  """
+  Reconfigure Slapproxy to re-deploy current Software Instance with parameters.
+
+  Args:
+    config: Slaprunner configuration.
+    software_type: reconfigure Software Instance with software type.
+  """
   slap = slapos.slap.slap()
   slap.initializeConnection(config['master_url'])
   #Get current software release profile
@@ -163,7 +203,7 @@ def updateInstanceParameter(config, software_type=None):
     profile = realpath(config, os.path.join(software_folder,
                                           config['software_profile']))
   except:
-    return False
+    raise Exception("Software Release profile not found")
   #get instance parameter
   param_path = os.path.join(config['runner_workdir'], ".parameter.xml")
   xml_result = readParameters(param_path)
@@ -175,6 +215,7 @@ def updateInstanceParameter(config, software_type=None):
           filter_kw=None, state=None, shared=False)
 
 def startProxy(config):
+  """Start Slapproxy server"""
   proxy_pid = os.path.join(config['runner_workdir'], 'proxy.pid')
   pid = readPid(proxy_pid)
   running = False
@@ -193,6 +234,7 @@ def startProxy(config):
 
 
 def stopProxy(config):
+  """Stop Slapproxy server"""
   pid = readPid(os.path.join(config['runner_workdir'], 'proxy.pid'))
   if pid:
     try:
@@ -202,10 +244,15 @@ def stopProxy(config):
 
 
 def removeProxyDb(config):
+  """Remove Slapproxy database, this is use to initialize proxy for example when
+    configuring new Software Release"""
   if os.path.exists(config['database_uri']):
     os.unlink(config['database_uri'])
 
 def isSoftwareRunning(config):
+  """
+    Return True if slapgrid-sr is still running and false if slapgrid if not
+  """
   slapgrid_pid = os.path.join(config['runner_workdir'], 'slapgrid-sr.pid')
   pid = readPid(slapgrid_pid)
   if pid:
@@ -221,6 +268,10 @@ def isSoftwareRunning(config):
 
 
 def runSoftwareWithLock(config):
+  """
+    Use Slapgrid to compile current Software Release and wait until
+    compilation is done
+  """
   slapgrid_pid = os.path.join(config['runner_workdir'], 'slapgrid-sr.pid')
   if not isSoftwareRunning(config):
     if not os.path.exists(config['software_root']):
@@ -262,6 +313,9 @@ def runSoftwareWithLock(config):
 
 
 def isInstanceRunning(config):
+  """
+    Return True if slapgrid-cp is still running and false if slapgrid if not
+  """
   slapgrid_pid = os.path.join(config['runner_workdir'], 'slapgrid-cp.pid')
   pid = readPid(slapgrid_pid)
   if pid:
@@ -276,6 +330,7 @@ def isInstanceRunning(config):
   return running
 
 def killRunningSlapgrid(config, ptype):
+  """Kill slapgrid process and all running children process"""
   slapgrid_pid = os.path.join(config['runner_workdir'], ptype)
   pid = readPid(slapgrid_pid)
   if pid:
@@ -304,6 +359,10 @@ def pidppid(pid):
   return list(int(p) for p, pp in ppid if int(pp) == pid)
 
 def runInstanceWithLock(config):
+  """
+    Use Slapgrid to deploy current Software Release and wait until
+    deployment is done.
+  """
   slapgrid_pid = os.path.join(config['runner_workdir'], 'slapgrid-cp.pid')
   if not isInstanceRunning(config):
     startProxy(config)
@@ -317,13 +376,24 @@ def runInstanceWithLock(config):
     return True
   return False
 
-def getProfilePath(peojectDir, profile):
-  if not os.path.exists(os.path.join(peojectDir, ".project")):
+def getProfilePath(projectDir, profile):
+  """
+  Return the path of the current Software Release `profile`
+
+  Args:
+    projectDir: Slaprunner workspace location.
+    profile: file to search into the workspace.
+
+  Returns:
+    String, path of current Software Release profile
+  """
+  if not os.path.exists(os.path.join(projectDir, ".project")):
     return False
-  projectFolder = open(os.path.join(peojectDir, ".project")).read()
+  projectFolder = open(os.path.join(projectDir, ".project")).read()
   return os.path.join(projectFolder, profile)
 
 def getSlapStatus(config):
+  """Return all Slapos Partitions with associate informations"""
   slap = slapos.slap.slap()
   slap.initializeConnection(config['master_url'])
   partition_list = []
@@ -354,10 +424,12 @@ def runBuildoutAnnotate(config):
   return False
 
 def svcStopAll(config):
+  """Stop all Instance process on this computer"""
   return Popen([config['supervisor'], config['configuration_file_path'],
                 'shutdown']).communicate()[0]
 
 def removeInstanceRoot(config):
+  """Clean instance directory and stop all its running process"""
   if os.path.exists(config['instance_root']):
     svcStopAll(config)
     for root, dirs, files in os.walk(config['instance_root']):
@@ -369,6 +441,7 @@ def removeInstanceRoot(config):
     shutil.rmtree(config['instance_root'])
 
 def getSvcStatus(config):
+  """Return all Softwares Instances process Informations"""
   result = Popen([config['supervisor'], config['configuration_file_path'],
                   'status']).communicate()[0]
   regex = "(^unix:.+\.socket)|(^error:).*$"
@@ -382,15 +455,40 @@ def getSvcStatus(config):
   return supervisord
 
 def getSvcTailProcess(config, process):
+  """Get log for the specifie process
+
+  Args:
+    config: Slaprunner configuration
+    process: process name. this value is pass to supervisord.
+  Returns:
+    a string that contains the log of the process.
+  """
   return Popen([config['supervisor'], config['configuration_file_path'],
                 "tail", process]).communicate()[0]
 
 def svcStartStopProcess(config, process, action):
+  """Send start or stop process command to supervisord
+
+  Args:
+    config: Slaprunner configuration.
+    process: process to start or stop.
+    action: current state which is used to generate the new process state.
+  """
   cmd = {"RESTART":"restart", "STOPPED":"start", "RUNNING":"stop", "EXITED":"start", "STOP":"stop"}
   return Popen([config['supervisor'], config['configuration_file_path'],
                 cmd[action], process]).communicate()[0]
 
 def getFolderContent(config, folder):
+  """
+  Read all file and folder into specified directory
+
+  Args:
+    config: Slaprunner configuration.
+    folder: the directory to read.
+
+  Returns:
+    Html formated string or error message when fail.
+  """
   r=['<ul class="jqueryFileTree" style="display: none;">']
   try:
     folder = str(folder)
@@ -418,6 +516,16 @@ def getFolderContent(config, folder):
   return jsonify(result=''.join(r))
 
 def getFolder(config, folder):
+  """
+  Read list of folder for the specified directory
+
+  Args:
+    config: Slaprunner configuration.
+    folder: the directory to read.
+
+  Returns:
+    Html formated string or error message when fail.
+  """
   r=['<ul class="jqueryFileTree" style="display: none;">']
   try:
     folder = str(folder)
@@ -442,6 +550,13 @@ def getFolder(config, folder):
   return jsonify(result=''.join(r))
 
 def getProjectList(folder):
+  """Return the list of projet (folder) into the workspace
+
+  Agrs:
+    folder: path of the workspace
+  Returns:
+    a list that contains each folder name.
+  """
   project = []
   project_list = sorted(os.listdir(folder), key=str.lower)
   for elt in project_list:
@@ -449,6 +564,14 @@ def getProjectList(folder):
   return project
 
 def configNewSR(config, projectpath):
+  """Configure a Software Release as current Software Release
+
+  Args:
+    config: slaprunner configuration
+    projectpath: path of the directory that contains the software realease to configure
+  Returns:
+    True if all is done well, otherwise return false.
+  """
   folder = realpath(config, projectpath)
   if folder:
     if isInstanceRunning(config):
@@ -465,6 +588,13 @@ def configNewSR(config, projectpath):
     return False
 
 def newSoftware(folder, config, session):
+  """
+  Create a new Software Release folder with default profiles
+
+  Args:
+    folder: directory of the new software release
+    config: slraprunner configuration
+    session: Flask session directory"""
   json = ""
   code = 0
   runner_dir = config['runner_workdir']
@@ -498,12 +628,14 @@ def newSoftware(folder, config, session):
   return jsonify(code=code, result=json)
 
 def checkSoftwareFolder(path, config):
+  """Check id `path` is a valid Software Release folder"""
   realdir = realpath(config, path)
   if realdir and os.path.exists(os.path.join(realdir, config['software_profile'])):
     return jsonify(result=path)
   return jsonify(result="")
 
 def getProjectTitle(config):
+  """Generate the name of the current software Release (for slaprunner UI)"""
   conf = os.path.join(config['runner_workdir'], ".project")
   if os.path.exists(conf):
     project = open(conf, "r").read().split("/")
@@ -512,6 +644,7 @@ def getProjectTitle(config):
   return "No Profile"
 
 def getSoftwareReleaseName(config):
+  """Get the name of the current Software Release"""
   sr_profile = os.path.join(config['runner_workdir'], ".project")
   if os.path.exists(sr_profile):
     project = open(sr_profile, "r").read().split("/")
@@ -520,6 +653,12 @@ def getSoftwareReleaseName(config):
   return "No_name"
 
 def loadSoftwareData(runner_dir):
+  """Get All Compiled Softwares Releases name and directory
+
+  Agrs:
+    runner_dir: base directory of slapos web runner.
+  Returns:
+    a dictionnary that contains all compiled Software Release with path"""
   import pickle
   file_path = os.path.join(runner_dir, '.softdata')
   if not os.path.exists(file_path):
@@ -530,6 +669,12 @@ def loadSoftwareData(runner_dir):
   return data
 
 def writeSoftwareData(runner_dir, data):
+  """Save the list of compiled Software Release into a file
+
+  Args:
+    runner_dir: base directory of slapos web runner.
+    data: dictionnary data about real name and directory of each software release
+  """
   import pickle
   file_path = os.path.join(runner_dir, '.softdata')
   pkl_file = open(file_path, 'wb')
@@ -538,6 +683,11 @@ def writeSoftwareData(runner_dir, data):
   pkl_file.close()
 
 def removeSoftwareByName(config, folderName):
+  """Remove all content of the specified software release
+
+  Args:
+    config: slaprunner configuration
+    foldername: the name given to the software release"""
   if isSoftwareRunning(config) or isInstanceRunning(config):
     raise Exception("Software installation or instantiation in progress, cannot remove")
   path = os.path.join(config['software_root'], folderName)
@@ -662,6 +812,13 @@ def realpath(config, path, check_exist=True):
   return False
 
 def readParameters(path):
+  """Read Instance parameters stored into a local file.
+
+  Agrs:
+    path: path of the xml file that contains parameters
+
+  Return:
+    a dictionnary of instance parameters."""
   if os.path.exists(path):
     try:
       xmldoc = minidom.parse(path)
diff --git a/slapos/runner/views.py b/slapos/runner/views.py
index c853a08..f7d7912 100755
--- a/slapos/runner/views.py
+++ b/slapos/runner/views.py
@@ -77,6 +77,7 @@ def inspectSoftware():
   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")
@@ -114,6 +115,7 @@ def editInstanceProfile():
   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 = ''
@@ -127,6 +129,7 @@ def inspectInstance():
       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)
@@ -253,6 +256,7 @@ def getProjectStatus():
   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")
@@ -262,6 +266,7 @@ def editCurrentProject():
                            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)
@@ -277,6 +282,7 @@ def createFile():
   except Exception, e:
     return jsonify(code=0, result=str(e))
 
+#remove file or directory
 @app.route("/removeFile", methods=['POST'])
 def removeFile():
   try:
@@ -296,6 +302,7 @@ def removeSoftwareDir():
   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'])
@@ -379,6 +386,7 @@ def getmd5sum():
   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)
@@ -415,6 +423,7 @@ def getPath():
   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")
@@ -441,6 +450,7 @@ def saveParameterXml():
       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")
@@ -457,6 +467,7 @@ def getParameterXml(request):
   else:
     return jsonify(code=1, result=parameters)
 
+#update user account data
 @app.route("/updateAccount", methods=['POST'])
 def updateAccount():
   account = []
-- 
2.30.9