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.
- checksums.yaml +4 -4
- data/.gitignore +7 -0
- data/.gitreview +4 -0
- data/Gemfile +21 -19
- data/Gemfile.lock +71 -0
- data/bin/forj +126 -83
- data/forj.gemspec +64 -0
- data/{lib → forj}/defaults.yaml +23 -1
- data/lib/appinit.rb +5 -5
- data/lib/build_tmpl/build-env.py +293 -0
- data/lib/cloud_test.rb +121 -0
- data/lib/forj-settings.rb +52 -39
- data/lib/forj/ForjCli.rb +11 -10
- data/lib/forj/ForjCore.rb +8 -6
- data/lib/forj/process/ForjProcess.rb +345 -82
- data/lib/ssh.rb +81 -20
- metadata +110 -80
- data/lib/compute.rb +0 -36
- data/lib/connection.rb +0 -144
- data/lib/down.rb +0 -60
- data/lib/forj-account.rb +0 -294
- data/lib/forj-config.rb +0 -522
- data/lib/helpers.rb +0 -56
- data/lib/lib-forj/lib/core/core.rb +0 -1740
- data/lib/lib-forj/lib/core/definition.rb +0 -441
- data/lib/lib-forj/lib/core/definition_internal.rb +0 -306
- data/lib/lib-forj/lib/core_process/CloudProcess.rb +0 -334
- data/lib/lib-forj/lib/core_process/global_process.rb +0 -406
- data/lib/lib-forj/lib/core_process/network_process.rb +0 -603
- data/lib/lib-forj/lib/lib-forj.rb +0 -37
- data/lib/lib-forj/lib/providers/hpcloud/Hpcloud.rb +0 -419
- data/lib/lib-forj/lib/providers/hpcloud/compute.rb +0 -108
- data/lib/lib-forj/lib/providers/hpcloud/network.rb +0 -117
- data/lib/lib-forj/lib/providers/hpcloud/security_groups.rb +0 -67
- data/lib/lib-forj/lib/providers/templates/compute.rb +0 -42
- data/lib/lib-forj/lib/providers/templates/core.rb +0 -61
- data/lib/lib-forj/lib/providers/templates/network.rb +0 -33
- data/lib/log.rb +0 -162
- data/lib/network.rb +0 -365
- data/lib/repositories.rb +0 -222
- data/lib/security.rb +0 -207
- data/lib/ssh.sh +0 -185
- data/spec/connection_spec.rb +0 -52
- data/spec/forj-config_spec.rb +0 -237
- 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 =
|
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
|
61
|
+
oConfig[:account_name] = account_name
|
52
62
|
|
53
|
-
oForjAccount =
|
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
|
-
|
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
|
-
|
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
|
-
|
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' % [
|
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
|
-
|
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.
|
135
|
+
oConfig.localSet(key_to_set, key_value)
|
123
136
|
else
|
124
|
-
oConfig.
|
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.
|
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 =
|
136
|
-
|
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 =
|
200
|
+
oForjAccount = Lorj::Account.new(oConfig)
|
188
201
|
|
189
|
-
|
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
|
-
|
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
|
-
|
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
|
-
|
25
|
+
class Lorj::BaseDefinition
|
26
|
+
# ************************************ SSH Object
|
27
|
+
define_obj(:ssh,
|
32
28
|
{
|
33
|
-
:create_e
|
34
|
-
}
|
29
|
+
:create_e => :ssh_connection
|
30
|
+
})
|
35
31
|
obj_needs :CloudObject, :forge
|
36
|
-
obj_needs :data, :
|
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
|
-
|
100
|
+
:create_e => :build_forge,
|
101
|
+
:delete_e => :delete_forge,
|
102
|
+
:get_e => :get_forge
|
102
103
|
}
|
103
|
-
obj_needs :CloudObject, :
|
104
|
-
obj_needs :CloudObject, :
|
105
|
-
obj_needs :
|
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
|
-
|
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
|
-
|
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
|
-
|
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
|
-
|
121
|
-
|
122
|
-
|
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
|
-
|
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 #{
|
173
|
+
ssh ubuntu@#{oAddress[:public_ip]} -o StrictHostKeyChecking=no -i #{private_key_file}
|
142
174
|
END
|
143
|
-
if not
|
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
|
-
|
147
|
-
Logging.high_level_msg ("\n%s\nThe forge is still building...\n" % sMsg)
|
178
|
+
PrcLib.info(sMsg)
|
148
179
|
|
149
|
-
oLog =
|
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 =
|
202
|
+
oServer = Get(:server, oServer[:attrs][:id])
|
164
203
|
rescue => e
|
165
|
-
|
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 =
|
213
|
+
oAddresses = Query(:public_ip, :server_id => oServer[:id])
|
175
214
|
if oAddresses.length == 0
|
176
215
|
# Assigning Public IP.
|
177
|
-
oAddress =
|
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 #{
|
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
|
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
|
-
|
195
|
-
|
233
|
+
PrcLib.info(sMsg)
|
234
|
+
PrcLib.high_level_msg ("\n%s\nThe forge is still building...\n" % sMsg)
|
196
235
|
sStatus = :cloud_init
|
197
|
-
|
198
|
-
oLog =
|
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
|
-
|
206
|
-
|
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
|
-
|
209
|
-
|
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
|
-
|
314
|
+
PrcLib.state("Checking server status")
|
216
315
|
when :starting
|
217
|
-
|
316
|
+
PrcLib.state("STARTING")
|
218
317
|
when :assign_ip
|
219
|
-
|
318
|
+
PrcLib.state("%s - %s - Assigning Public IP" % [sActivity[iCurAct], sCurAct])
|
220
319
|
when :cloud_init
|
221
|
-
|
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
|
-
|
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
|
-
|
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
|
-
|
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
|
-
|
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
|
-
|
252
|
-
|
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
|
-
|
377
|
+
PrcLib.state("Building your infra workspace in '%s'" % [infra])
|
275
378
|
|
276
|
-
|
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
|
-
|
384
|
+
PrcLib.info("The infra workspace '%s' has been built from maestro predefined files." % [infra])
|
282
385
|
else
|
283
|
-
|
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
|
-
|
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
|
-
|
424
|
+
PrcLib.info("'%s' infra file has changed from original template in maestro." % sInfra_path)
|
322
425
|
else
|
323
|
-
|
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
|
-
|
438
|
+
PrcLib.error("%s\n%s" % [e.message, e.backtrace.join("\n")])
|
336
439
|
end
|
337
440
|
if bResult
|
338
|
-
|
441
|
+
PrcLib.debug("No original files found has been updated. Infra workspace can be updated/created if needed.")
|
339
442
|
else
|
340
|
-
|
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
|
-
|
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
|
-
|
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
|
-
|
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
|
-
|
401
|
-
|
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
|
-
|
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
|
-
|
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
|
-
|
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
|
-
|
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
|
-
|
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
|
-
|
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
|
520
|
-
key_path = File.expand_path(config
|
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.
|
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
|
-
|
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
|
-
|
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
|
-
|
656
|
+
PrcLib.debug("Executing '%s'" % command)
|
554
657
|
system(command)
|
555
658
|
end
|
556
659
|
if not File.exists?(private_key_file)
|
557
|
-
|
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
|
-
|
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
|
-
|
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
|
-
|
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
|
-
|
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
|
-
|
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
|
-
|
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
|
-
|
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
|
-
|
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
|
-
|
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
|
-
|
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
|
-
|
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
|
-
|
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
|
-
|
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
|