Skip to content

Commit f485fcc

Browse files
authored
Merge branch 'master' into list_of_tags
2 parents 1ebf251 + 9ebda3f commit f485fcc

14 files changed

+104
-66
lines changed

.github/workflows/ci.build.prerelease.yml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
env:
2-
RUBY_VERSION: 2.7.x
2+
RUBY_VERSION: 3.3.6
33

44
name: CI Build Pre-Release
55
on:
@@ -12,7 +12,7 @@ jobs:
1212
env:
1313
DOCKER_REPOSITORY: ${{ secrets.DOCKER_REPOSITORY }}
1414
DOCKER_BUILD_ENABLED: ${{ secrets.DOCKER_BUILD_ENABLED }}
15-
runs-on: ubuntu-22.04
15+
runs-on: ubuntu-24.04
1616
steps:
1717
- name: Checkout
1818
if: contains(env.DOCKER_BUILD_ENABLED, 'true')

.github/workflows/ci.build.push.master.yml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
env:
2-
RUBY_VERSION: 2.7.x
2+
RUBY_VERSION: 3.3.6
33

44
name: CI Build Push
55
on:
@@ -15,7 +15,7 @@ jobs:
1515
DOCKER_REPOSITORY: ${{ secrets.DOCKER_REPOSITORY }}
1616
DOCKER_BUILD_ENABLED: ${{ secrets.DOCKER_BUILD_ENABLED }}
1717
DOCKER_BUILD_ALTERNATE_ENABLED: ${{ secrets.DOCKER_BUILD_ALTERNATE_ENABLED }}
18-
runs-on: ubuntu-22.04
18+
runs-on: ubuntu-24.04
1919
steps:
2020
- name: Check preconditions
2121
id: preconditions

.github/workflows/ci.build.push.yml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
env:
2-
RUBY_VERSION: 2.7.x
2+
RUBY_VERSION: 3.3.6
33

44
name: CI Build Push
55
on:
@@ -18,7 +18,7 @@ jobs:
1818
DOCKER_BUILD_ENABLED: ${{ secrets.DOCKER_BUILD_ENABLED }}
1919
DOCKER_BUILD_ALTERNATE_ENABLED: ${{ secrets.DOCKER_BUILD_ALTERNATE_ENABLED }}
2020
DOCKER_BUILD_ON_PUSH_DISABLED: ${{ secrets.DOCKER_BUILD_ON_PUSH_DISABLED }}
21-
runs-on: ubuntu-22.04
21+
runs-on: ubuntu-24.04
2222
steps:
2323
- name: Check preconditions
2424
id: preconditions

.github/workflows/ci.build.release.yml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
env:
2-
RUBY_VERSION: 2.7.x
2+
RUBY_VERSION: 3.3.6
33

44
name: CI Build Release
55
on:
@@ -12,7 +12,7 @@ jobs:
1212
env:
1313
DOCKER_REPOSITORY: ${{ secrets.DOCKER_REPOSITORY }}
1414
DOCKER_BUILD_ENABLED: ${{ secrets.DOCKER_BUILD_ENABLED }}
15-
runs-on: ubuntu-22.04
15+
runs-on: ubuntu-24.04
1616
steps:
1717
- name: Checkout
1818
if: contains(env.DOCKER_BUILD_ENABLED, 'true')

.rubocop.yml

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ AllCops:
1111
- 'vendor/**/*'
1212
- 'vendor/bundle/**/*'
1313
DisabledByDefault: false
14-
TargetRubyVersion: 2.7
14+
TargetRubyVersion: 3.3
1515

1616
NewCops: enable
1717

@@ -236,6 +236,9 @@ Style/OptionalBooleanParameter:
236236
Style/SlicingWithRange:
237237
Enabled: true
238238

239+
Style/HashSyntax:
240+
EnforcedShorthandSyntax: either
241+
239242
RSpec/ContextWording:
240243
Enabled: false
241244

Gemfile

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
source 'https://rubygems.org'
44
git_source(:github) { |repo| "https://github.com/#{repo}.git" }
55

6-
ruby '>= 3.0.0'
6+
ruby '>= 3.3'
77

88
# Bundle edge Rails instead: gem 'rails', github: 'rails/rails'
99
gem 'rails', '~> 7.2'

app/controllers/concerns/cookie_same_site_compat.rb

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -13,14 +13,14 @@ def cookie_same_site_none_incompatible?(useragent)
1313

1414
private
1515

16-
IOS_VERSION_REGEXP = %r{\(iP.+; CPU .*OS (\d+)[_\d]*.*\) AppleWebKit/}.freeze
17-
MACOS_VERSION_REGEXP = %r{\(Macintosh;.*Mac OS X (\d+)_(\d+)[_\d]*.*\) AppleWebKit/}.freeze
18-
SAFARI_REGEXP = %r{Version/.* Safari/}.freeze
19-
CHROMIUM_BASED_REGEXP = /Chrom(?:e|ium)/.freeze
20-
CHROMIUM_VERSION_REGEXP = %r{Chrom[^ /]+/(\d+)[.\d]* }.freeze
21-
MAC_EMBEDDED_REGEXP = %r{^Mozilla/[.\d]+ \(Macintosh;.*Mac OS X [_\d]+\) AppleWebKit/[.\d]+ \(KHTML, like Gecko\)$}.freeze
22-
UC_BROWSER_REGEXP = %r{UCBrowser/}.freeze
23-
UC_BROWSER_VERSION_REGEXP = %r{UCBrowser/(\d+)\.(\d+)\.(\d+)[.\d]* }.freeze
16+
IOS_VERSION_REGEXP = %r{\(iP.+; CPU .*OS (\d+)[_\d]*.*\) AppleWebKit/}
17+
MACOS_VERSION_REGEXP = %r{\(Macintosh;.*Mac OS X (\d+)_(\d+)[_\d]*.*\) AppleWebKit/}
18+
SAFARI_REGEXP = %r{Version/.* Safari/}
19+
CHROMIUM_BASED_REGEXP = /Chrom(?:e|ium)/
20+
CHROMIUM_VERSION_REGEXP = %r{Chrom[^ /]+/(\d+)[.\d]* }
21+
MAC_EMBEDDED_REGEXP = %r{^Mozilla/[.\d]+ \(Macintosh;.*Mac OS X [_\d]+\) AppleWebKit/[.\d]+ \(KHTML, like Gecko\)$}
22+
UC_BROWSER_REGEXP = %r{UCBrowser/}
23+
UC_BROWSER_VERSION_REGEXP = %r{UCBrowser/(\d+)\.(\d+)\.(\d+)[.\d]* }
2424

2525
def webkit_same_site_bug?(useragent)
2626
return true if ios_version?(12, useragent)

app/models/application_redis_record.rb

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -146,8 +146,8 @@ def self.connection_pool
146146
end
147147
delegate :connection_pool, to: 'self.class'
148148

149-
def self.with_connection(&block)
150-
RedisStore.with_connection(&block)
149+
def self.with_connection(&)
150+
RedisStore.with_connection(&)
151151
end
152152
delegate :with_connection, to: 'self.class'
153153

app/models/meeting.rb

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -203,6 +203,7 @@ def self.find_or_create_with_server!(id, server, moderator_pw, voice_bridge = ni
203203
def self.allocate_voice_bridge(meeting_id, voice_bridge = nil)
204204
voice_bridge_len = Rails.configuration.x.voice_bridge_len
205205
use_external_voice_bridge = Rails.configuration.x.use_external_voice_bridge
206+
test_voice_bridge = "99999" # default value in BBB, must be avoided
206207

207208
# In order to make consistent random pin numbers, use the provided meeting as the seed. Ruby's 'Random' PRNG takes a 128bit
208209
# integer as seed. Create one from a truncated hash of the meeting id.
@@ -225,6 +226,7 @@ def self.allocate_voice_bridge(meeting_id, voice_bridge = nil)
225226
end
226227
tries += 1
227228
logger.debug { "Trying to allocate voice bridge number #{voice_bridge}, try #{tries}" }
229+
next if voice_bridge == test_voice_bridge # avoid special voice bridge number
228230

229231
_created, allocated_meeting_id = redis.multi do |transaction|
230232
transaction.hsetnx('voice_bridges', voice_bridge, meeting_id)

app/services/recording_ready_notifier_service.rb

Lines changed: 30 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -21,8 +21,7 @@ def execute(recording_id)
2121
notify(callback_url, meeting_id, recording.record_id, tenant_name) if callback_url
2222
end
2323

24-
def encoded_payload(meeting_id, record_id, tenant_name)
25-
secret = fetch_secrets(tenant_name: tenant_name)[0]
24+
def encoded_payload(meeting_id, record_id, secret)
2625
payload = { meeting_id: meeting_id, record_id: record_id }
2726
JWT.encode(payload, secret)
2827
end
@@ -31,27 +30,38 @@ def notify(callback_url, meeting_id, record_id, tenant_name)
3130
logger.info("Recording Ready Notify for [#{meeting_id}] starts")
3231
logger.info('Making callback for recording ready notification')
3332

34-
payload = encoded_payload(meeting_id, record_id, tenant_name)
35-
uri = URI.parse(callback_url)
36-
http = Net::HTTP.new(uri.host, uri.port)
37-
http.use_ssl = (uri.scheme == 'https')
38-
logger.info("Sending request to #{uri.scheme}://#{uri.host}#{uri.request_uri}")
39-
request = Net::HTTP::Post.new(uri.request_uri)
40-
request.set_form_data(signed_parameters: payload)
33+
secrets = fetch_secrets(tenant_name: tenant_name)
34+
success = false
4135

42-
response = http.request(request)
43-
code = response.code.to_i
36+
secrets.each do |secret|
37+
payload = encoded_payload(meeting_id, record_id, secret)
4438

45-
if code == 410
46-
logger.info("Notified for deleted meeting: #{meeting_id}")
47-
elsif code == 404
48-
logger.info("404 error when notifying for recording: #{meeting_id}, ignoring")
49-
elsif code < 200 || code >= 300
50-
logger.info("Callback HTTP request failed: #{response.code} #{response.message} (code #{code})")
51-
else
52-
logger.info("Recording notifier successful: #{meeting_id} (code #{code})")
39+
uri = URI.parse(callback_url)
40+
http = Net::HTTP.new(uri.host, uri.port)
41+
http.use_ssl = (uri.scheme == 'https')
42+
logger.info("Sending request to #{uri.scheme}://#{uri.host}#{uri.request_uri}")
43+
request = Net::HTTP::Post.new(uri.request_uri)
44+
request.set_form_data(signed_parameters: payload)
45+
46+
response = http.request(request)
47+
code = response.code.to_i
48+
49+
if code == 410
50+
logger.info("Notified for deleted meeting: #{meeting_id}")
51+
break
52+
elsif code == 404
53+
logger.info("404 error when notifying for recording: #{meeting_id}, ignoring")
54+
break
55+
elsif code < 200 || code >= 300
56+
logger.info("Callback HTTP request failed: #{response.code} #{response.message} (code #{code})")
57+
else
58+
logger.info("Recording notifier successful: #{meeting_id} (code #{code})")
59+
success = true
60+
break
61+
end
5362
end
54-
true
63+
64+
success
5565
rescue StandardError => e
5666
logger.info('Rescued')
5767
logger.info(e.to_s)

config/puma.rb

Lines changed: 0 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -46,14 +46,6 @@
4646
#
4747
workers ENV.fetch("WEB_CONCURRENCY", 0)
4848

49-
# Specifies the number of `workers` to boot in clustered mode.
50-
# Workers are forked web server processes. If using threads and workers together
51-
# the concurrency of the application would be max `threads` * `workers`.
52-
# Workers do not work on JRuby or Windows (both of which do not support
53-
# processes).
54-
#
55-
workers ENV.fetch("WEB_CONCURRENCY", 0)
56-
5749
# Use the `preload_app!` method when specifying a `workers` number.
5850
# This directive tells Puma to first boot the application and load code
5951
# before forking the application. This takes advantage of Copy On Write

dockerfiles/v1/focal260-amazonlinux

Lines changed: 25 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
FROM amazonlinux:2.0.20240620.0 AS amazonlinux
2+
SHELL ["/bin/bash", "-c"]
23

34
FROM ubuntu:20.04 AS bbb-playback
45
ENV DEBIAN_FRONTEND=noninteractive
@@ -47,37 +48,45 @@ ENV NGINX_HOSTNAME=localhost
4748
CMD [ "/etc/nginx/start", "-g", "daemon off;" ]
4849

4950
FROM amazonlinux-base AS base
51+
# Install basic packages
52+
RUN yum -y install git gcc-c++ make libyaml-devel libffi-devel glibc-devel readline-devel openssl-devel
5053
# Install Node.js (needed for yarn)
51-
RUN yum -y install gcc-c++ make
5254
RUN curl -sL https://rpm.nodesource.com/setup_16.x | bash -
5355
RUN yum -y install nodejs
54-
# Install Ruby & Rails
56+
# Install other packages
5557
RUN curl -sL -o /etc/yum.repos.d/yarn.repo https://dl.yarnpkg.com/rpm/yarn.repo
56-
RUN amazon-linux-extras enable ruby3.0 postgresql14 \
57-
&& yum -y install git tar gzip yarn shared-mime-info libxslt zlib-devel sqlite-devel mariadb-devel libpq-devel ruby-devel rubygems-devel rubygem-bundler rubygem-io-console rubygem-irb rubygem-json rubygem-minitest rubygem-power_assert rubygem-rake rubygem-test-unit rubygem-bigdecimal
58-
RUN yum -y install python3 python3-pip shadow-utils
59-
RUN gem install bundler -v '2.1.4'
58+
RUN amazon-linux-extras enable postgresql14 \
59+
&& yum -y install tar gzip yarn shared-mime-info libxslt zlib-devel sqlite-devel mariadb-devel libpq-devel python3 python3-pip shadow-utils
60+
# Setup user scalelite
6061
RUN groupadd scalelite --gid 1000 && \
6162
useradd -u 1000 -d /srv/scalelite -g scalelite scalelite
6263
RUN groupadd scalelite-spool --gid 2000 && \
6364
usermod -a -G scalelite-spool scalelite
65+
USER scalelite:scalelite
66+
# Install Ruby
67+
RUN git clone https://github.com/rbenv/rbenv.git ~/.rbenv && \
68+
git clone https://github.com/rbenv/ruby-build.git ~/.rbenv/plugins/ruby-build && \
69+
~/.rbenv/bin/rbenv install 3.3.6 && \
70+
~/.rbenv/bin/rbenv global 3.3.6 && \
71+
~/.rbenv/bin/rbenv rehash
72+
ENV PATH="~/.rbenv/shims:~/.rbenv/bin:$PATH"
73+
RUN echo 'export PATH="~/.rbenv/bin:$PATH"' >> ~/.bashrc && \
74+
echo 'eval "$(rbenv init -)"' >> ~/.bashrc
75+
RUN gem install bundler -v '~> 2.5'
6476
WORKDIR /srv/scalelite
6577

6678
FROM base as builder
67-
RUN rm -rf nginx
68-
USER scalelite:scalelite
6979
COPY --chown=scalelite:scalelite Gemfile* ./
70-
RUN bundle --version
71-
RUN bundle config build.nokogiri --use-system-libraries
72-
RUN bundle config set --local deployment 'true'
73-
RUN bundle config set --local without 'development:test'
74-
RUN bundle install -j4
75-
RUN rm -rf vendor/bundle/ruby/*/cache
76-
RUN find vendor/bundle/ruby/*/gems/ \( -name '*.c' -o -name '*.o' \) -delete
80+
RUN source ~/.bashrc && bundle --version && \
81+
bundle config build.nokogiri --use-system-libraries && \
82+
bundle config set --local deployment 'true' && \
83+
bundle config set --local without 'development:test' && \
84+
bundle install -j4 && \
85+
rm -rf vendor/bundle/ruby/*/cache && \
86+
find vendor/bundle/ruby/*/gems/ \( -name '*.c' -o -name '*.o' \) -delete
7787
COPY --chown=scalelite:scalelite . ./
7888

7989
FROM base AS application
80-
USER scalelite:scalelite
8190
ENV RAILS_ENV=production RAILS_LOG_TO_STDOUT=true
8291
COPY --from=builder --chown=scalelite:scalelite /srv/scalelite ./
8392

lib/redis_store.rb

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,7 @@ def self.before_fork
3434
end
3535
end
3636

37-
def self.with_connection(&block)
38-
connection_pool.with(&block)
37+
def self.with_connection(&)
38+
connection_pool.with(&)
3939
end
4040
end

spec/services/recording_ready_notifier_service_spec.rb

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,28 @@
2626
expect(return_val).to be true
2727
end
2828

29+
it 'retries with different secrets if multiple secrets are set' do
30+
stub_request(:post, url)
31+
.to_return(
32+
{ status: 401, body: '', headers: {} }, # First secret fails
33+
{ status: 401, body: '', headers: {} }, # Second secret fails
34+
{ status: 200, body: '', headers: {} } # Third secret succeeds
35+
)
36+
37+
allow_any_instance_of(ApiHelper).to receive(:fetch_secrets).and_return(%w[secret1 secret2 secret3])
38+
39+
allow(JWT).to receive(:encode).and_return('eyJhbGciOiJIUzI1NiJ9.eyJtZWV0aW5nX2lkIjoibWVldGluZzE5In0')
40+
41+
allow(Rails.logger).to receive(:info).and_call_original # Allow all other logger calls to pass through
42+
43+
expect(Rails.logger).to receive(:info).with("Callback HTTP request failed: 401 (code 401)").twice
44+
expect(Rails.logger).to receive(:info).with("Recording notifier successful: #{recording.meeting_id} (code #{200})").once
45+
46+
return_val = described_class.execute(recording.id)
47+
48+
expect(return_val).to be true
49+
end
50+
2951
it 'returns false if recording ready notification fails' do
3052
stub_request(:post, url).to_timeout
3153

0 commit comments

Comments
 (0)