Module: Nucleon::Facade

Includes:
Mixin::Colors
Included in:
Nucleon
Defined in:
lib/core/facade.rb

Overview


Core Nucleon facade (extend Facade)

Constant Summary collapse

@@ip_cache =

nil
@@exec_state =

nil

Instance Method Summary collapse

Methods included from Mixin::Colors

#black, #blue, #cyan, #green, #grey, #purple, #red, #yellow

Instance Method Details

#action(provider, options) ⇒ Object




355
356
357
# File 'lib/core/facade.rb', line 355

def action(provider, options)
  plugin(:nucleon, :action, provider, options)
end

#action_cli(provider, args = [], quiet = false, name = :nucleon, display_errors = true, state = nil) ⇒ Object



375
376
377
# File 'lib/core/facade.rb', line 375

def action_cli(provider, args = [], quiet = false, name = :nucleon, display_errors = true, state = nil)
  Plugin::Action.exec_cli(provider, args, quiet, name, display_errors, state)
end

#action_config(provider) ⇒ Object



363
364
365
366
367
368
369
# File 'lib/core/facade.rb', line 363

def action_config(provider)
  action = action(provider, { :settings => {}, :quiet => true })
  return {} unless action

  action.configure
  action.config
end

#action_help(action = nil, extended_help = false) ⇒ Object



392
393
394
# File 'lib/core/facade.rb', line 392

def action_help(action = nil, extended_help = false)
  Plugin::Action.action_help(action, extended_help)
end

#action_run(provider, options = {}, quiet = true, display_errors = true, state = nil) ⇒ Object



371
372
373
# File 'lib/core/facade.rb', line 371

def action_run(provider, options = {}, quiet = true, display_errors = true, state = nil)
  Plugin::Action.exec(provider, options, quiet, display_errors, state)
end

#actions(data, build_hash = false, keep_array = false) ⇒ Object



359
360
361
# File 'lib/core/facade.rb', line 359

def actions(data, build_hash = false, keep_array = false)
  plugins(:nucleon, :action, data, build_hash, keep_array)
end

#active_plugins(namespace = nil, plugin_type = nil, provider = nil) ⇒ Object




298
299
300
# File 'lib/core/facade.rb', line 298

def active_plugins(namespace = nil, plugin_type = nil, provider = nil)
  Manager.connection.active_plugins(namespace, plugin_type, provider)
end

#admin?Boolean


Returns:

  • (Boolean)


172
173
174
175
176
177
178
179
180
181
182
183
184
# File 'lib/core/facade.rb', line 172

def admin?
  is_admin = ( ENV['USER'] == 'root' )
  unless is_admin
    ext_admin = exec(:check_admin) do |op, results|
      if op == :reduce
        results.values.include?(true)
      else
        results ? true : false
      end
    end
  end
  is_admin || ext_admin ? true : false
end

#check(method, options = {}) ⇒ Object




462
463
464
# File 'lib/core/facade.rb', line 462

def check(method, options = {})
  Manager.connection.check(method, options)
end

#class_const(name, separator = '::') ⇒ Object




601
602
603
# File 'lib/core/facade.rb', line 601

def class_const(name, separator = '::')
  Manager.connection.class_const(name, separator)
end

#class_name(name, separator = '::', want_array = false) ⇒ Object


Utilities



595
596
597
# File 'lib/core/facade.rb', line 595

def class_name(name, separator = '::', want_array = false)
  Manager.connection.class_name(name, separator, want_array)
end

#cli_run(command, options = {}, &code) ⇒ Object




499
500
501
502
503
504
505
506
507
508
509
510
511
# File 'lib/core/facade.rb', line 499

def cli_run(command, options = {}, &code)
  command = command.join(' ') if command.is_a?(Array)
  config  = Config.ensure(options)

  logger.info("Executing command #{command}")

  result = Util::Shell.connection.exec(command, config, &code)

  unless config.get(:quiet, false) || result.status == Nucleon.code.success
    ui.error("Command #{command} failed to execute")
  end
  result
end

#codeObject


Status codes



230
231
232
# File 'lib/core/facade.rb', line 230

def code
  Codes.new
end

#codes(*codes) ⇒ Object



234
235
236
# File 'lib/core/facade.rb', line 234

def codes(*codes)
  Codes.codes(*codes)
end

#collect(method, options = {}) ⇒ Object




474
475
476
# File 'lib/core/facade.rb', line 474

def collect(method, options = {})
  Manager.connection.collect(method, options)
end

#command(options, provider = nil) ⇒ Object


Utility plugin type facade



409
410
411
# File 'lib/core/facade.rb', line 409

def command(options, provider = nil)
  plugin(:nucleon, :command, provider, options)
end

#commands(data, build_hash = false, keep_array = false) ⇒ Object



413
414
415
# File 'lib/core/facade.rb', line 413

def commands(data, build_hash = false, keep_array = false)
  plugins(:nucleon, :command, data, build_hash, keep_array)
end

#config(type, options = {}) ⇒ Object




456
457
458
# File 'lib/core/facade.rb', line 456

def config(type, options = {})
  Manager.connection.config(type, options)
end

#create_plugin(namespace, plugin_type, provider, options = {}) ⇒ Object




316
317
318
# File 'lib/core/facade.rb', line 316

def create_plugin(namespace, plugin_type, provider, options = {})
  Manager.connection.create(namespace, plugin_type, provider, options)
end

#define_types(namespace, type_info) ⇒ Object



257
258
259
# File 'lib/core/facade.rb', line 257

def define_types(namespace, type_info)
  Manager.connection.define_types(namespace, type_info)
end

#event(options, provider = nil) ⇒ Object




419
420
421
# File 'lib/core/facade.rb', line 419

def event(options, provider = nil)
  plugin(:nucleon, :event, provider, options)
end

#events(data, build_hash = false, keep_array = false) ⇒ Object



423
424
425
# File 'lib/core/facade.rb', line 423

def events(data, build_hash = false, keep_array = false)
  plugins(:nucleon, :event, data, build_hash, keep_array)
end

#exec(method, options = {}, &code) ⇒ Object


Plugin extensions



450
451
452
# File 'lib/core/facade.rb', line 450

def exec(method, options = {}, &code)
  Manager.connection.exec(method, options, &code)
end

#executable(args, name = 'nucleon') ⇒ Object

ARGV



522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
# File 'lib/core/facade.rb', line 522

def executable(args, name = 'nucleon') #ARGV
  $0 = name.to_s # Set process name

  $stdout.sync = true
  $stderr.sync = true

  @@exec_state = executable_state
  exit_status  = code.unknown_status

  # We need to catch this early.
  Util::Console.use_colors = ! args.include?("--no-color")
  args = args - [ "--no-color", "--color" ]

  begin
    arg_components = Util::CLI::Parser.split(args, cyan(name) + yellow(" <action components> [<arg> ...]"))
    main_command   = arg_components.shift

    logger.info("Beginning #{name} execution run with arguments: #{args.inspect}")

    exec(:executable_load)
    load_plugins

    exec(:executable_init, { :name => name, :args => args })

    action, action_components, args = search_actions(args)

    if main_command.processed && action.is_a?(Hash)
      action_cli(action[:provider], args, false, name, false, @@exec_state)

      action_error = @@exec_state.error
      exit_status  = @@exec_state.status
    else
      puts I18n.t('nucleon.core.exec.help.usage') + ': ' + main_command.help + "\n"
      puts I18n.t('nucleon.core.exec.help.header') + ":\n"

      action = main_command.processed ? action : nil
      puts action_help(action, args.include?("--help"))

      puts "\n" + I18n.t('nucleon.core.exec.help.footer', { :command => cyan(name) + yellow(" <action> -h") }) + "\n\n"
      exit_status = code.help_wanted
    end

  rescue => error
    action_error = error
    exit_status  = code.unknown_status
  end

  if action_error && ! action_error.is_a?(SystemExit)
    logger.error("Nucleon executable experienced an error:")
    logger.error(action_error.inspect)
    logger.error(action_error.message)
    logger.error(Util::Data.to_yaml(action_error.backtrace))

    ui.error(action_error.message, { :prefix => false }) if action_error.message
  end
  exec(:executable_exit, { :status => exit_status })
  exit_status
end

#executable_stateObject



518
519
520
# File 'lib/core/facade.rb', line 518

def executable_state
  Plugin::Action::State.new(code.unknown_status)
end

#extension(provider) ⇒ Object


Core plugin type facade



349
350
351
# File 'lib/core/facade.rb', line 349

def extension(provider)
  plugin(:nucleon, :extension, provider, {})
end

#get_plugin(namespace, plugin_type, plugin_name) ⇒ Object




322
323
324
# File 'lib/core/facade.rb', line 322

def get_plugin(namespace, plugin_type, plugin_name)
  Manager.connection.get(namespace, plugin_type, plugin_name)
end

#handle(klass) ⇒ Object




128
129
130
131
132
133
134
135
# File 'lib/core/facade.rb', line 128

def handle(klass)
  if parallel? && klass.respond_to?(:current_actor)
    myself = klass.current_actor
  else
    myself = klass
  end
  myself
end

#interrupt_handlerObject




583
584
585
586
587
588
589
590
# File 'lib/core/facade.rb', line 583

def interrupt_handler
  logger.warn("Nucleon executable interrupted, shutting down")
  if @@exec_state.action
    @@exec_state.action.status = code.action_interrupted
    @@exec_state.action.finalize_execution(false)
  end
  code.action_interrupted
end

#ip_address(reset = false) ⇒ Object



190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
# File 'lib/core/facade.rb', line 190

def ip_address(reset = false)
  external_ip    = nil
  cached_ip_file = File.join(Dir.tmpdir(), 'nucleon_ip.json')

  unless @@ip_cache
    json_text  = Util::Data.ensure_value(Util::Disk.read(cached_ip_file), '')
    @@ip_cache = Util::Data.parse_json(json_text) unless json_text.empty?
  end

  fetch_ip = lambda do
    ip_command = value(:external_address_command, 'curl --silent ifconfig.me')
    ip_address = `#{ip_command}`.strip

    unless ip_address.empty?
      @@ip_cache = {
        'ip'      => ip_address,
        'updated' => Time.new.to_s
      }
      Util::Disk.write(cached_ip_file, Util::Data.to_json(@@ip_cache))
    end
    ip_address
  end

  if reset || (! @@ip_cache || @@ip_cache.empty? || ! @@ip_cache.has_key?('ip'))
    external_ip = fetch_ip.call
  else
    external_ip    = @@ip_cache['ip']
    updated_time   = Time.parse(@@ip_cache['updated'])
    cache_duration = (Time.new - updated_time) / 60 # Seconds to minutes

    if cache_duration >= value(:external_address_lifetime, 360)
      external_ip = fetch_ip.call
    end
  end
  external_ip
end

#load_plugins(base_dir = nil, search_parents = true) ⇒ Object




267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
# File 'lib/core/facade.rb', line 267

def load_plugins(base_dir = nil, search_parents = true)
  base_dir = base_dir.nil? ? Dir.pwd : base_dir

  search_plugins = lambda do |search_dir|
    lib_dir = File.join(search_dir, 'lib')

    if File.directory?(lib_dir)
      logger.debug("Registering plugins at #{lib_dir}")
      register(lib_dir)
    end

    if search_parents
      parent_search_dir = search_dir.sub(/#{File::SEPARATOR}[^#{File::SEPARATOR}]+$/, '')
      search_plugins.call(parent_search_dir) unless parent_search_dir.split(File::SEPARATOR).empty?
    end
  end

  search_plugins.call(base_dir)
end

#loaded_plugins(namespace = nil, plugin_type = nil, provider = nil) ⇒ Object



292
293
294
# File 'lib/core/facade.rb', line 292

def loaded_plugins(namespace = nil, plugin_type = nil, provider = nil)
  Manager.connection.loaded_plugins(namespace, plugin_type, provider)
end

#log_levelObject



118
119
120
# File 'lib/core/facade.rb', line 118

def log_level
  Util::Logger.level
end

#log_level=(log_level) ⇒ Object



122
123
124
# File 'lib/core/facade.rb', line 122

def log_level=log_level
  Util::Logger.level = log_level
end

#loggerObject




114
115
116
# File 'lib/core/facade.rb', line 114

def logger
  Core.logger
end

#manager(collection, name, klass, reset = false) ⇒ Object




139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
# File 'lib/core/facade.rb', line 139

def manager(collection, name, klass, reset = false)
  name     = name.to_sym
  actor_id = "#{klass}::#{name}".to_sym

  if collection.has_key?(actor_id)
    manager = parallel? ? Celluloid::Actor[actor_id] : collection[actor_id]
  else
    if parallel?
      klass.supervise_as(actor_id, actor_id, reset)
      manager = Celluloid::Actor[actor_id]
    else
      manager = klass.new(actor_id, reset) # Managers should have standardized initialization parameters
    end
    collection[actor_id] = manager
  end
  test_connection(actor_id, manager)
end

#namespacesObject




247
248
249
# File 'lib/core/facade.rb', line 247

def namespaces
  Manager.connection.namespaces
end

#plugin(namespace, plugin_type, provider, options = {}) ⇒ Object




304
305
306
# File 'lib/core/facade.rb', line 304

def plugin(namespace, plugin_type, provider, options = {})
  Manager.connection.load(namespace, plugin_type, provider, options)
end

#plugin_class(namespace, plugin_type) ⇒ Object




338
339
340
# File 'lib/core/facade.rb', line 338

def plugin_class(namespace, plugin_type)
  Manager.connection.plugin_class(namespace, plugin_type)
end

#plugins(namespace, plugin_type, data, build_hash = false, keep_array = false) ⇒ Object




310
311
312
# File 'lib/core/facade.rb', line 310

def plugins(namespace, plugin_type, data, build_hash = false, keep_array = false)
  Manager.connection.load_multiple(namespace, plugin_type, data, build_hash, keep_array)
end

#project(options, provider = nil) ⇒ Object




398
399
400
# File 'lib/core/facade.rb', line 398

def project(options, provider = nil)
  plugin(:nucleon, :project, provider, options)
end

#projects(data, build_hash = false, keep_array = false) ⇒ Object



402
403
404
# File 'lib/core/facade.rb', line 402

def projects(data, build_hash = false, keep_array = false)
  plugins(:nucleon, :project, data, build_hash, keep_array)
end

#provider_class(namespace, plugin_type, provider) ⇒ Object



342
343
344
# File 'lib/core/facade.rb', line 342

def provider_class(namespace, plugin_type, provider)
  Manager.connection.provider_class(namespace, plugin_type, provider)
end

#quiet=(quiet) ⇒ Object



108
109
110
# File 'lib/core/facade.rb', line 108

def quiet=quiet
  Util::Console.quiet = quiet
end

#register(base_path, &code) ⇒ Object



287
288
289
290
# File 'lib/core/facade.rb', line 287

def register(base_path, &code)
  Manager.connection.register(base_path, &code)
  Manager.connection.autoload
end

#reload(core = false, loaded = [], &code) ⇒ Object


Core plugin interface



241
242
243
# File 'lib/core/facade.rb', line 241

def reload(core = false, loaded = [], &code)
  Manager.connection.reload(core, loaded, &code)
end

#remove_plugin(plugin) ⇒ Object



332
333
334
# File 'lib/core/facade.rb', line 332

def remove_plugin(plugin)
  Manager.connection.remove(plugin)
end

#remove_plugin_by_name(namespace, plugin_type, plugin_instance_name) ⇒ Object




328
329
330
# File 'lib/core/facade.rb', line 328

def remove_plugin_by_name(namespace, plugin_type, plugin_instance_name)
  Manager.connection.remove_by_name(namespace, plugin_type, plugin_instance_name)
end

#render_object(data) ⇒ Object




637
638
639
640
# File 'lib/core/facade.rb', line 637

def render_object(data)
  require 'pp'
  PP.pp(data, "").strip
end

#render_tree(data, logger, state = :debug, padding = '') ⇒ Object




644
645
646
647
648
649
650
651
652
653
654
# File 'lib/core/facade.rb', line 644

def render_tree(data, logger, state = :debug, padding = '')
  if data.is_a?(Hash) || data.is_a?(Nucleon::Config)
    data = data.export if data.is_a?(Nucleon::Config)
    data.each do |key, value|
      logger.send(state, "#{padding}#{key}")
      if value.is_a?(Hash) || value.is_a?(Nucleon::Config)
        render_tree(value, logger, state, "#{padding}  ")
      end
    end
  end
end

#runObject


External execution



481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
# File 'lib/core/facade.rb', line 481

def run
  begin
    logger.debug("Running contained process at #{Time.now}")
    yield

  rescue Exception => error
    logger.error("Nucleon run experienced an error! Details:")
    logger.error(error.inspect)
    logger.error(error.message)
    logger.error(Util::Data.to_yaml(error.backtrace))

    ui.error(error.message) if error.message
    raise
  end
end

#search_actions(args) ⇒ Object



379
380
381
382
383
384
385
386
387
388
389
390
# File 'lib/core/facade.rb', line 379

def search_actions(args)
  action_info = Plugin::Action.search_actions(args)

  action_components = action_info[:components]
  action            = action_info[:actions]

  action_components.each do |component|
    args.shift
  end

  [ action, action_components, args ]
end

#sha1(data) ⇒ Object




607
608
609
# File 'lib/core/facade.rb', line 607

def sha1(data)
  Digest::SHA1.hexdigest(Util::Data.to_json(data, false))
end

#silenceObject




613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
# File 'lib/core/facade.rb', line 613

def silence
  result = nil

  begin
    orig_stderr = $stderr.clone
    orig_stdout = $stdout.clone
    $stderr.reopen File.new('/dev/null', 'w')
    $stdout.reopen File.new('/dev/null', 'w')

    result = yield

  rescue Exception => error
    $stdout.reopen orig_stdout
    $stderr.reopen orig_stderr
    raise error
  ensure
    $stdout.reopen orig_stdout
    $stderr.reopen orig_stderr
  end
  result
end

#template(options, provider = nil) ⇒ Object




429
430
431
# File 'lib/core/facade.rb', line 429

def template(options, provider = nil)
  plugin(:nucleon, :template, provider, options)
end

#templates(data, build_hash = false, keep_array = false) ⇒ Object



433
434
435
# File 'lib/core/facade.rb', line 433

def templates(data, build_hash = false, keep_array = false)
  plugins(:nucleon, :template, data, build_hash, keep_array)
end

#test_connection(actor_id, manager) ⇒ Object



157
158
159
160
161
162
163
164
165
166
167
168
# File 'lib/core/facade.rb', line 157

def test_connection(actor_id, manager)
  if parallel?
    begin
      # Raise error if no test method found but retry for dead actors
      manager.test_connection

    rescue NoMethodError, Celluloid::DeadActorError
      retry
    end
  end
  manager
end

#translator(options, provider = nil) ⇒ Object




439
440
441
# File 'lib/core/facade.rb', line 439

def translator(options, provider = nil)
  plugin(:nucleon, :translator, provider, options)
end

#translators(data, build_hash = false, keep_array = false) ⇒ Object



443
444
445
# File 'lib/core/facade.rb', line 443

def translators(data, build_hash = false, keep_array = false)
  plugins(:nucleon, :translator, data, build_hash, keep_array)
end

#type_default(namespace, plugin_type) ⇒ Object



261
262
263
# File 'lib/core/facade.rb', line 261

def type_default(namespace, plugin_type)
  Manager.connection.type_default(namespace, plugin_type)
end

#types(namespace) ⇒ Object




253
254
255
# File 'lib/core/facade.rb', line 253

def types(namespace)
  Manager.connection.types(namespace)
end

#uiObject




100
101
102
# File 'lib/core/facade.rb', line 100

def ui
  Core.ui
end

#ui_group(resource, color = :cyan, &code) ⇒ Object



104
105
106
# File 'lib/core/facade.rb', line 104

def ui_group(resource, color = :cyan, &code)
  Core.ui_group(resource, color, &code)
end

#value(method, value, options = {}) ⇒ Object




468
469
470
# File 'lib/core/facade.rb', line 468

def value(method, value, options = {})
  Manager.connection.value(method, value, options)
end