diff --git a/files/gitlab-cookbooks/gitlab/recipes/gitlab-workhorse.rb b/files/gitlab-cookbooks/gitlab/recipes/gitlab-workhorse.rb index 92cf5867bf7a5ad62cfdef132fc7e5f85914003d_ZmlsZXMvZ2l0bGFiLWNvb2tib29rcy9naXRsYWIvcmVjaXBlcy9naXRsYWItd29ya2hvcnNlLnJi..abde52a699e43e3681dedfca84e0af0a33db3e26_ZmlsZXMvZ2l0bGFiLWNvb2tib29rcy9naXRsYWIvcmVjaXBlcy9naXRsYWItd29ya2hvcnNlLnJi 100644 --- a/files/gitlab-cookbooks/gitlab/recipes/gitlab-workhorse.rb +++ b/files/gitlab-cookbooks/gitlab/recipes/gitlab-workhorse.rb @@ -15,7 +15,7 @@ # limitations under the License. # account_helper = AccountHelper.new(node) -redis_helper = RedisHelper.new(node) +redis_helper = NewRedisHelper::GitlabWorkhorse.new(node) workhorse_helper = GitlabWorkhorseHelper.new(node) logfiles_helper = LogfilesHelper.new(node) logging_settings = logfiles_helper.logging_settings('gitlab-workhorse') @@ -89,7 +89,7 @@ alt_document_root = node['gitlab']['gitlab_workhorse']['alt_document_root'] shutdown_timeout = node['gitlab']['gitlab_workhorse']['shutdown_timeout'] workhorse_keywatcher = node['gitlab']['gitlab_workhorse']['workhorse_keywatcher'] -redis_params = redis_helper.workhorse_params +redis_params = redis_helper.redis_params config_file_path = File.join(working_dir, "config.toml") image_scaler_max_procs = node['gitlab']['gitlab_workhorse']['image_scaler_max_procs'] image_scaler_max_filesize = node['gitlab']['gitlab_workhorse']['image_scaler_max_filesize'] diff --git a/files/gitlab-cookbooks/package/libraries/helpers/new_redis_helper/gitlab_workhorse.rb b/files/gitlab-cookbooks/package/libraries/helpers/new_redis_helper/gitlab_workhorse.rb new file mode 100644 index 0000000000000000000000000000000000000000..abde52a699e43e3681dedfca84e0af0a33db3e26_ZmlsZXMvZ2l0bGFiLWNvb2tib29rcy9wYWNrYWdlL2xpYnJhcmllcy9oZWxwZXJzL25ld19yZWRpc19oZWxwZXIvZ2l0bGFiX3dvcmtob3JzZS5yYg== --- /dev/null +++ b/files/gitlab-cookbooks/package/libraries/helpers/new_redis_helper/gitlab_workhorse.rb @@ -0,0 +1,23 @@ +module NewRedisHelper + class GitlabWorkhorse < NewRedisHelper::Base + def redis_params + { + url: redis_url, + password: redis_credentials[:password], + sentinels: sentinel_urls, + sentinelMaster: master_name, + sentinelPassword: redis_sentinels_password + } + end + + private + + def node_access_keys + %w[gitlab gitlab_workhorse] + end + + def support_sentinel_groupname? + true + end + end +end diff --git a/spec/chef/cookbooks/package/libraries/new_redis_helper/gitlab_workhorse_spec.rb b/spec/chef/cookbooks/package/libraries/new_redis_helper/gitlab_workhorse_spec.rb new file mode 100644 index 0000000000000000000000000000000000000000..abde52a699e43e3681dedfca84e0af0a33db3e26_c3BlYy9jaGVmL2Nvb2tib29rcy9wYWNrYWdlL2xpYnJhcmllcy9uZXdfcmVkaXNfaGVscGVyL2dpdGxhYl93b3JraG9yc2Vfc3BlYy5yYg== --- /dev/null +++ b/spec/chef/cookbooks/package/libraries/new_redis_helper/gitlab_workhorse_spec.rb @@ -0,0 +1,197 @@ +require 'chef_helper' + +RSpec.describe NewRedisHelper::GitlabWorkhorse do + let(:chef_run) { ChefSpec::SoloRunner.new(step_into: %w(templatesymlink)).converge('gitlab::default') } + let(:workhorse_redis_yml_template) { chef_run.template('/var/opt/gitlab/gitlab-rails/etc/redis.workhorse.yml') } + let(:workhorse_redis_yml_file_content) { ChefSpec::Renderer.new(chef_run, workhorse_redis_yml_template).content } + let(:workhorse_redis_yml) { YAML.safe_load(workhorse_redis_yml_file_content, aliases: true, symbolize_names: true) } + + subject { described_class.new(chef_run.node) } + + before do + allow(Gitlab).to receive(:[]).and_call_original + end + + context '#redis_params' do + context 'by default' do + it 'returns information about the default Redis instance' do + expect(subject.redis_params).to eq( + url: 'unix:/var/opt/gitlab/redis/redis.socket', + password: nil, + sentinels: [], + sentinelMaster: 'gitlab-redis', + sentinelPassword: nil + ) + end + end + + context 'with user specified values' do + context 'when settings specified via gitlab_rails' do + before do + stub_gitlab_rb( + gitlab_rails: { + redis_host: 'my.redis.host', + redis_password: 'redis-password' + } + ) + end + + it 'returns information about the provided Redis instance via gitlab_rails' do + expect(subject.redis_params).to eq( + url: 'redis://:redis-password@my.redis.host/', + password: 'redis-password', + sentinels: [], + sentinelMaster: 'gitlab-redis', + sentinelPassword: nil + ) + end + end + + context 'when settings specified via gitlab_rails for separate Redis instance' do + before do + stub_gitlab_rb( + gitlab_rails: { + redis_host: 'my.redis.host', + redis_password: 'redis-password', + redis_workhorse_instance: 'different.workhorse.redis.instance', + redis_workhorse_password: 'different-redis-password' + } + ) + end + + it 'returns information about the provided Redis instance via gitlab_rails workhorse instance' do + expect(subject.redis_params).to eq( + url: 'redis://:different-redis-password@different.workhorse.redis.instance/', + password: 'different-redis-password', + sentinels: [], + sentinelMaster: 'gitlab-redis', + sentinelPassword: nil + ) + end + end + + context 'when settings specified via gitlab_workhorse' do + context 'when pointing to different Redis instances' do + before do + stub_gitlab_rb( + gitlab_rails: { + redis_host: 'my.redis.host', + redis_password: 'redis-password', + redis_workhorse_instance: 'different.workhorse.redis.instance', + redis_workhorse_password: 'different-redis-password' + }, + gitlab_workhorse: { + redis_host: 'workhorse.redis.host', + redis_password: 'redis-workhorse-password' + } + ) + end + + it 'returns information about the provided Redis instance via gitlab_workhorse' do + expect(subject.redis_params).to eq( + url: 'redis://:redis-workhorse-password@workhorse.redis.host/', + password: 'redis-workhorse-password', + sentinels: [], + sentinelMaster: 'gitlab-redis', + sentinelPassword: nil + ) + end + + # TODO: When Workhorse recipe spec is cleaned up, this should ideally + # end up there. + it 'populates workhorse.redis.yml with values from gitlab_workhorse' do + expect(workhorse_redis_yml).to eq( + production: { + url: 'redis://:redis-workhorse-password@workhorse.redis.host/', + secret_file: '/var/opt/gitlab/gitlab-rails/shared/encrypted_settings/redis.workhorse.yml.enc' + } + ) + end + end + + context 'when pointing to same Redis instance' do + before do + stub_gitlab_rb( + gitlab_rails: { + redis_host: 'my.redis.host', + redis_password: 'redis-password', + }, + gitlab_workhorse: { + redis_host: 'my.redis.host', + redis_password: 'redis-password' + } + ) + end + + it 'returns information about the provided Redis instance via gitlab_workhorse' do + expect(subject.redis_params).to eq( + url: 'redis://:redis-password@my.redis.host/', + password: 'redis-password', + sentinels: [], + sentinelMaster: 'gitlab-redis', + sentinelPassword: nil + ) + end + + # TODO: When Workhorse recipe spec is cleaned up, this should ideally + # end up there. + it 'does not populate workhorse.redis.yml' do + expect(chef_run).not_to render_file('/var/opt/gitlab/gitlab-rails/etc/redis.workhorse.yml') + end + end + end + + context 'when sentinels are specified' do + context 'when Redis master settings are specified via redis key' do + before do + stub_gitlab_rb( + gitlab_workhorse: { + redis_host: 'workhorse.redis.host', + redis_sentinels: [ + { host: '10.0.0.1', port: 26379 }, + { host: '10.0.0.2', port: 26379 }, + { host: '10.0.0.3', port: 26379 } + ], + redis_sentinels_password: 'workhorse-sentinel-password' + }, + redis: { + master_name: 'redis-for-workhorse', + master_password: 'redis-password' + } + ) + end + + it 'returns information about the provided Redis instance via gitlab_workhorse' do + expect(subject.redis_params).to eq( + url: 'redis://:redis-password@redis-for-workhorse/', + password: 'redis-password', + sentinels: [ + "redis://:workhorse-sentinel-password@10.0.0.1:26379", + "redis://:workhorse-sentinel-password@10.0.0.2:26379", + "redis://:workhorse-sentinel-password@10.0.0.3:26379" + ], + sentinelMaster: 'redis-for-workhorse', + sentinelPassword: 'workhorse-sentinel-password' + ) + end + + # TODO: When Workhorse recipe spec is cleaned up, this should ideally + # end up there. + it 'populates workhorse.redis.yml with values from gitlab_workhorse' do + expect(workhorse_redis_yml).to eq( + production: { + url: 'redis://:redis-password@workhorse.redis.host/', + secret_file: '/var/opt/gitlab/gitlab-rails/shared/encrypted_settings/redis.workhorse.yml.enc', + sentinels: [ + { host: '10.0.0.1', port: 26379, password: 'workhorse-sentinel-password' }, + { host: '10.0.0.2', port: 26379, password: 'workhorse-sentinel-password' }, + { host: '10.0.0.3', port: 26379, password: 'workhorse-sentinel-password' }, + ] + } + ) + end + end + end + end + end +end