From 9f5832a5d3144f56238a6b44167fb0eb03e6b077 Mon Sep 17 00:00:00 2001
From: Calvin Walton <calvin.walton@kepstin.ca>
Date: Wed, 28 Apr 2021 16:11:10 -0400
Subject: [PATCH] Recording: bbb-record --rebuild restarts processing at the
 sanity step

Previously, bbb-record --rebuild was restarting recording processing
from scratch by creating the .../recording/<meeting_id>.done file. This
causes the recording to be reprocessed starting at the archive step.
However, re-running the archive step for an existing meeting is not
really supported! Ever since the segmented recording code was added, it
shouldn't /corrupt/ the recording files, but it's still not good.

And as a side-effect, re-running the archive step will re-create the
.norecord file for meetings without recording marks, meaning that you
cannot use bbb-record --rebuild to force a recording without marks to be
processed.

Switch bbb-record to restart recording processing at the sanity stage to
match the BBB 2.2 behaviour. Rather than have it insert tasks directly
into resque via redis-cli, it goes through a ruby wrapper that performs
input validation and uses the resque apis.
---
 bigbluebutton-config/bin/bbb-record           |  8 +-
 .../core/scripts/rap-enqueue.rb               | 75 +++++++++++++++++++
 2 files changed, 78 insertions(+), 5 deletions(-)
 create mode 100755 record-and-playback/core/scripts/rap-enqueue.rb

diff --git a/bigbluebutton-config/bin/bbb-record b/bigbluebutton-config/bin/bbb-record
index 28c99366ff..00bb36c8d2 100755
--- a/bigbluebutton-config/bin/bbb-record
+++ b/bigbluebutton-config/bin/bbb-record
@@ -79,10 +79,8 @@ mark_for_rebuild() {
      rm -rf /var/bigbluebutton/deleted/$type/$MEETING_ID
   done
 
-  # touch the file so rap-starter starts the process
-  touch $STATUS/recorded/$MEETING_ID.done
-  # In the future it could simply schedule a job on resque
-  # redis-cli rpush resque:queue:rap:sanity "{\"class\":\"BigBlueButton::Resque::SanityWorker\",\"args\":[{\"meeting_id\":\"$MEETING_ID\"}]}"
+  # Restart processing at the 'sanity' step
+  /usr/local/bigbluebutton/core/scripts/rap-enqueue.rb sanity "$MEETING_ID"
 }
 
 mark_for_republish() {
@@ -105,7 +103,7 @@ mark_for_republish() {
       rm -rf /var/bigbluebutton/deleted/$type/$MEETING_ID
 
       # Restart processing at the 'publish' step
-      redis-cli rpush resque:queue:rap:publish "{\"class\":\"BigBlueButton::Resque::PublishWorker\",\"args\":[{\"meeting_id\":\"$MEETING_ID\",\"format_name\":\"$type\"}]}"
+      /usr/local/bigbluebutton/core/scripts/rap-enqueue.rb "publish:$type" "$MEETING_ID"
    done
 }
 
diff --git a/record-and-playback/core/scripts/rap-enqueue.rb b/record-and-playback/core/scripts/rap-enqueue.rb
new file mode 100755
index 0000000000..691f26216a
--- /dev/null
+++ b/record-and-playback/core/scripts/rap-enqueue.rb
@@ -0,0 +1,75 @@
+#!/usr/bin/ruby
+# frozen_string_literal: true
+
+# Copyright © 2021 BigBlueButton Inc. and by respective authors.
+#
+# This file is part of BigBlueButton open source conferencing system.
+#
+# BigBlueButton is free software: you can redistribute it and/or modify it
+# under the terms of the GNU Lesser General Public License as published by the
+# Free Software Foundation, either version 3 of the License, or (at your
+# option) any later version.
+#
+# BigBlueButton is distributed in the hope that it will be useful, but WITHOUT
+# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+# FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public License for more
+# details.
+#
+# You should have received a copy of the GNU Lesser General Public License
+# along with BigBlueButton.  If not, see <http://www.gnu.org/licenses/>.
+
+require_relative '../lib/recordandplayback'
+
+require 'recordandplayback/workers'
+require 'rubygems'
+require 'yaml'
+require 'resque'
+
+def meeting_id_valid?(meeting_id)
+  /\A[0-9a-f]+-[0-9]+\z/.match?(meeting_id)
+end
+
+begin
+  if ARGV.length < 2
+    warn 'Usage: rap-enqueue.rb STEP[:FORMAT] MEETING_ID [MEETING_ID ...]'
+    warn ''
+    warn 'Enqueue a recording task for MEETING_ID, starting at step STEP,'
+    warn 'optionally with processing format FORMAT (required for the process'
+    warn 'and publish steps)'
+    exit 1
+  end
+
+  props = BigBlueButton.read_props
+
+  redis_host = props['redis_workers_host'] || props['redis_host']
+  redis_port = props['redis_workers_port'] || props['redis_port']
+  Resque.redis = "#{redis_host}:#{redis_port}"
+
+  common_opts = {
+    'single_step': false
+  }
+
+  step = ARGV.shift
+  step_name, step_format = step.split(':')
+  common_opts['format_name'] = step_format unless step_format.nil?
+
+  klass = \
+    begin
+      Object.const_get("BigBlueButton::Resque::#{step_name.capitalize}Worker")
+    rescue NameError
+      warn "Worker for step name #{step_name} was not found."
+      exit 1
+    end
+
+  ARGV.each do |meeting_id|
+    unless meeting_id_valid?(meeting_id)
+      warn "Meeting ID #{meeting_id} is not correctly formatted"
+      next
+    end
+
+    opts = common_opts.merge('meeting_id': meeting_id)
+
+    warn "Enqueing #{step_name} worker with #{opts.inspect}"
+    ::Resque.enqueue(klass, opts)
+  end
+end
-- 
GitLab