Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add Redis job #322

Merged
merged 1 commit into from
Jul 10, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions config/blobs.yml
Original file line number Diff line number Diff line change
Expand Up @@ -90,3 +90,7 @@ postgres/postgresql-11.18.tar.gz:
size: 26714356
object_id: 3836fb7b-3c82-4b7e-40af-8e001b7a3b55
sha: sha256:3c693225e26b3c40f40d7cbbc1409edb2e7db8072a9b3a7d4d3eb73c131c5a3b
redis/7.0.11.tar.gz:
size: 3019850
object_id: ee31345d-be80-45bf-49c9-1b2f3fb11b4a
sha: sha256:7f1941bfa7fa01e2fd167771ff22b8e46b1a6bb0707f01b3e6308d9770e44bf3
6 changes: 6 additions & 0 deletions jobs/cloud_controller_ng/spec
Original file line number Diff line number Diff line change
Expand Up @@ -224,6 +224,8 @@ provides:
- ssl.skip_cert_verify
- system_domain
- uaa.clients.cc_routing.secret
- cc.experimental.use_puma_webserver
- cc.experimental.use_redis

consumes:
- name: database
Expand Down Expand Up @@ -1210,6 +1212,10 @@ properties:
description: "Use Puma in place of Thin as the webserver. This may increase performance as Puma forks Cloud Controller processes to avoid relying on threads"
default: false

cc.experimental.use_redis:
description: "Use co-deployed Redis for rate limiting and metrics. If the Puma webserver is enabled, Redis will automatically be used."
default: false

cc.puma.workers:
description: "Number of workers for Puma webserver."
default: 3
Expand Down
11 changes: 11 additions & 0 deletions jobs/cloud_controller_ng/templates/bpm.yml.erb
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,16 @@ def mount_nfs_volume!(config)
end
end

def mount_redis_volume!(config)
if p("cc.experimental.use_puma_webserver") || p("cc.experimental.use_redis")
config['additional_volumes'] = [] unless config.key?('additional_volumes')
config['additional_volumes'] << {
"path" => "/var/vcap/data/redis",
"mount_only" => true,
}
end
end

def enable_fog_debugging!(config)
if p("cc.log_fog_requests")
case p("cc.packages.fog_connection.provider", "").downcase
Expand Down Expand Up @@ -67,6 +77,7 @@ if properties.env
end
end
mount_nfs_volume!(cloud_controller_ng_config)
mount_redis_volume!(cloud_controller_ng_config)

nginx_config = {
"name" => "nginx",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@

def validate_app_domains(app_domains)
app_domains.each do |app_domain|
if app_domain.is_a?(Hash) && app_domain['internal'] == true && app_domain.has_key?('router_group_name')
if app_domain.is_a?(Hash) && app_domain['internal'] == true && app_domain.key?('router_group_name')
raise 'Error for app_domains: Router groups cannot be specified for internal domains.'
end
end
Expand Down Expand Up @@ -456,6 +456,11 @@ rate_limiter_v2_api:
per_process_admin_limit: <%= (p("cc.rate_limiter_v2_api.admin_limit").to_f/instances).ceil %>
reset_interval_in_minutes: <%= p("cc.rate_limiter_v2_api.reset_interval_in_minutes") %>

<% if p("cc.experimental.use_puma_webserver") || p("cc.experimental.use_redis") %>
redis:
socket: "/var/vcap/data/redis/redis.sock"
<% end %>

<%
cc_uploader_url = nil
if_link("cc_uploader") do |cc_uploader|
Expand Down
14 changes: 14 additions & 0 deletions jobs/redis/monit
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
<%
cloud_controller_internal = link("cloud_controller_internal")
if cloud_controller_internal.p("cc.experimental.use_puma_webserver") || cloud_controller_internal.p("cc.experimental.use_redis")
%>

check process redis
with pidfile /var/vcap/sys/run/bpm/redis/redis.pid
start program "/var/vcap/jobs/bpm/bin/bpm start redis"
stop program "/var/vcap/jobs/bpm/bin/bpm stop redis"
group vcap

<%
end
%>
18 changes: 18 additions & 0 deletions jobs/redis/spec
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
---
name: redis

description: "Co-deployed Redis used for rate limiting and metrics"

templates:
bpm.yml.erb: config/bpm.yml
pre-start.sh.erb: bin/pre-start.sh
redis-cli.sh.erb: bin/redis-cli.sh

packages:
- redis

consumes:
- name: cloud_controller_internal
type: cloud_controller_internal

properties: {}
16 changes: 16 additions & 0 deletions jobs/redis/templates/bpm.yml.erb
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
---
processes:
- name: redis
executable: /var/vcap/packages/redis/redis-server
args:
- --port
- 0
- --unixsocket
- /var/vcap/data/redis/redis.sock
- --save
- ""
ephemeral_disk: true
limits:
open_files: 10032
hooks:
pre_start: /var/vcap/jobs/redis/bin/pre-start.sh
5 changes: 5 additions & 0 deletions jobs/redis/templates/pre-start.sh.erb
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
#!/bin/bash

set -e

sysctl -w vm.overcommit_memory=1
5 changes: 5 additions & 0 deletions jobs/redis/templates/redis-cli.sh.erb
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
#!/bin/bash

set -e

/var/vcap/packages/redis/redis-cli -s /var/vcap/data/redis/redis.sock
9 changes: 9 additions & 0 deletions packages/redis/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
redis
============
Redis in-memory data store.

This file can be downloaded from the following locations:

| Filename | Download URL |
| -------- | ------------ |
| 7.0.11.tar.gz | https://github.com/redis/redis/archive/7.0.11.tar.gz |
16 changes: 16 additions & 0 deletions packages/redis/packaging
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
#!/bin/bash -eu

function main() {
local redis_version
redis_version="7.0.11"

tar xzf "redis/${redis_version}.tar.gz"

pushd "redis-${redis_version}" > /dev/null
make

cp src/redis-server src/redis-cli "${BOSH_INSTALL_TARGET}"
popd > /dev/null
}

main
4 changes: 4 additions & 0 deletions packages/redis/spec
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
---
name: redis
files:
- redis/7.0.11.tar.gz
45 changes: 45 additions & 0 deletions spec/cloud_controller_ng/bpm_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,21 @@ def expect_default_debug_env_vars(env_vars)
expect(env_vars['FOG_DEBUG']).to be(true)
end

def redis_volume_mounted?(process)
return false unless process.key?('additional_volumes')

results = process['additional_volumes'].select { |v| v['path'] == '/var/vcap/data/redis' }
return false unless results.length == 1

redis_volume = results[0]
return false unless redis_volume.key?('mount_only')

mount_only = redis_volume['mount_only']
return false unless mount_only.is_a?(TrueClass) && mount_only == true

true
end

let(:release_path) { File.join(File.dirname(__FILE__), '../..') }
let(:release) { ReleaseDir.new(release_path) }
let(:job) { release.job('cloud_controller_ng') }
Expand Down Expand Up @@ -96,6 +111,36 @@ def expect_default_debug_env_vars(env_vars)
expect(env_vars).not_to have_key('ALIYUN_OSS_SDK_LOG_LEVEL')
end
end

context 'when the puma webserver is used' do
it 'mounts the redis volume into the ccng job container' do
template_hash = YAML.safe_load(template.render({ 'cc' => { 'experimental' => { 'use_puma_webserver' => true } } }, consumes: {}))

results = template_hash['processes'].select { |p| p['name'].include?('cloud_controller_ng') }
expect(results.length).to eq(1)
expect(redis_volume_mounted?(results[0])).to be_truthy
end
end

context "when 'cc.experimental.use_redis' is set to 'true'" do
it 'mounts the redis volume into the ccng job container' do
template_hash = YAML.safe_load(template.render({ 'cc' => { 'experimental' => { 'use_redis' => true } } }, consumes: {}))

results = template_hash['processes'].select { |p| p['name'].include?('cloud_controller_ng') }
expect(results.length).to eq(1)
expect(redis_volume_mounted?(results[0])).to be_truthy
end
end

context "when neither the puma webserver is used nor 'cc.experimental.use_redis' is set to 'true'" do
it 'does not mount the redis volume into the ccng job container' do
template_hash = YAML.safe_load(template.render({}, consumes: {}))

results = template_hash['processes'].select { |p| p['name'].include?('cloud_controller_ng') }
expect(results.length).to eq(1)
expect(redis_volume_mounted?(results[0])).to be_falsey
end
end
end
end
end
Expand Down
25 changes: 25 additions & 0 deletions spec/cloud_controller_ng/cloud_controller_ng_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -599,6 +599,31 @@ module Test
end
end
end

describe 'redis config' do
context 'when the puma webserver is used' do
it 'renders the redis socket into the ccng config' do
merged_manifest_properties['cc']['experimental'] = { 'use_puma_webserver' => true }
template_hash = YAML.safe_load(template.render(merged_manifest_properties, consumes: links))
expect(template_hash['redis']['socket']).to eq('/var/vcap/data/redis/redis.sock')
end
end

context "when 'cc.experimental.use_redis' is set to 'true'" do
it 'renders the redis socket into the ccng config' do
merged_manifest_properties['cc']['experimental'] = { 'use_redis' => true }
template_hash = YAML.safe_load(template.render(merged_manifest_properties, consumes: links))
expect(template_hash['redis']['socket']).to eq('/var/vcap/data/redis/redis.sock')
end
end

context "when neither the puma webserver is used nor 'cc.experimental.use_redis' is set to 'true'" do
it 'does not render the redis socket into the ccng config' do
template_hash = YAML.safe_load(template.render(merged_manifest_properties, consumes: links))
expect(template_hash).not_to have_key('redis')
end
end
end
end
end
end
Expand Down
47 changes: 47 additions & 0 deletions spec/redis/monit_spec.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
# frozen_string_literal: true

require 'rspec'
require 'bosh/template/test'

module Bosh
module Template
module Test
describe 'redis job template rendering' do
let(:release_path) { File.join(File.dirname(__FILE__), '../..') }
let(:release) { ReleaseDir.new(release_path) }
let(:job) { release.job('redis') }
let(:spec) { job.instance_variable_get(:@spec) }
let(:job_path) { job.instance_variable_get(:@job_path) }
let(:cc_internal_properties) { { 'cc' => { 'experimental' => { 'use_puma_webserver' => false, 'use_redis' => false } } } }
let(:link) { Link.new(name: 'cloud_controller_internal', properties: cc_internal_properties) }

describe 'monit' do
let(:template) { Template.new(spec, File.join(job_path, 'monit')) }

context 'when the puma webserver is used' do
it 'renders the monit directives' do
cc_internal_properties['cc']['experimental']['use_puma_webserver'] = true
result = template.render({}, consumes: [link])
expect(result).to include('check process redis')
end
end

context "when 'cc.experimental.use_redis' is set to 'true'" do
it 'renders the monit directives' do
cc_internal_properties['cc']['experimental']['use_redis'] = true
result = template.render({}, consumes: [link])
expect(result).to include('check process redis')
end
end

context "when neither the puma webserver is used nor 'cc.experimental.use_redis' is set to 'true'" do
it 'does not render the monit directives' do
result = template.render({}, consumes: [link])
expect(result.strip).to eq('')
end
end
end
end
end
end
end