98 lines
		
	
	
		
			2.1 KiB
		
	
	
	
		
			Ruby
		
	
	
	
			
		
		
	
	
			98 lines
		
	
	
		
			2.1 KiB
		
	
	
	
		
			Ruby
		
	
	
	
| # frozen_string_literal: true
 | |
| 
 | |
| # rubocop:disable Rails/ApplicationController
 | |
| class ChaosController < ActionController::Base
 | |
|   before_action :validate_chaos_secret, unless: :development_or_test?
 | |
| 
 | |
|   def leakmem
 | |
|     do_chaos :leak_mem, Chaos::LeakMemWorker, memory_mb, duration_s
 | |
|   end
 | |
| 
 | |
|   def cpu_spin
 | |
|     do_chaos :cpu_spin, Chaos::CpuSpinWorker, duration_s
 | |
|   end
 | |
| 
 | |
|   def db_spin
 | |
|     do_chaos :db_spin, Chaos::DbSpinWorker, duration_s, interval_s
 | |
|   end
 | |
| 
 | |
|   def sleep
 | |
|     do_chaos :sleep, Chaos::SleepWorker, duration_s
 | |
|   end
 | |
| 
 | |
|   def kill
 | |
|     do_chaos :kill, Chaos::KillWorker, 'KILL'
 | |
|   end
 | |
| 
 | |
|   def quit
 | |
|     do_chaos :kill, Chaos::KillWorker, 'QUIT'
 | |
|   end
 | |
| 
 | |
|   def gc
 | |
|     gc_stat = Gitlab::Chaos.run_gc
 | |
| 
 | |
|     render json: {
 | |
|       worker_id: ::Prometheus::PidProvider.worker_id,
 | |
|       gc_stat: gc_stat
 | |
|     }
 | |
|   end
 | |
| 
 | |
|   private
 | |
| 
 | |
|   def do_chaos(method, worker, *args)
 | |
|     if async
 | |
|       worker.perform_async(*args)
 | |
|     else
 | |
|       Gitlab::Chaos.public_send(method, *args) # rubocop: disable GitlabSecurity/PublicSend
 | |
|     end
 | |
| 
 | |
|     render plain: "OK"
 | |
|   end
 | |
| 
 | |
|   def validate_chaos_secret
 | |
|     unless chaos_secret_configured
 | |
|       render plain: "chaos misconfigured: please configure GITLAB_CHAOS_SECRET",
 | |
|              status: :internal_server_error
 | |
|       return
 | |
|     end
 | |
| 
 | |
|     unless Devise.secure_compare(chaos_secret_configured, chaos_secret_request)
 | |
|       render plain: "To experience chaos, please set a valid `X-Chaos-Secret` header or `token` param",
 | |
|              status: :unauthorized
 | |
|     end
 | |
|   end
 | |
| 
 | |
|   def chaos_secret_configured
 | |
|     ENV['GITLAB_CHAOS_SECRET']
 | |
|   end
 | |
| 
 | |
|   def chaos_secret_request
 | |
|     request.headers["HTTP_X_CHAOS_SECRET"] || params[:token]
 | |
|   end
 | |
| 
 | |
|   def interval_s
 | |
|     interval_s = params[:interval_s] || 1
 | |
|     interval_s.to_f.seconds
 | |
|   end
 | |
| 
 | |
|   def duration_s
 | |
|     duration_s = params[:duration_s] || 30
 | |
|     duration_s.to_i.seconds
 | |
|   end
 | |
| 
 | |
|   def memory_mb
 | |
|     memory_mb = params[:memory_mb] || 100
 | |
|     memory_mb.to_i
 | |
|   end
 | |
| 
 | |
|   def async
 | |
|     async = params[:async] || false
 | |
|     Gitlab::Utils.to_boolean(async)
 | |
|   end
 | |
| 
 | |
|   def development_or_test?
 | |
|     Rails.env.development? || Rails.env.test?
 | |
|   end
 | |
| end
 | |
| # rubocop:enable Rails/ApplicationController
 |