[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