Commit d11396b4 authored by Christopher Gearhart's avatar Christopher Gearhart

Squashed some bugs and improved error handling for reading Remote Servers file

parent a6b230dd
......@@ -99,6 +99,7 @@ def register():
description="Choose which hosts to use for render processes",
items=[("All Servers", "All Servers", "Render on all servers")],
default="All Servers")
bpy.props.lastServerGroup = "All Servers"
bpy.props.serverPrefs = {"servers":None, "login":None, "path":None, "hostConnection":None}
bpy.types.Scene.availableServers = IntProperty(name="Available Servers", default=0)
bpy.types.Scene.offlineServers = IntProperty(name="Offline Servers", default=0)
......
......@@ -87,7 +87,8 @@ class refreshNumAvailableServers(Operator):
# start initial process
self.state = 1 # initializes state for modal
if bpy.props.needsUpdating:
if bpy.props.needsUpdating or bpy.props.lastServerGroup != scn.serverGroups:
bpy.props.lastServerGroup = scn.serverGroups
updateStatus = updateServerPrefs()
if not updateStatus["valid"]:
self.report({"ERROR"}, updateStatus["errorMessage"])
......@@ -233,7 +234,7 @@ class sendFrame(Operator):
# average the rendered frames if there are new frames to average
elif self.state[i] == 4:
# only average if there are new frames to average
numRenderedFiles = getNumRenderedFiles("image", list(bpy.props.imFrame), None)
numRenderedFiles = getNumRenderedFiles("image", [bpy.props.imFrame], None)
if numRenderedFiles > 0:
averaged = True
averageFrames(self, bpy.props.nameImOutputFiles)
......@@ -327,7 +328,8 @@ class sendFrame(Operator):
bpy.props.nameImOutputFiles = getNameOutputFiles()
bpy.props.imFrame = scn.frame_current
self.state = [1, 0] # initializes state for modal
if bpy.props.needsUpdating:
if bpy.props.needsUpdating or bpy.props.lastServerGroup != scn.serverGroups:
bpy.props.lastServerGroup = scn.serverGroups
updateStatus = updateServerPrefs()
if not updateStatus["valid"]:
self.report({"ERROR"}, updateStatus["errorMessage"])
......@@ -534,7 +536,8 @@ class sendAnimation(Operator):
self.statusChecked = False
self.expandedFrameRange = []
self.state = [1, 0] # initializes state for modal
if bpy.props.needsUpdating:
if bpy.props.needsUpdating or bpy.props.lastServerGroup != scn.serverGroups:
bpy.props.lastServerGroup = scn.serverGroups
updateStatus = updateServerPrefs()
if not updateStatus["valid"]:
self.report({"ERROR"}, updateStatus["errorMessage"])
......
......@@ -25,6 +25,8 @@ def getFrames(projectName, archiveFiles=False, frameRange=False):
f.write(fileStrings)
includeDict = "--include-from='{outFilePath}'".format(outFilePath=outFilePath)
f.close()
else:
includeDict = ""
archiveRsyncCommand = "rsync -qx --rsync-path='mkdir -p {dumpLocation}/backups/ && rsync' --remove-source-files {includeDict} --exclude='{nameOutputFiles}_????.???' --exclude='*_average.???' {dumpLocation}/* {dumpLocation}/backups/;".format(includeDict=includeDict, dumpLocation=dumpLocation, nameOutputFiles=getNameOutputFiles(), imExtension=bpy.props.imExtension)
else:
archiveRsyncCommand = "mkdir -p {dumpLocation};".format(dumpLocation=dumpLocation)
......@@ -232,7 +234,7 @@ def getRenderDumpFolder():
# check to make sure dumpLoc exists on local machine
if not os.path.exists(dumpLoc):
os.path.mkdir(dumpLoc)
os.mkdir(dumpLoc)
return dumpLoc
......@@ -291,15 +293,20 @@ def updateServerPrefs():
if localVerify > 0:
return {"valid":False, "errorMessage":"rsync not installed on local machine."}
# run setupServerPrefs() and store last results to oldServerPrefs
oldServerPrefs = bpy.props.serverPrefs
bpy.props.serverPrefs = setupServerPrefs()
newServerPrefs = setupServerPrefs()
if newServerPrefs["valid"]:
bpy.props.serverPrefs = newServerPrefs
else:
return newServerPrefs
if bpy.props.serverPrefs != oldServerPrefs:
# verify user entries correspond to responsive servers
# try:
# subprocess.call("ssh -oStrictHostKeyChecking=no {login} 'echo hi'".format(login=bpy.props.serverPrefs["login"]), shell=True)
# except:
# return {"valid":False, "errorMessage":"ssh to '{login}' failed. Check your settings and ensure ssh keys are setup".format(login=bpy.props.serverPrefs["login"])}
# verify host server login, built from user entries, correspond to a responsive server
try:
subprocess.call("ssh -T -oStrictHostKeyChecking=no -x {login} 'echo hi'".format(login=bpy.props.serverPrefs["login"]), shell=True)
except:
return {"valid":False, "errorMessage":"ssh to '{login}' failed. Check your settings and ensure ssh keys are setup".format(login=bpy.props.serverPrefs["login"])}
# initialize server groups enum property
groupNames = [("All Servers", "All Servers", "Render on all servers")]
......
......@@ -23,8 +23,7 @@ def readFileFor(f, flagName):
nextLine = f.readline()
numIters += 1
if numIters >= 300:
print("Unable to read with over 300 preceeding lines.")
break
raise ValueError("Unable to find '### BEGIN {flagName} ###' in the first 300 lines of Remote Servers file".format(flagName=flagName))
# read the following lines leading up to '### END flagName ###'
nextLine = f.readline()
......@@ -35,31 +34,60 @@ def readFileFor(f, flagName):
numIters += 1
if numIters >= 250:
print("Unable to read over 250 lines.")
break
raise ValueError("'### END {flagName} ###' not found within 250 lines of '### BEGIN {flagName} ###' in the Remote Servers file".format(flagName=flagName))
return readLines
def invalidEntry(field):
return "Could not load '{field}'. Please read the instructions carefully to make sure you've set up your file correctly".format(field=field)
def setupServerPrefs():
# Variable definitions
# variable definitions
libraryServersPath = os.path.join(getLibraryPath(), "servers")
serverFile = open(os.path.join(libraryServersPath, "remoteServers.txt"),"r")
# Set SSH login information for host server
username = readFileFor(serverFile, "SSH USERNAME").replace("\"", "")
hostServer = readFileFor(serverFile, "HOST SERVER").replace("\"", "")
extension = readFileFor(serverFile, "EXTENSION").replace("\"", "")
path = readFileFor(serverFile, "HOST SERVER PATH").replace("\"", "")
# set SSH login information for host server
try:
username = readFileFor(serverFile, "SSH USERNAME").replace("\"", "")
except:
return {"valid":False, "errorMessage":invalidEntry("SSH USERNAME")}
try:
hostServer = readFileFor(serverFile, "HOST SERVER").replace("\"", "")
except:
return {"valid":False, "errorMessage":invalidEntry("HOST SERVER")}
try:
extension = readFileFor(serverFile, "EXTENSION").replace("\"", "")
except:
return {"valid":False, "errorMessage":invalidEntry("EXTENSION")}
# build SSH login information
login = "{username}@{hostServer}{extension}".format(username=username, hostServer=hostServer, extension=extension)
hostConnection = "{hostServer}{extension}".format(hostServer=hostServer, extension=extension)
# Format host server path
# set base path for host server
try:
path = readFileFor(serverFile, "HOST SERVER PATH").replace("\"", "")
except:
return {"valid":False, "errorMessage":invalidEntry("HOST SERVER PATH")}
# format host server path
path = path.replace(" ", "_")
if not path.endswith("/"):
if not path.endswith("/") and path != "":
path += "/"
# Set server dictionary
servers = json.loads(readFileFor(serverFile, "REMOTE SERVERS DICTIONARY"))
return {"servers":servers, "login":login, "path":path, "hostConnection":hostConnection}
# read file for servers dictionary
try:
tmpServers = readFileFor(serverFile, "REMOTE SERVERS DICTIONARY")
except:
return {"valid":False, "errorMessage":"Could not load 'REMOTE SERVERS DICTIONARY'. Please read the instructions carefully to make sure you've set up your file correctly"}
# convert servers dictionary string to object
try:
servers = json.loads(tmpServers)
except:
return {"valid":False, "errorMessage":"Could not load dictionary. Please make sure you've entered a valid dictionary and check for syntax errors"}
return {"valid":True, "servers":servers, "login":login, "path":path, "hostConnection":hostConnection}
def writeServersFile(serverDict, serverGroups):
f = open(os.path.join(getLibraryPath(), "to_host_server", "servers.txt"), "w")
......
......@@ -49,6 +49,8 @@ the author, Chris Gearhart, at chris@bblanimation.com.
changes to this file (Text > Save), and switch back to the 3D viewport. Now
you're ready to render on your remote servers!
***DO NOT MODIFY LINES CONTAINING "###"***
### BEGIN SSH USERNAME ###
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment