Skip to content

Commit 6b76837

Browse files
Add option to check for deprecated stacks in pre-start rake task (#3894)
* add stack_check rake task Co-authored-by: João Pereira <[email protected]>
1 parent f76b71d commit 6b76837

File tree

9 files changed

+192
-11
lines changed

9 files changed

+192
-11
lines changed

app/models/runtime/stack.rb

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -100,6 +100,10 @@ def stacks
100100
@hash['stacks']
101101
end
102102

103+
def deprecated_stacks
104+
@hash['deprecated_stacks']
105+
end
106+
103107
def default
104108
@hash['default']
105109
end
@@ -112,7 +116,10 @@ def default
112116
'description' => String,
113117
optional('build_rootfs_image') => String,
114118
optional('run_rootfs_image') => String
115-
}]
119+
}],
120+
optional('deprecated_stacks') => [
121+
String
122+
]
116123
}
117124
end
118125
end

config/stacks.yml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,3 +3,4 @@ default: "cflinuxfs4"
33
stacks:
44
- name: "cflinuxfs4"
55
description: "test cflinuxfs4 entry"
6+
deprecated_stacks: [ 'cflinuxfs3' ]

lib/cloud_controller/check_stacks.rb

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
module VCAP::CloudController
2+
class CheckStacks
3+
attr_reader :config
4+
5+
def initialize(config)
6+
@config = config
7+
@stack_config = VCAP::CloudController::Stack::ConfigFile.new(config.get(:stacks_file))
8+
end
9+
10+
def validate_stacks
11+
deprecated_stacks = @stack_config.deprecated_stacks
12+
return if deprecated_stacks.blank?
13+
14+
deprecated_stacks.each { |stack| validate_stack(stack) }
15+
end
16+
17+
private
18+
19+
def validate_stack(deprecated_stack)
20+
configured_stacks = @stack_config.stacks
21+
deprecated_stack_in_config = (configured_stacks.find { |stack| stack['name'] == deprecated_stack }).present?
22+
23+
return if deprecated_stack_in_config
24+
25+
deprecated_stack_in_db = VCAP::CloudController::Stack.first(name: deprecated_stack).present?
26+
27+
raise "rake task 'stack_check' failed, stack '#{deprecated_stack}' not supported" if deprecated_stack_in_db
28+
end
29+
end
30+
end

lib/cloud_controller/config.rb

Lines changed: 11 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -107,14 +107,7 @@ def initialize(config_hash, context: :api)
107107
end
108108

109109
def configure_components
110-
Encryptor.db_encryption_key = get(:db_encryption_key)
111-
112-
if get(:database_encryption)
113-
Encryptor.database_encryption_keys = get(:database_encryption)[:keys]
114-
Encryptor.current_encryption_key_label = get(:database_encryption)[:current_key_label]
115-
Encryptor.pbkdf2_hmac_iterations = get(:database_encryption)[:pbkdf2_hmac_iterations]
116-
end
117-
110+
load_db_encryption_key
118111
dependency_locator = CloudController::DependencyLocator.instance
119112
dependency_locator.config = self
120113

@@ -124,6 +117,16 @@ def configure_components
124117
@schema_class.configure_components(self)
125118
end
126119

120+
def load_db_encryption_key
121+
Encryptor.db_encryption_key = get(:db_encryption_key)
122+
123+
return unless get(:database_encryption)
124+
125+
Encryptor.database_encryption_keys = get(:database_encryption)[:keys]
126+
Encryptor.current_encryption_key_label = get(:database_encryption)[:current_key_label]
127+
Encryptor.pbkdf2_hmac_iterations = get(:database_encryption)[:pbkdf2_hmac_iterations]
128+
end
129+
127130
def get(*keys)
128131
invalid_config_path!(keys) unless valid_config_path?(keys, @schema_class.schema)
129132

lib/tasks/stack_check.rake

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
namespace :stacks do
2+
desc 'Check Installed Stacks'
3+
task stack_check: :environment do
4+
logger = Steno.logger('cc.stack')
5+
VCAP::CloudController::DB.load_models(RakeConfig.config.get(:db), logger)
6+
RakeConfig.config.load_db_encryption_key
7+
require 'models/runtime/buildpack_lifecycle_data_model'
8+
require 'models/runtime/stack'
9+
require 'cloud_controller/check_stacks'
10+
11+
VCAP::CloudController::CheckStacks.new(RakeConfig.config).validate_stacks
12+
end
13+
end
Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,4 @@
11
stacks:
2-
- unknown_key: true
2+
- unknown_key: true
3+
4+
deprecated_stacks: {}

spec/fixtures/config/stacks.yml

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,3 +7,6 @@ stacks:
77
description: "default-stack-description"
88
- name: "cider"
99
description: "cider-description"
10+
11+
deprecated_stacks:
12+
- old_stack
Lines changed: 121 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,121 @@
1+
require 'spec_helper'
2+
require 'yaml'
3+
require 'cloud_controller/check_stacks'
4+
require 'tasks/rake_config'
5+
6+
module VCAP::CloudController
7+
RSpec.describe CheckStacks do
8+
let(:stack_file_contents) do
9+
{
10+
'default' => 'cflinuxfs4',
11+
'stacks' => [
12+
cflinuxfs4
13+
],
14+
'deprecated_stacks' => 'cflinuxfs3'
15+
}
16+
end
17+
18+
let(:cflinuxfs3) { { 'name' => 'cflinuxfs3', 'description' => 'fs3' } }
19+
let(:cflinuxfs4) { { 'name' => 'cflinuxfs4', 'description' => 'fs4' } }
20+
21+
before do
22+
Stack.dataset.destroy
23+
file = Tempfile.new
24+
file.write(stack_file_contents.to_yaml)
25+
file.close
26+
Stack.configure(file)
27+
Stack.populate
28+
TestConfig.override(stacks_file: file.path)
29+
end
30+
31+
let(:stack_checker) { CheckStacks.new(TestConfig.config_instance) }
32+
33+
describe 'the deprecated stacks is nil' do
34+
let(:stack_file_contents) do
35+
{
36+
'default' => 'cflinuxfs4',
37+
'stacks' => [
38+
cflinuxfs3,
39+
cflinuxfs4
40+
]
41+
}
42+
end
43+
44+
it 'does nothing' do
45+
expect { stack_checker.validate_stacks }.not_to raise_error
46+
end
47+
end
48+
49+
describe 'there are no deprecated stacks' do
50+
let(:stack_file_contents) do
51+
{
52+
'default' => 'cflinuxfs4',
53+
'stacks' => [
54+
cflinuxfs3,
55+
cflinuxfs4
56+
],
57+
'deprecated_stacks' => []
58+
}
59+
end
60+
61+
it 'does nothing' do
62+
expect { stack_checker.validate_stacks }.not_to raise_error
63+
end
64+
end
65+
66+
describe 'the deprecated stack is in the config' do
67+
let(:stack_file_contents) do
68+
{
69+
'default' => 'cflinuxfs4',
70+
'stacks' => [
71+
cflinuxfs3,
72+
cflinuxfs4
73+
],
74+
'deprecated_stacks' => ['cflinuxfs3']
75+
}
76+
end
77+
78+
describe 'the deprecated stack is in the db' do
79+
it 'does not raise an error' do
80+
expect { stack_checker.validate_stacks }.not_to raise_error
81+
end
82+
end
83+
84+
describe 'the deprecated stack is not in the db' do
85+
before do
86+
Stack.first(name: 'cflinuxfs3').destroy
87+
end
88+
89+
it 'does not raise an error' do
90+
expect { stack_checker.validate_stacks }.not_to raise_error
91+
end
92+
end
93+
end
94+
95+
describe 'when the deprecated stack is not in the config' do
96+
let(:stack_file_contents) do
97+
{
98+
'default' => 'cflinuxfs4',
99+
'stacks' => [cflinuxfs4],
100+
'deprecated_stacks' => ['cflinuxfs3']
101+
}
102+
end
103+
104+
describe 'the deprecated stack is in the db' do
105+
before do
106+
Stack.make(name: 'cflinuxfs3')
107+
end
108+
109+
it 'logs an error and exits 1' do
110+
expect { stack_checker.validate_stacks }.to raise_error "rake task 'stack_check' failed, stack 'cflinuxfs3' not supported"
111+
end
112+
end
113+
114+
describe 'the deprecated stack is not in the db' do
115+
it 'does not raise an error' do
116+
expect { stack_checker.validate_stacks }.not_to raise_error
117+
end
118+
end
119+
end
120+
end
121+
end

spec/unit/models/runtime/stack_spec.rb

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,8 @@ module VCAP::CloudController
4545

4646
{
4747
default: 'default => Missing key',
48-
stacks: 'name => Missing key'
48+
stacks: 'name => Missing key',
49+
deprecated_stacks: 'deprecated_stacks => Expected instance of Array, given instance of Hash }'
4950
}.each do |key, expected_error|
5051
it "requires #{key} (validates via '#{expected_error}')" do
5152
expect do

0 commit comments

Comments
 (0)