[Durian-svn] [2710] Integration of UI into renderfarm, no existing files changed, instead
brecht
institute at blender.org
Fri Apr 30 15:58:51 CEST 2010
Revision: 2710
https://blenderinstitute.dyndns.org/durian-svn/?do=log&project=durian&path=/&rev=2710
Author: brecht
Date: 2010-04-30 15:58:51 +0200 (Fri, 30 Apr 2010)
Log Message:
-----------
Integration of UI into renderfarm, no existing files changed, instead
there are files with the new_ prefix, this allows to test the new code
while the old one keeps running, as long as different files and nodes
are used.
Modified Paths:
--------------
frm/master_ui.py
Added Paths:
-----------
frm/new_blend_2_frames.py
frm/new_blender_setup.py
frm/new_master.py
frm/new_node_update_frames.sh
Modified: frm/master_ui.py
===================================================================
--- frm/master_ui.py 2010-04-30 13:50:49 UTC (rev 2709)
+++ frm/master_ui.py 2010-04-30 13:58:51 UTC (rev 2710)
@@ -81,11 +81,11 @@
JOBS = []
def sortkey(self):
- if job.priority == 'Critical':
+ if self.priority == 'Critical':
return 0
- elif job.priority == 'High':
+ elif self.priority == 'High':
return 1
- elif job.priority == 'Medium':
+ elif self.priority == 'Medium':
return 2
else:
return 3
@@ -95,8 +95,6 @@
# master loop and stop rendering that job
job = Job.find(id)
job.enabled = enabled
- if job.enabled: job.status = 'Waiting'
- else: job.status = 'Disabled'
Job.dump()
def job_set_priority(id, priority):
@@ -166,8 +164,6 @@
# master loop will detect slave.enabled and start/stop jobs
slave = Slave.find(id)
slave.enabled = enabled
- if slave.enabled: slave.status = 'Waiting'
- else: slave.status = 'Disabled'
Slave.dump()
def slave_add(id, ip):
@@ -198,6 +194,9 @@
######################### Server ###########################
class HHandler(http.server.BaseHTTPRequestHandler):
+ def log_message(self, format, *args):
+ pass
+
def do_POST(self):
# get arguments
length = int(self.headers['content-length'])
@@ -338,7 +337,7 @@
logs, revision = latest_svn_info()
output("<form method='post' action='/job_add'>\n")
- output("<input name='id' value='/d/pro/scenes/05.8_ambushfight/05.8a_comp.blend' size='50'/>\n")
+ output("<input name='id' value='/d/pro/props/peach.blend' size='50'/>\n")
output("<input name='revision' value='%s' size='10'/>\n" % (revision,))
output("<select name='quality'>\n")
for option in Job.quality_types:
@@ -360,7 +359,7 @@
output("<br/>\n")
# progress
- section("Progress")
+ section("Overall Progress")
output(TOTAL_PROGRESS)
output("<br/>\n")
Copied: frm/new_blend_2_frames.py (from rev 2699, frm/blend_2_frames.py)
===================================================================
--- frm/new_blend_2_frames.py (rev 0)
+++ frm/new_blend_2_frames.py 2010-04-30 13:58:51 UTC (rev 2710)
@@ -0,0 +1,35 @@
+import blend_render_info
+import os
+
+from render_dirs import FARM_DIR
+
+#frames/%s/%s_######" % (fname, fname)
+
+def blend_2_frames(path):
+ values = blend_render_info.read_blend_rend_chunk(path)
+
+ images = []
+ fname = os.path.splitext(os.path.basename(path))[0]
+
+ for start, end, scene in values:
+ format_string = os.path.join(FARM_DIR, "frames", fname, fname + "_%.6d.exr")
+ frame = start
+ while frame <= end:
+ images.append((frame, format_string % frame))
+ frame += 1
+
+ return images
+
+def main():
+ import sys
+ for arg in sys.argv[1:]:
+ if arg.lower().endswith('.blend'):
+ for path in blend_2_frames(arg):
+ print(path)
+
+
+if __name__ == '__main__':
+ main()
+
+#for frame, path in blend_2_frames(os.path.join(FARM_DIR, "/pro/comps/03.1_alley/03.1b.blend")):
+# print path
Property changes on: frm/new_blend_2_frames.py
___________________________________________________________________
Added: svn:executable
+ *
Added: svn:mergeinfo
+
Copied: frm/new_blender_setup.py (from rev 2699, frm/blender_setup.py)
===================================================================
--- frm/new_blender_setup.py (rev 0)
+++ frm/new_blender_setup.py 2010-04-30 13:58:51 UTC (rev 2710)
@@ -0,0 +1,108 @@
+# runs on the nodes inside blender
+
+import bpy
+import os
+import sys
+
+def get_ip():
+
+ import socket
+ import fcntl
+ import struct
+
+ def get_ip_address(ifname):
+ s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
+ return socket.inet_ntoa(fcntl.ioctl(
+ s.fileno(),
+ 0x8915, # SIOCGIFADDR
+ struct.pack('256s', ifname[:15])
+ )[20:24])
+
+ for iface in "eth0", "eth1", "eth2", "eth3":
+ try:
+ ip = get_ip_address(iface)
+ break
+ except:
+ ip = None
+
+ return ip
+
+ip = get_ip()
+fpath = bpy.data.filename
+fname = os.path.splitext(os.path.basename(fpath))[0]
+scene_current = bpy.context.scene
+
+print("loaded:", fpath, scene_current)
+
+# not working
+bpy.context.user_preferences.filepaths.temporary_directory = "/tmp/durian_farm"
+os.system("rm -rf /tmp/durian_farm")
+os.system("mkdir /tmp/durian_farm")
+
+for scene in bpy.data.scenes:
+ rd = scene.render
+
+ # file stuff...
+ override = False # (rd.file_format != 'PNG')
+
+ rd.file_format = 'OPEN_EXR'
+ rd.exr_half = True
+ rd.output_path = "/shared/software/durian_farm/frames/%s/%s_######" % (fname, fname)
+ rd.use_file_extension = True
+
+ rd.use_placeholder = False
+ rd.use_overwrite = False
+
+
+ rd.render_stamp = False
+ rd.stamp_note = True
+ rd.stamp_render_time = True
+ rd.stamp_note_text = "rev:%s, %s" % (bpy.app.build_revision, ip)
+ rd.stamp_font_size = 18
+ rd.stamp_foreground = 1.0, 1.0, 1.0, 1.0
+ rd.stamp_background = 0.0, 0.0, 0.0, 0.75
+
+ if override:
+ continue
+
+ # render settings...
+ rd.resolution_percentage = 100
+ rd.resolution_x = 2048
+ rd.resolution_y = 872
+
+ rd.use_border = False
+# rd.color_management = False
+# rd.alpha_mode = 'SKY'
+ rd.color_mode = 'RGB'
+
+
+ if bpy.app.debug:
+ rd.resolution_percentage = 50
+ # rd.simplify_child_particles = 0.0
+ #rd.simplify_shadow_samples = 0
+ #rd.simplify_subdivision = 0
+ rd.simplify_triangulate = True
+ rd.use_simplify = True
+
+ #rd.use_textures = False
+ #rd.use_raytracing = False
+ #rd.use_sss = False
+ #rd.use_shadows = False
+
+ # rd.file_format = 'PNG'
+
+ # special ben check
+ '''
+ if ip.endswith(".12"):
+ if "nautilus" in os.popen("ps -A").read():
+ rd.threads_mode = 'FIXED'
+ rd.threads = 12
+ '''
+
+render_frame = sys.argv[-1]
+scene.current_frame_start = render_frame
+scene.current_frame_end = render_frame
+
+print("rendering frame %d" % (render_frame))
+bpy.ops.render.render(animation=True)
+
Property changes on: frm/new_blender_setup.py
___________________________________________________________________
Added: svn:executable
+ *
Added: svn:mergeinfo
+
Copied: frm/new_master.py (from rev 2699, frm/master.py)
===================================================================
--- frm/new_master.py (rev 0)
+++ frm/new_master.py 2010-04-30 13:58:51 UTC (rev 2710)
@@ -0,0 +1,302 @@
+#!/shared/software/python/bin/python3.1
+
+# TODO
+# * auto-generate avis after job is done, non-blocking
+# * detect crashes so it does not get stuck on these frames
+# * do svn updates on the slave instead of rsync with master
+# * re-enable svn update
+# * backup old frames before starting a new job
+# * remove .exrs to restart job
+# * find out why address already in use error happens
+# * fix multiple nodes updating movie files
+# * rsync is not killed currently
+
+import os
+import time
+import master_ui
+import new_blend_2_frames
+from render_dirs import FARM_DIR
+
+os.umask(777)
+
+# cat /shared/software/durian_farm/id_dsa.pub > /home/guest/.ssh/authorized_keys
+
+jobs = []
+
+def log_file(ip, ext="log"):
+ return "%s/logs/%s.%s" % (FARM_DIR, ip, ext)
+
+def remote_command(ip, cmd, user="guest", passwd="guest", log=True):
+ logpath = log_file(ip)
+
+ # node exception
+ if int(ip.split(".")[-1]) >= 200:
+ user = "root"
+
+ # add redirection
+ if log:
+ cmd += " >> %s 2>&1" % logpath
+
+ # set the umask so files & dirs we create can be moved about
+ cmd_final = "ssh -n -f -p 22 %s@%s 'umask 002 ; FARM_DIR=\"%s\" %s'" % (user, ip, FARM_DIR, cmd)
+
+
+ if log:
+ file = open(logpath, 'a+')
+ fw = file.write
+ fw(("\n\n" + "=" * len(cmd_final)) + "\n")
+ fw(" %s\n" % time.asctime())
+ fw(cmd_final + "\n")
+ file.close()
+ os.system("chmod 777 " + logpath)
+
+ print("running:", cmd_final)
+
+ os.system(cmd_final)
+
+ print("done")
+
+def slaves_status_update():
+ # set status for all slaves
+ for slave in master_ui.SLAVES:
+ if slave.enabled:
+ slave.status = "Waiting"
+ else:
+ slave.status = "Disabled"
+
+ # set slaves status based on log files
+ logs = os.path.join(FARM_DIR, "logs")
+
+ for f in sorted(os.listdir(logs)):
+ if f.endswith(".busy"):
+ busy_path = os.path.join(logs, f)
+ ip = f.replace(".busy", "")
+
+ for slave in master_ui.SLAVES:
+ if slave.ip == ip:
+ slave.status = open(busy_path, "r").read().strip()
+
+def jobs_status_update():
+ total_done = 0
+ total_tot = 0
+
+ kill_non_critical = False
+
+ # update job status based on existence of exr's
+ for job in master_ui.JOBS:
+ # list images for this job
+ blendfile_abs = os.path.join(FARM_DIR, job.id)
+
+ if os.path.exists(blendfile_abs):
+ images = new_blend_2_frames.blend_2_frames(blendfile_abs)
+ else:
+ images = []
+
+ # see how many of these images are done
+ image_done = 0
+ image_tot = len(images)
+
+ for frame, path in images:
+ if os.path.exists(path):
+ image_done += 1
+
+ total_done += image_done
+ total_tot += image_tot
+
+ # if we have unfinished critical jobs, we kill non-critical ones
+ if job.priority == "Critical":
+ if image_done != len(images):
+ kill_non_critical = True
+
+ # update status
+ if image_done == len(images):
+ job.status = "Done"
+ elif not job.enabled:
+ job.status = "Disabled"
+ else:
+ job.status = "In Progress"
+
+ # update progress
+ if image_tot == 0: percentage = 0.0
+ else: percentage = float(image_done)/float(image_tot)
+ job.progress = "%.2f%% (%d/%d)" % (100*percentage, image_done, image_tot)
+
+ # update total progress
@@ Diff output truncated at 10240 characters. @@
More information about the Durian-svn
mailing list