forj 1.0.1 → 1.0.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (45) hide show
  1. checksums.yaml +4 -4
  2. data/.gitignore +7 -0
  3. data/.gitreview +4 -0
  4. data/Gemfile +21 -19
  5. data/Gemfile.lock +71 -0
  6. data/bin/forj +126 -83
  7. data/forj.gemspec +64 -0
  8. data/{lib → forj}/defaults.yaml +23 -1
  9. data/lib/appinit.rb +5 -5
  10. data/lib/build_tmpl/build-env.py +293 -0
  11. data/lib/cloud_test.rb +121 -0
  12. data/lib/forj-settings.rb +52 -39
  13. data/lib/forj/ForjCli.rb +11 -10
  14. data/lib/forj/ForjCore.rb +8 -6
  15. data/lib/forj/process/ForjProcess.rb +345 -82
  16. data/lib/ssh.rb +81 -20
  17. metadata +110 -80
  18. data/lib/compute.rb +0 -36
  19. data/lib/connection.rb +0 -144
  20. data/lib/down.rb +0 -60
  21. data/lib/forj-account.rb +0 -294
  22. data/lib/forj-config.rb +0 -522
  23. data/lib/helpers.rb +0 -56
  24. data/lib/lib-forj/lib/core/core.rb +0 -1740
  25. data/lib/lib-forj/lib/core/definition.rb +0 -441
  26. data/lib/lib-forj/lib/core/definition_internal.rb +0 -306
  27. data/lib/lib-forj/lib/core_process/CloudProcess.rb +0 -334
  28. data/lib/lib-forj/lib/core_process/global_process.rb +0 -406
  29. data/lib/lib-forj/lib/core_process/network_process.rb +0 -603
  30. data/lib/lib-forj/lib/lib-forj.rb +0 -37
  31. data/lib/lib-forj/lib/providers/hpcloud/Hpcloud.rb +0 -419
  32. data/lib/lib-forj/lib/providers/hpcloud/compute.rb +0 -108
  33. data/lib/lib-forj/lib/providers/hpcloud/network.rb +0 -117
  34. data/lib/lib-forj/lib/providers/hpcloud/security_groups.rb +0 -67
  35. data/lib/lib-forj/lib/providers/templates/compute.rb +0 -42
  36. data/lib/lib-forj/lib/providers/templates/core.rb +0 -61
  37. data/lib/lib-forj/lib/providers/templates/network.rb +0 -33
  38. data/lib/log.rb +0 -162
  39. data/lib/network.rb +0 -365
  40. data/lib/repositories.rb +0 -222
  41. data/lib/security.rb +0 -207
  42. data/lib/ssh.sh +0 -185
  43. data/spec/connection_spec.rb +0 -52
  44. data/spec/forj-config_spec.rb +0 -237
  45. data/spec/repositories_spec.rb +0 -50
data/lib/forj-settings.rb CHANGED
@@ -16,17 +16,27 @@
16
16
 
17
17
  module Forj
18
18
  module Settings
19
+
20
+ def Settings.common_options(options)
21
+ PrcLib.set_level(Logger::INFO) if options[:verbose]
22
+ PrcLib.set_level(Logger::DEBUG) if options[:debug]
23
+ unless options[:lorj_debug].nil?
24
+ PrcLib.core_level = options[:lorj_debug].to_i
25
+ PrcLib.set_level(Logger::DEBUG)
26
+ end
27
+ end
28
+
19
29
  def Settings.account_show_all(oConfig, account_name)
20
30
  oConfig.set(:account_name, account_name)
21
31
 
22
- oForjAccount = ForjAccount.new(oConfig)
32
+ oForjAccount = Lorj::Account.new(oConfig)
23
33
  oForjAccount.ac_load()
24
34
  puts "List of account settings for provider '%s': " % [oForjAccount.get(:provider)]
25
35
  puts "%-15s %-12s :\n------------------------------" % ['key', 'section name']
26
36
 
27
37
  oForjAccount.metadata_each { |section, found_key, hValue|
28
- next if rhGet(hValue, :readonly)
29
- sDesc = rhGet(hValue, :desc)
38
+ next if Lorj::rhGet(hValue, :readonly)
39
+ sDesc = Lorj::rhGet(hValue, :desc)
30
40
  puts "%-15s %-12s : %s" % [found_key, section, sDesc]
31
41
  }
32
42
  puts "\nUse `forj set KeyName=Value -a %s` to set one." % [ account_name]
@@ -37,8 +47,8 @@ module Forj
37
47
  puts "List of available FORJ default settings:"
38
48
  puts "%-15s %-12s :\n------------------------------" % ['key', 'section name']
39
49
  oConfig.meta_each { |section, found_key, hValue|
40
- next if rhGet(hValue, :readonly)
41
- sDesc = rhGet(hValue, :desc)
50
+ next if Lorj::rhGet(hValue, :readonly)
51
+ sDesc = Lorj::rhGet(hValue, :desc)
42
52
  puts "%-15s %-12s : %s" % [found_key, section, sDesc]
43
53
  }
44
54
  puts "\nUse `forj set KeyName=Value` to set one. "
@@ -48,29 +58,29 @@ module Forj
48
58
  def Settings.account_set(oConfig, account_name, *p)
49
59
  bDirty = false
50
60
 
51
- oConfig.set(:account_name, account_name)
61
+ oConfig[:account_name] = account_name
52
62
 
53
- oForjAccount = ForjAccount.new(oConfig)
63
+ oForjAccount = Lorj::Account.new(oConfig)
54
64
  oForjAccount.ac_load()
55
65
 
56
66
  p.flatten!
57
67
  p.each { | key_val |
58
68
  mkey_val = key_val.match(/^(.*) *= *(.*)$/)
59
-
60
- Logging.fatal(1, "Syntax error. Please set your value like: 'key=value' and retry.") if not mkey_val
69
+
70
+ PrcLib.fatal(1, "Syntax error. Please set your value like: 'key=value' and retry.") if not mkey_val
61
71
 
62
72
  key_to_set = mkey_val[1]
63
73
  key_value = mkey_val[2]
64
74
 
65
75
  sBef = "unset"
66
76
  sAft = "unset"
67
-
68
- Logging.fatal(1, "Unable to update protected '%s'. use `forj setup`, to update it." % key_to_set) if oForjAccount.readonly?(key_to_set)
77
+
78
+ PrcLib.fatal(1, "Unable to update protected '%s'. use `forj setup`, to update it." % key_to_set) if oForjAccount.readonly?(key_to_set)
69
79
  if oForjAccount.meta_type?(key_to_set) == :default
70
- Logging.fatal(1, "Unable set '%s' value. To update this one, use forj set %s, WITHOUT -a %s" % [key_to_set, key_to_set, account_name])
80
+ PrcLib.fatal(1, "Unable set '%s' value. To update this one, use forj set %s, WITHOUT -a %s" % [key_to_set, key_to_set, account_name])
71
81
  end
72
82
 
73
- full_key = '%s/%s' % [ForjDefault.get_meta_section(key_to_set), key_to_set]
83
+ full_key = '%s/%s' % [Lorj::Default.get_meta_section(key_to_set), key_to_set]
74
84
 
75
85
  old_value = oForjAccount.get(key_to_set)
76
86
  sBef = "'%s' (%s)" % [old_value, oForjAccount.exist?(key_to_set)] if oForjAccount.exist?(key_to_set)
@@ -92,63 +102,66 @@ module Forj
92
102
  }
93
103
  oForjAccount.ac_save() if bDirty
94
104
  end
95
-
105
+
96
106
  def Settings.config_set(oConfig, *p)
97
107
  bDirty = false
98
108
 
99
109
  p.flatten!
100
110
  p.each { | key_val |
101
111
  mkey_val = key_val.match(/^(.*) *= *(.*)$/)
102
-
103
- Logging.fatal(1, "Syntax error. Please set your value like: 'key=value' and retry.") if not mkey_val
112
+
113
+ PrcLib.fatal(1, "Syntax error. Please set your value like: 'key=value' and retry.") if not mkey_val
104
114
 
105
115
  key_to_set = mkey_val[1]
106
116
  key_value = mkey_val[2]
107
117
 
108
118
  sBef = "unset"
109
119
  sAft = "unset"
110
-
120
+ if Lorj::Default.get_meta_section(key_to_set).nil?
121
+ PrcLib.warning("key '%s' is not a recognized default key by forj process. " % key_to_set)
122
+ end
123
+
111
124
  old_value = oConfig.get(key_to_set)
112
125
  sBef = "%s: '%s'" % [oConfig.exist?(key_to_set), oConfig.get(key_to_set)] if oConfig.exist?(key_to_set)
113
-
126
+
114
127
  if old_value == key_value
115
128
  puts "%-15s: No update" % [key_to_set]
116
129
  next
117
130
  end
118
-
131
+
119
132
  bDirty = true
120
-
133
+
121
134
  if key_value != ""
122
- oConfig.LocalSet(key_to_set, key_value)
135
+ oConfig.localSet(key_to_set, key_value)
123
136
  else
124
- oConfig.LocalDel(key_to_set)
137
+ oConfig.localDel(key_to_set)
125
138
  end
126
139
 
127
140
  sAft = "%s: '%s'" % [oConfig.exist?(key_to_set), oConfig.get(key_to_set)] if oConfig.exist?(key_to_set)
128
141
  puts "%-15s: %s => %s" % [key_to_set, sBef, ANSI.bold+sAft+ANSI.clear]
129
142
  }
130
- oConfig.SaveConfig() if bDirty
143
+ oConfig.saveConfig() if bDirty
131
144
  end
132
145
 
133
146
  def Settings.account_get_all(oConfig, account_name)
134
147
  oConfig.set(:account_name, account_name)
135
- oForjAccount = ForjAccount.new(oConfig)
136
- Logging.fatal(1, "Unable to load account '%s'. Not found." % account_name) if not oForjAccount.ac_load
137
-
148
+ oForjAccount = Lorj::Account.new(oConfig)
149
+ PrcLib.fatal(1, "Unable to load account '%s'. Not found." % account_name) if not oForjAccount.ac_load
150
+
138
151
  puts "legend: default = Application defaults, local = Local default config, %s = '%s' account config\n\n" % [account_name, account_name]
139
152
  puts "%s %-15s(%-7s) %-12s:\n----------------------------------------" % ['U', 'key', 'origin', 'section name']
140
153
  oForjAccount.metadata_each { | section, mykey, hValue |
141
154
  key_exist = oForjAccount.exist?(mykey)
142
155
 
143
156
  sUpdMsg = '+'
144
- sUpdMsg = ' ' if rhGet(hValue, :readonly)
157
+ sUpdMsg = ' ' if Lorj::rhGet(hValue, :readonly)
145
158
 
146
159
  if key_exist
147
160
  highlight = ''
148
161
  highlight = ANSI.bold if key_exist == account_name
149
162
  highlight = ANSI.bold + ANSI.yellow if key_exist == 'local'
150
163
  default_key = nil
151
- default_key = " (from default key '%s')" % rhGet(hValue, :default) if rhExist?(hValue, :default) == 1 and key_exist != account_name
164
+ default_key = " (from default key '%s')" % Lorj::rhGet(hValue, :default) if Lorj::rhExist?(hValue, :default) == 1 and key_exist != account_name
152
165
  puts "%s %-15s(%s%-7s%s) %-12s: '%s'%s" % [sUpdMsg, mykey, highlight, key_exist, ANSI.clear, section, oForjAccount.get(mykey), default_key]
153
166
  else
154
167
  puts "%s %-15s( ) %-12s: unset" % [sUpdMsg, mykey, section]
@@ -158,16 +171,16 @@ module Forj
158
171
  puts "Use `forj set <key>=<value> -a %s` to update account data." % account_name
159
172
  puts "Or `forj set <key>= -a %s` to restore key default value." % account_name
160
173
  end
161
-
174
+
162
175
  def Settings.config_get_all(oConfig)
163
176
  puts "legend: default = Application defaults, local = Local default config\n\n"
164
177
  puts "%s %-15s(%-7s) %-12s:\n----------------------------------------" % ['U', '''key', 'origin', 'section name']
165
-
178
+
166
179
  oConfig.meta_each { |section, found_key, hValue|
167
180
  sUpdMsg = '+'
168
- sUpdMsg = ' ' if rhGet(hValue, :readonly)
169
- found_key = rhGet(hValue, :default) if rhExist?(hValue, :default) == 1
170
-
181
+ sUpdMsg = ' ' if Lorj::rhGet(hValue, :readonly)
182
+ found_key = Lorj::rhGet(hValue, :default) if Lorj::rhExist?(hValue, :default) == 1
183
+
171
184
  where = oConfig.exist?(found_key)
172
185
  if where
173
186
  highlight = ''
@@ -180,13 +193,13 @@ module Forj
180
193
  puts "\nUse 'forj set <key>=<value>' to update defaults on values identified with '+'"
181
194
 
182
195
  end
183
-
196
+
184
197
  def Settings.account_get(oConfig, account_name, key)
185
198
 
186
199
  oConfig.set(:account_name, account_name)
187
- oForjAccount = ForjAccount.new(oConfig)
200
+ oForjAccount = Lorj::Account.new(oConfig)
188
201
 
189
- Logging.fatal(1, "Unable to load account '%s'. Not found." % account_name) if not oForjAccount.ac_load
202
+ PrcLib.fatal(1, "Unable to load account '%s'. Not found." % account_name) if not oForjAccount.ac_load
190
203
 
191
204
  if oForjAccount.exist?(key)
192
205
  puts "%s: '%s'" % [oForjAccount.exist?(key), oForjAccount.get(key)]
@@ -194,15 +207,15 @@ module Forj
194
207
  key_symb = key.parameterize.underscore.to_sym
195
208
  puts "%s: '%s'" % [oForjAccount.exist?(key_symb), oForjAccount.get(key_symb)]
196
209
  else
197
- Logging.message("key '%s' not found"% [key])
210
+ PrcLib.message("key '%s' not found"% [key])
198
211
  end
199
212
  end
200
-
213
+
201
214
  def Settings.config_get(oConfig, key)
202
215
  if oConfig.exist?(key)
203
216
  puts "%s:'%s'" % [oConfig.exist?(key), oConfig.get(key)]
204
217
  else
205
- Logging.message("key '%s' not found" % [key])
218
+ PrcLib.message("key '%s' not found" % [key])
206
219
  end
207
220
  end
208
221
  end
data/lib/forj/ForjCli.rb CHANGED
@@ -21,18 +21,19 @@
21
21
  # Define framework object on BaseDefinition
22
22
  # See lib/core/definition.rb for function details usage.
23
23
 
24
- class ForjCliProcess
25
- def connect_to(sObjectType, hParams)
26
- end
27
- end
28
-
29
- class BaseDefinition
30
24
 
31
- define_obj :box_ssh,
25
+ class Lorj::BaseDefinition
26
+ # ************************************ SSH Object
27
+ define_obj(:ssh,
32
28
  {
33
- :create_e => :connect_to
34
- }
29
+ :create_e => :ssh_connection
30
+ })
35
31
  obj_needs :CloudObject, :forge
36
- obj_needs :data, :box_name
32
+ obj_needs :data, :instance_name
33
+ obj_needs :data, :keypair_name
34
+ obj_needs :data, :keypair_path
37
35
 
36
+ obj_needs_optional
37
+ obj_needs :data, :forge_server
38
+ obj_needs :data, :ssh_user
38
39
  end
data/lib/forj/ForjCore.rb CHANGED
@@ -25,7 +25,7 @@ $FORJCORE_PATH = File.expand_path(File.dirname(__FILE__))
25
25
 
26
26
  require File.join($FORJCORE_PATH, "process", "ForjProcess.rb")
27
27
 
28
- class BaseDefinition
28
+ class Lorj::BaseDefinition
29
29
 
30
30
  process_default :use_controller => false
31
31
 
@@ -97,12 +97,14 @@ class BaseDefinition
97
97
  # ******************* forge object
98
98
  define_obj :forge,
99
99
  {
100
- :create_e => :build_forge
101
- # :delete_e => :drop_forge
100
+ :create_e => :build_forge,
101
+ :delete_e => :delete_forge,
102
+ :get_e => :get_forge
102
103
  }
103
- obj_needs :CloudObject, :metadata
104
- obj_needs :CloudObject, :userdata
105
- obj_needs :data, :instance_name
104
+ obj_needs :CloudObject, :compute_connection
105
+ obj_needs :CloudObject, :metadata, { :for => [:create_e] }
106
+ obj_needs :CloudObject, :userdata, { :for => [:create_e] }
107
+ obj_needs :data, :instance_name, { :for => [:create_e] }
106
108
 
107
109
  obj_needs_optional
108
110
  obj_needs :CloudObject, :server
@@ -24,6 +24,7 @@ require 'digest'
24
24
  require 'json'
25
25
  require 'encryptor' # gem install encryptor
26
26
  require 'base64'
27
+ require 'net/ssh'
27
28
 
28
29
  $INFRA_VERSION = "0.0.37"
29
30
 
@@ -41,12 +42,12 @@ class ForjCoreProcess
41
42
  :iv => Base64::strict_encode64(OpenSSL::Cipher::Cipher.new('aes-256-cbc').random_iv)
42
43
  }
43
44
 
44
- Logging.debug("Writing '%s' key file" % key_file)
45
+ PrcLib.debug("Writing '%s' key file" % key_file)
45
46
  File.open(key_file, 'w') do |out|
46
47
  out.write(Base64::encode64(entr.to_yaml))
47
48
  end
48
49
  else
49
- Logging.debug("Loading '%s' key file" % key_file)
50
+ PrcLib.debug("Loading '%s' key file" % key_file)
50
51
  encoded_key = IO.read(key_file)
51
52
  entr = YAML.load(Base64::decode64(encoded_key))
52
53
  end
@@ -106,7 +107,9 @@ class ForjCoreProcess
106
107
 
107
108
  config.set(:meta_data, hMeta) # Used by :server object
108
109
 
109
- Logging.info("Metadata set:\n%s" % hMeta)
110
+ hMetaPrintable = hMeta.clone
111
+ hMetaPrintable['hpcloud_priv'] = "XXX - data hidden - XXX"
112
+ PrcLib.info("Metadata set:\n%s" % hMetaPrintable)
110
113
 
111
114
  oMetaData = register(hMeta, sObjectType)
112
115
  oMetaData[:meta_data] = hMeta
@@ -116,17 +119,46 @@ class ForjCoreProcess
116
119
 
117
120
  def build_forge(sObjectType, hParams)
118
121
 
122
+ oForge = Get(sObjectType, config[:instance_name])
123
+ if oForge.empty? or oForge[:servers].length == 0
124
+ PrcLib.high_level_msg ("\nBuilding your forge...\n")
125
+ Create(:internet_server)
126
+ else
127
+ oForge[:servers].each { | oServerToFind |
128
+ Get(:server, oServerToFind[:id]) if /^maestro\./ =~ oServerToFind[:name]
129
+ }
130
+ PrcLib.high_level_msg ("\nChecking your forge...\n")
131
+ oServer = DataObjects(:server, :ObjectData)
132
+ if oServer
133
+ oIP = Query(:public_ip, :server_id => oServer[:id])
134
+ if oIP.length > 0
135
+ register oIP[0]
136
+ end
137
+ Create(:keypairs)
138
+ else
139
+ PrcLib.high_level_msg ("\nYour forge exist, without maestro. Building Maestro...\n")
140
+ Create(:internet_server)
119
141
 
120
- object.Create(:internet_server)
121
-
122
- Logging.high_level_msg ("\nBuilding your forge...\n")
142
+ PrcLib.high_level_msg ("\nBuilding your forge...\n")
143
+ end
144
+ end
123
145
 
124
146
  oServer = DataObjects(:server, :ObjectData)
125
147
 
148
+ #Get keypairs
149
+ hKeys = keypair_detect(oServer[:key_name], File.join($FORJ_KEYPAIRS_PATH, oServer[:key_name]))
150
+
151
+ private_key_file = File.join(hKeys[:keypair_path], hKeys[:private_key_name])
152
+ public_key_file = File.join(hKeys[:keypair_path], hKeys[:public_key_name])
153
+
154
+ oServerKey = Get(:keypairs, oServer[:key_name])
155
+
156
+ keypair_coherent = coherent_keypair?(hKeys, oServerKey)
157
+
126
158
  # Define the log lines to get and test.
127
159
  config.set(:log_lines, 5)
128
160
 
129
- Logging.info("Maestro server '%s' id is '%s'." % [oServer[:name], oServer[:id]])
161
+ PrcLib.info("Maestro server '%s' id is '%s'." % [oServer[:name], oServer[:id]])
130
162
  # Waiting for server to come online before assigning a public IP.
131
163
 
132
164
  sStatus = :checking
@@ -135,21 +167,22 @@ class ForjCoreProcess
135
167
 
136
168
  if oServer[:attrs][:status] == :active
137
169
  sMsg = <<-END
138
- Your server is up and running and is publically accessible through IP '#{oAddress[:public_ip]}'.
170
+ Your forj Maestro server is up and running and is publically accessible through IP '#{oAddress[:public_ip]}'.
139
171
 
140
172
  You can connect to '#{oServer[:name]}' with:
141
- ssh ubuntu@#{oAddress[:public_ip]} -o StrictHostKeyChecking=no -i #{get_data(:keypairs, :private_key_file)}
173
+ ssh ubuntu@#{oAddress[:public_ip]} -o StrictHostKeyChecking=no -i #{private_key_file}
142
174
  END
143
- if not object.get_data(:keypairs)[:coherent]
175
+ if not keypair_coherent
144
176
  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."
145
177
  end
146
- Logging.info(sMsg)
147
- Logging.high_level_msg ("\n%s\nThe forge is still building...\n" % sMsg)
178
+ PrcLib.info(sMsg)
148
179
 
149
- oLog = object.Get(:server_log, 5)[:attrs][:output]
180
+ oLog = Get(:server_log, 25)[:attrs][:output]
150
181
  if /cloud-init boot finished/ =~ oLog
151
182
  sStatus = :active
183
+ PrcLib.high_level_msg ("\n%s\nThe forge is ready...\n" % sMsg)
152
184
  else
185
+ PrcLib.high_level_msg ("\n%s\nThe forge is still building...\n" % sMsg)
153
186
  sStatus = :cloud_init
154
187
  end
155
188
  else
@@ -157,12 +190,18 @@ ssh ubuntu@#{oAddress[:public_ip]} -o StrictHostKeyChecking=no -i #{get_data(:ke
157
190
  sStatus = :starting
158
191
  end
159
192
 
193
+ mCloudInitError = []
194
+ iCurAct = 0
195
+ oOldLog = ""
196
+
160
197
  while sStatus != :active
161
- maestro_create_status(sStatus)
198
+ maestro_create_status(sStatus, iCurAct)
199
+ iCurAct += 1
200
+ iCurAct = iCurAct % 4
162
201
  begin
163
- oServer = object.Get(:server, oServer[:attrs][:id])
202
+ oServer = Get(:server, oServer[:attrs][:id])
164
203
  rescue => e
165
- Logging.error(e.message)
204
+ PrcLib.error(e.message)
166
205
  end
167
206
  if sStatus == :starting
168
207
  if oServer[:attrs][:status] == :active
@@ -171,56 +210,120 @@ ssh ubuntu@#{oAddress[:public_ip]} -o StrictHostKeyChecking=no -i #{get_data(:ke
171
210
  elsif sStatus == :assign_ip
172
211
  if oAddress.empty?
173
212
  query_cache_cleanup(:public_ip) # To be able to ask for server IP assigned
174
- oAddresses = object.Query(:public_ip, :server_id => oServer[:id])
213
+ oAddresses = Query(:public_ip, :server_id => oServer[:id])
175
214
  if oAddresses.length == 0
176
215
  # Assigning Public IP.
177
- oAddress = object.Create(:public_ip)
216
+ oAddress = Create(:public_ip)
178
217
  else
179
218
  oAddress = oAddresses[0]
180
219
  end
181
220
  end
182
221
  sMsg = <<-END
183
- Public IP for server '#{oServer[:name]}' is assigned'
222
+ Public IP for server '#{oServer[:name]}' is assigned.
184
223
  Now, as soon as the server respond to the ssh port, you will be able to get a tail of the build with:
185
224
  while [ 1 = 1 ]
186
225
  do
187
- ssh ubuntu@#{oAddress[:public_ip]} -o StrictHostKeyChecking=no -i #{get_data(:keypairs, :private_key_file)} tail -f /var/log/cloud-init.log
226
+ ssh ubuntu@#{oAddress[:public_ip]} -o StrictHostKeyChecking=no -i #{private_key_file} tail -f /var/log/cloud-init.log
188
227
  sleep 5
189
228
  done
190
229
  END
191
- if not object.get_data(:keypairs)[:coherent]
230
+ if not keypair_coherent
192
231
  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."
193
232
  end
194
- Logging.info(sMsg)
195
- Logging.high_level_msg ("\n%s\nThe forge is still building...\n" % sMsg)
233
+ PrcLib.info(sMsg)
234
+ PrcLib.high_level_msg ("\n%s\nThe forge is still building...\n" % sMsg)
196
235
  sStatus = :cloud_init
197
- elsif sStatus == :cloud_init
198
- oLog = object.Get(:server_log, 5)[:attrs][:output]
236
+ else #analyze the log output
237
+ oLog = Get(:server_log, 25)[:attrs][:output]
238
+ iCurAct = 4 if oLog == oOldLog
239
+ oOldLog = oLog
199
240
  if /cloud-init boot finished/ =~ oLog
200
241
  sStatus = :active
242
+ if mCloudInitError != []
243
+ PrcLib.high_level_msg ("Critical error cleared. Cloud-init seems moving...")
244
+ PrcLib.info ("Critical error cleared. Cloud-init seems moving...")
245
+ mCloudInitError = []
246
+ end
247
+ elsif /\[CRITICAL\]/ =~ oLog
248
+ mCritical = oLog.scan(/.*\[CRITICAL\].*\n/)
249
+ if not (mCloudInitError == mCritical)
250
+ sReported = oLog.clone
251
+ sReported['CRITICAL'] = ANSI.bold('CRITICAL')
252
+ PrcLib.error("cloud-init error detected:\n-----\n%s\n-----\nPlease connect to the box to decide what you need to do." % [sReported])
253
+ mCloudInitError = mCritical
254
+ end
255
+ elsif sStatus == :cloud_init and /cloud-init-nonet gave up waiting for a network device/ =~ oLog
256
+ # Valid for ubuntu image 12.04
257
+ PrcLib.warning("Cloud-init has gave up to configure the network. waiting...")
258
+ sStatus = :nonet
259
+ elsif sStatus == :nonet and /Booting system without full network configuration/ =~ oLog
260
+ # Valid for ubuntu image 12.04
261
+ PrcLib.warning("forj has detected an issue to bring up your maestro server. Removing it and re-creating a new one. please be patient...")
262
+ sStatus = :restart
263
+ elsif sStatus == :restart
264
+ Delete(:server)
265
+ Create(:internet_server)
266
+ sStatus = :starting
201
267
  end
202
268
  end
203
269
  sleep(5) if sStatus != :active
204
270
  end
205
- sMsg = "Server '%s' is now ACTIVE. Bootstrap done." % oServer[:name]
206
- Logging.info(sMsg)
271
+
272
+ oForge = get_forge(sObjectType, config[:instance_name], hParams)
273
+ sMsg = "Your Forge '%s' is ready and accessible from IP #{oAddress[:public_ip]}." % config[:instance_name]
207
274
  # TODO: read the blueprint/layout to identify which services are implemented and can be accessible.
208
- Logging.high_level_msg ("Your Forge '%s' is over and accessible from IP #{oAddress[:public_ip]}. Enjoy!\n" % config[:instance_name])
209
- oServer
275
+ if config[:blueprint]
276
+ sMsg += "\nMaestro has implemented the following server(s) for your blueprint '%s':" % config[:blueprint]
277
+ iCount = 0
278
+ oForge[:servers].each { | oServer|
279
+ next if /^maestro\./ =~ oServer[:name]
280
+ register(oServer)
281
+ oIP = Query(:public_ip, :server_id => oServer[:id])
282
+ if oIP.length == 0
283
+ sMsg += "\n- %s (No public IP)" % [oServer[:name]]
284
+ else
285
+ sMsg += "\n- %s (%s)" % [oServer[:name], oIP[0][:public_ip]]
286
+ end
287
+ iCount += 1
288
+ }
289
+ if iCount > 0
290
+ sMsg += "\n%d server(s) identified.\n" % iCount
291
+ else
292
+ sMsg = "No servers found except maestro"
293
+ PrcLib.warning("Something went wrong, while creating nodes for " \
294
+ "blueprint '%s'. check maestro logs." % config[:blueprint])
295
+ end
296
+ else
297
+ 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)"
298
+ end
299
+ PrcLib.info(sMsg)
300
+ PrcLib.high_level_msg ("\n%s\nEnjoy!\n" % sMsg)
301
+ oForge
210
302
  end
211
303
 
212
- def maestro_create_status(sStatus)
304
+ def maestro_create_status(sStatus, iCurAct = 4)
305
+ sActivity = "/-\\|?"
306
+ if iCurAct < 4
307
+ sCurAct = "ACTIVE"
308
+ else
309
+ sCurAct = ANSI.bold("PENDING")
310
+ end
311
+
213
312
  case sStatus
214
313
  when :checking
215
- Logging.state("Checking server status")
314
+ PrcLib.state("Checking server status")
216
315
  when :starting
217
- Logging.state("STARTING")
316
+ PrcLib.state("STARTING")
218
317
  when :assign_ip
219
- Logging.state("ACTIVE - Assigning Public IP")
318
+ PrcLib.state("%s - %s - Assigning Public IP" % [sActivity[iCurAct], sCurAct])
220
319
  when :cloud_init
221
- Logging.state("ACTIVE - Currently running cloud-init. Be patient.")
320
+ PrcLib.state("%s - %s - Currently running cloud-init. Be patient." % [sActivity[iCurAct], sCurAct])
321
+ when :nonet
322
+ PrcLib.state("%s - %s - Currently running cloud-init. Be patient." % [sActivity[iCurAct], sCurAct])
323
+ when :restart
324
+ PrcLib.state("RESTARTING - Currently restarting maestro box. Be patient.")
222
325
  when :active
223
- Logging.info("Server is active")
326
+ PrcLib.info("Server is active")
224
327
  end
225
328
  end
226
329
 
@@ -233,11 +336,11 @@ done
233
336
 
234
337
  begin
235
338
  if maestro_repo and File.directory?(maestro_repo)
236
- Logging.info("Using maestro repo '%s'" % maestro_repo)
339
+ PrcLib.info("Using maestro repo '%s'" % maestro_repo)
237
340
  hResult[:maestro_repo] = maestro_repo
238
341
  else
239
342
  hResult[:maestro_repo] = File.join(path_maestro, 'maestro')
240
- Logging.state("Cloning maestro repo from '%s' to '%s'" % [maestro_url, File.join(path_maestro, 'maestro')])
343
+ PrcLib.state("Cloning maestro repo from '%s' to '%s'" % [maestro_url, File.join(path_maestro, 'maestro')])
241
344
  if File.directory?(path_maestro)
242
345
  if File.directory?(File.join(path_maestro, 'maestro'))
243
346
  FileUtils.rm_r File.join(path_maestro, 'maestro')
@@ -245,11 +348,11 @@ done
245
348
  end
246
349
  git = Git.clone(maestro_url, 'maestro', :path => path_maestro)
247
350
  git.checkout(config[:branch]) if config[:branch] != 'master'
248
- Logging.info("Maestro repo '%s' cloned on branch '%s'" % [File.join(path_maestro, 'maestro'), config[:branch]])
351
+ PrcLib.info("Maestro repo '%s' cloned on branch '%s'" % [File.join(path_maestro, 'maestro'), config[:branch]])
249
352
  end
250
353
  rescue => e
251
- Logging.error("Error while cloning the repo from %s\n%s\n%s" % [maestro_url, e.message, e.backtrace.join("\n")])
252
- Logging.info("If this error persist you could clone the repo manually in ~/.forj/")
354
+ PrcLib.error("Error while cloning the repo from %s\n%s\n%s" % [maestro_url, e.message, e.backtrace.join("\n")])
355
+ PrcLib.info("If this error persist you could clone the repo manually in ~/.forj/")
253
356
  end
254
357
  oMaestro = register(hResult, sObjectType)
255
358
  oMaestro[:maestro_repo] = hResult[:maestro_repo]
@@ -271,16 +374,16 @@ done
271
374
  bReBuildInfra = infra_is_original?(infra, maestro_repo)
272
375
 
273
376
  if bReBuildInfra
274
- Logging.state("Building your infra workspace in '%s'" % [infra])
377
+ PrcLib.state("Building your infra workspace in '%s'" % [infra])
275
378
 
276
- Logging.debug("Copying recursively '%s' to '%s'" % [cloud_init, infra])
379
+ PrcLib.debug("Copying recursively '%s' to '%s'" % [cloud_init, infra])
277
380
  FileUtils.copy_entry(cloud_init, dest_cloud_init)
278
381
 
279
382
  file_ver = File.join(infra, 'forj-cli.ver')
280
383
  File.write(file_ver, $INFRA_VERSION)
281
- Logging.info("The infra workspace '%s' has been built from maestro predefined files." % [infra])
384
+ PrcLib.info("The infra workspace '%s' has been built from maestro predefined files." % [infra])
282
385
  else
283
- Logging.info("Re-using your infra... in '%s'" % [infra])
386
+ PrcLib.info("Re-using your infra... in '%s'" % [infra])
284
387
  end
285
388
 
286
389
 
@@ -300,7 +403,7 @@ done
300
403
  begin
301
404
  hResult = YAML.load_file(sMD5List)
302
405
  rescue => e
303
- Logging.error("Unable to load valid Original files list '%s'. Your infra workspace won't be migrated, until fixed." % sMD5List)
406
+ PrcLib.error("Unable to load valid Original files list '%s'. Your infra workspace won't be migrated, until fixed." % sMD5List)
304
407
  bResult = false
305
408
  end
306
409
  if not hResult
@@ -318,9 +421,9 @@ done
318
421
  md5_file = Digest::MD5.file(sInfra_path).hexdigest
319
422
  if hResult.key?(sMaestroRelPath) and hResult[sMaestroRelPath] != md5_file
320
423
  bResult = false
321
- Logging.info("'%s' infra file has changed from original template in maestro." % sInfra_path)
424
+ PrcLib.info("'%s' infra file has changed from original template in maestro." % sInfra_path)
322
425
  else
323
- Logging.debug("'%s' infra file has not been updated." % sInfra_path)
426
+ PrcLib.debug("'%s' infra file has not been updated." % sInfra_path)
324
427
  end
325
428
  end
326
429
  md5_file = Digest::MD5.file(path).hexdigest
@@ -332,12 +435,12 @@ done
332
435
  YAML.dump(hResult, out)
333
436
  end
334
437
  rescue => e
335
- Logging.error("%s\n%s" % [e.message, e.backtrace.join("\n")])
438
+ PrcLib.error("%s\n%s" % [e.message, e.backtrace.join("\n")])
336
439
  end
337
440
  if bResult
338
- Logging.debug("No original files found has been updated. Infra workspace can be updated/created if needed.")
441
+ PrcLib.debug("No original files found has been updated. Infra workspace can be updated/created if needed.")
339
442
  else
340
- Logging.warning("At least, one file has been updated. Infra workspace won't be updated by forj cli.")
443
+ PrcLib.warning("At least, one file has been updated. Infra workspace won't be updated by forj cli.")
341
444
  end
342
445
  bResult
343
446
  end
@@ -358,7 +461,7 @@ done
358
461
  end
359
462
 
360
463
  def old_infra_data_update(oConfig, version, infra_dir)
361
- Logging.info("Migrating your local infra repo (%s) to the latest version." % version)
464
+ PrcLib.info("Migrating your local infra repo (%s) to the latest version." % version)
362
465
  bRebuild = false # Be default migration is successful. No need to rebuild it.
363
466
  case version
364
467
  when '0.0.36'
@@ -381,7 +484,7 @@ done
381
484
  Dir.foreach(infra_dir) do | file |
382
485
  next if not /^maestro\.box\..*\.env$/ =~ file
383
486
  build_env = File.join(infra_dir, file)
384
- Logging.debug("Reading data from '%s'" % build_env)
487
+ PrcLib.debug("Reading data from '%s'" % build_env)
385
488
  tags = {'SET_DNS_TENANTID' => :tenant_id,
386
489
  'SET_DNS_ZONE' => :service,
387
490
  'SET_DOMAIN' => :domain_name
@@ -393,16 +496,16 @@ done
393
496
  f.each_line do |line|
394
497
  mObj = line.match(/^(SET_[A-Z_]+)=["'](.*)["'].*$/)
395
498
  if mObj
396
- Logging.debug("Reviewing detected '%s' tag" % [mObj[1]])
499
+ PrcLib.debug("Reviewing detected '%s' tag" % [mObj[1]])
397
500
  tag = (tags[mObj[1]]? tags[mObj[1]] : nil)
398
501
  if tag and mObj[2]
399
502
  if bUpdate == nil and rhGet(yDns, tag) and rhGet(yDns, tag) != mObj[2]
400
- Logging.message("Your account setup is different than build env.")
401
- Logging.message("We suggest you to update your account setup with data from your build env.")
503
+ PrcLib.message("Your account setup is different than build env.")
504
+ PrcLib.message("We suggest you to update your account setup with data from your build env.")
402
505
  bUpdate = agree("Do you want to update your setup with those build environment data?")
403
506
  end
404
507
  if bUpdate != nil and bUpdate
405
- Logging.debug("Saved: '%s' = '%s'" % [mObj[1],mObj[2]])
508
+ PrcLib.debug("Saved: '%s' = '%s'" % [mObj[1],mObj[2]])
406
509
  rhSet(yDns, mObj[2], tag)
407
510
  end
408
511
  end
@@ -410,7 +513,7 @@ done
410
513
  end
411
514
  end
412
515
  rescue => e
413
- Logging.fatal(1, "Failed to open the build environment file '%s'" % build_env, e)
516
+ PrcLib.fatal(1, "Failed to open the build environment file '%s'" % build_env, e)
414
517
  end
415
518
  end
416
519
  file_ver = File.join(infra_dir, 'forj-cli.ver')
@@ -437,7 +540,7 @@ done
437
540
 
438
541
  build_tmpl_dir = File.expand_path(File.join($LIB_PATH, 'build_tmpl'))
439
542
 
440
- Logging.state("Preparing user_data - file '%s'" % mime)
543
+ PrcLib.state("Preparing user_data - file '%s'" % mime)
441
544
  # generate boot_*.sh
442
545
  mime_cmd = "#{build_tmpl_dir}/write-mime-multipart.py"
443
546
  bootstrap = "#{build_tmpl_dir}/bootstrap_build.sh"
@@ -454,13 +557,13 @@ done
454
557
  ]
455
558
 
456
559
  # TODO: Replace shell script call to ruby functions
457
- if $LIB_FORJ_DEBUG >=1
560
+ if $LIB_FORJ_DEBUG >= 1
458
561
  cmd += " >> #{$FORJ_DATA_PATH}/forj.log"
459
562
  else
460
563
  cmd += " | tee -a #{$FORJ_DATA_PATH}/forj.log"
461
564
  end
462
565
  raise ForjError.new, "#{bootstrap} script file is not found." if not File.exists?(bootstrap)
463
- Logging.debug("Running '%s'" % cmd)
566
+ PrcLib.debug("Running '%s'" % cmd)
464
567
  Kernel.system(cmd)
465
568
 
466
569
  raise ForjError.new(), "mime file '%s' not found." % mime if not File.exists?(mime)
@@ -468,7 +571,7 @@ done
468
571
  begin
469
572
  user_data = File.read(mime)
470
573
  rescue => e
471
- Logging.fatal(1, e.message)
574
+ PrcLib.fatal(1, e.message)
472
575
  end
473
576
  if $LIB_FORJ_DEBUG < 5
474
577
  File.delete(mime)
@@ -482,7 +585,7 @@ done
482
585
  oUserData[:user_data] = user_data
483
586
  oUserData[:user_data_encoded] = Base64.strict_encode64(user_data)
484
587
  oUserData[:mime] = mime
485
- Logging.info("user_data prepared. File: '%s'" % mime)
588
+ PrcLib.info("user_data prepared. File: '%s'" % mime)
486
589
  oUserData
487
590
  end
488
591
 
@@ -516,15 +619,15 @@ class ForjCoreProcess
516
619
  # keypair_files post setup
517
620
  def forj_setup_keypairs_files
518
621
  # Getting Account keypair information
519
- key_name = config.get(:keypair_name)
520
- key_path = File.expand_path(config.get(:keypair_files))
622
+ key_name = config[:keypair_name]
623
+ key_path = File.expand_path(config[:keypair_files])
521
624
 
522
625
  keys_imported = nil
523
- keys_imported = keypair_detect(key_name, config.oConfig.LocalGet(key_name, :imported_keys)) if config.oConfig.LocalExist?(key_name, :imported_keys)
626
+ keys_imported = keypair_detect(key_name, config.oConfig.localGet(key_name, :imported_keys)) if config.oConfig.localExist?(key_name, :imported_keys)
524
627
  keys = keypair_detect(key_name, key_path)
525
628
 
526
629
  if keys_imported and keys_imported[:key_basename] != keys[:key_basename] and $FORJ_KEYPAIRS_PATH != keys[:keypair_path]
527
- 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] ])
630
+ 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] ])
528
631
  new_key_name = key_name
529
632
  sMsg = "Please, provide a different keypair name:"
530
633
  while key_name == new_key_name
@@ -546,24 +649,24 @@ class ForjCoreProcess
546
649
  # Creation sequences
547
650
  if not keys[:private_key_exist? ]
548
651
  # Need to create a key. ask if we need so.
549
- Logging.message("The private key file attached to keypair named '%s' is not found. Running ssh-keygen to create it." % keys[:keypair_name])
652
+ PrcLib.message("The private key file attached to keypair named '%s' is not found. Running ssh-keygen to create it." % keys[:keypair_name])
550
653
  if not File.exists?(private_key_file)
551
654
  AppInit.ensure_dir_exists(File.dirname(private_key_file))
552
655
  command = 'ssh-keygen -t rsa -f %s' % private_key_file
553
- Logging.debug("Executing '%s'" % command)
656
+ PrcLib.debug("Executing '%s'" % command)
554
657
  system(command)
555
658
  end
556
659
  if not File.exists?(private_key_file)
557
- 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])
660
+ 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])
558
661
  else
559
- Logging.fatal(1, "ssh-keygen did not created your key pairs. Aborting. Please review errors in ~/.forj/forj.log")
662
+ PrcLib.fatal(1, "ssh-keygen did not created your key pairs. Aborting. Please review errors in ~/.forj/forj.log")
560
663
  end
561
664
  end
562
665
 
563
666
  if not keys[:public_key_exist? ]
564
- Logging.message("Your public key '%s' was not found. Getting it from the private one. It may require your passphrase." % [public_key_file])
667
+ PrcLib.message("Your public key '%s' was not found. Getting it from the private one. It may require your passphrase." % [public_key_file])
565
668
  command = 'ssh-keygen -y -f %s > %s' % [private_key_file,public_key_file ]
566
- Logging.debug("Executing '%s'" % command)
669
+ PrcLib.debug("Executing '%s'" % command)
567
670
  system(command)
568
671
  end
569
672
 
@@ -574,7 +677,7 @@ class ForjCoreProcess
574
677
 
575
678
  if keys[:keypair_path] != $FORJ_KEYPAIRS_PATH
576
679
  if not File.exists?(forj_private_key_file) or not File.exists?(forj_public_key_file)
577
- Logging.info("Importing key pair to FORJ keypairs list.")
680
+ PrcLib.info("Importing key pair to FORJ keypairs list.")
578
681
  FileUtils.copy(private_key_file, forj_private_key_file)
579
682
  FileUtils.copy(public_key_file, forj_public_key_file)
580
683
  # Attaching this keypair to the account
@@ -584,22 +687,23 @@ class ForjCoreProcess
584
687
  else
585
688
  # Checking source/dest files content
586
689
  if Digest::MD5.file(private_key_file).hexdigest != Digest::MD5.file(forj_private_key_file).hexdigest
587
- Logging.info("Updating private key keypair piece to FORJ keypairs list.")
690
+ PrcLib.info("Updating private key keypair piece to FORJ keypairs list.")
588
691
  FileUtils.copy(private_key_file, forj_private_key_file)
589
692
  else
590
- Logging.info("Private key keypair up to date.")
693
+ PrcLib.info("Private key keypair up to date.")
591
694
  end
592
695
  if Digest::MD5.file(public_key_file).hexdigest != Digest::MD5.file(forj_public_key_file).hexdigest
593
- Logging.info("Updating public key keypair piece to FORJ keypairs list.")
696
+ PrcLib.info("Updating public key keypair piece to FORJ keypairs list.")
594
697
  FileUtils.copy(public_key_file, forj_public_key_file)
595
698
  else
596
- Logging.info("Public key keypair up to date.")
699
+ PrcLib.info("Public key keypair up to date.")
597
700
  end
598
701
  end
599
702
  end
600
703
  # Saving internal copy of private key file for forj use.
601
704
  config.set(:keypair_path, forj_private_key_file )
602
- Logging.info("Configured forj keypair '%s' with '%s'" % [ keys[:keypair_name], File.join(keys[:keypair_path], keys[:key_basename]) ] )
705
+ PrcLib.info("Configured forj keypair '%s' with '%s'" % [ keys[:keypair_name], File.join(keys[:keypair_path], keys[:key_basename]) ] )
706
+ true # forj_setup_keypairs_files successfull
603
707
  end
604
708
 
605
709
  def forj_DNS_settings()
@@ -620,25 +724,184 @@ class ForjCoreProcess
620
724
  def setup_tenant_name()
621
725
  # TODO: To re-introduce with a Controller call instead.
622
726
  oSSLError=SSLErrorMgt.new # Retry object
623
- Logging.debug("Getting tenants from hpcloud cli libraries")
727
+ PrcLib.debug("Getting tenants from hpcloud cli libraries")
624
728
  begin
625
729
  tenants = Connection.instance.tenants(@sAccountName)
626
730
  rescue => e
627
731
  if not oSSLError.ErrorDetected(e.message,e.backtrace, e)
628
732
  retry
629
733
  end
630
- Logging.fatal(1, 'Network: Unable to connect.')
734
+ PrcLib.fatal(1, 'Network: Unable to connect.')
631
735
  end
632
736
  tenant_id = rhGet(@oConfig.ExtraGet(:hpc_accounts, @sAccountName, :credentials), :tenant_id)
633
737
  tenant_name = nil
634
738
  tenants.each { |elem| tenant_name = elem['name'] if elem['id'] == tenant_id }
635
739
  if tenant_name
636
- Logging.debug("Tenant ID '%s': '%s' found." % [tenant_id, tenant_name])
740
+ PrcLib.debug("Tenant ID '%s': '%s' found." % [tenant_id, tenant_name])
637
741
  rhSet(@hAccountData, tenant_name, :maestro, :tenant_name)
638
742
  else
639
- Logging.error("Unable to find the tenant Name for '%s' ID." % tenant_id)
743
+ PrcLib.error("Unable to find the tenant Name for '%s' ID." % tenant_id)
640
744
  end
641
745
  @oConfig.set('tenants', tenants)
642
746
  end
643
747
 
644
748
  end
749
+
750
+ #Funtions for get
751
+ class ForjCoreProcess
752
+ def get_forge(sCloudObj, sForgeId, hParams)
753
+ sQuery = {}
754
+ hServers = []
755
+ sQuery[:name] = sForgeId
756
+
757
+ oServers = Query(:server, sQuery )
758
+
759
+ regex = Regexp.new('\.%s$' % sForgeId)
760
+
761
+ oServers.each { |oServer|
762
+ oName = oServer[:name]
763
+ hServers<<oServer if regex =~ oName
764
+ }
765
+ PrcLib.info("%s server(s) were found under instance name %s " % [hServers.count(), sQuery[:name]])
766
+
767
+ oForge = register(hServers, sCloudObj)
768
+ oForge[:servers] = hServers
769
+ oForge[:name] = sForgeId
770
+ oForge
771
+ end
772
+ end
773
+
774
+ #Funtions for destroy
775
+ class ForjCoreProcess
776
+ def delete_forge(sCloudObj, hParams)
777
+
778
+ PrcLib.state("Destroying server(s) of your forge")
779
+
780
+ forge_serverid = config.get(:forge_server)
781
+
782
+ oForge = hParams[:forge]
783
+
784
+ oForge[:servers].each{|server|
785
+ next if forge_serverid and forge_serverid != server[:id]
786
+ register(server)
787
+ PrcLib.state("Destroying server '%s'" % server[:name])
788
+ Delete(:server)
789
+ }
790
+ if forge_serverid.nil?
791
+ PrcLib.high_level_msg ("The forge '%s' has been destroyed. (all servers linked to the forge)\n" % oForge[:name] )
792
+ else
793
+ PrcLib.high_level_msg ("Server(s) selected in the forge '%s' has been removed.\n" % [oForge[:name]])
794
+ end
795
+ end
796
+ end
797
+
798
+ # Functions for ssh
799
+ class ForjCoreProcess
800
+ def ssh_connection(sObjectType, hParams)
801
+ oForge = hParams[:forge]
802
+ oServer = nil
803
+
804
+ oForge[:servers].each{|server|
805
+ next if hParams[:forge_server] != server[:id]
806
+ oServer = server
807
+ break
808
+ }
809
+
810
+ #Get server information
811
+ PrcLib.state("Getting server information")
812
+ oServer = Get(:server, oServer[:id])
813
+ register(oServer)
814
+
815
+ # Get Public IP of the server. Needs the server to be loaded.
816
+ oAddress = Query(:public_ip, :server_id => oServer[:id])
817
+
818
+ if oAddress.length == 0
819
+ PrcLib.fatal(1, "ip address for %s server was not found" % oServer[:name])
820
+ else
821
+ public_ip = oAddress[0][:public_ip]
822
+ end
823
+
824
+ if config[:identity].nil? or not config[:identity].is_a?(String)
825
+ hKeys = keypair_detect(oServer[:key_name], File.join($FORJ_KEYPAIRS_PATH, oServer[:key_name]))
826
+ else
827
+ hKeys = keypair_detect(oServer[:key_name], File.expand_path(config[:identity]))
828
+ end
829
+
830
+ private_key_file = File.join(hKeys[:keypair_path], hKeys[:private_key_name])
831
+ public_key_file = File.join(hKeys[:keypair_path], hKeys[:public_key_name])
832
+
833
+ PrcLib.info("Found openssh private key file '%s'." % private_key_file) if hKeys[:private_key_exist? ]
834
+ if hKeys[:public_key_exist? ]
835
+ PrcLib.info("Found openssh public key file '%s'." % public_key_file)
836
+ else
837
+ PrcLib.warning("Openssh public key file '%s' not found. Unable to verify keys coherence with remote server." % public_key_file)
838
+ end
839
+
840
+ if hKeys[:private_key_exist? ]
841
+ ssh_options = { :keys => private_key_file}
842
+ PrcLib.debug("Using private key '%s'." % private_key_file)
843
+ else
844
+ PrcLib.fatal 1, <<-END
845
+ The server '#{oServer[:name]}' has been configured with a keypair '#{oServer[:key_name]}' which is not found locally.
846
+ You won't be able to connect to that server without '#{oServer[:key_name]}' private key.
847
+ To connect to this box, you need to provide the appropriate private key file with option -i
848
+ END
849
+ end
850
+
851
+ # Get ssh user
852
+ image = Get(:image, oServer[:image_id])
853
+ user = hParams[:ssh_user]
854
+
855
+ if user.nil?
856
+ user = image[:ssh_user]
857
+ end
858
+
859
+ PrcLib.debug("Using account '%s'." % user)
860
+
861
+ begin
862
+ PrcLib.state("creating ssh connection with '%s' box" % oServer[:name])
863
+ session = Net::SSH.start(public_ip, user, ssh_options) do |ssh|
864
+ ssh_login(ssh_options, user, public_ip)
865
+ end
866
+ PrcLib.debug("Error closing ssh connection, box %s " % oServer[:name]) if not session
867
+ rescue => e
868
+ PrcLib.fatal 1, <<-END
869
+ #{e.message}
870
+ 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.
871
+ You have to check with the user who created that box.
872
+ END
873
+ end
874
+ register({ :success => true }, sObjectType)
875
+ end
876
+
877
+ def setup_ssh_user(sCloudObj, hParams)
878
+ images = Query(:image, { name: hParams[:image_name]} )
879
+ case images.length
880
+ when 0
881
+ sDefault = hParams[:default_value]
882
+ else
883
+ if images[0, :ssh_user].nil?
884
+ sDefault = hParams[:default_value]
885
+ else
886
+ sDefault = images[0, :ssh_user]
887
+ end
888
+ end
889
+ { default_value: sDefault, list: config[:users] }
890
+ end
891
+
892
+ def ssh_login(options, user, public_ip)
893
+ sOpts = "-o StrictHostKeyChecking=no -o ServerAliveInterval=180"
894
+ sOpts += " -i %s" % options[:keys] if options[:keys]
895
+
896
+ command = 'ssh %s %s@%s' % [sOpts, user, public_ip]
897
+ PrcLib.debug("Running '%s'" % command)
898
+ system(command)
899
+ end
900
+
901
+ def ssh_user(image_name)
902
+ return "fedora" if image_name =~ /fedora/i
903
+ return "centos" if image_name =~ /centos/i
904
+ return "ubuntu"
905
+ end
906
+
907
+ end