forj 1.0.17 → 1.0.18
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/forj.gemspec +3 -3
- data/lib/process/forj_core/data.yaml +23 -11
- data/lib/process/forj_core/process/forj_process.rb +179 -114
- data/lib/process/forj_core/process/lorj_account.rb +13 -17
- metadata +4 -4
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA1:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 3713a3141ee28056dfc779808c37fbeb2653fb0e
|
|
4
|
+
data.tar.gz: 17ac0ed878a17cdda2af6928f063b1318a93b202
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: ee0f4ac5e241c57d7b8b15c9d58ffdf4d55640d6cd58a4ab9c6fc8e207a0903cac2d50a2b1afa3359c2d3c624d72599b4ca1975af7078e494d923f1f917f8d6a
|
|
7
|
+
data.tar.gz: 7e3067f2f0cdf2a8c5f202ecbf043e55501dc776f1b06bf504126634721ba66a786dcc955aa3d9c8448ea71628b1396b464e0800e47ff1dbfb32063c6be28a13
|
data/forj.gemspec
CHANGED
|
@@ -19,8 +19,8 @@ Gem::Specification.new do |s|
|
|
|
19
19
|
s.name = 'forj'
|
|
20
20
|
s.homepage = 'https://www.forj.io'
|
|
21
21
|
|
|
22
|
-
s.version = '1.0.
|
|
23
|
-
s.date = '2015-
|
|
22
|
+
s.version = '1.0.18'
|
|
23
|
+
s.date = '2015-07-02'
|
|
24
24
|
s.summary = 'forj command line'
|
|
25
25
|
s.description = 'forj cli - See https://www.forj.io for documentation/information'
|
|
26
26
|
|
|
@@ -51,7 +51,7 @@ Gem::Specification.new do |s|
|
|
|
51
51
|
s.add_runtime_dependency 'json', '1.7.5'
|
|
52
52
|
s.add_runtime_dependency 'bundler'
|
|
53
53
|
s.add_runtime_dependency 'nokogiri','1.5.11'
|
|
54
|
-
s.add_runtime_dependency 'lorj_cloud', '>= 0.1.
|
|
54
|
+
s.add_runtime_dependency 'lorj_cloud', '>= 0.1.9'
|
|
55
55
|
|
|
56
56
|
s.add_development_dependency "rake", "~> 10.0"
|
|
57
57
|
s.add_development_dependency "rspec", "~> 3.1.0"
|
|
@@ -25,7 +25,7 @@
|
|
|
25
25
|
:add:
|
|
26
26
|
- :ssh_user
|
|
27
27
|
:gardener_config:
|
|
28
|
-
:desc: "Maestro gardener Cloud configuration:"
|
|
28
|
+
:desc: "Maestro FOG gardener Cloud configuration:"
|
|
29
29
|
:explanation: |-
|
|
30
30
|
Maestro gardener is currently the layer used by Maestro to access your cloud.
|
|
31
31
|
|
|
@@ -41,8 +41,8 @@
|
|
|
41
41
|
As those changes are in transition, the old gardener behavior has been kept and can be re-enabled.
|
|
42
42
|
See 'lorj_disabled' paramater in 'forj get/set' or --disable-lorj from cli.
|
|
43
43
|
|
|
44
|
-
In order to switch easily
|
|
45
|
-
|
|
44
|
+
In order to switch easily and re-activate FOG on gardener, setup will still requires
|
|
45
|
+
the openstack uri (auth V2.0 only), project name, user and password.
|
|
46
46
|
:bp_config:
|
|
47
47
|
:desc: "Maestro and blueprint configuration:"
|
|
48
48
|
:maestro_access_config:
|
|
@@ -106,6 +106,7 @@
|
|
|
106
106
|
:ask_step: :maestro_access_config
|
|
107
107
|
:pre_step_function: :update_keypair_config
|
|
108
108
|
:post_step_function: :forj_check_cloud_keypair
|
|
109
|
+
:export: true
|
|
109
110
|
:auth_uri:
|
|
110
111
|
:desc: "Generic service auth url"
|
|
111
112
|
:account_exclusive: true
|
|
@@ -113,12 +114,14 @@
|
|
|
113
114
|
:required: true
|
|
114
115
|
:ask_sort: 0
|
|
115
116
|
:ask_step: :provider_config
|
|
117
|
+
:export: true
|
|
116
118
|
:account_id:
|
|
117
119
|
:desc: "Generic Cloud Account name."
|
|
118
120
|
:account_exclusive: true
|
|
119
121
|
:account: true
|
|
120
122
|
:required: true
|
|
121
123
|
:ask_step: :provider_config
|
|
124
|
+
:export: true
|
|
122
125
|
:account_key:
|
|
123
126
|
:desc: "Generic cloud account key"
|
|
124
127
|
:account_exclusive: true
|
|
@@ -126,15 +129,17 @@
|
|
|
126
129
|
:required: true
|
|
127
130
|
:encrypted: true
|
|
128
131
|
:ask_step: :provider_config
|
|
132
|
+
:export: true
|
|
129
133
|
:tenant:
|
|
130
134
|
:desc: "Openstack Tenant Name (Project name)"
|
|
131
135
|
:account_exclusive: true
|
|
132
136
|
:account: true
|
|
133
137
|
:required: true
|
|
134
138
|
:ask_step: :provider_config
|
|
139
|
+
:export: true
|
|
135
140
|
:gardener:
|
|
136
141
|
:os_user:
|
|
137
|
-
:desc: "Openstack compute cloud User name"
|
|
142
|
+
:desc: "Openstack compute cloud User name for Fog Gardener"
|
|
138
143
|
:account_exclusive: true
|
|
139
144
|
:account: true
|
|
140
145
|
:required: true
|
|
@@ -143,7 +148,7 @@
|
|
|
143
148
|
:default_value: "<%= (config[:provider] == 'openstack')?config['credentials#account_id']:nil %>"
|
|
144
149
|
:ask_sort: 2
|
|
145
150
|
:os_enckey:
|
|
146
|
-
:desc: "Openstack compute cloud password"
|
|
151
|
+
:desc: "Openstack compute cloud password for Fog Gardener"
|
|
147
152
|
:account_exclusive: true
|
|
148
153
|
:encrypted: true
|
|
149
154
|
:account: true
|
|
@@ -152,12 +157,9 @@
|
|
|
152
157
|
:default_value: "<%= (config[:provider] == 'openstack')?config['credentials#account_key']:nil %>"
|
|
153
158
|
:ask_sort: 3
|
|
154
159
|
:os_auth_uri:
|
|
155
|
-
:desc: "Openstack service auth url"
|
|
160
|
+
:desc: "Openstack service auth url for Fog Gardener"
|
|
156
161
|
:explanation: |-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
Currently, Gardener supports only openstack cloud type, with authentication version 2.
|
|
160
|
-
Multiple provider support and Openstack authentication v3 will be implemented soon.
|
|
162
|
+
Only Openstack v2.0 authentication is supported by FOG gardener.
|
|
161
163
|
:account_exclusive: true
|
|
162
164
|
:account: true
|
|
163
165
|
:required: true
|
|
@@ -175,6 +177,7 @@
|
|
|
175
177
|
:account: true
|
|
176
178
|
:post_step_function: :forj_dns_settings
|
|
177
179
|
:ask_step: :dns_config
|
|
180
|
+
:export: true
|
|
178
181
|
:dns_service:
|
|
179
182
|
:desc: "DNS service region name Maestro will use."
|
|
180
183
|
:account_exclusive: true
|
|
@@ -191,7 +194,7 @@
|
|
|
191
194
|
:network:
|
|
192
195
|
:webproxy:
|
|
193
196
|
:desc: "HTTP/HTTPS proxy setting to access internet from your cloud"
|
|
194
|
-
|
|
197
|
+
:export: true
|
|
195
198
|
# Defines maestro environment.
|
|
196
199
|
:maestro:
|
|
197
200
|
:tenant_name:
|
|
@@ -208,12 +211,14 @@
|
|
|
208
211
|
:required: true
|
|
209
212
|
:default_value: "forj"
|
|
210
213
|
:ask_step: :maestro_config
|
|
214
|
+
:export: "server#network_name"
|
|
211
215
|
:security_group:
|
|
212
216
|
:desc: "Security group name to configure and attach to each forge boxes."
|
|
213
217
|
:account: true
|
|
214
218
|
:validate: !ruby/regexp /^\w?\w*$/
|
|
215
219
|
:default_value: "forj"
|
|
216
220
|
:ask_step: :maestro_config
|
|
221
|
+
:export: "server#security_group"
|
|
217
222
|
:ports:
|
|
218
223
|
:desc: "Ports open in the security groups given."
|
|
219
224
|
:default_value: [22, 80, 443, 3000, 3131-3135, 4505-4506, 5000, 5666, 8000, 8080-8081, 8083, 8125, 8139-8140, 8773-8776, 9292, 29418, 35357]
|
|
@@ -243,6 +248,7 @@
|
|
|
243
248
|
:desc: "Maestro Flavor name"
|
|
244
249
|
:default_value: 'medium'
|
|
245
250
|
:account: true
|
|
251
|
+
:export: "server#flavor_name"
|
|
246
252
|
:list_values:
|
|
247
253
|
:query_type: :query_call # Will execute a query on flavor, query_params is empty for all.
|
|
248
254
|
:object: :flavor
|
|
@@ -272,6 +278,8 @@
|
|
|
272
278
|
|
|
273
279
|
Checking image '<%= config['maestro#image_name'] %>'...
|
|
274
280
|
:account: true
|
|
281
|
+
:export: "server#ssh_user"
|
|
282
|
+
|
|
275
283
|
:ask_step: :maestro_img_config
|
|
276
284
|
:ask_sort: 0
|
|
277
285
|
:after: :image_name
|
|
@@ -302,15 +310,19 @@
|
|
|
302
310
|
:server:
|
|
303
311
|
:network_name:
|
|
304
312
|
:get: false
|
|
313
|
+
:export: false
|
|
305
314
|
:security_group:
|
|
306
315
|
:get: false
|
|
316
|
+
:export: false
|
|
307
317
|
:box_name:
|
|
308
318
|
:get: false
|
|
309
319
|
:flavor_name:
|
|
310
320
|
:get: false
|
|
311
321
|
:account: false
|
|
322
|
+
:export: false
|
|
312
323
|
:image_name:
|
|
313
324
|
:account: false
|
|
314
325
|
:get: false
|
|
326
|
+
:export: false
|
|
315
327
|
:ports:
|
|
316
328
|
:get: false
|
|
@@ -55,8 +55,7 @@ class ForjCoreProcess
|
|
|
55
55
|
o_address = hParams.refresh[:public_ip, :ObjectData]
|
|
56
56
|
o_address = Lorj::Data.new if o_address.nil?
|
|
57
57
|
|
|
58
|
-
s_status = active_server?(server, o_address, boot_options
|
|
59
|
-
boot_options[:coherent], s_status)
|
|
58
|
+
s_status = active_server?(server, o_address, boot_options, s_status)
|
|
60
59
|
|
|
61
60
|
till_server_active(s_status, hParams, o_address, boot_options)
|
|
62
61
|
|
|
@@ -154,44 +153,32 @@ class ForjCoreProcess
|
|
|
154
153
|
predef_keypair
|
|
155
154
|
end
|
|
156
155
|
|
|
157
|
-
def active_server?(o_server, o_address,
|
|
158
|
-
keypair_coherent, s_status
|
|
159
|
-
)
|
|
156
|
+
def active_server?(o_server, o_address, ssh_key, status)
|
|
160
157
|
if o_server[:attrs][:status] == :active
|
|
161
158
|
return :assign_ip if o_address[:public_ip].nil?
|
|
162
159
|
|
|
163
160
|
image = server_get_image o_server
|
|
164
161
|
|
|
165
|
-
s_msg =
|
|
166
|
-
|
|
167
|
-
"You can connect to '%s' with:\n"\
|
|
168
|
-
'ssh %s@%s -o StrictHostKeyChecking=no -i ',
|
|
169
|
-
o_address[:public_ip], o_server[:name],
|
|
170
|
-
image[:ssh_user], o_address[:public_ip])
|
|
162
|
+
s_msg = 'Your forj Maestro server is up and running and is publically'\
|
|
163
|
+
" accessible through IP '#{o_address[:public_ip]}'."
|
|
171
164
|
|
|
172
|
-
if keypair_coherent
|
|
173
|
-
s_msg += private_key_file
|
|
174
|
-
else
|
|
175
|
-
s_msg += ANSI.red(ANSI.bold('<no valid private key found>')) + "\n\n" +
|
|
176
|
-
ANSI.bold('Unfortunatelly') + ', Forj was not able to find a '\
|
|
177
|
-
'valid keypair to connect to your server.' \
|
|
178
|
-
"\nYou need to fix this issue to gain access to your server."
|
|
179
|
-
end
|
|
180
165
|
PrcLib.info(s_msg)
|
|
166
|
+
PrcLib.high_level_msg("\n%s\n", s_msg)
|
|
181
167
|
|
|
182
168
|
o_log = process_get(:server_log, 25)[:attrs][:output]
|
|
183
169
|
if /cloud-init boot finished/ =~ o_log
|
|
184
|
-
|
|
185
|
-
PrcLib.high_level_msg("\n%s\nThe forge is ready...\n", s_msg)
|
|
170
|
+
status = :active
|
|
186
171
|
else
|
|
187
|
-
PrcLib.
|
|
188
|
-
|
|
172
|
+
PrcLib.info(server_connect_info(o_server, image, o_address,
|
|
173
|
+
ssh_key, status))
|
|
174
|
+
PrcLib.high_level_msg("The forge is still building...\n")
|
|
175
|
+
status = :cloud_init
|
|
189
176
|
end
|
|
190
177
|
else
|
|
191
178
|
sleep 5
|
|
192
|
-
|
|
179
|
+
status = :starting
|
|
193
180
|
end
|
|
194
|
-
|
|
181
|
+
status
|
|
195
182
|
end
|
|
196
183
|
end
|
|
197
184
|
|
|
@@ -244,6 +231,8 @@ class ForjCoreProcess
|
|
|
244
231
|
pending_count = 0
|
|
245
232
|
server_error = 0
|
|
246
233
|
o_server = hParams.refresh[:server, :ObjectData]
|
|
234
|
+
server_name = o_server[:attrs, :name]
|
|
235
|
+
image = server_get_image o_server
|
|
247
236
|
|
|
248
237
|
while s_status != :active
|
|
249
238
|
if i_cur_act == 4
|
|
@@ -258,7 +247,7 @@ class ForjCoreProcess
|
|
|
258
247
|
if s_status == :restart
|
|
259
248
|
process_delete(:server)
|
|
260
249
|
PrcLib.message("Bad server '%s' removed. Creating a new one...",
|
|
261
|
-
|
|
250
|
+
server_name)
|
|
262
251
|
sleep(5)
|
|
263
252
|
process_create(:internet_server)
|
|
264
253
|
s_status = :starting
|
|
@@ -266,7 +255,10 @@ class ForjCoreProcess
|
|
|
266
255
|
next
|
|
267
256
|
end
|
|
268
257
|
|
|
269
|
-
|
|
258
|
+
unless o_server.refresh
|
|
259
|
+
sleep(5)
|
|
260
|
+
next
|
|
261
|
+
end
|
|
270
262
|
|
|
271
263
|
if o_server[:status] == :error
|
|
272
264
|
if server_error == 1
|
|
@@ -275,7 +267,7 @@ class ForjCoreProcess
|
|
|
275
267
|
server_error = 1
|
|
276
268
|
PrcLib.warning("The creation of server '%s' has currently failed. "\
|
|
277
269
|
'Trying to rebuild it, once before give up.',
|
|
278
|
-
|
|
270
|
+
server_name)
|
|
279
271
|
s_status = :restart
|
|
280
272
|
next
|
|
281
273
|
end
|
|
@@ -300,7 +292,6 @@ class ForjCoreProcess
|
|
|
300
292
|
lorj_detect(hParams, o_old_log, boot_options)
|
|
301
293
|
|
|
302
294
|
if pending_count == 60
|
|
303
|
-
image = server_get_image o_server
|
|
304
295
|
highlight = ANSI.yellow('-' * 40)
|
|
305
296
|
PrcLib.warning("No more server activity detected.\n"\
|
|
306
297
|
"#{highlight}\n"\
|
|
@@ -312,12 +303,17 @@ class ForjCoreProcess
|
|
|
312
303
|
"situation.\nYou can connect to the server if you "\
|
|
313
304
|
"want to.\nTo connect, use:\n"\
|
|
314
305
|
'ssh %s@%s -o StrictHostKeyChecking=no -i %s',
|
|
315
|
-
o_old_log,
|
|
306
|
+
o_old_log, server_name, image[:ssh_user],
|
|
316
307
|
o_address[:public_ip], boot_options[:keys])
|
|
317
308
|
end
|
|
318
309
|
end
|
|
319
310
|
sleep(5) if s_status != :active
|
|
320
311
|
end
|
|
312
|
+
PrcLib.info('The Forge build is over!')
|
|
313
|
+
msg = server_connect_info(o_server, image, o_address, boot_options,
|
|
314
|
+
s_status)
|
|
315
|
+
PrcLib.info(msg)
|
|
316
|
+
PrcLib.high_level_msg("\nThe forge is ready...\n#{msg}\n")
|
|
321
317
|
end
|
|
322
318
|
|
|
323
319
|
# Function to get the image data from the server
|
|
@@ -336,22 +332,6 @@ class ForjCoreProcess
|
|
|
336
332
|
|
|
337
333
|
# rubocop:enable CyclomaticComplexity
|
|
338
334
|
# rubocop:enable PerceivedComplexity
|
|
339
|
-
|
|
340
|
-
# Function to get the server, tracking errors
|
|
341
|
-
#
|
|
342
|
-
# *return*
|
|
343
|
-
# - Server found.
|
|
344
|
-
#
|
|
345
|
-
def load_server(server)
|
|
346
|
-
begin
|
|
347
|
-
found_server = process_get(:server, server[:attrs][:id])
|
|
348
|
-
rescue => e
|
|
349
|
-
PrcLib.error(e.message)
|
|
350
|
-
else
|
|
351
|
-
return found_server
|
|
352
|
-
end
|
|
353
|
-
server
|
|
354
|
-
end
|
|
355
335
|
end
|
|
356
336
|
|
|
357
337
|
# Functions for boot - build_forge
|
|
@@ -369,30 +349,74 @@ class ForjCoreProcess
|
|
|
369
349
|
end
|
|
370
350
|
end
|
|
371
351
|
image = hParams.refresh[:image]
|
|
372
|
-
s_msg =
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
while [ 1 = 1 ]
|
|
377
|
-
do
|
|
378
|
-
ssh %s@%s -o StrictHostKeyChecking=no -i %s tail -f /var/log/cloud-init.log
|
|
379
|
-
sleep 5
|
|
380
|
-
done
|
|
381
|
-
END
|
|
382
|
-
s_msg = format(s_msg, o_server[:name], image[:ssh_user],
|
|
383
|
-
o_address[:public_ip], boot_options[:keys]
|
|
384
|
-
)
|
|
385
|
-
unless boot_options[:coherent]
|
|
386
|
-
s_msg += ANSI.bold("\nUnfortunatelly") + " your current keypair' \
|
|
387
|
-
' is not usable to connect to your server.\nYou need to fix' \
|
|
388
|
-
' this issue to gain access to your server."
|
|
389
|
-
end
|
|
352
|
+
s_msg = "Public IP for server '#{o_address[:public_ip]}' is assigned."
|
|
353
|
+
s_msg += server_connect_info(o_server, image, o_address,
|
|
354
|
+
boot_options, s_status)
|
|
355
|
+
|
|
390
356
|
PrcLib.info(s_msg)
|
|
391
357
|
PrcLib.high_level_msg("\n%s\nThe forge is still building...\n", s_msg)
|
|
392
358
|
s_status = :cloud_init
|
|
393
359
|
s_status
|
|
394
360
|
end
|
|
395
361
|
|
|
362
|
+
# function to print out the ssh connection information to the user
|
|
363
|
+
#
|
|
364
|
+
# * *args*:
|
|
365
|
+
# - server : Server object with :name
|
|
366
|
+
# - image : Image object with :ssh_user
|
|
367
|
+
# - address: Server address with :public_ip
|
|
368
|
+
# - ssh_key: Server ssh keys with :keys
|
|
369
|
+
# - status : Boot status. If boot status is :active
|
|
370
|
+
# the msg will simply display how to connect to.
|
|
371
|
+
# otherwise, it display, how to show instant log.
|
|
372
|
+
#
|
|
373
|
+
# * *returns*:
|
|
374
|
+
# - msg : A composite message to display
|
|
375
|
+
def server_connect_info(server, image, address, ssh_key, status)
|
|
376
|
+
server_name = server.nil? ? 'undefined' : server[:name]
|
|
377
|
+
image_user = image.nil? ? 'undefined' : image[:ssh_user]
|
|
378
|
+
public_ip = address.nil? ? 'undefined' : address[:public_ip]
|
|
379
|
+
|
|
380
|
+
if ssh_key[:coherent]
|
|
381
|
+
private_key = ssh_key[:keys]
|
|
382
|
+
else
|
|
383
|
+
private_key ANSI.red(ANSI.bold('<no valid private key found>'))
|
|
384
|
+
more = "\n\n" +
|
|
385
|
+
ANSI.bold('Unfortunatelly') + ', Forj was not able to find a '\
|
|
386
|
+
'valid keypair to connect to your server.' \
|
|
387
|
+
"\nYou need to fix this issue to gain access to your server."
|
|
388
|
+
end
|
|
389
|
+
|
|
390
|
+
if status == :active
|
|
391
|
+
"Maestro is accessible through http://#{public_ip}. This will provide"\
|
|
392
|
+
" you access to your complete forge implemented by your blueprint.\n\n"\
|
|
393
|
+
'If you want to access your server through ssh, you have several '\
|
|
394
|
+
"options:\n- using `forj ssh`\n- using ssh cli with:\n"\
|
|
395
|
+
" ssh #{image_user}@#{public_ip} -o StrictHostKeyChecking=no -i "\
|
|
396
|
+
"#{private_key}\n\n"\
|
|
397
|
+
" You can also create a new host in your ssh config with:\n"\
|
|
398
|
+
" echo 'host c_#{server_name}\n"\
|
|
399
|
+
" hostname #{public_ip}\n"\
|
|
400
|
+
" identity_file #{private_key}\n"\
|
|
401
|
+
" User #{image_user}\n"\
|
|
402
|
+
" # If you need to set a proxy to access this server\n"\
|
|
403
|
+
" # ProxyCommand corkscrew web-proxy 8080 %%h %%p' >> "\
|
|
404
|
+
"~/.ssh/config\n"\
|
|
405
|
+
"\n So, you will be able to connect to your server with:\n"\
|
|
406
|
+
" ssh c_#{server_name}#{more}\n"
|
|
407
|
+
else
|
|
408
|
+
"Your forge is still building...\n"\
|
|
409
|
+
"Now, as soon as the server respond to the ssh port,\n"\
|
|
410
|
+
"you will be able to get a tail of the build with:\n"\
|
|
411
|
+
"while [ 1 = 1 ]\n"\
|
|
412
|
+
"do\n"\
|
|
413
|
+
" ssh #{image_user}@#{public_ip} -o StrictHostKeyChecking=no -i "\
|
|
414
|
+
"#{private_key} tail -f /var/log/cloud-init.log\n"\
|
|
415
|
+
" sleep 5\n"\
|
|
416
|
+
"done#{more}"
|
|
417
|
+
end
|
|
418
|
+
end
|
|
419
|
+
|
|
396
420
|
def analyze_log_output(output_options, s_status, hParams)
|
|
397
421
|
o_log = process_get(:server_log, 25)
|
|
398
422
|
return output_options if o_log.nil? || o_log.empty?
|
|
@@ -474,30 +498,15 @@ class ForjCoreProcess
|
|
|
474
498
|
o_address = params[:public_ip, :ObjectData]
|
|
475
499
|
blueprint = params[:blueprint]
|
|
476
500
|
instance_name = params[:instance_name]
|
|
477
|
-
s_msg =
|
|
478
|
-
|
|
479
|
-
|
|
480
|
-
instance_name
|
|
481
|
-
)
|
|
501
|
+
s_msg = "Your Forge '#{instance_name}' is ready and accessible from" \
|
|
502
|
+
" IP #{o_address[:public_ip]}."
|
|
503
|
+
|
|
482
504
|
# TODO: read the blueprint/layout to identify which services
|
|
483
505
|
# are implemented and can be accessible.
|
|
484
506
|
if blueprint
|
|
485
|
-
s_msg +=
|
|
486
|
-
|
|
487
|
-
|
|
488
|
-
blueprint
|
|
489
|
-
)
|
|
490
|
-
server_options = display_servers_with_ip(o_forge, s_msg)
|
|
491
|
-
s_msg += server_options[:message]
|
|
492
|
-
i_count = server_options[:count]
|
|
493
|
-
if i_count > 0
|
|
494
|
-
s_msg += format("\n%d server(s) identified.\n", i_count)
|
|
495
|
-
else
|
|
496
|
-
s_msg = 'No servers found except maestro'
|
|
497
|
-
PrcLib.warning('Something went wrong, while creating nodes for '\
|
|
498
|
-
"blueprint '%s'. check maestro logs "\
|
|
499
|
-
'(Usually /var/log/cloud-init.log).', blueprint)
|
|
500
|
-
end
|
|
507
|
+
s_msg += "\nMaestro has implemented the following server(s) for your"\
|
|
508
|
+
" blueprint '#{blueprint}':"
|
|
509
|
+
s_msg = display_servers_with_ip(o_forge, blueprint, s_msg)
|
|
501
510
|
else
|
|
502
511
|
s_msg += "\nMaestro has NOT implemented any servers, because you did" \
|
|
503
512
|
' not provided a blueprint. Connect to Maestro, and ask Maestro to' \
|
|
@@ -508,7 +517,7 @@ class ForjCoreProcess
|
|
|
508
517
|
PrcLib.high_level_msg("\n%s\nEnjoy!\n", s_msg)
|
|
509
518
|
end
|
|
510
519
|
|
|
511
|
-
def display_servers_with_ip(o_forge, s_msg)
|
|
520
|
+
def display_servers_with_ip(o_forge, blueprint, s_msg)
|
|
512
521
|
i_count = 0
|
|
513
522
|
o_forge[:servers].each do |_type, server|
|
|
514
523
|
next if /^maestro\./ =~ server[:name]
|
|
@@ -521,8 +530,21 @@ class ForjCoreProcess
|
|
|
521
530
|
end
|
|
522
531
|
i_count += 1
|
|
523
532
|
end
|
|
524
|
-
|
|
525
|
-
|
|
533
|
+
|
|
534
|
+
if i_count > 0
|
|
535
|
+
s_msg += format("\n%d server(s) identified.\n", i_count)
|
|
536
|
+
|
|
537
|
+
else
|
|
538
|
+
s_msg = 'No servers found except maestro'
|
|
539
|
+
PrcLib.warning('Something went wrong, while creating nodes for blueprint'\
|
|
540
|
+
" '#{blueprint}'. check maestro logs "\
|
|
541
|
+
"(Usually /var/log/cloud-init.log).\n"\
|
|
542
|
+
'Consider Lorj Gardener by setting :default/:lorj: '\
|
|
543
|
+
'false in /opt/config/lorj/config.yaml if puppet'\
|
|
544
|
+
' returned some strange ruby error.')
|
|
545
|
+
end
|
|
546
|
+
|
|
547
|
+
s_msg
|
|
526
548
|
end
|
|
527
549
|
end
|
|
528
550
|
|
|
@@ -728,11 +750,14 @@ class ForjCoreProcess
|
|
|
728
750
|
if b_rebuild_infra
|
|
729
751
|
PrcLib.state("Building your infra workspace in '%s'", infra)
|
|
730
752
|
|
|
731
|
-
|
|
732
|
-
|
|
753
|
+
if File.directory?(cloud_init)
|
|
754
|
+
PrcLib.debug("Copying recursively '%s' to '%s'", cloud_init, infra)
|
|
755
|
+
FileUtils.copy_entry(cloud_init, dest_cloud_init)
|
|
756
|
+
end
|
|
733
757
|
|
|
734
758
|
file_ver = File.join(infra, 'forj-cli.ver')
|
|
735
759
|
File.write(file_ver, INFRA_VERSION)
|
|
760
|
+
infra_cleanup(infra, maestro_repo)
|
|
736
761
|
PrcLib.info("The infra workspace '%s' has been built from maestro" \
|
|
737
762
|
' predefined files.', infra)
|
|
738
763
|
else
|
|
@@ -744,19 +769,57 @@ class ForjCoreProcess
|
|
|
744
769
|
o_infra
|
|
745
770
|
end
|
|
746
771
|
|
|
747
|
-
|
|
772
|
+
# check from the list of files under maestro control
|
|
773
|
+
# Do cleanup for files that disappeared.
|
|
774
|
+
#
|
|
775
|
+
# Then it update the hidden maestro controlled file.
|
|
776
|
+
#
|
|
777
|
+
def infra_cleanup(infra_dir, maestro_dir)
|
|
778
|
+
md5_list_file = File.join(infra_dir, '.maestro_original.yaml')
|
|
779
|
+
|
|
780
|
+
md5_list = {}
|
|
781
|
+
md5_list = YAML.load_file(md5_list_file) if File.exist?(md5_list_file)
|
|
782
|
+
|
|
783
|
+
cur_md5_list = {}
|
|
784
|
+
|
|
785
|
+
template_dir = File.join(maestro_dir, 'templates', 'infra')
|
|
786
|
+
cloud_init_dir = File.join(infra_dir, 'cloud-init')
|
|
787
|
+
|
|
788
|
+
load_infra(template_dir, cloud_init_dir, cur_md5_list)
|
|
789
|
+
|
|
790
|
+
md5_list.each do |path, _md5|
|
|
791
|
+
if cur_md5_list.key?(path)
|
|
792
|
+
md5_list[path] = cur_md5_list[path]
|
|
793
|
+
else
|
|
794
|
+
begin
|
|
795
|
+
File.delete(File.join(template_dir, path))
|
|
796
|
+
rescue
|
|
797
|
+
PrcLib.debug("'%s' infra file has already been removed.", path)
|
|
798
|
+
else
|
|
799
|
+
PrcLib.debug("'%s' infra file has been removed.", path)
|
|
800
|
+
end
|
|
801
|
+
md5_list.delete(path)
|
|
802
|
+
end
|
|
803
|
+
end
|
|
804
|
+
infra_save_md5(md5_list_file, md5_list)
|
|
805
|
+
end
|
|
806
|
+
|
|
807
|
+
def load_infra(template, dest_cloud_init, md5_list, is_original = false)
|
|
748
808
|
# We are taking care on bootstrap files only.
|
|
749
|
-
|
|
750
|
-
|
|
809
|
+
cloud_init_path = File.join(template, 'cloud-init')
|
|
810
|
+
return is_original unless File.directory?(cloud_init_path)
|
|
811
|
+
|
|
812
|
+
Find.find(cloud_init_path) do |path|
|
|
751
813
|
next if File.directory?(path)
|
|
814
|
+
file_original = true # By default we consider it to be original
|
|
752
815
|
s_maestro_rel_path = path.clone
|
|
753
|
-
s_maestro_rel_path[
|
|
816
|
+
s_maestro_rel_path[cloud_init_path + '/'] = ''
|
|
754
817
|
s_infra_path = File.join(dest_cloud_init, s_maestro_rel_path)
|
|
755
818
|
if File.exist?(s_infra_path)
|
|
756
819
|
md5_file = Digest::MD5.file(s_infra_path).hexdigest
|
|
757
|
-
if
|
|
758
|
-
|
|
759
|
-
|
|
820
|
+
if md5_list.key?(s_maestro_rel_path) &&
|
|
821
|
+
md5_list.rh_get(s_maestro_rel_path, :md5) != md5_file
|
|
822
|
+
file_original = false
|
|
760
823
|
PrcLib.info("'%s' infra file has changed from original template" \
|
|
761
824
|
' in maestro.', s_infra_path)
|
|
762
825
|
else
|
|
@@ -764,49 +827,51 @@ class ForjCoreProcess
|
|
|
764
827
|
end
|
|
765
828
|
end
|
|
766
829
|
md5_file = Digest::MD5.file(path).hexdigest
|
|
767
|
-
|
|
768
|
-
|
|
830
|
+
md5_list[s_maestro_rel_path] = { :md5 => md5_file,
|
|
831
|
+
:original => file_original }
|
|
832
|
+
is_original &= false
|
|
769
833
|
end
|
|
770
|
-
|
|
834
|
+
is_original
|
|
771
835
|
end
|
|
772
836
|
|
|
773
|
-
def
|
|
774
|
-
|
|
775
|
-
|
|
776
|
-
|
|
777
|
-
|
|
778
|
-
rescue => e
|
|
779
|
-
PrcLib.error("%s\n%s", e.message, e.backtrace.join("\n"))
|
|
780
|
-
# end
|
|
837
|
+
def infra_save_md5(md5_list_file, data)
|
|
838
|
+
File.open(md5_list_file, 'w') { |out| YAML.dump(data, out) }
|
|
839
|
+
rescue => e
|
|
840
|
+
PrcLib.error("File '%s': %s\n%s", md5_list_file, e.message,
|
|
841
|
+
e.backtrace.join("\n"))
|
|
781
842
|
end
|
|
782
843
|
end
|
|
783
844
|
|
|
784
845
|
# Functions for boot - create_or_use_infra
|
|
785
846
|
class ForjCoreProcess
|
|
786
847
|
# Function which compare directories from maestro templates to infra.
|
|
848
|
+
#
|
|
849
|
+
# * *return*:
|
|
850
|
+
# - true if the infra repository file contains some files managed by maestro
|
|
851
|
+
# which has not been updated manually.
|
|
852
|
+
# - false otherwise.
|
|
787
853
|
def infra_is_original?(infra_dir, maestro_dir)
|
|
788
854
|
dest_cloud_init = File.join(infra_dir, 'cloud-init')
|
|
789
855
|
template = File.join(maestro_dir, 'templates', 'infra')
|
|
790
856
|
return false unless File.exist?(template)
|
|
791
857
|
s_md5_list = File.join(infra_dir, '.maestro_original.yaml')
|
|
792
858
|
b_result = true
|
|
793
|
-
|
|
859
|
+
md5_list = {}
|
|
794
860
|
if File.exist?(s_md5_list)
|
|
795
861
|
begin
|
|
796
|
-
|
|
862
|
+
md5_list = YAML.load_file(s_md5_list)
|
|
797
863
|
rescue
|
|
798
864
|
PrcLib.error("Unable to load valid Original files list '%s'. " \
|
|
799
865
|
"Your infra workspace won't be migrated, until fixed.",
|
|
800
866
|
s_md5_list)
|
|
801
867
|
b_result = false
|
|
802
868
|
end
|
|
803
|
-
unless
|
|
804
|
-
|
|
869
|
+
unless md5_list
|
|
870
|
+
md5_list = {}
|
|
805
871
|
b_result = false
|
|
806
872
|
end
|
|
807
873
|
end
|
|
808
|
-
b_result = load_infra(template, dest_cloud_init,
|
|
809
|
-
open_md5(s_md5_list, h_result)
|
|
874
|
+
b_result = load_infra(template, dest_cloud_init, md5_list, b_result)
|
|
810
875
|
if b_result
|
|
811
876
|
PrcLib.debug(
|
|
812
877
|
'No original files found has been updated. Infra workspace' \
|
|
@@ -21,25 +21,21 @@ require 'lorj'
|
|
|
21
21
|
# lorj_account process functions
|
|
22
22
|
class ForjCoreProcess
|
|
23
23
|
def build_lorj_account(sObjectType, hParams)
|
|
24
|
-
|
|
24
|
+
map = {}
|
|
25
|
+
|
|
26
|
+
Lorj.data.meta_each do |section, key, data|
|
|
27
|
+
section_key = "#{section}##{key}"
|
|
28
|
+
|
|
29
|
+
next if data.nil? || data[:export].nil?
|
|
25
30
|
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
'credentials#tenant' => {},
|
|
31
|
-
'credentials#keypair_name' => {},
|
|
32
|
-
'services#compute' => {},
|
|
33
|
-
'services#network' => {},
|
|
34
|
-
'maestro#image_name' => { :keys => [:server, :image_name] },
|
|
35
|
-
'maestro#ssh_user' => { :keys => [:server, :ssh_user] },
|
|
36
|
-
'maestro#flavor_name' => { :keys => [:server, :flavor_name] },
|
|
37
|
-
'maestro#network_name' => { :keys => [:server, :network_name] },
|
|
38
|
-
'maestro#security_group' => { :keys => [:server, :security_group] },
|
|
39
|
-
'dns#domain_name' => {},
|
|
40
|
-
'network#webproxy' => {}
|
|
41
|
-
}
|
|
31
|
+
if data[:export].boolean?
|
|
32
|
+
map[section_key] = {} if data[:export]
|
|
33
|
+
next
|
|
34
|
+
end
|
|
42
35
|
|
|
36
|
+
map[section_key] = { :keys => data[:export] }
|
|
37
|
+
end
|
|
38
|
+
data = {}
|
|
43
39
|
data[:key], data[:data] = account_export(map, true, true,
|
|
44
40
|
:exclude => ['forj_core'])
|
|
45
41
|
data_registered = register(data, sObjectType)
|
metadata
CHANGED
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: forj
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 1.0.
|
|
4
|
+
version: 1.0.18
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- forj team
|
|
8
8
|
autorequire:
|
|
9
9
|
bindir: bin
|
|
10
10
|
cert_chain: []
|
|
11
|
-
date: 2015-
|
|
11
|
+
date: 2015-07-02 00:00:00.000000000 Z
|
|
12
12
|
dependencies:
|
|
13
13
|
- !ruby/object:Gem::Dependency
|
|
14
14
|
name: thor
|
|
@@ -128,14 +128,14 @@ dependencies:
|
|
|
128
128
|
requirements:
|
|
129
129
|
- - ">="
|
|
130
130
|
- !ruby/object:Gem::Version
|
|
131
|
-
version: 0.1.
|
|
131
|
+
version: 0.1.9
|
|
132
132
|
type: :runtime
|
|
133
133
|
prerelease: false
|
|
134
134
|
version_requirements: !ruby/object:Gem::Requirement
|
|
135
135
|
requirements:
|
|
136
136
|
- - ">="
|
|
137
137
|
- !ruby/object:Gem::Version
|
|
138
|
-
version: 0.1.
|
|
138
|
+
version: 0.1.9
|
|
139
139
|
- !ruby/object:Gem::Dependency
|
|
140
140
|
name: rake
|
|
141
141
|
requirement: !ruby/object:Gem::Requirement
|