forj 1.0.1 → 1.0.2
Sign up to get free protection for your applications and to get access to all the features.
- 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
|