Skip to content

Commit

Permalink
configmap: Remove installation configmap
Browse files Browse the repository at this point in the history
Installation configmap can significantly complicate new installation
process and has multiple issues with its design (and related tests).
Remove installation congigmap
Redesign related tests or make them always skip until further
redesign would be done in the scope of different change

Refs: #2153
Signed-off-by: Konstantin Yarovoy <[email protected]>
  • Loading branch information
Konstantin Yarovoy committed Oct 7, 2024
1 parent 9713630 commit 5084133
Show file tree
Hide file tree
Showing 4 changed files with 126 additions and 145 deletions.
204 changes: 69 additions & 135 deletions src/tasks/utils/cnf_manager.cr
Original file line number Diff line number Diff line change
Expand Up @@ -16,9 +16,7 @@ require "ecr"

module CNFManager
class ElapsedTimeConfigMapTemplate
# elapsed_time should be Int32 but it is being passed as string
# So the old behaviour has been retained as is to prevent any breakages
def initialize(@release_name : String, @helm_used : Bool, @elapsed_time : String, @immutable : Bool, @tracing_used : Bool, @e2_found : Bool)
def initialize(@release_name : String, @helm_used : Bool, @immutable : Bool, @tracing_used : Bool, @e2_found : Bool)
end

ECR.def_to_s("src/templates/elapsed_time_configmap.yml.ecr")
Expand Down Expand Up @@ -446,142 +444,82 @@ module CNFManager
capture = ORANMonitor.start_e2_capture?(config)

# todo separate out install methods into a module/function that accepts a block
liveness_time = 0
Log.for("sample_setup:install_method").info { "#{install_method[0]}" }
Log.for("sample_setup:install_method").info { "#{install_method[1]}" }
elapsed_time = Time.measure do
case install_method[0]
when CNFInstall::InstallMethod::ManifestDirectory
Log.for("verbose").info { "deploying by manifest file" } if verbose
manifest_directory = config.deployments.get_deployment_param(:manifest_directory)
KubectlClient::Apply.file("#{destination_cnf_dir}/#{manifest_directory}")
when CNFInstall::InstallMethod::HelmChart
helm_chart_name = config.deployments.get_deployment_param(:helm_chart_name)
helm_repo_name = config.deployments.get_deployment_param(:helm_repo_name)
helm_repo_url = config.deployments.get_deployment_param(:helm_repo_url)
if !helm_repo_name.empty? || !helm_repo_url.empty?
Helm.helm_repo_add(helm_repo_name, helm_repo_url)
end
Log.for("verbose").info { "deploying with chart repository" } if verbose
begin
helm_install = Helm.install(release_name, helm_chart_name, helm_namespace_option, helm_values)
rescue e : Helm::InstallationFailed
stdout_failure "Helm installation failed"
stdout_failure "\t#{e.message}"
exit 1
rescue e : Helm::CannotReuseReleaseNameError
stdout_warning "Release name #{release_name} has already been setup."
# Mark that install is not fresh
fresh_install = false
end
export_published_chart(config, cli_args)
when CNFInstall::InstallMethod::HelmDirectory
Log.for("verbose").info { "deploying with helm directory" } if verbose
#TODO Add helm options into cnf-testsuite yml
#e.g. helm install nsm --set insecure=true ./nsm/helm_chart
begin
helm_install = Helm.install(release_name, "#{install_method[1]}", helm_namespace_option, helm_values)
rescue e : Helm::InstallationFailed
stdout_failure "Helm installation failed"
stdout_failure "\t#{e.message}"
exit 1
rescue e : Helm::CannotReuseReleaseNameError
stdout_warning "Release name #{release_name} has already been setup."
# Mark that install is not fresh
fresh_install = false
end
else
raise "Deployment method not found"
case install_method[0]
when CNFInstall::InstallMethod::ManifestDirectory
Log.for("verbose").info { "deploying by manifest file" } if verbose
manifest_directory = config.deployments.get_deployment_param(:manifest_directory)
KubectlClient::Apply.file("#{destination_cnf_dir}/#{manifest_directory}")
when CNFInstall::InstallMethod::HelmChart
helm_chart_name = config.deployments.get_deployment_param(:helm_chart_name)
helm_repo_name = config.deployments.get_deployment_param(:helm_repo_name)
helm_repo_url = config.deployments.get_deployment_param(:helm_repo_url)
if !helm_repo_name.empty? || !helm_repo_url.empty?
Helm.helm_repo_add(helm_repo_name, helm_repo_url)
end

#Generating manifest from installed CNF
#Returns true or false in case when manifest was generated successfully or not
successfully_generated_manifest = CNFInstall::Manifest.generate_common_manifest(config, release_name, deployment_namespace)

if !successfully_generated_manifest
stdout_failure "Generating manifest was not successfull."
Log.for("verbose").info { "deploying with chart repository" } if verbose
begin
helm_install = Helm.install(release_name, helm_chart_name, helm_namespace_option, helm_values)
rescue e : Helm::InstallationFailed
stdout_failure "Helm installation failed"
stdout_failure "\t#{e.message}"
exit 1
rescue e : Helm::CannotReuseReleaseNameError
stdout_warning "Release name #{release_name} has already been setup."
# Mark that install is not fresh
fresh_install = false
end

resource_ymls = cnf_workload_resources(nil, config) do |resource|
resource
end

resource_names = Helm.workload_resource_kind_names(resource_ymls, deployment_namespace)
#TODO move to kubectlclient and make resource_install_and_wait_for_all function
# get liveness probe initialDelaySeconds and FailureThreshold
# if ((periodSeconds * failureThreshhold) + initialDelaySeconds) / defaultFailureThreshold) > startuptimelimit then fail; else pass
# get largest startuptime of all resoures, then save into config map
resource_ymls.map do |resource|
kind = resource["kind"].as_s.downcase
case kind
when "pod"
Log.info { "resource: #{resource}" }
containers = resource.dig("spec", "containers")
when "deployment","statefulset","replicaset","daemonset"
Log.info { "resource: #{resource}" }
containers = resource.dig("spec", "template", "spec", "containers")
end
containers && containers.as_a.map do |container|
initialDelaySeconds = container.dig?("livenessProbe", "initialDelaySeconds")
failureThreshhold = container.dig?("livenessProbe", "failureThreshhold")
periodSeconds = container.dig?("livenessProbe", "periodSeconds")
total_period_failure = 0
total_extended_period = 0
adjusted_with_default = 0
defaultFailureThreshold = 3
defaultPeriodSeconds = 10

if !failureThreshhold.nil? && failureThreshhold.as_i?
ft = failureThreshhold.as_i
else
ft = defaultFailureThreshold
end

if !periodSeconds.nil? && periodSeconds.as_i?
ps = periodSeconds.as_i
else
ps = defaultPeriodSeconds
end

total_period_failure = ps * ft

if !initialDelaySeconds.nil? && initialDelaySeconds.as_i?
total_extended_period = initialDelaySeconds.as_i + total_period_failure
else
total_extended_period = total_period_failure
end

adjusted_with_default = (total_extended_period / defaultFailureThreshold).round.to_i

Log.info { "total_period_failure: #{total_period_failure}" }
Log.info { "total_extended_period: #{total_extended_period}" }
Log.info { "liveness_time: #{liveness_time}" }
Log.info { "adjusted_with_default: #{adjusted_with_default}" }
if liveness_time < adjusted_with_default
liveness_time = adjusted_with_default
end
end
export_published_chart(config, cli_args)
when CNFInstall::InstallMethod::HelmDirectory
Log.for("verbose").info { "deploying with helm directory" } if verbose
#TODO Add helm options into cnf-testsuite yml
#e.g. helm install nsm --set insecure=true ./nsm/helm_chart
begin
helm_install = Helm.install(release_name, "#{install_method[1]}", helm_namespace_option, helm_values)
rescue e : Helm::InstallationFailed
stdout_failure "Helm installation failed"
stdout_failure "\t#{e.message}"
exit 1
rescue e : Helm::CannotReuseReleaseNameError
stdout_warning "Release name #{release_name} has already been setup."
# Mark that install is not fresh
fresh_install = false
end
if !skip_wait_for_install
stdout_success "Waiting for resource availability, timeout for each resource is #{wait_count} seconds\n"
workload_resource_names = resource_names.select { |resource|
["replicaset", "deployment", "statefulset", "pod", "daemonset"].includes?(resource[:kind].downcase)
}
total_resource_count = workload_resource_names.size()
current_resource_number = 1
workload_resource_names.each do | resource |
stdout_success "Waiting for resource (#{current_resource_number}/#{total_resource_count}): [#{resource[:kind]}] #{resource[:name]}", same_line: true
ready = KubectlClient::Get.resource_wait_for_install(resource[:kind], resource[:name], wait_count: wait_count, namespace: resource[:namespace])
if !ready
stdout_failure "CNF setup has timed-out, [#{resource[:kind]}] #{resource[:name]} is not ready after #{wait_count} seconds.", same_line: true
stdout_failure "Recommended course of actions would be to investigate the resource in cluster, then call cnf_cleanup and try to reinstall the CNF."
exit 1
end
current_resource_number += 1
else
raise "Deployment method not found"
end

#Generating manifest from installed CNF
#Returns true or false in case when manifest was generated successfully or not
successfully_generated_manifest = CNFInstall::Manifest.generate_common_manifest(config, release_name, deployment_namespace)

if !successfully_generated_manifest
stdout_failure "Generating manifest was not successfull."
exit 1
end
resource_ymls = CNFManager.cnf_workload_resources(nil, config) do |resource|
resource
end
resource_names = Helm.workload_resource_kind_names(resource_ymls, deployment_namespace)
if !skip_wait_for_install
stdout_success "Waiting for resource availability, timeout for each resource is #{wait_count} seconds\n"
workload_resource_names = resource_names.select { |resource|
["replicaset", "deployment", "statefulset", "pod", "daemonset"].includes?(resource[:kind].downcase)
}
total_resource_count = workload_resource_names.size()
current_resource_number = 1
workload_resource_names.each do | resource |
stdout_success "Waiting for resource (#{current_resource_number}/#{total_resource_count}): [#{resource[:kind]}] #{resource[:name]}", same_line: true
ready = KubectlClient::Get.resource_wait_for_install(resource[:kind], resource[:name], wait_count: wait_count, namespace: resource[:namespace])
if !ready
stdout_failure "CNF setup has timed-out, [#{resource[:kind]}] #{resource[:name]} is not ready after #{wait_count} seconds.", same_line: true
stdout_failure "Recommended course of actions would be to investigate the resource in cluster, then call cnf_cleanup and try to reinstall the CNF."
exit 1
end
stdout_success "All CNF resources are up!", same_line: true
current_resource_number += 1
end
stdout_success "All CNF resources are up!", same_line: true
end

if match[:found]
Expand All @@ -602,8 +540,6 @@ module CNFManager
end

Log.info { "final e2_found: #{e2_found}" }
Log.info { "final liveness_time: #{liveness_time}" }
Log.info { "elapsed_time.seconds: #{elapsed_time.seconds}" }
Log.info { "helm_install: #{helm_install}" }
Log.info { "helm_install[:error].to_s: #{helm_install[:error].to_s}" }
Log.info { "helm_install[:error].to_s.size: #{helm_install[:error].to_s.size}" }
Expand All @@ -627,8 +563,6 @@ module CNFManager
elapsed_time_template = ElapsedTimeConfigMapTemplate.new(
"cnf-testsuite-#{release_name}-startup-information",
helm_used,
# "#{elapsed_time.seconds}",
"#{liveness_time}",
immutable_configmap,
tracing_used,
e2_found
Expand Down
2 changes: 0 additions & 2 deletions src/tasks/workload/configuration.cr
Original file line number Diff line number Diff line change
Expand Up @@ -405,8 +405,6 @@ end

# https://www.cloudytuts.com/tutorials/kubernetes/how-to-create-immutable-configmaps-and-secrets/
class ImmutableConfigMapTemplate
# elapsed_time should be Int32 but it is being passed as string
# So the old behaviour has been retained as is to prevent any breakages
def initialize(@test_url : String)
end

Expand Down
64 changes: 57 additions & 7 deletions src/tasks/workload/microservice.cr
Original file line number Diff line number Diff line change
Expand Up @@ -102,16 +102,66 @@ end
desc "Does the CNF have a reasonable startup time (< 30 seconds)?"
task "reasonable_startup_time" do |t, args|
CNFManager::Task.task_runner(args, task: t) do |args, config|
release_name = config.deployments.get_deployment_param(:name)

current_dir = FileUtils.pwd
helm = Helm::BinarySingleton.helm
Log.for("verbose").info {helm} if check_verbose(args)

configmap = KubectlClient::Get.configmap("cnf-testsuite-#{release_name}-startup-information")
#TODO check if json is empty
startup_time = configmap["data"].as_h["startup_time"].as_s
startup_time = 0
resource_ymls = CNFManager.cnf_workload_resources(args, config) { |resource| resource }
# get liveness probe initialDelaySeconds and FailureThreshold
# if ((periodSeconds * failureThreshhold) + initialDelaySeconds) / defaultFailureThreshold) > startuptimelimit then fail; else pass
# get largest startuptime of all resoures
resource_ymls.map do |resource|
kind = resource["kind"].as_s.downcase
case kind
when "pod"
Log.info { "resource: #{resource}" }
containers = resource.dig("spec", "containers")
when "deployment","statefulset","replicaset","daemonset"
Log.info { "resource: #{resource}" }
containers = resource.dig("spec", "template", "spec", "containers")
end
containers && containers.as_a.map do |container|
initialDelaySeconds = container.dig?("livenessProbe", "initialDelaySeconds")
failureThreshhold = container.dig?("livenessProbe", "failureThreshhold")
periodSeconds = container.dig?("livenessProbe", "periodSeconds")
total_period_failure = 0
total_extended_period = 0
adjusted_with_default = 0
defaultFailureThreshold = 3
defaultPeriodSeconds = 10

if !failureThreshhold.nil? && failureThreshhold.as_i?
ft = failureThreshhold.as_i
else
ft = defaultFailureThreshold
end

if !periodSeconds.nil? && periodSeconds.as_i?
ps = periodSeconds.as_i
else
ps = defaultPeriodSeconds
end

total_period_failure = ps * ft

if !initialDelaySeconds.nil? && initialDelaySeconds.as_i?
total_extended_period = initialDelaySeconds.as_i + total_period_failure
else
total_extended_period = total_period_failure
end

adjusted_with_default = (total_extended_period / defaultFailureThreshold).round.to_i

Log.info { "total_period_failure: #{total_period_failure}" }
Log.info { "total_extended_period: #{total_extended_period}" }
Log.info { "startup_time: #{startup_time}" }
Log.info { "adjusted_with_default: #{adjusted_with_default}" }
if startup_time < adjusted_with_default
startup_time = adjusted_with_default
end
end
end
# Correlation for a slow box vs a fast box
# sysbench base fast machine (disk), time in ms 0.16
# sysbench base slow machine (disk), time in ms 6.55
Expand Down Expand Up @@ -162,9 +212,9 @@ task "reasonable_startup_time" do |t, args|
# LOGGING.info "startup_time_limit TEST mode: #{startup_time_limit}"
# end
Log.info { "startup_time_limit: #{startup_time_limit}" }
Log.info { "startup_time: #{startup_time.to_i}" }
Log.info { "startup_time: #{startup_time}" }

if startup_time.to_i <= startup_time_limit
if startup_time <= startup_time_limit
CNFManager::TestcaseResult.new(CNFManager::ResultStatus::Passed, "CNF had a reasonable startup time 🚀")
else
CNFManager::TestcaseResult.new(CNFManager::ResultStatus::Failed, "CNF had a startup time of #{startup_time} seconds 🐢")
Expand Down
1 change: 0 additions & 1 deletion src/templates/elapsed_time_configmap.yml.ecr
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@ metadata:
immutable: true
<% end %>
data:
startup_time: '<%= @elapsed_time %>'
helm_used: '<%= @helm_used %>'
tracing_used: '<%= @tracing_used %>'
e2_found: '<%= @e2_found %>'

0 comments on commit 5084133

Please sign in to comment.