Better defaults management, logger class implementation with logging levels, and write to file configuration implementation
parent
e79fa3b89f
commit
ee1df1fb0c
|
@ -6,7 +6,8 @@ set(CMAKE_CXX_STANDARD 20)
|
|||
# Create modules directory
|
||||
file(MAKE_DIRECTORY ${CMAKE_BINARY_DIR}/modules)
|
||||
|
||||
add_executable(dpm
|
||||
add_executable(
|
||||
dpm
|
||||
src/dpm.cpp
|
||||
src/ModuleLoader.cpp
|
||||
src/dpm_interface.cpp
|
||||
|
@ -15,6 +16,7 @@ add_executable(dpm
|
|||
src/handlers.cpp
|
||||
src/module_interface.cpp
|
||||
src/ConfigManager.cpp
|
||||
src/Logger.cpp
|
||||
)
|
||||
|
||||
target_include_directories(dpm PRIVATE include)
|
||||
|
@ -25,7 +27,8 @@ target_link_options(dpm PRIVATE -rdynamic)
|
|||
|
||||
# Add the info module
|
||||
add_library(info MODULE modules/info.cpp)
|
||||
set_target_properties(info PROPERTIES
|
||||
set_target_properties(
|
||||
info PROPERTIES
|
||||
PREFIX ""
|
||||
SUFFIX ".so"
|
||||
LIBRARY_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}/modules"
|
||||
|
@ -34,13 +37,16 @@ set_target_properties(info PROPERTIES
|
|||
# Installation rules
|
||||
install(TARGETS dpm DESTINATION bin)
|
||||
install(DIRECTORY DESTINATION /etc/dpm/conf.d)
|
||||
install(DIRECTORY "${CMAKE_SOURCE_DIR}/data/"
|
||||
install(
|
||||
DIRECTORY "${CMAKE_SOURCE_DIR}/data/"
|
||||
DESTINATION /etc/dpm/conf.d
|
||||
FILES_MATCHING
|
||||
PATTERN "*.conf"
|
||||
)
|
||||
|
||||
# Install all .so files from build/modules to the module path
|
||||
install(DIRECTORY ${CMAKE_BINARY_DIR}/modules/
|
||||
install(
|
||||
DIRECTORY ${CMAKE_BINARY_DIR}/modules/
|
||||
DESTINATION /usr/lib/dpm/modules
|
||||
FILES_MATCHING PATTERN "*.so")
|
||||
FILES_MATCHING PATTERN "*.so"
|
||||
)
|
|
@ -1,3 +1,4 @@
|
|||
[logging]
|
||||
log_file = /var/log/dpm.log
|
||||
write_to_log = true
|
||||
write_to_log = true
|
||||
log_level = INFO
|
|
@ -48,7 +48,13 @@
|
|||
class ConfigManager {
|
||||
public:
|
||||
// Constructor
|
||||
ConfigManager( const std::string& config_dir = DPMDefaultPaths::CONFIG_DIR );
|
||||
ConfigManager();
|
||||
|
||||
// Set the configuration directory
|
||||
void setConfigDir(const std::string& config_dir);
|
||||
|
||||
// Get the current configuration directory
|
||||
std::string getConfigDir() const;
|
||||
|
||||
// Load all configuration files from the config directory
|
||||
bool loadConfigurations();
|
||||
|
|
|
@ -0,0 +1,52 @@
|
|||
/**
|
||||
* @file DPMDefaults.hpp
|
||||
* @brief Default configuration values for the DPM utility
|
||||
*
|
||||
* Defines the DPMDefaults structure which provides default configuration values
|
||||
* for paths, logging settings, and other system-wide defaults used by the DPM
|
||||
* utility when explicit configuration is not provided.
|
||||
*
|
||||
* @copyright Copyright (c) 2025 SILO GROUP LLC
|
||||
* @author Chris Punches <chris.punches@silogroup.org>
|
||||
*
|
||||
* Part of the Dark Horse Linux Package Manager (DPM)
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License as
|
||||
* published by the Free Software Foundation, either version 3 of the
|
||||
* License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*
|
||||
* For bug reports or contributions, please contact the dhlp-contributors
|
||||
* mailing list at: https://lists.darkhorselinux.org/mailman/listinfo/dhlp-contributors
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <string>
|
||||
#include "LoggingLevels.hpp"
|
||||
|
||||
// default system configuration
|
||||
struct DPMDefaults {
|
||||
static const char* const MODULE_PATH;
|
||||
static const char* const CONFIG_DIR;
|
||||
static const char* const LOG_FILE;
|
||||
static const bool write_to_log;
|
||||
static const LoggingLevels LOG_LEVEL;
|
||||
};
|
||||
|
||||
// Initialize static constants
|
||||
inline const char * const DPMDefaults::MODULE_PATH = "/usr/lib/dpm/modules/";
|
||||
|
||||
inline const char * const DPMDefaults::CONFIG_DIR = "/etc/dpm/conf.d/";
|
||||
|
||||
inline const char * const DPMDefaults::LOG_FILE = "/var/log/dpm.log";
|
||||
inline const bool DPMDefaults::write_to_log = false;
|
||||
inline const LoggingLevels DPMDefaults::LOG_LEVEL = LoggingLevels::INFO;
|
|
@ -0,0 +1,46 @@
|
|||
// Logger.hpp
|
||||
#pragma once
|
||||
|
||||
#include <fstream>
|
||||
#include <iostream>
|
||||
#include <ctime>
|
||||
#include <string>
|
||||
#include <filesystem>
|
||||
#include <stdexcept>
|
||||
#include <cstdlib>
|
||||
|
||||
#include "LoggingLevels.hpp"
|
||||
#include "DPMDefaults.hpp"
|
||||
|
||||
class Logger {
|
||||
public:
|
||||
// constructor
|
||||
Logger();
|
||||
|
||||
// destructor
|
||||
~Logger();
|
||||
|
||||
// Log method that accepts a string
|
||||
void log(LoggingLevels log_level, const std::string& message);
|
||||
|
||||
// Configuration setters
|
||||
void setLogFile(const std::string& log_file);
|
||||
void setWriteToLog(bool write_to_log);
|
||||
void setLogLevel(LoggingLevels log_level);
|
||||
|
||||
// String to LoggingLevels conversion
|
||||
static LoggingLevels stringToLogLevel(const std::string& level_str, LoggingLevels default_level = LoggingLevels::INFO);
|
||||
|
||||
private:
|
||||
// the logging level to stay initialized to
|
||||
LoggingLevels log_level;
|
||||
|
||||
// whether or not to log to file
|
||||
bool log_to_file;
|
||||
|
||||
// log file path
|
||||
std::string log_file;
|
||||
};
|
||||
|
||||
// Global logger instance
|
||||
extern Logger g_logger;
|
|
@ -0,0 +1,10 @@
|
|||
#pragma once
|
||||
|
||||
// Log level enum that will be accessible to modules
|
||||
enum LoggingLevels {
|
||||
FATAL = 0,
|
||||
ERROR = 1,
|
||||
WARN = 2,
|
||||
INFO = 3,
|
||||
DEBUG = 4
|
||||
};
|
|
@ -39,6 +39,7 @@
|
|||
#include "error.hpp"
|
||||
#include "ModuleLoader.hpp"
|
||||
#include "dpm_interface_helpers.hpp"
|
||||
#include "Logger.hpp"
|
||||
|
||||
/*
|
||||
*
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/**
|
||||
* @file dpm_interface_helpers.hpp
|
||||
* @file dpm_interface_helpers.hpp
|
||||
* @brief Helper functions for DPM command-line interface
|
||||
*
|
||||
* Provides utility functions for command-line argument parsing and
|
||||
|
@ -34,18 +34,17 @@
|
|||
#include <iostream>
|
||||
#include <getopt.h>
|
||||
|
||||
#include "Logger.hpp"
|
||||
#include "LoggingLevels.hpp"
|
||||
#include "DPMDefaults.hpp"
|
||||
|
||||
// data structure for supplied arguments
|
||||
struct CommandArgs {
|
||||
std::string module_path;
|
||||
std::string config_dir;
|
||||
std::string module_name;
|
||||
std::string command; // All arguments combined into a single command string
|
||||
std::string command;
|
||||
};
|
||||
|
||||
// parse dpm cli arguments into a serialized structure
|
||||
CommandArgs parse_args( int argc, char * argv[] );
|
||||
|
||||
// default system paths
|
||||
struct DPMDefaultPaths {
|
||||
static const std::string MODULE_PATH;
|
||||
static const std::string CONFIG_DIR;
|
||||
};
|
||||
|
|
|
@ -39,14 +39,6 @@
|
|||
#define MODULE_VERSION "0.1.0"
|
||||
#define DPM_VERSION "0.1.0"
|
||||
|
||||
// Command enum for switch case
|
||||
enum Command {
|
||||
CMD_UNKNOWN,
|
||||
CMD_HELP,
|
||||
CMD_VERSION,
|
||||
CMD_SYSTEM,
|
||||
CMD_CONFIG
|
||||
};
|
||||
|
||||
// Declaration of the DPM config function we want to call
|
||||
extern "C" const char* dpm_get_config(const char* section, const char* key);
|
||||
|
@ -64,6 +56,15 @@ extern "C" const char* dpm_get_description(void) {
|
|||
return "DPM Info Module - Provides information about the DPM system";
|
||||
}
|
||||
|
||||
// Command enum for switch case
|
||||
enum Command {
|
||||
CMD_UNKNOWN,
|
||||
CMD_HELP,
|
||||
CMD_VERSION,
|
||||
CMD_SYSTEM,
|
||||
CMD_CONFIG
|
||||
};
|
||||
|
||||
// Function to detect architecture using uname
|
||||
std::string detect_architecture() {
|
||||
struct utsname system_info;
|
||||
|
|
|
@ -34,8 +34,8 @@
|
|||
// Global configuration manager instance
|
||||
ConfigManager g_config_manager;
|
||||
|
||||
ConfigManager::ConfigManager(const std::string& config_dir)
|
||||
: _config_dir(config_dir)
|
||||
ConfigManager::ConfigManager()
|
||||
: _config_dir(DPMDefaults::CONFIG_DIR)
|
||||
{
|
||||
// Ensure the config directory ends with a slash
|
||||
if (!_config_dir.empty() && _config_dir.back() != '/') {
|
||||
|
@ -43,6 +43,21 @@ ConfigManager::ConfigManager(const std::string& config_dir)
|
|||
}
|
||||
}
|
||||
|
||||
void ConfigManager::setConfigDir(const std::string& config_dir)
|
||||
{
|
||||
_config_dir = config_dir;
|
||||
|
||||
// Ensure the config directory ends with a slash
|
||||
if (!_config_dir.empty() && _config_dir.back() != '/') {
|
||||
_config_dir += '/';
|
||||
}
|
||||
}
|
||||
|
||||
std::string ConfigManager::getConfigDir() const
|
||||
{
|
||||
return _config_dir;
|
||||
}
|
||||
|
||||
std::string ConfigManager::trimWhitespace(const std::string& str) const
|
||||
{
|
||||
const std::string whitespace = " \t\n\r\f\v";
|
||||
|
|
|
@ -0,0 +1,149 @@
|
|||
// Logger.cpp
|
||||
#include "Logger.hpp"
|
||||
|
||||
// Global logger instance
|
||||
Logger g_logger;
|
||||
|
||||
Logger::Logger()
|
||||
: log_level(DPMDefaults::LOG_LEVEL),
|
||||
log_to_file(DPMDefaults::write_to_log),
|
||||
log_file(DPMDefaults::LOG_FILE)
|
||||
{
|
||||
}
|
||||
|
||||
Logger::~Logger()
|
||||
{
|
||||
}
|
||||
|
||||
void Logger::setLogFile(const std::string& new_log_file)
|
||||
{
|
||||
log_file = new_log_file;
|
||||
|
||||
// If logging to file is enabled, ensure the log directory exists and is writable
|
||||
if (log_to_file) {
|
||||
std::filesystem::path log_path(log_file);
|
||||
std::filesystem::path log_dir = log_path.parent_path();
|
||||
|
||||
// Check if the directory exists, create if not
|
||||
if (!log_dir.empty() && !std::filesystem::exists(log_dir)) {
|
||||
try {
|
||||
if (!std::filesystem::create_directories(log_dir)) {
|
||||
std::cerr << "FATAL: Failed to create log directory: " << log_dir.string() << std::endl;
|
||||
exit(1);
|
||||
}
|
||||
} catch (const std::filesystem::filesystem_error& e) {
|
||||
std::cerr << "FATAL: Error creating log directory: " << e.what() << std::endl;
|
||||
exit(1);
|
||||
}
|
||||
}
|
||||
|
||||
// Verify we can write to the log file
|
||||
try {
|
||||
std::ofstream test_log_file(log_file, std::ios::app);
|
||||
if (!test_log_file.is_open()) {
|
||||
std::cerr << "FATAL: Cannot open log file for writing: " << log_file << std::endl;
|
||||
exit(1);
|
||||
}
|
||||
test_log_file.close();
|
||||
} catch (const std::exception& e) {
|
||||
std::cerr << "FATAL: Error validating log file access: " << e.what() << std::endl;
|
||||
exit(1);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void Logger::setWriteToLog(bool new_write_to_log)
|
||||
{
|
||||
log_to_file = new_write_to_log;
|
||||
|
||||
// If logging was just enabled, validate the log file
|
||||
if (log_to_file) {
|
||||
setLogFile(log_file);
|
||||
}
|
||||
}
|
||||
|
||||
void Logger::setLogLevel(LoggingLevels new_log_level)
|
||||
{
|
||||
log_level = new_log_level;
|
||||
}
|
||||
|
||||
LoggingLevels Logger::stringToLogLevel(const std::string& level_str, LoggingLevels default_level)
|
||||
{
|
||||
if (level_str == "FATAL") {
|
||||
return LoggingLevels::FATAL;
|
||||
} else if (level_str == "ERROR") {
|
||||
return LoggingLevels::ERROR;
|
||||
} else if (level_str == "WARN") {
|
||||
return LoggingLevels::WARN;
|
||||
} else if (level_str == "INFO") {
|
||||
return LoggingLevels::INFO;
|
||||
} else if (level_str == "DEBUG") {
|
||||
return LoggingLevels::DEBUG;
|
||||
}
|
||||
|
||||
// Return default if no match
|
||||
return default_level;
|
||||
}
|
||||
|
||||
void Logger::log(LoggingLevels message_level, const std::string& message)
|
||||
{
|
||||
// Only process if the message level is less than or equal to the configured level
|
||||
if (message_level <= log_level) {
|
||||
// Convert log level to string
|
||||
std::string level_str;
|
||||
switch (message_level) {
|
||||
case LoggingLevels::FATAL:
|
||||
level_str = "FATAL";
|
||||
break;
|
||||
case LoggingLevels::ERROR:
|
||||
level_str = "ERROR";
|
||||
break;
|
||||
case LoggingLevels::WARN:
|
||||
level_str = "WARN";
|
||||
break;
|
||||
case LoggingLevels::INFO:
|
||||
level_str = "INFO";
|
||||
break;
|
||||
case LoggingLevels::DEBUG:
|
||||
level_str = "DEBUG";
|
||||
break;
|
||||
default:
|
||||
level_str = "UNKNOWN";
|
||||
break;
|
||||
}
|
||||
|
||||
// Console output without timestamp
|
||||
if (message_level == LoggingLevels::FATAL ||
|
||||
message_level == LoggingLevels::ERROR ||
|
||||
message_level == LoggingLevels::WARN) {
|
||||
// Send to stderr
|
||||
std::cerr << level_str << ": " << message << std::endl;
|
||||
} else {
|
||||
// Send to stdout
|
||||
std::cout << message << std::endl;
|
||||
}
|
||||
|
||||
// Write to log file if enabled (with timestamp)
|
||||
if (log_to_file) {
|
||||
try {
|
||||
// Get current time for timestamp (only for log file)
|
||||
std::time_t now = std::time(nullptr);
|
||||
char timestamp[32];
|
||||
std::strftime(timestamp, sizeof(timestamp), "%Y-%m-%d %H:%M:%S", std::localtime(&now));
|
||||
|
||||
// Full formatted message with timestamp for log file
|
||||
std::string formatted_message = std::string(timestamp) + " [" + level_str + "] " + message;
|
||||
|
||||
std::ofstream log_stream(log_file, std::ios::app);
|
||||
if (log_stream.is_open()) {
|
||||
log_stream << formatted_message << std::endl;
|
||||
log_stream.close();
|
||||
} else {
|
||||
std::cerr << "Failed to write to log file: " << log_file << std::endl;
|
||||
}
|
||||
} catch (const std::exception& e) {
|
||||
std::cerr << "Error writing to log file: " << e.what() << std::endl;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
85
src/dpm.cpp
85
src/dpm.cpp
|
@ -36,6 +36,7 @@
|
|||
#include "dpm_interface_helpers.hpp"
|
||||
#include "error.hpp"
|
||||
#include "ConfigManager.hpp"
|
||||
#include "Logger.hpp"
|
||||
|
||||
/*
|
||||
* DPM serves three functions:
|
||||
|
@ -60,63 +61,93 @@ int default_behavior(const ModuleLoader& loader)
|
|||
* @param argv Array of C-style strings containing the arguments
|
||||
* @return Exit code indicating success (0) or failure (non-zero)
|
||||
*/
|
||||
int main(int argc, char* argv[])
|
||||
int main( int argc, char* argv[] )
|
||||
{
|
||||
// Load configuration files
|
||||
if (!g_config_manager.loadConfigurations()) {
|
||||
std::cerr << "Warning: No configuration files present or loaded from '" << DPMDefaultPaths::CONFIG_DIR << "*.conf', reverting to defaults." << std::endl;
|
||||
// Continue execution, as we might be able to use default values
|
||||
// process the arguments supplied to DPM and provide
|
||||
// an object that contains them for command and routing
|
||||
// processing
|
||||
CommandArgs args = parse_args( argc, argv );
|
||||
|
||||
// Set the configuration directory path (CLI argument takes precedence over defaults)
|
||||
if ( !args.config_dir.empty() )
|
||||
{
|
||||
// args.config_dir was supplied so set it
|
||||
g_config_manager.setConfigDir( args.config_dir );
|
||||
} else {
|
||||
// args.config_dir was not supplied, so fall back to default path
|
||||
g_config_manager.setConfigDir( DPMDefaults::CONFIG_DIR );
|
||||
}
|
||||
|
||||
// process the arguments suppplied to DPM and provide
|
||||
// an object that contains them for command and routing
|
||||
// processing - this will include any module_path from CLI
|
||||
auto args = parse_args(argc, argv);
|
||||
// Load configuration files
|
||||
if ( !g_config_manager.loadConfigurations() )
|
||||
{
|
||||
// failed to load any configuration files, so alert the user
|
||||
std::cerr << "Warning: No configuration files present or loaded from '"
|
||||
<< g_config_manager.getConfigDir() << "*.conf', reverting to defaults." << std::endl;
|
||||
}
|
||||
|
||||
// Configure logger (CLI args > config > defaults)
|
||||
// Check configuration for log settings
|
||||
bool config_write_to_log = g_config_manager.getConfigBool("logging", "write_to_log", DPMDefaults::write_to_log);
|
||||
std::string config_log_file = g_config_manager.getConfigString("logging", "log_file", DPMDefaults::LOG_FILE);
|
||||
|
||||
// Parse log_level from config using the new method
|
||||
std::string log_level_str = g_config_manager.getConfigString("logging", "log_level", "INFO");
|
||||
LoggingLevels config_log_level = Logger::stringToLogLevel(log_level_str, DPMDefaults::LOG_LEVEL);
|
||||
|
||||
// Configure global logger instance
|
||||
g_logger.setLogLevel(config_log_level);
|
||||
g_logger.setWriteToLog(config_write_to_log);
|
||||
g_logger.setLogFile(config_log_file);
|
||||
|
||||
// Determine the module path (CLI arg > config > default)
|
||||
std::string module_path;
|
||||
|
||||
// If CLI argument was provided, use it
|
||||
if (!args.module_path.empty()) {
|
||||
if ( !args.module_path.empty() )
|
||||
{
|
||||
module_path = args.module_path;
|
||||
} else {
|
||||
// Otherwise, check configuration file
|
||||
const char* config_module_path = g_config_manager.getConfigValue("modules", "module_path");
|
||||
if (config_module_path) {
|
||||
const char * config_module_path = g_config_manager.getConfigValue( "modules", "module_path" );
|
||||
if ( config_module_path )
|
||||
{
|
||||
module_path = config_module_path;
|
||||
}
|
||||
// Finally, use default if nothing else is available
|
||||
else {
|
||||
module_path = DPMDefaultPaths::MODULE_PATH;
|
||||
} else {
|
||||
// use default if nothing else is available
|
||||
module_path = DPMDefaults::MODULE_PATH;
|
||||
}
|
||||
}
|
||||
|
||||
// create a module loader object with the determined path
|
||||
ModuleLoader loader(module_path);
|
||||
ModuleLoader loader( module_path );
|
||||
|
||||
// check the module path for the loader object
|
||||
int path_check_result = main_check_module_path(loader);
|
||||
if (path_check_result != 0) {
|
||||
int path_check_result = main_check_module_path( loader );
|
||||
if ( path_check_result != 0 )
|
||||
{
|
||||
// exit if there's an error and ensure
|
||||
// it has an appropriate return code
|
||||
return 1;
|
||||
return path_check_result;
|
||||
}
|
||||
|
||||
// if no module is provided to execute, then trigger the default
|
||||
// dpm behaviour
|
||||
if (args.module_name.empty()) {
|
||||
return default_behavior(loader);
|
||||
if ( args.module_name.empty() )
|
||||
{
|
||||
return default_behavior( loader );
|
||||
}
|
||||
|
||||
// execute the module
|
||||
DPMErrorCategory execute_error = loader.execute_module(args.module_name, args.command);
|
||||
DPMErrorCategory execute_error = loader.execute_module( args.module_name, args.command );
|
||||
|
||||
std::string extracted_path;
|
||||
loader.get_module_path(extracted_path);
|
||||
std::string absolute_modules_path;
|
||||
loader.get_module_path( absolute_modules_path );
|
||||
|
||||
FlexDPMError result = make_error(execute_error);
|
||||
// construct an error object
|
||||
FlexDPMError result = make_error( execute_error );
|
||||
result.module_name = args.module_name.c_str();
|
||||
result.module_path = extracted_path.c_str();
|
||||
result.module_path = absolute_modules_path.c_str();
|
||||
|
||||
// pair result with a message and exit with the appropriate error code
|
||||
return handle_error(result);
|
||||
|
|
|
@ -65,23 +65,23 @@ int main_check_module_path(const ModuleLoader& loader)
|
|||
loader.get_module_path(path);
|
||||
|
||||
if (!std::filesystem::exists(path)) {
|
||||
std::cerr << "FATAL: modules.modules_path does not exist: " << path << std::endl;
|
||||
g_logger.log(LoggingLevels::FATAL, "modules.modules_path does not exist: " + path);
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (!std::filesystem::is_directory(path)) {
|
||||
std::cerr << "FATAL: modules.modules_path is not a directory: " << path << std::endl;
|
||||
g_logger.log(LoggingLevels::FATAL, "modules.modules_path is not a directory: " + path);
|
||||
return 1;
|
||||
}
|
||||
|
||||
try {
|
||||
auto perms = std::filesystem::status(path).permissions();
|
||||
if ((perms & std::filesystem::perms::owner_read) == std::filesystem::perms::none) {
|
||||
std::cerr << "FATAL: Permission denied: " << path << std::endl;
|
||||
g_logger.log(LoggingLevels::FATAL, "Permission denied: " + path);
|
||||
return 1;
|
||||
}
|
||||
} catch (const std::filesystem::filesystem_error&) {
|
||||
std::cerr << "FATAL: Permission denied: " << path << std::endl;
|
||||
g_logger.log(LoggingLevels::FATAL, "Permission denied: " + path);
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
@ -122,18 +122,18 @@ int main_list_modules(const ModuleLoader& loader)
|
|||
// set the module path
|
||||
DPMErrorCategory get_path_error = loader.get_module_path(path);
|
||||
if ( get_path_error != DPMErrorCategory::SUCCESS ) {
|
||||
std::cerr << "Failed to get modules.modules_path" << std::endl;
|
||||
g_logger.log(LoggingLevels::FATAL, "Failed to get modules.modules_path");
|
||||
return 1;
|
||||
}
|
||||
|
||||
DPMErrorCategory list_error = loader.list_available_modules(modules);
|
||||
if (list_error != DPMErrorCategory::SUCCESS) {
|
||||
std::cerr << "FATAL: No modules found in modules.modules_path: " << path << std::endl;
|
||||
g_logger.log(LoggingLevels::FATAL, "No modules found in modules.modules_path: " + path);
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (modules.empty()) {
|
||||
std::cerr << "FATAL: No modules found in modules.modules_path: '" << path << "'." << std::endl;
|
||||
g_logger.log(LoggingLevels::FATAL, "No modules found in modules.modules_path: '" + path + "'.");
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -154,8 +154,8 @@ int main_list_modules(const ModuleLoader& loader)
|
|||
dlclose(handle);
|
||||
}
|
||||
|
||||
if (valid_modules.empty()) {
|
||||
std::cerr << "FATAL: No valid modules found in modules.modules_path: '" << path << "'." << std::endl;
|
||||
if ( valid_modules.empty() ) {
|
||||
g_logger.log(LoggingLevels::FATAL, "No valid modules found in modules.modules_path: '" + path + "'.");
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -193,7 +193,7 @@ int main_list_modules(const ModuleLoader& loader)
|
|||
const int column_spacing = 4;
|
||||
|
||||
// Display the table header
|
||||
std::cout << "\nAvailable modules in modules.modules_path: '" << path << "':" << std::endl << std::endl;
|
||||
g_logger.log(LoggingLevels::DEBUG, "\nAvailable modules in modules.modules_path: '" + path + "':\n");
|
||||
std::cout << std::left << std::setw(max_name_length + column_spacing) << "MODULE"
|
||||
<< std::setw(max_version_length + column_spacing) << "VERSION"
|
||||
<< "DESCRIPTION" << std::endl;
|
||||
|
|
|
@ -30,9 +30,7 @@
|
|||
|
||||
#include "dpm_interface_helpers.hpp"
|
||||
|
||||
// Define the static constants
|
||||
const std::string DPMDefaultPaths::MODULE_PATH = "/usr/lib/dpm/modules/";
|
||||
const std::string DPMDefaultPaths::CONFIG_DIR = "/etc/dpm/conf.d/";
|
||||
|
||||
|
||||
/**
|
||||
* Parse command line arguments for DPM.
|
||||
|
@ -47,6 +45,7 @@ const std::string DPMDefaultPaths::CONFIG_DIR = "/etc/dpm/conf.d/";
|
|||
*
|
||||
* The function handles the following arguments:
|
||||
* - ``-m, --module-path PATH``: Sets the directory path where DPM modules are located
|
||||
* - ``-c, --config-dir PATH``: Sets the directory path where DPM configuration files are located
|
||||
* - ``-h, --help``: Displays a help message and exits
|
||||
*
|
||||
* Additional arguments are processed as follows:
|
||||
|
@ -61,25 +60,31 @@ CommandArgs parse_args(int argc, char* argv[])
|
|||
{
|
||||
CommandArgs args;
|
||||
args.module_path = "";
|
||||
args.config_dir = "";
|
||||
|
||||
static struct option long_options[] = {
|
||||
{"module-path", required_argument, 0, 'm'},
|
||||
{"config-dir", required_argument, 0, 'c'},
|
||||
{"help", no_argument, 0, 'h'},
|
||||
{0, 0, 0, 0}
|
||||
};
|
||||
|
||||
int opt;
|
||||
int option_index = 0;
|
||||
while ((opt = getopt_long(argc, argv, "m:h", long_options, &option_index)) != -1) {
|
||||
while ((opt = getopt_long(argc, argv, "m:c:h", long_options, &option_index)) != -1) {
|
||||
switch (opt) {
|
||||
case 'm':
|
||||
args.module_path = optarg;
|
||||
break;
|
||||
case 'c':
|
||||
args.config_dir = optarg;
|
||||
break;
|
||||
case 'h':
|
||||
std::cout << "Usage: dpm [options] [module-name] [module args...] [module-command] [command-args]\n\n"
|
||||
<< "Options:\n\n"
|
||||
<< " -m, --module-path PATH Path to DPM modules (overrides modules.modules_path in config)\n"
|
||||
<< " -h, --help Show this help message\n\n";
|
||||
<< " -c, --config-dir PATH Path to DPM configuration directory\n"
|
||||
<< " -h, --help Show this help message\n\n";
|
||||
exit(0);
|
||||
case '?':
|
||||
exit(1);
|
||||
|
|
Loading…
Reference in New Issue