From 8d01ff77b98cb3380a34d8a495edb4c34bd40139 Mon Sep 17 00:00:00 2001 From: Anton Chuchkalov Date: Tue, 2 Feb 2016 14:34:17 +0700 Subject: [PATCH 1/3] rename delete_server_worker to delete_expired_server_worker --- devops-service/db/mongo/models/report.rb | 1 + devops-service/lib/executors/expiration_scheduler.rb | 4 ++-- devops-service/spec/executors/expiration_scheduler_spec.rb | 4 ++-- devops-service/spec/executors/server_executor_spec.rb | 6 +++--- ...ete_server_worker.rb => delete_expired_server_worker.rb} | 6 +++--- 5 files changed, 11 insertions(+), 10 deletions(-) rename devops-service/workers/{delete_server_worker.rb => delete_expired_server_worker.rb} (83%) diff --git a/devops-service/db/mongo/models/report.rb b/devops-service/db/mongo/models/report.rb index c557b22..e0d03db 100644 --- a/devops-service/db/mongo/models/report.rb +++ b/devops-service/db/mongo/models/report.rb @@ -11,6 +11,7 @@ module Devops STACK_TYPE = 5 DEPLOY_STACK_TYPE = 6 DELETE_SERVER_TYPE = 7 + EXPIRE_SERVER_TYPE = 8 attr_accessor :id, :file, :updated_at, :created_by, :project, :deploy_env, :type, :chef_node_name, :host, :status, :stack, :subreports, :job_result_code diff --git a/devops-service/lib/executors/expiration_scheduler.rb b/devops-service/lib/executors/expiration_scheduler.rb index 5eee52f..d84702d 100644 --- a/devops-service/lib/executors/expiration_scheduler.rb +++ b/devops-service/lib/executors/expiration_scheduler.rb @@ -1,4 +1,4 @@ -require "workers/delete_server_worker" +require "workers/delete_expired_server_worker" module Devops module Executor @@ -9,7 +9,7 @@ module Devops def schedule_expiration! return unless @expires - DeleteServerWorker.perform_in(interval_in_seconds, server_chef_node_name: @server.chef_node_name) + DeleteExpiredServerWorker.perform_in(interval_in_seconds, server_chef_node_name: @server.chef_node_name) end def interval_in_seconds diff --git a/devops-service/spec/executors/expiration_scheduler_spec.rb b/devops-service/spec/executors/expiration_scheduler_spec.rb index 6964e5d..f8009f8 100644 --- a/devops-service/spec/executors/expiration_scheduler_spec.rb +++ b/devops-service/spec/executors/expiration_scheduler_spec.rb @@ -5,12 +5,12 @@ RSpec.describe Devops::Executor::ExpirationScheduler do describe '#schedule_expiration!' do it 'schedules server deleting at given time' do - expect(DeleteServerWorker).to receive(:perform_in).with(120, server_chef_node_name: 'chef_node_name') + expect(DeleteExpiredServerWorker).to receive(:perform_in).with(120, server_chef_node_name: 'chef_node_name') described_class.new('2m', server).schedule_expiration! end it "doesn't schedule job if expires is nil" do - expect(DeleteServerWorker).not_to receive(:perform_in) + expect(DeleteExpiredServerWorker).not_to receive(:perform_in) described_class.new(nil, server).schedule_expiration! end end diff --git a/devops-service/spec/executors/server_executor_spec.rb b/devops-service/spec/executors/server_executor_spec.rb index de70722..142f193 100644 --- a/devops-service/spec/executors/server_executor_spec.rb +++ b/devops-service/spec/executors/server_executor_spec.rb @@ -139,14 +139,14 @@ RSpec.describe Devops::Executor::ServerExecutor, type: :executor, stubbed_connec it 'schedules expiration for server' do deploy_env.expires = '2m' - allow(DeleteServerWorker).to receive(:perform_in) - expect(DeleteServerWorker).to receive(:perform_in).with(120, {server_chef_node_name: 'node_name'}) + allow(DeleteExpiredServerWorker).to receive(:perform_in) + expect(DeleteExpiredServerWorker).to receive(:perform_in).with(120, {server_chef_node_name: 'node_name'}) create_server end it "doesn't schedule expiration if deploy_env.expires is nil" do deploy_env.expires = nil - expect(DeleteServerWorker).not_to receive(:perform_in) + expect(DeleteExpiredServerWorker).not_to receive(:perform_in) create_server end diff --git a/devops-service/workers/delete_server_worker.rb b/devops-service/workers/delete_expired_server_worker.rb similarity index 83% rename from devops-service/workers/delete_server_worker.rb rename to devops-service/workers/delete_expired_server_worker.rb index c4e02eb..a749e73 100644 --- a/devops-service/workers/delete_server_worker.rb +++ b/devops-service/workers/delete_expired_server_worker.rb @@ -3,13 +3,13 @@ require "db/mongo/models/report" require "lib/executors/server_executor" require "workers/worker" -class DeleteServerWorker < Worker +class DeleteExpiredServerWorker < Worker def perform(options) chef_node_name = options.fetch('server_chef_node_name') - puts "Expire server '#{chef_node_name}'." call() do |out, file| + out.puts "Expire server '#{chef_node_name}'." server = mongo.server_by_chef_node_name(chef_node_name) report = save_report(file, server) @@ -28,7 +28,7 @@ class DeleteServerWorker < Worker "created_by" => 'SYSTEM', "project" => server.project, "deploy_env" => server.deploy_env, - "type" => Devops::Model::Report::DELETE_SERVER_TYPE + "type" => Devops::Model::Report::EXPIRE_SERVER_TYPE ) mongo.save_report(report) report From 775c9758cae801fa3f4a3fa140da0e49dadb8495 Mon Sep 17 00:00:00 2001 From: Anton Chuchkalov Date: Tue, 2 Feb 2016 15:43:13 +0700 Subject: [PATCH 2/3] move servers deleting to background --- .../lib/devops-client/handler/server.rb | 5 +-- .../devops-client/options/server_options.rb | 2 +- .../lib/devops-client/output/project.rb | 10 ++--- devops-service/app/api2/handlers/project.rb | 13 ++----- devops-service/app/api2/handlers/server.rb | 9 +++-- devops-service/app/api2/routes/server.rb | 3 +- .../lib/executors/server_executor.rb | 29 ++++++++------ .../spec/executors/server_executor_spec.rb | 10 ++--- .../workers/delete_server_worker.rb | 39 +++++++++++++++++++ devops-service/workers/run_workers.rb | 2 + 10 files changed, 78 insertions(+), 44 deletions(-) create mode 100644 devops-service/workers/delete_server_worker.rb diff --git a/devops-client/lib/devops-client/handler/server.rb b/devops-client/lib/devops-client/handler/server.rb index 1d85e02..55fbdcf 100644 --- a/devops-client/lib/devops-client/handler/server.rb +++ b/devops-client/lib/devops-client/handler/server.rb @@ -87,10 +87,7 @@ class Server < Handler end if question(I18n.t("handler.server.question.delete", :name => name)) puts "Server '#{name}', deleting..." - o = delete("/server/#{name}", options) - ["server", "chef_node", "chef_client", "message"].each do |k| - puts o[k] unless o[k].nil? - end + puts delete("/server/#{name}", options) end end "" diff --git a/devops-client/lib/devops-client/options/server_options.rb b/devops-client/lib/devops-client/options/server_options.rb index 7a44bc0..662db24 100644 --- a/devops-client/lib/devops-client/options/server_options.rb +++ b/devops-client/lib/devops-client/options/server_options.rb @@ -126,7 +126,7 @@ class ServerOptions < CommonOptions options[:groups] = groups.split(",") end - parser.recognize_option_value(:private_ip, 'server', short: '-N', i18n_scope: 'create') + parser.recognize_option_value(:private_ip, short: '-N', i18n_scope: 'create') # it was disabled somewhy # parser.on('--public-ip', "Associate public IP with server") do diff --git a/devops-client/lib/devops-client/output/project.rb b/devops-client/lib/devops-client/output/project.rb index b137aad..c080e45 100644 --- a/devops-client/lib/devops-client/output/project.rb +++ b/devops-client/lib/devops-client/output/project.rb @@ -154,17 +154,13 @@ module Output def delete_servers_output output = '' - if @data['deleted'].empty? + if @data['reports'].empty? output << 'There are no deleted servers.' else - output << "Deleted servers:\n----\n" - output << @data['deleted'].join("\n") + output << "Reports for servers deleting:\n----\n" + output << @data['reports'].join("\n") end - if !@data['failed'].empty? - output << "\nThere were errors during deleting these servers:\n----\n" - output << @data['failed'].join("\n") - end output end diff --git a/devops-service/app/api2/handlers/project.rb b/devops-service/app/api2/handlers/project.rb index 3e36bb9..7193e8b 100644 --- a/devops-service/app/api2/handlers/project.rb +++ b/devops-service/app/api2/handlers/project.rb @@ -4,6 +4,7 @@ require "workers/project_test_worker" require "app/api2/parsers/project" require "lib/project/type/types_factory" require "lib/executors/server_executor" +require "workers/delete_server_worker" require_relative "../helpers/version_2.rb" require_relative "request_handler" @@ -314,16 +315,10 @@ module Devops private def delete_chosen_servers!(servers) - deleted, failed = [], [] - servers.each do |server| - begin - Devops::Executor::ServerExecutor.new(server, '').delete_server - deleted << server.id - rescue - failed << server.id - end + reports = servers.map do |server| + Worker.start_async(DeleteServerWorker, 'server_id' => server.id) end - {deleted: deleted, failed: failed} + {reports: reports} end end diff --git a/devops-service/app/api2/handlers/server.rb b/devops-service/app/api2/handlers/server.rb index 6b35d72..f6a462c 100644 --- a/devops-service/app/api2/handlers/server.rb +++ b/devops-service/app/api2/handlers/server.rb @@ -10,6 +10,7 @@ require "db/mongo/models/server" require "workers/create_server_worker" require "workers/bootstrap_worker" +require "workers/delete_server_worker" require "app/api2/parsers/server" require_relative "request_handler" @@ -47,10 +48,10 @@ module Devops end def delete id - s = get_server_by_key(id, parser.instance_key) - ### Authorization - Devops::Db.connector.check_project_auth s.project, s.deploy_env, parser.current_user - Devops::Executor::ServerExecutor.new(s, "").delete_server + server = get_server_by_key(id, parser.instance_key) + Devops::Db.connector.check_project_auth server.project, server.deploy_env, parser.current_user + jid = Worker.start_async(DeleteServerWorker, 'server_id' => id) + [jid] end def create_server_stream out diff --git a/devops-service/app/api2/routes/server.rb b/devops-service/app/api2/routes/server.rb index 69bd54e..b411fbc 100644 --- a/devops-service/app/api2/routes/server.rb +++ b/devops-service/app/api2/routes/server.rb @@ -127,8 +127,7 @@ module Devops # 200 - Deleted hash["DELETE"] = lambda {|id| check_privileges("server", "w") - info, r = Devops::API2_0::Handler::Server.new(request).delete(id) - create_response(info, r) + json Devops::API2_0::Handler::Server.new(request).delete(id) } app.multi_routes "/server/:id", {:headers => [:accept, :content_type]}, hash diff --git a/devops-service/lib/executors/server_executor.rb b/devops-service/lib/executors/server_executor.rb index a8aebc6..e861220 100644 --- a/devops-service/lib/executors/server_executor.rb +++ b/devops-service/lib/executors/server_executor.rb @@ -432,23 +432,25 @@ module Devops unbootstrap end mongo.server_delete @server.id - msg = "Static server '#{@server.id}' is removed" - DevopsLogger.logger.info msg - return msg, nil + puts_and_flush "Static server '#{@server.id}' is removed" + return 0 end - r = delete_from_chef_server(@server.chef_node_name) + + puts_and_flush "Deleting from chef server:" + delete_from_chef_server(@server.chef_node_name).each do |key, result| + @out.puts "#{key} - #{result}" + end + + puts_and_flush "Deleting from cloud:" provider = @server.provider_instance begin - r[:server] = provider.delete_server @server + puts_and_flush provider.delete_server @server rescue Fog::Compute::OpenStack::NotFound, Fog::Compute::AWS::NotFound - r[:server] = "Server with id '#{@server.id}' not found in '#{provider.name}' servers" - DevopsLogger.logger.warn r[:server] + puts_and_flush "Server with id '#{@server.id}' not found among '#{provider.name}' servers" end mongo.server_delete @server.id - info = "Server '#{@server.id}' with name '#{@server.chef_node_name}' for project '#{@server.project}-#{@server.deploy_env}' is removed" - DevopsLogger.logger.info info - r.each{|key, log| DevopsLogger.logger.info("#{key} - #{log}")} - return info, r + puts_and_flush "Server '#{@server.id}' with name '#{@server.chef_node_name}' for project '#{@server.project}-#{@server.deploy_env}' is removed." + 0 end def roll_back @@ -493,6 +495,11 @@ module Devops private + def puts_and_flush(message) + @out.puts message + @out.flush + end + def schedule_expiration if @deploy_env.expires @out << "Planning expiration in #{@deploy_env.expires}" diff --git a/devops-service/spec/executors/server_executor_spec.rb b/devops-service/spec/executors/server_executor_spec.rb index 142f193..bc19b58 100644 --- a/devops-service/spec/executors/server_executor_spec.rb +++ b/devops-service/spec/executors/server_executor_spec.rb @@ -660,9 +660,8 @@ RSpec.describe Devops::Executor::ServerExecutor, type: :executor, stubbed_connec delete_server end - it 'returns message and nil' do - expect(delete_server.first).to be_a(String) - expect(delete_server.last).to be nil + it 'returns 0' do + expect(delete_server).to eq 0 end it "doesn't try to remove it from cloud" do @@ -707,9 +706,8 @@ RSpec.describe Devops::Executor::ServerExecutor, type: :executor, stubbed_connec delete_server end - it 'returns message and hash with :chef_node, :chef_client and :server keys' do - expect(delete_server.first).to be_a(String) - expect(delete_server.last).to be_a(Hash).and include(:chef_client, :chef_node, :server) + it 'returns 0' do + expect(delete_server).to eq 0 end end end diff --git a/devops-service/workers/delete_server_worker.rb b/devops-service/workers/delete_server_worker.rb new file mode 100644 index 0000000..4354e16 --- /dev/null +++ b/devops-service/workers/delete_server_worker.rb @@ -0,0 +1,39 @@ +require "db/mongo/models/server" +require "db/mongo/models/report" +require "lib/executors/server_executor" +require "workers/worker" +require 'byebug' + +class DeleteServerWorker < Worker + + # options should contain 'server_id' + def perform(options) + server_id = options.fetch('server_id') + + call() do |out, file| + out.puts "Deleting server with id #{server_id}" and out.flush + @server = mongo.server_by_instance_id(server_id) + report = save_report(file) + + e = Devops::Executor::ServerExecutor.new(@server, out) + e.report = report + e.delete_server + end + end + + private + + def save_report(file) + report = Devops::Model::Report.new( + "file" => file, + "_id" => jid, + "created_by" => 'SYSTEM', + "project" => @server.project, + "deploy_env" => @server.deploy_env, + "type" => Devops::Model::Report::DELETE_SERVER_TYPE + ) + mongo.save_report(report) + report + end + +end diff --git a/devops-service/workers/run_workers.rb b/devops-service/workers/run_workers.rb index 7dac55e..6e25e39 100644 --- a/devops-service/workers/run_workers.rb +++ b/devops-service/workers/run_workers.rb @@ -5,6 +5,8 @@ require File.join(root, "deploy_worker") require File.join(root, "bootstrap_worker") require File.join(root, "project_test_worker") require File.join(root, "stack_bootstrap_worker") +require File.join(root, "delete_server_worker") +require File.join(root, "delete_expired_server_worker") config = {} #require File.join(root, "../proxy") From 724349b5783e479093c25fcf7d181ac535603907 Mon Sep 17 00:00:00 2001 From: Anton Chuchkalov Date: Wed, 10 Feb 2016 17:05:35 +0300 Subject: [PATCH 3/3] fix deleting by node name; set owner properly --- devops-service/app/api2/handlers/project.rb | 3 ++- devops-service/app/api2/handlers/server.rb | 5 +++-- devops-service/workers/delete_server_worker.rb | 8 ++++---- 3 files changed, 9 insertions(+), 7 deletions(-) diff --git a/devops-service/app/api2/handlers/project.rb b/devops-service/app/api2/handlers/project.rb index 7193e8b..5f8f918 100644 --- a/devops-service/app/api2/handlers/project.rb +++ b/devops-service/app/api2/handlers/project.rb @@ -315,8 +315,9 @@ module Devops private def delete_chosen_servers!(servers) + current_user = parser.current_user reports = servers.map do |server| - Worker.start_async(DeleteServerWorker, 'server_id' => server.id) + Worker.start_async(DeleteServerWorker, 'server_id' => server.id, 'current_user' => current_user) end {reports: reports} end diff --git a/devops-service/app/api2/handlers/server.rb b/devops-service/app/api2/handlers/server.rb index f6a462c..aa77939 100644 --- a/devops-service/app/api2/handlers/server.rb +++ b/devops-service/app/api2/handlers/server.rb @@ -49,8 +49,9 @@ module Devops def delete id server = get_server_by_key(id, parser.instance_key) - Devops::Db.connector.check_project_auth server.project, server.deploy_env, parser.current_user - jid = Worker.start_async(DeleteServerWorker, 'server_id' => id) + current_user = parser.current_user + Devops::Db.connector.check_project_auth server.project, server.deploy_env, current_user + jid = Worker.start_async(DeleteServerWorker, 'server_id' => server.id, 'current_user' => current_user) [jid] end diff --git a/devops-service/workers/delete_server_worker.rb b/devops-service/workers/delete_server_worker.rb index 4354e16..77f3e5c 100644 --- a/devops-service/workers/delete_server_worker.rb +++ b/devops-service/workers/delete_server_worker.rb @@ -2,18 +2,18 @@ require "db/mongo/models/server" require "db/mongo/models/report" require "lib/executors/server_executor" require "workers/worker" -require 'byebug' class DeleteServerWorker < Worker # options should contain 'server_id' def perform(options) server_id = options.fetch('server_id') + current_user = options.fetch('current_user') call() do |out, file| out.puts "Deleting server with id #{server_id}" and out.flush @server = mongo.server_by_instance_id(server_id) - report = save_report(file) + report = save_report(file, current_user) e = Devops::Executor::ServerExecutor.new(@server, out) e.report = report @@ -23,11 +23,11 @@ class DeleteServerWorker < Worker private - def save_report(file) + def save_report(file, current_user) report = Devops::Model::Report.new( "file" => file, "_id" => jid, - "created_by" => 'SYSTEM', + "created_by" => current_user, "project" => @server.project, "deploy_env" => @server.deploy_env, "type" => Devops::Model::Report::DELETE_SERVER_TYPE