lib/forj/process/ForjProcess.rb in forj-1.0.5 vs lib/forj/process/ForjProcess.rb in forj-1.0.6
- old
+ new
@@ -31,13 +31,13 @@
# Functions for boot - build_forge
class ForjCoreProcess
def build_forge(sObjectType, hParams)
forge_exist?(sObjectType)
- o_server = data_objects(:server, :ObjectData)
+ o_server = hParams.refresh[:server, :ObjectData]
- boot_options = boot_keypairs(o_server)
+ boot_options = boot_keypairs(hParams)
# Define the log lines to get and test.
config.set(:log_lines, 5)
PrcLib.info("Maestro server '%s' id is '%s'.",
@@ -45,21 +45,21 @@
# Waiting for server to come online before assigning a public IP.
s_status = :checking
maestro_create_status(s_status)
- o_address = data_objects(:public_ip, :ObjectData)
+ o_address = hParams.refresh[:public_ip, :ObjectData]
s_status = active_server?(o_server, o_address, boot_options[:keys],
boot_options[:coherent], s_status
)
till_server_active(s_status, o_server, o_address, boot_options)
o_forge = get_forge(sObjectType, config[:instance_name], hParams)
- read_blueprint_implemented(o_forge, o_address)
+ read_blueprint_implemented(o_forge, hParams)
o_forge
end
def forge_exist?(sObjectType)
o_forge = process_get(sObjectType, config[:instance_name])
@@ -91,31 +91,21 @@
PrcLib.high_level_msg("\nBuilding your forge...\n")
end
end
- def boot_keypairs(o_server)
- # Get keypairs
- h_keys = keypair_detect(
- o_server[:key_name],
- File.join(Forj.keypairs_path, o_server[:key_name])
- )
+ def boot_keypairs(params)
+ o_server = params[:server, :ObjectData]
+ h_keys = params[:keypairs]
- private_key_file = File.join(
- h_keys[:keypair_path],
- h_keys[:private_key_name]
- )
- # public_key_file = File.join(
- # h_keys[:keypair_path],
- # h_keys[:public_key_name]
- # )
+ if h_keys.nil? || o_server[:key_name] != h_keys[:name]
+ h_keys = process_get(:keypairs, o_server[:key_name])
+ end
+ private_key_file = File.join(h_keys[:keypair_path],
+ h_keys[:private_key_name])
- o_server_key = process_get(:keypairs, o_server[:key_name])
-
- keypair_coherent = coherent_keypair?(h_keys, o_server_key)
- boot_options = { :keys => private_key_file, :coherent => keypair_coherent }
- boot_options
+ { :keys => private_key_file, :coherent => h_keys[:coherent] }
end
def active_server?(o_server, o_address, private_key_file,
keypair_coherent, s_status
)
@@ -156,16 +146,18 @@
end
# Functions for boot - build_forge
class ForjCoreProcess
# rubocop:disable CyclomaticComplexity
- def maestro_create_status(sStatus, iCurAct = 4)
+
+ def maestro_create_status(sStatus, iCurAct = 4, pending_count = 0)
s_activity = '/-\\|?'
if iCurAct < 4
s_cur_act = 'ACTIVE'
else
- s_cur_act = ANSI.bold('PENDING')
+ s_cur_act = format('%s - %d s', ANSI.bold('PENDING'),
+ (pending_count + 1) * 5)
end
case sStatus
when :checking
PrcLib.state('Checking server status')
@@ -184,19 +176,28 @@
PrcLib.state('RESTARTING - Currently restarting maestro box. Be patient.')
when :active
PrcLib.info('Server is active')
end
end
- # rubocop:enable CyclomaticComplexity
+ # TODO: Rewrite this function to break it for rubocop.
+ # rubocop: disable PerceivedComplexity
+ # rubocop: disable Metrics/MethodLength
+
def till_server_active(s_status, o_server, o_address, boot_options)
m_cloud_init_error = []
i_cur_act = 0
o_old_log = ''
+ pending_count = 0
while s_status != :active
- maestro_create_status(s_status, i_cur_act)
+ 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
o_server = load_server(o_server)
# s_status = o_server[:attrs][:status]
if s_status == :starting
@@ -210,27 +211,62 @@
output_options = analyze_log_output(output_options, s_status)
s_status = output_options[:status]
m_cloud_init_error = output_options[:error]
o_old_log = output_options[:old_log]
i_cur_act = output_options[:cur_act]
+ if pending_count == 60
+ image = server_get_image o_server
+ highlight = ANSI.yellow('-' * 40)
+ PrcLib.warning("No more server activity detected.\n"\
+ "#{highlight}\n"\
+ "%s\n"\
+ "#{highlight}\n"\
+ "The server '%s' is not providing any output log for"\
+ " more than 5 minutes.\nPlease review the current"\
+ 'output show below to determine if this a normal '\
+ "situation.\nYou can connect to the server if you "\
+ "want to.\nTo connect, use:\n"\
+ 'ssh %s@%s -o StrictHostKeyChecking=no -i %s',
+ o_old_log, o_server[:name], image[:ssh_user],
+ o_address[:public_ip], boot_options[:keys])
+ end
end
sleep(5) if s_status != :active
end
end
+ # Function to get the image data from the server
+ #
+
+ def server_get_image(server)
+ image = data_objects(:image, :ObjectData)
+ return image unless image.nil?
+
+ image = process_get(:image, server[:image_id])
+
+ return Lorj::Data.new if image.nil?
+
+ register(image)
+ end
+
+ # rubocop:enable CyclomaticComplexity
+ # rubocop:enable PerceivedComplexity
+
# Function to get the server, tracking errors
#
# *return*
# - Server found.
#
def load_server(server)
begin
found_server = process_get(:server, server[:attrs][:id])
rescue => e
PrcLib.error(e.message)
+ else
+ return found_server
end
- (found_server.nil? ? server : found_server)
+ server
end
end
# Functions for boot - build_forge
class ForjCoreProcess
@@ -244,21 +280,23 @@
o_address = process_create(:public_ip)
else
o_address = o_addresses[0]
end
end
+
+ image = data_objects[:image, :ObjectData]
s_msg = <<-END
Public IP for server '%s' is assigned.
Now, as soon as the server respond to the ssh port,
you will be able to get a tail of the build with:
while [ 1 = 1 ]
do
- ssh ubuntu@%s -o StrictHostKeyChecking=no -i %s tail -f /var/log/cloud-init.log
+ ssh %s@%s -o StrictHostKeyChecking=no -i %s tail -f /var/log/cloud-init.log
sleep 5
done
END
- s_msg = format(s_msg, o_server[:name],
+ s_msg = format(s_msg, o_server[:name], image[: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' \
@@ -269,32 +307,30 @@
s_status = :cloud_init
s_status
end
def analyze_log_output(output_options, s_status)
- # m_cloud_init_error = []
- # o_old_log = ''
- o_log = process_get(:server_log, 25)[:attrs][:output]
- # i_cur_act = 4 if o_log == o_old_log
- output_options[:cur_act] = 4 if o_log == output_options[:old_log]
- # o_old_log = o_log
- output_options[:old_log] = o_log
- if /cloud-init boot finished/ =~ o_log
- # s_status = :active
+ o_log = process_get(:server_log, 25)
+ return output_options if o_log.nil? || o_log.empty?
+
+ log = o_log[:attrs][:output]
+ output_options[:cur_act] = 4 if log == output_options[:old_log]
+ output_options[:old_log] = log
+ if /cloud-init boot finished/ =~ log
output_options[:status] = :active
output_options[:error] = display_boot_moving_error(
output_options[:error]
)
- elsif /\[CRITICAL\]/ =~ o_log
- m_critical = o_log.scan(/.*\[CRITICAL\].*\n/)
+ elsif /\[CRITICAL\]/ =~ log
+ m_critical = log.scan(/.*\[CRITICAL\].*\n/)
output_options[:error] = display_boot_critical_error(
output_options[:error],
m_critical
)
else
# validate server status
- output_options = analyze_server_status(s_status, o_log, output_options)
+ output_options = analyze_server_status(s_status, log, output_options)
end
output_options
end
def display_boot_critical_error(m_cloud_init_error, m_critical)
@@ -346,38 +382,36 @@
output_options[:status] = :starting
end
output_options
end
- def read_blueprint_implemented(o_forge, o_address)
+ def read_blueprint_implemented(o_forge, params)
+ o_address = params[:public_ip, :ObjectData]
+ blueprint = params[:blueprint]
+ instance_name = params[:instance_name]
s_msg = format(
"Your Forge '%s' is ready and accessible from" \
" IP #{o_address[:public_ip]}.",
- config[:instance_name]
+ instance_name
)
# TODO: read the blueprint/layout to identify which services
# are implemented and can be accessible.
- if config[:blueprint]
+ if blueprint
s_msg += format(
"\n" + 'Maestro has implemented the following server(s) for your' \
" blueprint '%s':",
- config[:blueprint]
+ blueprint
)
server_options = display_servers_with_ip(o_forge, s_msg)
s_msg += server_options[:message]
i_count = server_options[:count]
if i_count > 0
s_msg += format("\n%d server(s) identified.\n", i_count)
else
s_msg = 'No servers found except maestro'
- PrcLib.warning(
- format(
- 'Something went wrong, while creating nodes for blueprint' \
- " '%s'. check maestro logs.",
- config[:blueprint]
- )
- )
+ PrcLib.warning('Something went wrong, while creating nodes for '\
+ "blueprint '%s'. check maestro logs.", blueprint)
end
else
s_msg += "\nMaestro has NOT implemented any servers, because you did" \
' not provided a blueprint. Connect to Maestro, and ask Maestro to' \
' implement any kind of blueprint you need. (Feature currently' \
@@ -859,11 +893,11 @@
PrcLib.fatal(1, e.message)
end
if PrcLib.core_level < 5
File.delete(mime)
else
- ForjLib.debug(5, "user_data temp file '%s' kept", mime)
+ Lorj.debug(5, "user_data temp file '%s' kept", mime)
end
config[:user_data] = user_data
o_user_data = register(hParams, sObjectType)
@@ -933,58 +967,37 @@
keys
end
def create_keys_automatically(keys, private_key_file)
return if keys[:private_key_exist?]
- # Need to create a key. ask if we need so.
- PrcLib.message("The private key file attached to keypair named '%s' is not"\
- ' found. Running ssh-keygen to create it.',
- keys[:keypair_name])
unless File.exist?(private_key_file)
+ # Need to create a key. ask if we need so.
+ PrcLib.message("The private key file attached to keypair named '%s' is "\
+ 'not found. Running ssh-keygen to create it.',
+ keys[:keypair_name])
PrcLib.ensure_dir_exists(File.dirname(private_key_file))
command = format('ssh-keygen -t rsa -f %s', private_key_file)
PrcLib.debug(format("Executing '%s'", command))
system(command)
end
- if !File.exist?(private_key_file)
- PrcLib.fatal(1, "'%s' not found. Unable to add your keypair to hpcloud."\
- ' Create it yourself and provide it with -p option. '\
- 'Then retry.', private_key_file)
- else
- PrcLib.fatal(1, 'ssh-keygen did not created your key pairs. Aborting.'\
+ return if File.exist?(private_key_file)
+ PrcLib.fatal(1, 'ssh-keygen did not created your key pairs. Aborting.'\
' Please review errors in ~/.forj/forj.log')
- end
end
end
# Functions for setup
class ForjCoreProcess
- def load_key_with_passphrase(keys, public_key_file, private_key_file)
- # unless keys[:public_key_exist?]
- return if keys[:private_key_exist?]
- PrcLib.message("Your public key '%s' was not found. Getting it from the" \
- ' private one. It may require your passphrase.',
- public_key_file)
- command = format(
- 'ssh-keygen -y -f %s > %s',
- private_key_file,
- public_key_file
- )
- PrcLib.debug("Executing '%s'", command)
- system(command)
- # end
- end
-
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
- @hAccountData.rh_set(key_name, :credentials, 'keypair_name')
- @hAccountData.rh_set(forj_private_key_file, :credentials, 'keypair_path')
+ config.set(:keypair_name, key_name, :name => 'account')
+ config.set(:keypair_path, forj_private_key_file, :name => 'account')
config.local_set(key_name.to_s, private_key_file, :imported_keys)
end
def save_md5(private_key_file, forj_private_key_file,
public_key_file, forj_public_key_file
@@ -1013,11 +1026,11 @@
# Functions for setup
class ForjCoreProcess
def save_internal_key(forj_private_key_file, keys)
# Saving internal copy of private key file for forj use.
- config.set(:keypair_path, forj_private_key_file)
+ config.set(:keypair_path, forj_private_key_file, :name => 'account')
PrcLib.info("Configured forj keypair '%s' with '%s'",
keys[:keypair_name],
File.join(keys[:keypair_path], keys[:key_basename])
)
end
@@ -1041,14 +1054,12 @@
public_key_file = File.join(keys[:keypair_path], keys[:public_key_name])
# Creation sequences
create_keys_automatically(keys, private_key_file)
- load_key_with_passphrase(keys, public_key_file, private_key_file)
-
forj_private_key_file = File.join(Forj.keypairs_path, key_name)
- # forj_public_key_file = File.join($FORJ_KEYPAIRS_PATH, key_name + '.pub')
+ forj_public_key_file = File.join(Forj.keypairs_path, key_name + '.pub')
# Saving sequences
if keys[:keypair_path] != Forj.keypairs_path
if !File.exist?(forj_private_key_file) ||
!File.exist?(forj_public_key_file)
@@ -1066,20 +1077,21 @@
true # forj_setup_keypairs_files successfull
end
def forj_dns_settings
s_ask = 'Optionally, you can ask Maestro to use/manage a domain name on' \
- " your cloud. It requires your DNS cloud service to be enabled.\nDo " \
+ " your cloud. It requires your DNS cloud service to be enabled.\nDo" \
' you want to configure it?'
config.set(:dns_settings, agree(s_ask))
true
end
def forj_dns_settings?(sKey)
# Return true to ask the question. false otherwise
unless config.get(:dns_settings)
- config.set(sKey, nil)
+ section = Lorj.data.first_section(sKey)
+ config.del(sKey, :name => 'account', :section => section)
return false # Do not ask
end
true
end
@@ -1270,20 +1282,14 @@
# Functions for ssh
class ForjCoreProcess
def setup_ssh_user(_sCloudObj, hParams)
images = process_query(:image, :name => hParams[:image_name])
- case images.length
- when 0
- s_default = hParams[:default_value]
- else
- if images[0, :ssh_user].nil?
- s_default = hParams[:default_value]
- else
- s_default = images[0, :ssh_user]
- end
+ result = { :list => config[:users] }
+ if images.length >= 1 && !images[0, :ssh_user].nil?
+ result[:default_value] = images[0, :ssh_user]
end
- { :default_value => s_default, :list => config[:users] }
+ result
end
def ssh_login(options, user, public_ip)
s_opts = '-o StrictHostKeyChecking=no -o ServerAliveInterval=180'
s_opts += format(' -i %s', options[:keys]) if options[:keys]