#!/usr/bin/python ''' Created on Aug 23, 2018 @author: Hovanes Egiyan ''' import fcntl, struct, subprocess, os, errno, shutil, sys, optparse lock = struct.pack('hhllhh', fcntl.F_WRLCK, 0 , 0 , 0 , 0 , 0) unlock = struct.pack('hhllhh', fcntl.F_UNLCK, 0 , 0 , 0 , 0 , 0) defaultDirName = "Default" def tryExistingWorkspaces(dirName) : """ Return a workspace name that already exists in direcotry dirName and is not locked. If such a workspaces does not exist, return None """ # print "Searching for avilable CSS workspace in {0}".format(dirName) workSpaceList = [os.path.join(dirName, dI) for dI in os.listdir(dirName) if (os.path.isdir(os.path.join(dirName, dI)) and dI != defaultDirName) ] # print workSpaceList for workSpace in workSpaceList: lockFileName = os.path.join(os.path.join(workSpace, ".metadata"), ".lock") # print "Will try file <{0}>".format(lockFileName) testFile = None try: testFile = open(lockFileName, "w") fcntl.fcntl(testFile.fileno(), fcntl.F_SETLK, lock) fcntl.fcntl(testFile.fileno(), fcntl.F_SETLK, unlock) testFile.close() os.remove(lockFileName) except IOError: if testFile != None: testFile.close() continue # print "Found unlocked workspace {0}, launching CSS".format(workSpace) return workSpace print "No available workspaces found in {0}".format(dirName) return None def getWorkSpaceDirName( dirName, wsNumber ) : """ Get the directory name for a new workspace in a directory dirName and with number wsNumber """ # print "Directory is {0} , number is {1}".format( dirName, wsNumber ) wsName = "Workspace_{0:06d}".format(wsNumber) return os.path.join(dirName, wsName) def createWorkSpace(dirName): wsDirName = None # Name of the template workspace that never gets used but keeps getting copied templateWorkspaceDirName = os.path.join( dirName, defaultDirName ) if( not os.path.exists(templateWorkspaceDirName) ): print "Template workspace directory <{0}> does not exist".format(templateWorkspaceDirName) raise errno.ENOENT # File where we keep the last workspace number numberFileName = os.path.join( dirName, ".ws_number") # print "Reading file number from <{0}>".format(numberFileName) try: # Open the file with the WS number numberFile = open(numberFileName, "r") firstLine = numberFile.next() # print firstLine wsNumber = int(firstLine.split()[0]) + 1 # print "Number is {0}".format(wsNumber) wsDirName = getWorkSpaceDirName( dirName, wsNumber ) if( os.path.exists( wsDirName ) ) : print "Workspace directory <{0}> already exists".format(wsDirName) raise OSError( "Workspace <{0}> already exists".format(wsDirName) ) # Try to copy the default workspace into the new directory with the name found above try: shutil.copytree( templateWorkspaceDirName, wsDirName ) # Directories are the same except shutil.Error as e: print('Directory not copied. Error: %s' % e) # Any error saying that the directory doesn't exist except OSError as e: print('Directory not copied. Error: %s' % e) # Close the number with the lst workspace number and then reopen it to save the current number numberFile.close() numberFile = open(numberFileName, "w") numberFile.write( str(wsNumber) ) numberFile.write( "\n" ) numberFile.close() except IOError as err: print "Could not open file <{0}>".format(numberFileName) raise err return wsDirName if __name__ == '__main__': workspaceToUse = None existingWorkspace = None homeDir = os.environ['HOME'] # Define the command line parser and the potential options parser = optparse.OptionParser(usage = "usage: %prog [options] ") parser.add_option( "-n", "--new", action="store_true", dest="create_new", metavar="NEW_WS", default=True, help="Create new workspace" ) parser.add_option( "-f", "--find", action="store_false", dest="create_new", metavar="NEW_WS", default=True, help="Try to find unused workspace or create new workspace" ) parser.add_option( "-d", "--dir", action="store", dest="dir", type="string", metavar="WS_DIR", default=homeDir+"/CSS-Workspaces-AUTO", help="Directory where automatic worspaces are located" ) parser.add_option( "-e", "--exe", action="store", dest="css_exe", type="string", metavar="CSS_EXEC", default="css", help="CSS executable" ) parser.add_option( "-o", "--opt", action="store", dest="css_opt", type="string", metavar="CSS_OPT", default="-data", help="CSS options" ) # Parse rgumants (opts, args) = parser.parse_args( sys.argv[1:] ) cssExecutable = opts.css_exe cssOptKey = opts.css_opt worskpaceLocation = opts.dir # Try to see if there are unlock workspaces in the directory if ( not opts.create_new ): existingWorkspace = tryExistingWorkspaces(worskpaceLocation) # print "Result is " , existingWorkspace # If no unlocked workspace found create a new workspace if(existingWorkspace == None): newWorkSpace = createWorkSpace(worskpaceLocation) if(newWorkSpace != None): workspaceToUse = newWorkSpace else : workspaceToUse = None else : workspaceToUse = existingWorkspace print "Will use " , workspaceToUse fakeCommand = ["ls" , "-l", workspaceToUse] # subprocess.call( fakeCommand ) if workspaceToUse != None: cssCommand = [cssExecutable, cssOptKey, workspaceToUse] # print "Will call {0}".format( cssCommand ) subprocess.call( cssCommand ) else : print "Could not determine what workspace to use in {0}".format(worskpaceLocation)