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.

Parameters:

  • options (Hash)

    Parameters to run Reedb by sorted in a hash datastructure.

Returns:

  • nil



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.

Parameters:

  • reason (String) (defaults to: nil)

    Reason why Reedb is being terminated to be written into central logs.

Returns:

  • nil



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