Skip to content

Commit eba053b

Browse files
committed
Add Redis settings specific to Workhorse
Instead of reusing gitlab_rails['redis_*'] settings for GitLab Workhorse also, allow users to set Redis configuration specifically to Workhorse. However, maintain status quo with defaults and fallbacks so that the change is backward incompatable. Changelog: added Signed-off-by: Balasankar "Balu" C <[email protected]>
1 parent a54ec81 commit eba053b

File tree

4 files changed

+151
-2
lines changed

4 files changed

+151
-2
lines changed

files/gitlab-config-template/gitlab.rb.template

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1128,6 +1128,28 @@ external_url 'GENERATED_EXTERNAL_URL'
11281128
##! Semantic metadata used when registering GitLab Workhorse as a Consul service
11291129
# gitlab_workhorse['consul_service_meta'] = {}
11301130

1131+
##! Redis settings specific for GitLab Workhorse
1132+
##! To be used when Workhorse is supposed to use a different Redis instance than
1133+
##! other components. The settings specified here should match
1134+
##! `gitlab_rails['redis_workhorse_*']` settings, if specified. If not specified,
1135+
##! they are inferred from the below values. `gitlab_rails['redis_workhorse_*']`
1136+
##! settings tell the Rails app which Redis has channels to publish messages to,
1137+
##! and `gitlab_workhorse['redis_*']` tells Workhorse which Redis has channels to
1138+
##! subscribe to. Hence, the requirement of the settings to match.
1139+
# gitlab_workhorse['redis_socket'] = "/var/opt/gitlab/redis/redis.socket"
1140+
# gitlab_workhorse['redis_host'] = "127.0.0.1"
1141+
# gitlab_workhorse['redis_port'] = nil
1142+
# gitlab_workhorse['redis_database'] = nil
1143+
# gitlab_workhorse['redis_username'] = nil
1144+
# gitlab_workhorse['redis_password'] = nil
1145+
# gitlab_workhorse['redis_ssl'] = false
1146+
# gitlab_workhorse['redis_cluster_nodes'] = []
1147+
# gitlab_workhorse['redis_sentinels'] = []
1148+
# gitlab_workhorse['redis_sentinels_password'] = nil
1149+
# gitlab_workhorse['redis_sentinel_master'] = nil
1150+
# gitlab_workhorse['redis_sentinel_master_ip'] = nil
1151+
# gitlab_workhorse['redis_sentinel_master_port'] = nil
1152+
11311153
################################################################################
11321154
## GitLab User Settings
11331155
##! Modify default git user.

files/gitlab-cookbooks/gitlab/attributes/default.rb

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -817,6 +817,20 @@
817817
default['gitlab']['gitlab_workhorse']['consul_service_name'] = 'workhorse'
818818
default['gitlab']['gitlab_workhorse']['consul_service_meta'] = nil
819819

820+
default['gitlab']['gitlab_workhorse']['redis_socket'] = "/var/opt/gitlab/redis/redis.socket"
821+
default['gitlab']['gitlab_workhorse']['redis_host'] = "127.0.0.1"
822+
default['gitlab']['gitlab_workhorse']['redis_port'] = nil
823+
default['gitlab']['gitlab_workhorse']['redis_database'] = nil
824+
default['gitlab']['gitlab_workhorse']['redis_username'] = nil
825+
default['gitlab']['gitlab_workhorse']['redis_password'] = nil
826+
default['gitlab']['gitlab_workhorse']['redis_ssl'] = false
827+
default['gitlab']['gitlab_workhorse']['redis_cluster_nodes'] = []
828+
default['gitlab']['gitlab_workhorse']['redis_sentinels'] = []
829+
default['gitlab']['gitlab_workhorse']['redis_sentinels_password'] = nil
830+
default['gitlab']['gitlab_workhorse']['redis_sentinel_master'] = nil
831+
default['gitlab']['gitlab_workhorse']['redis_sentinel_master_ip'] = nil
832+
default['gitlab']['gitlab_workhorse']['redis_sentinel_master_port'] = nil
833+
820834
####
821835
# mailroom
822836
####

files/gitlab-cookbooks/gitlab/libraries/gitlab_workhorse.rb

Lines changed: 113 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,9 @@
1515
# limitations under the License.
1616
#
1717

18+
require_relative './redis_uri'
19+
require_relative '../../package/libraries/helpers/new_redis_helper'
20+
1821
module GitlabWorkhorse
1922
class << self
2023
def parse_variables
@@ -30,13 +33,123 @@ def parse_variables
3033
network = user_network || default_network
3134

3235
Gitlab['gitlab_workhorse']['listen_addr'] ||= File.join(sockets_dir, 'socket') if network == "unix"
36+
37+
parse_redis_settings
3338
end
3439

3540
def parse_secrets
3641
# gitlab-workhorse expects exactly 32 bytes, encoded with base64
3742
Gitlab['gitlab_workhorse']['secret_token'] ||= SecureRandom.base64(32)
3843
end
3944

45+
def parse_redis_settings
46+
gitlab_workhorse_redis_configured = Gitlab['gitlab_workhorse'].key?('redis_socket') ||
47+
Gitlab['gitlab_workhorse'].key?('redis_host')
48+
49+
rails_workhorse_redis_configured =
50+
Gitlab['gitlab_rails']['redis_workhorse_instance'] ||
51+
(Gitlab['gitlab_rails']['redis_workhorse_sentinels'] &&
52+
!Gitlab['gitlab_rails']['redis_workhorse_sentinels'].empty?)
53+
54+
if gitlab_workhorse_redis_configured
55+
# Parse settings from `redis['master_*']` first.
56+
parse_redis_master_settings
57+
# If gitlab_workhorse settings are specified, populate
58+
# gitlab_rails['redis_workhorse_*'] settings from it.
59+
update_separate_redis_instance_settings
60+
elsif rails_workhorse_redis_configured
61+
# If user has specified a separate Redis host for Workhorse via
62+
# `gitlab_rails['redis_workhorse_*']` settings, copy them to
63+
# `gitlab_workhorse['redis_*']`.
64+
parse_separate_redis_instance_settings
65+
parse_redis_master_settings
66+
else
67+
# If user hasn't specified any separate Redis settings for Workhorse,
68+
# copy the global settings from GitLab Rails
69+
parse_global_rails_redis_settings
70+
parse_redis_master_settings
71+
end
72+
end
73+
74+
# rubocop:disable Metrics/CyclomaticComplexity
75+
# rubocop:disable Metrics/AbcSize
76+
# rubocop:disable Metrics/PerceivedComplexity
77+
def update_separate_redis_instance_settings
78+
if Gitlab['gitlab_workhorse']['redis_host']
79+
uri_from_workhorse = NewRedisHelper.build_redis_url(
80+
ssl: Gitlab['gitlab_workhorse']['redis_ssl'] || Gitlab['node']['gitlab']['gitlab_workhorse']['redis_ssl'],
81+
host: Gitlab['gitlab_workhorse']['redis_host'] || Gitlab['node']['gitlab']['gitlab_workhorse']['redis_host'],
82+
port: Gitlab['gitlab_workhorse']['redis_port'] || Gitlab['node']['gitlab']['gitlab_workhorse']['redis_port'],
83+
password: Gitlab['gitlab_workhorse']['redis_password'] || Gitlab['node']['gitlab']['gitlab_workhorse']['redis_password'],
84+
path: Gitlab['gitlab_workhorse']['redis_database'] || Gitlab['node']['gitlab']['gitlab_workhorse']['redis_database']
85+
).to_s
86+
87+
uri_from_rails = NewRedisHelper.build_redis_url(
88+
ssl: Gitlab['gitlab_rails']['redis_ssl'] || Gitlab['node']['gitlab']['gitlab_rails']['redis_ssl'],
89+
host: Gitlab['gitlab_rails']['redis_host'] || Gitlab['node']['gitlab']['gitlab_rails']['redis_host'],
90+
port: Gitlab['gitlab_rails']['redis_port'] || Gitlab['node']['gitlab']['gitlab_rails']['redis_port'],
91+
password: Gitlab['gitlab_rails']['redis_password'] || Gitlab['node']['gitlab']['gitlab_rails']['redis_password'],
92+
path: Gitlab['gitlab_rails']['redis_database'] || Gitlab['node']['gitlab']['gitlab_rails']['redis_database']
93+
).to_s
94+
Gitlab['gitlab_rails']['redis_workhorse_instance'] = uri_from_workhorse if uri_from_workhorse != uri_from_rails
95+
96+
else
97+
workhorse_redis_socket = Gitlab['gitlab_workhorse']['redis_socket'] || Gitlab['node']['gitlab']['gitlab_workhorse']['redis_socket']
98+
rails_redis_socket = Gitlab['gitlab_rails']['redis_socket'] || Gitlab['node']['gitlab']['gitlab_rails']['redis_socket']
99+
Gitlab['gitlab_rails']['redis_workhorse_instance'] = "unix://#{workhorse_redis_socket}" if workhorse_redis_socket != rails_redis_socket
100+
end
101+
102+
%w[username password cluster_nodes sentinels sentinel_master sentinels_password].each do |setting|
103+
Gitlab['gitlab_rails']["redis_workhorse_#{setting}"] ||= Gitlab['gitlab_workhorse']["redis_#{setting}"]
104+
end
105+
end
106+
# rubocop:enable Metrics/CyclomaticComplexity
107+
# rubocop:enable Metrics/AbcSize
108+
# rubocop:enable Metrics/PerceivedComplexity
109+
110+
def parse_global_rails_redis_settings
111+
%w[ssl host socket port password database sentinels sentinels_password].each do |setting|
112+
Gitlab['gitlab_workhorse']["redis_#{setting}"] ||= Gitlab['gitlab_rails']["redis_#{setting}"]
113+
end
114+
end
115+
116+
def parse_separate_redis_instance_settings
117+
# If an individual Redis instance is specified for Workhorse, figure out
118+
# host, port, password, etc. from it
119+
if Gitlab['gitlab_rails']['redis_workhorse_instance']
120+
uri = URI(Gitlab['gitlab_rails']['redis_workhorse_instance'])
121+
122+
Gitlab['gitlab_workhorse']['redis_ssl'] = uri.scheme == 'rediss' unless Gitlab['gitlab_workhorse'].key?('redis_ssl')
123+
if uri.scheme == 'unix'
124+
Gitlab['gitlab_workhorse']['redis_socket'] = uri.path
125+
else
126+
Gitlab['gitlab_workhorse']['redis_host'] ||= if uri.path.start_with?('/')
127+
uri.host
128+
else
129+
uri.path
130+
end
131+
Gitlab['gitlab_workhorse']['redis_port'] ||= uri.port
132+
Gitlab['gitlab_workhorse']['redis_password'] ||= uri.password
133+
Gitlab['gitlab_workhorse']['redis_database'] ||= uri.path.delete_prefix('/') if uri.path.start_with?('/')
134+
end
135+
end
136+
137+
%w[username password cluster_nodes sentinels sentinel_master sentinels_password].each do |setting|
138+
Gitlab['gitlab_workhorse']["redis_#{setting}"] ||= Gitlab['gitlab_rails']["redis_workhorse_#{setting}"]
139+
end
140+
end
141+
142+
def parse_redis_master_settings
143+
# TODO: When GitLab rails gets it's own set if `redis_sentinel_master_*`
144+
# settings, update the following to use them instead of
145+
# `Gitlab['redis'][*]` settings. It can be then merged with
146+
# `parse_rails_redis_settings` method
147+
Gitlab['gitlab_workhorse']['redis_sentinel_master'] ||= Gitlab['redis']['master_name'] || Gitlab[:node]['redis']['master_name']
148+
Gitlab['gitlab_workhorse']['redis_sentinel_master_ip'] ||= Gitlab['redis']['master_ip'] || Gitlab[:node]['redis']['master_ip']
149+
Gitlab['gitlab_workhorse']['redis_sentinel_master_port'] ||= Gitlab['redis']['master_port'] || Gitlab[:node]['redis']['master_port']
150+
Gitlab['gitlab_workhorse']['redis_password'] ||= Gitlab['redis']['master_password'] || Gitlab[:node]['redis']['master_password']
151+
end
152+
40153
private
41154

42155
def auth_socket_specified?

spec/chef/cookbooks/gitlab/libraries/redis_helper_spec.rb

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -197,15 +197,15 @@
197197
it 'renders parameters for workhorse redis' do
198198
stub_gitlab_rb(baseline_config_with_sentinel.merge({
199199
gitlab_rails: {
200-
redis_workhorse_instance: "redis://:redis.workhorse.com:8888",
200+
redis_workhorse_instance: "redis://:@redis.workhorse.com:8888",
201201
redis_workhorse_password: "workhorse.password"
202202
}
203203
}))
204204

205205
params = subject.workhorse_params
206206
expect(params[:password]).to eq('workhorse.password')
207207
expect(params[:sentinels]).to eq([])
208-
expect(params[:url].to_s).to eq('redis://:redis.workhorse.com:8888')
208+
expect(params[:url].to_s).to eq('redis://:@redis.workhorse.com:8888')
209209
end
210210
end
211211

0 commit comments

Comments
 (0)