corl 0.5.6 → 0.5.7

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (58) hide show
  1. checksums.yaml +4 -4
  2. data/.gitignore +10 -1
  3. data/Gemfile +1 -0
  4. data/Gemfile.lock +4 -0
  5. data/README.rdoc +125 -517
  6. data/Rakefile +57 -0
  7. data/VERSION +1 -1
  8. data/bootstrap/os/ubuntu/00_base.sh +10 -7
  9. data/bootstrap/os/ubuntu/05_ruby.sh +4 -4
  10. data/corl.gemspec +32 -5
  11. data/info/AUTOMATION.rdoc +5 -0
  12. data/info/INSTALLATION.rdoc +163 -0
  13. data/info/PACKAGING.rdoc +171 -0
  14. data/info/PLUGINS.rdoc +57 -0
  15. data/info/TODO.rdoc +27 -0
  16. data/lib/CORL/configuration/file.rb +2 -2
  17. data/lib/CORL/machine/docker.rb +327 -0
  18. data/lib/CORL/machine/vagrant.rb +142 -107
  19. data/lib/CORL/node/docker.rb +269 -0
  20. data/lib/CORL/node/vagrant.rb +23 -0
  21. data/lib/CORL/provisioner/puppetnode.rb +52 -27
  22. data/lib/core/facade.rb +36 -34
  23. data/lib/core/mixin/builder.rb +44 -44
  24. data/lib/core/mixin/machine/ssh.rb +34 -34
  25. data/lib/core/mod/vagrant.rb +32 -0
  26. data/lib/core/plugin/cloud_action.rb +1 -1
  27. data/lib/core/plugin/machine.rb +85 -85
  28. data/lib/core/plugin/network.rb +23 -9
  29. data/lib/core/plugin/node.rb +10 -7
  30. data/lib/core/plugin/provisioner.rb +3 -3
  31. data/lib/core/vagrant/action.rb +15 -13
  32. data/lib/core/vagrant/actions/include_overrides.rb +17 -0
  33. data/lib/core/vagrant/actions/init_keys.rb +9 -5
  34. data/lib/core/vagrant/commands/launcher.rb +1 -1
  35. data/lib/core/vagrant/config.rb +343 -143
  36. data/lib/core/vagrant/plugins.rb +14 -14
  37. data/lib/corl.rb +3 -7
  38. data/lib/nucleon/action/node/provision.rb +15 -4
  39. data/lib/nucleon/action/node/seed.rb +2 -2
  40. data/lib/nucleon/extension/vagrant.rb +30 -0
  41. data/locales/en.yml +5 -0
  42. data/rdoc/site/0.5.7/README.rdoc +595 -0
  43. data/rdoc/site/0.5.7/info/AUTOMATION.rdoc +382 -0
  44. data/rdoc/site/0.5.7/info/INSTALLATION.rdoc +543 -0
  45. data/rdoc/site/0.5.7/info/PACKAGES.rdoc +556 -0
  46. data/rdoc/site/0.5.7/info/PACKAGING.rdoc +563 -0
  47. data/rdoc/site/0.5.7/info/PLUGINS.rdoc +534 -0
  48. data/rdoc/site/0.5.7/info/TODO.rdoc +412 -0
  49. data/tmp/README.rdoc +217 -0
  50. data/tmp/info/AUTOMATION.rdoc +6 -0
  51. data/tmp/info/INSTALLATION.rdoc +158 -0
  52. data/tmp/info/PACKAGES.rdoc +177 -0
  53. data/tmp/info/PACKAGING.rdoc +184 -0
  54. data/tmp/info/PLUGINS.rdoc +129 -0
  55. data/tmp/info/README.rdoc +217 -0
  56. data/tmp/info/TODO.rdoc +36 -0
  57. metadata +41 -3
  58. data/TODO.rdoc +0 -12
@@ -1,13 +1,13 @@
1
1
 
2
2
  #
3
3
  # Because we create configurations and operate on resulting machines during
4
- # the course of a single CLI command run we need to be able to reload the
5
- # configurations based on updates to fetch Vagrant VMs and run Vagrant machine
4
+ # the course of a single CLI command run we need to be able to reload the
5
+ # configurations based on updates to fetch Vagrant VMs and run Vagrant machine
6
6
  # actions. TODO: Inquire about some form of inclusion in Vagrant core?
7
7
  #
8
8
  module Vagrant
9
9
  class Vagrantfile
10
-
10
+
11
11
  def reload
12
12
  @loader.clear_config_cache(@keys)
13
13
  @config, _ = @loader.load(@keys)
@@ -18,15 +18,15 @@ module Config
18
18
  class Loader
19
19
  def clear_config_cache(sources = nil)
20
20
  @config_cache = {}
21
-
21
+
22
22
  if sources
23
23
  keep = {}
24
24
  sources.each do |source|
25
25
  keep[source] = @sources[source] if @sources[source]
26
26
  end
27
27
  @sources = keep
28
- end
29
- end
28
+ end
29
+ end
30
30
  end
31
31
  end
32
32
  end
@@ -36,299 +36,430 @@ end
36
36
  module CORL
37
37
  module Vagrant
38
38
  module Config
39
-
39
+
40
+ @@logger = Util::Logger.new('vagrant')
41
+
42
+ def self.logger
43
+ @@logger
44
+ end
45
+
46
+ #
47
+ # Vagrant node network container
48
+ #
40
49
  @@network = nil
41
-
50
+
42
51
  def self.network=network
43
52
  @@network = network
44
53
  end
45
-
54
+
46
55
  def self.network
47
56
  @@network
48
57
  end
49
-
50
-
58
+
59
+ #
60
+ # Whether or not we are re-rendering this configuration
61
+ #
62
+ @@rerender = false
63
+
51
64
  #
52
65
  # Gateway CORL configurator for Vagrant.
53
- #
66
+ #
54
67
  def self.register(directory, config, &code)
55
68
  ::Vagrant.require_version ">= 1.5.0"
56
-
57
- config_network = network
69
+
70
+ Nucleon.dump_enabled=true
71
+
72
+ config_network = network
58
73
  config_network = load_network(directory) unless config_network
59
-
74
+
60
75
  if config_network
61
76
  # Vagrant settings
62
77
  unless configure_vagrant(config_network, config.vagrant)
63
78
  raise "Configuration of Vagrant general settings failed"
64
79
  end
65
-
80
+
66
81
  config_network.nodes(:vagrant, true).each do |node_name, node|
67
82
  config.vm.define node.id.to_sym do |machine|
68
- # VM settings
69
- unless configure_vm(node, machine)
70
- raise "Configuration of Vagrant VM failed: #{node_name}"
71
- end
72
-
83
+ render("\n")
84
+ render("config.vm.define '#{node.id}' do |node|")
85
+
73
86
  # SSH settings
74
87
  unless configure_ssh(node, machine)
75
88
  raise "Configuration of Vagrant VM SSH settings failed"
76
89
  end
77
-
78
- # Server shares
79
- unless configure_shares(node, machine)
80
- raise "Configuration of Vagrant shares failed: #{node_name}"
90
+
91
+ # VM settings
92
+ unless configure_vm(node, machine)
93
+ raise "Configuration of Vagrant VM failed: #{node_name}"
81
94
  end
82
-
95
+
83
96
  # Provisioner configuration
84
97
  unless configure_provisioner(network, node, machine, &code)
85
98
  raise "Configuration of Vagrant provisioner failed: #{node_name}"
86
99
  end
87
- end
100
+ end
88
101
  end
89
102
  end
103
+ @@rerender = true
90
104
  end
91
-
105
+
92
106
  #---
93
-
107
+
94
108
  def self.load_network(directory)
95
109
  # Load network if it exists
96
110
  @@network = CORL.network(directory, CORL.config(:vagrant_network, { :directory => directory }))
97
111
  end
98
-
112
+
99
113
  #---
100
-
114
+
101
115
  def self.configure_vagrant(network, vagrant)
102
116
  success = true
103
117
  Util::Data.hash(network.settings(:vagrant_config)).each do |name, data|
104
118
  if vagrant.respond_to?("#{name}=")
105
119
  data = Util::Data.value(data)
106
- #dbg(name, 'vagrant property')
107
- #dbg(data, 'vagrant property data')
120
+ render("config.vagrant.#{name} = %property", { :property => data })
108
121
  vagrant.send("#{name}=", data)
109
122
  else
110
123
  params = parse_params(data)
111
- #dbg(name, 'vagrant method')
112
- #dbg(params, 'vagrant method params')
113
- vagrant.send(name, params)
124
+ render("config.vagrant.#{name} %params", { :params => params })
125
+ vagrant.send(name, params)
114
126
  end
115
127
  end
116
128
  success
117
129
  end
118
-
130
+
119
131
  #---
120
-
132
+
121
133
  def self.configure_ssh(node, machine)
122
134
  success = true
123
-
124
- #dbg(node.user, 'ssh user')
135
+
136
+ render(" node.ssh.username = %property", { :property => node.user })
125
137
  machine.ssh.username = node.user
126
-
127
- #dbg(node.ssh_port, 'ssh port')
138
+
139
+ render(" node.ssh.guest_port = %property", { :property => node.ssh_port })
128
140
  machine.ssh.guest_port = node.ssh_port
129
-
141
+
130
142
  if node.cache_setting(:use_private_key, false)
131
143
  key_dir = node.network.key_cache_directory
132
144
  key_name = node.plugin_name
133
-
134
- ssh_config = ::CORL::Config.new({
145
+
146
+ ssh_config = ::CORL::Config.new({
135
147
  :keypair => node.keypair,
136
148
  :key_dir => key_dir,
137
- :key_name => key_name
149
+ :key_name => key_name
138
150
  })
139
-
151
+
140
152
  if keypair = Util::SSH.unlock_private_key(node.private_key, ssh_config)
141
153
  if keypair.is_a?(String)
154
+ render(" node.ssh.private_key_path = %property", { :property => keypair })
142
155
  machine.ssh.private_key_path = keypair
143
156
  else
144
- node.keypair = keypair
145
- machine.ssh.private_key_path = keypair.private_key_file(key_dir, key_name)
157
+ private_key_file = keypair.private_key_file(key_dir, key_name)
158
+ node.keypair = keypair
159
+ render(" node.ssh.private_key_path = %property", { :property => private_key_file })
160
+ machine.ssh.private_key_path = private_key_file
146
161
  end
147
162
  end
148
163
  unless keypair && File.exists?(machine.ssh.private_key_path)
164
+ render(" node.ssh.private_key_path = %property", { :property => node.private_key })
149
165
  machine.ssh.private_key_path = node.private_key
150
166
  end
151
- #dbg(machine.ssh.private_key_path, 'ssh private key')
152
167
  end
153
-
168
+
169
+ render("\n")
170
+
154
171
  Util::Data.hash(node.ssh).each do |name, data|
155
172
  if machine.ssh.respond_to?("#{name}=")
156
173
  data = Util::Data.value(data)
157
- #dbg(name, 'ssh property')
158
- #dbg(data, 'ssh property data')
174
+ render(" node.ssh.#{name} = %property", { :property => data })
159
175
  machine.ssh.send("#{name}=", data)
160
176
  else
161
177
  params = parse_params(data)
162
- #dbg(name, 'ssh method')
163
- #dbg(params, 'ssh method params')
164
- machine.ssh.send(name, params)
178
+ render(" node.ssh.#{name} %params", { :params => params })
179
+ machine.ssh.send(name, params)
165
180
  end
166
181
  end
167
182
  success
168
183
  end
169
-
184
+
170
185
  #---
171
-
186
+
172
187
  def self.configure_vm(node, machine)
173
- vm_config = Util::Data.hash(node.vm)
188
+ vm_config = Util::Data.hash(Util::Data.clone(node.vm))
174
189
  success = true
175
-
176
- #dbg(node.hostname, 'VM hostname')
190
+
191
+ render(" node.vm.hostname = %property", { :property => node.hostname })
177
192
  machine.vm.hostname = node.hostname
178
-
179
- box = node.cache_setting(:box)
180
- box_url = node.cache_setting(:box_url)
181
-
193
+
194
+ box = node.cache_setting(:box)
195
+ box_url = node.cache_setting(:box_url)
196
+ box_file = nil
197
+
182
198
  if box_url
183
- box_file = box_url.gsub(/^file\:\/\//, '')
199
+ box_file = box_url.gsub(/^file\:\/\//, '')
184
200
  unless File.exists?(box_file)
185
- box_url = nil
201
+ box_url = nil
186
202
  node.clear_cache
187
203
  end
188
204
  end
189
-
190
- if box && box_url
191
- #dbg(box, 'VM box')
192
- machine.vm.box = box
193
- #dbg(box_url, 'VM box url')
194
- machine.vm.box_url = box_url
195
- else
196
- #dbg(node.image, 'VM box')
197
- machine.vm.box = node.image
205
+
206
+ if vm_config.has_key?(:private_network)
207
+ network_options = Util::Data.hash(vm_config[:private_network])
208
+
209
+ if node[:public_ip]
210
+ network_options[:ip] = node[:public_ip]
211
+ end
212
+ render(" node.vm.network :private_network, %params", { :params => network_options })
213
+ machine.vm.network :private_network, network_options
214
+ vm_config.delete(:private_network)
215
+ render("\n")
216
+
217
+ elsif vm_config.has_key?(:public_network)
218
+ network_options = Util::Data.hash(vm_config[:public_network])
219
+
220
+ render(" node.vm.network :public_network, %params", { :params => network_options })
221
+ machine.vm.network :public_network, network_options
222
+ vm_config.delete(:public_network)
223
+ render("\n")
198
224
  end
199
-
200
- unless vm_config.has_key?(:public_network)
201
- if node.public_ip
202
- #dbg(node.public_ip, 'private ip address')
203
- machine.vm.network :private_network, :ip => node.public_ip
204
- else
205
- #dbg('dhcp private ip address')
206
- machine.vm.network :private_network, :type => "dhcp"
225
+
226
+ if vm_config.has_key?(:provision)
227
+ Util::Data.array(vm_config[:provision]).each do |provisioner|
228
+ if provisioner.is_a?(String)
229
+ render(" node.vm.provision :#{provisioner}")
230
+ machine.vm.provision provisioner
231
+ else
232
+ provision_options = Util::Data.symbol_map(provisioner)
233
+ provision_type = provision_options.delete(:type)
234
+
235
+ if provision_type
236
+ render(" node.vm.provision :#{provision_type}, %params", { :params => provision_options })
237
+ machine.vm.provision provision_type, provision_options
238
+ end
239
+ end
207
240
  end
241
+ vm_config.delete(:provision)
208
242
  end
209
-
243
+
210
244
  vm_config.each do |name, data|
211
245
  case name.to_sym
212
246
  # Network interfaces
213
247
  when :forwarded_ports
214
248
  data.each do |forward_name, info|
215
249
  forward_config = CORL::Config.new({ :auto_correct => true }).import(info)
216
-
250
+
217
251
  forward_config.keys do |key|
218
252
  forward_config[key] = Util::Data.value(forward_config[key])
219
253
  end
220
- #dbg(forward_config.export, 'vm forwarded port config')
221
- machine.vm.network :forwarded_port, forward_config.export
254
+ forward_options = forward_config.export
255
+ render(" node.vm.network :forwarded_port, %params", { :params => forward_options })
256
+ machine.vm.network :forwarded_port, forward_options
222
257
  end
258
+ render("\n")
223
259
  when :usable_port_range
224
260
  low, high = data.to_s.split(/\s*--?\s*/)
225
- #dbg("#{low} <--> #{high}", 'vm usable port range')
261
+ render(" node.vm.usable_port_range = #{low}..#{high}")
226
262
  machine.vm.usable_port_range = Range.new(low, high)
227
-
228
- when :public_network
229
- #dbg('public network')
230
- machine.vm.network :public_network
231
-
263
+
232
264
  # Provider specific settings
233
265
  when :providers
234
266
  data.each do |provider, info|
235
- #dbg(provider, 'vm provider')
236
- machine.vm.provider provider.to_sym do |interface|
267
+ provider = provider.to_sym
268
+ info = Util::Data.symbol_map(info)
269
+ already_processed = {}
270
+
271
+ machine.vm.provider provider do |interface, override|
272
+ render(" node.vm.provider '#{provider}' do |provider, override| # for #{node.hostname}") unless already_processed[provider]
273
+
274
+ if box || box_url
275
+ if provider != :docker
276
+ if box && box_url
277
+ render(" override.vm.box = %property", { :property => box }) unless already_processed[provider]
278
+ override.vm.box = box
279
+
280
+ render(" override.vm.box_url = %property", { :property => box_url }) unless already_processed[provider]
281
+ override.vm.box_url = box_url
282
+ end
283
+ else
284
+ if box_file
285
+ render(" provider.build_dir = %property", { :property => box_file }) unless already_processed[provider]
286
+ interface.build_dir = box_file
287
+ else
288
+ render(" provider.image = %property", { :property => box }) unless already_processed[provider]
289
+ interface.image = box
290
+ end
291
+ end
292
+ render("\n")
293
+ end
294
+
295
+ if info.has_key?(:private_network)
296
+ network_options = info[:private_network].is_a?(Hash) ? info[:private_network] : { :ip => info[:private_network] }
297
+
298
+ render(" node.vm.network :private_network, %params", { :params => network_options }) unless already_processed[provider]
299
+ machine.vm.network :private_network, network_options
300
+ info.delete(:private_network)
301
+
302
+ elsif info.has_key?(:public_network)
303
+ network_options = info[:public_network].is_a?(Hash) ? info[:public_network] : { :ip => info[:public_network] }
304
+
305
+ render(" node.vm.network :public_network, %params", { :params => network_options })
306
+ machine.vm.network :public_network, network_options
307
+ info.delete(:public_network)
308
+ end
309
+
310
+ if info.has_key?(:override) && info[:override].has_key?(:provision)
311
+ Util::Data.array(info[:override][:provision]).each do |provisioner|
312
+ if provisioner.is_a?(String)
313
+ render(" override.vm.provision :#{provisioner}")
314
+ override.vm.provision provisioner
315
+ else
316
+ provision_options = Util::Data.symbol_map(provisioner)
317
+ provision_type = provision_options.delete(:type)
318
+
319
+ if provision_type
320
+ render(" override.vm.provision :#{provision_type}, %params", { :params => provision_options })
321
+ override.vm.provision provision_type, provision_options
322
+ end
323
+ end
324
+ end
325
+ info[:override].delete(:provision)
326
+ end
327
+
237
328
  info.each do |property, item|
238
- #dbg(property, 'vm property')
239
- #dbg(item, 'vm property item')
240
- if interface.respond_to?("#{property}=")
241
- interface.send("#{property}=", item)
329
+ if property.to_sym == :override
330
+ configure_provider_overrides(provider, machine, override, item, already_processed[provider], [], ' ')
242
331
  else
243
- params = parse_params(item)
244
- #dbg(params, 'vm method params')
245
- interface.send(property, params)
332
+ if interface.respond_to?("#{property}=")
333
+ render(" provider.#{property} = %property", { :property => item }) unless already_processed[provider]
334
+ interface.send("#{property}=", item)
335
+ else
336
+ params = parse_params(item)
337
+ render(" provider.#{property} %params", { :params => params }) unless already_processed[provider]
338
+ interface.send(property, params)
339
+ end
246
340
  end
247
341
  end
342
+
343
+ # Server shares
344
+ unless configure_shares(node, provider, override, already_processed[provider], ' ')
345
+ raise "Configuration of Vagrant shares failed: #{node_name}"
346
+ end
347
+
348
+ unless already_processed[provider]
349
+ render(" end")
350
+ render("\n")
351
+ end
352
+ already_processed[provider] = 1
248
353
  end
249
354
  end
250
355
  # All other basic VM settings...
251
356
  else
252
357
  if machine.vm.respond_to?("#{name}=")
253
- #dbg(name, 'other property')
254
- #dbg(data, 'other property data')
358
+ render(" node.vm.#{name} = %property", { :property => data })
255
359
  machine.vm.send("#{name}=", data)
256
360
  else
257
361
  params = parse_params(data)
258
- #dbg(name, 'other method')
259
- #dbg(params, 'other method params')
362
+ render(" node.vm.#{name} %params", { :params => params })
260
363
  machine.vm.send(name, params)
261
364
  end
262
- end
365
+ end
366
+ render("\n")
263
367
  end
264
368
  success
265
369
  end
266
-
370
+
267
371
  #---
268
-
269
- def self.configure_shares(node, machine)
372
+
373
+ def self.configure_shares(node, provider, machine, already_processed, indent = '')
374
+ use_nfs = provider.to_sym != :docker
270
375
  bindfs_installed = Gems.exist?('vagrant-bindfs')
271
376
  success = true
272
-
273
- if bindfs_installed
377
+
378
+ if use_nfs && bindfs_installed
274
379
  machine.vm.synced_folder ".", "/vagrant", disabled: true
275
380
  machine.vm.synced_folder ".", "/tmp/vagrant", :type => "nfs"
276
381
  machine.bindfs.bind_folder "/tmp/vagrant", "/vagrant"
277
382
  end
278
-
383
+
384
+ render("\n") unless already_processed
385
+
279
386
  Util::Data.hash(node.shares).each do |name, options|
280
- config = CORL::Config.ensure(options)
281
- share_type = config.get(:type, nil)
387
+ config = CORL::Config.ensure(options)
388
+
389
+ if config[:type].to_sym == :nfs && ! use_nfs
390
+ config.delete(:type)
391
+ end
392
+
393
+ share_type = config.get(:type, nil)
282
394
  local_dir = config.delete(:local, '')
283
395
  remote_dir = config.delete(:remote, '')
284
-
396
+
285
397
  config.init(:create, true)
286
-
398
+
287
399
  unless local_dir.empty? || remote_dir.empty?
288
400
  bindfs_options = config.delete(:bindfs, {})
289
401
  share_options = {}
290
-
402
+
291
403
  config.keys.each do |key|
292
404
  share_options[key] = Util::Data.value(config[key])
293
- end
294
-
405
+ end
406
+
295
407
  if share_type && share_type.to_sym == :nfs && bindfs_installed
296
408
  final_dir = remote_dir
297
409
  remote_dir = [ '/tmp', remote_dir.sub(/^\//, '') ].join('/')
298
-
299
- #dbg(remote_dir, 'vm bindfs local')
300
- #dbg(final_dir, 'vm bindfs remote')
301
- #dbg(bindfs_options, 'vm bindfs options')
410
+
411
+ render("#{indent}override.bindfs.bind_folder '#{remote_dir}', '#{final_dir}', %params", { :params => bindfs_options }) unless already_processed
302
412
  machine.bindfs.bind_folder remote_dir, final_dir, bindfs_options
303
413
  end
304
-
305
- #dbg(local_dir, 'vm share local')
306
- #dbg(remote_dir, 'vm share remote')
307
- #dbg(share_options, 'vm share options')
414
+
415
+ render("#{indent}override.vm.synced_folder '#{local_dir}', '#{remote_dir}', %params", { :params => share_options }) unless already_processed
308
416
  machine.vm.synced_folder local_dir, remote_dir, share_options
309
417
  end
310
- end
418
+ end
311
419
  success
312
420
  end
313
-
421
+
314
422
  #---
315
-
423
+
316
424
  def self.configure_provisioner(network, node, machine, &code)
317
425
  success = true
318
-
319
- # CORL provisioning
320
- machine.vm.provision :corl do |provisioner|
321
- provisioner.network = network
322
- provisioner.node = node
323
-
324
- code.call(node, machine, provisioner) if code
426
+
427
+ unless node[:docker_host]
428
+ # CORL provisioning
429
+ machine.vm.provision :corl do |provisioner|
430
+ provisioner.network = network
431
+ provisioner.node = node
432
+
433
+ code.call(node, machine, provisioner) if code
434
+ end
435
+ end
436
+ success
437
+ end
438
+
439
+ #---
440
+
441
+ def self.configure_provider_overrides(provider, machine, config, data, already_processed, parents = [], indent = '')
442
+ data.each do |name, info|
443
+ label = (parents.empty? ? name : "#{parents.join('.')}.#{name}")
444
+
445
+ if info.is_a?(Hash)
446
+ configure_provider_overrides(provider, machine.send(name), config.send(name), info, already_processed, [ parents, name].flatten, indent)
447
+ else
448
+ if machine.respond_to?("#{name}=")
449
+ render("#{indent}override.#{label} = %property", { :property => info }) unless already_processed
450
+ config.send("#{name}=", info)
451
+ else
452
+ params = parse_params(info)
453
+ render("#{indent}override.#{label} %params", { :params => params }) unless already_processed
454
+ config.send(name, params)
455
+ end
456
+ end
325
457
  end
326
- success
327
458
  end
328
-
459
+
329
460
  #---
330
-
331
- def self.parse_params(data)
461
+
462
+ def self.parse_params(data)
332
463
  params = data
333
464
  if data.is_a?(Hash)
334
465
  params = []
@@ -345,6 +476,75 @@ module Config
345
476
  end
346
477
  params
347
478
  end
479
+
480
+ #---
481
+
482
+ def self.render(statement, inputs = {})
483
+ return unless [ :debug, :info, :warn, :error ].include?(Nucleon.log_level)
484
+
485
+ if statement =~ /^\s+$/
486
+ puts statement
487
+ else
488
+ Util::Data.clone(inputs).each do |name, data|
489
+ rendered_data = render_value(data)
490
+
491
+ if rendered_data.empty?
492
+ statement.gsub!(/,\s*$/, '')
493
+ end
494
+ statement.gsub!("\%#{name}", rendered_data)
495
+ end
496
+ Core.ui_group('') do |ui|
497
+ ui.success(statement, { :prefix => false })
498
+ end
499
+ end
500
+ end
501
+
502
+ #---
503
+
504
+ def self.render_value(data)
505
+ rendered_value = ''
506
+
507
+ case data
508
+ when Hash
509
+ keypairs = []
510
+ data.each do |name, value|
511
+ keypairs << "#{name}: " + render_value(value)
512
+ end
513
+ rendered_value = keypairs.join(', ')
514
+ when Array
515
+ unless data.empty?
516
+ data.collect! {|value| render_value(value) }
517
+ rendered_value = '[' + data.join(', ') + ']'
518
+ end
519
+ when String
520
+ if check_numeric(data) || data[0] == ':'
521
+ rendered_value = data.to_s
522
+ else
523
+ if data =~ /\'/
524
+ rendered_value = "\"#{data}\""
525
+ else
526
+ rendered_value = "'#{data}'"
527
+ end
528
+ end
529
+ when Symbol
530
+ rendered_value = ":#{data}"
531
+ else
532
+ rendered_value = data.to_s
533
+ end
534
+ rendered_value
535
+ end
536
+
537
+ #---
538
+
539
+ def self.check_numeric(string)
540
+ return true if string =~ /^\d+$/
541
+ begin
542
+ Float(string)
543
+ return true
544
+ rescue
545
+ return false
546
+ end
547
+ end
348
548
  end
349
549
  end
350
550
  end