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 option to check for deprecated stacks in pre-start rake task #3894

Merged
merged 11 commits into from
Jul 31, 2024
9 changes: 8 additions & 1 deletion app/models/runtime/stack.rb
Original file line number Diff line number Diff line change
Expand Up @@ -100,6 +100,10 @@ def stacks
@hash['stacks']
end

def deprecated_stacks
@hash['deprecated_stacks']
end

def default
@hash['default']
end
Expand All @@ -112,7 +116,10 @@ def default
'description' => String,
optional('build_rootfs_image') => String,
optional('run_rootfs_image') => String
}]
}],
optional('deprecated_stacks') => [
String
]
}
end
end
Expand Down
5 changes: 5 additions & 0 deletions config/stacks.yml
Original file line number Diff line number Diff line change
Expand Up @@ -3,3 +3,8 @@ default: "cflinuxfs4"
stacks:
- name: "cflinuxfs4"
description: "test cflinuxfs4 entry"




tcdowney marked this conversation as resolved.
Show resolved Hide resolved
deprecated_stacks: [ 'cflinuxfs3' ]
30 changes: 30 additions & 0 deletions lib/cloud_controller/check_stacks.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
module VCAP::CloudController
class CheckStacks
attr_reader :config

def initialize(config)
@config = config
@stack_config = VCAP::CloudController::Stack::ConfigFile.new(config.get(:stacks_file))
end

def validate_stacks
deprecated_stacks = @stack_config.deprecated_stacks
return if deprecated_stacks.blank?

deprecated_stacks.each { |stack| validate_stack(stack) }
end

private

def validate_stack(deprecated_stack)
configured_stacks = @stack_config.stacks
deprecated_stack_in_config = (configured_stacks.find { |stack| stack['name'] == deprecated_stack }).present?

return if deprecated_stack_in_config

deprecated_stack_in_db = VCAP::CloudController::Stack.first(name: deprecated_stack).present?

raise "rake task 'stack_check' failed, stack '#{deprecated_stack}' not supported" if deprecated_stack_in_db
end
end
end
14 changes: 14 additions & 0 deletions lib/tasks/stack_check.rake
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
namespace :stacks do
desc 'Check Installed Stacks'
task stack_check: :environment do
logger = Steno.logger('cc.stack')
VCAP::CloudController::Encryptor.db_encryption_key = RakeConfig.config.get(:db_encryption_key)
tcdowney marked this conversation as resolved.
Show resolved Hide resolved
VCAP::CloudController::DB.connect(RakeConfig.config.get(:db), logger)

require 'models/runtime/buildpack_lifecycle_data_model'
require 'models/runtime/stack'
require 'cloud_controller/check_stacks'

VCAP::CloudController::CheckStacks.new(RakeConfig.config).validate_stacks
end
end
4 changes: 3 additions & 1 deletion spec/fixtures/config/invalid_stacks.yml
Original file line number Diff line number Diff line change
@@ -1,2 +1,4 @@
stacks:
- unknown_key: true
- unknown_key: true

deprecated_stacks: {}
3 changes: 3 additions & 0 deletions spec/fixtures/config/stacks.yml
Original file line number Diff line number Diff line change
Expand Up @@ -7,3 +7,6 @@ stacks:
description: "default-stack-description"
- name: "cider"
description: "cider-description"

deprecated_stacks:
- old_stack
122 changes: 122 additions & 0 deletions spec/unit/lib/cloud_controller/check_stacks_spec.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,122 @@
require 'spec_helper'
require 'yaml'
require 'cloud_controller/check_stacks'
require 'tasks/rake_config'

module VCAP::CloudController
RSpec.describe CheckStacks do
let(:stack_file_contents) do
{
'default' => 'cflinuxfs4',
'stacks' => [
cflinuxfs4
],
'deprecated_stacks' => 'cflinuxfs3'
}
end

let(:cflinuxfs3) { { 'name' => 'cflinuxfs3', 'description' => 'fs3' } }
let(:cflinuxfs4) { { 'name' => 'cflinuxfs4', 'description' => 'fs4' } }

before do
# binding.pry
tcdowney marked this conversation as resolved.
Show resolved Hide resolved
Stack.dataset.destroy
file = Tempfile.new
file.write(stack_file_contents.to_yaml)
file.close
Stack.configure(file)
Stack.populate
TestConfig.override(stacks_file: file.path)
end

let(:stack_checker) { CheckStacks.new(TestConfig.config_instance) }

describe 'there deprecated stacks is nil' do
xandroc marked this conversation as resolved.
Show resolved Hide resolved
let(:stack_file_contents) do
{
'default' => 'cflinuxfs4',
'stacks' => [
cflinuxfs3,
cflinuxfs4
]
}
end

it 'does nothing' do
expect { stack_checker.validate_stacks }.not_to raise_error
end
end

describe 'there are no deprecated stacks' do
let(:stack_file_contents) do
{
'default' => 'cflinuxfs4',
'stacks' => [
cflinuxfs3,
cflinuxfs4
],
'deprecated_stacks' => []
}
end

it 'does nothing' do
expect { stack_checker.validate_stacks }.not_to raise_error
end
end

describe 'the deprecated stack is in the config' do
let(:stack_file_contents) do
{
'default' => 'cflinuxfs4',
'stacks' => [
cflinuxfs3,
cflinuxfs4
],
'deprecated_stacks' => ['cflinuxfs3']
}
end

describe 'the deprecated stack is in the db' do
Copy link
Contributor

@Samze Samze Jul 26, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

question Do we need these describes for the db behaviour? Looking at the code, if the deprecated stack is in the stacks list we don't even check the DB. We return early here https://github.com/cloudfoundry/cloud_controller_ng/pull/3894/files#diff-b51e853460880f38ea614d45c335bfdaa98ebf81f6166ce4c13ffab95bfbf871R23

it 'does not raise an error' do
expect { stack_checker.validate_stacks }.not_to raise_error
end
end

describe 'the deprecated stack is not in the db' do
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

before do
Stack.first(name: 'cflinuxfs3').destroy
end

it 'does not raise an error' do
expect { stack_checker.validate_stacks }.not_to raise_error
end
end
end

describe 'when the deprecated stack is not in the config' do
let(:stack_file_contents) do
{
'default' => 'cflinuxfs4',
'stacks' => [cflinuxfs4],
'deprecated_stacks' => ['cflinuxfs3']
}
end

describe 'the deprecated stack is in the db' do
before do
Stack.make(name: 'cflinuxfs3')
end

it 'logs an error and exits 1' do
expect { stack_checker.validate_stacks }.to raise_error "rake task 'stack_check' failed, stack 'cflinuxfs3' not supported"
end
end

describe 'the deprecated stack is not in the db' do
it 'does not raise an error' do
expect { stack_checker.validate_stacks }.not_to raise_error
end
end
end
end
end
3 changes: 2 additions & 1 deletion spec/unit/models/runtime/stack_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,8 @@ module VCAP::CloudController

{
default: 'default => Missing key',
stacks: 'name => Missing key'
stacks: 'name => Missing key',
deprecated_stacks: 'deprecated_stacks => Expected instance of Array, given instance of Hash }'
}.each do |key, expected_error|
it "requires #{key} (validates via '#{expected_error}')" do
expect do
Expand Down