diff --git a/devops-client/lib/devops-client/handler/image.rb b/devops-client/lib/devops-client/handler/image.rb index 0238f80..800da6e 100644 --- a/devops-client/lib/devops-client/handler/image.rb +++ b/devops-client/lib/devops-client/handler/image.rb @@ -47,7 +47,9 @@ class Image < Handler def get_templates bt = BootstrapTemplates.new(@host, self.options) bt.auth = self.auth - return bt.list_handler(["templates", "list"]), bt.table + list = bt.list_handler(["templates", "list"]) + return list, nil if list.empty? + return list, bt.table end def create_handler @@ -74,11 +76,16 @@ class Image < Handler q["bootstrap_template"] = if options[:bootstrap_template].nil? and options[:no_bootstrap_template] == false bt, bt_t = get_templates - i = choose_number_from_list(I18n.t("handler.image.create.template"), bt, bt_t, -1) - if i == -1 + if bt.empty? + puts I18n.t("handler.image.create.template_empty") nil else - bt[i] + i = choose_number_from_list(I18n.t("handler.image.create.template"), bt, bt_t, -1) + if i == -1 + nil + else + bt[i] + end end else nil diff --git a/devops-client/lib/devops-client/version.rb b/devops-client/lib/devops-client/version.rb index c68adb3..2759c4b 100644 --- a/devops-client/lib/devops-client/version.rb +++ b/devops-client/lib/devops-client/version.rb @@ -1,3 +1,3 @@ module DevopsClient - VERSION = "2.1.33" + VERSION = "2.1.34" end diff --git a/devops-client/locales/en.yml b/devops-client/locales/en.yml index 4850142..d1ce9e7 100644 --- a/devops-client/locales/en.yml +++ b/devops-client/locales/en.yml @@ -53,6 +53,7 @@ en: create: ssh_user: "The ssh username" template: "Bootstrap template or empty value" + template_empty: "No bootatrap template found, it will be used default template" filter: question: delete: "Are you sure to delete image filter(s) '%{name}'?" diff --git a/devops-client/locales/ru.yml b/devops-client/locales/ru.yml index ab6ef60..0d25af7 100644 --- a/devops-client/locales/ru.yml +++ b/devops-client/locales/ru.yml @@ -51,6 +51,7 @@ ru: create: ssh_user: "Имя пользоватлея ssh" template: "Шаблон загрузки или пустое значение" + template_empty: "Нет ни одного шаблона загрузки, будет использован шаблон по умолчанию" filter: question: delete: "Вы уверены, что хотите удалить фильтр(ы) образа '%{name}'?" diff --git a/devops-service/Gemfile b/devops-service/Gemfile index 44a471e..47bd822 100644 --- a/devops-service/Gemfile +++ b/devops-service/Gemfile @@ -1,6 +1,6 @@ source 'https://rubygems.org' -ruby "~>2" +ruby "2.0.0" gem "thin", "~>1.5.1" gem "mime-types", "~>1.25.1" @@ -12,6 +12,6 @@ gem "mixlib-shellout" gem "chef", ">=11" gem "mongo" gem "bson_ext" -gem "multi_json" +gem "multi_json", "1.7.8" gem "rufus-scheduler", "2.0.24" gem "sidekiq", "3.2.6" diff --git a/devops-service/commands/knife_commands.rb b/devops-service/commands/knife_commands.rb index ffd03e7..5504a61 100644 --- a/devops-service/commands/knife_commands.rb +++ b/devops-service/commands/knife_commands.rb @@ -91,6 +91,30 @@ EOH return lline end + def self.knife_bootstrap out, ip, options + knife_stream(out, "bootstrap", options + [ ip ]) + end + + def self.knife_stream out, cmd, options=[] + knife_cmd = "knife #{cmd} #{options.join(" ")}" + out << "\nExecuting '#{knife_cmd}' \n\n" + out.flush if out.respond_to?(:flush) + status = nil + IO.popen(knife_cmd + " 2>&1") do |o| + while line = o.gets do + out << line + out.flush if out.respond_to?(:flush) + end + o.close + status = $?.to_i + end + return status + end + + def self.set_run_list node, list + knife("node run_list set #{node} '#{list.join("','")}'") + end + private def self.get_config File.join(ENV["HOME"], ".chef", "knife.rb") diff --git a/devops-service/commands/server.rb b/devops-service/commands/server.rb index b09a12e..a742dc6 100644 --- a/devops-service/commands/server.rb +++ b/devops-service/commands/server.rb @@ -1,8 +1,34 @@ require "commands/knife_commands" +require "commands/deploy" require "db/exceptions/record_not_found" module ServerCommands + include DeployCommands + + def create_server_proc + lambda do |out, s, provider, mongo| + begin + out << "Create server...\n" + out.flush if out.respond_to?(:flush) + unless provider.create_server(s, out) + return 3 + end + mongo.server_insert s + out.flush if out.respond_to?(:flush) + logger.info "Server with parameters: #{s.to_hash.inspect} is running" + key = mongo.key(s.key) + s.chef_node_name = provider.create_default_chef_node_name(s) if s.chef_node_name.nil? + return two_phase_bootstrap(s, out, provider, mongo, key.path, logger) + rescue IOError => e + logger.error e.message + logger.warn roll_back(s, provider) + mongo.server_delete s.id + return 5 + end + end + end + def create_server_proc lambda do |out, s, provider, mongo| begin @@ -64,6 +90,45 @@ module ServerCommands end end + def two_phase_bootstrap s, out, provider, mongo, cert_path, logger + out << "\n\nBootstrap..." + out.flush if out.respond_to?(:flush) + run_list = s.options[:run_list] + s.options[:run_list] = provider.run_list + out << "\nBootstrap with provider run list: #{s.options[:run_list].inspect}" + status = bootstrap(s, out, cert_path, logger) + out.flush if out.respond_to?(:flush) + if status == 0 + mongo.server_set_chef_node_name s + logger.info "Server with id '#{s.id}' is bootstraped" + if check_server(s) + out << "Server #{s.chef_node_name} is created" + else + out << roll_back(s, provider) + mongo.server_delete s.id + return 5 + end + out << "\n" + out.flush if out.respond_to?(:flush) + + out << "\nAdd project run list: #{run_list.inspect}" + s.options[:run_list] += run_list + KnifeCommands.set_run_list(s.chef_node_name, s.options[:run_list]) + status = deploy_server(out, s, cert_path) + if status != 0 + msg = "Failed on chef-client with project run list, server with id '#{s.id}'" + logger.error msg + out << "\n" + msg + "\n" + end + else + msg = "Failed while bootstraping server with id '#{s.id}'" + logger.error msg + out << "\n" + msg + "\n" + out << roll_back(s, provider) + mongo.server_delete s.id + end + return status + end def extract_servers provider, project, env, params, user, mongo flavors = provider.flavors diff --git a/devops-service/config.ru b/devops-service/config.ru index d21d008..150f5b9 100644 --- a/devops-service/config.ru +++ b/devops-service/config.ru @@ -40,5 +40,5 @@ run Rack::URLMap.new({ "#{config[:url_prefix]}/client" => Client.new(config), "#{config[:url_prefix]}/v2.0/report" => Report.new(config, "v2"), "#{config[:url_prefix]}/sidekiq" => Sidekiq::Web, - "#{config[:url_prefix]}/version" => "hello" + "#{config[:url_prefix]}/version" => DevopsVersion.new }) diff --git a/devops-service/devops-service.rb b/devops-service/devops-service.rb index 2432053..fd6f02f 100644 --- a/devops-service/devops-service.rb +++ b/devops-service/devops-service.rb @@ -29,6 +29,7 @@ class DevopsService < Sinatra::Base [:keys_dir, :scripts_dir].each {|key| d = @@config[key]; FileUtils.mkdir_p(d) unless File.exists?(d) } mongo = DevopsService.mongo mongo.create_root_user + ::Provider::ProviderFactory.init(config) ::Provider::ProviderFactory.all.each do |p| next if p.certificate_path.nil? begin diff --git a/devops-service/providers/base_provider.rb b/devops-service/providers/base_provider.rb index f60e5f2..77deb86 100644 --- a/devops-service/providers/base_provider.rb +++ b/devops-service/providers/base_provider.rb @@ -3,7 +3,7 @@ require "fog" module Provider class BaseProvider - attr_accessor :ssh_key, :certificate_path, :connection_options + attr_accessor :ssh_key, :certificate_path, :connection_options, :run_list protected def connection_compute options diff --git a/devops-service/providers/ec2.rb b/devops-service/providers/ec2.rb index 96dba38..17464bb 100644 --- a/devops-service/providers/ec2.rb +++ b/devops-service/providers/ec2.rb @@ -17,6 +17,7 @@ module Provider :aws_secret_access_key => config[:aws_secret_access_key] } self.availability_zone = config[:aws_availability_zone] || "us-east-1a" + self.run_list = config[:aws_integration_run_list] || [] end def configured? @@ -189,6 +190,7 @@ module Provider def convert_groups list res = {} list.each do |g| + next if g["groupName"].nil? res[g["groupName"]] = { "description" => g["groupDescription"], "id" => g["groupId"] diff --git a/devops-service/providers/openstack.rb b/devops-service/providers/openstack.rb index 9a27102..32b58b0 100644 --- a/devops-service/providers/openstack.rb +++ b/devops-service/providers/openstack.rb @@ -16,6 +16,7 @@ module Provider :openstack_auth_url => config[:openstack_auth_url], :openstack_tenant => config[:openstack_tenant] } + self.run_list = config[:openstack_integration_run_list] || [] end # Returns 'true' if all parameters defined diff --git a/devops-service/providers/provider_factory.rb b/devops-service/providers/provider_factory.rb index aec7cce..59bff68 100644 --- a/devops-service/providers/provider_factory.rb +++ b/devops-service/providers/provider_factory.rb @@ -24,10 +24,15 @@ module Provider begin require "providers/#{p}" o = Provider.const_get(p.capitalize).new(conf) - @@providers[p] = o if o.configured? + if o.configured? + @@providers[p] = o + puts "Provider '#{p}' has been loaded" + end rescue => e + puts "Error while loading provider '#{p}': " + e.message next - rescue LoadError + rescue LoadError => e + puts "Can not load provider '#{p}': " + e.message next end end