#!/usr/bin/ruby require_relative 'objects/rcm_file' require_relative 'objects/rcm_package' require_relative 'objects/rcm_service' require_relative 'managers/rcm_package_manager' require_relative 'managers/rcm_file_manager' require_relative 'managers/rcm_service_manager' require_relative 'rcm_utils' require 'yaml' require 'logger' module RCM PACKAGES = 'packages'.freeze FILES = 'files'.freeze SERVICES = 'services'.freeze VALID_LOG_LEVELS = %w(fatal error info debug).freeze RCM_ENV = ENV.fetch('ENVIRONMENT', '') @@wanted = { PACKAGES => {}, FILES => {}, SERVICES => {} } @@got = { PACKAGES => {}, FILES => {}, SERVICES => {} } @@crackalackin = { PACKAGES => [], FILES => [], SERVICES => [] } @@logger = ::Logger.new(STDOUT) @@pkg_mgr = ::RCM::Apt.new(@@logger) @@file_mgr = ::RCM::FileManager.new(@@logger) @@svc_mgr = ::RCM::ServiceManager.new(@@logger) def self.configure_logger # Can be exposed as settings but was expanding the scope as this # object will need to be passed to all other objects @@logger.level = ::Logger::DEBUG @@logger.progname = 'rcm' end def self.parse_packages(markup) @@logger.info("Environment = #{RCM_ENV}") @@pkg_mgr.update unless RCM_ENV == 'dev' markup.each do |d| # ensure package version exists, if mentioned. version = d.fetch('version', '') desired_state = d.fetch('desired_state', ::RCM::Package::INSTALLED) valid_package_states = [::RCM::Package::INSTALLED, ::RCM::Package::REMOVED] if (valid_package_states & [desired_state]).empty? raise "Unknown desired_state: #{desired_state}. Valid states: #{valid_package_states.join(', ')}" end unless version.empty? available_versions = @@pkg_mgr.get_versions(d['name']) if (available_versions & [version]).empty? raise "\n\n#{d['name']} = #{version} is not available.\nAvailable versions: #{available_versions.join(', ')}" end end p = RCM::Package.new(d['name'], version, desired_state) @@wanted[PACKAGES][d['name']] = p end end def self.parse_files(markup) markup.each do |d| raise "\n\n'#{d['local_file']}' is not readable.\n\n" unless ::File.readable?(d['local_file']) f = RCM::File.new(d['path'], d['owner'], d['group'], d['mode'], d['local_file']) @@wanted[FILES][d['path']] = f end end def self.parse_services(markup) pkgs = @@wanted[PACKAGES] files = @@wanted[FILES] file_dependencies = {} package_dependencies = {} markup.each do |d| dependencies = d.fetch('dependencies', {}) dependencies.each do |dep| case dep when PACKAGES raise "\n\nPlease ensure #{dep['name']} is managed by this program before adding it as a dependency.\n\n" unless pkgs.key?(dep['name']) p = pkgs[dep['name']] package_dependencies[p.name] = p when FILES raise "\n\nPlease ensure #{dep['path']} is managed by this program before adding it as a dependency.\n\n" unless files.key?(dep['path']) f = files[dep['path']] file_dependencies[f.path] = f end end s = RCM::Service.new(d['name'], file_dependencies, package_dependencies) @@wanted[SERVICES][d['name']] = s end end def whachuwant # or parse_config # Consume config from YAML, and convert it to usable objects in @@wanted. config_file = RCM_ENV.empty? ? 'config.yaml' : "config_#{RCM_ENV}.yaml" raise "#{config_file} not found." unless ::File.readable?(config_file) config = YAML.load_file(config_file) config.each do |yaml_objects| yaml_objects.each do |collection, resource_definition| case collection when PACKAGES parse_packages(resource_definition) when FILES parse_files(resource_definition) when SERVICES parse_services(resource_definition) end end end end def whachugot # or get_current_state @@got[PACKAGES] = @@pkg_mgr.get_current_state(@@wanted[PACKAGES]) @@got[FILES] = @@file_mgr.get_current_state(@@wanted[FILES]) # @@got[SERVICES] = @@svc_mgr.get_current_state(@@wanted[SERVICES]) end def crackalackin_packages @@wanted[PACKAGES].each do |pkg_name, pkg_obj| current_pkg = @@got[PACKAGES][pkg_name] next if current_pkg == pkg_obj # Set the version correctly current_pkg.version = pkg_obj.version @@crackalackin[PACKAGES].push(current_pkg) end @@logger.debug('Missing packages:' + @@crackalackin[PACKAGES].join("\n")) end def crackalackin_files @@wanted[FILES].each do |path, file_obj| file_on_fs = @@got[FILES][path] next if file_on_fs == file_obj # Set the version correctly @@crackalackin[FILES].push(file_obj) end @@logger.debug('Missing files:' + @@crackalackin[FILES].join("\n")) puts @@crackalackin[FILES] end def cracka_stop_lackin() puts 'not implemented' end def main self.configure_logger end module_function :whachuwant, :whachugot, :crackalackin_packages, :crackalackin_files, :cracka_stop_lackin, :main end RCM.main RCM.whachuwant RCM.whachugot RCM.crackalackin_packages RCM.crackalackin_files