lib/forj/process/ForjProcess.rb in forj-1.0.1 vs lib/forj/process/ForjProcess.rb in forj-1.0.2
- old
+ new
@@ -22,10 +22,11 @@
require 'find'
require 'digest'
require 'json'
require 'encryptor' # gem install encryptor
require 'base64'
+require 'net/ssh'
$INFRA_VERSION = "0.0.37"
# Functions for boot
class ForjCoreProcess
@@ -39,16 +40,16 @@
: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)
}
- Logging.debug("Writing '%s' key file" % key_file)
+ PrcLib.debug("Writing '%s' key file" % key_file)
File.open(key_file, 'w') do |out|
out.write(Base64::encode64(entr.to_yaml))
end
else
- Logging.debug("Loading '%s' key file" % key_file)
+ PrcLib.debug("Loading '%s' key file" % key_file)
encoded_key = IO.read(key_file)
entr = YAML.load(Base64::decode64(encoded_key))
end
os_enckey = hParams[:os_enckey]
@@ -104,125 +105,227 @@
# Add init bootstrap additionnal steps
hMeta['bootstrap'] = hParams[:bootstrap] if hParams[:bootstrap]
config.set(:meta_data, hMeta) # Used by :server object
- Logging.info("Metadata set:\n%s" % hMeta)
+ hMetaPrintable = hMeta.clone
+ hMetaPrintable['hpcloud_priv'] = "XXX - data hidden - XXX"
+ PrcLib.info("Metadata set:\n%s" % hMetaPrintable)
oMetaData = register(hMeta, sObjectType)
oMetaData[:meta_data] = hMeta
oMetaData
end
def build_forge(sObjectType, hParams)
+ oForge = Get(sObjectType, config[:instance_name])
+ if oForge.empty? or oForge[:servers].length == 0
+ PrcLib.high_level_msg ("\nBuilding your forge...\n")
+ Create(:internet_server)
+ else
+ oForge[:servers].each { | oServerToFind |
+ Get(:server, oServerToFind[:id]) if /^maestro\./ =~ oServerToFind[:name]
+ }
+ PrcLib.high_level_msg ("\nChecking your forge...\n")
+ oServer = DataObjects(:server, :ObjectData)
+ if oServer
+ oIP = Query(:public_ip, :server_id => oServer[:id])
+ if oIP.length > 0
+ register oIP[0]
+ end
+ Create(:keypairs)
+ else
+ PrcLib.high_level_msg ("\nYour forge exist, without maestro. Building Maestro...\n")
+ Create(:internet_server)
- object.Create(:internet_server)
+ PrcLib.high_level_msg ("\nBuilding your forge...\n")
+ end
+ end
- Logging.high_level_msg ("\nBuilding your forge...\n")
-
oServer = DataObjects(:server, :ObjectData)
+ #Get keypairs
+ hKeys = keypair_detect(oServer[:key_name], File.join($FORJ_KEYPAIRS_PATH, oServer[:key_name]))
+
+ private_key_file = File.join(hKeys[:keypair_path], hKeys[:private_key_name])
+ public_key_file = File.join(hKeys[:keypair_path], hKeys[:public_key_name])
+
+ oServerKey = Get(:keypairs, oServer[:key_name])
+
+ keypair_coherent = coherent_keypair?(hKeys, oServerKey)
+
# Define the log lines to get and test.
config.set(:log_lines, 5)
- Logging.info("Maestro server '%s' id is '%s'." % [oServer[:name], oServer[:id]])
+ PrcLib.info("Maestro server '%s' id is '%s'." % [oServer[:name], oServer[:id]])
# Waiting for server to come online before assigning a public IP.
sStatus = :checking
maestro_create_status(sStatus)
oAddress = DataObjects(:public_ip, :ObjectData)
if oServer[:attrs][:status] == :active
sMsg = <<-END
-Your server is up and running and is publically accessible through IP '#{oAddress[:public_ip]}'.
+Your forj Maestro server is up and running and is publically accessible through IP '#{oAddress[:public_ip]}'.
You can connect to '#{oServer[:name]}' with:
-ssh ubuntu@#{oAddress[:public_ip]} -o StrictHostKeyChecking=no -i #{get_data(:keypairs, :private_key_file)}
+ssh ubuntu@#{oAddress[:public_ip]} -o StrictHostKeyChecking=no -i #{private_key_file}
END
- if not object.get_data(:keypairs)[:coherent]
+ if not keypair_coherent
sMsg += 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
- Logging.info(sMsg)
- Logging.high_level_msg ("\n%s\nThe forge is still building...\n" % sMsg)
+ PrcLib.info(sMsg)
- oLog = object.Get(:server_log, 5)[:attrs][:output]
+ oLog = Get(:server_log, 25)[:attrs][:output]
if /cloud-init boot finished/ =~ oLog
sStatus = :active
+ PrcLib.high_level_msg ("\n%s\nThe forge is ready...\n" % sMsg)
else
+ PrcLib.high_level_msg ("\n%s\nThe forge is still building...\n" % sMsg)
sStatus = :cloud_init
end
else
sleep 5
sStatus = :starting
end
+ mCloudInitError = []
+ iCurAct = 0
+ oOldLog = ""
+
while sStatus != :active
- maestro_create_status(sStatus)
+ maestro_create_status(sStatus, iCurAct)
+ iCurAct += 1
+ iCurAct = iCurAct % 4
begin
- oServer = object.Get(:server, oServer[:attrs][:id])
+ oServer = Get(:server, oServer[:attrs][:id])
rescue => e
- Logging.error(e.message)
+ PrcLib.error(e.message)
end
if sStatus == :starting
if oServer[:attrs][:status] == :active
sStatus = :assign_ip
end
elsif sStatus == :assign_ip
if oAddress.empty?
query_cache_cleanup(:public_ip) # To be able to ask for server IP assigned
- oAddresses = object.Query(:public_ip, :server_id => oServer[:id])
+ oAddresses = Query(:public_ip, :server_id => oServer[:id])
if oAddresses.length == 0
# Assigning Public IP.
- oAddress = object.Create(:public_ip)
+ oAddress = Create(:public_ip)
else
oAddress = oAddresses[0]
end
end
sMsg = <<-END
-Public IP for server '#{oServer[:name]}' is assigned'
+Public IP for server '#{oServer[:name]}' 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@#{oAddress[:public_ip]} -o StrictHostKeyChecking=no -i #{get_data(:keypairs, :private_key_file)} tail -f /var/log/cloud-init.log
+ ssh ubuntu@#{oAddress[:public_ip]} -o StrictHostKeyChecking=no -i #{private_key_file} tail -f /var/log/cloud-init.log
sleep 5
done
END
- if not object.get_data(:keypairs)[:coherent]
+ if not keypair_coherent
sMsg += 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
- Logging.info(sMsg)
- Logging.high_level_msg ("\n%s\nThe forge is still building...\n" % sMsg)
+ PrcLib.info(sMsg)
+ PrcLib.high_level_msg ("\n%s\nThe forge is still building...\n" % sMsg)
sStatus = :cloud_init
- elsif sStatus == :cloud_init
- oLog = object.Get(:server_log, 5)[:attrs][:output]
+ else #analyze the log output
+ oLog = Get(:server_log, 25)[:attrs][:output]
+ iCurAct = 4 if oLog == oOldLog
+ oOldLog = oLog
if /cloud-init boot finished/ =~ oLog
sStatus = :active
+ if mCloudInitError != []
+ PrcLib.high_level_msg ("Critical error cleared. Cloud-init seems moving...")
+ PrcLib.info ("Critical error cleared. Cloud-init seems moving...")
+ mCloudInitError = []
+ end
+ elsif /\[CRITICAL\]/ =~ oLog
+ mCritical = oLog.scan(/.*\[CRITICAL\].*\n/)
+ if not (mCloudInitError == mCritical)
+ sReported = oLog.clone
+ sReported['CRITICAL'] = ANSI.bold('CRITICAL')
+ PrcLib.error("cloud-init error detected:\n-----\n%s\n-----\nPlease connect to the box to decide what you need to do." % [sReported])
+ mCloudInitError = mCritical
+ end
+ elsif sStatus == :cloud_init and /cloud-init-nonet gave up waiting for a network device/ =~ oLog
+ # Valid for ubuntu image 12.04
+ PrcLib.warning("Cloud-init has gave up to configure the network. waiting...")
+ sStatus = :nonet
+ elsif sStatus == :nonet and /Booting system without full network configuration/ =~ oLog
+ # Valid for ubuntu image 12.04
+ PrcLib.warning("forj has detected an issue to bring up your maestro server. Removing it and re-creating a new one. please be patient...")
+ sStatus = :restart
+ elsif sStatus == :restart
+ Delete(:server)
+ Create(:internet_server)
+ sStatus = :starting
end
end
sleep(5) if sStatus != :active
end
- sMsg = "Server '%s' is now ACTIVE. Bootstrap done." % oServer[:name]
- Logging.info(sMsg)
+
+ oForge = get_forge(sObjectType, config[:instance_name], hParams)
+ sMsg = "Your Forge '%s' is ready and accessible from IP #{oAddress[:public_ip]}." % config[:instance_name]
# TODO: read the blueprint/layout to identify which services are implemented and can be accessible.
- Logging.high_level_msg ("Your Forge '%s' is over and accessible from IP #{oAddress[:public_ip]}. Enjoy!\n" % config[:instance_name])
- oServer
+ if config[:blueprint]
+ sMsg += "\nMaestro has implemented the following server(s) for your blueprint '%s':" % config[:blueprint]
+ iCount = 0
+ oForge[:servers].each { | oServer|
+ next if /^maestro\./ =~ oServer[:name]
+ register(oServer)
+ oIP = Query(:public_ip, :server_id => oServer[:id])
+ if oIP.length == 0
+ sMsg += "\n- %s (No public IP)" % [oServer[:name]]
+ else
+ sMsg += "\n- %s (%s)" % [oServer[:name], oIP[0][:public_ip]]
+ end
+ iCount += 1
+ }
+ if iCount > 0
+ sMsg += "\n%d server(s) identified.\n" % iCount
+ else
+ sMsg = "No servers found except maestro"
+ PrcLib.warning("Something went wrong, while creating nodes for " \
+ "blueprint '%s'. check maestro logs." % config[:blueprint])
+ end
+ else
+ sMsg += "\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 under development)"
+ end
+ PrcLib.info(sMsg)
+ PrcLib.high_level_msg ("\n%s\nEnjoy!\n" % sMsg)
+ oForge
end
- def maestro_create_status(sStatus)
+ def maestro_create_status(sStatus, iCurAct = 4)
+ sActivity = "/-\\|?"
+ if iCurAct < 4
+ sCurAct = "ACTIVE"
+ else
+ sCurAct = ANSI.bold("PENDING")
+ end
+
case sStatus
when :checking
- Logging.state("Checking server status")
+ PrcLib.state("Checking server status")
when :starting
- Logging.state("STARTING")
+ PrcLib.state("STARTING")
when :assign_ip
- Logging.state("ACTIVE - Assigning Public IP")
+ PrcLib.state("%s - %s - Assigning Public IP" % [sActivity[iCurAct], sCurAct])
when :cloud_init
- Logging.state("ACTIVE - Currently running cloud-init. Be patient.")
+ PrcLib.state("%s - %s - Currently running cloud-init. Be patient." % [sActivity[iCurAct], sCurAct])
+ when :nonet
+ PrcLib.state("%s - %s - Currently running cloud-init. Be patient." % [sActivity[iCurAct], sCurAct])
+ when :restart
+ PrcLib.state("RESTARTING - Currently restarting maestro box. Be patient.")
when :active
- Logging.info("Server is active")
+ PrcLib.info("Server is active")
end
end
def clone_or_use_maestro_repo(sObjectType, hParams)
@@ -231,27 +334,27 @@
path_maestro = File.expand_path('~/.forj/')
hResult = {}
begin
if maestro_repo and File.directory?(maestro_repo)
- Logging.info("Using maestro repo '%s'" % maestro_repo)
+ PrcLib.info("Using maestro repo '%s'" % maestro_repo)
hResult[:maestro_repo] = maestro_repo
else
hResult[:maestro_repo] = File.join(path_maestro, 'maestro')
- Logging.state("Cloning maestro repo from '%s' to '%s'" % [maestro_url, File.join(path_maestro, 'maestro')])
+ PrcLib.state("Cloning maestro repo from '%s' to '%s'" % [maestro_url, File.join(path_maestro, 'maestro')])
if File.directory?(path_maestro)
if File.directory?(File.join(path_maestro, 'maestro'))
FileUtils.rm_r File.join(path_maestro, 'maestro')
end
end
git = Git.clone(maestro_url, 'maestro', :path => path_maestro)
git.checkout(config[:branch]) if config[:branch] != 'master'
- Logging.info("Maestro repo '%s' cloned on branch '%s'" % [File.join(path_maestro, 'maestro'), config[:branch]])
+ PrcLib.info("Maestro repo '%s' cloned on branch '%s'" % [File.join(path_maestro, 'maestro'), config[:branch]])
end
rescue => e
- Logging.error("Error while cloning the repo from %s\n%s\n%s" % [maestro_url, e.message, e.backtrace.join("\n")])
- Logging.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" % [maestro_url, e.message, e.backtrace.join("\n")])
+ PrcLib.info("If this error persist you could clone the repo manually in ~/.forj/")
end
oMaestro = register(hResult, sObjectType)
oMaestro[:maestro_repo] = hResult[:maestro_repo]
oMaestro
end
@@ -269,20 +372,20 @@
AppInit.ensure_dir_exists(dest_cloud_init)
bReBuildInfra = infra_is_original?(infra, maestro_repo)
if bReBuildInfra
- Logging.state("Building your infra workspace in '%s'" % [infra])
+ PrcLib.state("Building your infra workspace in '%s'" % [infra])
- Logging.debug("Copying recursively '%s' to '%s'" % [cloud_init, infra])
+ PrcLib.debug("Copying recursively '%s' to '%s'" % [cloud_init, infra])
FileUtils.copy_entry(cloud_init, dest_cloud_init)
file_ver = File.join(infra, 'forj-cli.ver')
File.write(file_ver, $INFRA_VERSION)
- Logging.info("The infra workspace '%s' has been built from maestro predefined files." % [infra])
+ PrcLib.info("The infra workspace '%s' has been built from maestro predefined files." % [infra])
else
- Logging.info("Re-using your infra... in '%s'" % [infra])
+ PrcLib.info("Re-using your infra... in '%s'" % [infra])
end
oInfra = register(hInfra, sObjectType)
oInfra[:infra_repo] = hInfra[:infra_repo]
@@ -298,11 +401,11 @@
hResult = {}
if File.exists?(sMD5List)
begin
hResult = YAML.load_file(sMD5List)
rescue => e
- Logging.error("Unable to load valid Original files list '%s'. Your infra workspace won't be migrated, until fixed." % sMD5List)
+ PrcLib.error("Unable to load valid Original files list '%s'. Your infra workspace won't be migrated, until fixed." % sMD5List)
bResult = false
end
if not hResult
hResult = {}
bResult = false
@@ -316,13 +419,13 @@
sInfra_path = File.join(dest_cloud_init, sMaestroRelPath)
if File.exists?(sInfra_path)
md5_file = Digest::MD5.file(sInfra_path).hexdigest
if hResult.key?(sMaestroRelPath) and hResult[sMaestroRelPath] != md5_file
bResult = false
- Logging.info("'%s' infra file has changed from original template in maestro." % sInfra_path)
+ PrcLib.info("'%s' infra file has changed from original template in maestro." % sInfra_path)
else
- Logging.debug("'%s' infra file has not been updated." % sInfra_path)
+ PrcLib.debug("'%s' infra file has not been updated." % sInfra_path)
end
end
md5_file = Digest::MD5.file(path).hexdigest
hResult[sMaestroRelPath] = md5_file
end
@@ -330,16 +433,16 @@
begin
File.open(sMD5List, 'w') do |out|
YAML.dump(hResult, out)
end
rescue => e
- Logging.error("%s\n%s" % [e.message, e.backtrace.join("\n")])
+ PrcLib.error("%s\n%s" % [e.message, e.backtrace.join("\n")])
end
if bResult
- Logging.debug("No original files found has been updated. Infra workspace can be updated/created if needed.")
+ PrcLib.debug("No original files found has been updated. Infra workspace can be updated/created if needed.")
else
- Logging.warning("At least, one file has been updated. Infra workspace won't be updated by forj cli.")
+ PrcLib.warning("At least, one file has been updated. Infra workspace won't be updated by forj cli.")
end
bResult
end
def infra_rebuild(infra_dir)
@@ -356,11 +459,11 @@
return(old_infra_data_update(oConfig, forj_infra_version, infra_dir))
end
end
def old_infra_data_update(oConfig, version, infra_dir)
- Logging.info("Migrating your local infra repo (%s) to the latest version." % version)
+ PrcLib.info("Migrating your local infra repo (%s) to the latest version." % version)
bRebuild = false # Be default migration is successful. No need to rebuild it.
case version
when '0.0.36'
# Moving from 0.0.36 or less to 0.0.37 or higher.
# SET_COMPUTE="{SET_COMPUTE!}" => Setting for Compute. ignored. Coming from HPC
@@ -379,11 +482,11 @@
yDns = {}
yDns = oConfig.oConfig.ExtraGet(:forj_accounts, sAccountName, :dns) if oConfig.oConfig.ExtraExist?(:forj_accounts, sAccountName, :dns)
Dir.foreach(infra_dir) do | file |
next if not /^maestro\.box\..*\.env$/ =~ file
build_env = File.join(infra_dir, file)
- Logging.debug("Reading data from '%s'" % build_env)
+ PrcLib.debug("Reading data from '%s'" % build_env)
tags = {'SET_DNS_TENANTID' => :tenant_id,
'SET_DNS_ZONE' => :service,
'SET_DOMAIN' => :domain_name
}
begin
@@ -391,28 +494,28 @@
File.open(build_env) do |f|
f.each_line do |line|
mObj = line.match(/^(SET_[A-Z_]+)=["'](.*)["'].*$/)
if mObj
- Logging.debug("Reviewing detected '%s' tag" % [mObj[1]])
+ PrcLib.debug("Reviewing detected '%s' tag" % [mObj[1]])
tag = (tags[mObj[1]]? tags[mObj[1]] : nil)
if tag and mObj[2]
if bUpdate == nil and rhGet(yDns, tag) and rhGet(yDns, tag) != mObj[2]
- Logging.message("Your account setup is different than build env.")
- Logging.message("We suggest you to update your account setup with data from your build env.")
+ PrcLib.message("Your account setup is different than build env.")
+ PrcLib.message("We suggest you to update your account setup with data from your build env.")
bUpdate = agree("Do you want to update your setup with those build environment data?")
end
if bUpdate != nil and bUpdate
- Logging.debug("Saved: '%s' = '%s'" % [mObj[1],mObj[2]])
+ PrcLib.debug("Saved: '%s' = '%s'" % [mObj[1],mObj[2]])
rhSet(yDns, mObj[2], tag)
end
end
end
end
end
rescue => e
- Logging.fatal(1, "Failed to open the build environment file '%s'" % build_env, e)
+ PrcLib.fatal(1, "Failed to open the build environment file '%s'" % build_env, e)
end
end
file_ver = File.join(infra_dir, 'forj-cli.ver')
File.write(file_ver, $INFRA_VERSION)
oConfig.oConfig.ExtraSet(:forj_accounts, sAccountName, :dns, yDns)
@@ -435,11 +538,11 @@
meta_data = JSON.generate(hParams[:metadata, :meta_data])
build_tmpl_dir = File.expand_path(File.join($LIB_PATH, 'build_tmpl'))
- Logging.state("Preparing user_data - file '%s'" % mime)
+ PrcLib.state("Preparing user_data - file '%s'" % mime)
# generate boot_*.sh
mime_cmd = "#{build_tmpl_dir}/write-mime-multipart.py"
bootstrap = "#{build_tmpl_dir}/bootstrap_build.sh"
cmd = "%s '%s' '%s' '%s' '%s' '%s' '%s' '%s'" % [
@@ -452,25 +555,25 @@
mime_cmd, # $6: mime script file to execute.
mime # $7: mime file generated.
]
# TODO: Replace shell script call to ruby functions
- if $LIB_FORJ_DEBUG >=1
+ if $LIB_FORJ_DEBUG >= 1
cmd += " >> #{$FORJ_DATA_PATH}/forj.log"
else
cmd += " | tee -a #{$FORJ_DATA_PATH}/forj.log"
end
raise ForjError.new, "#{bootstrap} script file is not found." if not File.exists?(bootstrap)
- Logging.debug("Running '%s'" % cmd)
+ PrcLib.debug("Running '%s'" % cmd)
Kernel.system(cmd)
raise ForjError.new(), "mime file '%s' not found." % mime if not File.exists?(mime)
begin
user_data = File.read(mime)
rescue => e
- Logging.fatal(1, e.message)
+ PrcLib.fatal(1, e.message)
end
if $LIB_FORJ_DEBUG < 5
File.delete(mime)
else
ForjLib.debug(5, "user_data temp file '%s' kept" % mime)
@@ -480,11 +583,11 @@
oUserData = register(hParams, sObjectType)
oUserData[:user_data] = user_data
oUserData[:user_data_encoded] = Base64.strict_encode64(user_data)
oUserData[:mime] = mime
- Logging.info("user_data prepared. File: '%s'" % mime)
+ PrcLib.info("user_data prepared. File: '%s'" % mime)
oUserData
end
end
@@ -514,19 +617,19 @@
end
# keypair_files post setup
def forj_setup_keypairs_files
# Getting Account keypair information
- key_name = config.get(:keypair_name)
- key_path = File.expand_path(config.get(:keypair_files))
+ key_name = config[:keypair_name]
+ key_path = File.expand_path(config[:keypair_files])
keys_imported = nil
- keys_imported = keypair_detect(key_name, config.oConfig.LocalGet(key_name, :imported_keys)) if config.oConfig.LocalExist?(key_name, :imported_keys)
+ keys_imported = keypair_detect(key_name, config.oConfig.localGet(key_name, :imported_keys)) if config.oConfig.localExist?(key_name, :imported_keys)
keys = keypair_detect(key_name, key_path)
if keys_imported and keys_imported[:key_basename] != keys[:key_basename] and $FORJ_KEYPAIRS_PATH != keys[:keypair_path]
- Logging.warning("The private key '%s' was assigned to a different private key file '%s'.\nTo not overwrite it, we recommend you to choose a different keypair name." % [key_name, keys_imported[:key_basename] ])
+ PrcLib.warning("The private key '%s' was assigned to a different private key file '%s'.\nTo not overwrite it, we recommend you to choose a different keypair name." % [key_name, keys_imported[:key_basename] ])
new_key_name = key_name
sMsg = "Please, provide a different keypair name:"
while key_name == new_key_name
new_key_name = ask (sMsg) do | q |
q.validate = /.+/
@@ -544,64 +647,65 @@
# Creation sequences
if not keys[:private_key_exist? ]
# Need to create a key. ask if we need so.
- Logging.message("The private key file attached to keypair named '%s' is not found. Running ssh-keygen to create it." % keys[:keypair_name])
+ PrcLib.message("The private key file attached to keypair named '%s' is not found. Running ssh-keygen to create it." % keys[:keypair_name])
if not File.exists?(private_key_file)
AppInit.ensure_dir_exists(File.dirname(private_key_file))
command = 'ssh-keygen -t rsa -f %s' % private_key_file
- Logging.debug("Executing '%s'" % command)
+ PrcLib.debug("Executing '%s'" % command)
system(command)
end
if not File.exists?(private_key_file)
- Logging.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])
+ 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
- Logging.fatal(1, "ssh-keygen did not created your key pairs. Aborting. Please review errors in ~/.forj/forj.log")
+ PrcLib.fatal(1, "ssh-keygen did not created your key pairs. Aborting. Please review errors in ~/.forj/forj.log")
end
end
if not keys[:public_key_exist? ]
- Logging.message("Your public key '%s' was not found. Getting it from the private one. It may require your passphrase." % [public_key_file])
+ PrcLib.message("Your public key '%s' was not found. Getting it from the private one. It may require your passphrase." % [public_key_file])
command = 'ssh-keygen -y -f %s > %s' % [private_key_file,public_key_file ]
- Logging.debug("Executing '%s'" % command)
+ PrcLib.debug("Executing '%s'" % command)
system(command)
end
forj_private_key_file = File.join($FORJ_KEYPAIRS_PATH, key_name )
forj_public_key_file = File.join($FORJ_KEYPAIRS_PATH, key_name + ".pub")
# Saving sequences
if keys[:keypair_path] != $FORJ_KEYPAIRS_PATH
if not File.exists?(forj_private_key_file) or not File.exists?(forj_public_key_file)
- Logging.info("Importing key pair to FORJ keypairs list.")
+ 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
rhSet(@hAccountData, key_name, :credentials, 'keypair_name')
rhSet(@hAccountData, forj_private_key_file, :credentials, 'keypair_path')
config.oConfig.LocalSet(key_name.to_s, private_key_file, :imported_keys)
else
# Checking source/dest files content
if Digest::MD5.file(private_key_file).hexdigest != Digest::MD5.file(forj_private_key_file).hexdigest
- Logging.info("Updating private key keypair piece to FORJ keypairs list.")
+ PrcLib.info("Updating private key keypair piece to FORJ keypairs list.")
FileUtils.copy(private_key_file, forj_private_key_file)
else
- Logging.info("Private key keypair up to date.")
+ PrcLib.info("Private key keypair up to date.")
end
if Digest::MD5.file(public_key_file).hexdigest != Digest::MD5.file(forj_public_key_file).hexdigest
- Logging.info("Updating public key keypair piece to FORJ keypairs list.")
+ PrcLib.info("Updating public key keypair piece to FORJ keypairs list.")
FileUtils.copy(public_key_file, forj_public_key_file)
else
- Logging.info("Public key keypair up to date.")
+ PrcLib.info("Public key keypair up to date.")
end
end
end
# Saving internal copy of private key file for forj use.
config.set(:keypair_path, forj_private_key_file )
- Logging.info("Configured forj keypair '%s' with '%s'" % [ keys[:keypair_name], File.join(keys[:keypair_path], keys[:key_basename]) ] )
+ PrcLib.info("Configured forj keypair '%s' with '%s'" % [ keys[:keypair_name], File.join(keys[:keypair_path], keys[:key_basename]) ] )
+ true # forj_setup_keypairs_files successfull
end
def forj_DNS_settings()
sAsk = "Optionally, you can ask Maestro to use/manage a domain name on your cloud. It requires your DNS cloud service to be enabled.\nDo you want to configure it?"
config.set(:dns_settings, agree(sAsk))
@@ -618,27 +722,186 @@
end
def setup_tenant_name()
# TODO: To re-introduce with a Controller call instead.
oSSLError=SSLErrorMgt.new # Retry object
- Logging.debug("Getting tenants from hpcloud cli libraries")
+ PrcLib.debug("Getting tenants from hpcloud cli libraries")
begin
tenants = Connection.instance.tenants(@sAccountName)
rescue => e
if not oSSLError.ErrorDetected(e.message,e.backtrace, e)
retry
end
- Logging.fatal(1, 'Network: Unable to connect.')
+ PrcLib.fatal(1, 'Network: Unable to connect.')
end
tenant_id = rhGet(@oConfig.ExtraGet(:hpc_accounts, @sAccountName, :credentials), :tenant_id)
tenant_name = nil
tenants.each { |elem| tenant_name = elem['name'] if elem['id'] == tenant_id }
if tenant_name
- Logging.debug("Tenant ID '%s': '%s' found." % [tenant_id, tenant_name])
+ PrcLib.debug("Tenant ID '%s': '%s' found." % [tenant_id, tenant_name])
rhSet(@hAccountData, tenant_name, :maestro, :tenant_name)
else
- Logging.error("Unable to find the tenant Name for '%s' ID." % tenant_id)
+ PrcLib.error("Unable to find the tenant Name for '%s' ID." % tenant_id)
end
@oConfig.set('tenants', tenants)
+ end
+
+end
+
+#Funtions for get
+class ForjCoreProcess
+ def get_forge(sCloudObj, sForgeId, hParams)
+ sQuery = {}
+ hServers = []
+ sQuery[:name] = sForgeId
+
+ oServers = Query(:server, sQuery )
+
+ regex = Regexp.new('\.%s$' % sForgeId)
+
+ oServers.each { |oServer|
+ oName = oServer[:name]
+ hServers<<oServer if regex =~ oName
+ }
+ PrcLib.info("%s server(s) were found under instance name %s " % [hServers.count(), sQuery[:name]])
+
+ oForge = register(hServers, sCloudObj)
+ oForge[:servers] = hServers
+ oForge[:name] = sForgeId
+ oForge
+ end
+end
+
+#Funtions for destroy
+class ForjCoreProcess
+ def delete_forge(sCloudObj, hParams)
+
+ PrcLib.state("Destroying server(s) of your forge")
+
+ forge_serverid = config.get(:forge_server)
+
+ oForge = hParams[:forge]
+
+ oForge[:servers].each{|server|
+ next if forge_serverid and forge_serverid != server[:id]
+ register(server)
+ PrcLib.state("Destroying server '%s'" % server[:name])
+ Delete(:server)
+ }
+ if forge_serverid.nil?
+ PrcLib.high_level_msg ("The forge '%s' has been destroyed. (all servers linked to the forge)\n" % oForge[:name] )
+ else
+ PrcLib.high_level_msg ("Server(s) selected in the forge '%s' has been removed.\n" % [oForge[:name]])
+ end
+ end
+end
+
+# Functions for ssh
+class ForjCoreProcess
+ def ssh_connection(sObjectType, hParams)
+ oForge = hParams[:forge]
+ oServer = nil
+
+ oForge[:servers].each{|server|
+ next if hParams[:forge_server] != server[:id]
+ oServer = server
+ break
+ }
+
+ #Get server information
+ PrcLib.state("Getting server information")
+ oServer = Get(:server, oServer[:id])
+ register(oServer)
+
+ # Get Public IP of the server. Needs the server to be loaded.
+ oAddress = Query(:public_ip, :server_id => oServer[:id])
+
+ if oAddress.length == 0
+ PrcLib.fatal(1, "ip address for %s server was not found" % oServer[:name])
+ else
+ public_ip = oAddress[0][:public_ip]
+ end
+
+ if config[:identity].nil? or not config[:identity].is_a?(String)
+ hKeys = keypair_detect(oServer[:key_name], File.join($FORJ_KEYPAIRS_PATH, oServer[:key_name]))
+ else
+ hKeys = keypair_detect(oServer[:key_name], File.expand_path(config[:identity]))
+ end
+
+ private_key_file = File.join(hKeys[:keypair_path], hKeys[:private_key_name])
+ public_key_file = File.join(hKeys[:keypair_path], hKeys[:public_key_name])
+
+ PrcLib.info("Found openssh private key file '%s'." % private_key_file) if hKeys[:private_key_exist? ]
+ if hKeys[:public_key_exist? ]
+ PrcLib.info("Found openssh public key file '%s'." % public_key_file)
+ else
+ PrcLib.warning("Openssh public key file '%s' not found. Unable to verify keys coherence with remote server." % public_key_file)
+ end
+
+ if hKeys[:private_key_exist? ]
+ ssh_options = { :keys => private_key_file}
+ PrcLib.debug("Using private key '%s'." % private_key_file)
+ else
+ PrcLib.fatal 1, <<-END
+The server '#{oServer[:name]}' has been configured with a keypair '#{oServer[:key_name]}' which is not found locally.
+You won't be able to connect to that server without '#{oServer[:key_name]}' private key.
+To connect to this box, you need to provide the appropriate private key file with option -i
+ END
+ end
+
+ # Get ssh user
+ image = Get(:image, oServer[:image_id])
+ user = hParams[:ssh_user]
+
+ if user.nil?
+ user = image[:ssh_user]
+ end
+
+ PrcLib.debug("Using account '%s'." % user)
+
+ begin
+ PrcLib.state("creating ssh connection with '%s' box" % oServer[:name])
+ session = Net::SSH.start(public_ip, user, ssh_options) do |ssh|
+ ssh_login(ssh_options, user, public_ip)
+ end
+ PrcLib.debug("Error closing ssh connection, box %s " % oServer[:name]) if not session
+ rescue => e
+ PrcLib.fatal 1, <<-END
+#{e.message}
+You were not able to connect to this box. Please note that there is no garantuee that your local private key file '#{private_key_file}' is the one that was used while building this box.
+You have to check with the user who created that box.
+ END
+ end
+ register({ :success => true }, sObjectType)
+ end
+
+ def setup_ssh_user(sCloudObj, hParams)
+ images = Query(:image, { name: hParams[:image_name]} )
+ case images.length
+ when 0
+ sDefault = hParams[:default_value]
+ else
+ if images[0, :ssh_user].nil?
+ sDefault = hParams[:default_value]
+ else
+ sDefault = images[0, :ssh_user]
+ end
+ end
+ { default_value: sDefault, list: config[:users] }
+ end
+
+ def ssh_login(options, user, public_ip)
+ sOpts = "-o StrictHostKeyChecking=no -o ServerAliveInterval=180"
+ sOpts += " -i %s" % options[:keys] if options[:keys]
+
+ command = 'ssh %s %s@%s' % [sOpts, user, public_ip]
+ PrcLib.debug("Running '%s'" % command)
+ system(command)
+ end
+
+ def ssh_user(image_name)
+ return "fedora" if image_name =~ /fedora/i
+ return "centos" if image_name =~ /centos/i
+ return "ubuntu"
end
end