2015-08-12 09:41:19 +03:00
|
|
|
require "lib/knife/knife_factory"
|
2015-09-15 19:54:43 +03:00
|
|
|
require "workers/worker"
|
|
|
|
|
require "workers/delete_server_worker"
|
2015-08-12 11:37:17 +03:00
|
|
|
require "hooks"
|
2015-08-11 19:47:54 +03:00
|
|
|
|
|
|
|
|
module Devops
|
|
|
|
|
module Executor
|
|
|
|
|
class ServerExecutor
|
2015-08-12 11:37:17 +03:00
|
|
|
include Hooks
|
|
|
|
|
|
2015-09-22 15:07:56 +03:00
|
|
|
RESULT_CODES = {
|
|
|
|
|
server_bootstrap_fail: 2,
|
2015-09-25 17:31:10 +03:00
|
|
|
server_not_in_chef_nodes: 5,
|
|
|
|
|
server_bootstrap_unknown_error: 7,
|
|
|
|
|
deploy_unknown_error: 6,
|
|
|
|
|
deploy_failed: 8
|
2015-09-22 15:07:56 +03:00
|
|
|
}
|
|
|
|
|
|
2015-09-25 17:31:10 +03:00
|
|
|
MAX_SSH_RETRIES_AMOUNT = 20
|
|
|
|
|
|
2015-08-12 11:37:17 +03:00
|
|
|
#params:
|
|
|
|
|
# out - container for output data
|
|
|
|
|
# deploy_info - hash with deploy data
|
|
|
|
|
define_hook :before_deploy
|
|
|
|
|
define_hook :after_deploy
|
|
|
|
|
|
|
|
|
|
define_hook :before_create
|
|
|
|
|
define_hook :after_create
|
|
|
|
|
|
|
|
|
|
#params:
|
|
|
|
|
# out - container for output data
|
|
|
|
|
define_hook :before_bootstrap
|
|
|
|
|
define_hook :after_bootstrap
|
2015-08-11 19:47:54 +03:00
|
|
|
|
2015-08-21 15:17:42 +03:00
|
|
|
before_deploy :create_run_list
|
|
|
|
|
|
2015-08-11 19:47:54 +03:00
|
|
|
def initialize server, out
|
2015-08-12 11:37:17 +03:00
|
|
|
if server
|
|
|
|
|
@project = Devops::Db.connector.project(server.project)
|
|
|
|
|
@deploy_env = @project.deploy_env(server.deploy_env)
|
|
|
|
|
end
|
2015-08-11 19:47:54 +03:00
|
|
|
@knife_instance = KnifeFactory.instance
|
|
|
|
|
@server = server
|
|
|
|
|
@out = out
|
2015-08-12 12:24:48 +03:00
|
|
|
@out.class.send(:define_method, :flush) { } unless @out.respond_to?(:flush)
|
2015-08-11 19:47:54 +03:00
|
|
|
end
|
|
|
|
|
|
2015-09-22 15:07:56 +03:00
|
|
|
def self.result_code(symbolic_code)
|
|
|
|
|
RESULT_CODES.fetch(symbolic_code)
|
2015-09-21 15:54:33 +03:00
|
|
|
end
|
|
|
|
|
|
2015-09-22 15:07:56 +03:00
|
|
|
def self.symbolic_result_code(integer_code)
|
2015-09-25 17:31:10 +03:00
|
|
|
RESULT_CODES.key(integer_code) || :unknown_error
|
2015-09-21 15:54:33 +03:00
|
|
|
end
|
|
|
|
|
|
2015-09-22 15:07:56 +03:00
|
|
|
def result_code(symbolic_code)
|
|
|
|
|
self.class.result_code(symbolic_code)
|
2015-09-21 15:54:33 +03:00
|
|
|
end
|
|
|
|
|
|
2015-09-17 11:50:35 +03:00
|
|
|
def report= r
|
|
|
|
|
@report = r
|
|
|
|
|
end
|
|
|
|
|
|
2015-08-12 11:37:17 +03:00
|
|
|
def project= p
|
|
|
|
|
@project = p
|
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
def deploy_env= e
|
|
|
|
|
@deploy_env = e
|
|
|
|
|
end
|
|
|
|
|
|
2015-08-12 16:39:41 +03:00
|
|
|
def server
|
|
|
|
|
@server
|
|
|
|
|
end
|
|
|
|
|
|
2015-08-11 19:47:54 +03:00
|
|
|
def create_server options
|
2015-08-12 11:37:17 +03:00
|
|
|
@server = Devops::Model::Server.new({"project" => @project.id, "deploy_env" => @deploy_env.identifier, "created_by" => options["created_by"], "provider" => @deploy_env.provider})
|
2015-08-11 19:47:54 +03:00
|
|
|
provider = @server.provider_instance
|
|
|
|
|
mongo = ::Devops::Db.connector
|
|
|
|
|
begin
|
|
|
|
|
@out << "Create server...\n"
|
2015-08-12 12:24:48 +03:00
|
|
|
@out.flush
|
2015-08-11 19:47:54 +03:00
|
|
|
|
2015-08-12 11:37:17 +03:00
|
|
|
@server.run_list = options["run_list"] || []
|
|
|
|
|
@server.chef_node_name = options["name"]
|
|
|
|
|
@server.key = options["key"] || provider.ssh_key
|
2015-08-11 19:47:54 +03:00
|
|
|
|
|
|
|
|
i = mongo.image(@deploy_env.image)
|
|
|
|
|
@server.remote_user = i.remote_user
|
2015-08-12 11:37:17 +03:00
|
|
|
|
2015-08-11 19:47:54 +03:00
|
|
|
res = {}
|
2015-08-12 11:37:17 +03:00
|
|
|
@out << "\nBefore create hooks...\n"
|
2015-08-11 19:47:54 +03:00
|
|
|
res[:before] = self.run_hook :before_create
|
2015-08-12 16:39:41 +03:00
|
|
|
@out << "Done\n"
|
|
|
|
|
|
2015-08-11 19:47:54 +03:00
|
|
|
return false unless provider.create_server(@server, @deploy_env.image, @deploy_env.flavor, @deploy_env.subnets, @deploy_env.groups, @out)
|
|
|
|
|
mongo.server_insert @server
|
2015-08-12 16:39:41 +03:00
|
|
|
|
2015-08-12 11:37:17 +03:00
|
|
|
@out << "\nAfter create hooks...\n"
|
2015-08-11 19:47:54 +03:00
|
|
|
res[:after] = self.run_hook :after_create
|
2015-08-12 16:39:41 +03:00
|
|
|
@out << "Done\n"
|
2015-08-12 12:24:48 +03:00
|
|
|
@out.flush
|
2015-08-11 19:47:54 +03:00
|
|
|
DevopsLogger.logger.info "Server with parameters: #{@server.to_hash.inspect} is running"
|
2015-09-15 19:54:43 +03:00
|
|
|
|
|
|
|
|
schedule_expiration(@server)
|
|
|
|
|
|
2015-08-11 19:47:54 +03:00
|
|
|
unless options["without_bootstrap"]
|
|
|
|
|
bootstrap_options = {
|
|
|
|
|
bootstrap_template: i.bootstrap_template
|
|
|
|
|
}
|
2015-08-12 12:24:48 +03:00
|
|
|
return two_phase_bootstrap(bootstrap_options)
|
2015-08-11 19:47:54 +03:00
|
|
|
else
|
|
|
|
|
return 0
|
|
|
|
|
end
|
|
|
|
|
rescue => e
|
2015-08-31 16:49:49 +03:00
|
|
|
@out << e.message
|
2015-08-11 19:47:54 +03:00
|
|
|
DevopsLogger.logger.error e.message
|
|
|
|
|
roll_back
|
|
|
|
|
mongo.server_delete @server.id
|
2015-09-21 15:54:33 +03:00
|
|
|
# return 5
|
|
|
|
|
return result_code(:server_not_in_chef_nodes)
|
2015-08-11 19:47:54 +03:00
|
|
|
end
|
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
def bootstrap options
|
2015-08-12 12:24:48 +03:00
|
|
|
@out << "\n\nBootstrap...\n"
|
|
|
|
|
@out.flush
|
2015-08-11 19:47:54 +03:00
|
|
|
k = Devops::Db.connector.key(@server.key)
|
|
|
|
|
cert_path = k.path
|
2015-08-12 13:55:22 +03:00
|
|
|
options[:cert_path] = k.path
|
2015-08-12 11:37:17 +03:00
|
|
|
@out << "\nBefore bootstrap hooks...\n"
|
2015-08-11 19:47:54 +03:00
|
|
|
res = self.run_hook(:before_bootstrap, @out)
|
|
|
|
|
@out << "Done\n"
|
|
|
|
|
if @server.private_ip.nil?
|
|
|
|
|
@out << "Error: Private IP is null"
|
|
|
|
|
return false
|
|
|
|
|
end
|
|
|
|
|
ja = {
|
|
|
|
|
:provider => @server.provider,
|
|
|
|
|
:devops_host => `hostname`.strip
|
|
|
|
|
}
|
|
|
|
|
ip = @server.private_ip
|
|
|
|
|
unless @server.public_ip.nil?
|
|
|
|
|
ip = @server.public_ip
|
|
|
|
|
@out << "\nPublic IP is present\n"
|
|
|
|
|
end
|
2015-09-03 17:03:47 +03:00
|
|
|
|
|
|
|
|
address = "#{@server.remote_user}@#{ip}"
|
|
|
|
|
|
|
|
|
|
cmd = 'ssh '
|
|
|
|
|
cmd << "-i #{cert_path} "
|
|
|
|
|
cmd << '-q '
|
2015-09-21 15:54:33 +03:00
|
|
|
cmd << '-o StrictHostKeyChecking=no '
|
2015-09-03 17:03:47 +03:00
|
|
|
cmd << '-o ConnectTimeout=2 -o ConnectionAttempts=1 '
|
|
|
|
|
cmd << "#{address} 'exit'"
|
|
|
|
|
cmd << " 2>&1"
|
|
|
|
|
|
2015-08-11 19:47:54 +03:00
|
|
|
@out << "\nWaiting for SSH..."
|
2015-09-21 17:41:40 +03:00
|
|
|
@out << "\nTest command: '#{cmd}'\n"
|
2015-09-03 17:03:47 +03:00
|
|
|
@out.flush
|
|
|
|
|
|
|
|
|
|
retries_amount = 0
|
2015-08-11 19:47:54 +03:00
|
|
|
begin
|
|
|
|
|
sleep(5)
|
|
|
|
|
res = `#{cmd}`
|
2015-09-03 17:03:47 +03:00
|
|
|
retries_amount += 1
|
2015-09-25 17:31:10 +03:00
|
|
|
if retries_amount > MAX_SSH_RETRIES_AMOUNT
|
2015-09-21 15:54:33 +03:00
|
|
|
@out.puts "Can not connect to #{address}"
|
|
|
|
|
@out.puts res
|
|
|
|
|
@out.flush
|
2015-09-03 17:03:47 +03:00
|
|
|
DevopsLogger.logger.error "Can not connect with command '#{cmd}':\n#{res}"
|
2015-09-21 15:54:33 +03:00
|
|
|
return result_code(:server_bootstrap_fail)
|
2015-08-11 19:47:54 +03:00
|
|
|
end
|
|
|
|
|
raise ArgumentError.new("Can not connect with command '#{cmd}' ") unless $?.success?
|
|
|
|
|
rescue ArgumentError => e
|
2015-09-25 17:31:10 +03:00
|
|
|
@out.puts "SSH command failed, retry (#{retries_amount}/#{MAX_SSH_RETRIES_AMOUNT})"
|
2015-09-21 15:54:33 +03:00
|
|
|
@out.flush
|
2015-08-11 19:47:54 +03:00
|
|
|
retry
|
|
|
|
|
end
|
|
|
|
|
|
2015-08-25 16:07:29 +03:00
|
|
|
provider = @server.provider_instance
|
2015-08-21 15:17:42 +03:00
|
|
|
@server.chef_node_name = provider.create_default_chef_node_name(@server) if @server.chef_node_name.nil?
|
2015-09-25 17:31:10 +03:00
|
|
|
|
2015-08-12 13:43:37 +03:00
|
|
|
r = @knife_instance.knife_bootstrap(@out, ip, self.bootstrap_options(ja, options))
|
2015-09-21 20:57:07 +03:00
|
|
|
|
2015-08-11 19:47:54 +03:00
|
|
|
if r == 0
|
|
|
|
|
@out << "Chef node name: #{@server.chef_node_name}\n"
|
|
|
|
|
::Devops::Db.connector.server_set_chef_node_name @server
|
|
|
|
|
@out << "Chef node name has been updated\n"
|
|
|
|
|
@out << "After bootstrap hooks...\n"
|
|
|
|
|
res = self.run_hook(:after_bootstrap, @out)
|
|
|
|
|
@out << "Done\n"
|
2015-09-21 20:57:07 +03:00
|
|
|
@out.flush
|
2015-08-12 12:24:48 +03:00
|
|
|
DevopsLogger.logger.info "Server with id '#{@server.id}' is bootstraped"
|
2015-09-21 20:57:07 +03:00
|
|
|
r
|
2015-08-11 19:47:54 +03:00
|
|
|
else
|
2015-08-21 15:17:42 +03:00
|
|
|
@out << "Can not bootstrap node '#{@server.id}', error code: #{r}"
|
2015-09-21 20:57:07 +03:00
|
|
|
@out.flush
|
|
|
|
|
result_code(:server_bootstrap_fail)
|
2015-08-11 19:47:54 +03:00
|
|
|
end
|
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
def bootstrap_options attributes, options
|
|
|
|
|
bootstrap_options = [
|
|
|
|
|
"-x #{@server.remote_user}",
|
|
|
|
|
"-i #{options[:cert_path]}",
|
2015-08-20 21:55:44 +03:00
|
|
|
"--json-attributes '#{attributes.to_json}'"
|
2015-08-11 19:47:54 +03:00
|
|
|
]
|
2015-08-20 21:55:44 +03:00
|
|
|
bootstrap_options.push "-N #{@server.chef_node_name}" if @server.chef_node_name
|
2015-08-11 19:47:54 +03:00
|
|
|
bootstrap_options.push "--sudo" unless @server.remote_user == "root"
|
|
|
|
|
bootstrap_options.push "-t #{options[:bootstrap_template]}" if options[:bootstrap_template]
|
|
|
|
|
rl = options[:run_list]
|
|
|
|
|
bootstrap_options.push "-r #{rl.join(",")}" unless rl.nil?# rl.empty?
|
|
|
|
|
bootstrap_options.push "-c #{options[:config]}" if options[:config]
|
|
|
|
|
bootstrap_options
|
|
|
|
|
end
|
|
|
|
|
|
2015-10-23 14:54:56 +03:00
|
|
|
def prepare_two_phase_bootstrap options
|
2015-10-26 12:39:54 +03:00
|
|
|
@out << "Prepare bootstrap...\n"
|
|
|
|
|
@out << "Done\n"
|
2015-10-23 14:54:56 +03:00
|
|
|
end
|
|
|
|
|
|
2015-08-12 12:24:48 +03:00
|
|
|
def two_phase_bootstrap options
|
2015-10-23 14:54:56 +03:00
|
|
|
prepare_two_phase_bootstrap(options)
|
2015-09-25 17:31:10 +03:00
|
|
|
# bootstrap phase
|
|
|
|
|
begin
|
|
|
|
|
provider = @server.provider_instance
|
|
|
|
|
mongo = ::Devops::Db.connector
|
|
|
|
|
options[:run_list] = provider.run_list
|
|
|
|
|
bootstrap_status = bootstrap(options)
|
|
|
|
|
|
|
|
|
|
if bootstrap_status == 0
|
|
|
|
|
if check_server
|
|
|
|
|
@out << "Server #{@server.chef_node_name} is created"
|
|
|
|
|
else
|
|
|
|
|
@out << roll_back
|
|
|
|
|
@out.flush
|
|
|
|
|
mongo.server_delete @server.id
|
|
|
|
|
return result_code(:server_not_in_chef_nodes)
|
|
|
|
|
end
|
2015-08-12 12:24:48 +03:00
|
|
|
else
|
2015-09-25 17:31:10 +03:00
|
|
|
# @out << roll_back
|
|
|
|
|
# mongo.server_delete @server.id
|
|
|
|
|
msg = "Failed while bootstraping server with id '#{@server.id}'\n"
|
|
|
|
|
msg << "Bootstraping operation result was #{bootstrap_status}"
|
|
|
|
|
DevopsLogger.logger.error msg
|
|
|
|
|
@out.puts msg
|
|
|
|
|
@out.flush
|
|
|
|
|
return result_code(:server_bootstrap_fail)
|
2015-08-12 12:24:48 +03:00
|
|
|
end
|
2015-09-25 17:31:10 +03:00
|
|
|
rescue => e
|
|
|
|
|
@out << "\nError: #{e.message}\n"
|
2015-08-12 12:24:48 +03:00
|
|
|
@out.flush
|
2015-09-25 17:31:10 +03:00
|
|
|
return result_code(:server_bootstrap_unknown_error)
|
|
|
|
|
end
|
2015-08-12 12:24:48 +03:00
|
|
|
|
2015-09-25 17:31:10 +03:00
|
|
|
# deploy phase. Assume that all servers are bootstraped successfully here.
|
|
|
|
|
begin
|
2015-09-28 15:10:24 +03:00
|
|
|
#raise "hello"
|
2015-09-25 17:31:10 +03:00
|
|
|
@out << "\n"
|
2015-10-01 17:27:04 +03:00
|
|
|
run_list = compute_run_list
|
|
|
|
|
@out << "\nComputed run list: #{run_list.join(", ")}"
|
2015-09-25 17:31:10 +03:00
|
|
|
@out.flush
|
2015-10-01 17:27:04 +03:00
|
|
|
@knife_instance.set_run_list(@server.chef_node_name, run_list)
|
|
|
|
|
deploy_info = @project.deploy_info(@deploy_env)
|
|
|
|
|
deploy_status = deploy_server(deploy_info)
|
2015-09-25 17:31:10 +03:00
|
|
|
if deploy_status == 0
|
|
|
|
|
0
|
|
|
|
|
else
|
2015-08-21 15:17:42 +03:00
|
|
|
msg = "Failed on chef-client with run list, server with id '#{@server.id}'"
|
2015-09-25 17:31:10 +03:00
|
|
|
msg << "\nDeploing server operation status was #{deploy_status}"
|
2015-08-12 12:24:48 +03:00
|
|
|
DevopsLogger.logger.error msg
|
|
|
|
|
@out << "\n" + msg + "\n"
|
2015-09-25 17:31:10 +03:00
|
|
|
result_code(:deploy_failed)
|
2015-08-12 12:24:48 +03:00
|
|
|
end
|
2015-09-25 17:31:10 +03:00
|
|
|
rescue => e
|
|
|
|
|
@out << "\nError: #{e.message}\n"
|
|
|
|
|
result_code(:deploy_unknown_error)
|
2015-08-12 12:24:48 +03:00
|
|
|
end
|
|
|
|
|
end
|
|
|
|
|
|
2015-08-11 19:47:54 +03:00
|
|
|
def check_server
|
|
|
|
|
@knife_instance.chef_node_list.include?(@server.chef_node_name) and @knife_instance.chef_client_list.include?(@server.chef_node_name)
|
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
def unbootstrap
|
|
|
|
|
k = Devops::Db.connector.key(@server.key)
|
|
|
|
|
cert_path = k.path
|
|
|
|
|
i = 0
|
2015-10-22 15:39:27 +03:00
|
|
|
res = delete_from_chef_server(@server.chef_node_name)
|
|
|
|
|
begin
|
2015-10-22 13:56:16 +03:00
|
|
|
new_name = "/etc/chef.backup_#{Time.now.strftime("%d-%m-%Y_%H.%M.%S")}"
|
|
|
|
|
# r = `ssh -i #{cert_path} -q #{@server.remote_user}@#{@server.private_ip} rm -Rf /etc/chef`
|
2015-10-22 16:23:01 +03:00
|
|
|
cmd = "ssh -i #{cert_path} -q #{@server.remote_user}@#{@server.private_ip} \"/bin/sh -c 'if [[ -d /etc/chef ]]; then mv /etc/chef #{new_name}; else echo not found; fi'\""
|
2015-10-22 13:56:16 +03:00
|
|
|
DevopsLogger.logger.info("Trying to run command '#{cmd}'")
|
2015-10-22 16:52:31 +03:00
|
|
|
r = `#{cmd}`.strip
|
2015-10-22 15:39:27 +03:00
|
|
|
if r == 'not found'
|
|
|
|
|
res[:server] = "Directory '/etc/chef' does not exists"
|
|
|
|
|
else
|
|
|
|
|
raise(r) unless $?.success?
|
|
|
|
|
res[:server] = "'/etc/chef' renamed to '#{new_name}'"
|
|
|
|
|
end
|
2015-08-11 19:47:54 +03:00
|
|
|
rescue => e
|
|
|
|
|
DevopsLogger.logger.error "Unbootstrap error: " + e.message
|
|
|
|
|
i += 1
|
|
|
|
|
sleep(1)
|
|
|
|
|
retry unless i == 5
|
2015-10-22 13:56:16 +03:00
|
|
|
return {error: e.message}
|
2015-08-11 19:47:54 +03:00
|
|
|
end
|
2015-10-22 13:56:16 +03:00
|
|
|
res
|
2015-08-11 19:47:54 +03:00
|
|
|
end
|
|
|
|
|
|
|
|
|
|
def deploy_server_with_tags tags, deploy_info
|
|
|
|
|
old_tags_str = nil
|
|
|
|
|
new_tags_str = nil
|
|
|
|
|
unless tags.empty?
|
|
|
|
|
old_tags_str = @knife_instance.tags_list(@server.chef_node_name).join(" ")
|
|
|
|
|
@out << "Server tags: #{old_tags_str}\n"
|
|
|
|
|
@knife_instance.tags_delete(@server.chef_node_name, old_tags_str)
|
|
|
|
|
|
|
|
|
|
new_tags_str = tags.join(" ")
|
|
|
|
|
@out << "Server new tags: #{new_tags_str}\n"
|
|
|
|
|
cmd = @knife_instance.tags_create(@server.chef_node_name, new_tags_str)
|
|
|
|
|
unless cmd[1]
|
|
|
|
|
m = "Error: Cannot add tags '#{new_tags_str}' to server '#{@server.chef_node_name}'"
|
|
|
|
|
DevopsLogger.logger.error(m)
|
|
|
|
|
@out << m + "\n"
|
|
|
|
|
return 3
|
|
|
|
|
end
|
|
|
|
|
DevopsLogger.logger.info("Set tags for '#{@server.chef_node_name}': #{new_tags_str}")
|
|
|
|
|
end
|
|
|
|
|
|
2015-08-12 17:16:52 +03:00
|
|
|
r = deploy_server deploy_info
|
2015-08-11 19:47:54 +03:00
|
|
|
|
|
|
|
|
unless tags.empty?
|
|
|
|
|
@out << "Restore tags\n"
|
|
|
|
|
cmd = @knife_instance.tags_delete(@server.chef_node_name, new_tags_str)
|
|
|
|
|
DevopsLogger.logger.info("Deleted tags for #{@server.chef_node_name}: #{new_tags_str}")
|
|
|
|
|
cmd = @knife_instance.tags_create(@server.chef_node_name, old_tags_str)
|
|
|
|
|
DevopsLogger.logger.info("Set tags for #{@server.chef_node_name}: #{old_tags_str}")
|
|
|
|
|
end
|
|
|
|
|
return r
|
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
def deploy_server deploy_info
|
2015-08-12 14:19:52 +03:00
|
|
|
@out << "\nBefore deploy hooks...\n"
|
2015-08-11 19:47:54 +03:00
|
|
|
res = self.run_hook(:before_deploy, @out, deploy_info)
|
|
|
|
|
@out << "Done\n"
|
|
|
|
|
@out << "\nRun chef-client on '#{@server.chef_node_name}'\n"
|
|
|
|
|
cmd = "chef-client --no-color"
|
|
|
|
|
if deploy_info["use_json_file"]
|
2015-08-20 17:21:41 +03:00
|
|
|
deploy_info.delete("use_json_file")
|
2015-09-21 15:54:33 +03:00
|
|
|
@out << "Deploy Input Parameters:\n"
|
2015-08-11 19:47:54 +03:00
|
|
|
json = JSON.pretty_generate(deploy_info)
|
|
|
|
|
@out << json
|
|
|
|
|
@out << "\n"
|
|
|
|
|
file = "#{@server.project}_#{@server.deploy_env}_#{Time.new.to_i}"
|
|
|
|
|
dir = DevopsConfig.config[:project_info_dir]
|
|
|
|
|
File.open(File.join(dir, file), "w") do |f|
|
|
|
|
|
f.write json
|
|
|
|
|
end
|
2015-08-12 12:24:48 +03:00
|
|
|
@out.flush
|
2015-08-11 19:47:54 +03:00
|
|
|
cmd << " -j http://#{DevopsConfig.config[:address]}:#{DevopsConfig.config[:port]}/#{DevopsConfig.config[:url_prefix]}/v2.0/deploy/data/#{file}"
|
2015-09-30 17:05:52 +03:00
|
|
|
else
|
2015-10-01 17:27:04 +03:00
|
|
|
cmd << " -r #{deploy_info["run_list"].join(",")}" unless @server.stack.nil?
|
2015-08-11 19:47:54 +03:00
|
|
|
end
|
|
|
|
|
ip = if @server.public_ip.nil?
|
|
|
|
|
@server.private_ip
|
|
|
|
|
else
|
|
|
|
|
@out << "Public IP detected\n"
|
|
|
|
|
@server.public_ip
|
|
|
|
|
end
|
2015-08-12 12:24:48 +03:00
|
|
|
@out.flush
|
2015-08-11 19:47:54 +03:00
|
|
|
k = Devops::Db.connector.key(@server.key)
|
|
|
|
|
lline = @knife_instance.ssh_stream(@out, cmd, ip, @server.remote_user, k.path)
|
|
|
|
|
r = /Chef\sClient\sfinished/i
|
|
|
|
|
if lline[r].nil?
|
|
|
|
|
1
|
|
|
|
|
else
|
2015-08-12 14:19:52 +03:00
|
|
|
@out << "\nAfter deploy hooks...\n"
|
|
|
|
|
res = self.run_hook(:after_deploy, @out, deploy_info)
|
2015-08-11 19:47:54 +03:00
|
|
|
@out << "Done\n"
|
|
|
|
|
0
|
|
|
|
|
end
|
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
def delete_from_chef_server node_name
|
|
|
|
|
{
|
|
|
|
|
:chef_node => @knife_instance.chef_node_delete(node_name),
|
|
|
|
|
:chef_client => @knife_instance.chef_client_delete(node_name)
|
|
|
|
|
}
|
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
=begin
|
|
|
|
|
def delete_etc_chef s, cert_path
|
|
|
|
|
cmd = "ssh -i #{cert_path} -t -q #{s.remote_user}@#{s.private_ip}"
|
|
|
|
|
cmd += " sudo " unless s.remote_user == "root"
|
|
|
|
|
cmd += "rm -Rf /etc/chef"
|
|
|
|
|
r = `#{cmd}`
|
|
|
|
|
raise(r) unless $?.success?
|
|
|
|
|
end
|
|
|
|
|
=end
|
|
|
|
|
|
|
|
|
|
def delete_server
|
|
|
|
|
mongo = ::Devops::Db.connector
|
|
|
|
|
if @server.static?
|
|
|
|
|
if !@server.chef_node_name.nil?
|
|
|
|
|
unbootstrap
|
|
|
|
|
end
|
|
|
|
|
mongo.server_delete @server.id
|
|
|
|
|
msg = "Static server '#{@server.id}' is removed"
|
|
|
|
|
DevopsLogger.logger.info msg
|
|
|
|
|
return msg, nil
|
|
|
|
|
end
|
|
|
|
|
r = delete_from_chef_server(@server.chef_node_name)
|
|
|
|
|
provider = @server.provider_instance
|
|
|
|
|
begin
|
|
|
|
|
r[:server] = 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]
|
|
|
|
|
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
|
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
def roll_back
|
|
|
|
|
unless @server.id.nil?
|
|
|
|
|
@out << "Server '#{@server.chef_node_name}' with id '#{@server.id}' is not created\n"
|
|
|
|
|
@out << delete_from_chef_server(@server.chef_node_name).values.join("\n")
|
|
|
|
|
begin
|
|
|
|
|
@out << @server.provider_instance.delete_server(@server)
|
|
|
|
|
rescue => e
|
|
|
|
|
@out << e.message
|
|
|
|
|
end
|
|
|
|
|
@out << "\nRolled back\n"
|
|
|
|
|
end
|
|
|
|
|
end
|
|
|
|
|
|
2015-08-21 15:17:42 +03:00
|
|
|
def create_run_list out, deploy_info
|
|
|
|
|
out << "\nGenerate run list hook...\n"
|
2015-09-11 12:22:58 +03:00
|
|
|
if deploy_info["run_list"]
|
2015-09-30 17:05:52 +03:00
|
|
|
out << "Deploy info already contains 'run_list': #{deploy_info["run_list"].join(", ")}\n"
|
2015-09-11 12:22:58 +03:00
|
|
|
return
|
|
|
|
|
end
|
2015-08-21 15:17:42 +03:00
|
|
|
out << "Project run list: #{@project.run_list.join(", ")}\n"
|
|
|
|
|
out << "Deploy environment run list: #{@deploy_env.run_list.join(", ")}\n"
|
|
|
|
|
out << "Server run list: #{@server.run_list.join(", ")}\n"
|
2015-10-01 17:27:04 +03:00
|
|
|
=begin
|
2015-08-24 17:20:55 +03:00
|
|
|
rlist = Set.new.merge(@deploy_env.provider_instance.run_list).merge(@project.run_list).merge(@deploy_env.run_list).merge(@server.run_list)
|
2015-08-21 15:17:42 +03:00
|
|
|
if @server.stack
|
2015-08-27 14:29:19 +03:00
|
|
|
stack = Devops::Db.connector.stack(@server.stack)
|
2015-08-21 15:17:42 +03:00
|
|
|
out << "Stack run list: #{stack.run_list.join(", ")}\n"
|
|
|
|
|
rlist.merge(stack.run_list)
|
|
|
|
|
end
|
2015-10-01 17:27:04 +03:00
|
|
|
=end
|
|
|
|
|
deploy_info["run_list"] = compute_run_list
|
2015-08-21 15:17:42 +03:00
|
|
|
out << "New deploy run list: #{deploy_info["run_list"].join(", ")}\nRun list has been generated\n\n"
|
|
|
|
|
end
|
|
|
|
|
|
2015-10-01 17:27:04 +03:00
|
|
|
def compute_run_list
|
2015-10-01 22:41:35 +03:00
|
|
|
rlist = []
|
|
|
|
|
[@deploy_env.provider_instance.run_list, @project.run_list, @deploy_env.run_list, @server.run_list].each do |sub_run_list|
|
|
|
|
|
rlist += sub_run_list if sub_run_list.is_a?(Array)
|
|
|
|
|
end
|
|
|
|
|
rlist = Set.new(rlist)
|
2015-10-01 17:27:04 +03:00
|
|
|
if @server.stack
|
|
|
|
|
stack = Devops::Db.connector.stack(@server.stack)
|
2015-10-02 18:19:44 +03:00
|
|
|
# out << "Stack run list: #{stack.run_list.join(", ")}\n"
|
2015-10-01 22:41:35 +03:00
|
|
|
srl = stack.run_list
|
|
|
|
|
rlist.merge(srl) if srl.is_a?(Array)
|
2015-10-01 17:27:04 +03:00
|
|
|
end
|
|
|
|
|
rlist.to_a
|
|
|
|
|
end
|
|
|
|
|
|
2015-09-03 17:03:47 +03:00
|
|
|
private
|
|
|
|
|
|
2015-09-15 19:54:43 +03:00
|
|
|
def schedule_expiration(server)
|
|
|
|
|
expires = @deploy_env.expires
|
|
|
|
|
return unless expires
|
|
|
|
|
interval = interval_in_seconds(expires)
|
|
|
|
|
@out << "Planning expiration in #{expires}"
|
|
|
|
|
DeleteServerWorker.perform_in(interval, server_chef_node_name: server.chef_node_name)
|
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
def interval_in_seconds(interval_as_string)
|
|
|
|
|
interval = interval_as_string.to_i
|
|
|
|
|
measure_unit = interval_as_string.chars.last
|
|
|
|
|
case measure_unit
|
|
|
|
|
when 's'
|
|
|
|
|
interval
|
|
|
|
|
when 'm'
|
|
|
|
|
interval * 60
|
|
|
|
|
when 'h'
|
|
|
|
|
interval * 60 * 60
|
|
|
|
|
when 'd'
|
|
|
|
|
interval * 60 * 60 * 24
|
|
|
|
|
when 'w'
|
|
|
|
|
interval * 60 * 60 * 24 * 7
|
|
|
|
|
else
|
|
|
|
|
raise 'Wrong interval format'
|
|
|
|
|
end
|
|
|
|
|
end
|
|
|
|
|
|
2015-08-11 19:47:54 +03:00
|
|
|
end
|
|
|
|
|
end
|
|
|
|
|
end
|