lib/forj/process/ForjProcess.rb in forj-1.0.9 vs lib/forj/process/ForjProcess.rb in forj-1.0.10
- old
+ new
@@ -55,11 +55,11 @@
o_address = hParams.refresh[:public_ip, :ObjectData]
s_status = active_server?(server, o_address, boot_options[:keys],
boot_options[:coherent], s_status)
- till_server_active(s_status, server, o_address, boot_options)
+ till_server_active(s_status, hParams, o_address, boot_options)
o_forge = get_forge(sObjectType, config[:instance_name], hParams)
read_blueprint_implemented(o_forge, hParams)
o_forge
@@ -152,11 +152,11 @@
predef_keypair
end
def active_server?(o_server, o_address, private_key_file,
keypair_coherent, s_status
- )
+ )
if o_server[:attrs][:status] == :active
image = server_get_image o_server
s_msg = format('Your forj Maestro server is up and running and is '\
"publically accessible through IP '%s'.\n\n"\
@@ -189,14 +189,18 @@
end
s_status
end
end
+# rubocop:disable Metrics/ClassLength
+
# Functions for boot - build_forge
class ForjCoreProcess
+ # TODO: Rewrite this function to break it for rubocop.
# rubocop:disable CyclomaticComplexity
+ # Function displaying the server status
def maestro_create_status(sStatus, iCurAct = 4, pending_count = 0)
s_activity = '/-\\|?'
if iCurAct < 4
s_cur_act = 'ACTIVE'
else
@@ -226,30 +230,58 @@
end
# TODO: Rewrite this function to break it for rubocop.
# rubocop: disable PerceivedComplexity
# rubocop: disable Metrics/MethodLength
+ # rubocop: disable Metrics/AbcSize
- def till_server_active(s_status, o_server, o_address, boot_options)
+ # Loop until server is active
+ def till_server_active(s_status, hParams, o_address, boot_options)
m_cloud_init_error = []
i_cur_act = 0
o_old_log = ''
pending_count = 0
+ server_error = 0
+ o_server = hParams.refresh[:server, :ObjectData]
while s_status != :active
if i_cur_act == 4
pending_count += 1
else
pending_count = 0
end
maestro_create_status(s_status, i_cur_act, pending_count)
i_cur_act += 1
i_cur_act = i_cur_act % 4
+
+ if s_status == :restart
+ process_delete(:server)
+ PrcLib.message("Bad server '%s' removed. Creating a new one...",
+ o_server[:name])
+ sleep(5)
+ process_create(:internet_server)
+ s_status = :starting
+ o_server = hParams.refresh[:server, :ObjectData]
+ next
+ end
+
o_server = load_server(o_server)
- # s_status = o_server[:attrs][:status]
+
+ if o_server[:status] == :error
+ if server_error == 1
+ PrcLib.fatal(1, 'Server tried to be rebuilt but failed again.')
+ end
+ server_error = 1
+ PrcLib.warning("The creation of server '%s' has currently failed. "\
+ 'Trying to rebuild it, once before give up.',
+ o_server[:name])
+ s_status = :restart
+ next
+ end
+
if s_status == :starting
- s_status = :assign_ip if o_server[:attrs][:status] == :active
+ s_status = :assign_ip if o_server[:status] == :active
elsif s_status == :assign_ip
s_status = assign_ip_boot(o_address, boot_options, s_status, o_server)
else # analyze the log output
output_options = { :status => s_status, :error => m_cloud_init_error,
:old_log => o_old_log, :cur_act => i_cur_act
@@ -340,11 +372,11 @@
sleep 5
done
END
s_msg = format(s_msg, o_server[:name], image[:ssh_user],
o_address[:public_ip], boot_options[:keys]
- )
+ )
unless boot_options[:coherent]
s_msg += ANSI.bold("\nUnfortunatelly") + " your current keypair' \
' is not usable to connect to your server.\nYou need to fix' \
' this issue to gain access to your server."
end
@@ -494,11 +526,11 @@
entr = {
:key => rand(36**10).to_s(36),
:salt => Time.now.to_i.to_s,
:iv => Base64.strict_encode64(
OpenSSL::Cipher::Cipher.new('aes-256-cbc').random_iv
- )
+ )
}
PrcLib.debug("Writing '%s' key file", key_file)
File.open(key_file, 'w') do |out|
out.write(Base64.encode64(entr.to_yaml))
@@ -642,18 +674,19 @@
else
h_result[:maestro_repo] = File.join(path_maestro, 'maestro')
clone_maestro_repo(maestro_url, path_maestro, config)
end
rescue => e
- PrcLib.error('Error while cloning the repo from %s\n%s\n%s',
- maestro_url, e.message, e.backtrace.join("\n"))
- PrcLib.info(
- 'If this error persist you could clone the repo manually in ~/.forj/'
- )
+ PrcLib.error("Error while cloning the repo from %s\n%s\n%s"\
+ "\nIf this error persist you could clone the repo manually"\
+ " in '%s'",
+ maestro_url, e.message, e.backtrace.join("\n"),
+ h_result[:maestro_repo])
end
o_maestro = register(h_result, sObjectType)
o_maestro[:maestro_repo] = h_result[:maestro_repo]
+ o_maestro[:maestro_repo_exist?] = File.directory?(h_result[:maestro_repo])
o_maestro
end
end
# Functions for boot - create_or_use_infra
@@ -894,11 +927,11 @@
"mime file '%s' not found.",
mime
) unless File.exist?(mime)
end
- def build_userdata(sObjectType, hParams)
+ def build_userdata(sObjectType, hParams) # rubocop: disable Metrics/AbcSize
# get the paths for maestro and infra repositories
# maestro_path = hParams[:maestro_repository].values
# infra_path = hParams[:infra_repository].values
# concatenate the paths for boothook and cloud_config files
@@ -909,10 +942,17 @@
mime = File.join(
Forj.build_path,
format('userdata.mime.%s', rand(36**5).to_s(36))
)
+ unless hParams[:maestro_repository, :maestro_repo_exist?]
+ PrcLib.fatal(1, "Maestro repository doesn't exist. This is required for "\
+ "cloud_init user_data build. Check why '%s' "\
+ "doesn't exist.",
+ hParams[:maestro_repository, :maestro_repo])
+ end
+
meta_data = JSON.generate(hParams[:metadata, :meta_data])
build_tmpl_dir = File.expand_path(File.join(LIB_PATH, 'build_tmpl'))
PrcLib.state("Preparing user_data - file '%s'", mime)
@@ -1089,11 +1129,11 @@
#
# This function is can be executed only if we copy files to internal
# forj keypair storage. Otherwise this update is ignored.
def save_sequences(private_key_file, forj_private_key_file,
public_key_file, forj_public_key_file, key_name
- )
+ )
PrcLib.info('Importing key pair to FORJ keypairs list.')
FileUtils.copy(private_key_file, forj_private_key_file)
FileUtils.copy(public_key_file, forj_public_key_file)
# Attaching this keypair to the account
@@ -1105,11 +1145,11 @@
#
# This function is can be executed only if we copy files to internal
# forj keypair storage. Otherwise this update is ignored.
def save_md5(private_key_file, forj_private_key_file,
public_key_file, forj_public_key_file
- )
+ )
# Checking source/dest files content
if Digest::MD5.file(private_key_file).hexdigest !=
Digest::MD5.file(forj_private_key_file).hexdigest
PrcLib.info(
'Updating private key keypair piece to FORJ keypairs list.'
@@ -1136,11 +1176,11 @@
# Saving internal copy of private key file for forj use.
config.set(:keypair_base, keys[:keypair_name], :name => 'account')
PrcLib.info("Configured forj keypair '%s' with '%s'",
keys[:keypair_name],
File.join(keys[:keypair_path], keys[:key_basename])
- )
+ )
end
# keypair_files post setup
#
# This function will get the keypair_files setup by user and it will:
@@ -1212,20 +1252,20 @@
# Used in keypair_name pre-step at setup time.
# return true to not skip the data.
#
def update_keypair_config(_ = nil)
%w(local account).each do |config_name|
- next if config.exist?(:keypair_base, :names => [config_name])
-
+ next if config.latest_version?(config_name)
keypair_path = config.get(:keypair_path, nil, :name => config_name)
- next if keypair_path.nil?
-
- options = { :name => config_name }
- options.merge!(:section => :default) if config_name == 'local'
- config.set(:keypair_base, File.basename(keypair_path), options)
- config.set(:keypair_path, File.dirname(keypair_path), options)
+ unless keypair_path.nil?
+ options = { :name => config_name }
+ options.merge!(:section => :default) if config_name == 'local'
+ config.set(:keypair_base, File.basename(keypair_path), options)
+ config.set(:keypair_path, File.dirname(keypair_path), options)
+ end
+ config.version_set(config_name, Forj.file_version)
end
true
end
def forj_dns_settings
@@ -1294,34 +1334,53 @@
def forj_check_cloud_keypair
key_name = config[:keypair_name]
return true if key_name.nil?
config[:key_cloud_coherence] = false
cloud_key = process_get(:keypairs, key_name)
+ register(cloud_key)
if !cloud_key.empty?
if cloud_key[:coherent]
config[:key_cloud_coherence] = true
return true
end
else
return true
end
keypair_display(cloud_key)
- s_ask = 'Do you still want to create new key?'
- PrcLib.fatal(1, 'This keypair name cannot be used. ' \
- 'You may check keypair_path setting ' \
- 'in your account.') unless agree(s_ask)
+
+ return true unless cloud_key[:public_key_exist?]
+
+ PrcLib.message("You need to create a new keypair instead of '%s'"\
+ 'or quit the setup to get the original key and retry.',
+ key_name)
+ s_ask = 'Do you want to create new keypair?'
+
+ PrcLib.fatal(1, 'Quitting setup per your request.') unless agree(s_ask)
false
end
# pre process before asking keypair files
# return true continue to ask keypair files
# return false skip asking keypair files
def forj_cloud_keypair_coherent?(_keypair_files)
+ return true unless config.exist?(:key_cloud_coherence)
+
+ keypair = data_objects(:keypairs)
+
+ return true unless keypair.nil? || keypair[:private_key_exist?]
+
if config[:key_cloud_coherence]
PrcLib.message('Your local ssh keypair is detected ' \
'and valid to access the box.')
return false
end
+ match = ANSI.bold(format('matching %s keypair name previously set',
+ ANSI.red(config[:keypair_name])))
+ desc = 'the base keypair file name (with absolute path) ' + match
+
+ Lorj.data.set(:sections, :credentials, :keypair_files,
+ { :desc => desc }, 'setup')
+
true
end
end
# Funtions for get