corl 0.4.1 → 0.4.2
Sign up to get free protection for your applications and to get access to all the features.
- data/.gitmodules +1 -1
- data/Gemfile +1 -1
- data/Gemfile.lock +15 -8
- data/VERSION +1 -1
- data/bootstrap/os/ubuntu/00_base.sh +10 -1
- data/bootstrap/os/ubuntu/05_ruby.sh +6 -0
- data/bootstrap/os/ubuntu/06_puppet.sh +6 -6
- data/bootstrap/os/ubuntu/09_nucleon.sh +14 -0
- data/bootstrap/os/ubuntu/10_corl.sh +7 -2
- data/corl.gemspec +16 -9
- data/lib/CORL/action/authorize.rb +57 -0
- data/lib/CORL/action/bootstrap.rb +5 -0
- data/lib/CORL/action/destroy.rb +64 -0
- data/lib/CORL/action/exec.rb +9 -0
- data/lib/CORL/action/image.rb +39 -7
- data/lib/CORL/action/images.rb +4 -3
- data/lib/CORL/action/lookup.rb +2 -2
- data/lib/CORL/action/regions.rb +51 -0
- data/lib/CORL/action/seed.rb +1 -1
- data/lib/CORL/action/spawn.rb +8 -9
- data/lib/CORL/action/ssh.rb +74 -0
- data/lib/CORL/action/start.rb +37 -5
- data/lib/CORL/action/stop.rb +37 -5
- data/lib/CORL/configuration/file.rb +34 -7
- data/lib/CORL/event/puppet.rb +1 -1
- data/lib/CORL/machine/aws.rb +153 -0
- data/lib/CORL/machine/physical.rb +14 -5
- data/lib/CORL/machine/rackspace.rb +58 -0
- data/lib/CORL/network/default.rb +1 -1
- data/lib/CORL/node/aws.rb +40 -16
- data/lib/CORL/node/local.rb +4 -3
- data/lib/CORL/node/rackspace.rb +25 -7
- data/lib/CORL/provisioner/puppetnode.rb +11 -9
- data/lib/core/errors.rb +6 -0
- data/lib/core/mod/fog_aws_server.rb +38 -0
- data/lib/core/plugin/action.rb +3 -11
- data/lib/core/plugin/configuration.rb +20 -2
- data/lib/{CORL/machine/fog.rb → core/plugin/fog_machine.rb} +92 -92
- data/lib/core/plugin/{fog.rb → fog_node.rb} +20 -7
- data/lib/core/plugin/machine.rb +58 -37
- data/lib/core/plugin/network.rb +76 -111
- data/lib/core/plugin/node.rb +271 -87
- data/lib/core/plugin/provisioner.rb +1 -1
- data/lib/corl.rb +6 -14
- data/locales/en.yml +18 -1
- metadata +39 -32
- data/lib/CORL/node/google.rb +0 -111
- data/lib/core/util/ssh.rb +0 -286
data/lib/core/plugin/node.rb
CHANGED
@@ -8,27 +8,38 @@ class Node < CORL.plugin_class(:base)
|
|
8
8
|
#-----------------------------------------------------------------------------
|
9
9
|
# Node plugin interface
|
10
10
|
|
11
|
-
def normalize
|
11
|
+
def normalize(reload)
|
12
12
|
super
|
13
13
|
|
14
|
+
export.each do |name, value|
|
15
|
+
myself[name] = value
|
16
|
+
end
|
17
|
+
|
18
|
+
yield if block_given? # Chance to create a machine to feed hostname
|
19
|
+
|
14
20
|
ui.resource = hostname
|
15
21
|
logger = hostname
|
16
22
|
|
17
|
-
|
18
|
-
|
19
|
-
|
23
|
+
myself[:groups] = [ "all", plugin_provider.to_s, plugin_name.to_s ] | groups
|
24
|
+
|
25
|
+
unless reload
|
26
|
+
@cli_interface = Util::Liquid.new do |method, args, &code|
|
27
|
+
result = exec({ :commands => [ [ method, args ].flatten.join(' ') ] }) do |op, data|
|
28
|
+
code.call(op, data) if code
|
29
|
+
end
|
30
|
+
if result
|
31
|
+
result = result.first
|
32
|
+
alert(result.errors) unless result.errors.empty?
|
33
|
+
end
|
34
|
+
result
|
20
35
|
end
|
21
|
-
result = result.first
|
22
|
-
|
23
|
-
alert(result.errors) unless result.errors.empty?
|
24
|
-
result
|
25
|
-
end
|
26
36
|
|
27
|
-
|
28
|
-
|
29
|
-
|
37
|
+
@action_interface = Util::Liquid.new do |method, args, &code|
|
38
|
+
action(method, *args) do |op, data|
|
39
|
+
code.call(op, data) if code
|
40
|
+
end
|
30
41
|
end
|
31
|
-
end
|
42
|
+
end
|
32
43
|
end
|
33
44
|
|
34
45
|
#---
|
@@ -103,7 +114,7 @@ class Node < CORL.plugin_class(:base)
|
|
103
114
|
#-----------------------------------------------------------------------------
|
104
115
|
|
105
116
|
def groups
|
106
|
-
array(
|
117
|
+
array(myself[:groups])
|
107
118
|
end
|
108
119
|
|
109
120
|
#-----------------------------------------------------------------------------
|
@@ -129,33 +140,38 @@ class Node < CORL.plugin_class(:base)
|
|
129
140
|
#---
|
130
141
|
|
131
142
|
def id(reset = false)
|
132
|
-
myself[:id] = machine.plugin_name if reset || myself[:id].nil?
|
143
|
+
myself[:id] = machine.plugin_name if machine && ( reset || myself[:id].nil? )
|
133
144
|
myself[:id]
|
134
145
|
end
|
135
|
-
|
146
|
+
|
136
147
|
#---
|
137
148
|
|
138
149
|
def public_ip(reset = false)
|
139
|
-
myself[:public_ip] = machine.public_ip if reset || myself[:public_ip].nil?
|
150
|
+
myself[:public_ip] = machine.public_ip if machine && ( reset || myself[:public_ip].nil? )
|
140
151
|
myself[:public_ip]
|
141
152
|
end
|
142
153
|
|
143
154
|
def private_ip(reset = false)
|
144
|
-
myself[:private_ip] = machine.private_ip if reset || myself[:private_ip].nil?
|
155
|
+
myself[:private_ip] = machine.private_ip if machine && ( reset || myself[:private_ip].nil? )
|
145
156
|
myself[:private_ip]
|
146
157
|
end
|
147
158
|
|
148
159
|
#---
|
149
160
|
|
150
|
-
def hostname
|
151
|
-
|
152
|
-
|
161
|
+
def hostname
|
162
|
+
hostname = myself[:hostname]
|
163
|
+
|
164
|
+
if hostname.to_s != ui.resource.to_s
|
165
|
+
ui.resource = hostname
|
166
|
+
logger = hostname
|
167
|
+
end
|
168
|
+
hostname
|
153
169
|
end
|
154
170
|
|
155
171
|
#---
|
156
172
|
|
157
173
|
def state(reset = false)
|
158
|
-
myself[:state] = machine.state if reset || myself[:state].nil?
|
174
|
+
myself[:state] = machine.state if machine && ( reset || myself[:state].nil? )
|
159
175
|
myself[:state]
|
160
176
|
end
|
161
177
|
|
@@ -173,6 +189,7 @@ class Node < CORL.plugin_class(:base)
|
|
173
189
|
|
174
190
|
def ssh_port=ssh_port
|
175
191
|
myself[:ssh_port] = ssh_port
|
192
|
+
machine.init_ssh(ssh_port) if machine
|
176
193
|
end
|
177
194
|
|
178
195
|
def ssh_port
|
@@ -191,6 +208,13 @@ class Node < CORL.plugin_class(:base)
|
|
191
208
|
|
192
209
|
#---
|
193
210
|
|
211
|
+
def ssh_path(home_env_var = 'HOME', reset = false)
|
212
|
+
home = home(home_env_var, reset)
|
213
|
+
home ? File.join(home, '.ssh') : nil
|
214
|
+
end
|
215
|
+
|
216
|
+
#---
|
217
|
+
|
194
218
|
def private_key=private_key
|
195
219
|
myself[:private_key] = private_key
|
196
220
|
end
|
@@ -208,7 +232,7 @@ class Node < CORL.plugin_class(:base)
|
|
208
232
|
end
|
209
233
|
|
210
234
|
def public_key
|
211
|
-
config_key = myself[:
|
235
|
+
config_key = myself[:public_key]
|
212
236
|
return File.expand_path(config_key) if config_key
|
213
237
|
end
|
214
238
|
|
@@ -217,20 +241,16 @@ class Node < CORL.plugin_class(:base)
|
|
217
241
|
def machine_types # Must be set at machine level (queried)
|
218
242
|
machine.machine_types if machine
|
219
243
|
end
|
220
|
-
|
221
|
-
def machine_type=machine_type
|
222
|
-
myself[:machine_type] = machine_type
|
223
|
-
end
|
224
244
|
|
225
245
|
def machine_type(reset = false)
|
226
|
-
myself[:machine_type] = machine.machine_type if reset || myself[:machine_type].nil?
|
227
|
-
machine_type
|
246
|
+
myself[:machine_type] = machine.machine_type if machine && ( reset || myself[:machine_type].nil? )
|
247
|
+
machine_type = myself[:machine_type]
|
228
248
|
|
229
249
|
if machine_type.nil? && machine
|
230
250
|
if types = machine_types
|
231
251
|
unless types.empty?
|
232
|
-
machine_type
|
233
|
-
myself
|
252
|
+
machine_type = machine_type_id(types.first)
|
253
|
+
myself[:machine_type] = machine_type
|
234
254
|
end
|
235
255
|
end
|
236
256
|
end
|
@@ -284,7 +304,7 @@ class Node < CORL.plugin_class(:base)
|
|
284
304
|
end
|
285
305
|
|
286
306
|
def image(reset = false)
|
287
|
-
myself[:image] = machine.image if reset || myself[:image].nil?
|
307
|
+
myself[:image] = machine.image if machine && ( reset || myself[:image].nil? )
|
288
308
|
myself[:image]
|
289
309
|
end
|
290
310
|
|
@@ -303,6 +323,71 @@ class Node < CORL.plugin_class(:base)
|
|
303
323
|
#-----------------------------------------------------------------------------
|
304
324
|
# Machine operations
|
305
325
|
|
326
|
+
def attach_keys(keypair)
|
327
|
+
base_name = "#{plugin_provider}-#{plugin_name}"
|
328
|
+
save_config = {
|
329
|
+
:pull => false,
|
330
|
+
:push => false,
|
331
|
+
:message => "Updating SSH keys for node #{plugin_provider} (#{plugin_name})"
|
332
|
+
}
|
333
|
+
|
334
|
+
active = machine && machine.running?
|
335
|
+
result = run.authorize({ :public_key => keypair.ssh_key }) if active
|
336
|
+
success = false
|
337
|
+
|
338
|
+
if ! active || result.status == code.success
|
339
|
+
private_key = network.attach_data(:keys, "#{base_name}-id_#{keypair.type}", keypair.encrypted_key)
|
340
|
+
public_key = network.attach_data(:keys, "#{base_name}-id_#{keypair.type}.pub", keypair.ssh_key)
|
341
|
+
|
342
|
+
if private_key && public_key
|
343
|
+
FileUtils.chmod(0600, private_key)
|
344
|
+
FileUtils.chmod(0644, public_key)
|
345
|
+
|
346
|
+
save_config[:files] = [ private_key, public_key ]
|
347
|
+
|
348
|
+
myself.private_key = private_key
|
349
|
+
myself.public_key = public_key
|
350
|
+
|
351
|
+
success = save(extended_config(:key_save, save_config))
|
352
|
+
end
|
353
|
+
end
|
354
|
+
success
|
355
|
+
end
|
356
|
+
|
357
|
+
#---
|
358
|
+
|
359
|
+
def delete_keys
|
360
|
+
private_key = myself[:private_key]
|
361
|
+
public_key = myself[:public_key]
|
362
|
+
|
363
|
+
keys = []
|
364
|
+
keys << private_key if private_key
|
365
|
+
keys << public_key if public_key
|
366
|
+
|
367
|
+
success = true
|
368
|
+
|
369
|
+
unless keys.empty?
|
370
|
+
files = network.delete_attachments(keys)
|
371
|
+
|
372
|
+
if files && ! files.empty?
|
373
|
+
delete_setting(:private_key)
|
374
|
+
delete_setting(:public_key)
|
375
|
+
|
376
|
+
success = save(extended_config(:key_delete, {
|
377
|
+
:files => [ private_key, public_key ],
|
378
|
+
:pull => false,
|
379
|
+
:push => false,
|
380
|
+
:message => "Removing SSH keys for node #{plugin_provider} (#{plugin_name})"
|
381
|
+
}))
|
382
|
+
else
|
383
|
+
success = false
|
384
|
+
end
|
385
|
+
end
|
386
|
+
success
|
387
|
+
end
|
388
|
+
|
389
|
+
#---
|
390
|
+
|
306
391
|
def create_machine(name, provider, options = {})
|
307
392
|
CORL.create_plugin(:machine, provider, extended_config(name, options).import({ :meta => { :parent => myself }}))
|
308
393
|
end
|
@@ -447,6 +532,8 @@ class Node < CORL.plugin_class(:base)
|
|
447
532
|
|
448
533
|
#---
|
449
534
|
|
535
|
+
execute_block_on_receiver :exec
|
536
|
+
|
450
537
|
def exec(options = {})
|
451
538
|
results = nil
|
452
539
|
|
@@ -458,26 +545,33 @@ class Node < CORL.plugin_class(:base)
|
|
458
545
|
|
459
546
|
yield(:config, config) if block_given?
|
460
547
|
|
461
|
-
|
548
|
+
if local? && local_machine
|
549
|
+
active_machine = local_machine
|
550
|
+
|
551
|
+
config[:info_prefix] = "[#{hostname}] "
|
552
|
+
config[:error_prefix] = "[#{hostname}] "
|
553
|
+
else
|
554
|
+
active_machine = machine
|
555
|
+
end
|
462
556
|
|
463
557
|
if commands = config.get(:commands, nil)
|
464
|
-
render("Starting command execution: #{commands.join('; ')}")
|
465
558
|
results = active_machine.exec(commands, config.export) do |type, command, data|
|
466
|
-
|
467
|
-
|
468
|
-
|
469
|
-
|
559
|
+
unless local?
|
560
|
+
if type == :error
|
561
|
+
alert(data.gsub(/^\[[^\]]+\]\s*/, ''))
|
562
|
+
else
|
563
|
+
render(data.gsub(/^\[[^\]]+\]\s*/, ''))
|
564
|
+
end
|
470
565
|
end
|
471
|
-
yield(:progress, { :type => type, :command => command, :data => data })
|
566
|
+
yield(:progress, { :type => type, :command => command, :data => data }) if block_given?
|
472
567
|
end
|
473
568
|
end
|
474
569
|
|
475
570
|
success = true
|
476
571
|
results.each do |result|
|
477
|
-
success = false if result.status !=
|
572
|
+
success = false if result.status != code.success
|
478
573
|
end
|
479
574
|
if success
|
480
|
-
render("Successfully finished execution")
|
481
575
|
yield(:process, config) if block_given?
|
482
576
|
extension(:exec_success, { :config => config, :results => results })
|
483
577
|
end
|
@@ -496,11 +590,23 @@ class Node < CORL.plugin_class(:base)
|
|
496
590
|
|
497
591
|
#---
|
498
592
|
|
593
|
+
execute_block_on_receiver :command
|
594
|
+
|
499
595
|
def command(command, options = {})
|
596
|
+
config = Config.ensure(options)
|
597
|
+
as_admin = config.delete(:as_admin, false)
|
598
|
+
|
500
599
|
unless command.is_a?(CORL::Plugin::Command)
|
501
|
-
command = CORL.command(Config.new({ :command => command }).import(
|
600
|
+
command = CORL.command(Config.new({ :command => command }).import(config), :bash)
|
502
601
|
end
|
503
|
-
|
602
|
+
|
603
|
+
admin_command = ''
|
604
|
+
if as_admin
|
605
|
+
admin_command = 'sudo' if user.to_s == 'ubuntu'
|
606
|
+
admin_command = extension_set(:admin_command, admin_command, config)
|
607
|
+
end
|
608
|
+
|
609
|
+
results = exec({ :commands => [ "#{admin_command} #{command.to_s}".strip ] }) do |op, data|
|
504
610
|
yield(op, data) if block_given?
|
505
611
|
end
|
506
612
|
results.first
|
@@ -508,19 +614,34 @@ class Node < CORL.plugin_class(:base)
|
|
508
614
|
|
509
615
|
#---
|
510
616
|
|
617
|
+
execute_block_on_receiver :action
|
618
|
+
|
511
619
|
def action(provider, options = {})
|
512
|
-
|
513
|
-
|
620
|
+
codes :network_load_error
|
621
|
+
|
622
|
+
config = Config.ensure(options).defaults({
|
623
|
+
:log_level => Nucleon.log_level,
|
624
|
+
:net_remote => :edit,
|
625
|
+
:net_provider => network.plugin_provider
|
626
|
+
})
|
514
627
|
|
515
628
|
logger.info("Executing remote action #{provider} with encoded arguments: #{config.export.inspect}")
|
516
629
|
|
517
|
-
|
630
|
+
encoded_config = Util::CLI.encode(Util::Data.clean(config.export))
|
631
|
+
action_config = extended_config(:action, {
|
518
632
|
:command => provider,
|
519
633
|
:data => { :encoded => encoded_config }
|
520
634
|
})
|
521
|
-
|
635
|
+
|
636
|
+
result = command(:corl, { :subcommand => action_config, :as_admin => true }) do |op, data|
|
522
637
|
yield(op, data) if block_given?
|
523
|
-
end
|
638
|
+
end
|
639
|
+
|
640
|
+
# Update local network configuration so we capture any updates
|
641
|
+
if result.status == code.success && ! network.load({ :remote => config[:net_remote], :pull => true })
|
642
|
+
result.status = code.network_load_error
|
643
|
+
end
|
644
|
+
result
|
524
645
|
end
|
525
646
|
|
526
647
|
#---
|
@@ -529,6 +650,40 @@ class Node < CORL.plugin_class(:base)
|
|
529
650
|
@action_interface
|
530
651
|
end
|
531
652
|
|
653
|
+
#---
|
654
|
+
|
655
|
+
def terminal(options = {})
|
656
|
+
myself.status = code.unknown_status
|
657
|
+
|
658
|
+
if machine && machine.running?
|
659
|
+
config = Config.ensure(options)
|
660
|
+
|
661
|
+
if extension_check(:terminal, { :config => config })
|
662
|
+
logger.info("Launching terminal for node: #{plugin_name}")
|
663
|
+
|
664
|
+
if local? && local_machine
|
665
|
+
active_machine = local_machine
|
666
|
+
|
667
|
+
config[:info_prefix] = "[#{hostname}] "
|
668
|
+
config[:error_prefix] = "[#{hostname}] "
|
669
|
+
else
|
670
|
+
active_machine = machine
|
671
|
+
end
|
672
|
+
|
673
|
+
config[:private_keys] = private_key
|
674
|
+
|
675
|
+
myself.status = active_machine.terminal(user, config.export)
|
676
|
+
|
677
|
+
if status == code.success
|
678
|
+
extension(:exec_success, { :config => config })
|
679
|
+
end
|
680
|
+
end
|
681
|
+
else
|
682
|
+
logger.warn("Node #{plugin_name} does not have an attached machine or is not running so cannot launch terminal")
|
683
|
+
end
|
684
|
+
status == code.success
|
685
|
+
end
|
686
|
+
|
532
687
|
#---
|
533
688
|
|
534
689
|
def bootstrap(local_path, options = {})
|
@@ -547,14 +702,15 @@ class Node < CORL.plugin_class(:base)
|
|
547
702
|
:home_path_lookup_failure,
|
548
703
|
:auth_upload_failure,
|
549
704
|
:bootstrap_upload_failure,
|
550
|
-
:bootstrap_exec_failure
|
705
|
+
:bootstrap_exec_failure,
|
706
|
+
:reload_failure
|
551
707
|
|
552
708
|
if File.directory?(local_path)
|
553
709
|
if user_home || user_home = home(config.get(:home_env_var, 'HOME'), config.get(:force, false))
|
554
710
|
myself.status = code.success
|
555
711
|
|
556
712
|
# Transmit authorisation / credential files
|
557
|
-
package_files = [ '.fog', '.netrc', '.google-privatekey.p12' ]
|
713
|
+
package_files = [ '.fog', '.netrc', '.google-privatekey.p12', '.vimrc' ]
|
558
714
|
auth_files.each do |file|
|
559
715
|
package_files = file.gsub(local_path + '/', '')
|
560
716
|
end
|
@@ -581,16 +737,24 @@ class Node < CORL.plugin_class(:base)
|
|
581
737
|
|
582
738
|
# Execute bootstrap process
|
583
739
|
if status == code.success
|
584
|
-
remote_script = File.join(remote_bootstrap_path, bootstrap_init)
|
740
|
+
remote_script = File.join(remote_bootstrap_path, bootstrap_init)
|
741
|
+
|
742
|
+
myself[:bootstrap] = remote_script
|
585
743
|
|
586
|
-
result = command(remote_script) do |op, data|
|
744
|
+
result = command("HOSTNAME='#{hostname}' #{remote_script}", { :as_admin => true }) do |op, data|
|
587
745
|
yield("exec_#{op}".to_sym, data) if block_given?
|
588
746
|
data
|
589
747
|
end
|
590
748
|
|
591
|
-
if result.status
|
749
|
+
if result.status == code.success
|
750
|
+
# Reboot the machine
|
751
|
+
unless reload
|
752
|
+
warn('corl.core.node.bootstrap.reload')
|
753
|
+
myself.status = code.reload_failure
|
754
|
+
end
|
755
|
+
else
|
592
756
|
warn('corl.core.node.bootstrap.status', { :script => remote_script, :status => result.status })
|
593
|
-
myself.status = code.bootstrap_exec_failure
|
757
|
+
myself.status = code.bootstrap_exec_failure
|
594
758
|
end
|
595
759
|
end
|
596
760
|
end
|
@@ -612,10 +776,10 @@ class Node < CORL.plugin_class(:base)
|
|
612
776
|
id(true)
|
613
777
|
public_ip(true)
|
614
778
|
private_ip(true)
|
615
|
-
hostname(true)
|
616
779
|
state(true)
|
617
|
-
|
618
|
-
|
780
|
+
|
781
|
+
machine_type(false)
|
782
|
+
image(false)
|
619
783
|
|
620
784
|
# Provider or external configuration preparation
|
621
785
|
yield(config) if block_given?
|
@@ -641,6 +805,17 @@ class Node < CORL.plugin_class(:base)
|
|
641
805
|
|
642
806
|
yield(:config, config) if block_given?
|
643
807
|
success = machine.start(config.export)
|
808
|
+
success = save(config) if success
|
809
|
+
|
810
|
+
if success
|
811
|
+
if bootstrap_script = myself[:bootstrap]
|
812
|
+
result = command("HOSTNAME='#{hostname}' #{bootstrap_script}", { :as_admin => true }) do |op, data|
|
813
|
+
yield("bootstrap_#{op}".to_sym, data) if block_given?
|
814
|
+
data
|
815
|
+
end
|
816
|
+
success = false unless result.status == code.success && reload
|
817
|
+
end
|
818
|
+
end
|
644
819
|
|
645
820
|
if success && block_given?
|
646
821
|
process_success = yield(:process, config)
|
@@ -699,6 +874,7 @@ class Node < CORL.plugin_class(:base)
|
|
699
874
|
|
700
875
|
yield(:config, config) if block_given?
|
701
876
|
success = machine.create_image(config.export)
|
877
|
+
success = save(config) if success
|
702
878
|
|
703
879
|
if success && block_given?
|
704
880
|
process_success = yield(:process, config)
|
@@ -729,6 +905,17 @@ class Node < CORL.plugin_class(:base)
|
|
729
905
|
yield(:config, config) if block_given?
|
730
906
|
success = machine.stop(config.export)
|
731
907
|
|
908
|
+
myself.machine = nil
|
909
|
+
|
910
|
+
delete_setting(:id)
|
911
|
+
delete_setting(:public_ip)
|
912
|
+
delete_setting(:private_ip)
|
913
|
+
delete_setting(:ssh_port)
|
914
|
+
|
915
|
+
myself[:state] = :stopped
|
916
|
+
|
917
|
+
success = save(config) if success
|
918
|
+
|
732
919
|
if success && block_given?
|
733
920
|
process_success = yield(:process, config)
|
734
921
|
success = process_success if process_success == false
|
@@ -752,42 +939,39 @@ class Node < CORL.plugin_class(:base)
|
|
752
939
|
if machine && machine.created?
|
753
940
|
config = Config.ensure(options)
|
754
941
|
|
755
|
-
|
756
|
-
|
757
|
-
if config[:force]
|
758
|
-
run = true
|
759
|
-
else
|
760
|
-
choice = nil
|
761
|
-
begin
|
762
|
-
choice = ui.ask("Are you sure you want to permanently destroy (Y|N): #{plugin_name}?")
|
763
|
-
run = choice.upcase == "Y"
|
764
|
-
|
765
|
-
rescue Errors::UIExpectsTTY
|
766
|
-
run = false
|
767
|
-
end
|
768
|
-
end
|
769
|
-
|
770
|
-
if run
|
771
|
-
if extension_check(:destroy, { :config => config })
|
772
|
-
logger.info("Destroying node: #{plugin_name}")
|
942
|
+
if extension_check(:destroy, { :config => config })
|
943
|
+
logger.info("Destroying node: #{plugin_name}")
|
773
944
|
|
774
|
-
|
775
|
-
success = machine.destroy(config.export)
|
945
|
+
yield(:config, config) if block_given?
|
776
946
|
|
777
|
-
|
778
|
-
|
779
|
-
success = process_success if process_success == false
|
780
|
-
end
|
947
|
+
# Shut down machine
|
948
|
+
success = machine.destroy(config.export)
|
781
949
|
|
782
|
-
|
783
|
-
|
784
|
-
|
950
|
+
myself.machine = nil
|
951
|
+
|
952
|
+
# Remove SSH keys
|
953
|
+
if success && delete_keys
|
954
|
+
# Remove node information
|
955
|
+
network.delete_node(plugin_provider, plugin_name, false)
|
956
|
+
|
957
|
+
network.save({
|
958
|
+
:commit => true,
|
959
|
+
:remote => config.get(:remote, :edit),
|
960
|
+
:push => true
|
961
|
+
})
|
962
|
+
end
|
963
|
+
|
964
|
+
if success && block_given?
|
965
|
+
process_success = yield(:process, config)
|
966
|
+
success = process_success if process_success == false
|
967
|
+
end
|
968
|
+
|
969
|
+
if success
|
970
|
+
extension(:destroy_success, { :config => config })
|
785
971
|
end
|
786
|
-
else
|
787
|
-
logger.warn("Node #{plugin_name} does not have an attached machine or is not created so cannot be destroyed")
|
788
972
|
end
|
789
973
|
else
|
790
|
-
logger.
|
974
|
+
logger.warn("Node #{plugin_name} does not have an attached machine or is not created so cannot be destroyed")
|
791
975
|
end
|
792
976
|
success
|
793
977
|
end
|
data/lib/corl.rb
CHANGED
@@ -32,9 +32,6 @@ require 'rubygems'
|
|
32
32
|
require 'nucleon_base'
|
33
33
|
CORL = Nucleon
|
34
34
|
|
35
|
-
require 'tmpdir'
|
36
|
-
require 'sshkey'
|
37
|
-
|
38
35
|
require 'hiera'
|
39
36
|
require 'facter'
|
40
37
|
|
@@ -47,13 +44,6 @@ I18n.load_path << File.expand_path(File.join('..', 'locales', 'en.yml'), lib_dir
|
|
47
44
|
|
48
45
|
#---
|
49
46
|
|
50
|
-
# Object modifications (100% pure monkey patches)
|
51
|
-
Dir.glob(File.join(mod_dir, '*.rb')).each do |file|
|
52
|
-
require file
|
53
|
-
end
|
54
|
-
|
55
|
-
#---
|
56
|
-
|
57
47
|
# Mixins for classes
|
58
48
|
Dir.glob(File.join(mixin_dir, '*.rb')).each do |file|
|
59
49
|
require file
|
@@ -65,10 +55,12 @@ end
|
|
65
55
|
#---
|
66
56
|
|
67
57
|
# Include CORL utilities
|
68
|
-
[
|
69
|
-
|
70
|
-
|
71
|
-
|
58
|
+
#[].each do |name|
|
59
|
+
# nucleon_require(util_dir, name)
|
60
|
+
#end
|
61
|
+
|
62
|
+
# Special errors
|
63
|
+
nucleon_require(core_dir, :errors)
|
72
64
|
|
73
65
|
# Include facade
|
74
66
|
nucleon_require(core_dir, :facade)
|
data/locales/en.yml
CHANGED
@@ -90,7 +90,20 @@ en:
|
|
90
90
|
hostnames: |-
|
91
91
|
Hostnames of machines to create on provider infrastructure
|
92
92
|
start: |-
|
93
|
-
Spawning new machines on %{
|
93
|
+
Spawning new machines on %{node_provider}
|
94
|
+
ssh:
|
95
|
+
options:
|
96
|
+
errors:
|
97
|
+
ssh_nodes_empty: |-
|
98
|
+
Nodes must be specified in order to launch a SSH terminal
|
99
|
+
ssh_nodes: |-
|
100
|
+
Provider %{node_provider} node %{name} is not a valid node to launch terminal (%{value} given)
|
101
|
+
start: |-
|
102
|
+
Launching terminal for machine %{hostname} (%{id})
|
103
|
+
success: |-
|
104
|
+
Machine %{hostname} (%{id}) successfully ended terminal session
|
105
|
+
failure: |-
|
106
|
+
Machine %{hostname} (%{id}) terminal session failed with status %{status}
|
94
107
|
bootstrap:
|
95
108
|
options:
|
96
109
|
bootstrap_path: |-
|
@@ -112,6 +125,8 @@ en:
|
|
112
125
|
Bootstrap path must be an existing directory
|
113
126
|
auth_files: |-
|
114
127
|
Authorization file %{value} does not exist on the local system
|
128
|
+
bootstrap_nodes_empty: |-
|
129
|
+
Nodes must be specified in order to run the bootstrap action
|
115
130
|
bootstrap_nodes: |-
|
116
131
|
Provider %{node_provider} node %{name} is not a valid node to bootstrap (%{value} given)
|
117
132
|
start: |-
|
@@ -133,6 +148,8 @@ en:
|
|
133
148
|
errors:
|
134
149
|
project_reference: |-
|
135
150
|
Project reference %{value} failed to parse or provider %{provider} isn't loaded >> Possible providers: %{choices}
|
151
|
+
start: |-
|
152
|
+
Now seeding CORL node
|
136
153
|
provision:
|
137
154
|
options:
|
138
155
|
provider: |-
|