[PATCH] virt: Encode a webm video from vm screenshots

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



When we are debugging issues (notably during unattended
installs), having to look individual screenshots is less
than optimal. So introduce in virt tests the ability to
get a webm file that can be played quite nicely and out
of the box in recent versions of firefox and chromium.

In order to do that, move to a sequential screenshot
naming policy for each vm, and encode videos at vm
postprocessing stage.

In order to use that feature, the host needs to have a
ffmpeg build sufficiently recent that can encode webm
files. The infrastructure will do the best possible to
find it out on your path.

Feature successfuly tested under Fedora 16.

Signed-off-by: Lucas Meneghel Rodrigues <lmr@xxxxxxxxxx>
---
 client/tests/kvm/base.cfg.sample |    6 ++++
 client/virt/virt_env_process.py  |   54 +++++++++++++++++++++++++++++++++----
 2 files changed, 54 insertions(+), 6 deletions(-)

diff --git a/client/tests/kvm/base.cfg.sample b/client/tests/kvm/base.cfg.sample
index 6b3f9fd..7827cc8 100644
--- a/client/tests/kvm/base.cfg.sample
+++ b/client/tests/kvm/base.cfg.sample
@@ -86,6 +86,12 @@ screendump_quality = 30
 screendump_temp_dir = /dev/shm
 screendump_verbose = no
 
+# Encode video from vm screenshots (requires ffmpeg build that can encode webm)
+encode_video_files = no
+encode_video_framerate = 1
+keep_video_files = no
+keep_video_files_on_error = yes
+
 # Default remote shell port (SSH under linux)
 shell_port = 22
 
diff --git a/client/virt/virt_env_process.py b/client/virt/virt_env_process.py
index e5316d2..d5225a4 100644
--- a/client/virt/virt_env_process.py
+++ b/client/virt/virt_env_process.py
@@ -16,6 +16,16 @@ _screendump_thread = None
 _screendump_thread_termination_event = None
 
 
+def ffmpeg_path():
+    try:
+        return virt_utils.find_command("ffmpeg")
+    except ValueError:
+        return None
+
+
+_ffmpeg = ffmpeg_path()
+
+
 def preprocess_image(test, params):
     """
     Preprocess a single QEMU image according to the instructions in params.
@@ -156,6 +166,28 @@ def postprocess_vm(test, params, env, name):
     except kvm_monitor.MonitorError, e:
         logging.warn(e)
 
+    # Encode a webm video from the screenshots produced?
+    if params.get("encode_video_files", "yes") == "yes":
+        video_framerate = int(params.get("encode_video_framerate", 1))
+        if _ffmpeg is not None:
+            logging.debug("Param 'encode_video_files' specified, trying to "
+                          "encode a video from the screenshots produced by "
+                          "vm %s", vm.name)
+            try:
+                os.chdir(test.debugdir)
+                try:
+                    utils.run("%s -r %d -b 1800 -i screendumps_%s/%s %s.webm" %
+                              (_ffmpeg, video_framerate, vm.name, "%04d.jpg",
+                               vm.name))
+                except error.CmdError, e:
+                    logging.error("Failed to encode video for vm %s: %s",
+                                  vm.name, e)
+            except:
+                pass
+        else:
+            logging.error("Param 'encode_video' specified, but ffmpeg not "
+                          "present, not encoding video for vm %s", vm.name)
+
     if params.get("kill_vm") == "yes":
         kill_vm_timeout = float(params.get("kill_vm_timeout", 0))
         if kill_vm_timeout:
@@ -364,20 +396,27 @@ def postprocess(test, params, env):
             pass
 
     # Should we keep the PPM files?
-    if params.get("keep_ppm_files") != "yes":
+    if params.get("keep_ppm_files", "no") != "yes":
         logging.debug("Param 'keep_ppm_files' not specified, removing all PPM "
                       "files from debug dir")
         for f in glob.glob(os.path.join(test.debugdir, '*.ppm')):
             os.unlink(f)
 
     # Should we keep the screendump dirs?
-    if params.get("keep_screendumps") != "yes":
+    if params.get("keep_screendumps", "no") != "yes":
         logging.debug("Param 'keep_screendumps' not specified, removing "
                       "screendump dirs")
         for d in glob.glob(os.path.join(test.debugdir, "screendumps_*")):
             if os.path.isdir(d) and not os.path.islink(d):
                 shutil.rmtree(d, ignore_errors=True)
 
+    # Should we keep the video files?
+    if params.get("keep_videos", "no") != "yes":
+        logging.debug("Param 'keep_videos' not specified, removing all webm "
+                      "files from debug dir")
+        for f in glob.glob(os.path.join(test.debugdir, '*.webm')):
+            os.unlink(f)
+
     # Kill all unresponsive VMs
     if params.get("kill_unresponsive_vms") == "yes":
         logging.debug("Param 'kill_unresponsive_vms' specified, killing all "
@@ -453,13 +492,16 @@ def _take_screendumps(test, params, env):
             pass
     temp_filename = os.path.join(temp_dir, "scrdump-%s.ppm" %
                                  virt_utils.generate_random_string(6))
-    delay = float(params.get("screendump_delay", 5))
+    delay = float(params.get("screendump_delay", 1))
     quality = int(params.get("screendump_quality", 30))
 
     cache = {}
+    counter = {}
 
     while True:
         for vm in env.get_all_vms():
+            if vm not in counter.keys():
+                counter[vm] = 0
             if not vm.is_alive():
                 continue
             try:
@@ -482,9 +524,9 @@ def _take_screendumps(test, params, env):
                 os.makedirs(screendump_dir)
             except OSError:
                 pass
-            screendump_filename = os.path.join(screendump_dir,
-                    "%s_%s.jpg" % (vm.name,
-                                   time.strftime("%Y-%m-%d_%H-%M-%S")))
+            counter[vm] += 1
+            screendump_filename = os.path.join(screendump_dir, "%04d.jpg" %
+                                               counter[vm])
             hash = utils.hash_file(temp_filename)
             if hash in cache:
                 try:
-- 
1.7.7

--
To unsubscribe from this list: send the line "unsubscribe kvm" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[Index of Archives]     [KVM ARM]     [KVM ia64]     [KVM ppc]     [Virtualization Tools]     [Spice Development]     [Libvirt]     [Libvirt Users]     [Linux USB Devel]     [Linux Audio Users]     [Yosemite Questions]     [Linux Kernel]     [Linux SCSI]     [XFree86]
  Powered by Linux