Module: Reedb::Core

Includes:
Reedb
Defined in:
lib/reedb.rb

Overview

Core submodule of the Interface stack

Constant Summary

Constants included from Reedb

CERT_PATH, DEBOUNCE_DELTA, DEB_ADD, DEB_REM, DEFAULT_PATH, EXIT_CORRUPT_FS, EXIT_HTTP_MALFUNCT, EXIT_MISSING_USER_CODE, EXIT_OS_PARSE, EXIT_PANIC_INTERUPT, EXIT_STILL_LOCKED, FILE_CACHE_TIME, KEY_CACHE_TIME, KEY_PATH, NET_PORT, THREAD_TIMEOUT_TIME, TOKEN_BYTE_SIZE, VERSION

Class Method Summary collapse

Methods included from Reedb

archos, daemon?, included, passlength, verbose?

Class Method Details

.init(options, &user_code) ⇒ Object

Initialise Reedb with a set of parameters passed into this method. Please check the wiki to find out what option parameters are available to use here.



273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
# File 'lib/reedb.rb', line 273

def init(options, &user_code)
  unless options.include?(:os) && options.include?(:pw_length)
    puts 'Missing :os (:linux|:osx) and/or :pw_length fields from options!'
    exit Reedb::EXIT_OS_PARSE
  end

  # Checks if user code was provided and exits the entire application if not provided!
  if user_code == nil && !options[:daemon]
    puts 'No user function was provided to run! Reedb must run in daemon mode to do that!'
    exit Reedb::EXIT_MISSING_USER_CODE
  end

  @@daemon = options.include?(:daemon) ? options[:daemon] : true
  @@archos = options[:os]
  @@pw_length = options[:pw_length]
  @@verbose = options.include?(:verbose) ? options[:verbose] : false
  @@no_token = options.include?(:no_token) ? options[:no_token] : false
  override = options.include?(:force) ? options[:force] : false

  if @@no_token
    puts 'NO_TOKEN mode has not been implemented yet! Defaulting to token mode.'
    @@no_token = false
  end

  # Now @@path is either a path OR a placeholder.
  @@path = options.include?(:path) ? options[:path] : Reedb::DEFAULT_PATH

  # Enable cleanup mode
  # This means that the config will be cleaned and unused tokens removed
  # instead of leaving them in the file and configurations.
  # It is recommended to use cleanup mode.
  #
  @@cleanup = options.include?(:cleanup) ? options[:cleanup] : true

  # Set of vaults that map a VaultBuffer to the vault itself.
  # Never exposed outside the API
  #
  @@active_vaults = {}

  # List of tokens authorised for this daemon. Maps tokens to vault names.
  # This is used for authentication and never exposed to the outside API
  # NOTE! This is not used when the :no_token option is enabled
  #
  @@tokens = {} unless @@no_token


  # This is called when the default path applies
  if @@path == Reedb::DEFAULT_PATH

    # For good operating systems.
    if @@archos == :linux
      master_path = File.expand_path('~/.config/reedb/')
      master_path = '/etc/reedb' if Utilities::parse_user == 'root'

      log_path = File.expand_path('~/.config/reedb/logs/')

      # For OSX
    elsif @@archos == :osx
      master_path = File.expand_path('~/Library/Application\ Support/reedb/')
      master_path = '/Library/Application\ Support/reedb' if Utilities::parse_user == 'root'

      log_path = File.expand_path('~/Library/Application\ Support/reedb/logs/')

    elsif @@archos == :win
      puts 'This is currently not supported :( Sorry.'
      # Windows crap
    elsif @@archos == :other
      raise UnknownOSError.new, 'Operating system was not specified, yet an override path was not specified either. Can not continue without more information!'
      exit(Reedb::EXIT_OS_PARSE)
    else
      raise UnknownOSError.new, "Could not recognise specified OS. What are you running? Why don't you go here:
 getfedora.org :)"
      exit(Reedb::EXIT_OS_PARSE)
    end
  else
    master_path = @@path
    log_path = File.join("#{master_path}", 'logs')
  end

  # Sets up the config path
  @@config_path = File.join("#{master_path}", 'master.cfg')
  @@lock_file = File.join("#{master_path}", 'lock')

  # Now go create directories if they need to be created.
  FileUtils::mkdir_p("#{log_path}") unless File.directory?("#{log_path}")
  FileUtils::chmod_R(0744, "#{log_path}")
  FileUtils::chmod_R(0744, "#{master_path}")

  # Now that pathing has been established, check if there is a lock file.
  if File.exist?(@@lock_file) && !override
    puts '[FATAL] Another instance of Reedb is already operating from this directory! Choose another directory or terminate the old instance first!'
    exit(Reedb::EXIT_STILL_LOCKED)
  elsif File.exist?(@@lock_file) && override
    puts "There was another instance of Reedb running but you forced my hand. It's dead now..."
  end

  # Create a lock file
  File.open(@@lock_file, 'w+') { |f| f.write('Hier koennte Ihre Werbung stehen.') }

  # Start up the logging service.
  Reedb::DaemonLogger.setup("#{log_path}")

  # Now go and declare this daemon started and log it.
  @@started = true
  Reedb::DaemonLogger.write('Reedb was started successfully. Reading vault information now...', 'debug')

  # Now cache the config
  cache_config

  '' '
  The bottom part initiates the main run look that bounces between debouncer thread and user code.
  This function only returns after all the user code was handled.
  ' ''

  # Open debounce object
  @@debouncer = Reedb::Debouncer.new(self)


  # Now actually run the code on two threads and hope that the scheduler does it's job!
  @@debouncerThread = Thread.new { @@debouncer.main }
  user = Thread.new(&user_code)

  # Wait for user code to terminate
  user.join

  # Then call terminate just in case they haven't yet
  Reedb::Core::terminate('null', true)
end

.terminate(reason = nil, silent = false) ⇒ Object

Terminate Reedb with a reason. After calling this function the core functionality (and depending interfaces on the stack) is no longer available.



411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
# File 'lib/reedb.rb', line 411

def terminate(reason = nil, silent = false)
  puts 'Must start process first' if !@@started && !silent
  return unless @@started

  new_reason = 'unknown reason'
  new_reason = 'a user request' if reason == 'user'
  new_reason = 'a system request' if reason == 'root'

  # My first easter-egg. Yay! :)
  new_reason = 'the illuminati' if reason == 'aliens'

  DaemonLogger.write("[TERM]: Scheduling termination because of #{new_reason}.")

  # Let the debouncer thread time out
  @@debouncer.running = false
  sleep(Reedb::THREAD_TIMEOUT_TIME)

  # Then join it and be done with it
  @@debouncerThread.join

  # Closing open vaults here
  counter = 0

  # Iterate over active vaults
  @@active_vaults.each do |uuid, vault|
    vault.close

    # Iterate over the token list and remove them until all are gone
    # TODO: Search for a more Ruby-esk way to do this.
    while !@@config[:vaults][uuid][:tokens].empty?
      Reedb::Daemon::free_token(@@config[:vaults][uuid][:tokens][0])
    end
    counter += 1
  end
  write_config

  # Then declare Reedb terminated and remove the lock file
  @@started = false
  File.delete(@@lock_file) if File.exist?(@@lock_file)
  DaemonLogger.write("[TERM]: Closed #{counter} vaults. Done!")
  return 0
end